diff --git a/common/changes/@uifabric/experiments/v-vibr-ShimmerComponent_2018-03-06-18-42.json b/common/changes/@uifabric/experiments/v-vibr-ShimmerComponent_2018-03-06-18-42.json new file mode 100644 index 0000000000000..463a9790d75ce --- /dev/null +++ b/common/changes/@uifabric/experiments/v-vibr-ShimmerComponent_2018-03-06-18-42.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@uifabric/experiments", + "comment": "Adds a new Shimmer Component to experiments package.", + "type": "minor" + } + ], + "packageName": "@uifabric/experiments", + "email": "v-vibr@microsoft.com" +} \ No newline at end of file diff --git a/common/changes/@uifabric/experiments/v-vibr-Shimmer_2018-03-13-19-06.json b/common/changes/@uifabric/experiments/v-vibr-Shimmer_2018-03-13-19-06.json new file mode 100644 index 0000000000000..54306e0a14cff --- /dev/null +++ b/common/changes/@uifabric/experiments/v-vibr-Shimmer_2018-03-13-19-06.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@uifabric/experiments", + "comment": "Changes in the props and naming.", + "type": "minor" + } + ], + "packageName": "@uifabric/experiments", + "email": "v-vibr@microsoft.com" +} \ No newline at end of file diff --git a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx index 70ce162d2824e..4d7c4b60eea86 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx +++ b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx @@ -17,15 +17,19 @@ import { DefaultPalette, IStyleSet } from '../../Styling'; -import { ShimmerRectangle } from './ShimmerRectangle/ShimmerRectangle'; +import { ShimmerLine } from './ShimmerLine/ShimmerLine'; import { ShimmerCircle } from './ShimmerCircle/ShimmerCircle'; +const LINE_DEFAULT_HEIGHT = 16; +const CIRCLE_DEFAULT_HEIGHT = 24; + const getClassNames = classNamesFunction(); export class ShimmerBase extends BaseComponent { public static defaultProps: IShimmerProps = { width: 100, - isDataLoaded: false + isDataLoaded: false, + isBaseStyle: false }; private _classNames: {[key in keyof IShimmerStyles]: string}; constructor(props: IShimmerProps) { @@ -33,14 +37,17 @@ export class ShimmerBase extends BaseComponent { } public render(): JSX.Element { - const { getStyles, width, lineElements, children, isDataLoaded } = this.props; + const { getStyles, width, lineElements, children, isDataLoaded, isBaseStyle } = this.props; const maxHeight: number | undefined = lineElements ? this._findMaxHeight(lineElements) : undefined; - this._classNames = getClassNames(getStyles!, { width, maxHeight, isDataLoaded }); + this._classNames = getClassNames(getStyles!, { width, maxHeight, isDataLoaded, isBaseStyle }); const elements: JSX.Element[] | JSX.Element = lineElements ? lineElements.map((elem: ICircle | ILine | IGap, index: number): JSX.Element => { switch (elem.type) { case ShimmerElementType.CIRCLE: + if (!elem.height) { + elem.height = CIRCLE_DEFAULT_HEIGHT; + } return ( { /> ); case ShimmerElementType.GAP: - const gapWidth = elem.width ? elem.width + '%' : '1%'; + const gapWidth = elem.widthInPercentage || elem.widthInPixel ? + elem.widthInPercentage ? elem.widthInPercentage + '%' : elem.widthInPixel + 'px' + : '5px'; return (
{ } } /> ); - case ShimmerElementType.RECTANGLE: + case ShimmerElementType.LINE: + if (!elem.height) { + elem.height = LINE_DEFAULT_HEIGHT; + } return ( - ); } - }) : - ; + }) : ( + + ); return (
- { elements } -
-
- { !!isDataLoaded ? - !!children ? children : null - : null } + { !!isBaseStyle ? children : elements }
+ + { !!isDataLoaded && +
+ { !!children ? children : null } +
+ }
); } private _findMaxHeight(items: Array): number { - const maxHeight = items.reduce((acc: number, next: ICircle | IGap | ILine): number => { + const itemsDefaulted: Array = items.map((item: ICircle | IGap | ILine): ICircle | IGap | ILine => { + switch (item.type) { + case ShimmerElementType.CIRCLE: + if (!item.height) { + item.height = CIRCLE_DEFAULT_HEIGHT; + } + case ShimmerElementType.LINE: + if (!item.height) { + item.height = LINE_DEFAULT_HEIGHT; + } + } + return item; + }); + + const maxHeight = itemsDefaulted.reduce((acc: number, next: ICircle | IGap | ILine): number => { return next.height ? next.height > acc ? next.height : acc : acc; @@ -97,19 +127,11 @@ export class ShimmerBase extends BaseComponent { } private _getBorderAlignStyles(maxHeight: number | undefined, elem: ICircle | IGap | ILine): IStyleSet | undefined { - let height: number | undefined; - switch (elem.type) { - case ShimmerElementType.RECTANGLE: - height = !!elem.height ? elem.height : 16; - break; - case ShimmerElementType.CIRCLE: - height = !!elem.height ? elem.height : 24; - break; - } - console.log(height); - const dif: number | undefined = maxHeight && height ? - maxHeight - height > 0 ? - maxHeight - height : undefined + const elemHeight: number | undefined = elem.height; + + const dif: number | undefined = maxHeight && elemHeight ? + maxHeight - elemHeight > 0 ? + maxHeight - elemHeight : undefined : undefined; let borderStyle: IStyleSet | undefined; diff --git a/packages/experiments/src/components/Shimmer/Shimmer.styles.ts b/packages/experiments/src/components/Shimmer/Shimmer.styles.ts index ef1f852e36b7a..78dd50cdf8fd2 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.styles.ts +++ b/packages/experiments/src/components/Shimmer/Shimmer.styles.ts @@ -8,15 +8,18 @@ export function getStyles(props: IShimmerStyleProps): IShimmerStyles { const { width, maxHeight, - isDataLoaded + isDataLoaded, + isBaseStyle } = props; + const BACKGROUND_OFF_SCREEN_POSITION = '1000%'; + const shimmerAnimation: string = keyframes({ '0%': { - backgroundPosition: '-900%' + backgroundPosition: `-${BACKGROUND_OFF_SCREEN_POSITION}` }, '100%': { - backgroundPosition: '1000%' + backgroundPosition: BACKGROUND_OFF_SCREEN_POSITION } }); @@ -26,8 +29,15 @@ export function getStyles(props: IShimmerStyleProps): IShimmerStyles { { position: 'relative', margin: '10px', + width: 'auto', boxSizing: 'content-box', minHeight: maxHeight ? `${maxHeight}px` : '16px' + }, + isBaseStyle && { + margin: '0', + minHeight: 'inherit', + display: 'flex', + alignItems: 'center' } ], shimmerWrapper: [ @@ -60,6 +70,10 @@ export function getStyles(props: IShimmerStyleProps): IShimmerStyles { isDataLoaded && { opacity: '0', visibility: 'hidden' + }, + isBaseStyle && { + position: 'static', + width: 'auto' } ], dataWrapper: [ diff --git a/packages/experiments/src/components/Shimmer/Shimmer.types.ts b/packages/experiments/src/components/Shimmer/Shimmer.types.ts index e5fe6b32ca4b9..2a221f9ff398f 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.types.ts +++ b/packages/experiments/src/components/Shimmer/Shimmer.types.ts @@ -19,7 +19,7 @@ export interface IShimmerProps extends React.AllHTMLAttributes { componentRef?: (component: IShimmer) => void; /** - * Sets the width of the shimmer wave container in percentages. + * Sets the width of the shimmer wave wrapper in percentages. * @default 100% */ width?: number; @@ -30,6 +30,12 @@ export interface IShimmerProps extends React.AllHTMLAttributes { */ isDataLoaded?: boolean; + /** + * Provide when Shimmer is intended to be used when using 'onRenderMissingItem' optional callback of the DetailsList Fabric Component. + * @default false + */ + isBaseStyle?: boolean; + /** * Elements to render in one line of the Shimmer. */ @@ -48,19 +54,25 @@ export interface IShimmerElement { type: ShimmerElementType; /** - * The hight of the element (ICircle, ILine, IGap). + * The hight of the element in pixels (ICircle, ILine). * Read more details for each specific element. */ height?: number; /** - * The width of the element (ICircle, ILine, IGap). + * The width of the element in pixels (ILine, IGap). * Read more details for each specific element. */ - width?: number; + widthInPixel?: number; /** - * The vertical alignemt of the element (ICircle, ILine, IGap). + * The width of the element in pixels (ILine, IGap). + * Read more details for each specific element. + */ + widthInPercentage?: number; + + /** + * The vertical alignemt of the element (ICircle, ILine). * @default center */ verticalAlign?: ShimmerElementVerticalAlign; @@ -68,52 +80,49 @@ export interface IShimmerElement { export interface ILine extends IShimmerElement { /** - * Sets the height of the rectangle. - * The value will represent the height in pixels. - * @default 16 + * Sets the height of the shimmer line in pixels. + * @default 16px */ height?: number; /** - * If not provided the line will the take the remaining space to fill the shimmer container. - * The value provided will represent the width as '%' relative to the shimmer container. + * The value provided will represent the width as '%' relative to the shimmer wrapper. */ - width?: number; -} + widthInPercentage?: number; -export interface ICircle extends IShimmerElement { /** - * Sets the height of the circle. - * The value will represent the height in pixels. - * @default 24 + * Sets the width of the Line to an exact value in pixels. + * @default 50px */ - height?: number; + widthInPixel?: number; +} +export interface ICircle extends IShimmerElement { /** - * Width of the circle element if provided will be ignored. - * The value will be set equal to the height of the circle for scale ratio reasons. + * Sets the height of the shimmer circle in pixels. + * @default 24px */ - width?: number; + height?: number; } export interface IGap extends IShimmerElement { /** - * Height for gap element will be ignored and set equal to the heighest element on the line. + * The value will be calculated as '%' relative the to shimmer wrapper. */ - height?: number; + widthInPercentage?: number; /** - * Sets the width relative to the shimmer container width for responsiveness reasons. - * The value will be calculated as '%' relative the to shimmer container. - * @default 1% + * Sets the width of the Gap to an exact value in pixels. + * @default 5px */ - width?: number; + widthInPixel?: number; } export interface IShimmerStyleProps { width?: number; maxHeight?: number; isDataLoaded?: boolean; + isBaseStyle?: boolean; } export interface IShimmerStyles { @@ -123,7 +132,7 @@ export interface IShimmerStyles { } export const enum ShimmerElementType { - RECTANGLE = 'line', + LINE = 'line', CIRCLE = 'circle', GAP = 'gap' } diff --git a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.base.tsx b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.base.tsx index b5c88d108ca59..3c045acd15f1b 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.base.tsx +++ b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.base.tsx @@ -7,15 +7,13 @@ import { IShimmerCircleProps, IShimmerCircleStyleProps, IShimmerCircleStyles -} from './ShimmerCircle.styles'; +} from './ShimmerCircle.types'; const getClassNames = classNamesFunction(); export class ShimmerCircleBase extends BaseComponent { - public static defaultProps: IShimmerCircleProps = { - height: 24 - }; private _classNames: {[key in keyof IShimmerCircleStyles]: string}; + constructor(props: IShimmerCircleProps) { super(props); } diff --git a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts index f3947ce7061e9..9f8677cd3a8c8 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts @@ -1,51 +1,11 @@ -import * as React from 'react'; import { - IStyle, - DefaultPalette, - IStyleSet -} from '../../../Styling'; -import { IStyleFunction } from '../../../Utilities'; - -export interface IShimmerCircle { - -} - -/** - * ShimmerCircle component props. - */ -export interface IShimmerCircleProps extends React.AllHTMLAttributes { - /** - * Optional callback to access the IShimmerCircle interface. Use this instead of ref for accessing - * the public methods and properties of the component. - */ - componentRef?: (component: IShimmerCircle) => void; - - /** - * Sets the height of the circle. - * @default 24px - */ - height?: number; - - /** - * Used to - */ - borderAlignStyle?: IStyleSet; - - /** - * Call to provide customized styling that will layer on top of the variant rules. - */ - getStyles?: IStyleFunction; -} - -export interface IShimmerCircleStyleProps { - height?: number; - borderAlignStyle?: IStyleSet; -} - -export interface IShimmerCircleStyles { - root?: IStyle; - svg?: IStyle; -} + IShimmerCircleStyleProps, + IShimmerCircleStyles +} from './ShimmerCircle.types'; +import { + IStyleSet, + DefaultPalette +} from 'office-ui-fabric-react'; export function getStyles(props: IShimmerCircleStyleProps): IShimmerCircleStyles { const { diff --git a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.tsx b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.tsx index 594bb1b89f052..63b114832079d 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.tsx +++ b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.tsx @@ -1,7 +1,12 @@ import { styled } from '../../../Utilities'; -import { getStyles, IShimmerCircleProps, IShimmerCircleStyleProps, IShimmerCircleStyles } from './ShimmerCircle.styles'; +import { getStyles } from './ShimmerCircle.styles'; +import { + IShimmerCircleProps, + IShimmerCircleStyleProps, + IShimmerCircleStyles +} from './ShimmerCircle.types'; import { ShimmerCircleBase } from './ShimmerCircle.base'; export const ShimmerCircle = styled( diff --git a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.types.ts b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.types.ts new file mode 100644 index 0000000000000..4f5511464fd16 --- /dev/null +++ b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.types.ts @@ -0,0 +1,47 @@ +import * as React from 'react'; +import { + IStyle, + IStyleSet +} from '../../../Styling'; +import { IStyleFunction } from '../../../Utilities'; + +export interface IShimmerCircle { + +} + +/** + * ShimmerCircle component props. + */ +export interface IShimmerCircleProps extends React.AllHTMLAttributes { + /** + * Optional callback to access the IShimmerCircle interface. Use this instead of ref for accessing + * the public methods and properties of the component. + */ + componentRef?: (component: IShimmerCircle) => void; + + /** + * Sets the height of the circle. + * @default 24px + */ + height?: number; + + /** + * Used to + */ + borderAlignStyle?: IStyleSet; + + /** + * Call to provide customized styling that will layer on top of the variant rules. + */ + getStyles?: IStyleFunction; +} + +export interface IShimmerCircleStyleProps { + height?: number; + borderAlignStyle?: IStyleSet; +} + +export interface IShimmerCircleStyles { + root?: IStyle; + svg?: IStyle; +} \ No newline at end of file diff --git a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx new file mode 100644 index 0000000000000..2f708b8fac860 --- /dev/null +++ b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx @@ -0,0 +1,34 @@ +import * as React from 'react'; +import { + BaseComponent, + classNamesFunction, +} from '../../../Utilities'; +import { + IShimmerLineProps, + IShimmerLineStyleProps, + IShimmerLineStyles +} from './ShimmerLine.types'; +import { ShimmerElementVerticalAlign } from 'experiments/lib/Shimmer'; + +const getClassNames = classNamesFunction(); + +export class ShimmerLineBase extends BaseComponent { + public static defaultProps: IShimmerLineProps = { + verticalAlign: ShimmerElementVerticalAlign.CENTER, + }; + private _classNames: {[key in keyof IShimmerLineStyles]: string}; + + constructor(props: IShimmerLineProps) { + super(props); + } + + public render(): JSX.Element { + const { height, getStyles, widthInPercentage, widthInPixel, borderAlignStyle } = this.props; + + this._classNames = getClassNames(getStyles!, { height, widthInPixel, widthInPercentage, borderAlignStyle }); + + return ( +
+ ); + } +} \ No newline at end of file diff --git a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts new file mode 100644 index 0000000000000..b5bcb4095e0de --- /dev/null +++ b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts @@ -0,0 +1,30 @@ +import { + IShimmerLineStyleProps, + IShimmerLineStyles +} from './ShimmerLine.types'; +import { IStyleSet } from 'office-ui-fabric-react'; + +export function getStyles(props: IShimmerLineStyleProps): IShimmerLineStyles { + const { + height, + widthInPercentage, + widthInPixel, + borderAlignStyle + } = props; + + const styles: IStyleSet = !!borderAlignStyle ? borderAlignStyle : {}; + const ACTUAL_WIDTH = widthInPercentage ? widthInPercentage + '%' : widthInPixel ? widthInPixel + 'px' : '100%'; + + return { + root: [ + 'ms-ShimmerLine-line', + { + color: 'transparent', + width: ACTUAL_WIDTH, + height: `${height}px`, + boxSizing: 'content-box', + }, + styles + ] + }; +} diff --git a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.tsx b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.tsx new file mode 100644 index 0000000000000..af52b5638fb8f --- /dev/null +++ b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.tsx @@ -0,0 +1,15 @@ +import { + styled +} from '../../../Utilities'; +import { + IShimmerLineProps, + IShimmerLineStyleProps, + IShimmerLineStyles +} from './ShimmerLine.types'; +import { ShimmerLineBase } from './ShimmerLine.base'; +import { getStyles } from './ShimmerLine.styles'; + +export const ShimmerLine = styled( + ShimmerLineBase, + getStyles +); diff --git a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.types.ts b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.types.ts new file mode 100644 index 0000000000000..976743a51c757 --- /dev/null +++ b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.types.ts @@ -0,0 +1,66 @@ +import * as React from 'react'; +import { + IStyle, + IStyleSet +} from '../../../Styling'; +import { IStyleFunction } from '../../../Utilities'; + +export interface IShimmerLine { + +} + +/** + * ShimmerLine component props. + */ +export interface IShimmerLineProps extends React.AllHTMLAttributes { + /** + * Optional callback to access the IShimmerLine interface. Use this instead of ref for accessing + * the public methods and properties of the component. + */ + componentRef?: (component: IShimmerLine) => void; + + /** + * Sets the height of the rectangle. + * @default 16px + */ + height?: number; + + /** + * Sets width of the element in percentages. + * @default 100% + */ + widthInPercentage?: number; + + /** + * Sets width of the element in pixels. + * @default 50px + */ + widthInPixel?: number; + + /** + * @default center + */ + verticalAlign?: string; + + /** + * Sets custom styling of the rectangle. + */ + borderAlignStyle?: IStyleSet; + + /** + * Call to provide customized styling that will layer on top of the variant rules. + */ + getStyles?: IStyleFunction; +} + +export interface IShimmerLineStyleProps { + height?: number; + verticalAlign?: string; + widthInPercentage?: number; + widthInPixel?: number; + borderAlignStyle?: IStyleSet; +} + +export interface IShimmerLineStyles { + root?: IStyle; +} \ No newline at end of file diff --git a/packages/experiments/src/components/Shimmer/ShimmerPage.tsx b/packages/experiments/src/components/Shimmer/ShimmerPage.tsx index db429abc2c0f4..71ee42a8c6cc6 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerPage.tsx +++ b/packages/experiments/src/components/Shimmer/ShimmerPage.tsx @@ -7,10 +7,13 @@ import { } from '@uifabric/example-app-base'; import { ShimmerBasicExample } from './examples/Shimmer.Basic.Example'; import { ShimmerLoadDataExample } from './examples/Shimmer.LoadData.Example'; +import { ShimmerApplicationExample } from 'experiments/lib/components/Shimmer/examples/Shimmer.Application.Example'; const ShimmerBasicExampleCode = require('!raw-loader!experiments/src/components/Shimmer/examples/Shimmer.Basic.Example.tsx') as string; // tslint:disable-next-line:max-line-length const ShimmerLoadDataExampleCode = require('!raw-loader!experiments/src/components/Shimmer/examples/Shimmer.LoadData.Example.tsx') as string; +// tslint:disable-next-line:max-line-length +const ShimmerApplicationExampleCode = require('!raw-loader!experiments/src/components/Shimmer/examples/Shimmer.Application.Example.tsx') as string; export class ShimmerPage extends React.Component { public render(): JSX.Element { @@ -32,6 +35,12 @@ export class ShimmerPage extends React.Component { > + + +
} propertiesTables={ @@ -55,7 +64,7 @@ export class ShimmerPage extends React.Component {
  • - When construncting a shimmer line using different elements like Circle, Rectangle or Gap, best if providing widths for each + When construncting a shimmer line using different elements like Circle, Line or Gap, best if providing widths for each of them to experience a better layout looking as close as possible to real data it is replacing.
  • @@ -69,7 +78,7 @@ export class ShimmerPage extends React.Component {
    • - Thinking... ) + Do not try using on the same element both types of widths. It will always default to just one of them.
    diff --git a/packages/experiments/src/components/Shimmer/ShimmerRectangle/ShimmerRectangle.base.tsx b/packages/experiments/src/components/Shimmer/ShimmerRectangle/ShimmerRectangle.base.tsx deleted file mode 100644 index 961f6674860d0..0000000000000 --- a/packages/experiments/src/components/Shimmer/ShimmerRectangle/ShimmerRectangle.base.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import * as React from 'react'; -import { - BaseComponent, - classNamesFunction, -} from '../../../Utilities'; -import { IShimmerRectangleProps, IShimmerRectangleStyleProps, IShimmerRectangleStyles } from './ShimmerRectangle.styles'; -import { ShimmerElementVerticalAlign } from 'experiments/lib/Shimmer'; - -const getClassNames = classNamesFunction(); - -export class ShimmerRectangleBase extends BaseComponent { - public static defaultProps: IShimmerRectangleProps = { - height: 16, - verticalAlign: ShimmerElementVerticalAlign.CENTER, - width: 100 - }; - private _classNames: {[key in keyof IShimmerRectangleStyles]: string}; - - constructor(props: IShimmerRectangleProps) { - super(props); - } - - public render(): JSX.Element { - const { height, getStyles, width, borderAlignStyle } = this.props; - - this._classNames = getClassNames(getStyles!, { height, width, borderAlignStyle }); - - return ( -
    - ); - } -} \ No newline at end of file diff --git a/packages/experiments/src/components/Shimmer/ShimmerRectangle/ShimmerRectangle.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerRectangle/ShimmerRectangle.styles.ts deleted file mode 100644 index 19c7059c1e1d9..0000000000000 --- a/packages/experiments/src/components/Shimmer/ShimmerRectangle/ShimmerRectangle.styles.ts +++ /dev/null @@ -1,82 +0,0 @@ -import * as React from 'react'; -import { - IStyle, - IStyleSet -} from '../../../Styling'; -import { IStyleFunction } from '../../../Utilities'; - -export interface IShimmerRectangle { - -} - -/** - * ShimmerRectangle component props. - */ -export interface IShimmerRectangleProps extends React.AllHTMLAttributes { - /** - * Optional callback to access the IShimmerRectangle interface. Use this instead of ref for accessing - * the public methods and properties of the component. - */ - componentRef?: (component: IShimmerRectangle) => void; - - /** - * Sets the height of the rectangle. - * @default 16px - */ - height?: number; - - /** - * Sets width of the elemnts. - * @default 100% - */ - width?: number; - - /** - * @default center - */ - verticalAlign?: string; - - /** - * Sets custom styling of the rectangle. - */ - borderAlignStyle?: IStyleSet; - - /** - * Call to provide customized styling that will layer on top of the variant rules. - */ - getStyles?: IStyleFunction; -} - -export interface IShimmerRectangleStyleProps { - height?: number; - verticalAlign?: string; - width?: number; - borderAlignStyle?: IStyleSet; -} - -export interface IShimmerRectangleStyles { - root?: IStyle; -} - -export function getStyles(props: IShimmerRectangleStyleProps): IShimmerRectangleStyles { - const { - height, - width, - borderAlignStyle - } = props; - - const styles: IStyleSet = !!borderAlignStyle ? borderAlignStyle : {}; - - return { - root: [ - 'ms-ShimmerRectangle-line', - { - color: 'transparent', - width: `${width}%`, - height: `${height}px`, - boxSizing: 'content-box', - }, - styles - ] - }; -} diff --git a/packages/experiments/src/components/Shimmer/ShimmerRectangle/ShimmerRectangle.tsx b/packages/experiments/src/components/Shimmer/ShimmerRectangle/ShimmerRectangle.tsx deleted file mode 100644 index 50b4947ae84c7..0000000000000 --- a/packages/experiments/src/components/Shimmer/ShimmerRectangle/ShimmerRectangle.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { - styled -} from '../../../Utilities'; -import { getStyles, IShimmerRectangleProps, IShimmerRectangleStyleProps, IShimmerRectangleStyles } from './ShimmerRectangle.styles'; -import { ShimmerRectangleBase } from './ShimmerRectangle.base'; - -export const ShimmerRectangle = styled( - ShimmerRectangleBase, - getStyles -); diff --git a/packages/experiments/src/components/Shimmer/examples/Shimmer.Application.Example.tsx b/packages/experiments/src/components/Shimmer/examples/Shimmer.Application.Example.tsx index 6eddf4414c785..a92bc7e53d414 100644 --- a/packages/experiments/src/components/Shimmer/examples/Shimmer.Application.Example.tsx +++ b/packages/experiments/src/components/Shimmer/examples/Shimmer.Application.Example.tsx @@ -6,10 +6,17 @@ import { HoverCard, IExpandingCardProps } from 'office-ui-fabric-react/lib/HoverCard'; -import { DetailsList, buildColumns, IColumn } from 'office-ui-fabric-react/lib/DetailsList'; import { autobind } from 'office-ui-fabric-react/lib/Utilities'; import { createListItems } from '@uifabric/example-app-base'; import './Shimmer.Example.scss'; +import { + Shimmer, +} from 'experiments/lib/Shimmer'; +import { IColumn, DetailsList, buildColumns } from 'office-ui-fabric-react'; + +const PAGING_DELAY = 3000; +const ITEMS_COUNT = 1000; +const PAGING_SIZE = 10; export interface IItem { [index: string]: string | number; @@ -24,7 +31,38 @@ export interface IItem { height: number; } -let _items: IItem[]; +export interface IShimmerElem { + [index: string]: HTMLElement; +} + +// tslint:disable-next-line:no-any +let _items: any[]; + +const fileIcons: { name: string; }[] = [ + { 'name': 'accdb' }, + { 'name': 'csv' }, + { 'name': 'docx' }, + { 'name': 'dotx' }, + { 'name': 'mpp' }, + { 'name': 'mpt' }, + { 'name': 'odp' }, + { 'name': 'ods' }, + { 'name': 'odt' }, + { 'name': 'one' }, + { 'name': 'onepkg' }, + { 'name': 'onetoc' }, + { 'name': 'potx' }, + { 'name': 'ppsx' }, + { 'name': 'pptx' }, + { 'name': 'pub' }, + { 'name': 'vsdx' }, + { 'name': 'vssx' }, + { 'name': 'vstx' }, + { 'name': 'xls' }, + { 'name': 'xlsx' }, + { 'name': 'xltx' }, + { 'name': 'xsn' } +]; export interface IShimmerApplicationExampleState { items?: IItem[]; @@ -32,14 +70,21 @@ export interface IShimmerApplicationExampleState { } export class ShimmerApplicationExample extends BaseComponent<{}, IShimmerApplicationExampleState> { + private _isFetchingItems: boolean; constructor(props: {}) { super(props); - _items = _items || createListItems(10); + if (!_items) { + _items = createListItems(ITEMS_COUNT); + _items.map((item: IItem) => { + const randomFileType = this._randomFileIcon(); + item.thumbnail = randomFileType.url; + }); + } this.state = { - items: _items, + items: _items.slice(0, PAGING_SIZE).concat(new Array(ITEMS_COUNT - PAGING_SIZE)), columns: _buildColumns() }; } @@ -48,18 +93,47 @@ export class ShimmerApplicationExample extends BaseComponent<{}, IShimmerApplica const { items, columns } = this.state; return ( -
    +

    Hover over location of a row item to see the card

    ); } + @autobind + private _onRenderMissingItem(index: number): JSX.Element { + this._onDataMiss(index as number); + return ( + + ); + } + + private _onDataMiss(index: number): void { + index = Math.floor(index / PAGING_SIZE) * PAGING_SIZE; + + if (!this._isFetchingItems) { + + this._isFetchingItems = true; + + setTimeout(() => { + this._isFetchingItems = false; + // tslint:disable-next-line:no-any + const itemsCopy = ([] as any[]).concat(this.state.items); + itemsCopy.splice.apply(itemsCopy, [index, PAGING_SIZE].concat(_items.slice(index, index + PAGING_SIZE))); + + this.setState({ + items: itemsCopy + }); + }, PAGING_DELAY); + } + } + @autobind private _onRenderItemColumn(item: IItem, index: number, column: IColumn): JSX.Element | string | number { const expandingCardProps: IExpandingCardProps = { @@ -78,6 +152,14 @@ export class ShimmerApplicationExample extends BaseComponent<{}, IShimmerApplica ); } + if (column.key === 'thumbnail') { + return ( + + ); + } + return item[column.key]; } @@ -106,8 +188,27 @@ export class ShimmerApplicationExample extends BaseComponent<{}, IShimmerApplica
    ); } + + private _randomFileIcon(): { docType: string; url: string; } { + const docType: string = fileIcons[Math.floor(Math.random() * fileIcons.length) + 0].name; + return { + docType, + url: `https://static2.sharepointonline.com/files/fabric/assets/brand-icons/document/svg/${docType}_16x1.svg` + }; + } } function _buildColumns(): IColumn[] { - return buildColumns(_items).filter((column: IColumn) => column.name === 'location' || column.name === 'key'); + const columns: IColumn[] = buildColumns(_items); + + columns.forEach((column: IColumn) => { + if (column.key === 'thumbnail') { + column.name = 'FileType'; + column.minWidth = 16; + column.maxWidth = 16; + column.isIconOnly = true; + column.iconName = 'Page'; + } + }); + return columns; } \ No newline at end of file diff --git a/packages/experiments/src/components/Shimmer/examples/Shimmer.Basic.Example.tsx b/packages/experiments/src/components/Shimmer/examples/Shimmer.Basic.Example.tsx index 72f53f5c1bdd9..2b93b32869906 100644 --- a/packages/experiments/src/components/Shimmer/examples/Shimmer.Basic.Example.tsx +++ b/packages/experiments/src/components/Shimmer/examples/Shimmer.Basic.Example.tsx @@ -27,53 +27,53 @@ export class ShimmerBasicExample extends React.Component<{}, {}> { Custom Shimmer with elements provided. Notice how the same elements change relative to the shimmer width provided. - Variations of vertical alignment for Circles and Rectangles. + Variations of vertical alignment for Circles and Lines.
    diff --git a/packages/experiments/src/components/Shimmer/examples/Shimmer.Example.scss b/packages/experiments/src/components/Shimmer/examples/Shimmer.Example.scss index 501e970ec958c..8238a266957eb 100644 --- a/packages/experiments/src/components/Shimmer/examples/Shimmer.Example.scss +++ b/packages/experiments/src/components/Shimmer/examples/Shimmer.Example.scss @@ -14,4 +14,8 @@ text-decoration: underline; cursor: pointer; } + + .shimmerExample-application .ms-Shimmer-container{ + margin-left: 42px; + } } \ No newline at end of file