Update lots of outdated pages and Fabric references

Elizabeth Craig 2020-10-30 22:59:56 -07:00
Родитель 9eb70028f0
Коммит 2414def9e2
45 изменённых файлов: 510 добавлений и 771 удалений

@ -1,27 +1,26 @@
### What is the `@fluentui/api-docs` package?
# API documentation generation in `@fluentui/react`
`@fluentui/react` 7/8 uses [API Extractor](API-Extractor) and the custom [`@fluentui/api-docs` package](https://github.com/microsoft/fluentui/tree/master/packages/api-docs) (formerly `@uifabric/api-docs`) to generate documentation which shows up in the [Controls section](https://developer.microsoft.com/en-us/fluentui#/controls/web) of our website as well as in the legacy demo app at [aka.ms/fluentdemo](http://aka.ms/fluentdemo).
### How can I make sure my APIs are being documented?
The `@fluentui/api-docs` package relies on the inline TSDoc tag `{@docCategory PageName}` to understand which types should be documented on the website and which page they should show up on, where `PageName` is the actual name of the page.
For example, if you wanted `ISliderProps` to show up on the 'Slider' page, it would look like the following ([see it live here](https://developer.microsoft.com/en-us/fabric#/controls/web/slider#ISliderProps)):
```tsx
/**
* {@docCategory Slider}
*/
export interface ISliderProps {
```
This should work automatically for `@fluentui/react` and the packages it consumes. If the API is in a newer package, you should check [this file](https://github.com/microsoft/fluentui/blob/master/packages/api-docs/config/api-docs.js) to verify that the package is included (and add it if not).
If the `docCategory` doesn't match any of the known component page names, it will be put under the References section in the sidebar.
### More details about the `@fluentui/api-docs` package
The `@fluentui/api-docs` (previously `@uifabric/api-docs`) package takes the api.json files generated by [API Extractor](API-Extractor) and splits them up into individual page.json files to populate both component pages and (new) references pages. These page.json files live in `@fluentui/api-docs`.
Generally, this tool is used on `@fluentui/react` and its dependencies (`@fluentui/react-northstar` uses a different approach). You can see or update the full list of included packages in [this file](https://github.com/microsoft/fluentui/blob/master/packages/api-docs/config/api-docs.js).
### How does the `@fluentui/api-docs` package know how to split up the APIs into page.json files?
The package relies on the following inline tag to determine the right place for an API: `{@docCategory PageName}`. By including this tag in your [TSDoc comment](https://api-extractor.com/pages/tsdoc/doc_comment_syntax/), where `PageName` is the API reference page where you want your API to live, you'll see your API documented on the Fluent UI website.
For example, if you wanted `ISliderProps` to show up on the 'Slider' page, it would look like the following:
```tsx
/**
* Props for Slider
* {@docCategory Slider}
*/
export interface ISliderProps extends React.ClassAttributes<SliderBase> {
```
You can see how this looks on the Fluent UI website [here](https://developer.microsoft.com/en-us/fabric#/controls/web/slider#ISliderProps).
### How can I make sure my APIs are being documented?
In `@fluentui/react` and the packages it consumes, generally as long as you include the `{@docCategory}` inline tag, you should see your API documented on the Fluent UI website!
If the API is in a newer package, you should check [this file](https://github.com/microsoft/fluentui/blob/master/packages/api-docs/config/api-docs.js) to verify that the package is included (and add it if not).

@ -3,26 +3,26 @@
We highly recommend using Webpack 4+. If you use Webpack 4 or Rollup.js, you can take advantage of tree-shaking to create smaller bundles. This allows you to imports the parts you need in a natural way:
```typescript
import { Button } from 'office-ui-fabric-react';
import { Button } from '@fluentui/react'; // or office-ui-fabric-react in earlier versions
```
This import will include the Button, plus the dependent modules. It should not include any modules that are unrelated.
## For Webpack < 4 or Browserify
If you are using a non-tree-shaking bundler, you may accrue larger bundle sizes by importing from the package entry point `office-ui-fabric-react`. By default bundlers will include every module referenced from that entry point, even if you don't use them.
If you are using a non-tree-shaking bundler, you may accrue larger bundle sizes by importing from the package entry point `@fluentui/react` (or `office-ui-fabric-react` in earlier versions). By default bundlers will include every module referenced from that entry point, even if you don't use them.
To address this friction, we also offer "top level imports" which help scope the graph to only the component and its dependencies.
```typescript
import { Button } from 'office-ui-fabric-react/lib/Button';
import { Dropdown } from 'office-ui-fabric-react/lib/Dropdown';
import { List } from 'office-ui-fabric-react/lib/List';
import { Button } from '@fluentui/react/lib/Button';
import { Dropdown } from '@fluentui/react/lib/Dropdown';
import { List } from '@fluentui/react/lib/List';
```
For a full list of top level imports, see the source here:
https://github.com/OfficeDev/office-ui-fabric-react/tree/master/packages/office-ui-fabric-react/src
https://github.com/microsoft/fluentui/tree/master/packages/@fluentui/react/src
## Using an AMD bundler like r.js

@ -1,3 +1,5 @@
**WARNING: Many of the general ideas on this page still apply to `@fluentui/react` 7/8 (and `office-ui-fabric-react` previously), but some of the details may be out of date or are specific to class components (which are no longer recommended).** Until updated guidance is finalized, please talk to the team or file an issue to learn about current best practices if you'd like to add a new component.
## Basic expectations for every component
- The component can always provide `id`, `className`, `style`, `aria-*` and `data-*` attributes on the container of a component.
@ -12,7 +14,7 @@ utility so that we can let the user use native functionality as expected.
## Build many smaller components and compose them together.
Often we want to build something complex, like a CommandBar. We see a picture of what we want and we build one giant component that does
this. Then we find other scenarios that have overlaps. The CommandBar contains a SearchBox, a set of left side collapsable links and right
this. Then we find other scenarios that have overlaps. The CommandBar contains a SearchBox, a set of left side collapsible links and right
side links. We may find we have other cases that just want a set of links, without the extra overhead. We may also find cases where we just
want a single command bar item with a dropdown menu.
@ -21,16 +23,11 @@ together. While it may be more effort to think in smaller blocks, it makes the c
## Use a .types.ts file to extract out the public contracts that should be supported and documented.
A props file contains all of the interface contracts that the user should know about to use the component. It is the "contract" for the component. When we evaluate semversioning, we look through the changes at Props files to determine if the change is a major, minor, or
patch.
A types file contains all of the interface contracts that the user should know about to use the component. It is the "contract" for the component. When we evaluate semantic versioning, we look through the changes to the types files to determine if the change is a major, minor, or patch.
The props files are also auto documented. All JSDoc comments will be extracted and shown on the demo site for documentation.
If your component exposes public methods/properties (or an imperative handle for function components), define an interface for the component in the types file and implement the interface.
When your component exposes public methods/properties, define an interface for the component in the props file and implement the interface.
The auto documentation will interpret the I{Component} interface as the class contract and show it in the documentation as the class
definition.
```typescript
```tsx
interface IButton {
/**
* Sets focus to the button element.
@ -42,7 +39,7 @@ interface IButton {
### Provide explicit return types for methods declared in .types.ts
Bad:
```typescript
```tsx
interface IButton {
/**
* Sets focus to the button element.
@ -52,7 +49,7 @@ interface IButton {
```
Good: explicitly specify the return type of `focus`:
```typescript
```tsx
interface IButton {
/**
* Sets focus to the button element.
@ -63,7 +60,7 @@ interface IButton {
## Naming guidance
### Flags(Booleans)
### Flags (Booleans)
Property flags should be as consistent as possible with given html guidelines.
@ -101,8 +98,7 @@ name. Always use present tense verbs instead of past tense.
|inputClick, onClickInput|onInputClick|
It should also be noted that for event callbacks, the ORDER of parameters should be consistent with the precisdence if one exists. For
example:
It should also be noted that for event callbacks, the ORDER of parameters should be consistent with the precedence if one exists. For example:
|BAD|GOOD|
|---|----|
@ -119,74 +115,70 @@ BAD:
GOOD:
`onRenderItem: IRenderFunction<IItemProps>`
## Use arrow function properties to avoid ALL binds in templates
## Use arrow function properties to avoid ALL binds
When we use bind in a template, it means that the function is recreated every time, which is an anti-pattern.
When we use `bind`, it means that the function is recreated every time, which is an anti-pattern.
BAD:
```typescript
class Foo {
public _onClick(ev: React.MouseEvent) {
```tsx
class Foo extends React.Component {
public render() {
return <button onClick={this._onClick.bind(this)}>Click me</button>
}
render() {
<button onClick={this._onClick.bind(this)}>Click me</button
private _onClick(ev: React.MouseEvent) {
}
}
```
Instead we can use an arrow function property as it will always be bound to the component.
GOOD:
```typescript
class Foo {
public _onClick = (ev: React.MouseEvent) => {
```tsx
class Foo extends React.Component {
public render() {
return <button onClick={this._onClick}>Click me</button>
}
render() {
<button onClick={this._onClick}>Click me</button
private _onClick = (ev: React.MouseEvent) => {
}
}
```
## For gathering refs, avoid string refs, use resolve functions
## For gathering refs, use `React.createRef`
Facebook has deprecated the use of string refs. Plus, string refs don't play very well with some scenarios like in Layered content, where
the content may be asynchronously rendered. The recommendation is to use functions to resolve refs. These functions must be pre-bound to
String refs are deprecated. Don't use them. Also don't use inline-created functions.
Bad:
```typescript
public render() {
return <div ref='root' />
```tsx
class Foo extends React.Component {
public render() {
return <div ref='root' />
}
}
```
Bad:
```typescript
public render() {
return <div ref={ (el) => this._root = el } />
```tsx
class Foo extends React.Component {
public render() {
return <div ref={ (el) => this._root = el } />
}
}
```
Good:
The `createRef` function in `lib/Utilities` is a polyfill for [React.createRef](https://reactjs.org/docs/refs-and-the-dom.html#creating-refs). (When Fabric switches over to React 16, we'll use React.createRef instead)
`React.createRef` creates a reference object that has the following type `{ current: T | null }`, where T is the element to reference (either a dom node or a react component). You set the reference by passing the reference object as the `ref` prop. You can then subsequently access the reference through the `.current` property on the reference object elsewhere in your code.
`createRef` creates a reference object that has the following type `{ current: T | null }`, where T is the element to reference (either a dom node or a react component). You set the reference by passing the reference object as the `ref` prop. You can then subsequently access the reference through the `.current` property on the reference object elsewhere in your code.
```typescript
import { createRef } from 'office-ui-fabric-react/lib/Utilities';
class Foo extends BaseComponent<...> {
```tsx
class Foo extends React.Component {
// Create the reference object that will be used for setting and accessing the reference
private _root = createRef<HTMLButtonElement>();
private _root = React.createRef<HTMLButtonElement>();
public render(): JSX.Element {
// Set the reference by passing the reference object as the ref prop
return <button ref={ _root } onClick={this._onClick} />;
return <button ref={_root} onClick={this._onClick} />;
}
private _onClick(): void {
@ -197,22 +189,24 @@ class Foo extends BaseComponent<...> {
```
Note that it's very critical you do NOT inline the functions in render! This causes weird side effects, because the function
is recreated. If you do this, react will call your function with null to clear it, and then render, and then once complete, will
is recreated. If you do this, React will call your function with null to clear it, and then render, and then once complete, will
call it again with the element. This creates timing issues where your ref may be null when you didn't expect.
## Use unique keys for items in a mapped array, avoid indexes for keys
## Use unique keys for items in a mapped array, avoid indices for keys
```typescript
public render() {
return (
<div>
{ this.props.items.map((item, index)=> (
<div key={ item.key }>
<input type="text" />
</div>
)) }
</div>
);
```tsx
class Foo extends React.Component {
public render() {
return (
<div>
{this.props.items.map((item, index)=> (
<div key={item.key}>
<input type="text" />
</div>
))}
</div>
);
}
}
```
@ -232,7 +226,7 @@ that your data has ids so that you can use that as a unique identifier for rende
When we do inline mapped entries, we want to inline the content in the map:
Bad:
```typescript
```tsx
class Foo extends React.Component {
public render() {
return (
@ -247,7 +241,7 @@ class Foo extends React.Component {
```
Better:
```typescript
```tsx
class Foo extends React.Component {
public render() {
return (
@ -260,17 +254,15 @@ class Foo extends React.Component {
}
}
class ItemComponent extends React.Component<...> {
let { item } = this.props;
render() {
class ItemComponent extends React.Component {
public render() {
let { item } = this.props;
return (
<div onClick={ this._onClick }>{ item.name }</div>
);
}
_onClick = (ev: MouseEvent) => {
private _onClick = (ev: MouseEvent) => {
}
}
```
@ -279,9 +271,7 @@ class ItemComponent extends React.Component<...> {
Some components allow users to override the root DOM element that is rendered by the component. Our `<Link />` component is one of these. The user can provide an `as` prop to specify the root element.
When designing your components you can chose to allow the user to do the same.
Your component should render a _default_ element but render the component passed through the `as` prop instead when it is provided. An example of such a component could be.
When designing components you can choose to allow the user to do the same. The component should render a particular element by default but render the component passed through the `as` prop instead when it is provided. For example:
```tsx
function MyLink({ as = 'a', text = 'Hello' }) {
@ -291,28 +281,6 @@ function MyLink({ as = 'a', text = 'Hello' }) {
}
```
## Extend from BaseComponent instead of React.Component in most cases.
In the common folder, there exists a BaseComponent class. For simple components, it may be unnecessary to use.
If you extend this, you get a few useful utilities:
_events: An instance of the EventGroup, scoped to the component. It will auto dispose on component unmounting so that you don't forget.
_async: A collection of utilities for performing async operations, scoped to the component. This includes setTimeout/setInterval helpers as
well as utilities for generating throttled/debounced wrappers. Again, anything you use here will be automatically cleaned up on unmounting.
_disposables: An array of IDisposable instances. If you have things you want disposed, you can push them into this.
Another interesting thing is that when exceptions occur within React's methods, things tend to silently fail. With the BaseComponent, we
make all methods "safe" meaning that if an exception occurs, we send the exception to a global callback which can be hooked up to a
telemetry post. By default however, we forward the exception to `console.error` with the exact class/method that threw the exception so
that there is an obvious hint what went wrong.
There are some cases where it may be overkill to subclass from this; a simple Button wrapper for example really doesn't need to be more
than a simple stateless component and doesn't need extra imports, which would result in making Button's dependency graph heavier. Use your
best judgement.
## Use React eventing, unless you need to use native.
Be aware that React eventing and DOM eventing are two different systems. They do not play well with each other. DOM event handlers will
@ -323,13 +291,11 @@ Unfortunately there are plenty of scenarios where we must mix the two systems to
application-wide clicks that bubble up to window in order to implement a light-dismiss behavior. Or perhaps you need to listen for window
resizes. Or maybe you need to observe scroll events so that you can hide/show something.
We use the EventGroup object for abstracting native eventing. It is simple to use; there is an "on" method and an "off" method that wrap
calling addEventListener in modern browsers (or attachEvent in legacy IE.) Again if you're using the BaseComponent, it is already available
to you via the _events property.
One abstraction we use for native eventing is the EventGroup class. It is simple to use; there is an "on" method and an "off" method that wrap calling addEventListener in modern browsers (or attachEvent in legacy IE). Be sure to dispose the EventGroup instance on unmount.
## Root elements should have a component class name.
Every component's root element should have a ms-Component class name. Additinally the user should be able to provide their own className
Every component's root element should have a ms-Component class name. Additionally the user should be able to provide their own className
via prop that should be added to the class list of the root element.
If specific component elements need special classnames injected, add more classNames to props.
@ -351,22 +317,19 @@ reasons:
Data and state should always follow the lifetime of the component that owns it. When that component is no longer needed, the state should
be garbage collected, event handlers should be removed, and xhr requires spawned in that context should be cancelled.
There are cases where everything should share a common instance of a store; Persona presence is a great example. We have solutions that
enable the code within a component scope to access shared stores. See store usage section below.
## Use const values global to a file, rather than as static members
Don't use public/private statics, use file scope.
Bad:
```typescript
```tsx
class Foo {
private static DEFAULT_DELAY = 300;
}
```
Good:
```typescript
```tsx
const DEFAULT_DELAY = 300;
class Foo {
@ -379,9 +342,8 @@ that if you export it, minify won't touch exports.
## Use private members only for managing state local to a component that should not affect rendering when mutating
Bad:
```typescript
```tsx
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = {
@ -402,7 +364,7 @@ class Foo extends React.Component {
```
Good:
```typescript
```tsx
class Foo extends React.Component {
private _isMounted: boolean;
@ -428,22 +390,22 @@ may be used to store the object reference.
## Use component state only for managing local state that is private to a component that should trigger re-render on mutation
Bad:
```typescript
```tsx
class Foo extends React.Component {
private _fooRocks: boolean;
render() {
return <div onClick={ this._onClick }>{ `Foo ${ this._fooRocks ? 'rocks' : 'rolls' }</div>;
return <div onClick={this._onClick}>Foo {this._fooRocks ? 'rocks' : 'rolls'}</div>;
}
private _onClick(): void {
private _onClick = (): void => {
this._fooRocks = !this._fooRocks;
this.forceUpdate();
}
```
Good:
```typescript
```tsx
class Foo extends React.Component {
constructor() {
super(props);
@ -454,91 +416,16 @@ class Foo extends React.Component {
}
render() {
return <div onClick={ this._onClick }>{ `Foo ${ this.state.fooRocks ? 'rocks' : 'rolls' }</div>;
return <div onClick={this._onClick}>Foo {this._fooRocks ? 'rocks' : 'rolls'}</div>;
}
private _onClick(): void {
private _onClick = (): void => {
this.setState({
fooRocks: !this.state.fooRocks
});
}
```
## Experimental: Use a store for storing shared state within a component hierarchy which must be shared across objects
While React state management is very useful for simple, private state, it becomes unwieldy when many things share that state
and you start ending up with many owners of the same state value. In these cases it may drive you towards a flux solution, but
before we jump there, lets call out a few things.
* Global singletons are code smell, do not use globals or singletons except for very rare cases
* Do not store complex shared state directly in the components, this is also code smell
Instead, make a store and wire dumb components together the store.
What is a store?
Think of a store as a self aware observable; it maintains state, and provides read/write access to that state. When its state
changes, it can emit change events causing components to re-evaluate.
Here's an example store which tracks selection:
```typescript
class SimpleSelectionStore extends BaseStore {
private _selectedKey: string;
public isSelected(key: string) {
return key === this._selectedKey;
}
public setSelected(key: string) {
if (this._selectedKey !== key) {
this._selectedKey = key;
this.emitChange();
}
}
}
```
While we do not want globals, we do want simplified access to the stores available in a given component scope.
You can use the StoreHost component to host stores within any given scope:
```typescript
const stores = {
selection: new SimpleSelectionStore()
};
public render() {
return (
<StoreHost stores={ stores }>
<UIContent />
</StoreHost>
);
}
```
You can write dumb components:
```typescript
const Item = (props) => (
<div onClick={ props.onClick }>{ `I am item ${ props.name } and I'm ${ props.isSelected ? 'selected' : 'unselected' }</div>
);
```
And you can use the `connect` function to create a ConnectedItem which wraps the dumb component and translates the props
and stores in its context into props for the dumb component:
```typescript
export ConnectedItem = connect(Item, (stores, props) => ({
name: props.item.name,
isSelected: stores.selection.isSelected(props.item.key),
onClick: () => stores.selection.setSelected(props.item.key)
}));
```
Now in this setup, your state is in one place, it is composable and can have lifetime, and your dumb ui has no understanding
of the contextual stores provided.
# CSS class name guidelines
TODO: include our class name guidelines.
@ -573,14 +460,6 @@ html[dir=rtl] .ms-Foo {
Additionally try to have symmetrical paddings rather than using padding-right or left specifics.
## Do not use core fabric classnames, but instead use core fabric scss mixins.
## Do not use Fabric Core classnames, but instead use Fabric Core SCSS mixins.
E.g. using ms-font-s classname in a component is forbidden. It makes overriding CSS rules really painful. Instead, use @include ms-font-m;
# Example page guidelines
Examples should follow a naming convention: Component.Desc.Example.ts
The root of the test component should use ms-ComponentDescExample as the root class.
Examples should not re-define component styles.

@ -1,21 +1,20 @@
This guide outlines recommendations for deprecating API behavior, particularly related to component props.
An example PR following these steps can be found here:
**https://github.com/OfficeDev/office-ui-fabric-react/pull/4811**
**https://github.com/microsoft/fluentui/pull/4811**
## Deprecation Steps
1. Ensure snapshot tests exist covering existing props functionality as a reference check against deprecation changes.
- The props you're deprecating should have representation in the snapshot output. Sometimes this may require getting the component under test into a certain state.
1. Keep the tests using deprecated props named in a file with deprecated suffix, such as `Persona.test.tsx` -> `Persona.deprecated.test.tsx`.
1. Keep the tests using deprecated props named in a file with deprecated suffix, such as `PersonaCoin.test.tsx` -> `PersonaCoin.deprecated.test.tsx`.
1. Copy the test's snapshot output (or ensure it's the same if regenerated.)
1. Modify existing tests to use new prop.
- Snapshot output should be identical in most cases, particularly if props naming is the only thing changing.
1. Add new property to interface.
1. Optionally, temporarily comment out old prop to help find all uses throughout code base and change. Take care that as of writing some uses are not covered by TypeScript as part of build, such as some objects created in tests without type declaration and Screener tests in `apps/vr-tests`.
- If you use VS Code, there is a task available to help aid called `Typescript (vr-tests) watch` which you can run via `Tasks -> Run Task`. You may have to rebuild occasionally to get the types reflected across packages correctly.
1. Optionally, temporarily comment out old prop to help find all uses throughout code base and change. (Some usage will be caught by the deprecation lint rule, but not in all cases.)
1. Update components that consume property as needed to support both deprecated and new props.
- Be sure to consider other components that both use and extend the modified interface. If a component needed a change, there's a good chance it will also need to continue supporting the deprecated prop and should also have deprecated tests.
1. Move deprecated prop to end of interface, update comments with deprecation description and add @deprecated.
1. Move deprecated prop to end of interface, update comments with deprecation description and add `@deprecated`.
```tsx
/**
@ -26,33 +25,31 @@ An example PR following these steps can be found here:
```
1. Make sure old and new tests pass.
1. Add call to warnDeprecations in constructor, like:
1. Add call to `warnDeprecations` in constructor, like:
```tsx
constructor(props: IPersonaCoinProps) {
super(props);
// 'primaryText' is deprecated and 'text' should be used instead
this._warnDeprecations({ 'primaryText': 'text' });
warnDeprecations('PersonaCoin', props, { 'primaryText': 'text' });
}
```
1. warnDeprecations will most likely cause deprecated tests to fail, requiring mocking of warnDeprecations. Please make note to clear mock at end of tests as shown below.
1. warnDeprecations will most likely cause deprecated tests to fail. Override the warning callback as follows:
```tsx
// Import statement for office-ui-fabric-react v5.X and earlier:
import * as WarnUtil from '@uifabric/utilities/lib/warn';
// or @fluentui/utilities in 8+
import { setWarningCallback } from '@uifabric/utilities';
// Import statement for office-ui-fabric-react v6.0 and later:
import * as WarnUtil from '@uifabric/utilities/lib-commonjs/warn';
describe('MyTests', () => {
describe('PersonaCoint', () => {
beforeAll(() => {
// Prevent warn deprecations from failing test
jest.spyOn(WarnUtil, 'warnDeprecations').mockImplementation(() => { /** no impl **/ });
const noOp = () => undefined;
setWarningCallback(noOp);
});
afterAll(() => {
jest.restoreAllMocks();
setWarningCallback();
});
// tests ...

@ -1,3 +1,5 @@
(This page is generally up to date for `@fluentui/react` and related version 7/8 packages as of October 2020.)
## Overview
Our tests are built using [Jest](https://facebook.github.io/jest/). This allows us to run tests in a node environment, and simulates the browser using jsdom.
@ -10,25 +12,28 @@ Visual regression testing uses [Storybook](https://storybook.js.org/basics/intro
## Running tests
In command prompt navigate to the appropriate package, for example `packages/office-ui-fabric-react`
Our Jest setup generally require that packages be built before testing, so before running tests the first time, you should run `yarn buildto my-package` from the repo root.
To just validate everything works, run `npm run build`, which will build the project including running tslint and jest for tests.
To run the tests for one package, `cd` to that package and then run `yarn test`.
If you *only* want to run jest, you can also do that as shown in [Build Commands](Build-Commands).
(You can also run tests for the whole repo by running `yarn test` at the repo root. This will also build beforehand if needed.)
## Running tests in watch mode
When you are developing tests, use the watch mode to run the tests as you write them!
1. Go to the package folder where you want to run the tests.
2. Type `npm run start-test`.
2. Type `yarn start-test`.
3. Edit and saving tests should now cause the console to re-run the tests you have added/modified.
### Debugging
To debug tests, you can use Visual Studio Code. Inside of a `*.test.ts` file, add a `debugger` statement where you want to break, and hit F5 to start debugging.
To debug tests, you can use Visual Studio Code.
1. Set breakpoints in the test file (`*.test.ts` or `*.test.tsx`)
2. Open the **Run** (debugger) pane in the sidebar and choose the configuration you want: usually "Debug current open test" to run only the current open test, or "Debug test" to run all tests for the package the current file is in
3. Start debugging
Note: Because of limitations with the current Node LTS version, breakpoints in VSCode will not hit until you're actively in the debugger using `debugger` statement. The latest Node version however has fixes that will enable breakpoints to resolve, so this workaround is temporary.
(As of fall 2020, if the debugger isn't hitting breakpoints or otherwise is not working properly, try opening VS Code user settings and setting `debug.javascript.usePreview` to false.)
## Writing tests
@ -50,7 +55,7 @@ Note that you do not need to import the assertions or the Jest APIs; they should
Jest enables you to create snapshot tests. Snapshots simply compare a JSON object with an expected output. The assertion `toMatchSnapshot` api will abstract loading a .snap file for the test to compare, or will create one if none exists.
```typescript
```tsx
import * as React from 'react';
import { CommandBar } from './CommandBar';
import * as renderer from 'react-test-renderer';
@ -69,13 +74,13 @@ describe('CommandBar', () => {
});
```
If you ever break a snapshot, you can update all baselines either manually, or using the `yarn update-snapshots` command within a given package folder. Currently the `office-ui-fabric-react` and `experiments` packages both have snapshot testing enabled.
If you ever break a snapshot, you can update all baselines either manually, or using the `yarn update-snapshots` command within a given package folder.
### Functional testing
In cases where you need to automate a component and validate it performs correctly, you can use [Enzyme](http://airbnb.io/enzyme/) apis to mount components, evaluate dom structure, and simulate events.
```jsx
```tsx
it('opens a menu with IContextualMenuItem.subMenuProps.items property', () => {
const commandBar = mount<CommandBar>(
<CommandBar
@ -107,11 +112,11 @@ In cases where you need to automate a component and validate it performs correct
### Visual regression testing
[Storybook](https://storybook.js.org/basics/introduction/) is a dev environment for UI components. We write 'stories' to capture different states of components. With every pull request, the stories are rendered by Screener to check for any visual changes. Screener posts a status to Github PRs where you can view the visual test report. If changes are found, the status will fail on Github until the regressions are fixed or an admin approves the changes. You can also validate with Screener locally by running `npm run screener:local` from `./apps/vr-tests`.
[Storybook](https://storybook.js.org/basics/introduction/) is a dev environment for UI components. We write "stories" to capture different states of components. With every pull request, the stories are rendered by [Screener](https://screener.io/) to check for any visual changes. Screener posts a status to Github PRs where you can view the visual test report. If changes are found, the status will fail on Github until the regressions are fixed or an admin approves the changes. You can also validate with Screener locally by running `yarn screener:local` from `./apps/vr-tests`.
Stories are found at `./apps/vr-tests/src/stories`. Most stories are written with a `FabricDecorator` that wraps the components with consistent padding. [Screener](https://github.com/screener-io/screener-storybook) steps are added to crop to a specific CSS class (most stories should crop to the `.testWrapper` class of the `FabricDecorator`) and to simulate different events, such as `hover` and `click`.
```jsx
```tsx
import * as React from 'react';
import Screener, { Steps } from 'screener-storybook/src/screener';
import { storiesOf } from '@storybook/react';
@ -142,7 +147,7 @@ storiesOf('Link', module)
Certain components may be written with a custom decorator/wrapper, and you may crop to a different CSS class or omit the `cropTo` option altogether. Components that render outside its container, require specific styles on its parent, or render on a different layer, such as Callout, are cases where you would customize the decorators.
```jsx
```tsx
storiesOf('Slider', module)
.addDecorator(story => (
// Vertical slider requires its parent to have a height specified
@ -176,7 +181,7 @@ storiesOf('Slider', module)
```
The `addStory` method can be used to add stories with additional configuration options. Currently, `addStory` supports an optional flag that allows the story to run twice: once in left-to-right mode and once in right-to-left mode (using Fabric's `setRTL` method to render the story in the correct mode).
```jsx
```tsx
storiesOf('Panel', module)
.addDecorator(FabricDecorator)
.addDecorator(story => <Screener steps={new Screener.Steps().snapshot('default').end()}>{story()}</Screener>)
@ -189,13 +194,14 @@ storiesOf('Panel', module)
```
### Test Utilities & Helpers
#### shallowUntilTarget Function
Enzyme has a method called Shallow Rendering that allows you to constrain yourself to testing a component as a unit, and to ensure that your tests aren't indirectly asserting on behavior of child components. If you would like to know more about Shallow Rendering in general then you can view the main Enzyme documentation [here](http://airbnb.io/enzyme/docs/api/shallow.html).
The `shallowUntilTarget()` function is a work around due to a conflict with decorated components, and considering at the time of writing this we are planning to use the **@customizable** decorater on all Fabric components it is likely that the built into Enzyme `shallow()` function will not yield the correct results because it's being applied to the customized component.
```jsx
```tsx
it('renders the result of onRenderData', () => {
const initialData = { content: 5 };
const renderedDataId = 'onRenderDataId';
@ -215,11 +221,11 @@ it('renders the result of onRenderData', () => {
For example above you expect shallow to return a ShallowWrapper of **ResizeGroup** but actually it will return a ShallowWrapper of **ComponentWithInjectedProps** - the customized component returned from the **@customizable** decorator function. **ResizeGroup** is a child of the customized component. `shallowUntilTarget()` will allow you so specify which component you want to target for your test using a string - in this case we want **'ResizeGroupBase'** because the same effect happens to components using the `styled` function.
We just need to import the function from the common folder.
```jsx
```tsx
import { shallowUntilTarget } from '../../common/shallowUntilTarget';
```
Usage is exactly the same as shallow with an added argument containing a string name of target component.
```jsx
```tsx
it('renders the result of onRenderData', () => {
const initialData = { content: 5 };
const renderedDataId = 'onRenderDataId';
@ -241,7 +247,7 @@ it('renders the result of onRenderData', () => {
*Q. Browser methods aren't working.*
A. Using browser methods like getBoundingClientRect won't work when using enzyme to render a document fragment. It's possible to mock this method out if you need, see the `FocusZone` unit tests as an example.
A. Using browser methods like `getBoundingClientRect` won't work when using enzyme to render a document fragment. It's possible to mock this method out if needed; see the `FocusZone` unit tests as an example.
*Q. My event isn't being triggered.*

@ -1,9 +1,10 @@
By default, the Fabric icons are not added to your bundle, in order to save bytes for scenarios where you don't care about icons, or you only care about a subset.
By default, the Fluent UI icons are not added to your bundle, in order to save bytes for scenarios where you don't care about icons, or you only care about a subset.
To make them available, you may initialize them as such:
```tsx
import { initializeIcons } from 'office-ui-fabric-react/lib/Icons';
// Also available from @uifabric/icons (7 and earlier) and @fluentui/font-icons-mdl2 (8+)
import { initializeIcons } from '@fluentui/react/lib/Icons';
initializeIcons(/* optional base url */);
```
@ -12,13 +13,13 @@ initializeIcons(/* optional base url */);
By default, the icon fonts for the default set of icons will be pulled from the SharePoint CDN. The default endpoint is `spoprod-a.akamaihd.net`, but if you run into access/security issues from the Akamai domain, you can also pass in `https://static2.sharepointonline.com/files/fabric/assets/icons/` as the `baseUrl`.
If you would like the icons to be served from your own CDN, simply copy the files from `@uifabric/icons/fonts` to your CDN. A build step is recommended to automate this. Then, in `initializeIcons`, provide the base URL to access those fonts. Note that it will require a trailing slash.
If you would like the icons to be served from your own CDN, simply copy the files from `@uifabric/icons/fonts` (or `@fluentui/font-icons-mdl2/fonts` in version 8+) to your CDN. A build step is recommended to automate this. Then, in `initializeIcons`, provide the base URL to access those fonts. Note that it will require a trailing slash.
(If you're using custom icons as described under "Registering custom icons" below, you don't need to modify the CDN setting.)
### Fabric icons
### Creating an icon subset
The Fabric Icons tool, https://aka.ms/uifabric-icons, lets you search and browse all of Fabric's icons. You can also use it to create and maintain subsets of the icon font to use in your web apps, which are drop-in replacements for the default Fabric Core and Fabric React icon sets. In addition, the Fabric Icons tool is updated with new icons several times a month, whereas the default Fabric set is updated only occasionally. You can see detailed docs for the tool at https://aka.ms/uifabric-icons?help.
The Fabric Icons tool, https://aka.ms/uifabric-icons, lets you search and browse all of Fabric/Fluent UI's MDL2 icons. You can also use it to create and maintain subsets of the icon font to use in your web apps, which are drop-in replacements for the default Fabric Core and Fluent UI React icon sets. In addition, the Fabric Icons tool is updated with new icons several times a month, whereas the default Fluent UI React set is updated only occasionally. You can see detailed docs for the tool at https://aka.ms/uifabric-icons?help.
Note that if you use the Fabric icons tool to create your own icon subset, you will also need to host those assets on your own CDN.
@ -28,14 +29,14 @@ It registers a map of icon names, which define how to render icons. Icons can be
What we're trying to optimize here is download size. We define a map of icon codes which map to a font-face. When the `Icon` component renders the `Upload` icon, we determine if the font-face has yet been registered, an if not, we add it to the page, causing the subset containing the `Upload` icon to be downloaded.
The `@uifabric/icons` packages can resolve over 1000 different icons, and will download from the 10+ font partitions, minimizing download overhead. We also include the most common icons in the first partition, optimizing for the basic scenarios. If there are commonly used icons missing in there, please file an issue so that we can evaluate adjusting the primary partition.
The `@uifabric/icons` package (or `@fluentui/font-icons-mdl2` in version 8+) can resolve over 1000 different icons, and will download from the 10+ font partitions, minimizing download overhead. We also include the most common icons in the first partition, optimizing for the basic scenarios. If there are commonly used icons missing in there, please file an issue so that we can evaluate adjusting the primary partition.
### Registering custom icons
If you want to use a different icon font or SVG icons, such as [Font Awesome](https://fontawesome.com/), you can use `registerIcons` to add custom icons.
```tsx
import { registerIcons } from '@uifabric/styling';
import { registerIcons } from '@fluentui/react/lib/Styling';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faFilter } from '@fortawesome/free-solid-svg-icons';
@ -49,14 +50,14 @@ registerIcons({
You can then use those icons anywhere you'd normally use icons, such as the `Icon` component or in `iconProps`:
```tsx
import { Button } from 'office-ui-fabric-react/lib/Button';
import { Icon } from '@fluentui/react/lib/Icon';
const IconTest = () => <Button iconProps={{ iconName: 'Home' }} />
const IconTest = () => <Icon iconName="Home" />
```
You can also use this with custom font families:
```tsx
import { registerIcons } from '@uifabric/styling';
import { registerIcons } from '@fluentui/react/lib/Styling';
registerIcons({
fontFace: {
@ -73,12 +74,12 @@ registerIcons({
When icons are rendered using the `Icon` component, but have not yet been registered, you will see console errors indicating so. In most cases, this can be addressed by registering the icons. But there are 2 cases, where this isn't desirable:
**Test scenarios**
### Test scenarios
In test scenarios, you may want to simply disable the warnings and avoid registering icons. To do this:
```tsx
import { setIconOptions } from 'office-ui-fabric-react/lib/Styling';
import { setIconOptions } from '@fluentui/react/lib/Styling';
// Suppress icon warnings.
setIconOptions({
@ -86,12 +87,12 @@ setIconOptions({
});
```
**Library icon registration**
### Library icon registration
If your code is running in an environment where icons may have already been registered, you may need to disable the warnings. (By default, registering the same icon twice will ignore subsequent registrations.) To initialize icons and avoid duplication warnings, pass options into `initializeIcons`:
```tsx
import { initializeIcons } from '@uifabric/icons';
import { initializeIcons } from '@fluentui/react/lib/Icons';
initializeIcons(undefined, { disableWarnings: true });
```

@ -1,96 +1,30 @@
# Fabric markdown documentation
Use markdown syntax to create jsx, that can be edited in GitHub (Link to edit in doc sections coming soon).
# Fluent UI React markdown documentation
## Overview
Component example pages can import markdown files (using Webpack's [raw-loader](https://github.com/webpack-contrib/raw-loader)) as a `string`, which can then be used as a child to the component `PageMarkdown`. These markdown files can then be edited from GitHub. This requires a commit and a Pull Request to master. Once merged, the changes to the MD files will render on the docs.
Pages in the Fluent UI React [documentation site](https://developer.microsoft.com/en-us/fluentui) can import markdown files (using Webpack's [raw-loader](https://github.com/webpack-contrib/raw-loader)) as a `string`, which can then be passed as a child to the `Markdown` component from `@uifabric/example-app-base` (`@fluentui/react-docsite-components` in version 8+). These markdown files can be edited from GitHub (using a commit and a pull request). Once merged, the changes to the MD files will render on the website.
Currently, these are the sections that use markdown on each example page:
- Overview
- Best Practices
- Best Practices - Do
- Best Practices - Don't
All other sections are currently generated with React code.
Many of the sections on the website pages, such as component overviews and best practices, are rendered from markdown files. Since text in markdown files is much easier to read, edit, and format than text in TSX, we recommend using a markdown file for each page section unless it needs more complex content which can't be represented with built-in markdown syntax. (The [markdown renderer](https://www.npmjs.com/package/markdown-to-jsx) we use has extremely limited support for custom HTML within markdown files.)
## Usage
Make your markdown file, preferably inside a docs folder. Then you can use that in the example page.
The pattern for where to locate markdown files and where to add references varies; the best way to figure it out is to either look for a similar existing page (and follow that pattern) or ask a team member.
```tsx
import * as React from 'react';
import {
ComponentPage,
PageMarkdown
} from '@uifabric/example-app-base';
export class YourComponentPage {
render() {
return (
<ComponentPage
title='YourComponent'
componentName='YourComponent'
// Link to the component root on GitHub
componentUrl='https://github.com/OfficeDev/office-ui-fabric-react/tree/master/packages/office-ui-fabric-react/src/components/YourComponent'
overview={
<PageMarkdown>
{/* Import your markdown file with raw-loader like so: */}
{ require<string>('!raw-loader!office-ui-fabric-react/src/components/YourComponent/docs/YourComponentOverview.md') }
</PageMarkdown>
}
/>
);
}
}
```
The [GetStartedPage](https://github.com/microsoft/fluentui/tree/master/apps/public-docsite/src/pages/Overviews/GetStartedPage) and [LocalizationPage](https://github.com/microsoft/fluentui/tree/master/apps/public-docsite/src/pages/Styles/LocalizationPage) provide decent examples of some simple and slightly more complex scenarios.
## Images
### Hosted images
Images on the website are hosted on a CDN. Contact a team member for more information about how to get new images added.
The easiest way to inline an image is to host your image and get the URL. Then you can use standard markdown to render an image inline. The image uses Fabric's Image component. 👍
Once an image is on a CDN, you can reference it like this:
Example:
`![image](https://media.giphy.com/media/111ebonMs90YLu/giphy.gif)`
`![image](https://some/url/here/img.jpg)`
Outputs:
`<img alt="image" src="https://media.giphy.com/media/111ebonMs90YLu/giphy.gif" class="foo-Image-generatedClassNames">`
Rendered:
![image](https://media.giphy.com/media/111ebonMs90YLu/giphy.gif)
### Local images
Internal images (hosted within the repository) need specific syntax to render, and have to be defined within the `<PageMarkdown>` component `resources` prop. The `resources` prop accepts an object of `images`. Specify your image import in the `src` attribute.
```tsx
<PageMarkdown
resources={{
images: {
// [key: string]: IImageProps;
ImageInParagraph: { src: require('./images/YourComponentImageFoo.png'), width: 800 },
Image1: { src: require('./images/YourComponentImage1.png'), width: 500 },
Image2: { src: require('./images/YourComponentImage2.png'), width: 500 },
}
}}
>
{ YourComponentOverview }
</PageMarkdown>
```
Images can then be used in a paragraph or an unordered list like so:
```md
image: ImageInParagraph
* image: Image1
* image: Image2
```
`<img alt="image" src="https://some/url/here/img.jpg">`
## Default overrides
@ -98,26 +32,14 @@ When using HTML in your markdown, some tags are automatically replaced by pre-st
Tag | Component | Notes
--- | --- | ---
h1 | PageHeader |
h2 | PageHeader | as h2
h3 | PageHeader | as h3
code | PageTag | Also works on backtick code blocks.
````tsx` | SyntaxHighlighter | Code fences display code blocks with syntax highlighting.
p | PageParagraph |
a | Link |
ul | | Renders list of internal images if `image:` is found
img | Image |
button | DefaultButton | You can pass DefaultButton's top level props such as `primary`
`h1` | `MarkdownHeader` |
`h2` | `MarkdownHeader` | as h2
`h3` | `MarkdownHeader` | as h3
`code` | `MarkdownCode` | Also works on backtick code blocks.
````tsx` | `SyntaxHighlighter` | Code fences display code blocks with syntax highlighting.
`p` | `MarkdownParagraph` |
`a` | `MarkdownLink` |
`img` | `MarkdownImage` |
`button` | `DefaultButton` | You can pass `DefaultButton`'s top-level props such as `primary`
## Roadblocks
- GitHub doesn't allow you to paste an image from the clipboard to upload to the GitHub CDN from an MD edit page, unlike the comment box.
- Comments in markdown need to have HTML syntax
- Multiline comments not currently possible, use HTML comment tags on each new line of your comments
## What's to come
- Investigate using Cloudinary or similar API to enable simple image hosting.
- Investigate adding WYSIWYG to fabric documentation.
Note that [`markdown-to-jsx`](https://www.npmjs.com/package/markdown-to-jsx) which we use for rendering markdown has extremely limited support for custom HTML: for example, it can't render nested HTML tags. If you need more complex formatting, you'll need to write that section in a TSX file instead.

@ -1,4 +1,4 @@
[A PR in early 2020](https://github.com/OfficeDev/office-ui-fabric-react/pull/11574) introduced some important changes to Fabric's build commands which are detailed below. [The Build Command documentation](Build-Commands) has been updated to reflect these changes.
[A PR in early 2020](https://github.com/microsoft/fluentui/pull/11574) introduced some important changes to Fabric's build commands which are detailed below. [The Build Command documentation](Build-Commands) has been updated to reflect these changes.
| Monorepo Build Command | Prereqs | Important Notes | Description |
| ---------------------- | ------- | -------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |

@ -169,7 +169,7 @@ To focus on a single file, you can include a filename pattern in the command to
### `yarn just`
Fabric uses the [`just`](https://github.com/kenotron/just-task) build system. All build, test, and lint tasks are defined as `just` tasks. These tasks are sequenced in parallel and series in a deterministic way according to the definition inside the project's `just-task.js`.
Fluent UI uses the [`just`](https://github.com/kenotron/just-task) build system. All build, test, and lint tasks are defined as `just` tasks. These tasks are sequenced in parallel and series in a deterministic way according to the definition inside the project's `just.config.ts`.
To run only an individual task, you can use `yarn just`. Some (non-comprehensive) examples:
- `yarn just ts`
@ -177,4 +177,4 @@ To run only an individual task, you can use `yarn just`. Some (non-comprehensive
- `yarn just lint`
- `yarn just jest`
Open the project's `just.config.js` and/or the repo-wide `scripts/just.config.js` to see the available task names.
Open the project's `just.config.ts` and/or the repo-wide `scripts/just.config.ts` to see the available task names.

@ -1,7 +1,5 @@
# Basic usage
In the root of a repo that relies on Office-ui-fabric-react simply run
`npx @fluentui/codemods` and the upgrade will begin automatically based on your tsconfig.json files!
If your repo is especially large and you experience an out of memory error run
In the root of a repo that relies on `office-ui-fabric-react`, simply run `npx @fluentui/codemods` and the upgrade will begin automatically based on your tsconfig.json files!
`npx @fluentui/codemods -s` to save synchronously which, while slower, will ensure that it completes!
If your repo is especially large and you experience an out of memory error, run `npx @fluentui/codemods -s` to save synchronously which, while slower, will ensure that it completes!

@ -1,3 +1,5 @@
**WARNING: This page describes an older way of structuring components in `@fluentui/react` 7/8 (and `office-ui-fabric-react` previously). As of late 2020, many existing components still use this structure, but new components should not.** Until updated guidance is finalized, please talk to the team (or file an issue) about what pattern to use if you'd like to add a new component.
A component should consist of these files:
* [`ComponentName.types.ts`](#componentnametypests) - The interfaces for the component. We separate these out for documentation reasons.
@ -82,7 +84,7 @@ const getClassNames = classNameFunction<IComponentNameStyleProps, IComponentName
/**
* ComponentName with no default styles.
* [Use the `styles` API to add your own styles.](https://github.com/OfficeDev/office-ui-fabric-react/wiki/Styling)
* [Use the `styles` API to add your own styles.](https://github.com/microsoft/fluentui/wiki/Styling)
*/
export class ComponentName extends React.Component<...> {
public render() {

@ -1,63 +0,0 @@
| Name | Has State? | Needs State? | Props/State Mismatch? | Controlled? | Uncontrolled? | Sample | Notes |
|-------------------|----------------|-------------------------|-----------------------|--------------|---------------|-----------------------------------------------------|----------------------------------------------|
| ActivityItem | No | No | No | | | | |
| Announced | No | No | No | | | | |
| Autofill | Yes (exported) | Yes | Yes | | | https://codepen.io/jdh-msft/pen/qvMjzJ?editors=0111 | Several abnormal params as well. |
| Breadcrumb | No | No | No | | | https://codesandbox.io/s/483l979yox | |
| Button | No* | No* | No* | | | | /OK in rewrite/ |
| Calendar | Yes (exported) | Yes | No | | | https://codepen.io/jdh-msft/pen/NJLvgj?editors=0011 | |
| Callout | Yes (exported) | Maybe | No | | | https://codepen.io/jdh-msft/pen/rRZzrQ?editors=0111 | /Cannot get to render correctly in codepen./ |
| Checkbox | Yes (exported) | Yes (in uncontrolled) | No | | | | |
| ChoiceGroup | Yes (exported) | Yes (in uncontrolled) | No | | | | |
| Coachmark | Yes (exported) | Yes | No | | | | /Some ambiguity around lifecycle/ |
| ColorPicker | | | | | | | |
| ComboBox | Yes (exported) | Yes | Yes | | | https://codepen.io/jdh-msft/pen/rRqwYM?editors=0011 | |
| CommandBar | No | No | No | | | | |
| ContextualMenu | Yes (exported) | Yes | No | | | | |
| DatePicker | Yes (exported) | Yes | No | | | | |
| DetailsList | Yes (exported) | Yes | | | | | |
| Dialog | No | No | No | | | | |
| Divider | No | No | No | | | | |
| DocumentCard | Yes (exported) | Maybe (debounce resize) | No | | | | |
| Dropdown | Yes (exported) | Yes | No | | | | |
| ExtendedPicker | | | | | | | |
| Fabric | Yes | Yes | No | No | Yes | | /Deprecating/ |
| Facepile | No | No | No | | | | |
| FloatingPicker | Yes | Yes | No | | | | |
| FocusTrapZone | | | | | | | |
| FocusZone | | | | | | | |
| GroupedList | Yes (exported) | Yes | PROPS ARE MODIFIED! | | | https://codepen.io/jdh-msft/pen/eXPEXj | |
| HoverCard | Yes (exported) | Yes | No | | | | |
| Icon | Yes (exported) | Yes | No | | | | |
| Image | Yes | Yes | No | Yes | No | | |
| Keytip | | | | | | | |
| Label | | | | | | | |
| Layer | No | No | No | Yes | No | | |
| Link | No | No | No | | | | |
| List | Yes | Maybe | No | Yes | No | | /State used for cache/ |
| MarqueeSelection | Yes (exported) | Yes | No | No | Yes | | |
| MessageBar | Yes (exported) | Yes | No | No | Yes | | truncated prop is confusing |
| Modal | Yes | Maybe | No | Yes | No | | |
| Nav | | | | | | | |
| OverflowSet | No | No | No | Yes | No | | |
| Overlay | No | No | No | Yes | No | | |
| Panel | Yes (exported) | Yes (Fewer) | Yes | | | https://codepen.io/jdh-msft/pen/Mxqbpd | |
| Persona | No | No | No | | | | |
| Pivot | Yes | Yes (uncontrolled) | No | Yes | Yes | | |
| ProgressIndicator | No | No | No | | | | |
| Rating | Yes | Yes (uncontrolled) | Yes | Yes (broken) | Yes | https://codepen.io/jdh-msft/pen/zXxJOK | |
| ResizeGroup | Yes (exported) | Yes | No | | | | |
| ScrollablePane | Yes (exported) | Yes | No | | | | |
| SearchBox | Yes | Yes | Yes | Yes (broken) | Yes | https://codepen.io/jdh-msft/pen/GLgBzd | |
| Shimmer | Yes | Yes | No | Yes | No | | |
| Slider | Yes | Yes (uncontrolled) | Yes | Yes (broken) | Yes | https://codepen.io/jdh-msft/pen/VNYBzp | |
| SpinButton | Yes | Yes (uncontrolled) | Yes | Yes (broken) | Yes | https://codepen.io/jdh-msft/pen/dLPjZN | |
| Spinner | No | No | No | Yes | No | | |
| Stack | No | No | No | Yes | No | | |
| Sticky | | | | | | | |
| SwatchColorPicker | Yes (exported) | Yes (uncontrolled) | Yes | No | Yes | https://codepen.io/jdh-msft/pen/wZBXzz | |
| TeachingBubble | Yes (exported) | No | No (state unused) | Yes | No | | |
| Text | No | No | No | | | | |
| TextField | Yes (exported) | Yes | Yes | Yes | Yes | https://codepen.io/jdh-msft/pen/NmPzZX | |
| Toggle | Yes (exported) | Yes (uncontrolled) | No | Yes | Yes | | |
| Tooltip | Yes (exported) | Yes | No | | | | |

@ -1,26 +1,27 @@
Fabric's recommended styling approach uses CSS-in-JS and revolves around the `styles` prop, which is provided by most Fabric components and allows strongly-typed customizations to individual areas of a component. This article explains how to customize existing styled components, write your own styled components, and convert an existing component which uses SCSS into a styled component.
**WARNING: This page describes an older way of handling component styles in `@fluentui/react` 7/8 (and `office-ui-fabric-react` previously). As of late 2020, many existing components still use this approach, but new components should not.** Until updated guidance is finalized, please talk to the team (or file an issue) about what pattern to use if you'd like to add a new component.
Fluent UI React's recommended styling approach uses CSS-in-JS and revolves around the `styles` prop, which is provided by most Fluent UI React components and allows strongly-typed customizations to individual areas of a component. This article explains how to customize existing styled components, write your own styled components, and convert an existing component which uses SCSS into a styled component.
If you'd like to customize colors and more for the whole app in one place, take a look at the [Theming](Theming) article instead.
- [Using a Styleable Component](#using-a-styleable-component)
- [Using a styleable component](#using-a-styleable-component)
* [`styles` prop](#-styles--prop)
* [Styling best practices](#styling-best-practices)
- [Creating a Styleable Component](#creating-a-styleable-component)
- [Creating a styleable component](#creating-a-styleable-component)
* [Component.types.ts](#componenttypests)
* [Component.base.ts](#componentbasets)
* [Component.ts](#componentts)
- [Moving styles from scss to ts](#moving-styles-from-scss-to-ts)
* [ClassNames logic](#classnames-logic)
* [mixins and includes](#mixins-and-includes)
- [Common Roadblocks](#common-roadblocks)
- [Common roadblocks](#common-roadblocks)
* [Applying a style set to a sub-component that already has a root style set](#applying-a-style-set-to-a-sub-component-that-already-has-a-root-style-set)
- [Footnotes](#footnotes)
* [Common Fabric Snippets](#common-fabric-snippets)
* [Motivations for moving away from SCSS](#motivations-for-moving-away-from-scss)
# Using a Styleable Component
# Using a styleable component
Unlike a `style` prop that only applies styles to the root component, the `styles` prop (provided by most Fabric components) allows you to control the styling of every part of a component: the root, the children, and even sub-components. You can use this for one-off component customizations, or you can create a brand new component with these custom styles. In fact, all of the variants in Fabric are just components built by passing in different values for `styles`.
Unlike a `style` prop that only applies styles to the root component, the `styles` prop (provided by most Fluent UI React components) allows you to control the styling of every part of a component: the root, the children, and even sub-components. You can use this for one-off component customizations, or you can create a brand new component with these custom styles. In fact, all of the variants in Fluent UI React are just components built by passing in different values for `styles`.
## `styles` prop
@ -62,10 +63,10 @@ const styles = {
background: theme.palette.themeSecondary,
},
'&.isExpanded': {
display: 'block'
display: 'block'
},
':hover .childElement': {
color: 'white'
color: 'white'
}
}
}
@ -76,7 +77,7 @@ const styles = {
return <Component styles={styles} ... />;
```
### Function-based Styling
### Function-based styling
The styling applied to each area may depend on the state of the component as well as the contextual theme settings. So you should also be able to define styles as a function of these inputs:
@ -173,10 +174,7 @@ Due to the values passed into the styling objects needing to be strings, and the
Use type-safe enums instead of the sass variables:
```ts
import {
FontSizes,
FontWeights,
} from 'office-ui-fabric-react/lib/Styling';
import { FontSizes, FontWeights } from '@fluentui/react/lib/Styling';
return ({
root: [
@ -225,7 +223,7 @@ return ({
# Creating a Styleable Component
# Creating a styleable component
## Component.types.ts
Our CSS-in-JS approach introduces two new types of interfaces to your types file, and adds a couple of props to IComponentProps:
@ -303,7 +301,7 @@ Our exported components are nothing more than base components with a default `st
The `styled` function is a public export, as are our base components. This means that you can create completely custom styled components that will be functionally identical to those coming from Fabric.
```tsx
import { styled } from 'office-ui-fabric-react/lib/Utilities';
import { styled } from '@fluentui/react/lib/Utilities';
import { IMyComponentProps, IMyComponentStyleProps, IMyComponentStyles } from './MyComponent.types';
import { styles } from './MyComponentVariant.styles';
@ -418,12 +416,10 @@ Here is what the resulting conversion should look like:
Sass mixins are simply an informal way of using functions. Translating them into actual javascript, where you can reuse and import/export them, is really easy.
If you find some fabric-core mixins are missing, consider adding them to the `@uifabric/styling` package if they are highly reusable. However keep in mind that the PLT1 (initial page load) bundle size WILL be affected, so do this sparingly only for very common things.
If you find some fabric-core mixins are missing, consider adding them to the `@fluentui/style-utilities` (`@uifabric/styling`) if they are highly reusable. However keep in mind that the initial page load bundle size WILL be affected, so do this sparingly only for very common things.
# Common Roadblocks
# Common roadblocks
## Applying a style set to a sub-component that already has a root style set
@ -434,7 +430,7 @@ When applying style sets in a component (e.g. Nav) to a sub-component (e.g. Acti
color: blue
}
```
The conflict happens because it's root style set would normally be applied to a class like **root-###**, but being applied as `link` inside the Nav component applies that style set to **link-###** class name. Styles applied using this `$` selector syntax do not render out. This is an open bug [here](https://github.com/OfficeDev/office-ui-fabric-react/issues/4138).
The conflict happens because it's root style set would normally be applied to a class like **root-###**, but being applied as `link` inside the Nav component applies that style set to **link-###** class name. Styles applied using this `$` selector syntax do not render out. This is an open bug [here](https://github.com/microsoft/fluentui/issues/4138).
Until then the only option is to use semantic classNames to target these elements.
@ -447,16 +443,6 @@ Until then the only option is to use semantic classNames to target these element
# Footnotes
## Common Fabric Snippets
There is a helpful VSCode extension containing snippets of commonly used Fabric and mergeStyles code here:
https://marketplace.visualstudio.com/items?itemName=jordanjanzen.office-ui-fabric-react-snippets.
You can also install it from the Extensions panel in VSCode.
The extension readme has instructions on how to use it, but the snippets do assume a few things so it's best to review after use and make sure to remove any unnecessary code or move it into the appropriate places.
## Motivations for moving away from SCSS
SCSS a build time process of expanding a high level css-like language into raw css. Our pipeline to load the raw css goes through a javascript conversion process and gets loaded on the page via a javascript library called `load-themed-styles`. Effectively, we have a complex build process which takes rules, converts them into JavaScript, and loads them dynamically.

@ -14,7 +14,7 @@ The Link component has the following default behavior
If for some reason the above does not fit your usecase you can chose to override by proving a HTML tag name or a React Component.
Lets say your application would require Links to be rendered as `<Route />` elements.
Lets say your application would require Links to be rendered as `<Route />` elements.
```jsx
import { Route } from './router'
@ -22,7 +22,7 @@ import { Route } from './router'
<Link as={Route} onClick={() => alert("Hello")} />
```
If your link has complex children that also require onClick you might run into trouble when Fabric renders a button as a child of a button. In that case you could override the HTML component of the parent by providing the `as` prop.
If your link has complex children that also require onClick you might run into trouble when Fluent UI React renders a button as a child of a button. In that case you could override the HTML component of the parent by providing the `as` prop.
```jsx
// Specify what to render by providing an HTML tag name
<Link as="div" onClick={() => alert("Hello")}>

@ -1,6 +1,6 @@
### Contribution license agreement
For pull requests affecting fewer than 15 lines of code, you will need to sign a [Contribution License Agreement (CLA)](https://cla.microsoft.com/) before your contribution can be incorporated. To complete the CLA, you will need to submit the request via the form and then electronically sign the CLA when you receive the email containing the link to the document.
For pull requests, you will need to sign a [Contribution License Agreement (CLA)](https://cla.microsoft.com/) before your contribution can be incorporated. To complete the CLA, you will need to submit the request via the form and then electronically sign the CLA when you receive the email containing the link to the document.
This needs to only be done once for any Microsoft open source project.

@ -1 +1 @@
Please see the [setup instructions page](https://github.com/OfficeDev/office-ui-fabric-react/wiki/Setup).
Please see the [setup instructions page](https://github.com/microsoft/fluentui/wiki/Setup).

@ -1,6 +1,8 @@
# Contributing a new component to Fluent UI React
**WARNING: This documentation is partially out of date as of Fluent UI React version 7/8. Until we have a chance to fully update this page, please file a ["new component" issue](https://github.com/microsoft/fluentui/issues/new?template=new_component.md) or [feature request](https://github.com/microsoft/fluentui/issues/new?template=feature_request.md) with an overview of your idea or reach out to the team internally for current guidance.**
**WARNING: As of Fluent UI React version 7/8, the general ideas on this page are still applicable, but the specific details may be out of date. Until we have a chance to fully update this page, please file a ["new component" issue](https://github.com/microsoft/fluentui/issues/new?template=new_component.md) or [feature request](https://github.com/microsoft/fluentui/issues/new?template=feature_request.md) with an overview of your idea or reach out to the team internally for current guidance.**
Microsoft employees can contact us on Teams via [Fluent Community](https://teams.microsoft.com/l/team/19%3ab207e5bce1cf40f0bcfbc6a60b8a7682%40thread.skype/conversations?groupId=ffe264f2-14d0-48b5-9384-64f808b81294&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47) "Design" or "Fluent UI React (Web)" channels.
## Components
Our components are a collection of small, independent, general-purpose UI components intended to be reused throughout an application.
@ -11,32 +13,32 @@ We have two main buckets for components, **Experimental** and **Fundamental**. T
### Questions to ask before starting to build a new component
#### Does the component already exist?
Before making the decision to design a new component, check to see if the pattern already exists within any current Microsoft design system including our [Adobe XD Toolkit](https://static2.sharepointonline.com/files/fabric/fabric-website/files/officeuifabric_v4.0.0.zip). Please feel free to open Github issues to clarify doubts.
Before making the decision to design a new component, check to see if the pattern already exists within any current Microsoft design system including our Figma toolkit *(public link needed)*. Please feel free to open Github issues to clarify doubts.
If you are a Microsoft employee please check the internal version of the [Adobe XD Toolkit (Microsoft Employees)](https://microsoft.sharepoint.com/teams/OfficeUIFabric97) or if you have more in depth questions regarding any Microsoft design system, please visit our internal Microsoft [Teams channel](https://teams.microsoft.com/l/channel/19%3a73a5dbc26c9a4d8d91264611995bbdbb%40thread.skype/Fabric%2520Design?groupId=ffe264f2-14d0-48b5-9384-64f808b81294&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47).
If you are a Microsoft employee please check the internal version of the Figma toolkit *(link needed)* or if you have more in depth questions regarding any Microsoft design system, please visit our internal Microsoft [Teams channel](https://teams.microsoft.com/l/channel/19%3ab743ef5589594c2e8a28b720003cb2ea%40thread.skype/Design?groupId=ffe264f2-14d0-48b5-9384-64f808b81294&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47).
#### Is the proposed component a variant of an existing component?
If the new component pattern you are proposing already exists, but varies slightly, then please consider creating a variant of the component. For example, if you were to create a new button that does one new thing for our exisiting button then we would suggest creating a variant off the original button, but containing the one additional feature. The **Button** component is a good example of this. It has multiple variants like the **ActionButton**, **PrimaryButton**, **CommandBarButton** each of which is a very small component in itself. They all use the **BaseButton** for the core implementation but apply specific variations.
If the new component pattern you are proposing already exists, but varies slightly, then please consider creating a variant of the component. For example, if you were to create a new button that does one new thing for our existing button then we would suggest creating a variant off the original button, but containing the one additional feature. The **Button** component is a good example of this. It has multiple variants like the **ActionButton**, **PrimaryButton**, **CommandBarButton** each of which is a very small component in itself. They all use the **BaseButton** for the core implementation but apply specific variations.
#### Should it be a shared component?
If its a new component request, does it add value at a broad level or is it a product-specific customization? Product-specific customizations should be stored in local product repos.
#### Does this pattern contain Microsoft Intellectual Property?
If the new component contains Microsoft Intellectual Property, it should be considered Internal and therefore all discussions around the component should __only__ happen internally or within our [Fabric Design Teams channel](https://teams.microsoft.com/l/channel/19%3a73a5dbc26c9a4d8d91264611995bbdbb%40thread.skype/Fabric%2520Design?groupId=ffe264f2-14d0-48b5-9384-64f808b81294&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47). If the component does not contain Microsoft Intellectual Property then this component can be discussed directly on GitHub in our [issues section](https://github.com/microsoft/fluentui/issues).
If the new component contains Microsoft Intellectual Property, it should be considered Internal and therefore all discussions around the component should __only__ happen internally or within our [Fluent Design Teams channel](https://teams.microsoft.com/l/channel/19%3ab743ef5589594c2e8a28b720003cb2ea%40thread.skype/Design?groupId=ffe264f2-14d0-48b5-9384-64f808b81294&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47). If the component does not contain Microsoft Intellectual Property then this component can be discussed directly on GitHub in our [issues section](https://github.com/microsoft/fluentui/issues).
### Create
Create a new component pattern or leverage an existing component and create a variant. Use our [Adobe XD Toolkit](https://static2.sharepointonline.com/files/fabric/fabric-website/files/officeuifabric_v4.0.0.zip) as a model for how we document component patterns in Fluent UI. We require that all components have detailed usage guidelines for developers and designers who want to integrate this pattern into their respective product/project. Component should be genericized before submission as much as possible leaving out product specific colors/customizations etc.
Create a new component pattern or leverage an existing component and create a variant. Use our Figma toolkit *(public link needed)* as a model for how we document component patterns in Fluent UI. We require that all components have detailed usage guidelines for developers and designers who want to integrate this pattern into their respective product/project. Component should be genericized before submission as much as possible leaving out product specific colors/customizations etc.
### Review and Socialize
Ask for design feedback within the Fluent UI community through our [FluentUI Design Teams channel](https://teams.microsoft.com/l/channel/19%3a73a5dbc26c9a4d8d91264611995bbdbb%40thread.skype/Fabric%2520Design?groupId=ffe264f2-14d0-48b5-9384-64f808b81294&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47). Or, schedule review with the HVC product team for review. Socialize the component in Fluent UI community so other teams have visibility. You can also post an issue on GitHub outlining the component request as long as it doesn't contain any Microsoft Intellectual Property.
Ask for design feedback within the Fluent UI community through our [FluentUI Design Teams channel](https://teams.microsoft.com/l/channel/19%3ab743ef5589594c2e8a28b720003cb2ea%40thread.skype/Design?groupId=ffe264f2-14d0-48b5-9384-64f808b81294&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47). Or, schedule review with the HVC product team for review. Socialize the component in Fluent UI community so other teams have visibility. You can also post an issue on GitHub outlining the component request as long as it doesn't contain any Microsoft Intellectual Property.
### Design Implementation
#### Request the component be added to our Fluent UI Adobe XD toolkit.
Submit Internal components to our [Fluent UI Design Teams channel](https://teams.microsoft.com/l/channel/19%3a73a5dbc26c9a4d8d91264611995bbdbb%40thread.skype/Fabric%2520Design?groupId=ffe264f2-14d0-48b5-9384-64f808b81294&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47) so a designer on our team can update our toolkit. External components can be submitted via GitHub in our [issue tracking](https://github.com/OfficeDev/office-ui-fabric-react/issues) section.
#### Request the component be added to our Fluent UI Figma toolkit.
Submit Internal components to our [Fluent UI Design Teams channel](https://teams.microsoft.com/l/channel/19%3ab743ef5589594c2e8a28b720003cb2ea%40thread.skype/Design?groupId=ffe264f2-14d0-48b5-9384-64f808b81294&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47) so a designer on our team can update our toolkit. External components can be submitted via GitHub in our [issue tracking](https://github.com/microsoft/fluentui/issues) section.
### Where does the code live for this component?
If the component has no Microsoft Intellectual Property then it belongs in our public project office-ui-fabric-react. If the component contains Microsoft Intellectual Property then it must live internally. Please reach out to our team for more information about our internal repository.
If the component has no Microsoft Intellectual Property then it belongs in our public project @fluentui/react. If the component contains Microsoft Intellectual Property then it must live internally. Please reach out to our team for more information about our internal repository.
### Component categorization and lifecycle
@ -48,24 +50,26 @@ Before you start coding up your component, it is important to understand the lif
* Once the component has been designed, developed and tested it can be deemed ready for promotion to the **Fundamental components** category. Please note, these components are widely used and changes can affect a lot of products.
* Once you feel your component is ready to be promoted to become a **Fundamental component**, please request for a review with a Fluent UI core members. From outside Microsoft, you can do this through a [GitHub issue](https://github.com/OfficeDev/office-ui-fabric-react/issues).
* Once you feel your component is ready to be promoted to become a **Fundamental component**, please request for a review with a Fluent UI core members. From outside Microsoft, you can do this through a [GitHub issue](https://github.com/microsoft/fluentui/issues).
* Once the review is complete, you should be able to promote your component to the **Fundamental components** category. That is a big milestone.
#### Experimental components
Experimental components are any new components that do not currently exist within our [Adobe XD Toolkit](https://static2.sharepointonline.com/files/fabric/fabric-website/files/officeuifabric_v4.0.0.zip). By default, our `create-component` script will place the component folder and files in `packages/experiments`. New components stay in the experimental phase until a Fluent UI core team member approves the migrations from Experimental to Fundamental. Experimental components are developed in the experiments project located in the `<root of project>packages/experiments` folder. We also view any components that were created as a prototype or proof of concept. Check out our [experiments checklist](Experimental-Component-Checklist) to learn more about the expectations we have of a component before a PR is created.
Experimental components are any new components that do not currently exist within our Figma toolkit *(link needed)*. By default, new components have historically gone under `packages/experiments` (this may change in the future). New components stay in the experimental phase until the Fluent UI core team approves the migrations from Experimental to Fundamental. Check out our [experiments checklist](Experimental-Component-Checklist) to learn more about the expectations we have of a component before a PR is created.
#### Fundamental components
Fundamental components are the official React representation of our [Adobe XD Toolkit](https://static2.sharepointonline.com/files/fabric/fabric-website/files/officeuifabric_v4.0.0.zip) and receive higher priority in respect to stabilization, bug fixes, accessibility and general design resourcing. Components __cannot__ be immediately added as a Fundamental type component as it will need a period of stabilization and API review. All components should always start off as Experimental. A good portion of the Fundamental components are currently integrated within some of our major products such as OneDrive, SharePoint and Outlook. Fundamental components are developed in the office-ui-fabric-react project in the `<root of project>/packages/office-ui-fabric-react` folder.
Fundamental components are the official React representation of our Figma toolkit *(link needed)* and receive higher priority in respect to stabilization, bug fixes, accessibility and general design resourcing. Components __cannot__ be immediately added as a Fundamental type component as it will need a period of stabilization and API review. All components should always start off as Experimental. A good portion of the Fundamental components are currently integrated within some of our major products such as OneDrive, SharePoint and Outlook.
Fundamental components have historically been developed in the `office-ui-fabric-react` package (now `@fluentui/react`), but we're moving towards a model of per-component packages such as `@fluentui/react-component-name` which are re-exported by `@fluentui/react`.
### Start coding your component
Follow [Component Anatomy](https://github.com/OfficeDev/office-ui-fabric-react/wiki/Component-Anatomy) for creating the component.
Moving forward from fall 2020, new components should be built on top of `@fluentui/react-compose`. Detailed guidance is still in progress as of writing.
### Unit tests and screener tests
For any new component you should think of adding **Unit tests**, **React functional tests** and **Screener tests** to prevent regressions.
For any new component you should think of adding **Unit tests**, **React functional tests** and **Screener tests** to prevent regressions. [More details here.](Testing)
### Code Owners
### Code owners
Add yourself to the [Code owners file](../.github/CODEOWNERS).
When you add a new component, add yourself to the [CODEOWNERS file](https://github.com/microsoft/fluentui/blob/master/.github/CODEOWNERS).

@ -1 +1 @@
Please see the [setup instructions page](https://github.com/OfficeDev/office-ui-fabric-react/wiki/Setup).
Please see the [setup instructions page](https://github.com/microsoft/fluentui/wiki/Setup).

@ -1,4 +1,4 @@
This document describes how to set up your development environment and contribute changes to the **fluentui** project. This document assumes basic working knowledge with Git and related tools. We are providing instructions specific to this project.
This document describes how to set up your development environment and contribute changes to the Fluent UI project. This document assumes basic working knowledge with Git and related tools. We are providing instructions specific to this project.
- [Basic setup](#basic-setup)
- [Development environment](#development-environment)
@ -18,7 +18,7 @@ This document describes how to set up your development environment and contribut
- Install [**Yarn 1**](https://classic.yarnpkg.com/) (not Yarn 2).
- the easiest way is to run `npm install -g yarn@1`
- Install **[Git](https://git-scm.com/)**.
- For code editing we like **[Visual Studio Code](https://code.visualstudio.com/)**
- For code editing we like **[Visual Studio Code](https://code.visualstudio.com/)** but any editor of your preference is fine.
- If you use VS Code, we recommend the **[Prettier plugin](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)**.
- For Git branch management, some team members like **[SourceTree](https://www.atlassian.com/software/sourcetree)** (others just use the command line or VS Code).
@ -30,7 +30,7 @@ Open a command line and run these:
* Run `npm -v` to check your npm version. If your version is below 6, run `npm install -g npm@6.x.x` (literal "x" characters here) to update it.
* Run `yarn -v` to check your yarn version. If it is below 1.15.0, run `npm install -g yarn@1.x.x` (literal "x" characters here) to update it. (Do not install Yarn 2.)
* Run `yarn -v` to check your yarn version. If it is below 1.15.0, run `npm install -g yarn@1.x.x` (literal "x" characters here) to update it. *(Do not install Yarn 2.)*
* Go to a folder and run `code .` to open the folder in VS Code. If you don't have VS Code in your path, you can open VS Code and press `F1` or `ctrl+shift+P` (`cmd+shift+P`), type `path`, and select the `Install 'code' command in PATH` option.
@ -38,7 +38,7 @@ Open a command line and run these:
## Building (without contributing)
If you do not wish to contribute changes, please follow the instructions on the [README](https://github.com/microsoft/fluentui#building-the-repo) page for how to clone and build the main repo. Else, keep reading.
If you do not wish to contribute changes, for `@fluentui/react` version 8 please follow the instructions on the [`@fluentui/react` README](https://github.com/microsoft/fluentui/blob/master/packages/react/README.md#building-the-repo) page for how to clone and build the main repo. Else, keep reading.
# Contributing changes
@ -69,7 +69,7 @@ We recommend setting up the following Git configuration. In the command line, ru
### Setting the upstream remote
Before starting to contribute changes, please set your upstream remote to the primary **office-ui-fabric-react** repository.
Before starting to contribute changes, please set your upstream remote to the primary **fluentui** repository.
When you initially run `git remote -v`, you should see only your fork (the "origin") in the output list.
@ -109,7 +109,7 @@ Create a branch from your fork for your code changes. If you prefer not to use G
### Building
Next, build the code.
Next, build the code.
```
cd fluentui
@ -117,12 +117,12 @@ yarn
yarn build
```
For all subsequent runs (unless you clean your repo) you can just run:
Generally for subsequent runs (unless you clean your repo) you can just run:
```
yarn start
```
After you've successfully built for the first time, start making your changes.
After you've successfully built for the first time, start making your changes.
[See this page for details about the development workflow.](Development-Workflow)

@ -123,7 +123,7 @@ If you're adjusting project dependencies, you may need to run `yarn` at the root
1. Create your branch on your fork
2. Push changes to it
3. **Important:** Run `yarn change` to create a changefile. 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.
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:
@ -165,27 +165,38 @@ When the major changes have been vetted and are final, we will coordinate a majo
### 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 means that major releases of one component don't require a major release of another unrelated one.
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 nightly builds
## See releases
https://uifabric.visualstudio.com/UI%20Fabric/_build?definitionId=104
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](https://github.com/microsoft/fluentui/releases).
## Getting help
1. Use the Microsoft 1ES extension:
https://docs.opensource.microsoft.com/tools/browser.html
#### Bugs
2. Be familiar with the CODEOWNERS list
https://github.com/microsoft/fluentui/blob/master/.github/CODEOWNERS
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](https://github.com/microsoft/fluentui/issues) and if you can't find one, [file a new issue](https://github.com/microsoft/fluentui/issues/new/choose). 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](https://github.com/microsoft/fluentui/issues/new/choose) or contact the team internally as described under "Questions."
#### Questions
Anyone can ask questions on [Stack Overflow](https://stackoverflow.com/questions/tagged/fluentui-react).
Microsoft employees can join [Fluent Community](https://teams.microsoft.com/l/channel/19%3a86b094239256467da9dfa96ba0897ca2%40thread.skype/Fluent%2520UI%2520React%2520(Web)?groupId=ffe264f2-14d0-48b5-9384-64f808b81294&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47) 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](https://docs.opensource.microsoft.com/tools/browser.html) to help map GitHub usernames to internal aliases
2. Be familiar with the [CODEOWNERS list](https://github.com/microsoft/fluentui/blob/master/.github/CODEOWNERS)
3. Use Teams chat to:
* Ping codeowners directly for help
* Ping the assigned owner for the issue/PR for help
* Ask the community for help
* Ping codeowners directly for help (please ask the community first unless urgent)
4. Not getting traction? Ask leads for help:
* React - Justin Slone (EM), Paul Gildea (PM)
* Web components - Chris Holt (EM)

@ -1,4 +1,4 @@
Fabric provides various options for customizing text fonts. For customizing icon fonts, [see this page instead](Using-icons).
Fluent UI React provides various options for customizing text fonts. For customizing icon fonts, [see this page instead](Using-icons).
[This codesandbox](https://codesandbox.io/s/customizing-fabric-icons-and-fonts-bveg8) has working examples of various font and icon customization methods.
@ -7,7 +7,7 @@ Fabric provides various options for customizing text fonts. For customizing icon
You can change the default text font using theming:
```ts
import { createTheme, } from '@fluentui/react';
import { createTheme } from '@fluentui/react';
const theme = createTheme({
// You can also modify certain other properties such as fontWeight if desired
@ -21,7 +21,7 @@ You can also target specific variants (small, medium, large, etc.) through the `
// Partial example of what can be done
const theme = createTheme({
defaultFontStyle: { fontFamily: 'Monaco, Menlo, Consolas', fontWeight: 'regular' },
fonts: {
fonts: {
small: {
fontSize: '11px'
},
@ -42,12 +42,12 @@ const theme = createTheme({
### Caveats
- This works in Fabric 7+ but not 5 or 6.
- This works in Fluent UI React (Fabric) 7+ but not 5 or 6.
- This does not prevent the Segoe `@font-face`s from being defined. In some browsers, this may mean the default font files are still loaded.
## Changing the CDN
By default, text fonts (such as Segoe) are loaded from `https://static2.sharepointonline.com/files/fabric/assets`.
By default, text fonts (such as Segoe) are loaded from `https://static2.sharepointonline.com/files/fabric/assets`.
To load the default text fonts from a different CDN, set the global variable `FabricConfig.fontBaseUrl`. The URL should **not** have a trailing slash.
@ -68,6 +68,6 @@ import { Button } from '@fluentui/react';
### Caveats
- Again: this global must be set **BEFORE** any Fabric code is imported or executed.
- The alternative CDN is assumed to follow the same file structure (relative to `fontBaseUrl`) as the default CDN.
- [#3881](https://github.com/OfficeDev/office-ui-fabric-react/issues/3881) tracks adding a way to change the CDN without a global.
- Again: this global must be set **BEFORE** any Fluent UI React code is imported or executed.
- The alternative CDN is assumed to follow the same file structure (relative to `fontBaseUrl`) as the default CDN.
- [#3881](https://github.com/microsoft/fluentui/issues/3881) tracks adding a way to change the CDN without a global.

@ -55,7 +55,7 @@ If this is your first change, below are some more detailed steps for getting you
Some of steps below include instructions specific to VS Code. It's fine to use another editor/IDE if you prefer, but we're providing instructions for VS Code because its automatic TypeScript integration and other features make it very convenient for Fluent UI React development.
### Open the repo
### Open the repo
To start, open the root folder of the repo in VS Code. You can do this by either `cd`ing to the folder and running `code .`, or opening VS Code and going to File > Open Folder. (You can also use another IDE or editor if you prefer.)
@ -64,7 +64,7 @@ To open files in VS Code, use the navigation sidebar or press `ctrl+P` (Mac: `cm
VS Code also has a built-in terminal. Press ``ctrl+` `` (Windows or Mac) to open it. (Using the built-in terminal isn't required, just convenient.)
### Create a branch
It's recommended to start with a fresh branch for each bug or task. If you have any lingering changes in your current branch that you want to save, go ahead and commit them. If you are just beginning, then you are good to go.
If you're familiar with Git/GitHub and have a preferred way to create branches, go ahead and use that. Otherwise, choose one of the options below.
@ -122,7 +122,7 @@ Alternatively, if you prefer not to re-compile on change, you can run `yarn buil
If you're making changes across multiple packages, you can either:
- `yarn start` and choose the "leaf" package (the one consuming the other packages) and `yarn build` in the other packages, OR
- From the root, `yarn buildto leaf-package-name`
### Verify your changes
#### Run package unit tests
@ -159,12 +159,12 @@ Go to the root folder of the repo and run the following, then address any failur
- If any API files (`*.api.md`) change, you should check them in.
- For `6.0`: run `npm run buildfast`
- If you get a message in a package about the API file being out of date, `cd` to that package and run `yarn update-api`.
### Commit your changes
Once you've made your change, or a subset of the change, you need to **commit** it to Git. A commit is a list of changes and a message describing them, plus other metadata. (Other terminology: In Git, files must be **staged** before committing, which just means telling Git which changes you'd like to commit now or leave for later.)
You can commit multiple times until you are ready to make a pull request. You should keep the message short since it will not be used in the release notes and is just for keeping track of the multiple commits in one pull request.
You can commit multiple times until you are ready to make a pull request. You should keep the message short since it will not be used in the release notes and is just for keeping track of the multiple commits in one pull request.
To commit files, choose one of the options below. (As usual, if you already have a different way you like to commit changes, that's fine too.)
@ -180,22 +180,22 @@ To commit files, choose one of the options below. (As usual, if you already have
1. `cd` to the root folder of the repo
2. Run `git status` to see the list of changed files
3. If you'd like to commit all the files, run `git add -A`. Otherwise, run `git add path/to/file-or-folder` to stage files individually.
4. Run `git commit -m "your message here"`
4. Run `git commit -m "your message here"`
#### Option 3: Sourcetree
In Sourcetree, click on commit in the top left. This won't actually do anything to your files, it will just change to show the commit UI. In the bottom container, stage all of the files you want to submit by selecting them and clicking "Stage". Add a short message in the textbox at the bottom on what is included in your change. This will not show as your entire submission text, just for this commit.
In Sourcetree, click on commit in the top left. This won't actually do anything to your files, it will just change to show the commit UI. In the bottom container, stage all of the files you want to submit by selecting them and clicking "Stage". Add a short message in the textbox at the bottom on what is included in your change. This will not show as your entire submission text, just for this commit.
### Create change files
Fluent UI React uses "change files" to figure out what type of release to make based on your changes (none, patch, minor, major) and generate a list of changes included in each release.
From the root of the repo, run `yarn change` (in 6: `npm run change`). This will prompt you to write a change description for each package.
From the root of the repo, run `yarn change` (in 6: `npm run change`). This will prompt you to write a change description for each package.
The change description will be used in the release notes, so it should include the name of the component (or utility etc) that you modified and a high-level summary of what you did.
See the [Change Files](Change-Files) page for more information about change files, including how to choose the appropriate change type.
### Push changes
Before making a pull request, you must push your branch to your fork on GitHub. Choose one of the methods below (or some other method you prefer).
@ -220,12 +220,12 @@ In Sourcetree click Push.
## Creating a pull request
Go to the [main Fluent UI React repo on GitHub](https://github.com/OfficeDev/office-ui-fabric-react). You should see a yellow bar at the top with your branch name and a button that says **Compare & Pull Request**. Click that button.
Go to the [main Fluent UI React repo on GitHub](https://github.com/microsoft/fluentui). You should see a yellow bar at the top with your branch name and a button that says **Compare & Pull Request**. Click that button.
> **NOTE:** If your change is based on the `7.0` or `6.0` branch, be sure to select that branch for the **base:** option instead of `master`. Otherwise your PR will have conflicts and lots of extra changes.
Fill out the fields with full description of your change, areas to test, and make sure you fill out the checklist when you have completed each item (add an `x` in between the `[]` at the top and make sure there are no spaces). If you are modifying the UI, this is also a good location to add screenshots of the before and after.
Fill out the fields with full description of your change, areas to test, and make sure you fill out the checklist when you have completed each item (add an `x` in between the `[]` at the top and make sure there are no spaces). If you are modifying the UI, this is also a good location to add screenshots of the before and after.
Click **Create Pull Request**, then watch it go through the process of running build checks and wait for reviews.
### Addressing check/build failures
@ -244,4 +244,4 @@ The most common errors are:
### Pull request reviews
Someone will review your change before the change is allowed to be merged in. They may ask questions for more information or ask you to change things. Be sure to respond to their comments and push additional changes to the branch if they ask you to modify things before they sign off. If no one has looked at it in a few days, you can ping whomever is on shield and ask them to take a look.
Someone will review your change before the change is allowed to be merged in. They may ask questions for more information or ask you to change things. Be sure to respond to their comments and push additional changes to the branch if they ask you to modify things before they sign off. If no one has looked at it in a few days, you can ping whomever is on shield and ask them to take a look.

@ -1,17 +1,19 @@
**WARNING: As of Fluent UI React version 7/8, the ideas on this page are generally correct, but we're in the process of developing new detailed guidance. Until we have a chance to fully update this page, please reach out to the team for current guidance.**
## Checklist before creating PR to experiments
* Validate file/package structure
* Validating the atomic-ness of the component
* Validating the atomic-ness of the component
* Is the component unique (is it already implemented elsewhere)
* Can it be broken down further
* Validating the api surface
* Does it have the basic expected props?
* Are there naming or typing inconsistencies?
* Is it hard to use or understand?
* Is it hard to use or understand?
* Is the documentation complete and clear?
* Are the prop descriptions consistent with other prop descriptions?
* Are the examples inspiring, delightful, useful, straightforward?
* Can you copy paste into a codepen?
* Can you copy paste into a codepen?
* Are the features robust enough to delight? (are we missing basic fundamentals?)

50
FAQ.md

@ -1,59 +1,55 @@
# [Office UI Fabric React FAQ](http://dev.office.com/fabric)
# Fluent UI React FAQ
## *Q. What is Office UI Fabric React?*
## *Q. What is Fluent UI React?*
Fabric React is a responsive, mobile-first, open-source collection of robust components designed to make it quick and simple for you to create web experiences using the `Office Design Language`.
Fluent UI React (formerly Fabric React) is a responsive, mobile-first, open-source collection of robust components designed to make it quick and simple for you to create web experiences using the Fluent design language.
## *Q. Who uses Office UI Fabric React?*
## *Q. Who uses Fluent UI React?*
React components from Office UI Fabric React are used by many teams accross O365 and Microsoft for building their experiences. Some examples are SharePoint, OneDrive, Outlook, VisualStudio team services, ...
React components from Fluent UI React are used by many teams across O365 and Microsoft for building their experiences. Some examples are SharePoint, OneDrive, Outlook, VisualStudio team services, ...
These components are also used by third party developers building extensiblity components using the SharePoint Framework.
These components are also used by third-party developers, in particular those building components using the SharePoint Framework.
## *Q. How do I get started with Office UI Fabric React?*
## *Q. How do I get started with Fluent UI React?*
Start with our [README](HOME) document.
To create your first app using Office UI Fabric React read the [Sample App](Sample-App) document.
Start from our [wiki homepage](Home) or the ["Get started" section](https://developer.microsoft.com/en-us/fluentui#/get-started/web) on our website.
## *Q. Where is the official website located?*
https://developer.microsoft.com/fabric
http://dev.office.com/fabric
https://developer.microsoft.com/fluentui
## *Q. I am seeing a bug. Where can I open an issue?*
Please open all issues at our [GitHub issues](https://github.com/OfficeDev/office-ui-fabric-react/issues) location.
Please open all issues at our [GitHub issues](https://github.com/microsoft/fluentui/issues) location.
Things to remember while opening an issue
Things to remember while opening an issue:
* Please fill out as many details as you can.
* We **highly encourage** you to submit PRs for issues.
## *Q. Can I contribute to Office UI Fabric React?*
## *Q. Can I contribute to Fluent UI React?*
Office UI Fabric React is an open-source distributed project. Lots of developers from inside and outside Microsoft contribute to this project. We highly encourage contributions. There is a core team that works hard to stay on top of the issues and pull requests.
Fluent UI React is an open-source distributed project. Lots of developers from inside and outside Microsoft contribute to this project. We highly encourage contributions. There is a core team that works hard to stay on top of the issues and pull requests.
## *Q. Why should I contribute?*
Office UI Fabric React is an open-source distributed project. If you are building a new app inside O365 or Microsoft, this project will potentially save you lots of time, resources and headaches. We encourage all developers who use Fabric React to return a small amount to the community. If you notice bugs, we encourage you to not only open an issue on it but also help fix it. If you have a component that you believe others should use, feel motivated and encouraged to contribute that component back to the community. Sharing is caring. Many developers contribute outside their primary job responsibilities. Additionally, there is plenty to learn. We use a lot of cutting edge best practices used in the industry. Learning those can help you in your career.
Fluent UI React is an open-source distributed project. If you are building a new app inside O365 or Microsoft, this project will potentially save you lots of time, resources and headaches. We encourage all developers who use Fluent UI React to return a small amount to the community. If you notice bugs, we encourage you to not only open an issue on it but also help fix it. If you have a component that you believe others should use, feel motivated and encouraged to contribute that component back to the community. Sharing is caring. Many developers contribute outside their primary job responsibilities. Additionally, there is plenty to learn. We use a lot of cutting edge best practices used in the industry. Learning those can help you in your career.
## *Q. How do I communicate with a Fabric React core team member?*
## *Q. How do I communicate with a Fluent UI React core team member?*
We have a very active community both outside and inside Microsoft. Please use the Microsoft [Teams channel](https://teams.microsoft.com/l/channel/19%3a73a5dbc26c9a4d8d91264611995bbdbb%40thread.skype/Fabric%2520Design?groupId=ffe264f2-14d0-48b5-9384-64f808b81294&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47) for communication from within Microsoft. And a [GitHub issue](https://github.com/OfficeDev/office-ui-fabric-react/issues) from outside Microsoft. We triage these issues at least once a week.
We have a very active community both outside and inside Microsoft. Please use the Microsoft [Teams channel](https://teams.microsoft.com/l/channel/19%3a86b094239256467da9dfa96ba0897ca2%40thread.skype/Fluent%2520UI%2520React%2520(Web)?groupId=ffe264f2-14d0-48b5-9384-64f808b81294&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47) for communication from within Microsoft. And a [GitHub issue](https://github.com/microsoft/fluentui/issues) from outside Microsoft. We triage these issues at least once a week.
## *Q. How do I contribute to Office UI Fabric React?*
## *Q. How do I contribute to Fluent UI React?*
Start by reading our [Contributing](Contributing) document. Please point out any missing or incorrect details.
## *Q. Can I become a part of the Fabric core team?*
## *Q. Can I become a part of the Fluent UI core team?*
Yes, you totally can. You will need to help out with reviewing pull requests and triaging and fixing issues. For now, only Microsoft employees can be a part of the core team. We are looking into changing that policy to allow non-Microsoft folks to be a part of the core team.
## *Q. My pull request has been hanging for a long time. What do I do?*
We are very proactive and work hard to keep the outstanding pull request count low. But if your pull request is non-trivial and stuck for a long time, please feel free to tag the pull request that it has been hanging for long and you need help.
We are very proactive and work hard to keep the outstanding pull request count low. But if your pull request is non-trivial and stuck for a long time, please feel free to tag the owners or contact them internally for help.
## *Q. Where do I read about specific best practices?*
@ -70,7 +66,7 @@ Please refer to the following documents.
## *Q. When and how does the issue Triage work?*
The Fabric React core team works hard to stay on top of the open issues. We have a team member assigned to "shield" each week to triage new issues as they come in.
The Fluent UI React core team works hard to stay on top of the open issues. We have a team member assigned to "shield" each week to triage new issues as they come in.
### Following issues will qualify as high priority
@ -83,6 +79,8 @@ Other bugs will qualify as Normal or lower priority and will get fixed as a part
From time to time we do plan to close issues that are very old and have no activity.
## *Q. Will there a UI Fabric React for Angular?*
## *Q. Will there a Fluent UI for Angular?*
A UI Fabric project for Angular is not currently on our roadmap. [UI Fabric Core](https://github.com/OfficeDev/office-ui-fabric-core) is a set of classes that give you access to our palette, typography and iconography, and can be used with any framework.
A Fluent UI project for Angular is not currently on our roadmap. However, we do have a new [web components package](https://aka.ms/fluentui-web-components) (`@fluentui/web-components`) in progress which can interoperate with Angular.
You can also use the [UI Fabric Core](https://github.com/OfficeDev/office-ui-fabric-core) CSS classes and SCSS variables/mixins for access to our palette, typography and iconography within any framework.

@ -1,8 +1,8 @@
Components in Fabric 7 use the Fluent theme by default, but you can also use the Fluent theme in Fabric 6.
Components in Fluent UI React (Fabric) 7+ use the Fluent theme by default, but you can also use the Fluent theme in Fabric 6.
The Fluent theme and component updates are included in the Fluent theme package:
```shell
```
npm install @uifabric/fluent-theme
```

@ -26,13 +26,15 @@ Some of these guidelines are enforced by TSLint rules, while others are just con
Use [JSDoc](http://usejsdoc.org/about-getting-started.html) comments for function, interfaces, enums, and classes. Be sure to include comments describing the item's functionality.
**Do not** include annotations in your doc comments which TS could infer from the context. These include:
In TS files, **do not** include annotations in your doc comments which TS could infer from the context. These include:
- Type annotations (example: `{string}` in `@param {string} foo`)
- Class-related tags: `@class`, `@member`, `@abstract`, `@extends`, `@constructor`, `@implements`, `@member`, `@memberof`, `@static`, `@protected`
- `@export`, `@exports`, `@async`, `@constant`, `@enum`, `@function`, `@interface`, `@readonly`, `@typedef`
- `@private` (using `@internal` is okay to indicate something which is exported from its file is not meant as a public API; not necessary to use on private class members)
- `@this`: outside a class, include `this: sometype` as the first parameter in the function signature (it won't be included at runtime but tells TS the type of `this`)
(Exception: If the file is in JS, please DO use the extra type annotations to help with maintainability! This mostly just applies to build scripts.)
### Use camelCase when naming objects, functions, and instances.
This applies regardless of whether the function is internal or exported.
@ -93,29 +95,11 @@ function _privateFunction() {
}
```
### Prefix interfaces (and sometimes types) with I
### Interface prefixing
TypeScript interfaces produce no code in the transpiled JavaScript output. This is an important distinction to understand and visualize, as we can alleviate bundle size increase concerns when they are used. Because of this, we prefix interfaces and interface-like types with I.
Historically we've prefixed all interface names (and sometimes type names) with `I`, for example `IPerson`. In newer code, we're dropping this prefix.
**Bad**
```ts
interface Person {
name: string;
age: number;
}
type Thing = Person;
```
**Good**
```ts
interface IPerson {
name: string;
age: number;
}
type IThing = IPerson;
```
Until all code is updated, please follow the convention for the package you're working in. This is enforced by lint rules.
### Avoid including the words Core, Utility, Common, or Helper in names

@ -10,51 +10,109 @@ React 16.8 added support for [hooks in function components](https://reactjs.org/
## Ref usage
React exposes a special `ref` prop for components. If you use `ref` on an intrinsic elements such as divs or spans, React will give you a reference to the element, allowing you access to the public API for the elements.
React exposes a special [`ref` prop](https://reactjs.org/docs/refs-and-the-dom.html) for components. Its behavior is different between intrinsic elements, class components, and function components:
- For **intrinsic/native elements** such as `<div>` or `<a>`, it returns a reference to the underlying HTML/DOM element object, allowing you access to its API.
- For **class components**, it exposes the class instance and its public API.
- For **function components**, it returns nothing by default, but Fluent UI components use [`React.forwardRef`](https://reactjs.org/docs/react-api.html#reactforwardref) to expose a reference to the component's root DOM element.
Using `ref` to access component public methods is more error prone:
1. If the component wraps itself in a higher order component or decorator, the `ref` will return the wrapper component rather than what you intended to access.
2. Accessing the full component's public methods is probably not desirable. It isn't exactly intended to access `public render` or to allow the consumer to call `componentWillUnmount`, despite these being publicly exposed to React.
Although it's possible to access a class component's public API using `ref`, we don't recommend this:
1. It will stop working if the component is converted to a function component
2. It's more error-prone:
* If the component wraps itself in a higher order component or decorator, the `ref` will return the wrapper component rather than what you intended to access.
* Accessing the full component's public methods is probably not desirable. It isn't exactly intended to access `public render` or to allow the consumer to call `componentWillUnmount`, despite these being publicly exposed to React.
### Consuming a component's public API
There ARE limited cases where a component should expose a public API contract. Usually, things can be more declarative in React, but some scenarios which are perhaps easier to do imperatively are:
There ARE limited cases where a component should expose a public API contract. It's recommended to do things declaratively in React, but there are some scenarios which are perhaps easier to do imperatively:
1. Exposing a `focus` method.
2. Accessing current values of uncontrolled prop values (such as the current value of a `TextField`.)
1. Exposing a `focus` method (or similar)
2. Accessing current values of uncontrolled prop values (such as the current value of a `TextField`)
In Fabric, we do the following for components which expose an imperative API surface:
In Fluent UI React, we do the following for components which expose an imperative API surface:
1. Define an `I{ComponentName}` interface which only exposes the methods intended to be supported.
2. Every component supports a `componentRef` prop, which will return the `I{ComponentName}` interface if provided.
2. Add a prop `componentRef?: IRefObject<IComponentName>`
So, use `componentRef` as a drop-in replacement for `ref`.
In the consuming code, you can create a ref with `React.createRef` (class components) or `React.useRef` (function components) and pass it as the `componentRef` prop.
Example usage of `componentRef` to access the `IButton` interface:
Example usage of `componentRef` to access the `ITextField` interface:
```tsx
private _primaryButton: IButton = React.createRef<IButton>();
const FooFunc: React.FunctionComponent = () => {
const textField = React.useRef<ITextField>();
public render() {
return <PrimaryButton componentRef={ this._primaryButton } ... />;
React.useEffect(() => {
textField.current.focus();
console.log(textField.current.value);
}, []);
return <TextField componentRef={textField} />;
}
public componentDidMount() {
this._primaryButton.value.focus();
class FooClass extends React.Component {
private _textField = React.createRef<ITextField>();
public render() {
return <TextField componentRef={this._textField} />;
}
public componentDidMount() {
this._textField.current.focus();
console.log(this._textField.current.value);
}
}
```
### Abstract resolving the componentRef
### Setting up the componentRef
Current recommended approach to automatically set up the componentRef is using `initializeComponentRef`.
This section is about how to set up `componentRef` for a new component, not how to use it.
```ts
import { initializeComponentRef } from 'office-ui-fabric-react/lib/Utilities';
For function component, use `useImperativeHandle`. (As a bonus, this example also shows how to use `forwardRef`.) For class components, use `initializeComponentRef`.
// inside the constructor
initializeComponentRef(this);
```tsx
import { IRefObject } from '@fluentui/react/lib/Utilities';
interface IFoo {
focus(): void;
otherMethod(): number;
readonly someValue: string;
}
interface IFooProps extends React.RefAttributes<HTMLDivElement> {
componentRef?: IRefObject<IFoo>;
}
const FooFunc: React.FunctionComponent<IFooProps> = React.forwardRef<HTMLDivElement, IFooProps> => {
React.useImperativeHandle(props.componentRef, () => ({
focus: () => /* do stuff to focus */,
otherMethod: () => /* do stuff */,
someValue: /* value here */
}));
return <div>...</div>;
}
import { initializeComponentRef } from '@fluentui/react/lib/Utilities';
class FooClass extends React.Component {
constructor(props) {
super(props);
// must be inside the constructor
initializeComponentRef(this);
}
public get someValue() {
// return value here
}
public focus() {
// do stuff to focus
}
public otherMethod() {
// do stuff
}
}
```
**We no longer recommend using BaseComponent due to its negative performance and bundle size implications.**

@ -8,15 +8,15 @@ Module and classes should only have a single purpose. It is a code smell when we
Having a single purpose makes the code more easily testable. Often complex classes which do many things will retain internal state that makes things difficult to mock or to cover every permutation.
### Be wary of your browser matrix (Fabric must support IE 11)
### Be wary of your browser matrix (Fluent UI React must support IE 11)
IE11 does not support most ES6+ features natively. The unsupported features fall into two categories: **APIs** which require polyfills and **must not** be used in published Fabric code, and **syntax** which TypeScript can transpile out.
IE11 does not support most ES6+ features natively. The unsupported features fall into two categories: **APIs** which require polyfills and **must not** be used in published Fluent UI React code, and **syntax** which TypeScript can transpile out.
(Exception: code which runs in a Node environment, primarily tests and build scripts, can use ES6+ features.)
#### APIs
Published Fabric code **must not** use ES6+ APIs which IE11 doesn't support, including (but not limited to) `[].find`, `WeakMap`, `IntersectionObserver`, `Promise`, `Object.assign`, and some features in `Map`. We do not provide polyfills and can't assume our consumers will do so.
Published Fluent UI React code **must not** use ES6+ APIs which IE11 doesn't support, including (but not limited to) `[].find`, `WeakMap`, `IntersectionObserver`, `Promise`, `Object.assign`, and some features in `Map`. We do not provide polyfills and can't assume our consumers will do so.
Some of these can fail type checking if you set your `lib` in `tsconfig.json` to `["es5", "dom"]` only.
@ -24,7 +24,7 @@ Some of these can fail type checking if you set your `lib` in `tsconfig.json` to
#### Syntax
IE11 also doesn't support certain ES6+ syntax, such as classes and async functions. However, these are **safe to use** in published Fabric code because TypeScript transpiles them down into ES5-compatible constructs.
IE11 also doesn't support certain ES6+ syntax, such as classes and async functions. However, these are **safe to use** in published Fluent UI React code because TypeScript transpiles them down into ES5-compatible constructs.
## React guidelines
@ -133,7 +133,7 @@ let list: Array<number> = [1, 2, 3];
### Use `for` or `for of` loops, especially in performance-sensitive code
Loops using `forEach` add function / closure allocation and add stack entries, which especially in legacy browsers can add overhead. Using `for of` will transpile into a transitional `for` loop which is proven to be slightly faster. Performance issues are death by a thousand papercuts, so be aware to adopt best practices and in bulk it makes a difference.
Loops using `forEach` add function / closure allocation and add stack entries, which especially in legacy browsers can add overhead. Using `for of` will transpile into a transitional `for` loop which is proven to be slightly faster. Performance issues are death by a thousand paper cuts, so be aware to adopt best practices and in bulk it makes a difference.
[Performance comparison of for vs forEach](https://hackernoon.com/javascript-performance-test-for-vs-for-each-vs-map-reduce-filter-find-32c1113f19d7)
@ -167,7 +167,7 @@ if (isValid) {
}
```
JavaScript treats all values as [truthy or falsey](https://www.sitepoint.com/javascript-truthy-falsy/). Everything is truthy, except the following six values which are falsey: `false`, `0`, `''` (empty string), `null`, `undefined`, `NaN`.
JavaScript treats all values as [truthy or falsy](https://www.sitepoint.com/javascript-truthy-falsy/). Everything is truthy, except the following six values which are falsy: `false`, `0`, `''` (empty string), `null`, `undefined`, `NaN`.
*With some caveats*, this allows a simpler conditional check syntax: `if (foo) { ... }`). This is okay to use if `foo` is an object and you'd like to check whether it's defined. However, **be careful with strings and numbers** if `0` or `''` is a valid value!
@ -229,7 +229,7 @@ for (let key of Object.keys(bar)) {
### Avoid default exports
We typically don't use default exports in Fabric. If you do want to export something as default, you should also export it as a named entity.
We typically don't use default exports in Fluent UI React. If you do want to export something as default, you should also export it as a named entity.
```js
// Good

@ -8,7 +8,7 @@ Fluent UI React is a collection of robust React-based components designed to mak
## Using Fluent UI React
For information about basics of using, building, and contributing to Fluent UI React, see the [README](https://github.com/microsoft/fluentui/blob/master/README.md#using-fabric-react).
For information about basics of using, building, and contributing to Fluent UI React, see the [README](https://github.com/microsoft/fluentui/blob/master/README.md).
For more detailed information, see the topics in the sidebar.

@ -1,6 +1,10 @@
Once you have defined the [`theme`](https://github.com/microsoft/fluentui/wiki/Theming) for your app, you need to apply the theme. Fluent UI React currently supports multiple ways of applying theme. Below is detailed guidance on the recommended and possible approaches.
### ThemeProvider (in preview)
- [ThemeProvider (in preview)](#themeprovider-in-preview)
- [loadTheme](#loadtheme)
- [Customizer (deprecated/legacy)](#customizer-deprecatedlegacy)
## ThemeProvider (in preview)
Starting in `@fluentui/react@8`, we've introduced a new component called `ThemeProvider`. It's designed to provide a contextual theme down to its child components. By default, it provides the Fluent theme. You can pass a partial or full theme you have created using `theme` prop. `ThemeProvider` will then merge it with the default (Fluent) theme and provide down to its children.
@ -45,7 +49,7 @@ export const App = () => (
<ThemeProvider theme={headerTheme}>
<MyHeader />
</ThemeProvider>
App content ...
</ThemeProvider>
);
@ -55,11 +59,11 @@ You can find more examples and supported props of `ThemeProvider` [here](https:/
`ThemeProvider` is supported with both version 7 and version 8 of Fluent UI react.
### loadTheme
## loadTheme
`loadTheme` is a way to provide a theme in global (and only global) scope, which will affect your entire application.
`loadTheme` is a way to provide a theme in global (and only global) scope, which will affect your entire application.
If you are `loadTheme` today, it's recommended to replace it with `ThemeProvider`. That way, your application consistently has one way of providing a theme.
If you are `loadTheme` today, it's recommended to replace it with `ThemeProvider`. That way, your application consistently has one way of providing a theme.
One caveat here is that if you app has styles which is authored in raw CSS which uses theming tokens and relies on `@microsoft/load-themed-styles`, `ThemeProvider` won't be able to replace `loadTheme` in this case without the need to re-write the styles. Only `loadTheme` calls `loadTheme` from `@microsoft/load-themed-styles` internally.
@ -86,6 +90,8 @@ export const App = () => (
);
```
### Customizer (deprecated/legacy)
## Customizer (deprecated/legacy)
Starting from `@fluentui/react@8`, `Customizer` is deprecated in favor of `ThemeProvider`. Compared to `ThemeProvider`, `Customizer` is not type-safe and does not support partial themes. For the sole purpose of providing and consuming a theme in your app, `ThemeProvider` is able to do everything `Customizer` can do today. You can learn more about how to replace `Customizer` with `ThemeProvider` [here](https://github.com/microsoft/fluentui/blob/master/packages/react-theme-provider/README.md#customizer).
Starting from `@fluentui/react` version 8, `Customizer` is deprecated in favor of `ThemeProvider`. Compared to `ThemeProvider`, `Customizer` is not type-safe and does not support partial themes. For the sole purpose of providing and consuming a theme in your app, `ThemeProvider` is able to do everything `Customizer` can do today. You can learn more about how to replace `Customizer` with `ThemeProvider` [here](https://github.com/microsoft/fluentui/blob/master/packages/react-theme-provider/README.md#customizer).
(If you're using `Customizer` for purposes besides theming, please let us know.)

@ -2,7 +2,7 @@
* Microsoft Edge & Narrator
## Other Configurations
Issues that do not reproduce in Edge & Narrator should be filed with the respective screen reading software, not the Fabric repo.
Issues that do not reproduce in Edge & Narrator should be filed with the respective screen reading software, not the Fluent UI repo.
## Troubleshooting
1. Check for duplicate issues! Many accessibility issues are reported multiple times. If they are caused by external factors such as screen reader issues they may take some time to resolve.
@ -11,7 +11,7 @@ Issues that do not reproduce in Edge & Narrator should be filed with the respect
1. [Accessibility Insights](https://github.com/microsoft/accessibility-insights-web/issues)
1. [Axe Core](https://github.com/dequelabs/axe-core/issues) (used by Accessibility Insights)
1. Find a reference example implementing the same [ARIA `role`](https://www.w3.org/TR/wai-aria-1.1/#role_definitions) and see if the reference exhibits the same behavior.
1. Find a reference example implementing the same [ARIA `role`](https://www.w3.org/TR/wai-aria-1.1/#role_definitions) and see if the reference exhibits the same behavior.
* Examples are usually found with a simple search of terms of "aria *role* example", such as ["aria grid example"](https://www.w3.org/TR/wai-aria-practices/examples/grid/dataGrids.html).
* Determine what `role` the component is using. This is most often accomplished by looking for `role` attribute value either in the source code or by inspecting the element's `role` attribute in a browser.
* The easiest way to find a reference is to search for `aria role x` or `aria attribute y` where `x` is the component role and `y` is the attribute name. For example searching `aria grid role` brings up some reference implementations for various grid implementations.
@ -22,7 +22,7 @@ Issues that do not reproduce in Edge & Narrator should be filed with the respect
* If the issue is reported against JAWS, NVDA, or another browser, the issue is with the screen reader or browser and should most likely be resolved as external.
* If the issue is reported against Microsoft Edge & Narrator, then continue trubleshooting below.
1. Verify ARIA is implemented by Fabric correctly. Note applicable references:
1. Verify ARIA is implemented by Fluent UI React correctly. Note applicable references:
* [ARIA Role Definitions](https://www.w3.org/TR/wai-aria-1.1/#role_definitions) for determining component attribute behavior by component's `role` attribute.
* [ARIA Attributes](https://www.w3.org/TR/wai-aria-1.1/#state_prop_def) for determining required attributes and correct attribute behavior.
* [ARIA Design Patterns](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_ex) for specifying component behavior, such as navigation behavior.
@ -34,9 +34,9 @@ Issues that do not reproduce in Edge & Narrator should be filed with the respect
### [No ARIA is better than bad ARIA.](https://www.w3.org/TR/wai-aria-practices-1.1/#no_aria_better_bad_aria)
Don't assume:
* That any missing ARIA attribute is required.
* That any missing ARIA attribute is required.
* That any ARIA is better than no ARIA.
* That the issue is with Fabric as opposed to MS Edge/Narrator/consuming app/third-party software.
* That the issue is with Fluent UI React as opposed to MS Edge/Narrator/consuming app/third-party software.
Before modifying ARIA roles, attributes or component navigation behavior, make sure you check the [ARIA Role Definitions](https://www.w3.org/TR/wai-aria-1.1/#role_definitions), [ARIA Attributes](https://www.w3.org/TR/wai-aria-1.1/#state_prop_def), and [ARIA Design Patterns](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_ex) to verify correct behavior.
@ -68,13 +68,13 @@ What can we conclude?
* [ARIA Attributes](https://www.w3.org/TR/wai-aria-1.1/#state_prop_def) for determining required attributes and correct attribute behavior.
* [ARIA Design Patterns](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_ex) for specifying component behavior, such as navigation behavior.
## Issue Reporting
## Issue Reporting
### Microsoft Edge
### Microsoft Edge
1. Sign into https://issues.microsoftedge.com with your account.
1. Check for a pre-existing issue, hit `Me too` under `Reports` on the issue if it exists. Otherwise, `Open new issue`.
1. Please provide the Windows build number (`Settings` > `System` > `About`), which screen readers replicate the issue, detailed steps to reproduce the issue, and a simplified test case, such as a JS Fiddle.
1. Check for a pre-existing issue, hit `Me too` under `Reports` on the issue if it exists. Otherwise, `Open new issue`.
1. Please provide the Windows build number (`Settings` > `System` > `About`), which screen readers replicate the issue, detailed steps to reproduce the issue, and a simplified test case, such as a JS Fiddle.
### Narrator
### Narrator
The best way to file feedback is via the feedback hub built into Windows. Put `Accessibility` and `Narrator` in the feedback item for increased visibility.
The best way to file feedback is via the feedback hub built into Windows. Put `Accessibility` and `Narrator` in the feedback item for increased visibility.

@ -6,7 +6,8 @@ Please consult the following troubleshooting guidelines to help categorize issue
## Creating Issues
Providing a CodePen exhibiting the issue you're seeing is the fastest way to get feedback regarding your issue. A variety of CodePens can be found below:
* [Fabric CodePen Template](https://codepen.io/FabricReact/)
* [Fabric CodePen Examples](http://codepen.io/dzearing/pens/public/?grid_type=list)
* [Fluent UI React CodePen](https://aka.ms/fluentpen)
* Click "Export to CodePen" above most examples [on the website](https://developer.microsoft.com/en-us/fluentui#/controls/web)
* [Fluent UI React CodePen examples](http://codepen.io/dzearing/pens/public/?grid_type=list)
In addition, for each issue, please provide the information described in the [issue template](https://github.com/OfficeDev/office-ui-fabric-react/blob/master/.github/ISSUE_TEMPLATE.md).
In addition, for each issue, please provide the information described in the [issue template](https://github.com/microsoft/fluentui/blob/master/.github/ISSUE_TEMPLATE.md).

@ -1,10 +1,10 @@
## Overview
`Layer` previously (< OUFR v6.66.0) used React's `unstable_renderSubtreeIntoContainer`, which will [soon be removed](https://github.com/facebook/react/issues/10143).
`Layer` previously (< OUFR v6.66.0) used React's `unstable_renderSubtreeIntoContainer`, which will [soon be removed](https://github.com/facebook/react/issues/10143).
Compared to `unstable_renderSubtreeIntoContainer`, [React Portals](https://reactjs.org/docs/portals.html) introduced in [OUFR v6.66.0](https://github.com/OfficeDev/office-ui-fabric-react/releases/tag/office-ui-fabric-react_v6.66.0) dispatches events in a way that respects virtual hierarchy rather than DOM hierarchy. This means that events will now trickle down and bubble up from portals through ancestors that previously would have not received these events.
Compared to `unstable_renderSubtreeIntoContainer`, [React Portals](https://reactjs.org/docs/portals.html) introduced in [OUFR v6.66.0](https://github.com/microsoft/fluentui/releases/tag/office-ui-fabric-react_v6.66.0) dispatches events in a way that respects virtual hierarchy rather than DOM hierarchy. This means that events will now trickle down and bubble up from portals through ancestors that previously would have not received these events.
Since pre-Portals `Layer` events never bubbled up to its ancestors prior to React Portals, `Layer`'s use of React portals has been implemented with event blocking added to more closely simulate `Layer`'s previous behavior. Event bubbling is controlled via a new `Layer` prop `eventBubblingEnabled` and is disabled by default for backwards compatibility.
Since pre-Portals `Layer` events never bubbled up to its ancestors prior to React Portals, `Layer`'s use of React portals has been implemented with event blocking added to more closely simulate `Layer`'s previous behavior. Event bubbling is controlled via a new `Layer` prop `eventBubblingEnabled` and is disabled by default for backwards compatibility.
## Known Behavior Changes
@ -33,7 +33,7 @@ If you have app or component code with localized, non-window capture or `onMouse
## Capture Events
`Layer` can block events that bubble up and prevent them from traversing up the hierarchy. However, capture events trickle down and cannot be easily blocked or controlled by `Layer`. Since Portals more accurately respect virtual hierarchy, capture events will now trickle down through content to any components contained in the `Layer`. (This didn't happen with old Layer because these events just traversed directly to the Layer subtree attached to root.)
`Layer` can block events that bubble up and prevent them from traversing up the hierarchy. However, capture events trickle down and cannot be easily blocked or controlled by `Layer`. Since Portals more accurately respect virtual hierarchy, capture events will now trickle down through content to any components contained in the `Layer`. (This didn't happen with old Layer because these events just traversed directly to the Layer subtree attached to root.)
![image](https://user-images.githubusercontent.com/26070760/45439777-914a7080-b66f-11e8-8c9d-db95bfe382ba.png)
@ -44,7 +44,7 @@ For example, one case of undesired behavior in Fabric was in the `BaseButton` co
```
private _onSplitContainerFocusCapture = (ev: React.FocusEvent<HTMLDivElement>) => {
const container = this._splitButtonContainer.current;
// If the target is coming from the portal we do not need to set focus on the container.
if (!container || (ev.target && portalContainsElement(ev.target, container))) {
return;
@ -56,18 +56,18 @@ For example, one case of undesired behavior in Fabric was in the `BaseButton` co
## onMouseEnter / onMouseLeave Events
When any of the components listed above are moused over, [every `onMouseEnter` handler along the subtree from the common ancestor of the component left down to the Layered component will be triggered](https://reactjs.org/docs/events.html#mouse-events). (This didn't happen with old Layer because these events just traversed directly to / from the `Layer` subtree attached to root.)
When any of the components listed above are moused over, [every `onMouseEnter` handler along the subtree from the common ancestor of the component left down to the Layered component will be triggered](https://reactjs.org/docs/events.html#mouse-events). (This didn't happen with old Layer because these events just traversed directly to / from the `Layer` subtree attached to root.)
![image](https://user-images.githubusercontent.com/26070760/45056057-a3f8f000-b046-11e8-8d3d-bfeef864f51b.png)
For example, if a `Tooltip` contains a `Modal` and the `Modal` is open, the `Tooltip` will appear over the Modal when the mouse enters the browser window. This happens because `Tooltip`'s `onMouseEnter` handler is now triggered with portals where it wasn't before.
For example, if a `Tooltip` contains a `Modal` and the `Modal` is open, the `Tooltip` will appear over the Modal when the mouse enters the browser window. This happens because `Tooltip`'s `onMouseEnter` handler is now triggered with portals where it wasn't before.
The same `portalContainsElement` utility mentioned for capture handlers can be used in these scenarios. For example, to prevent `Tooltips` from appearing over child `Modals`, the following code was added to `TooltipHost`:
```
private _onTooltipMouseEnter = (ev): void => {
...
if (ev.target && portalContainsElement(ev.target as HTMLElement, this._getTargetElement())) {
// Do not show tooltip when target is inside a portal relative to TooltipHost.
return;

@ -1,4 +1,4 @@
**Note: This page is about *contributing changes* to legacy versions of the UI Fabric library, not using them in your app. If you're consuming Fabric, please use the latest version if possible!**
**Note: This page is about *contributing changes* to legacy versions of the UI Fabric library, not using them in your app. If you're consuming Fabric/Fluent UI React, please use the latest version if possible!**
(If you must use an old version, the process for consuming it is similar; just substitute the old version number when installing, e.g. `npm install --save office-ui-fabric@6`. Also, be sure to reference the correct version of the control documentation: [here for version 6](https://developer.microsoft.com/en-us/fabric#/controls/web?fabricVer=6) or [here for version 5](https://developer.microsoft.com/en-us/fabric#/components?fabricVer=5).)
@ -17,7 +17,7 @@ Fabric has separate branches with the code from previous major releases, such as
### Working copy setup
Due to the install structure differences and the significant number of changed files between major release branches (`master`, `6.0`, and `5.0`, etc), it's recommended to make a **separate clone** for each one.
Due to the install structure differences and the significant number of changed files between major release branches (`master`, `6.0`, and `5.0`, etc), it's recommended to make a **separate clone** for each one.
#### Option 1: Making a separate clone
@ -28,7 +28,7 @@ To make a separate clone for development based off the `6.0` branch (as an examp
3. Choose a name for your new clone's folder (in this example, `fabric6`)
4. Clone the repo, supplying the folder name as an additional argument, and cd into the folder:
```
git clone https://github.com/OfficeDev/office-ui-fabric-react.git fabric6
git clone https://github.com/microsoft/fluentui.git fabric6
cd fabric6
```

@ -1,8 +1,8 @@
Performance testing with flamegraphs is a feature that runs on all PRs opened against Fabric and was introduced with [PR #9550](https://github.com/OfficeDev/office-ui-fabric-react/pull/9550). This page provides an overview of this feature.
Performance testing with flamegraphs is a feature that runs on all PRs opened against Fluent UI React and was introduced with [PR #9550](https://github.com/microsoft/fluentui/pull/9550). This page provides an overview of this feature.
## Sample Performance Test Results Table
Linked from [#9516](https://github.com/OfficeDev/office-ui-fabric-react/pull/9516#issuecomment-503795745), which made perf improvements to "New" Button components in `packages/experiments`, is a sample perf test comment:
Linked from [#9516](https://github.com/microsoft/fluentui/pull/9516#issuecomment-503795745), which made perf improvements to "New" Button components in `packages/experiments`, is a sample perf test comment:
Component Perf Analysis:
<table>
@ -146,16 +146,16 @@ If we look at [`Master Ticks` for `SplitButtonNew`](http://fabricweb.z5.web.core
## Running Tests Locally
The perf test app and some of its dependencies may not get built with default build commands. Make sure you do a [build to perf-test](https://github.com/OfficeDev/office-ui-fabric-react/wiki/Build-Commands) before running any perf tests.
The perf test app and some of its dependencies may not get built with default build commands. Make sure you do a [build to perf-test](https://github.com/microsoft/fluentui/wiki/Build-Commands) before running any perf tests.
After building to perf-test and its dependencies you can run perf-test from the `apps/perf-test` directory:
* `yarn just perf-test`: Builds perf-test package and runs perf-test scenarios.
* `yarn just run-perf-test`: Only runs perf-test scenarios. Assumes perf-test has been built previously.
> ⚠️
> If you modify Fabric source, you must do another build to perf-test to pick up those changes.
> ⚠️
> If you modify Fluent UI React source, you must do another build to perf-test to pick up those changes.
> ⚠️
> ⚠️
> If you are adding or modifying scenarios you must use `yarn just perf-test` to build and pick up scenario changes.
### Arguments
@ -197,11 +197,11 @@ Perf testing generates flamegraphs using a rollup strategy, rolling together the
### How do I add a scenario test?
You can add a scenario to [perf-test](https://github.com/OfficeDev/office-ui-fabric-react/tree/master/apps/perf-test/src/scenarios) similar to the others listed and it will automatically be picked up. Optionally, you can also add your scenario to [scenarioNames.ts](https://github.com/OfficeDev/office-ui-fabric-react/blob/master/apps/perf-test/src/scenarioNames.js) to give it a more readable name.
You can add a scenario to [perf-test](https://github.com/microsoft/fluentui/tree/master/apps/perf-test/src/scenarios) similar to the others listed and it will automatically be picked up. Optionally, you can also add your scenario to [scenarioNames.ts](https://github.com/microsoft/fluentui/blob/master/apps/perf-test/src/scenarioNames.js) to give it a more readable name.
Please note that each scenario will add 5-60 seconds to build time (assuming the current 5,000 iteration default holds.) In the future, scenarios may be more selectively filtered for CI integration in order to keep build time manageable.
> ⚠️
> ⚠️
> When you add or modify a scenario, you must rebuild perf-test or run `yarn run perf-test` in order to absorb the new scenario for testing locally.
# Future improvements

@ -6,7 +6,7 @@ Fluent V7 components support `styles` prop for you to customize styles. It can i
---
*Styles is an object.*
#### Good
```
```tsx
const checkboxStyles = { root: { background: 'red' } };
const App = () => {
return (
@ -15,7 +15,7 @@ const App = () => {
};
```
#### Bad
```
```tsx
const App = () => {
return (
<Checkbox styles={{ root: { background: 'red' }} />
@ -25,10 +25,10 @@ const App = () => {
---
*Styles is a function.*
#### Good
```
const checkboxStyles = ({ checked }) =>
```tsx
const checkboxStyles = ({ checked }) =>
({ root: { background: checked ? 'red' : 'blue' } });
const App = () => {
return (
<Checkbox styles={checkboxStyles} />
@ -36,7 +36,7 @@ const App = () => {
};
```
#### Bad
```
```tsx
const App = () => {
return (
<Checkbox styles={({ checked }) => ({ root: { background: checked ? 'red' : 'blue' } })} />
@ -46,8 +46,8 @@ const App = () => {
---
#### Good
*With memoization.*
```
import { memoizeFunction } = '@fluentui/react/lib/Utilities';
```tsx
import { memoizeFunction } from '@fluentui/react/lib/Utilities';
const getCheckboxStyles = memoizeFunction((background) => ({ root: { background } }));
@ -64,7 +64,7 @@ const App = () => {
```
#### Bad
*New styles object will be passed every time `getCheckboxStyles` is called :(*
```
```tsx
const getCheckboxStyles = (background) => ({ root: { background } });
const App = () => {
@ -78,8 +78,8 @@ const App = () => {
);
};
```
*Do not use `React.useMemo` for memoizing styles creation. Because it resets the cache every time component unmounts. It will help in case of re-renders, but not if the same component gets mounted multiple times.*
```
*Do not use `React.useMemo` for memoizing styles creation, because it resets the cache every time component unmounts. It will help in case of re-renders, but not if the same component gets mounted multiple times.*
```tsx
const App = () => {
const [color, setColor] = React.useState('red');
const toggleColor = () => setColor(color === 'red' ? 'blue' : 'red');
@ -87,7 +87,7 @@ const App = () => {
() => ({ root: { background: color } }),
[color]
);
return (
<>
<button onClick={toggleColor}>Toggle color</button>

@ -1,6 +1,6 @@
# Browser support
Fabric React supports many commonly used web browsers such as Internet Explorer, Google Chrome, Mozilla Firefox, Apple Safari, and Microsoft Edge. For browsers outside of this matrix, proper behavior of the components may be good but is not guaranteed.
Fluent UI React supports many commonly used web browsers such as Internet Explorer, Google Chrome, Mozilla Firefox, Apple Safari, and Microsoft Edge. For browsers outside of this matrix, proper behavior of the components may be good but is not guaranteed.
| Browser | Supported | Not supported |
|-----------------------------------------------------|:---------:|:-------------:|
@ -17,5 +17,5 @@ Fabric React supports many commonly used web browsers such as Internet Explorer,
Between now and end of year 2020, we will only fix IE 11 and Edge Legacy bugs if:
1. They block major functionality
2. There is a major accessibility bug
After the end of the year 2020, we will not be fixing these bugs unless there is a high priority partner escalation that will cause a legal problem.

@ -1,2 +1 @@
Content for creating a simple application has moved to:
[Getting Started with UI Fabric](Getting-Started-with-UI-Fabric)
[Please see the "Get started" section on our website.](https://developer.microsoft.com/en-us/fluentui#/get-started/web)

@ -8,17 +8,25 @@ For basic instructions on getting Next.js set up, see https://nextjs.org/
2. Add the Fluent UI dependencies: `@fluentui/react`, `@uifabric/utilities` and `@uifabric/merge-styles`.
```bash
# Fluent UI React (Fabric) 7 or earlier
yarn add @uifabric/utilities @uifabric/merge-styles @fluentui/react
# Fluent UI React 8+
yarn add @fluentui/utilities @fluentui/merge-styles @fluentui/react
```
3. Create a `_document.js` file under your `pages` folder with the following content:
1. Create a `_document.js` file under your `pages` folder with the following content:
```tsx
import * as React from 'react';
import Document, { Head, Main, NextScript } from 'next/document';
// Fluent UI React (Fabric) 7 or earlier
import { Stylesheet, InjectionMode } from "@uifabric/merge-styles";
import { resetIds } from "@uifabric/utilities";
// Fluent UI React 8+
// import { Stylesheet, InjectionMode } from "@uifabric/merge-styles";
// import { resetIds } from "@uifabric/utilities";
// Do this in file scope to initialize the stylesheet before Fabric components are imported.
// Do this in file scope to initialize the stylesheet before Fluent UI React components are imported.
const stylesheet = Stylesheet.getInstance();
// Set the config.
@ -34,15 +42,15 @@ export default class MyDocument extends Document {
resetIds();
const page = renderPage((App) => (props) => <App {...props} />);
return { ...page, styleTags: stylesheet.getRules(true) };
}
render() {
return (
<html>
<Head>
<style type="text/css" dangerouslySetInnerHTML={{__html: this.props.styleTags}} />
<Head>
<style type="text/css" dangerouslySetInnerHTML={{__html: this.props.styleTags}} />
</Head>
<body>
<Main />
@ -54,7 +62,7 @@ export default class MyDocument extends Document {
}
```
4. You should now be able to server render Fabric components in any of your pages:
4. You should now be able to server render Fluent UI React components in any of your pages:
```js
import * as React from "react";
@ -63,7 +71,7 @@ import {
ColorPicker,
createTheme,
Dropdown,
Fabric,
Fabric, // NOTE: Use ThemeProvider instead in version 8+
initializeIcons,
PrimaryButton,
Slider,
@ -74,7 +82,7 @@ import {
initializeIcons();
const Index = () => (
<Fabric>
<Fabric> {/* NOTE: Use ThemeProvider instead in version 8+ */}
<div>
<PrimaryButton>Hello, world</PrimaryButton>
<Toggle defaultChecked label="Hello" />
@ -92,7 +100,7 @@ export default Index;
NOTE: You will probably see a warning:
```bash
index.js:1 Warning: Prop `className` did not match. Server: "ms-Button-label server-label-4" Client: "ms-Button-label label-53"
index.js:1 Warning: Prop `className` did not match. Server: "ms-Button-label server-label-4" Client: "ms-Button-label label-53"
```
This is a known warning, and we are investigating ways to solve this.
@ -101,50 +109,34 @@ This is a known warning, and we are investigating ways to solve this.
> Note: There are many steps missing below to get nodemon/babel/typescript/es modules working in a node.js environment. This will need to be elaborated on.
It's possible to render Fabric components on the server side in a Node environment, using the [SSR support in `merge-styles`](https://github.com/OfficeDev/office-ui-fabric-react/tree/master/packages/merge-styles#server-side-rendering).
It's possible to render Fluent UI React components on the server side in a Node environment, using the [SSR support in `merge-styles`](https://github.com/microsoft/fluentui/tree/master/packages/merge-styles#server-side-rendering).
See https://codesandbox.io/s/dazzling-montalcini-kv9bz for an example which uses the SSR support to build html/css strings to inject into the page. The result is not mounted, so behaviors will not work, but represents the html/css output that would be generated by SSR.
Example:
```ts
```tsx
import * as React from "react";
import * as ReactDOM from "react-dom/server";
import {
initializeIcons,
PrimaryButton,
CommandBar,
Fabric,
DefaultButton,
ActionButton,
IconButton,
Toggle,
ColorPicker,
Checkbox,
ChoiceGroup,
Slider,
Dropdown,
ComboBox,
MessageBar,
MessageBarType,
TextField,
SpinButton,
Persona,
Rating,
Link,
SearchBox,
Text
Fabric, // NOTE: Use ThemeProvider instead in version 8+
// ...
} from "@fluentui/react";
// Fluent UI React (Fabric) 7 or earlier
import { renderStatic } from "@uifabric/merge-styles/lib/server";
// Fluent UI React 8+
// import { renderStatic } from "@fluentui/merge-styles/lib/server";
import "./styles.css";
initializeIcons();
function App() {
// NOTE: Use ThemeProvider instead in version 8+
return (
<Fabric dir={rtl ? "rtl" : "ltr"}>
...content
...content goes here...
</Fabric>
);
}
@ -199,7 +191,7 @@ Some of our legacy styling was done through scss rather than merge-styles. Keepi
The basic idea is to tell the styles loader to store styles in a variable, which you can later inject into your page. Example:
```ts
```tsx
import { configureLoadStyles } from '@microsoft/load-themed-styles';
// Store registered styles in a variable used later for injection.
@ -212,9 +204,9 @@ configureLoadStyles((styles: string) => {
import * as React from 'react';
import * as ReactDOMServer from 'react-dom/server';
import { Button } from '@fluentui/react/lib/Button';
import { Text } from '@fluentui/react/lib/Text';
let body = ReactDOMServer.renderToString(<Button>hello</Button>);
let body = ReactDOMServer.renderToString(<Text>hello</Text>);
console.log(
`

@ -1,5 +1,6 @@
This document describes theming at a high level. For low level technical details, follow the links.
**Note that the information on this page currently applies only to `@fluentui/react` version 7/8 (and `office-ui-fabric-react`)**, not `@fluentui/react-northstar` or `@fluentui/web-components`.
## What is theming?
@ -15,29 +16,23 @@ For example, `themePrimary` by default is `"#0078d4"`, but it could easily be `"
There are two kinds of theme slots: palette slots and semantic slots.
Palette slots are documented in [IPalette.ts](https://github.com/microsoft/fluentui/blob/master/packages/theme/src/types/IPalette.ts).
These are descriptive slots, it gives you an idea of what the color is, but you decide how to use it.
Most slots with color names (besides `white` and `black`), such as `yellow` and `yellowLight`, will remain a shade of yellow in all themes, useful in cases where color has meaning (such as for errors and warnings).
Customizing Fabric palette slots allows broad-stroke changes to the overall color scheme.
Palette slots are documented in [IPalette.ts](https://github.com/microsoft/fluentui/blob/master/packages/theme/src/types/IPalette.ts). These are **descriptive** slots: it gives you an idea of what the color is, but you decide how to use it. Most slots with color names (besides `white` and `black`), such as `yellow` and `yellowLight`, will remain a shade of yellow in all themes, useful in cases where color has meaning (such as for errors and warnings). Customizing palette slots allows broad-stroke changes to the overall color scheme.
Semantic slots are documented in [ISemanticColors.ts](https://github.com/microsoft/fluentui/blob/master/packages/theme/src/types/ISemanticColors.ts). These are **prescriptive** slots: each one has an intended use. This allows more targeted customizations. For example, you could change the light gray color of a disabled checkbox without affecting the light gray background used by list item hover/selection state, even though they share the same color, because they use different slots. This wouldn't be possible with palette slots.
Semantic slots are documented in [ISemanticColors.ts](https://github.com/microsoft/fluentui/blob/master/packages/theme/src/types/ISemanticColors.ts).
These, on the other hand, are prescriptive slots, each slot having an intended use.
This allows more targeted customizations.
For example, you could change the light gray color of a disabled checkbox without affecting the light gray background used by list item hover/selection state, even though they share the same color, because they use different slots.
This wouldn't be possible with Fabric palette slots.
We highly recommend using semantic slots wherever possible.
<a name="add-semantic-slot"></a>
> **NOTE:** The semantic slot list is fairly comprehensive, and should satisfy the vast majority of theming needs. Fabric's policy is that semantic slots may NEVER be removed from the list, so any additions are permanent. _Adding new slots should be a rare event that requires ample justification._
> **NOTE:** The semantic slot list is fairly comprehensive, and should satisfy the vast majority of theming needs. Fluent UI React's policy is that semantic slots may NEVER be removed from the list, so any additions are permanent. _Adding new slots should be a rare event that requires ample justification._
>
> If a designer can make a case that a new semantic slot is needed, **a new slot can be added to Fabric with the following process:**
> If a designer can make a case that a new semantic slot is needed, **a new slot can be added to Fluent UI React with the following process:**
>
> 1. The new slot must be approved by the Fabric theming feature crew
> 1. The new slot must be approved by the Fluent UI React theming feature crew
> 2. Add the slot definition to the [interface](https://github.com/microsoft/fluentui/blob/master/packages/theme/src/types/ISemanticColors.ts), with a description on how it can be used
> - Follow the naming convention at the top, and try to fit it in a category
> 3. Add the slot's default palette color in the default blue theme in [`makeSemanticColors()`](https://github.com/microsoft/fluentui/blob/master/packages/theme/src/utilities/makeSemanticColors.ts)
> 4. Add the variant-specific logic to the [variants package](https://github.com/microsoft/fluentui/blob/master/packages/variants/src/variants.ts)
> 5. For backwards-compatibility with SASS, add the semantic slot and raw default color to the [fallback scss file](https://github.com/microsoft/fluentui/blob/master/packages/common-styles/src/_semanticSlots.scss)
> 5. For backwards-compatibility with SASS, run the script to add the semantic slot and raw default color to the [fallback scss file](https://github.com/microsoft/fluentui/blob/master/packages/common-styles/src/_semanticSlots.scss): from within `packages/common-styles`, run `yarn update-sass-theme-files`.
## How do I make a theme?
@ -45,11 +40,9 @@ Check out the [Theme Designer](https://aka.ms/themedesigner) tool to quickly cre
You can define just the subset of slots you want to customize.
For instance, you could overwrite all the `neutral*`s with shades of red.
Anything using one of those Fabric palette slots will become reddish.
Anything using one of those palette slots will become reddish.
Semantic slots usually "inherit" from a Fabric palette slot.
For example, the `bodyText` semantic slot, if uncustomized, will always pick up the color from the Fabric palette slot `neutralPrimary`.
You can see these default assignments in [`makeSemanticColors()`](https://github.com/microsoft/fluentui/blob/master/packages/theme/src/utilities/makeSemanticColors.ts).
Semantic slots usually "inherit" from a palette slot. For example, the `bodyText` semantic slot, if uncustomized, will always pick up the color from the palette slot `neutralPrimary`. You can see these default assignments in [`makeSemanticColors()`](https://github.com/microsoft/fluentui/blob/master/packages/theme/src/utilities/makeSemanticColors.ts).
## What happens when you theme?
@ -61,4 +54,4 @@ Inside the registered CSS are theme tokens that the theming module keeps track o
## How to apply the theme?
Once you have defined the theme for your app, you need to apply the theme to the components. Fluent UI React currently supports multiple ways of applying theme. You can read [this wiki](https://github.com/microsoft/fluentui/wiki/How-to-apply-theme-to-Fluent-UI-React-components) in details.
Once you have defined the theme for your app, you need to apply the theme to the components. Fluent UI React currently supports multiple ways of applying themes. You can read [this wiki page](https://github.com/microsoft/fluentui/wiki/How-to-apply-theme-to-Fluent-UI-React-components) for more details.

@ -1,36 +0,0 @@
## Overview
Ngrok will generate a secure URL to your localhost server through any NAT or firewall. This is useful if you want someone to test your local build on their machine, a different OS, even mobile device browsers.
## Getting Started
Got to the [Ngrok website](https://ngrok.com/) and sign up for a free account. You will need to do this to get a authentication token.
### Download and Install
You will need to go to Ngrok's [download page](https://ngrok.com/download) and download binary for your OS and follow the corresponding instructions. Once complete the `ngrok` command should work from your terminal.
### Connect your account
Running this command will add your account's authtoken to your ngrok.yml file. This will give you more features and all open tunnels will be listed in your dashboard. You will find the command with your authentication token [here](https://dashboard.ngrok.com/get-started).
```
./ngrok authtoken [your own token]
```
### Open a Tunnel
Once you have your local server or other program running, you can open a tunnel pointing to the port where it's currently running. If you are running Fabric React locally with the `npm start` command then the port will be **4322**.
```
./ngrok http 4322
```
There will be a link in your terminal like http://2c566507.ngrok.io which you can now give to someone else to pull up your local build.
#### Invalid Host header
If you open the link in the browser and you see a white screen that says **Invalid Host header** you simply need to explicitly declare the Host header in your `ngrok` command.
```
ngrok http --host-header=rewrite 4322
```

@ -201,7 +201,7 @@ We know that the number of possible theming approaches and lack of clear guidanc
Please see [this wiki page](https://github.com/microsoft/fluentui/wiki/How-to-apply-theme-to-Fluent-UI-React-components) and the [`@fluentui/react-theme-provider` package README](https://github.com/microsoft/fluentui/blob/master/packages/react-theme-provider/README.md) for details about usage and migration. Note if you're using the new Button (`@fluentui/react/lib/Button`), it's also required to use `ThemeProvider`.
The `Fabric` and `Customizer` components have been deprecated in favor of `ThemeProvider`.
The `Fabric` and `Customizer` components have been deprecated in favor of `ThemeProvider`. (If you're using `Customizer` for purposes besides theming, please let us know.)
----

@ -82,7 +82,7 @@ We know that the number of possible theming approaches and lack of clear guidanc
Please see [this wiki page](How-to-apply-theme-to-Fluent-UI-React-components) and/or the [`@fluentui/react-theme-provider` package README](https://github.com/microsoft/fluentui/blob/master/packages/react-theme-provider/README.md) for details about usage and migration. Note if you're using the new Button, it's also required to use `ThemeProvider`.
The `Fabric` and `Customizer` components have been deprecated in favor of `ThemeProvider`. (If you're using `Customizer` for purposes besides styling, please let us know.)
The `Fabric` and `Customizer` components have been deprecated in favor of `ThemeProvider`. (If you're using `Customizer` for purposes besides theming, please let us know.)
### `[IN PREVIEW]` Composition utilities
These "In Preview" utilities are meant for component authors to try out and give us feedback on creating new components like we did with the new Button component. Note that these APIs are subject to change as we learn and iterate with component authors.

@ -1,3 +1,3 @@
Moved to:
https://github.com/OfficeDev/office-ui-fabric-react/wiki/Pull-request-reviewing-guidance
https://github.com/microsoft/fluentui/wiki/Pull-request-reviewing-guidance

@ -4,6 +4,7 @@
* [Release notes](Version-8%3A-Release-notes)
* [Migration guide](Version-8%3A-Migration-guide)
* [Contributing to the `7.0` branch](Contributing-to-the-7.0-branch)
* [How to apply themes (version 7/8)](How-to-apply-theme-to-Fluent-UI-React-components)
### Objectives & Key Results
* [Quarterly OKRs](Fluent-UI-Objectives)
@ -43,7 +44,6 @@
### Creating New Components
* [Creating a Component](New-Components)
* [Component Anatomy](Component-Anatomy)
* [Styling](Component-Styling)
* [Testing](Testing)
* [Theming](Theming)
@ -63,7 +63,7 @@
### References
* [FAQ](FAQ)
* [Browser Support](Browser-Support)
* [mergeStyles reference](https://github.com/OfficeDev/office-ui-fabric-react/blob/master/packages/merge-styles/README.md)
* [mergeStyles reference](https://github.com/microsoft/fluentui/blob/master/packages/merge-styles/README.md)
* [Perf Testing](Perf-Testing)
* [Layer & Portals](Layer-&-Portals)
* [Migration from 4.x to 5.x](Fabric5)