Skip to content
Adam Comella edited this page Apr 30, 2015 · 23 revisions

Intro

react-winjs is a library which exposes each WinJS control as a React component.

API Differences from WinJS

For the most part, the props of the react-winjs React components match the properties of the WinJS controls. Each React component has a few additional props which are applied to the root element of the WinJS control:

  • className: A string representing the element's CSS className.
  • style: An object where the keys are camel cased CSS attributes and the values are the corresponding values of those attributes.
  • id: A string representing the element's id.

What's interesting about a control's root element is that, not only might you want to manipulate it from React, but WinJS controls themselves typically manipulate their root elements. For example, the ListView will add classes such as win-listview and win-disposable to its root element. react-winjs implements the style and className props specially such that you can contribute to the root element's class names and styles without stomping on the ones that WinJS added.

Each component provides a property called winControl which returns the instance of the WinJS control. For example, winControl on a react-winjs ListView component will return an instance of WinJS.UI.ListView.

Events are exposed as camel cased props that begin with on. For example, WinJS's onbeforeshow event is exposed as the onBeforeShow prop.

Utility Functions

  • reactRenderer(componentFunction): Enables an itemTemplate to be specified as a React component. Given a function that returns a React component, returns an item renderer function that can be used with WinJS controls. See the FlipView and ListView examples.

Controls: Example Usages

AppBar

<ReactWinJS.AppBar>
    <ReactWinJS.AppBar.Button key="home" icon="home" label="Home" />
    <ReactWinJS.AppBar.Button key="save" icon="save" label="Save" />
</ReactWinJS.AppBar>

In WinJS, there is the WinJS.UI.AppBarCommand which has a type property. react-winjs differs in that it provides several components which map to WinJS.UI.AppBarCommand and each corresponds to a different value of the type property. Here's a summary of how that works:

react-winjs Component WinJS.UI.AppBarCommand type Property Notes
ReactWinJS.AppBar.Button "button"
ReactWinJS.AppBar.Toggle "toggle" Control its state with the selected prop
ReactWinJS.AppBar.Separator "separator"
ReactWinJS.AppBar.ContentCommand "content" Provide the custom content as the child
ReactWinJS.AppBar.FlyoutCommand "flyout" Provide the Flyout/Menu with the flyoutComponent prop

Limitations:

  • Each AppBar command must have a key.
  • The AppBar command's ref prop does not work.

AutoSuggestBox

<ReactWinJS.AutoSuggestBox placeholderText="Type a city" />

BackButton

<ReactWinJS.BackButton />

ContentDialog

<ReactWinJS.ContentDialog
  ref="dialog"
  title="Urgent Message"
  primaryCommandText="OK"
  secondaryCommandText="Cancel"
/>
  <div>
    This content will appear in the body of the ContentDialog. You can put <i>arbitrary</i> HTML in here.
  </div>
</ReactWinJS.ContentDialog>

// ...

// In an event handler:
this.refs.dialog.winControl.show().then(function (eventObject) {
  // eventObject.result tells you what caused the dialog to get dismissed.
});

DatePicker

<ReactWinJS.DatePicker current={this.state.date} onChange={this.handleDateChange} />

FlipView

<ReactWinJS.FlipView
  itemDataSource={this.props.ratingsList.dataSource}
  itemTemplate={this.flipViewItemRenderer}
  onPageSelected={this.handlePageSelected} />

// ...

// itemDataSource
ratingsList: new WinJS.Binding.List([{ rating: 4 }, { rating: 2 }])

// itemTemplate
flipViewItemRenderer: ReactWinJS.reactRenderer(function (item) {
  return <div>This flip view item's rating is: {item.data.rating}</div>;
})

Flyout

<ReactWinJS.Flyout ref="flyout">
  <div>This is the flyout content!!</div>
</ReactWinJS.Flyout>

// ...

// In an event handler:
this.refs.flyout.show(anchorElement);

Hub

<ReactWinJS.Hub>
    <ReactWinJS.Hub.Section key="sectionA" header="First section" isHeaderStatic={true}>
      <div>Hubs are useful for varied content</div>
    </ReactWinJS.Hub.Section>
    <ReactWinJS.Hub.Section key="sectionB" header="The second section">
      <div>This hub is boring however, it only contains one piece of dynamic content: {ratings.length}</div>
    </ReactWinJS.Hub.Section>
    <ReactWinJS.Hub.Section key="sectionC" header="The tail...">
      <div>Because it's only purpose is to show how to create a hub</div>
    </ReactWinJS.Hub.Section>
</ReactWinJS.Hub>

Limitations:

  • Each Hub.Section must have a key.
  • The Hub.Section's ref prop does not work.

ItemContainer

<ReactWinJS.ItemContainer>
  <div>
    An ItemContainer is a wrapper around content that adds
    pressed and selection behaviors!
  </div>
</ReactWinJS.ItemContainer>

ListView

<ReactWinJS.ListView
  itemDataSource={this.props.ratingsList.dataSource}
  itemTemplate={listViewItemRenderer}
  layout={listViewLayout} />

// ...

// itemDataSource
ratingsList: new WinJS.Binding.List([{ rating: 4 }, { rating: 2 }])

// itemTemplate
listViewItemRenderer: ReactWinJS.reactRenderer(function (item) {
  return <div>This list view item's rating is: {item.data.rating}</div>;
})

