();
+
+ constructor(props: IPivotProps) {
+ super(props);
+ this._pivotId = getId('Pivot');
+ const links: IPivotItemProps[] = this._getPivotLinks(this.props);
+ let selectedKey: string | undefined;
+
+ if (props.initialSelectedKey) {
+ selectedKey = props.initialSelectedKey;
+ } else if (props.initialSelectedIndex) {
+ selectedKey = links[props.initialSelectedIndex].itemKey as string;
+ } else if (props.selectedKey) {
+ selectedKey = props.selectedKey;
+ } else if (links.length) {
+ selectedKey = links[0].itemKey as string;
+ }
+
+ this.state = {
+ links,
+ selectedKey: selectedKey!,
+ selectedTabId: this._keyToTabIds[selectedKey!],
+ } as IPivotState;
+
+ this._renderPivotLink = this._renderPivotLink.bind(this);
+ }
+
+ public componentWillReceiveProps(nextProps: IPivotProps): void {
+ const links: IPivotItemProps[] = this._getPivotLinks(nextProps);
+
+ this.setState((prevState, props) => {
+ let selectedKey: string | undefined;
+ if (this._isKeyValid(nextProps.selectedKey)) {
+ selectedKey = nextProps.selectedKey;
+ } else if (this._isKeyValid(prevState.selectedKey)) {
+ selectedKey = prevState.selectedKey;
+ } else if (links.length) {
+ selectedKey = links[0].itemKey;
+ }
+
+ return {
+ links: links,
+ selectedKey,
+ selectedTabId: this._keyToTabIds[selectedKey as string],
+ } as IPivotState;
+ });
+ }
+
+ /**
+ * Sets focus to the first pivot tab.
+ */
+ public focus(): void {
+ if (this.focusZone.current) {
+ this.focusZone.current.focus();
+ }
+ }
+
+ public render(): JSX.Element {
+ return (
+
+ { this._renderPivotLinks() }
+ { this._renderPivotItem() }
+
+ );
+ }
+
+ /**
+ * Renders the set of links to route between pivots
+ */
+ private _renderPivotLinks(): JSX.Element {
+ return (
+
+
+ { this.state.links.map(this._renderPivotLink) }
+
+
+ );
+ }
+
+ private _renderPivotLink = (link: IPivotItemProps): JSX.Element => {
+ const { itemKey, headerButtonProps } = link;
+ const tabId = this._keyToTabIds[itemKey as string];
+ const { onRenderItemLink } = link;
+ let linkContent: JSX.Element | null;
+
+ if (onRenderItemLink) {
+ linkContent = onRenderItemLink(link, this._renderLinkContent);
+ } else {
+ linkContent = this._renderLinkContent(link);
+ }
+
+ return (
+
+ { linkContent }
+
+ );
+ }
+
+ private _renderLinkContent = (link: IPivotItemProps): JSX.Element => {
+ const { itemCount, itemIcon, headerText } = link;
+
+ return (
+
+ { itemIcon !== undefined && (
+
+
+
+ ) }
+ { headerText !== undefined && { link.headerText } }
+ { itemCount !== undefined && ({ itemCount }) }
+
+ );
+ }
+
+ /**
+ * Renders the current Pivot Item
+ */
+ private _renderPivotItem(): JSX.Element | null {
+ if (this.props.headersOnly) {
+ return null;
+ }
+
+ const itemKey: string = this.state.selectedKey;
+ const index = this._keyToIndexMapping[itemKey];
+ const { selectedTabId } = this.state;
+
+ return (
+
+ { React.Children.toArray(this.props.children)[index] }
+
+ );
+ }
+
+ /**
+ * Gets the set of PivotLinks as arrary of IPivotItemProps
+ * The set of Links is determined by child components of type PivotItem
+ */
+ private _getPivotLinks(props: IPivotProps): IPivotItemProps[] {
+ const links: IPivotItemProps[] = [];
+ this._keyToIndexMapping = {};
+ this._keyToTabIds = {};
+
+ React.Children.map(props.children, (child: any, index: number) => {
+ if (typeof child === 'object' && child.type === PivotItem) {
+ const pivotItem = child as PivotItem;
+ const itemKey = pivotItem.props.itemKey || index.toString();
+
+ links.push({
+ headerText: pivotItem.props.headerText || pivotItem.props.linkText,
+ headerButtonProps: pivotItem.props.headerButtonProps,
+ ariaLabel: pivotItem.props.ariaLabel,
+ itemKey: itemKey,
+ itemCount: pivotItem.props.itemCount,
+ itemIcon: pivotItem.props.itemIcon,
+ onRenderItemLink: pivotItem.props.onRenderItemLink
+ });
+ this._keyToIndexMapping[itemKey] = index;
+ this._keyToTabIds[itemKey] = this._getTabId(itemKey, index);
+ }
+ });
+
+ return links;
+ }
+
+ /**
+ * Generates the Id for the tab button.
+ */
+ private _getTabId(itemKey: string, index: number): string {
+ if (this.props.getTabId) {
+ return this.props.getTabId(itemKey, index);
+ }
+
+ return this._pivotId + `-Tab${index}`;
+ }
+
+ /**
+ * whether the key exists in the pivot items.
+ */
+ private _isKeyValid(itemKey: string | undefined): boolean {
+ return itemKey !== undefined && this._keyToIndexMapping[itemKey] !== undefined;
+ }
+
+ /**
+ * Handles the onClick event on PivotLinks
+ */
+ private _onLinkClick(itemKey: string, ev: React.MouseEvent): void {
+ ev.preventDefault();
+ this._updateSelectedItem(itemKey, ev);
+ }
+
+ /**
+ * Handle the onKeyPress eventon the PivotLinks
+ */
+ private _onKeyPress(itemKey: string, ev: React.KeyboardEvent): void {
+ ev.preventDefault();
+ if (ev.which === KeyCodes.enter) {
+ this._updateSelectedItem(itemKey);
+ }
+ }
+
+ /**
+ * Updates the state with the new selected index
+ */
+ private _updateSelectedItem(itemKey: string, ev?: React.MouseEvent): void {
+ this.setState({
+ selectedKey: itemKey,
+ selectedTabId: this._keyToTabIds[itemKey]
+ } as IPivotState);
+
+ if (this.props.onLinkClick && this._keyToIndexMapping[itemKey] >= 0) {
+ const index = this._keyToIndexMapping[itemKey];
+
+ // React.Element cannot directly convert to PivotItem.
+ const item = React.Children.toArray(this.props.children)[index] as any;
+
+ if (typeof item === 'object' && item.type === PivotItem) {
+ this.props.onLinkClick(item as PivotItem, ev);
+ }
+ }
+ }
+}
diff --git a/packages/office-ui-fabric-react/src/components/Pivot/Pivot.styles.ts b/packages/office-ui-fabric-react/src/components/Pivot/Pivot.styles.ts
new file mode 100644
index 0000000000000..2850c2c7743ac
--- /dev/null
+++ b/packages/office-ui-fabric-react/src/components/Pivot/Pivot.styles.ts
@@ -0,0 +1,63 @@
+import { IPivotStyleProps, IPivotStyles } from './Pivot.types';
+import {
+ normalize,
+ FontSizes,
+ FontWeights,
+} from '../../Styling';
+
+export const getStyles = (
+ props: IPivotStyleProps
+): IPivotStyles => {
+ const {
+ className,
+ theme,
+ } = props;
+
+ const { palette } = theme;
+
+ return ({
+ root: [
+ 'ms-Pivot',
+ normalize,
+ {
+ fontSize: FontSizes.medium,
+ fontWeight: FontWeights.regular,
+ position: 'relative',
+ color: palette.themePrimary,
+ whiteSpace: 'nowrap',
+ },
+ className
+ ],
+
+ links: [
+ 'ms-Pivot-links',
+ {}
+ ],
+
+ link: [
+ 'ms-Pivot-link',
+ {}
+ ],
+
+ text: [
+ 'ms-Pivot-text',
+ {}
+ ],
+
+ count: [
+ 'ms-Pivot-count',
+ {}
+ ],
+
+ icon: [
+ 'ms-Pivot-icon',
+ {}
+ ],
+
+ ellipsis: [
+ 'ms-Pivot-ellipsis',
+ {}
+ ],
+
+ });
+};
\ No newline at end of file
diff --git a/packages/office-ui-fabric-react/src/components/Pivot/Pivot.tsx b/packages/office-ui-fabric-react/src/components/Pivot/Pivot.tsx
index aa686955bf417..8bb22e4f3eb59 100644
--- a/packages/office-ui-fabric-react/src/components/Pivot/Pivot.tsx
+++ b/packages/office-ui-fabric-react/src/components/Pivot/Pivot.tsx
@@ -1,291 +1,18 @@
-import * as React from 'react';
+import { styled } from '../../Utilities';
import {
- BaseComponent,
- KeyCodes,
- css,
- getId,
- createRef
-} from '../../Utilities';
-import { CommandButton } from '../../Button';
-import { IPivotProps } from './Pivot.types';
-import { IPivotItemProps } from './PivotItem.types';
-import { FocusZone, FocusZoneDirection } from '../../FocusZone';
-import { PivotItem } from './PivotItem';
-import { PivotLinkFormat } from './Pivot.types';
-import { PivotLinkSize } from './Pivot.types';
-import { Icon } from '../../Icon';
-import * as stylesImport from './Pivot.scss';
-const styles: any = stylesImport;
+ IPivotProps,
+ IPivotStyleProps,
+ IPivotStyles
+} from './Pivot.types';
+import { PivotBase } from './Pivot.base';
+import { getStyles } from './Pivot.styles';
/**
- * Usage:
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
+ * The Pivot control and related tabs pattern are used for navigating frequently accessed,
+ * distinct content categories. Pivots allow for navigation between two or more content
+ * views and relies on text headers to articulate the different sections of content.
*/
-
-export interface IPivotState {
- links: IPivotItemProps[];
- selectedKey: string;
- selectedTabId: string;
-}
-
-export class Pivot extends BaseComponent {
- private _keyToIndexMapping: { [key: string]: number };
- private _keyToTabIds: { [key: string]: string };
- private _pivotId: string;
- private focusZone = createRef();
-
- constructor(props: IPivotProps) {
- super(props);
- this._pivotId = getId('Pivot');
- const links: IPivotItemProps[] = this._getPivotLinks(this.props);
- let selectedKey: string | undefined;
-
- if (props.initialSelectedKey) {
- selectedKey = props.initialSelectedKey;
- } else if (props.initialSelectedIndex) {
- selectedKey = links[props.initialSelectedIndex].itemKey as string;
- } else if (props.selectedKey) {
- selectedKey = props.selectedKey;
- } else if (links.length) {
- selectedKey = links[0].itemKey as string;
- }
-
- this.state = {
- links,
- selectedKey: selectedKey!,
- selectedTabId: this._keyToTabIds[selectedKey!],
- } as IPivotState;
-
- this._renderPivotLink = this._renderPivotLink.bind(this);
- }
-
- public componentWillReceiveProps(nextProps: IPivotProps): void {
- const links: IPivotItemProps[] = this._getPivotLinks(nextProps);
-
- this.setState((prevState, props) => {
- let selectedKey: string | undefined;
- if (this._isKeyValid(nextProps.selectedKey)) {
- selectedKey = nextProps.selectedKey;
- } else if (this._isKeyValid(prevState.selectedKey)) {
- selectedKey = prevState.selectedKey;
- } else if (links.length) {
- selectedKey = links[0].itemKey;
- }
-
- return {
- links: links,
- selectedKey,
- selectedTabId: this._keyToTabIds[selectedKey as string],
- } as IPivotState;
- });
- }
-
- /**
- * Sets focus to the first pivot tab.
- */
- public focus(): void {
- if (this.focusZone.current) {
- this.focusZone.current.focus();
- }
- }
-
- public render(): JSX.Element {
- return (
-
- { this._renderPivotLinks() }
- { this._renderPivotItem() }
-
- );
- }
-
- /**
- * Renders the set of links to route between pivots
- */
- private _renderPivotLinks(): JSX.Element {
- return (
-
-
- { this.state.links.map(this._renderPivotLink) }
-
-
- );
- }
-
- private _renderPivotLink = (link: IPivotItemProps): JSX.Element => {
- const { itemKey, headerButtonProps } = link;
- const tabId = this._keyToTabIds[itemKey as string];
- const { onRenderItemLink } = link;
- let linkContent: JSX.Element | null;
-
- if (onRenderItemLink) {
- linkContent = onRenderItemLink(link, this._renderLinkContent);
- } else {
- linkContent = this._renderLinkContent(link);
- }
-
- return (
-
- { linkContent }
-
- );
- }
-
- private _renderLinkContent = (link: IPivotItemProps): JSX.Element => {
- const { itemCount, itemIcon, headerText } = link;
-
- return (
-
- { itemIcon !== undefined && (
-
-
-
- ) }
- { headerText !== undefined && { link.headerText } }
- { itemCount !== undefined && ({ itemCount }) }
-
- );
- }
-
- /**
- * Renders the current Pivot Item
- */
- private _renderPivotItem(): JSX.Element | null {
- if (this.props.headersOnly) {
- return null;
- }
-
- const itemKey: string = this.state.selectedKey;
- const index = this._keyToIndexMapping[itemKey];
- const { selectedTabId } = this.state;
-
- return (
-
- { React.Children.toArray(this.props.children)[index] }
-
- );
- }
-
- /**
- * Gets the set of PivotLinks as arrary of IPivotItemProps
- * The set of Links is determined by child components of type PivotItem
- */
- private _getPivotLinks(props: IPivotProps): IPivotItemProps[] {
- const links: IPivotItemProps[] = [];
- this._keyToIndexMapping = {};
- this._keyToTabIds = {};
-
- React.Children.map(props.children, (child: any, index: number) => {
- if (typeof child === 'object' && child.type === PivotItem) {
- const pivotItem = child as PivotItem;
- const itemKey = pivotItem.props.itemKey || index.toString();
-
- links.push({
- headerText: pivotItem.props.headerText || pivotItem.props.linkText,
- headerButtonProps: pivotItem.props.headerButtonProps,
- ariaLabel: pivotItem.props.ariaLabel,
- itemKey: itemKey,
- itemCount: pivotItem.props.itemCount,
- itemIcon: pivotItem.props.itemIcon,
- onRenderItemLink: pivotItem.props.onRenderItemLink
- });
- this._keyToIndexMapping[itemKey] = index;
- this._keyToTabIds[itemKey] = this._getTabId(itemKey, index);
- }
- });
-
- return links;
- }
-
- /**
- * Generates the Id for the tab button.
- */
- private _getTabId(itemKey: string, index: number): string {
- if (this.props.getTabId) {
- return this.props.getTabId(itemKey, index);
- }
-
- return this._pivotId + `-Tab${index}`;
- }
-
- /**
- * whether the key exists in the pivot items.
- */
- private _isKeyValid(itemKey: string | undefined): boolean {
- return itemKey !== undefined && this._keyToIndexMapping[itemKey] !== undefined;
- }
-
- /**
- * Handles the onClick event on PivotLinks
- */
- private _onLinkClick(itemKey: string, ev: React.MouseEvent): void {
- ev.preventDefault();
- this._updateSelectedItem(itemKey, ev);
- }
-
- /**
- * Handle the onKeyPress eventon the PivotLinks
- */
- private _onKeyPress(itemKey: string, ev: React.KeyboardEvent): void {
- ev.preventDefault();
- if (ev.which === KeyCodes.enter) {
- this._updateSelectedItem(itemKey);
- }
- }
-
- /**
- * Updates the state with the new selected index
- */
- private _updateSelectedItem(itemKey: string, ev?: React.MouseEvent): void {
- this.setState({
- selectedKey: itemKey,
- selectedTabId: this._keyToTabIds[itemKey]
- } as IPivotState);
-
- if (this.props.onLinkClick && this._keyToIndexMapping[itemKey] >= 0) {
- const index = this._keyToIndexMapping[itemKey];
-
- // React.Element cannot directly convert to PivotItem.
- const item = React.Children.toArray(this.props.children)[index] as any;
-
- if (typeof item === 'object' && item.type === PivotItem) {
- this.props.onLinkClick(item as PivotItem, ev);
- }
- }
- }
-}
+export const Pivot = styled(
+ PivotBase,
+ getStyles
+);
diff --git a/packages/office-ui-fabric-react/src/components/Pivot/Pivot.types.ts b/packages/office-ui-fabric-react/src/components/Pivot/Pivot.types.ts
index 594dabd61284c..45f9286e8fb41 100644
--- a/packages/office-ui-fabric-react/src/components/Pivot/Pivot.types.ts
+++ b/packages/office-ui-fabric-react/src/components/Pivot/Pivot.types.ts
@@ -1,6 +1,7 @@
import * as React from 'react';
-
-import { Pivot } from './Pivot';
+import { PivotBase } from './Pivot.base';
+import { IStyle, ITheme } from '../../Styling';
+import { IStyleFunction } from '../../Utilities';
import { PivotItem } from './PivotItem';
export interface IPivot {
@@ -10,13 +11,29 @@ export interface IPivot {
focus(): void;
}
-export interface IPivotProps extends React.Props {
+export interface IPivotProps extends React.Props {
/**
* Optional callback to access the IPivot interface. Use this instead of ref for accessing
* the public methods and properties of the component.
*/
componentRef?: (component: IPivot | null) => void;
+ /**
+ * Call to provide customized styling that will layer on top of the variant rules.
+ */
+ getStyles?: IStyleFunction;
+
+ /**
+ * Theme provided by High-Order Component.
+ */
+ theme?: ITheme;
+
+ /**
+ * Additional css class to apply to the Pivot
+ * @defaultvalue undefined
+ */
+ className?: string;
+
/**
* The index of the pivot item initially selected.
*
@@ -67,6 +84,36 @@ export interface IPivotProps extends React.Props {
getTabId?: (itemKey: string, index: number) => string;
}
+export interface IPivotStyleProps {
+ /**
+ * Theme provided by High-Order Component.
+ */
+ theme: ITheme;
+
+ /**
+ * Accept custom classNames
+ */
+ className?: string;
+ linkIsSelected?: boolean;
+ linkIsDisabled?: boolean;
+ linkIsOverflow?: boolean;
+ rootIsLarge?: boolean;
+ rootIsTabs?: boolean;
+}
+
+export interface IPivotStyles {
+ /**
+ * Style for the root element.
+ */
+ root: IStyle;
+ links: IStyle;
+ link: IStyle;
+ text: IStyle;
+ count: IStyle;
+ icon: IStyle;
+ ellipsis: IStyle;
+}
+
export enum PivotLinkFormat {
/**
* Display Pivot Links as links
@@ -90,4 +137,4 @@ export enum PivotLinkSize {
* Display links using large font size
*/
large = 1
-}
+}
\ No newline at end of file
diff --git a/packages/office-ui-fabric-react/src/components/Pivot/index.ts b/packages/office-ui-fabric-react/src/components/Pivot/index.ts
index 666c1856e32a4..99040588b37c6 100644
--- a/packages/office-ui-fabric-react/src/components/Pivot/index.ts
+++ b/packages/office-ui-fabric-react/src/components/Pivot/index.ts
@@ -1,4 +1,5 @@
export * from './Pivot';
+export * from './Pivot.base';
export { PivotItem as PivotItem } from './PivotItem';
export * from './Pivot.types';
export * from './PivotItem.types';