Skip to content

Wrapper libraries: Fabric

xjerwa edited this page Apr 1, 2019 · 4 revisions

Wrapper library for office-ui-fabric-react, exposed as @angular-react/fabric and actively maintained and published on npm.

Contains quite a good coverage as far as wrapping the React components go, and for the wrapped components allows passing in all props as Inputs, listening to all events via Outputs, as well as pass in render props where applicable (see more details in ReactWrapperComponent).

In addition, some components have alternative declarative syntax for things that would make more sense as such in Angular-world, like <fab-command-bar> allowing using it's items in a declarative manner, via <fab-command-bar-item>. These make authoring apps much simpler in a lot of cases, leveraging Angular's data-binding to it's full extend, instead of changing things imperatively. These should be added when it makes sense and makes using the wrapper components easier, though it does introduce more complexity. More details for these components can be found in the Declarative Syntax Components section.

Docs & Guidelines

  • We try to stick to the official office-ui-fabric-react naming whenever possible, with a few minor changes to fit the Angular conventions:

    • Any React component (PascalCase-d) is changed to kebab-case, and prefixed with fab-. e.g. MessageBar -> fab-message-bar, Checkbox -> fab-checkbox.
    • For any documentation needs - check out the official ones for the React component, and convert the naming according to the above, as needed. Render props are "translated" as described here.
  • When office-ui-fabric-react marks a prop as deprecated, we remove it the next time around we upgrade our dependency on it. We're more harsh with deprecation since the wrapper components are currently authored & maintained completely manually (see #91), and maintaining more props means more manual work.

Available Components

The following are Fabric components that are readily available to be used. For the most up-to-date version of this list or more details for a specific component, refer to the components folder.

Component Notes Docs
breadcrumb Breadcrumb
button Different button types
Supports contextual-menu-item
Button
calendar Supports fab-calendar-strings Calendar
callout Different callout types Callout
checkbox Checkbox
choice-group ChoiceGroup
combo-box Different combo-box types
Supports fab-combo-box-option
ComboBox
command-bar Supports fab-command-bar-item CommandBar
contextual-menu See contextual-menu-item ContextualMenu
date-picker DatePicker
details-list Supports fab-details-list-column and fab-group-item DetailsList
dialog fab-dialog-content and fab-dialog-footer are also supported Dialog
divider N/A
dropdown Supports fab-dropdown-option Dropdown
grouped-list GroupedList
hover-card Different hover-card types HoverCard
icon Icon
image Image
link Link
marquee-selection MarqueeSelection
message-bar Must bind [dismissible]="true" for (onDismiss) to work MessageBar
modal Modal
nav Nav
panel Panel
persona fab-persona-coin is also supported Persona
pickers Currently only fab-tag-picker is supported Pickers
pivot fab-pivot-item is also supported Pivot
search-box SearchBox
shimmer fab-shimmer-elements-group is also supported Shimmer
slider Slider
spin-button SpinButton
spinner Spinner
text-field Different text-field types TextField
toggle Toggle
tooltip Applies to child element of fab-tooltip-host Tooltip

Notes and Tips

click vs. onClick

Angular's default click binding is (click) while the Fabric components follow React's (onClick). For safety, it is typically advised to stick with the (onClick) binding. Although both bindings will "work", there will be different behaviors in certain circumstances.

For example, in the following code, the click event will still fire even though the button is disabled. This is because the (click) binding is attached to the Angular wrapper around the React component.

<fab-default-button [disabled]="true" (click)="doSomething()">
  This will still fire an event!
</fab-default-button>

The correct way would be to use (onClick) as that event is what gets fired by the actual React button itself:

<fab-default-button [disabled]="true" (onClick)="doSomething()">
  This will not fire an event
</fab-default-button>

Declarative Syntax Components

Fabric components often have input members that expect an object, such as the columns member of DetailsList. Although objects can be passed through Angular input bindings, this may be inconvenient if you want to avoid declaring extra objects or have other requirements such as i18n.

The following components and directives have been added to simplify this process for a couple of common scenarios. If what you're looking for is not in the following list, you will need to create a wrapper component in your project to handle passing in different properties of a certain input object. Alternatively, consider contributing to this project to get it added :)

contextual-menu-item (FabContextualMenuModule)

Declarative syntax for IContextualMenuItem interface. Currently supported by different flavors of fab-*-button and fab-command-bar-item. Supports additional nesting of contextual-menu-item. Usage example:

<fab-default-button text="Button">
  <contextual-menu-item key="item-1" text="Item 1"></contextual-menu-item>
  <contextual-menu-item key="item-2" text="Item 2">
    <contextual-menu-item key="item-2-1" text="Item 2.1"></contextual-menu-item>
    <contextual-menu-item key="item-2-2" text="Item 2.2"></contextual-menu-item>
  </contextual-menu-item>
  <contextual-menu-item key="item-3" text="Item 3"></contextual-menu-item>
