diff --git a/common/changes/office-ui-fabric-react/staylo-AddErrorAsToIcon_2018-02-16-22-54.json b/common/changes/office-ui-fabric-react/staylo-AddErrorAsToIcon_2018-02-16-22-54.json new file mode 100644 index 00000000000000..e86b4124bafa32 --- /dev/null +++ b/common/changes/office-ui-fabric-react/staylo-AddErrorAsToIcon_2018-02-16-22-54.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "office-ui-fabric-react", + "comment": "Add imageErrorAs to IIconProps", + "type": "minor" + } + ], + "packageName": "office-ui-fabric-react", + "email": "staylo@microsoft.com" +} \ No newline at end of file diff --git a/packages/office-ui-fabric-react/src/components/ActivityItem/__snapshots__/ActivityItem.test.tsx.snap b/packages/office-ui-fabric-react/src/components/ActivityItem/__snapshots__/ActivityItem.test.tsx.snap index b3acb36fff522c..e861f560710775 100644 --- a/packages/office-ui-fabric-react/src/components/ActivityItem/__snapshots__/ActivityItem.test.tsx.snap +++ b/packages/office-ui-fabric-react/src/components/ActivityItem/__snapshots__/ActivityItem.test.tsx.snap @@ -173,7 +173,6 @@ exports[`ActivityItem renders compact with an icon correctly 1`] = ` > { directionalHint: DirectionalHint.bottomLeftEdge } } /> - { Icon({ - className: css('ms-Breadcrumb-chevron', styles.chevron), - iconName: getRTL() ? 'ChevronLeft' : 'ChevronRight' - }) } + { } ) } { renderedItems.map( diff --git a/packages/office-ui-fabric-react/src/components/Breadcrumb/__snapshots__/Breadcrumb.test.tsx.snap b/packages/office-ui-fabric-react/src/components/Breadcrumb/__snapshots__/Breadcrumb.test.tsx.snap index 30ff42150359c8..9ea260d7df8d62 100644 --- a/packages/office-ui-fabric-react/src/components/Breadcrumb/__snapshots__/Breadcrumb.test.tsx.snap +++ b/packages/office-ui-fabric-react/src/components/Breadcrumb/__snapshots__/Breadcrumb.test.tsx.snap @@ -44,7 +44,6 @@ exports[`Breadcrumb renders breadcumb correctly 1`] = ` + ); } return null; } diff --git a/packages/office-ui-fabric-react/src/components/Button/__snapshots__/Button.test.tsx.snap b/packages/office-ui-fabric-react/src/components/Button/__snapshots__/Button.test.tsx.snap index 0fbc1378c8cfc1..c2803b1370a6ba 100644 --- a/packages/office-ui-fabric-react/src/components/Button/__snapshots__/Button.test.tsx.snap +++ b/packages/office-ui-fabric-react/src/components/Button/__snapshots__/Button.test.tsx.snap @@ -180,7 +180,6 @@ exports[`Button renders CommandBarButton correctly 1`] = ` > { } ) } > - { Icon({ - className: 'ms-Check-circle ' + styles.circle, - iconName: 'CircleRing' - }) } - { Icon({ - className: 'ms-Check-check ' + styles.check, - iconName: 'StatusCircleCheckmark' - }) } + { } + { } ); } diff --git a/packages/office-ui-fabric-react/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap b/packages/office-ui-fabric-react/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap index 56ab252f499ae8..01505cb4f7b2f4 100644 --- a/packages/office-ui-fabric-react/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap +++ b/packages/office-ui-fabric-react/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap @@ -106,7 +106,6 @@ exports[`Checkbox renders Checkbox correctly 1`] = ` > - { Icon({ iconName: 'Search' }) } + { }
{ - const { - ariaLabel, - className, - styles, - iconName - } = props; - const classNames = getClassNames( - styles - ); +export interface IIconState { + imageLoadError: boolean; +} - if (props.iconType === IconType.image || props.iconType === IconType.Image) { - const containerClassName = css( - 'ms-Icon-imageContainer', - classNames.root, - classNames.imageContainer, - className - ); +export class Icon extends BaseComponent { + constructor(props: IIconProps) { + super(props); + this.state = { + imageLoadError: false, + }; + } - return ( -
- -
- ); - } else if (typeof iconName === 'string' && iconName.length === 0) { - return ( - + public render() { + const { + ariaLabel, + className, + styles, + iconName, + imageErrorAs, + } = this.props; + const classNames = getClassNames( + styles ); - } else { - const iconDefinition = getIcon(iconName) || { - subset: { - className: undefined - }, - code: undefined + + const containerProps = ariaLabel ? { 'aria-label': ariaLabel, 'data-icon-name': iconName, } : { + role: 'presentation', + 'aria-hidden': true, + 'data-icon-name': iconName, }; - return ( - - { iconDefinition.code } - - ); + if (this.props.iconType === IconType.image || this.props.iconType === IconType.Image) { + const containerClassName = css( + 'ms-Icon-imageContainer', + classNames.root, + classNames.imageContainer, + className + ); + const { imageLoadError } = this.state; + const imageProps = { ...this.props.imageProps, onLoadingStateChange: this.onImageLoadingStateChange }; + const ImageType = imageLoadError && imageErrorAs || Image; + return ( +
+ +
+ ); + } else if (typeof iconName === 'string' && iconName.length === 0) { + return ( + + ); + } else { + const iconDefinition = getIcon(iconName) || { + subset: { + className: undefined + }, + code: undefined + }; + + return ( + + { iconDefinition.code } + + ); + } + } + + private onImageLoadingStateChange = (state: ImageLoadState): void => { + if (this.props.imageProps && this.props.imageProps.onLoadingStateChange) { + this.props.imageProps.onLoadingStateChange(state); + } + if (state === ImageLoadState.error) { + this.setState({ imageLoadError: true }); + } } -}; +} diff --git a/packages/office-ui-fabric-react/src/components/Icon/Icon.types.ts b/packages/office-ui-fabric-react/src/components/Icon/Icon.types.ts index c776f1cfcee22f..378e791046a087 100644 --- a/packages/office-ui-fabric-react/src/components/Icon/Icon.types.ts +++ b/packages/office-ui-fabric-react/src/components/Icon/Icon.types.ts @@ -1,6 +1,8 @@ import * as React from 'react'; import { IImageProps } from '../Image/Image.types'; import { IStyle } from '../../Styling'; +import { Icon } from './Icon'; +import { IBaseProps } from '../../Utilities'; // Please keep alphabetized export enum IconType { @@ -34,7 +36,7 @@ export interface IIconStyles { imageContainer?: IStyle; } -export interface IIconProps extends React.HTMLAttributes { +export interface IIconProps extends IBaseProps, React.HTMLAttributes { /** * The name of the icon to use from the icon font. If string is empty, a placeholder icon will be rendered the same width as an icon */ @@ -65,4 +67,9 @@ export interface IIconProps extends React.HTMLAttributes { * @memberOf IIconProps */ imageProps?: IImageProps; + + /** + * If rendering an image icon, this function callback will be invoked in the event loading the image errors. + */ + imageErrorAs?: React.StatelessComponent | React.ComponentClass; } \ No newline at end of file diff --git a/packages/office-ui-fabric-react/src/components/Icon/__snapshots__/Icon.test.tsx.snap b/packages/office-ui-fabric-react/src/components/Icon/__snapshots__/Icon.test.tsx.snap index 3b1bc246f97218..ab530ac055dbe0 100644 --- a/packages/office-ui-fabric-react/src/components/Icon/__snapshots__/Icon.test.tsx.snap +++ b/packages/office-ui-fabric-react/src/components/Icon/__snapshots__/Icon.test.tsx.snap @@ -3,7 +3,6 @@ exports[`Icon renders Icon correctly 1`] = `