// layout
listViewLayout: { type: WinJS.UI.ListLayout }

Menu

<ReactWinJS.Menu ref="menu">
    <ReactWinJS.Menu.Button key="commandA" label="command the first" />
    <ReactWinJS.Menu.Button key="commandB" label="command the second" />
</ReactWinJS.Menu>

// ...

// In an event handler:
this.refs.menu.winControl.show(anchorElement);

Limitations:

  • Each Menu command must have a key.
  • The Menu command's ref prop does not work.

NavBar and friends

<ReactWinJS.NavBar>
    <ReactWinJS.NavBarContainer>
        <ReactWinJS.NavBarCommand key="home" label="Home" icon="home" tooltip="Go home!!" />
        <ReactWinJS.NavBarCommand key="save" label="Save" icon="save" />
    </ReactWinJS.NavBarContainer>
</ReactWinJS.NavBar>

Limitations:

  • Each NavBarCommand must have a key.
  • The NavBarCommand's ref prop does not work.

Pivot

<ReactWinJS.Pivot>
    <ReactWinJS.Pivot.Item key="itemA" header="First">
      <div>Pivots are useful for varied content</div>
    </ReactWinJS.Pivot.Item>
    <ReactWinJS.Pivot.Item key="itemB" header="Second">
      <div>This Pivot is boring however, it only contains one piece of dynamic content: {ratings.length}</div>
    </ReactWinJS.Pivot.Item>
    <ReactWinJS.Pivot.Item key="itemC" header="Tail...">
      <div>Because it's only purpose is to show how to create a Pivot</div>
    </ReactWinJS.Pivot.Item>
</ReactWinJS.Pivot>

Limitations:

  • Each Pivot.Item must have a key.
  • The Pivot.Item's ref prop does not work.

Rating

<ReactWinJS.Rating maxRating={5} userRating={this.state.rating} />

SearchBox

<ReactWinJS.SearchBox placeholderText="Search" />

SemanticZoom

var zoomedInView = <ReactWinJS.ListView
  itemDataSource={ratingsList.dataSource}
  itemTemplate={zoomedInItemRenderer}
  groupDataSource={ratingsList.groups.dataSource}
  groupHeaderTemplate={zoomedInHeaderRenderer}
  layout={zoomedInLayout} />;

var zoomedOutView = <ReactWinJS.ListView
  itemDataSource={ratingsList.groups.dataSource}
  itemTemplate={zoomeOutItemRenderer}
  layout={zoomedOutLayout} />;

<ReactWinJS.SemanticZoom
  zoomedInComponent={zoomedInView}
  zoomedOutComponent={zoomedOutView} />

// ...

// itemDataSource
function groupKey(item) {
    return item.group;
}
function groupData(item) {
    return { title: item.group; };
}
ratingsList: new WinJS.Binding.List([
  { rating: 4, group: "A" },
  { rating: 2, group: "A" },
  { rating: 8, group: "B" },
  { rating: 3, group: "B" }
]).createGrouped(groupKey, groupData);

// renderers
zoomedInItemRenderer: ReactWinJS.reactRenderer(function (item) {
  return <div>This list view item's rating is: {item.data.rating}</div>;
})
zoomedInHeaderRenderer: ReactWinJS.reactRenderer(function (item) {
  return <div>{item.data.title}</div>;
})
zoomeOutItemRenderer: ReactWinJS.reactRenderer(function (item) {
  return <div>{item.data.title}</div>;
})

// layouts
zoomedInLayout: { type: WinJS.UI.ListLayout }
zoomedOutLayout: { type: WinJS.UI.ListLayout }

SplitView

<ReactWinJS.SplitView
  paneComponent={<div>SplitView Navigation Pane</div>}
  contentComponent={<div>SplitView Content Area</div>} />

TimePicker

<ReactWinJS.TimePicker current={this.state.time} />

ToggleSwitch

<ReactWinJS.ToggleSwitch
  checked={this.props.toggleOn}
  onChange={this.handleToggle}
  labelOn="Switch is On"
  labeOff="Switch is Off" />

ToolBar

<ReactWinJS.ToolBar>
    <ReactWinJS.ToolBar.Button key="add" label="This is a ToolBar command" icon="add" />
    <ReactWinJS.ToolBar.Button key="remove" label="Another ToolBar command" icon="remove" />
</ReactWinJS.ToolBar>

In WinJS, there is the WinJS.UI.Command which has a type property. react-winjs differs in that it provides several components which map to WinJS.UI.Command and each corresponds to a different value of the type property. Here's a summary of how that works:

react-winjs Component WinJS.UI.Command type Property Notes
ReactWinJS.ToolBar.Button "button"
ReactWinJS.ToolBar.Toggle "toggle" Control its state with the selected prop
ReactWinJS.ToolBar.Separator "separator"
ReactWinJS.ToolBar.ContentCommand "content" Provide the custom content as the child
ReactWinJS.ToolBar.FlyoutCommand "flyout" Provide the Flyout/Menu with the flyoutComponent prop

Limitations:

  • Each ToolBar command must have a key.
  • The ToolBar command's ref prop does not work.

Tooltip

<ReactWinJS.Tooltip
  contentComponent={<div>This can have arbitrary content, like images...</div>}>
  <div>This has a tooltip, hover and see...</div>
</ReactWinJS.Tooltip>
Clone this wiki locally