</fab-default-button>

fab-calendar-strings (FabCalendarModule)

Declarative syntax for ICalendarStrings interface. Currently only supported by fab-calendar. Usage example:

<fab-calendar>
  <fab-calendar-strings
    [months]="['January', 'Fabruary', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']"
    [shortMonths]="['Jan', 'Fab', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']"
    [days]="['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']"
    [shortDays]="['S', 'M', 'T', 'W', 'T', 'F', 'S']"
    goToToday="Go to today"
    weekNumberFormatString="Week number {0}"
  ></fab-calendar-strings>
</fab-calendar>

fab-combo-box-option (FabComboBoxModule)

Declarative syntax for IComboBoxOption interface. Currently only supported by fab-combo-box. Usage example:
Note that the key input is actually optionKey here.

<fab-combo-box placeholder="ComboBox">
  <options>
    <fab-combo-box-option optionKey="option-1" text="Option 1">
    <fab-combo-box-option optionKey="option-2" text="Option 2">
    <fab-combo-box-option optionKey="option-3" text="Option 3">
  </options>
</fab-combo-box>

fab-command-bar-item (FabCommandBarModule)

Declarative syntax for ICommandBarItemProps interface. Currently only supported by fab-command-bar. Supports additional nesting of contextual-menu-item and custom renderer via render (same parameters as IContextualMenuItem's onRender). Usage example:

<fab-command-bar>
  <items>
    <fab-command-bar-item key="item-1" text="Item 1"></fab-command-bar-item>
    <fab-command-bar-item key="item-2" text="Item 2">
      <contextual-menu-item key="item-2-1" text="Item 2.1"></contextual-menu-item>
      <contextual-menu-item key="item-2-2" text="Item 2.2"></contextual-menu-item>
    </fab-command-bar-item>
  </items>
  <far-items>
    <fab-command-bar-item key="fitem-1" text="F. Item 1"></fab-command-bar-item>
    <fab-command-bar-item key="fitem-2" text="F. Item 2">
      <render>
        <ng-template let-item="item">
          Custom item content
        </ng-template>
      </render>
    </fab-command-bar-item>
  </far-items>
  <overflow-items>
    <fab-command-bar-item key="oitem-1" text="O. Item 1"></fab-command-bar-item>
    <fab-command-bar-item key="oitem-2" text="O. Item 2"></fab-command-bar-item>
  </overflow-items>
</fab-command-bar>

fab-details-list-column (FabDetailsListModule)

Declarative syntax for IColumn interface. Currently only supported by fab-details-list. Supports custom renderer via render (same parameters as IColumn's onRender). Usage example:

<fab-details-list [items]="shapes">
  <columns>
    <fab-details-list-column key="column-1" name="Column 1" fieldName="name"></fab-details-list-column>
    <fab-details-list-column key="column-2" name="Column 2">
      <render>
        <ng-template let-item="item" let-index="index" let-column="column">
          Size: {{ item.size }}, Index: {{ index }}, Column: {{ column.name }}
        </ng-template>
      </render>
    </fab-details-list-column>
    <fab-details-list-column key="column-3" name="Column 3" fieldName="color"></fab-details-list-column>
  </columns>
</fab-details-list>

fab-dropdown-option (FabDropdownModule)

Declarative syntax for IDropdownOption interface. Currently only supported by fab-dropdown. Usage example:
Note that the key input is actually optionKey here.

<fab-dropdown placeholder="Dropdown">
  <options>
    <fab-dropdown-option optionKey="option-1" text="Option 1">
    <fab-dropdown-option optionKey="option-2" text="Option 2">
    <fab-dropdown-option optionKey="option-3" text="Option 3">
  </options>
</fab-dropdown>

fab-group-item (FabGroupModule)

Declarative syntax for IGroup interface. Currently only supported by fab-details-list. Supports additional nesting of fab-group-item. Usage example:

<fab-details-list [items]="items">
  <groups>
    <fab-group-item key="group-1" name="Group 1" [count]="3" [startIndex]="0"></fab-group-item>
    <fab-group-item key="group-2" name="Group 2" [count]="3" [startIndex]="3">
      <fab-group-item key="group-2-1" name="Group 2.1" [count]="2" [startIndex]="3"></fab-group-item>
      <fab-group-item key="group-2-2" name="Group 2.2" [count]="1" [startIndex]="5"></fab-group-item>
    </fab-group-item>
    <fab-group-item key="group-3" name="Group 3" [count]="10" [startIndex]="6"></fab-group-item>
  </groups>
</fab-details-list>