From 31009ae36098dadb6a75e132754674d9d04c54ac Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Fri, 30 Mar 2018 18:08:57 -0700 Subject: [PATCH 01/36] Setting up an example with shimmer tiles. --- .../src/components/TilesList/TilesList.tsx | 34 ++++++- .../components/TilesList/TilesListPage.tsx | 24 ++--- .../TilesList/examples/ExampleHelpers.tsx | 56 +++++++++++ .../examples/TilesList.Document.Example.tsx | 97 +++++++++++++++++-- 4 files changed, 191 insertions(+), 20 deletions(-) diff --git a/packages/experiments/src/components/TilesList/TilesList.tsx b/packages/experiments/src/components/TilesList/TilesList.tsx index 2903d2adf8b1b..c3a72af5210b6 100644 --- a/packages/experiments/src/components/TilesList/TilesList.tsx +++ b/packages/experiments/src/components/TilesList/TilesList.tsx @@ -173,15 +173,21 @@ export class TilesList extends React.Component, IT className: pageClassName, ...divProps } = pageProps; - + console.log(page); const { items } = page; const data: IPageData = page.data; - const cells: ITileCell[] = items || []; + const cellsPerRow: number = Math.floor(data.pageWidths[0] / data.cellSizes[0].width); + const cells: ITileCell[] = items ? + items[0].key === 'shimmerItem' ? + this._getShimmerCells(items[0], cellsPerRow) : + items : + []; + console.log(cells); let grids: React.ReactNode[] = []; const previousCell = this.state.cells[page.startIndex - 1]; @@ -527,6 +533,30 @@ export class TilesList extends React.Component, IT return cells; } + + private _getShimmerCells(item: ITileCell, cellsPerRow: number): ITileCell[] { + let cells: ITileCell[] = []; + + for (let i = 0; i < cellsPerRow * 3; i++) { + cells.push({ + aspectRatio: 1, + content: item.content, + onRender: item.onRender, + grid: { + minRowHeight: item.grid.minRowHeight, + spacing: item.grid.spacing, + mode: item.grid.mode, + key: `grid-shimmerGroup-${item.key}`, + maxScaleFactor: item.grid.maxScaleFactor, + marginBottom: item.grid.marginBottom, + marginTop: item.grid.marginTop + }, + key: `shimmer-${i}` + }); + } + + return cells; + } } function isGridSegment(item: ITilesGridSegment | ITilesGridItem): item is ITilesGridSegment { diff --git a/packages/experiments/src/components/TilesList/TilesListPage.tsx b/packages/experiments/src/components/TilesList/TilesListPage.tsx index 7669494b5e10b..7a56d537ff6b9 100644 --- a/packages/experiments/src/components/TilesList/TilesListPage.tsx +++ b/packages/experiments/src/components/TilesList/TilesListPage.tsx @@ -8,21 +8,21 @@ import { } from '@uifabric/example-app-base'; /* tslint:disable:max-line-length */ -import { TilesListBasicExample } from './examples/TilesList.Basic.Example'; -const TilesListBasicExampleCode = require( - '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Basic.Example.tsx' -) as string; +// import { TilesListBasicExample } from './examples/TilesList.Basic.Example'; +// const TilesListBasicExampleCode = require( +// '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Basic.Example.tsx' +// ) as string; import { TilesListDocumentExample } from './examples/TilesList.Document.Example'; const TilesListDocumentExampleCode = require( '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx' ) as string; -import { TilesListMediaExample } from './examples/TilesList.Media.Example'; +// import { TilesListMediaExample } from './examples/TilesList.Media.Example'; -const TilesListMediaExampleCode = require( - '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Media.Example.tsx' -) as string; +// const TilesListMediaExampleCode = require( +// '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Media.Example.tsx' +// ) as string; export class TilesListPage extends React.Component { public render(): JSX.Element { @@ -32,15 +32,15 @@ export class TilesListPage extends React.Component componentName='TilesListExample' exampleCards={
- + {/* - + */} - + {/* - + */}
} propertiesTables={ diff --git a/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx b/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx index c6267a4d0974d..c204e12785d18 100644 --- a/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx +++ b/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx @@ -34,6 +34,13 @@ export interface IExampleGroup { key: string; } +export interface IExampleShimmerGroup { + key: string; + items: IExampleItem[]; + name: string; + index: number; +} + export function createMediaItems(count: number, indexOffset: number): IExampleItem[] { const items: IExampleItem[] = []; @@ -130,3 +137,52 @@ export function getTileCells(groups: IExampleGroup[], { return items; } + +export function createShimmerGroup(): IExampleShimmerGroup[] { + return [{ + items: [{ + key: 'shimmerItem', + name: lorem(4), + index: 0, + aspectRatio: 1 + }], + index: 0, + name: lorem(4), + key: 'shimmerGroup' + }]; +} + +export function getShimmerCells(groups: IExampleShimmerGroup[], { + onRenderCell, + size = 'large' +}: { + onRenderCell: (item: IExampleItem, finalSize?: ITileSize) => JSX.Element; + size?: 'large' | 'small' + }): (ITilesGridSegment | ITilesGridItem)[] { + const items: (ITilesGridSegment | ITilesGridItem)[] = []; + + for (const group of groups) { + items.push({ + items: group.items.map((item: IExampleItem): ITilesGridItem => { + return { + key: item.key, + content: item, + desiredSize: { + width: 176, + height: 171 + }, + onRender: onRenderCell + }; + }), + spacing: 8, + marginBottom: 40, + minRowHeight: 171, + mode: size === 'small' ? + TilesGridMode.fillHorizontal : + TilesGridMode.stack, + key: group.key + }); + } + + return items; +} \ No newline at end of file diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx index db7ccc2fc8287..bdb121a3f5208 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx @@ -3,14 +3,23 @@ import * as React from 'react'; import { TilesList, ITilesGridItem, - ITilesGridSegment + ITilesGridSegment, + ITileSize } from '../../TilesList'; -import { Tile } from '../../../Tile'; +import { Tile, ITileProps } from '../../../Tile'; import { Toggle } from 'office-ui-fabric-react/lib/Toggle'; import { Selection, SelectionZone } from 'office-ui-fabric-react/lib/Selection'; import { MarqueeSelection } from 'office-ui-fabric-react/lib/MarqueeSelection'; import { AnimationClassNames } from 'office-ui-fabric-react/lib/Styling'; -import { IExampleGroup, IExampleItem, createGroup, createDocumentItems, getTileCells } from './ExampleHelpers'; +import { + IExampleGroup, + IExampleItem, + createGroup, + createDocumentItems, + getTileCells, + createShimmerGroup, + getShimmerCells +} from './ExampleHelpers'; function createGroups(): IExampleGroup[] { let offset = 0; @@ -32,12 +41,15 @@ const GROUPS = createGroups(); const ITEMS = ([] as IExampleItem[]).concat(...GROUPS.map((group: { items: IExampleItem[]; }) => group.items)); +const SHIMMER_GROUP = createShimmerGroup(); + declare class TilesListClass extends TilesList { } const TilesListType: typeof TilesListClass = TilesList; export interface ITilesListDocumentExampleState { isModalSelection: boolean; + isDataLoaded: boolean; cells: (ITilesGridItem | ITilesGridSegment)[]; } @@ -56,9 +68,9 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu this.state = { isModalSelection: this._selection.isModal(), - cells: getTileCells(GROUPS, { - onRenderCell: this._onRenderDocumentCell, - onRenderHeader: this._onRenderHeader + isDataLoaded: false, + cells: getShimmerCells(SHIMMER_GROUP, { + onRenderCell: this._onRenderShimmerCell }) }; } @@ -74,6 +86,13 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu onText='Modal' offText='Normal' /> + { + const { isDataLoaded } = this.state; + let { cells } = this.state; + + if (cells.length && cells[0].key !== 'shimmerGroup') { + cells = getShimmerCells(SHIMMER_GROUP, { + onRenderCell: this._onRenderShimmerCell + }); + } else { + cells = getTileCells(GROUPS, { + onRenderCell: this._onRenderDocumentCell, + onRenderHeader: this._onRenderHeader + }); + } + + this.setState({ + isDataLoaded: !isDataLoaded, + cells: cells + }); + } + private _onSelectionChange = (): void => { this.setState({ isModalSelection: this._selection.isModal() @@ -139,6 +179,51 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu ); } + private _onRenderShimmerCell(content: IExampleItem, finalSize: ITileSize): JSX.Element { + const tileProps: ITileProps = { + itemName: ( +
+ ), + itemActivity: ( +
+ ), + showForegroundFrame: true, + foreground: ( +
+ ) + }; + return ( + + ); + } + private _onRenderHeader = (item: IExampleItem): JSX.Element => { return (
From d9180a8090fd15964ca94473cd02bfcabe122be7 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Mon, 2 Apr 2018 11:03:05 -0700 Subject: [PATCH 02/36] Adds some logic to fake some shimmer tiles. --- .../src/components/TilesList/TilesList.tsx | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/packages/experiments/src/components/TilesList/TilesList.tsx b/packages/experiments/src/components/TilesList/TilesList.tsx index c3a72af5210b6..b46cc000584c4 100644 --- a/packages/experiments/src/components/TilesList/TilesList.tsx +++ b/packages/experiments/src/components/TilesList/TilesList.tsx @@ -173,21 +173,22 @@ export class TilesList extends React.Component, IT className: pageClassName, ...divProps } = pageProps; - console.log(page); + const { items } = page; const data: IPageData = page.data; - const cellsPerRow: number = Math.floor(data.pageWidths[0] / data.cellSizes[0].width); + const isShimmer: boolean = items && items[0] && items[0].key === 'shimmerItem' ? true : false; + const cellsPerRow: number = isShimmer ? Math.floor(data.pageWidths[0] / data.cellSizes[0].width) : 0; const cells: ITileCell[] = items ? items[0].key === 'shimmerItem' ? this._getShimmerCells(items[0], cellsPerRow) : items : []; - console.log(cells); + let grids: React.ReactNode[] = []; const previousCell = this.state.cells[page.startIndex - 1]; @@ -203,20 +204,20 @@ export class TilesList extends React.Component, IT const renderedCells: React.ReactNode[] = []; - const width = data.pageWidths[page.startIndex + i]; + const width = data.pageWidths[isShimmer ? 0 : page.startIndex + i]; for (; i < endIndex && cells[i].grid === grid; i++) { // For each cell in the current grid. const cell = cells[i]; const index = page.startIndex + i; - const cellAsFirstRow = data.rows[index]; + const cellAsFirstRow = data.rows[isShimmer ? 0 : index]; if (cellAsFirstRow) { currentRow = cellAsFirstRow; } - let finalSize = data.cellSizes[index]; + let finalSize = data.cellSizes[isShimmer ? 0 : index]; if (currentRow) { const { @@ -537,20 +538,21 @@ export class TilesList extends React.Component, IT private _getShimmerCells(item: ITileCell, cellsPerRow: number): ITileCell[] { let cells: ITileCell[] = []; + const grid: ITileGrid = { + minRowHeight: item.grid.minRowHeight, + spacing: item.grid.spacing, + mode: item.grid.mode, + key: 'grid-shimmerGroup', + maxScaleFactor: item.grid.maxScaleFactor, + marginBottom: item.grid.marginBottom, + marginTop: item.grid.marginTop + }; for (let i = 0; i < cellsPerRow * 3; i++) { cells.push({ aspectRatio: 1, content: item.content, onRender: item.onRender, - grid: { - minRowHeight: item.grid.minRowHeight, - spacing: item.grid.spacing, - mode: item.grid.mode, - key: `grid-shimmerGroup-${item.key}`, - maxScaleFactor: item.grid.maxScaleFactor, - marginBottom: item.grid.marginBottom, - marginTop: item.grid.marginTop - }, + grid: grid, key: `shimmer-${i}` }); } From 3dc8f27cb0528f5717f21446fe3ec0eff698e968 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Mon, 2 Apr 2018 12:19:42 -0700 Subject: [PATCH 03/36] Imports shimmer inside TileList. --- .../experiments/src/components/TilesList/TilesList.tsx | 10 +++++++++- .../TilesList/examples/TilesList.Document.Example.tsx | 6 +++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/experiments/src/components/TilesList/TilesList.tsx b/packages/experiments/src/components/TilesList/TilesList.tsx index b46cc000584c4..704eafc2dda6b 100644 --- a/packages/experiments/src/components/TilesList/TilesList.tsx +++ b/packages/experiments/src/components/TilesList/TilesList.tsx @@ -5,6 +5,7 @@ import { List, IPageProps } from 'office-ui-fabric-react/lib/List'; import { FocusZone, FocusZoneDirection } from 'office-ui-fabric-react/lib/FocusZone'; import { css, IRenderFunction, IRectangle } from 'office-ui-fabric-react/lib/Utilities'; import * as TilesListStylesModule from './TilesList.scss'; +import { Shimmer } from 'experiments/lib/Shimmer'; // tslint:disable-next-line:no-any const TilesListStyles: any = TilesListStylesModule; @@ -289,7 +290,14 @@ export class TilesList extends React.Component, IT { ...divProps } className={ css(pageClassName, this._onGetPageClassName()) } > - { grids } + { isShimmer ? + + { grids } + : + grids + }
); } diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx index bdb121a3f5208..7f99be1f85461 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx @@ -188,7 +188,7 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu { width: `${(finalSize.width * 70) / 100}px`, height: '7px', - backgroundColor: '#f4f4f4' + // backgroundColor: '#f4f4f4' } } /> @@ -200,7 +200,7 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu { width: `${(finalSize.width * 30) / 100}px`, height: '7px', - backgroundColor: '#f4f4f4' + // backgroundColor: '#f4f4f4' } } /> @@ -213,7 +213,7 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu { width: `${(finalSize.width * 45) / 100}px`, height: `${(finalSize.width * 45) / 100}px`, - backgroundColor: '#f4f4f4' + // backgroundColor: '#f4f4f4' } } /> From 980a70da24c4b507bfd5441c82181e0f0495096c Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Mon, 2 Apr 2018 17:58:34 -0700 Subject: [PATCH 04/36] Reuse the _getCells function to create fake Shimmer Tiles. --- .../src/components/TilesList/TilesList.tsx | 66 +++++++++---------- .../examples/TilesList.Document.Example.tsx | 22 ++++++- 2 files changed, 50 insertions(+), 38 deletions(-) diff --git a/packages/experiments/src/components/TilesList/TilesList.tsx b/packages/experiments/src/components/TilesList/TilesList.tsx index 704eafc2dda6b..81eab230bb050 100644 --- a/packages/experiments/src/components/TilesList/TilesList.tsx +++ b/packages/experiments/src/components/TilesList/TilesList.tsx @@ -15,6 +15,8 @@ const CELLS_PER_PAGE = 100; const MIN_ASPECT_RATIO = 0.5; const MAX_ASPECT_RATIO = 3; +const ROW_OF_SHIMMER_CELLS = 3; + export interface ITilesListState { cells: ITileCell[]; } @@ -182,11 +184,15 @@ export class TilesList extends React.Component, IT const data: IPageData = page.data; const isShimmer: boolean = items && items[0] && items[0].key === 'shimmerItem' ? true : false; - const cellsPerRow: number = isShimmer ? Math.floor(data.pageWidths[0] / data.cellSizes[0].width) : 0; + const shimmerCellWithMarginsSize = isShimmer && (data.cellSizes[0].width + (items ? items[0].grid.spacing : 0)); + const shimmerCellsPerRow: number | undefined = isShimmer ? + Math.floor(data.pageWidths[0] / shimmerCellWithMarginsSize) + : undefined; + // const shimmerWrapperWidth = const cells: ITileCell[] = items ? - items[0].key === 'shimmerItem' ? - this._getShimmerCells(items[0], cellsPerRow) : + isShimmer ? + this._getCells(this.props.items, shimmerCellsPerRow) : items : []; @@ -478,7 +484,8 @@ export class TilesList extends React.Component, IT }; } - private _getCells(items: (ITilesGridSegment | ITilesGridItem)[]): ITileCell[] { + private _getCells(items: (ITilesGridSegment | ITilesGridItem)[], + shimmerCellsPerRow?: number | undefined): ITileCell[] { const cells: ITileCell[] = []; for (const item of items) { @@ -513,13 +520,25 @@ export class TilesList extends React.Component, IT minAspectRatio, desiredSize && (desiredSize.width / desiredSize.height) || 1)); - cells.push({ - aspectRatio: aspectRatio, - content: gridItem.content, - onRender: gridItem.onRender, - grid: grid, - key: gridItem.key - }); + if (shimmerCellsPerRow) { + for (let i = 0; i < shimmerCellsPerRow * ROW_OF_SHIMMER_CELLS; i++) { + cells.push({ + aspectRatio: aspectRatio, + content: gridItem.content, + onRender: gridItem.onRender, + grid: grid, + key: gridItem.key + i + }); + } + } else { + cells.push({ + aspectRatio: aspectRatio, + content: gridItem.content, + onRender: gridItem.onRender, + grid: grid, + key: gridItem.key + }); + } } } else { cells.push({ @@ -542,31 +561,6 @@ export class TilesList extends React.Component, IT return cells; } - - private _getShimmerCells(item: ITileCell, cellsPerRow: number): ITileCell[] { - let cells: ITileCell[] = []; - - const grid: ITileGrid = { - minRowHeight: item.grid.minRowHeight, - spacing: item.grid.spacing, - mode: item.grid.mode, - key: 'grid-shimmerGroup', - maxScaleFactor: item.grid.maxScaleFactor, - marginBottom: item.grid.marginBottom, - marginTop: item.grid.marginTop - }; - for (let i = 0; i < cellsPerRow * 3; i++) { - cells.push({ - aspectRatio: 1, - content: item.content, - onRender: item.onRender, - grid: grid, - key: `shimmer-${i}` - }); - } - - return cells; - } } function isGridSegment(item: ITilesGridSegment | ITilesGridItem): item is ITilesGridSegment { diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx index 7f99be1f85461..ead602a0334b5 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx @@ -6,7 +6,10 @@ import { ITilesGridSegment, ITileSize } from '../../TilesList'; -import { Tile, ITileProps } from '../../../Tile'; +import { + Tile, + ITileProps +} from '../../../Tile'; import { Toggle } from 'office-ui-fabric-react/lib/Toggle'; import { Selection, SelectionZone } from 'office-ui-fabric-react/lib/Selection'; import { MarqueeSelection } from 'office-ui-fabric-react/lib/MarqueeSelection'; @@ -219,8 +222,23 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu /> ) }; + + const shimmerTile: JSX.Element = ( +
+ ); + return ( - + shimmerTile + // ); } From b8d465bd36c1bcc3beebd97b7c4e646893c96eb5 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Tue, 3 Apr 2018 18:12:30 -0700 Subject: [PATCH 05/36] Break point before changing Tile. --- .../src/components/Shimmer/Shimmer.base.tsx | 2 +- .../src/components/Shimmer/Shimmer.styles.ts | 4 +- .../src/components/TilesList/TilesList.tsx | 17 ++++--- .../TilesList/examples/ExampleHelpers.tsx | 2 +- .../examples/TilesList.Document.Example.tsx | 46 ++++++++++++------- 5 files changed, 44 insertions(+), 27 deletions(-) diff --git a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx index 4d7c4b60eea86..7e00d06508b56 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx +++ b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx @@ -27,7 +27,7 @@ const getClassNames = classNamesFunction(); export class ShimmerBase extends BaseComponent { public static defaultProps: IShimmerProps = { - width: 100, + // width: 100, isDataLoaded: false, isBaseStyle: false }; diff --git a/packages/experiments/src/components/Shimmer/Shimmer.styles.ts b/packages/experiments/src/components/Shimmer/Shimmer.styles.ts index 78dd50cdf8fd2..6a23175efb3f1 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.styles.ts +++ b/packages/experiments/src/components/Shimmer/Shimmer.styles.ts @@ -48,7 +48,7 @@ export function getStyles(props: IShimmerStyleProps): IShimmerStyles { top: '0', alignItems: 'center', alignContent: 'space-between', - width: `${width}%`, + width: width ? `${width}%` : '100%', height: 'auto', boxSizing: 'border-box', background: `${DefaultPalette.neutralLighter} @@ -73,7 +73,7 @@ export function getStyles(props: IShimmerStyleProps): IShimmerStyles { }, isBaseStyle && { position: 'static', - width: 'auto' + width: width ? `${width}px` : 'auto' } ], dataWrapper: [ diff --git a/packages/experiments/src/components/TilesList/TilesList.tsx b/packages/experiments/src/components/TilesList/TilesList.tsx index 81eab230bb050..fab65c0fbad32 100644 --- a/packages/experiments/src/components/TilesList/TilesList.tsx +++ b/packages/experiments/src/components/TilesList/TilesList.tsx @@ -184,11 +184,14 @@ export class TilesList extends React.Component, IT const data: IPageData = page.data; const isShimmer: boolean = items && items[0] && items[0].key === 'shimmerItem' ? true : false; - const shimmerCellWithMarginsSize = isShimmer && (data.cellSizes[0].width + (items ? items[0].grid.spacing : 0)); + const shimmerCellSpacing: number = items ? items[0].grid.spacing : 0; + const shimmerCellWidth: number = isShimmer ? data.cellSizes[0].width : 0; const shimmerCellsPerRow: number | undefined = isShimmer ? - Math.floor(data.pageWidths[0] / shimmerCellWithMarginsSize) + Math.floor(data.pageWidths[0] / (shimmerCellSpacing + shimmerCellWidth)) : undefined; - // const shimmerWrapperWidth = + const shimmerWrapperWidth: number | undefined = shimmerCellsPerRow ? + (shimmerCellsPerRow * shimmerCellWidth) + (shimmerCellSpacing * (shimmerCellsPerRow - 1)) : + undefined; const cells: ITileCell[] = items ? isShimmer ? @@ -256,7 +259,7 @@ export class TilesList extends React.Component, IT // tslint:disable-next-line:jsx-ban-props style={ { - ...this._onGetCellStyle(cell, currentRow) + ...this._onGetCellStyle(cell, currentRow, isShimmer) } } > @@ -299,6 +302,7 @@ export class TilesList extends React.Component, IT { isShimmer ? { grids } : @@ -455,7 +459,7 @@ export class TilesList extends React.Component, IT return TilesListStyles.listPage; } - private _onGetCellStyle = (item: ITileCell, currentRow?: IRowData): React.CSSProperties => { + private _onGetCellStyle = (item: ITileCell, currentRow?: IRowData, isShimmer?: boolean): React.CSSProperties => { const { grid: { mode: gridMode, @@ -480,7 +484,8 @@ export class TilesList extends React.Component, IT `${width * maxScaleFactor}px` : // The item must not be scaled. `${width}px`, - margin: `${margin}px` + margin: !isShimmer ? `${margin}px` : 0, + border: isShimmer ? `${margin}px solid white` : 'none' }; } diff --git a/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx b/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx index c204e12785d18..5d432bc221117 100644 --- a/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx +++ b/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx @@ -175,7 +175,7 @@ export function getShimmerCells(groups: IExampleShimmerGroup[], { }; }), spacing: 8, - marginBottom: 40, + marginBottom: 0, minRowHeight: 171, mode: size === 'small' ? TilesGridMode.fillHorizontal : diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx index ead602a0334b5..ac5831c2b5c98 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx @@ -184,6 +184,7 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu private _onRenderShimmerCell(content: IExampleItem, finalSize: ITileSize): JSX.Element { const tileProps: ITileProps = { + tileSize: 'small', itemName: (
@@ -203,7 +204,7 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu { width: `${(finalSize.width * 30) / 100}px`, height: '7px', - // backgroundColor: '#f4f4f4' + backgroundColor: 'transparent' } } /> @@ -216,29 +217,40 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu { width: `${(finalSize.width * 45) / 100}px`, height: `${(finalSize.width * 45) / 100}px`, - // backgroundColor: '#f4f4f4' + backgroundColor: 'transparent' } } /> ) }; - const shimmerTile: JSX.Element = ( -
- ); + // const shimmerTile: JSX.Element = ( + //
+ //
+ //
+ // ); return ( - shimmerTile - // + // shimmerTile + ); } From 7d9094249dd50652d66f8f3dddada71f1a84427c Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Wed, 4 Apr 2018 18:01:50 -0700 Subject: [PATCH 06/36] Adds a Shimmer tile to Tile component. --- .../experiments/src/components/Tile/Tile.scss | 85 +++++++++++++++++++ .../experiments/src/components/Tile/Tile.tsx | 47 ++++++++++ .../src/components/Tile/Tile.types.ts | 7 ++ .../examples/TilesList.Document.Example.tsx | 74 ++-------------- 4 files changed, 144 insertions(+), 69 deletions(-) diff --git a/packages/experiments/src/components/Tile/Tile.scss b/packages/experiments/src/components/Tile/Tile.scss index 207b5f43611e6..abbb0480d4cfa 100644 --- a/packages/experiments/src/components/Tile/Tile.scss +++ b/packages/experiments/src/components/Tile/Tile.scss @@ -1,6 +1,30 @@ @import '~office-ui-fabric-react/src/common/common'; +$nameplatePadding: 12px; +$largeNameplateNameHeight: 15px; +$smallNameplateNameHeight: 12px; +$largeNameplateActivityHeight: 20px; +$smallNameplateActivityHeight: 20px; +$foregroundMargin: 16px; +$smallNameplateHeight: (($nameplatePadding * 2) + $smallNameplateNameHeight + $smallNameplateActivityHeight); +$largeNameplateHeight: (($nameplatePadding * 2) + $largeNameplateNameHeight + $largeNameplateActivityHeight); + +@mixin shimmerBorders($divHeight, $lineHeight, $type) { + @if $type == 'nameBorders' { + border-top: $nameplatePadding solid $ms-color-white; + border-left: $nameplatePadding solid $ms-color-white; + border-right: $nameplatePadding solid $ms-color-white; + border-bottom: ($divHeight - $lineHeight) solid $ms-color-white; + } + @if $type == 'activityBorders' { + border-top: ($divHeight - $lineHeight) solid $ms-color-white; + border-left: ($nameplatePadding * 4) solid $ms-color-white; + border-right: ($nameplatePadding * 4) solid $ms-color-white; + border-bottom: $nameplatePadding solid $ms-color-white + } +} + .tile { @include focus-clear(); @@ -394,3 +418,64 @@ } } } + +.shimmerTile { + width: 100%; + height: 100%; +} + +.aboveNameplateShimmer { + box-sizing: border-box; + width: 100%; + border-top: $foregroundMargin solid $ms-color-white; + border-left: ($foregroundMargin * 2) solid $ms-color-white; + border-right: ($foregroundMargin * 2) solid $ms-color-white; + + .isLargeShimmer & { + height: calc(100% - #{$largeNameplateHeight}); + } + + .isSmallShimmer & { + height: calc(100% - #{$smallNameplateHeight}); + } +} + +.nameplateShimmer { + width: 100%; + + .isLargeShimmer & { + height: $largeNameplateHeight; + + .nameShimmer { + width: 100%; + box-sizing: border-box; + height: ($largeNameplateNameHeight + $nameplatePadding); + @include shimmerBorders($largeNameplateNameHeight, $ms-font-size-m, 'nameBorders'); + } + + .activityShimmer { + width: 100%; + box-sizing: border-box; + height: ($largeNameplateActivityHeight + $nameplatePadding); + @include shimmerBorders($largeNameplateActivityHeight, $ms-font-size-s, 'activityBorders'); + } + } + + .isSmallShimmer & { + height: $smallNameplateHeight; + + .nameShimmer { + width: 100%; + box-sizing: border-box; + height: ($smallNameplateNameHeight + $nameplatePadding); + @include shimmerBorders($smallNameplateActivityHeight, $ms-font-size-s, 'nameBorders'); + } + + .activityShimmer { + width: 100%; + box-sizing: border-box; + height: ($smallNameplateActivityHeight + $nameplatePadding); + @include shimmerBorders($smallNameplateActivityHeight, $ms-font-size-s, 'activityBorders'); + } + } +} diff --git a/packages/experiments/src/components/Tile/Tile.tsx b/packages/experiments/src/components/Tile/Tile.tsx index 1a18e013a8ed8..1db0636276cf5 100644 --- a/packages/experiments/src/components/Tile/Tile.tsx +++ b/packages/experiments/src/components/Tile/Tile.tsx @@ -164,6 +164,7 @@ export class Tile extends BaseComponent { descriptionAriaLabel, href, onClick, + shimmerPlaceholder = false, ...divProps } = this.props; @@ -175,6 +176,10 @@ export class Tile extends BaseComponent { const isSelectable = !!selection && selectionIndex > -1; const isInvokable = (!!href || !!onClick || !!invokeSelection) && !isModal; + if (shimmerPlaceholder) { + return getShimmerTile(foreground, itemName, itemActivity, tileSize); + } + return (
); } + +function getShimmerTile( + foreground: React.ReactNode | React.ReactNode[], + itemName: React.ReactNode | React.ReactNode[], + itemActivity: React.ReactNode | React.ReactNode[], + tileSize: TileSize = 'large' +): JSX.Element { + + return ( +
+
+
+
+
+
+
+ ); +} + +// { +// ariaLabel ? ( +// +// { ariaLabel } +// +// ) : null +// } \ No newline at end of file diff --git a/packages/experiments/src/components/Tile/Tile.types.ts b/packages/experiments/src/components/Tile/Tile.types.ts index aceaf8f7829e8..45255634bfa70 100644 --- a/packages/experiments/src/components/Tile/Tile.types.ts +++ b/packages/experiments/src/components/Tile/Tile.types.ts @@ -38,6 +38,13 @@ export interface ITileProps extends IBaseProps, React.AllHTMLAttributes - ), - itemActivity: ( -
- ), - showForegroundFrame: true, - foreground: ( -
- ) - }; - - // const shimmerTile: JSX.Element = ( - //
- //
- //
- // ); - return ( - // shimmerTile - + ); } From eb2578343df8b03be17fb5f4d75fd4c634e4a30a Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Wed, 4 Apr 2018 20:37:59 -0700 Subject: [PATCH 07/36] Adds logic to Tile in case the content is not passed. --- .../experiments/src/components/Tile/Tile.scss | 4 +++ .../experiments/src/components/Tile/Tile.tsx | 34 +++++++++++-------- .../examples/TilesList.Document.Example.tsx | 6 ++-- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/packages/experiments/src/components/Tile/Tile.scss b/packages/experiments/src/components/Tile/Tile.scss index abbb0480d4cfa..da50c600b2f3b 100644 --- a/packages/experiments/src/components/Tile/Tile.scss +++ b/packages/experiments/src/components/Tile/Tile.scss @@ -422,6 +422,10 @@ $largeNameplateHeight: (($nameplatePadding * 2) + $largeNameplateNameHeight + $l .shimmerTile { width: 100%; height: 100%; + + .noShimmer { + background-color: $ms-color-white; + } } .aboveNameplateShimmer { diff --git a/packages/experiments/src/components/Tile/Tile.tsx b/packages/experiments/src/components/Tile/Tile.tsx index 1db0636276cf5..8065f943010b8 100644 --- a/packages/experiments/src/components/Tile/Tile.tsx +++ b/packages/experiments/src/components/Tile/Tile.tsx @@ -455,29 +455,33 @@ function getShimmerTile( }) } >
); } - -// { -// ariaLabel ? ( -// -// { ariaLabel } -// -// ) : null -// } \ No newline at end of file diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx index 767a1ca1d9151..dee24b2fdeb28 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx @@ -181,11 +181,13 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu ); } - private _onRenderShimmerCell(content: IExampleItem, finalSize: ITileSize): JSX.Element { + private _onRenderShimmerCell(item: IExampleItem): JSX.Element { return ( } // placeholder + itemName={ item.name } // placeholder + itemActivity={ item.key } // placeholder /> ); } From 02ed97cd433c4cff98ca773257099bfd0f75b0b9 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Wed, 4 Apr 2018 22:38:41 -0700 Subject: [PATCH 08/36] Refactors the example helpers and adds new proprietes to GridItem and GridSegment. --- .../components/TilesList/TilesList.types.ts | 8 +++ .../TilesList/examples/ExampleHelpers.tsx | 65 ++++--------------- .../examples/TilesList.Document.Example.tsx | 26 ++++---- 3 files changed, 36 insertions(+), 63 deletions(-) diff --git a/packages/experiments/src/components/TilesList/TilesList.types.ts b/packages/experiments/src/components/TilesList/TilesList.types.ts index d61e6d3ebcb0f..8d98a021d4b7c 100644 --- a/packages/experiments/src/components/TilesList/TilesList.types.ts +++ b/packages/experiments/src/components/TilesList/TilesList.types.ts @@ -19,6 +19,10 @@ export interface ITilesGridItem { * If not provided, this is assumed to be a square equivalent to the current row height. */ desiredSize?: { width: number; height: number; }; + /** + * Set to true if the item is intended to be a placeholder + */ + isPlaceholder?: boolean; /** * Invoked to render the virtual DOM for the item. * This content will be rendered inside the cell allocated for the item. @@ -88,6 +92,10 @@ export interface ITilesGridSegment { * The maximum aspect ratio for an item in the grid. */ maxAspectRatio?: number; + /** + * Set to true if the item is intended to be a placeholder + */ + isPlaceholder?: boolean; } export { ISize as ITileSize }; diff --git a/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx b/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx index 5d432bc221117..1eab3e848780b 100644 --- a/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx +++ b/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx @@ -34,13 +34,6 @@ export interface IExampleGroup { key: string; } -export interface IExampleShimmerGroup { - key: string; - items: IExampleItem[]; - name: string; - index: number; -} - export function createMediaItems(count: number, indexOffset: number): IExampleItem[] { const items: IExampleItem[] = []; @@ -86,11 +79,13 @@ export function createGroup(items: IExampleItem[], type: 'document' | 'media', i export function getTileCells(groups: IExampleGroup[], { onRenderCell, onRenderHeader, - size = 'large' + size = 'large', + shimmerMode = false }: { onRenderHeader: (item: IExampleItem) => JSX.Element; onRenderCell: (item: IExampleItem, finalSize?: ITileSize) => JSX.Element; - size?: 'large' | 'small' + size?: 'large' | 'small'; + shimmerMode?: boolean; }): (ITilesGridSegment | ITilesGridItem)[] { const items: (ITilesGridSegment | ITilesGridItem)[] = []; @@ -103,7 +98,8 @@ export function getTileCells(groups: IExampleGroup[], { name: group.name, index: group.index }, - onRender: onRenderHeader + onRender: onRenderHeader, + isPlaceholder: shimmerMode }; items.push(header); @@ -131,58 +127,25 @@ export function getTileCells(groups: IExampleGroup[], { TilesGridMode.fillHorizontal : TilesGridMode.stack : TilesGridMode.fill, - key: group.key + key: group.key, + isPlaceholder: shimmerMode }); } return items; } -export function createShimmerGroup(): IExampleShimmerGroup[] { +export function createShimmerGroups(type: 'document' | 'media', index: number): IExampleGroup[] { return [{ items: [{ - key: 'shimmerItem', + key: `shimmerItem-${index}`, name: lorem(4), - index: 0, + index: index, aspectRatio: 1 }], - index: 0, + index: index, name: lorem(4), - key: 'shimmerGroup' + key: `shimmerGroup-${index}`, + type: type }]; } - -export function getShimmerCells(groups: IExampleShimmerGroup[], { - onRenderCell, - size = 'large' -}: { - onRenderCell: (item: IExampleItem, finalSize?: ITileSize) => JSX.Element; - size?: 'large' | 'small' - }): (ITilesGridSegment | ITilesGridItem)[] { - const items: (ITilesGridSegment | ITilesGridItem)[] = []; - - for (const group of groups) { - items.push({ - items: group.items.map((item: IExampleItem): ITilesGridItem => { - return { - key: item.key, - content: item, - desiredSize: { - width: 176, - height: 171 - }, - onRender: onRenderCell - }; - }), - spacing: 8, - marginBottom: 0, - minRowHeight: 171, - mode: size === 'small' ? - TilesGridMode.fillHorizontal : - TilesGridMode.stack, - key: group.key - }); - } - - return items; -} \ No newline at end of file diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx index dee24b2fdeb28..d6077584af44a 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx @@ -3,8 +3,7 @@ import * as React from 'react'; import { TilesList, ITilesGridItem, - ITilesGridSegment, - ITileSize + ITilesGridSegment } from '../../TilesList'; import { Tile @@ -19,8 +18,7 @@ import { createGroup, createDocumentItems, getTileCells, - createShimmerGroup, - getShimmerCells + createShimmerGroups } from './ExampleHelpers'; function createGroups(): IExampleGroup[] { @@ -41,9 +39,9 @@ function createGroups(): IExampleGroup[] { const GROUPS = createGroups(); -const ITEMS = ([] as IExampleItem[]).concat(...GROUPS.map((group: { items: IExampleItem[]; }) => group.items)); +const SHIMMER_GROUPS = createShimmerGroups('document', 0); -const SHIMMER_GROUP = createShimmerGroup(); +const ITEMS = ([] as IExampleItem[]).concat(...GROUPS.map((group: { items: IExampleItem[]; }) => group.items)); declare class TilesListClass extends TilesList { } @@ -71,8 +69,10 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu this.state = { isModalSelection: this._selection.isModal(), isDataLoaded: false, - cells: getShimmerCells(SHIMMER_GROUP, { - onRenderCell: this._onRenderShimmerCell + cells: getTileCells(SHIMMER_GROUPS, { + onRenderCell: this._onRenderShimmerCell, + onRenderHeader: this._onRenderHeader, + shimmerMode: true }) }; } @@ -118,10 +118,12 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu private _onToggleIsDataLoaded = (checked: boolean): void => { const { isDataLoaded } = this.state; let { cells } = this.state; - - if (cells.length && cells[0].key !== 'shimmerGroup') { - cells = getShimmerCells(SHIMMER_GROUP, { - onRenderCell: this._onRenderShimmerCell + console.log(cells); + if (cells.length && !cells[0].isPlaceholder) { + cells = getTileCells(SHIMMER_GROUPS, { + onRenderCell: this._onRenderShimmerCell, + onRenderHeader: this._onRenderHeader, + shimmerMode: true }); } else { cells = getTileCells(GROUPS, { From 53fe917dc556d8f0f0b9c833b55824d51d3c0a57 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Wed, 4 Apr 2018 23:26:52 -0700 Subject: [PATCH 09/36] Refactors some logic. --- .../src/components/TilesList/TilesList.tsx | 51 ++++++++----------- .../TilesList/examples/ExampleHelpers.tsx | 5 +- .../examples/TilesList.Document.Example.tsx | 2 +- 3 files changed, 24 insertions(+), 34 deletions(-) diff --git a/packages/experiments/src/components/TilesList/TilesList.tsx b/packages/experiments/src/components/TilesList/TilesList.tsx index fab65c0fbad32..aae45f492fcf7 100644 --- a/packages/experiments/src/components/TilesList/TilesList.tsx +++ b/packages/experiments/src/components/TilesList/TilesList.tsx @@ -15,7 +15,7 @@ const CELLS_PER_PAGE = 100; const MIN_ASPECT_RATIO = 0.5; const MAX_ASPECT_RATIO = 3; -const ROW_OF_SHIMMER_CELLS = 3; +// const ROW_OF_SHIMMER_CELLS = 3; export interface ITilesListState { cells: ITileCell[]; @@ -29,6 +29,7 @@ export interface ITileGrid { marginTop: number; marginBottom: number; key: string; + isPlaceholder?: boolean; } export interface ITileCell { @@ -36,6 +37,7 @@ export interface ITileCell { content: TItem; aspectRatio: number; grid: ITileGrid; + isPlaceholder?: boolean; onRender(content: TItem, finalSize: { width: number; height: number; }): React.ReactNode | React.ReactNode[]; } @@ -193,11 +195,7 @@ export class TilesList extends React.Component, IT (shimmerCellsPerRow * shimmerCellWidth) + (shimmerCellSpacing * (shimmerCellsPerRow - 1)) : undefined; - const cells: ITileCell[] = items ? - isShimmer ? - this._getCells(this.props.items, shimmerCellsPerRow) : - items : - []; + const cells: ITileCell[] = items || []; let grids: React.ReactNode[] = []; @@ -489,8 +487,7 @@ export class TilesList extends React.Component, IT }; } - private _getCells(items: (ITilesGridSegment | ITilesGridItem)[], - shimmerCellsPerRow?: number | undefined): ITileCell[] { + private _getCells(items: (ITilesGridSegment | ITilesGridItem)[]): ITileCell[] { const cells: ITileCell[] = []; for (const item of items) { @@ -510,8 +507,9 @@ export class TilesList extends React.Component, IT mode: item.mode, key: `grid-${item.key}`, maxScaleFactor: maxScaleFactor, - marginTop: marginTop, - marginBottom: marginBottom + marginTop: item.isPlaceholder ? 0 : marginTop, + marginBottom: item.isPlaceholder ? 0 : marginBottom, + isPlaceholder: item.isPlaceholder }; for (const gridItem of item.items) { @@ -525,25 +523,14 @@ export class TilesList extends React.Component, IT minAspectRatio, desiredSize && (desiredSize.width / desiredSize.height) || 1)); - if (shimmerCellsPerRow) { - for (let i = 0; i < shimmerCellsPerRow * ROW_OF_SHIMMER_CELLS; i++) { - cells.push({ - aspectRatio: aspectRatio, - content: gridItem.content, - onRender: gridItem.onRender, - grid: grid, - key: gridItem.key + i - }); - } - } else { - cells.push({ - aspectRatio: aspectRatio, - content: gridItem.content, - onRender: gridItem.onRender, - grid: grid, - key: gridItem.key - }); - } + cells.push({ + aspectRatio: aspectRatio, + content: gridItem.content, + onRender: gridItem.onRender, + grid: grid, + key: gridItem.key, + isPlaceholder: gridItem.isPlaceholder + }); } } else { cells.push({ @@ -557,9 +544,11 @@ export class TilesList extends React.Component, IT key: `grid-header-${item.key}`, maxScaleFactor: 1, marginBottom: 0, - marginTop: 0 + marginTop: 0, + isPlaceholder: item.isPlaceholder }, - key: `header-${item.key}` + key: `header-${item.key}`, + isPlaceholder: item.isPlaceholder }); } } diff --git a/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx b/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx index 1eab3e848780b..7ecf9572dbda6 100644 --- a/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx +++ b/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx @@ -116,11 +116,12 @@ export function getTileCells(groups: IExampleGroup[], { width: 171 * item.aspectRatio, height: 171 }, - onRender: onRenderCell + onRender: onRenderCell, + isPlaceholder: shimmerMode }; }), spacing: 8, - marginBottom: 40, + marginBottom: shimmerMode ? 0 : 40, minRowHeight: 171, mode: group.type === 'document' ? size === 'small' ? diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx index d6077584af44a..3b08a9cfa390d 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx @@ -118,7 +118,7 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu private _onToggleIsDataLoaded = (checked: boolean): void => { const { isDataLoaded } = this.state; let { cells } = this.state; - console.log(cells); + if (cells.length && !cells[0].isPlaceholder) { cells = getTileCells(SHIMMER_GROUPS, { onRenderCell: this._onRenderShimmerCell, From 23758323c79d5948861ff4cd9132721fe67b43fb Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Thu, 5 Apr 2018 12:39:24 -0700 Subject: [PATCH 10/36] Changes the logic for changes in TilesList. Moves getShimmerCell as a private member of Tile class. --- .../experiments/src/components/Tile/Tile.tsx | 95 ++++++++++--------- .../src/components/TilesList/TilesList.tsx | 68 +++++++------ 2 files changed, 87 insertions(+), 76 deletions(-) diff --git a/packages/experiments/src/components/Tile/Tile.tsx b/packages/experiments/src/components/Tile/Tile.tsx index 8065f943010b8..463c38a96911c 100644 --- a/packages/experiments/src/components/Tile/Tile.tsx +++ b/packages/experiments/src/components/Tile/Tile.tsx @@ -177,7 +177,7 @@ export class Tile extends BaseComponent { const isInvokable = (!!href || !!onClick || !!invokeSelection) && !isModal; if (shimmerPlaceholder) { - return getShimmerTile(foreground, itemName, itemActivity, tileSize); + return this._getShimmerTile(); } return ( @@ -379,6 +379,53 @@ export class Tile extends BaseComponent { isModal: isModal }); } + + private _getShimmerTile(): JSX.Element { + const { + foreground, + itemName, + itemActivity, + tileSize = 'large' + } = this.props; + + return ( +
+
+
+
+
+
+
+ ); + } } export interface ITileLayout { @@ -439,49 +486,3 @@ export function renderTileWithLayout(tileElement: JSX.Element, props: Partial ); } - -function getShimmerTile( - foreground: React.ReactNode | React.ReactNode[], - itemName: React.ReactNode | React.ReactNode[], - itemActivity: React.ReactNode | React.ReactNode[], - tileSize: TileSize = 'large' -): JSX.Element { - - return ( -
-
-
-
-
-
-
- ); -} diff --git a/packages/experiments/src/components/TilesList/TilesList.tsx b/packages/experiments/src/components/TilesList/TilesList.tsx index aae45f492fcf7..f2288e536e1ab 100644 --- a/packages/experiments/src/components/TilesList/TilesList.tsx +++ b/packages/experiments/src/components/TilesList/TilesList.tsx @@ -15,7 +15,7 @@ const CELLS_PER_PAGE = 100; const MIN_ASPECT_RATIO = 0.5; const MAX_ASPECT_RATIO = 3; -// const ROW_OF_SHIMMER_CELLS = 3; +const ROW_OF_SHIMMER_CELLS = 3; export interface ITilesListState { cells: ITileCell[]; @@ -185,16 +185,6 @@ export class TilesList extends React.Component, IT const data: IPageData = page.data; - const isShimmer: boolean = items && items[0] && items[0].key === 'shimmerItem' ? true : false; - const shimmerCellSpacing: number = items ? items[0].grid.spacing : 0; - const shimmerCellWidth: number = isShimmer ? data.cellSizes[0].width : 0; - const shimmerCellsPerRow: number | undefined = isShimmer ? - Math.floor(data.pageWidths[0] / (shimmerCellSpacing + shimmerCellWidth)) - : undefined; - const shimmerWrapperWidth: number | undefined = shimmerCellsPerRow ? - (shimmerCellsPerRow * shimmerCellWidth) + (shimmerCellSpacing * (shimmerCellsPerRow - 1)) : - undefined; - const cells: ITileCell[] = items || []; let grids: React.ReactNode[] = []; @@ -206,26 +196,30 @@ export class TilesList extends React.Component, IT let currentRow: IRowData | undefined; + let shimmerWrapperWidth = 0; + for (let i = 0; i < endIndex;) { // For each cell at the start of a grid. const grid = cells[i].grid; + const isPlaceholder = grid.isPlaceholder; + const renderedCells: React.ReactNode[] = []; - const width = data.pageWidths[isShimmer ? 0 : page.startIndex + i]; + const width = data.pageWidths[page.startIndex + i]; for (; i < endIndex && cells[i].grid === grid; i++) { // For each cell in the current grid. const cell = cells[i]; const index = page.startIndex + i; - const cellAsFirstRow = data.rows[isShimmer ? 0 : index]; + const cellAsFirstRow = data.rows[index]; if (cellAsFirstRow) { currentRow = cellAsFirstRow; } - let finalSize = data.cellSizes[isShimmer ? 0 : index]; + let finalSize = data.cellSizes[index]; if (currentRow) { const { @@ -247,7 +241,7 @@ export class TilesList extends React.Component, IT } } - renderedCells.push( + const renderedCell: JSX.Element = (
extends React.Component, IT // tslint:disable-next-line:jsx-ban-props style={ { - ...this._onGetCellStyle(cell, currentRow, isShimmer) + ...this._onGetCellStyle(cell, currentRow) } } > { this._onRenderCell(cell, finalSize) }
); + + if (cell.isPlaceholder && grid.mode !== TilesGridMode.none) { + let cellsPerRow = Math.floor(width / (grid.spacing + finalSize.width)); + let totalPlaceholderItems = cellsPerRow * ROW_OF_SHIMMER_CELLS; + shimmerWrapperWidth = (cellsPerRow * finalSize.width) + (grid.spacing * (cellsPerRow - 1)); + for (let j = 0; j < totalPlaceholderItems; j++) { + renderedCells.push(renderedCell); + } + } else { + renderedCells.push(renderedCell); + } } const isOpenStart = previousCell && previousCell.grid === grid; @@ -271,7 +276,7 @@ export class TilesList extends React.Component, IT const margin = grid.spacing / 2; - grids.push( + const finalGrid: JSX.Element = (
extends React.Component, IT { ...renderedCells }
); + + grids.push( + isPlaceholder ? + ( + + { finalGrid } + + ) : + finalGrid + ); } return ( @@ -297,15 +315,7 @@ export class TilesList extends React.Component, IT { ...divProps } className={ css(pageClassName, this._onGetPageClassName()) } > - { isShimmer ? - - { grids } - : - grids - } + { grids }
); } @@ -457,7 +467,7 @@ export class TilesList extends React.Component, IT return TilesListStyles.listPage; } - private _onGetCellStyle = (item: ITileCell, currentRow?: IRowData, isShimmer?: boolean): React.CSSProperties => { + private _onGetCellStyle = (item: ITileCell, currentRow?: IRowData): React.CSSProperties => { const { grid: { mode: gridMode, @@ -482,8 +492,8 @@ export class TilesList extends React.Component, IT `${width * maxScaleFactor}px` : // The item must not be scaled. `${width}px`, - margin: !isShimmer ? `${margin}px` : 0, - border: isShimmer ? `${margin}px solid white` : 'none' + margin: !item.isPlaceholder ? `${margin}px` : 0, + border: item.isPlaceholder ? `${margin}px solid white` : 'none' }; } From fabcaab01f313b5df0da87c63f39c362c0d3fadd Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Thu, 5 Apr 2018 14:27:44 -0700 Subject: [PATCH 11/36] Changes Tile 'shimmerPlaceholder' prop name to 'asPlaceholder'. Applies a different logic to the margin replaced by border. --- packages/experiments/src/components/Tile/Tile.tsx | 6 +++--- packages/experiments/src/components/Tile/Tile.types.ts | 4 ++-- .../experiments/src/components/TilesList/TilesList.scss | 1 + packages/experiments/src/components/TilesList/TilesList.tsx | 3 ++- .../TilesList/examples/TilesList.Document.Example.tsx | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/experiments/src/components/Tile/Tile.tsx b/packages/experiments/src/components/Tile/Tile.tsx index 463c38a96911c..5893a53640906 100644 --- a/packages/experiments/src/components/Tile/Tile.tsx +++ b/packages/experiments/src/components/Tile/Tile.tsx @@ -164,7 +164,7 @@ export class Tile extends BaseComponent { descriptionAriaLabel, href, onClick, - shimmerPlaceholder = false, + asPlaceholder = false, ...divProps } = this.props; @@ -176,7 +176,7 @@ export class Tile extends BaseComponent { const isSelectable = !!selection && selectionIndex > -1; const isInvokable = (!!href || !!onClick || !!invokeSelection) && !isModal; - if (shimmerPlaceholder) { + if (asPlaceholder) { return this._getShimmerTile(); } @@ -380,7 +380,7 @@ export class Tile extends BaseComponent { }); } - private _getShimmerTile(): JSX.Element { + private _getShimmerTile = (): JSX.Element => { const { foreground, itemName, diff --git a/packages/experiments/src/components/Tile/Tile.types.ts b/packages/experiments/src/components/Tile/Tile.types.ts index 45255634bfa70..f4b26f96d3695 100644 --- a/packages/experiments/src/components/Tile/Tile.types.ts +++ b/packages/experiments/src/components/Tile/Tile.types.ts @@ -39,12 +39,12 @@ export interface ITileProps extends IBaseProps, React.AllHTMLAttributes extends React.Component, IT // The item must not be scaled. `${width}px`, margin: !item.isPlaceholder ? `${margin}px` : 0, - border: item.isPlaceholder ? `${margin}px solid white` : 'none' + borderStyle: item.isPlaceholder ? 'solid' : 'none', + borderWidth: item.isPlaceholder ? `${margin}px` : 0 }; } diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx index 3b08a9cfa390d..16bf828a149f8 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx @@ -186,7 +186,7 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu private _onRenderShimmerCell(item: IExampleItem): JSX.Element { return ( } // placeholder itemName={ item.name } // placeholder itemActivity={ item.key } // placeholder From 99b6e0df50da660bf0ac7e92ff94de8f2bbc5fd6 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Thu, 5 Apr 2018 16:08:58 -0700 Subject: [PATCH 12/36] Renames props and styles in Tile --- .../experiments/src/components/Tile/Tile.scss | 74 +++++++++---------- .../experiments/src/components/Tile/Tile.tsx | 36 ++++----- .../src/components/Tile/Tile.types.ts | 5 +- .../examples/TilesList.Document.Example.tsx | 2 +- 4 files changed, 58 insertions(+), 59 deletions(-) diff --git a/packages/experiments/src/components/Tile/Tile.scss b/packages/experiments/src/components/Tile/Tile.scss index da50c600b2f3b..e0f8b94877cf6 100644 --- a/packages/experiments/src/components/Tile/Tile.scss +++ b/packages/experiments/src/components/Tile/Tile.scss @@ -10,18 +10,21 @@ $foregroundMargin: 16px; $smallNameplateHeight: (($nameplatePadding * 2) + $smallNameplateNameHeight + $smallNameplateActivityHeight); $largeNameplateHeight: (($nameplatePadding * 2) + $largeNameplateNameHeight + $largeNameplateActivityHeight); -@mixin shimmerBorders($divHeight, $lineHeight, $type) { +@mixin placeholderBorders($type, $divHeight: 0, $lineHeight: 0) { @if $type == 'nameBorders' { - border-top: $nameplatePadding solid $ms-color-white; - border-left: $nameplatePadding solid $ms-color-white; - border-right: $nameplatePadding solid $ms-color-white; - border-bottom: ($divHeight - $lineHeight) solid $ms-color-white; + border-style: solid; + border-color: $ms-color-white; + border-width: $nameplatePadding $nameplatePadding ($divHeight - $lineHeight) $nameplatePadding; } @if $type == 'activityBorders' { - border-top: ($divHeight - $lineHeight) solid $ms-color-white; - border-left: ($nameplatePadding * 4) solid $ms-color-white; - border-right: ($nameplatePadding * 4) solid $ms-color-white; - border-bottom: $nameplatePadding solid $ms-color-white + border-style: solid; + border-color: $ms-color-white; + border-width: ($divHeight - $lineHeight) ($nameplatePadding * 4) $nameplatePadding ($nameplatePadding * 4); + } + @if $type == 'aboveNameplateBorders' { + border-style: solid; + border-color: $ms-color-white; + border-width: $foregroundMargin ($foregroundMargin * 2) 0; } } @@ -419,67 +422,62 @@ $largeNameplateHeight: (($nameplatePadding * 2) + $largeNameplateNameHeight + $l } } -.shimmerTile { +// Tile styling when tile is used as a placeholder to cover a shimmering background leaving only specific windows. +.placeholderTile { width: 100%; height: 100%; - .noShimmer { + .missingContent { background-color: $ms-color-white; } } -.aboveNameplateShimmer { +.aboveNameplatePlaceholder, +.activityPlaceholder, +.namePlaceholder, +.nameplatePlaceholder { box-sizing: border-box; width: 100%; - border-top: $foregroundMargin solid $ms-color-white; - border-left: ($foregroundMargin * 2) solid $ms-color-white; - border-right: ($foregroundMargin * 2) solid $ms-color-white; +} + +.aboveNameplatePlaceholder { + @include placeholderBorders('aboveNameplateBorders'); - .isLargeShimmer & { + .isLargePlaceholder & { height: calc(100% - #{$largeNameplateHeight}); } - .isSmallShimmer & { + .isSmallPlaceholder & { height: calc(100% - #{$smallNameplateHeight}); } } -.nameplateShimmer { - width: 100%; - - .isLargeShimmer & { +.nameplatePlaceholder { + .isLargePlaceholder & { height: $largeNameplateHeight; - .nameShimmer { - width: 100%; - box-sizing: border-box; + .namePlaceholder { height: ($largeNameplateNameHeight + $nameplatePadding); - @include shimmerBorders($largeNameplateNameHeight, $ms-font-size-m, 'nameBorders'); + @include placeholderBorders('nameBorders', $largeNameplateNameHeight, $ms-font-size-m); } - .activityShimmer { - width: 100%; - box-sizing: border-box; + .activityPlaceholder { height: ($largeNameplateActivityHeight + $nameplatePadding); - @include shimmerBorders($largeNameplateActivityHeight, $ms-font-size-s, 'activityBorders'); + @include placeholderBorders('activityBorders', $largeNameplateActivityHeight, $ms-font-size-s); } } - .isSmallShimmer & { + .isSmallPlaceholder & { height: $smallNameplateHeight; - .nameShimmer { - width: 100%; - box-sizing: border-box; + .namePlaceholder { height: ($smallNameplateNameHeight + $nameplatePadding); - @include shimmerBorders($smallNameplateActivityHeight, $ms-font-size-s, 'nameBorders'); + @include placeholderBorders('nameBorders', $smallNameplateActivityHeight, $ms-font-size-s); } - .activityShimmer { - width: 100%; - box-sizing: border-box; + .activityPlaceholder { height: ($smallNameplateActivityHeight + $nameplatePadding); - @include shimmerBorders($smallNameplateActivityHeight, $ms-font-size-s, 'activityBorders'); + @include placeholderBorders('activityBorders', $smallNameplateActivityHeight, $ms-font-size-s); } } } diff --git a/packages/experiments/src/components/Tile/Tile.tsx b/packages/experiments/src/components/Tile/Tile.tsx index 5893a53640906..847f0a33f7cb9 100644 --- a/packages/experiments/src/components/Tile/Tile.tsx +++ b/packages/experiments/src/components/Tile/Tile.tsx @@ -164,7 +164,7 @@ export class Tile extends BaseComponent { descriptionAriaLabel, href, onClick, - asPlaceholder = false, + renderPlaceholder = false, ...divProps } = this.props; @@ -176,8 +176,8 @@ export class Tile extends BaseComponent { const isSelectable = !!selection && selectionIndex > -1; const isInvokable = (!!href || !!onClick || !!invokeSelection) && !isModal; - if (asPlaceholder) { - return this._getShimmerTile(); + if (renderPlaceholder) { + return this._onRenderPlaceholderTile(); } return ( @@ -380,7 +380,7 @@ export class Tile extends BaseComponent { }); } - private _getShimmerTile = (): JSX.Element => { + private _onRenderPlaceholderTile = (): JSX.Element => { const { foreground, itemName, @@ -390,36 +390,36 @@ export class Tile extends BaseComponent { return (
diff --git a/packages/experiments/src/components/Tile/Tile.types.ts b/packages/experiments/src/components/Tile/Tile.types.ts index f4b26f96d3695..2f105a73600ef 100644 --- a/packages/experiments/src/components/Tile/Tile.types.ts +++ b/packages/experiments/src/components/Tile/Tile.types.ts @@ -39,12 +39,13 @@ export interface ITileProps extends IBaseProps, React.AllHTMLAttributes } // placeholder itemName={ item.name } // placeholder itemActivity={ item.key } // placeholder From 99548e8c1cea4947705c87c46299bd7bea6d3175 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Fri, 6 Apr 2018 10:30:10 -0700 Subject: [PATCH 13/36] Break point to test some new things. --- .../experiments/src/components/Tile/Tile.scss | 45 ++++++++++++++----- .../src/components/TilesList/TilesList.tsx | 43 +++++++++--------- .../examples/TilesList.Document.Example.tsx | 18 +++++++- .../TilesList/examples/TilesList.Example.scss | 9 ++++ 4 files changed, 82 insertions(+), 33 deletions(-) diff --git a/packages/experiments/src/components/Tile/Tile.scss b/packages/experiments/src/components/Tile/Tile.scss index e0f8b94877cf6..f269a548b2855 100644 --- a/packages/experiments/src/components/Tile/Tile.scss +++ b/packages/experiments/src/components/Tile/Tile.scss @@ -7,10 +7,28 @@ $smallNameplateNameHeight: 12px; $largeNameplateActivityHeight: 20px; $smallNameplateActivityHeight: 20px; $foregroundMargin: 16px; -$smallNameplateHeight: (($nameplatePadding * 2) + $smallNameplateNameHeight + $smallNameplateActivityHeight); + +// Values given by designers for placeholder tile. +// Large tile specs +$largeSquareWidth: 96px; +$largeSquareHeight: 96px; +$largeLineHeight: 7px; +$largeTopLineWidth: 144px; +$largeBottomLineWidth: $largeSquareWidth; +// Small tile specs +$smallSquareWidth: 62px; +$smallSquareHeight: 61px; +$smallLineHeight: 5px; +$smallTopLineWidth: 106px; +$smallBottomLineWidth: $smallSquareWidth; + + $largeNameplateHeight: (($nameplatePadding * 2) + $largeNameplateNameHeight + $largeNameplateActivityHeight); +$smallNameplateHeight: (($nameplatePadding * 2) + $smallNameplateNameHeight + $smallNameplateActivityHeight); +$largeAboveNameplateHeight: calc(100% - #{$largeNameplateHeight}); +$smallAboveNameplateHeight: calc(100% - #{$smallNameplateHeight}); -@mixin placeholderBorders($type, $divHeight: 0, $lineHeight: 0) { +@mixin placeholderBorders($type, $divHeight, $lineHeight, $lineWidth) { @if $type == 'nameBorders' { border-style: solid; border-color: $ms-color-white; @@ -19,12 +37,16 @@ $largeNameplateHeight: (($nameplatePadding * 2) + $largeNameplateNameHeight + $l @if $type == 'activityBorders' { border-style: solid; border-color: $ms-color-white; - border-width: ($divHeight - $lineHeight) ($nameplatePadding * 4) $nameplatePadding ($nameplatePadding * 4); + border-width: ($divHeight - ($lineHeight * 2)) ($nameplatePadding * 4) ($nameplatePadding + $lineHeight) ($nameplatePadding * 4); } @if $type == 'aboveNameplateBorders' { + // border-top: ($divHeight - $lineHeight) solid $ms-color-white; + // border-right: 0 solid $ms-color-white; + // border-bottom: 0 solid $ms-color-white; + // border-left: 0 solid $ms-color-white; border-style: solid; border-color: $ms-color-white; - border-width: $foregroundMargin ($foregroundMargin * 2) 0; + border-width: (($divHeight) - ($lineHeight)) 0 0 0; } } @@ -441,14 +463,15 @@ $largeNameplateHeight: (($nameplatePadding * 2) + $largeNameplateNameHeight + $l } .aboveNameplatePlaceholder { - @include placeholderBorders('aboveNameplateBorders'); .isLargePlaceholder & { - height: calc(100% - #{$largeNameplateHeight}); + height: $largeAboveNameplateHeight; + @include placeholderBorders('aboveNameplateBorders', $largeAboveNameplateHeight, $largeSquareHeight, $largeSquareWidth); } .isSmallPlaceholder & { - height: calc(100% - #{$smallNameplateHeight}); + height: $smallAboveNameplateHeight; + @include placeholderBorders('aboveNameplateBorders', $smallAboveNameplateHeight, $smallSquareHeight, $smallSquareWidth); } } @@ -458,12 +481,12 @@ $largeNameplateHeight: (($nameplatePadding * 2) + $largeNameplateNameHeight + $l .namePlaceholder { height: ($largeNameplateNameHeight + $nameplatePadding); - @include placeholderBorders('nameBorders', $largeNameplateNameHeight, $ms-font-size-m); + @include placeholderBorders('nameBorders', $largeNameplateNameHeight, $largeLineHeight, $largeTopLineWidth); } .activityPlaceholder { height: ($largeNameplateActivityHeight + $nameplatePadding); - @include placeholderBorders('activityBorders', $largeNameplateActivityHeight, $ms-font-size-s); + @include placeholderBorders('activityBorders', $largeNameplateActivityHeight, $largeLineHeight, $smallTopLineWidth); } } @@ -472,12 +495,12 @@ $largeNameplateHeight: (($nameplatePadding * 2) + $largeNameplateNameHeight + $l .namePlaceholder { height: ($smallNameplateNameHeight + $nameplatePadding); - @include placeholderBorders('nameBorders', $smallNameplateActivityHeight, $ms-font-size-s); + @include placeholderBorders('nameBorders', $smallNameplateActivityHeight, $smallLineHeight, $largeBottomLineWidth); } .activityPlaceholder { height: ($smallNameplateActivityHeight + $nameplatePadding); - @include placeholderBorders('activityBorders', $smallNameplateActivityHeight, $ms-font-size-s); + @include placeholderBorders('activityBorders', $smallNameplateActivityHeight, $smallLineHeight, $smallBottomLineWidth); } } } diff --git a/packages/experiments/src/components/TilesList/TilesList.tsx b/packages/experiments/src/components/TilesList/TilesList.tsx index c0d6fc8f31b71..73d05488fe95a 100644 --- a/packages/experiments/src/components/TilesList/TilesList.tsx +++ b/packages/experiments/src/components/TilesList/TilesList.tsx @@ -15,7 +15,7 @@ const CELLS_PER_PAGE = 100; const MIN_ASPECT_RATIO = 0.5; const MAX_ASPECT_RATIO = 3; -const ROW_OF_SHIMMER_CELLS = 3; +const ROW_OF_PLACEHOLDER_CELLS = 3; export interface ITilesListState { cells: ITileCell[]; @@ -241,33 +241,35 @@ export class TilesList extends React.Component, IT } } - const renderedCell: JSX.Element = ( -
{ + return ( +
- { this._onRenderCell(cell, finalSize) } -
- ); + > + { this._onRenderCell(cell, finalSize) } +
+ ); + }; if (cell.isPlaceholder && grid.mode !== TilesGridMode.none) { let cellsPerRow = Math.floor(width / (grid.spacing + finalSize.width)); - let totalPlaceholderItems = cellsPerRow * ROW_OF_SHIMMER_CELLS; + let totalPlaceholderItems = cellsPerRow * ROW_OF_PLACEHOLDER_CELLS; shimmerWrapperWidth = (cellsPerRow * finalSize.width) + (grid.spacing * (cellsPerRow - 1)); for (let j = 0; j < totalPlaceholderItems; j++) { - renderedCells.push(renderedCell); + renderedCells.push(renderedCell(j)); } } else { - renderedCells.push(renderedCell); + renderedCells.push(renderedCell()); } } @@ -300,6 +302,7 @@ export class TilesList extends React.Component, IT isPlaceholder ? ( diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx index 52d17f0614dae..0adbe359458ee 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx @@ -20,6 +20,10 @@ import { getTileCells, createShimmerGroups } from './ExampleHelpers'; +import * as TilesListExampleStylesModule from './TilesList.Example.scss'; + +// tslint:disable-next-line:no-any +const TilesListExampleStyles = TilesListExampleStylesModule as any; function createGroups(): IExampleGroup[] { let offset = 0; @@ -71,7 +75,7 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu isDataLoaded: false, cells: getTileCells(SHIMMER_GROUPS, { onRenderCell: this._onRenderShimmerCell, - onRenderHeader: this._onRenderHeader, + onRenderHeader: this._onRenderShimmerHeader, shimmerMode: true }) }; @@ -122,7 +126,7 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu if (cells.length && !cells[0].isPlaceholder) { cells = getTileCells(SHIMMER_GROUPS, { onRenderCell: this._onRenderShimmerCell, - onRenderHeader: this._onRenderHeader, + onRenderHeader: this._onRenderShimmerHeader, shimmerMode: true }); } else { @@ -201,4 +205,14 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu
); } + + private _onRenderShimmerHeader = (item: IExampleItem): JSX.Element => { + return ( +
+

{ item.name }

+
+ ); + } } diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Example.scss b/packages/experiments/src/components/TilesList/examples/TilesList.Example.scss index 221bbc222dc32..50970b29c2221 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Example.scss +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Example.scss @@ -2,3 +2,12 @@ .tileImage { display: block; } + +.shimmerHeader { + width: 100%; + height: 100%; + box-sizing: border-box; + border-style: solid; + border-color: white; + border-width: calc(100% - 10px) calc(100% - 50%) calc(100% - 10px) 10px; +} From 9a8ad261b2c6f6a1927e2ac24051b7a0583d5ff8 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Fri, 6 Apr 2018 16:00:11 -0700 Subject: [PATCH 14/36] Exports the TileLayoutValues enum. --- packages/experiments/src/components/Tile/Tile.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/experiments/src/components/Tile/Tile.tsx b/packages/experiments/src/components/Tile/Tile.tsx index 1a18e013a8ed8..ce904749d0435 100644 --- a/packages/experiments/src/components/Tile/Tile.tsx +++ b/packages/experiments/src/components/Tile/Tile.tsx @@ -14,7 +14,7 @@ const SignalStyles: any = SignalStylesModule; const CheckStyles: any = CheckStylesModule; // tslint:enable:no-any -const enum TileLayoutValues { +export const enum TileLayoutValues { nameplatePadding = 12, largeNameplateNameHeight = 15, smallNameplateNameHeight = 12, From 5e09d5feb2b7f283355951a788d51dc9c0a7035e Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Fri, 6 Apr 2018 17:04:04 -0700 Subject: [PATCH 15/36] Duplicate ShimmerLine to put basics for ShimmerGap. --- .../Shimmer/ShimmerGap/ShimmerGap.base.tsx | 34 ++++++++++ .../Shimmer/ShimmerGap/ShimmerGap.styles.ts | 30 +++++++++ .../Shimmer/ShimmerGap/ShimmerGap.tsx | 15 +++++ .../Shimmer/ShimmerGap/ShimmerGap.types.ts | 66 +++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.base.tsx create mode 100644 packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts create mode 100644 packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.tsx create mode 100644 packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.types.ts diff --git a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.base.tsx b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.base.tsx new file mode 100644 index 0000000000000..57f057798bc2c --- /dev/null +++ b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.base.tsx @@ -0,0 +1,34 @@ +import * as React from 'react'; +import { + BaseComponent, + classNamesFunction, +} from '../../../Utilities'; +import { + IShimmerGapProps, + IShimmerGapStyleProps, + IShimmerGapStyles +} from './ShimmerGap.types'; +import { ShimmerElementVerticalAlign } from 'experiments/lib/Shimmer'; + +const getClassNames = classNamesFunction(); + +export class ShimmerGapBase extends BaseComponent { + public static defaultProps: IShimmerGapProps = { + verticalAlign: ShimmerElementVerticalAlign.CENTER, + }; + private _classNames: {[key in keyof IShimmerGapStyles]: string}; + + constructor(props: IShimmerGapProps) { + 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/ShimmerGap/ShimmerGap.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts new file mode 100644 index 0000000000000..f7eba4b93ceab --- /dev/null +++ b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts @@ -0,0 +1,30 @@ +import { + IShimmerGapStyleProps, + IShimmerGapStyles +} from './ShimmerGap.types'; +import { IStyleSet } from 'office-ui-fabric-react/lib/Styling'; + +export function getStyles(props: IShimmerGapStyleProps): IShimmerGapStyles { + const { + height, + widthInPercentage, + widthInPixel, + borderAlignStyle + } = props; + + const styles: IStyleSet = !!borderAlignStyle ? borderAlignStyle : {}; + const ACTUAL_WIDTH = widthInPercentage ? widthInPercentage + '%' : widthInPixel ? widthInPixel + 'px' : '100%'; + + return { + root: [ + 'ms-ShimmerGap-line', + { + color: 'transparent', + width: ACTUAL_WIDTH, + height: `${height}px`, + boxSizing: 'content-box', + }, + styles + ] + }; +} diff --git a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.tsx b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.tsx new file mode 100644 index 0000000000000..dff5780583ed5 --- /dev/null +++ b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.tsx @@ -0,0 +1,15 @@ +import { + styled +} from '../../../Utilities'; +import { + IShimmerGapProps, + IShimmerGapStyleProps, + IShimmerGapStyles +} from './ShimmerGap.types'; +import { ShimmerGapBase } from './ShimmerGap.base'; +import { getStyles } from './ShimmerGap.styles'; + +export const ShimmerGap = styled( + ShimmerGapBase, + getStyles +); diff --git a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.types.ts b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.types.ts new file mode 100644 index 0000000000000..cd141fcb904c8 --- /dev/null +++ b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.types.ts @@ -0,0 +1,66 @@ +import * as React from 'react'; +import { + IStyle, + IStyleSet +} from '../../../Styling'; +import { IStyleFunction } from '../../../Utilities'; + +export interface IShimmerGap { + +} + +/** + * ShimmerGap component props. + */ +export interface IShimmerGapProps extends React.AllHTMLAttributes { + /** + * Optional callback to access the IShimmerGap interface. Use this instead of ref for accessing + * the public methods and properties of the component. + */ + componentRef?: (component: IShimmerGap | null) => 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 IShimmerGapStyleProps { + height?: number; + verticalAlign?: string; + widthInPercentage?: number; + widthInPixel?: number; + borderAlignStyle?: IStyleSet; +} + +export interface IShimmerGapStyles { + root?: IStyle; +} \ No newline at end of file From 3f8168fae0f8cb7e4990cd9e972731de58d9d6e1 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Fri, 6 Apr 2018 18:27:19 -0700 Subject: [PATCH 16/36] Removes unnecessary checks and moves functions outside for re-usability. --- .../src/components/Shimmer/Shimmer.base.tsx | 113 +++++++++--------- .../src/components/Shimmer/Shimmer.types.ts | 5 + 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx index 4d7c4b60eea86..7b02d7b9d6e35 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx +++ b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx @@ -21,6 +21,7 @@ import { ShimmerLine } from './ShimmerLine/ShimmerLine'; import { ShimmerCircle } from './ShimmerCircle/ShimmerCircle'; const LINE_DEFAULT_HEIGHT = 16; +const GAP_DEFAULT_HEIGHT = 16; const CIRCLE_DEFAULT_HEIGHT = 24; const getClassNames = classNamesFunction(); @@ -38,21 +39,18 @@ export class ShimmerBase extends BaseComponent { public render(): JSX.Element { const { getStyles, width, lineElements, children, isDataLoaded, isBaseStyle } = this.props; - const maxHeight: number | undefined = lineElements ? this._findMaxHeight(lineElements) : undefined; + const maxHeight: number | undefined = lineElements ? findMaxHeight(lineElements) : undefined; 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: @@ -71,14 +69,11 @@ export class ShimmerBase extends BaseComponent { /> ); case ShimmerElementType.LINE: - if (!elem.height) { - elem.height = LINE_DEFAULT_HEIGHT; - } return ( ); } @@ -102,60 +97,60 @@ export class ShimmerBase extends BaseComponent {
); } +} - private _findMaxHeight(items: Array): 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; - }); +export function getBorderAlignStyles(maxHeight: number | undefined, elem: ICircle | IGap | ILine): IStyleSet | undefined { + const elemHeight: number | undefined = elem.height; - const maxHeight = itemsDefaulted.reduce((acc: number, next: ICircle | IGap | ILine): number => { - return next.height ? - next.height > acc ? next.height : acc - : acc; - }, 0); - return maxHeight; - } - - private _getBorderAlignStyles(maxHeight: number | undefined, elem: ICircle | IGap | ILine): IStyleSet | undefined { - const elemHeight: number | undefined = elem.height; + const dif: number = maxHeight && elemHeight ? maxHeight - elemHeight : 0; - const dif: number | undefined = maxHeight && elemHeight ? - maxHeight - elemHeight > 0 ? - maxHeight - elemHeight : undefined - : undefined; + let borderStyle: IStyleSet | undefined; - let borderStyle: IStyleSet | undefined; - const hasVerticalAlign: boolean = elem.verticalAlign ? true : false; + if (!elem.verticalAlign || elem.verticalAlign === ShimmerElementVerticalAlign.CENTER) { + borderStyle = { + alignSelf: 'center', + borderBottom: `${dif ? dif / 2 : 0}px solid ${DefaultPalette.white}`, + borderTop: `${dif ? dif / 2 : 0}px solid ${DefaultPalette.white}` + }; + } else if (elem.verticalAlign && elem.verticalAlign === ShimmerElementVerticalAlign.TOP) { + borderStyle = { + alignSelf: 'top', + borderBottom: `${dif ? dif : 0}px solid ${DefaultPalette.white}`, + borderTop: `0px solid ${DefaultPalette.white}` + }; + } else if (elem.verticalAlign && elem.verticalAlign === ShimmerElementVerticalAlign.BOTTOM) { + borderStyle = { + alignSelf: 'bottom', + borderBottom: `0px solid ${DefaultPalette.white}`, + borderTop: `${dif ? dif : 0}px solid ${DefaultPalette.white}` + }; + } + return borderStyle; +} - if (elem.verticalAlign === ShimmerElementVerticalAlign.CENTER || !hasVerticalAlign) { - borderStyle = { - alignSelf: 'center', - borderBottom: `${dif ? dif / 2 : 0}px solid ${DefaultPalette.white}`, - borderTop: `${dif ? dif / 2 : 0}px solid ${DefaultPalette.white}` - }; - } else if (elem.verticalAlign === ShimmerElementVerticalAlign.TOP && hasVerticalAlign) { - borderStyle = { - alignSelf: 'top', - borderBottom: `${dif ? dif : 0}px solid ${DefaultPalette.white}`, - borderTop: `0px solid ${DefaultPalette.white}` - }; - } else if (elem.verticalAlign === ShimmerElementVerticalAlign.BOTTOM && hasVerticalAlign) { - borderStyle = { - alignSelf: 'bottom', - borderBottom: `0px solid ${DefaultPalette.white}`, - borderTop: `${dif ? dif : 0}px solid ${DefaultPalette.white}` - }; +export function findMaxHeight(items: Array): 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; + } + case ShimmerElementType.GAP: + if (!item.height) { + item.height = GAP_DEFAULT_HEIGHT; + } } - return borderStyle; - } + return item; + }); + + const maxHeight = itemsDefaulted.reduce((acc: number, next: ICircle | IGap | ILine): number => { + return next.height ? + next.height > acc ? next.height : acc + : acc; + }, 0); + return maxHeight; } \ No newline at end of file diff --git a/packages/experiments/src/components/Shimmer/Shimmer.types.ts b/packages/experiments/src/components/Shimmer/Shimmer.types.ts index 8b8d01f8380a9..5f645ee4b3b54 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.types.ts +++ b/packages/experiments/src/components/Shimmer/Shimmer.types.ts @@ -106,6 +106,11 @@ export interface ICircle extends IShimmerElement { } export interface IGap extends IShimmerElement { + /** + * Sets the height of the shimmer gap in pixels. + * @default 16px + */ + height?: number; /** * The value will be calculated as '%' relative the to shimmer wrapper. */ From 08ecdae8cf80d93a36663419df0a4e682430700a Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Fri, 6 Apr 2018 18:52:26 -0700 Subject: [PATCH 17/36] Change the name of maxHeight to maxLineHeight for better semantics. --- .../src/components/Shimmer/Shimmer.base.tsx | 18 +++++++++--------- .../src/components/Shimmer/Shimmer.styles.ts | 4 ++-- .../src/components/Shimmer/Shimmer.types.ts | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx index 7b02d7b9d6e35..b8d81dfc70c39 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx +++ b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx @@ -39,8 +39,8 @@ export class ShimmerBase extends BaseComponent { public render(): JSX.Element { const { getStyles, width, lineElements, children, isDataLoaded, isBaseStyle } = this.props; - const maxHeight: number | undefined = lineElements ? findMaxHeight(lineElements) : undefined; - this._classNames = getClassNames(getStyles!, { width, maxHeight, isDataLoaded, isBaseStyle }); + const maxLineHeight: number | undefined = lineElements ? findMaxHeight(lineElements) : undefined; + this._classNames = getClassNames(getStyles!, { width, maxLineHeight, isDataLoaded, isBaseStyle }); const elements: JSX.Element[] | JSX.Element = lineElements ? lineElements.map((elem: ICircle | ILine | IGap, index: number): JSX.Element => { @@ -50,7 +50,7 @@ export class ShimmerBase extends BaseComponent { ); case ShimmerElementType.GAP: @@ -63,7 +63,7 @@ export class ShimmerBase extends BaseComponent { // tslint:disable-next-line:jsx-ban-props style={ { width: gapWidth, - height: maxHeight + 'px', + height: maxLineHeight + 'px', backgroundColor: `${DefaultPalette.white}` } } /> @@ -73,7 +73,7 @@ export class ShimmerBase extends BaseComponent { ); } @@ -99,10 +99,10 @@ export class ShimmerBase extends BaseComponent { } } -export function getBorderAlignStyles(maxHeight: number | undefined, elem: ICircle | IGap | ILine): IStyleSet | undefined { +export function getBorderAlignStyles(maxLineHeight: number | undefined, elem: ICircle | IGap | ILine): IStyleSet | undefined { const elemHeight: number | undefined = elem.height; - const dif: number = maxHeight && elemHeight ? maxHeight - elemHeight : 0; + const dif: number = maxLineHeight && elemHeight ? maxLineHeight - elemHeight : 0; let borderStyle: IStyleSet | undefined; @@ -147,10 +147,10 @@ export function findMaxHeight(items: Array): number { return item; }); - const maxHeight = itemsDefaulted.reduce((acc: number, next: ICircle | IGap | ILine): number => { + const maxLineHeight = itemsDefaulted.reduce((acc: number, next: ICircle | IGap | ILine): number => { return next.height ? next.height > acc ? next.height : acc : acc; }, 0); - return maxHeight; + return maxLineHeight; } \ No newline at end of file diff --git a/packages/experiments/src/components/Shimmer/Shimmer.styles.ts b/packages/experiments/src/components/Shimmer/Shimmer.styles.ts index 78dd50cdf8fd2..ef294896bd3b5 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.styles.ts +++ b/packages/experiments/src/components/Shimmer/Shimmer.styles.ts @@ -7,7 +7,7 @@ import { export function getStyles(props: IShimmerStyleProps): IShimmerStyles { const { width, - maxHeight, + maxLineHeight, isDataLoaded, isBaseStyle } = props; @@ -31,7 +31,7 @@ export function getStyles(props: IShimmerStyleProps): IShimmerStyles { margin: '10px', width: 'auto', boxSizing: 'content-box', - minHeight: maxHeight ? `${maxHeight}px` : '16px' + minHeight: maxLineHeight ? `${maxLineHeight}px` : '16px' }, isBaseStyle && { margin: '0', diff --git a/packages/experiments/src/components/Shimmer/Shimmer.types.ts b/packages/experiments/src/components/Shimmer/Shimmer.types.ts index 5f645ee4b3b54..dcf2f04113ad6 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.types.ts +++ b/packages/experiments/src/components/Shimmer/Shimmer.types.ts @@ -125,7 +125,7 @@ export interface IGap extends IShimmerElement { export interface IShimmerStyleProps { width?: number; - maxHeight?: number; + maxLineHeight?: number; isDataLoaded?: boolean; isBaseStyle?: boolean; } From 9fad784826f0b7c54583e7e1fdea4ed98a4e0044 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Fri, 6 Apr 2018 19:16:28 -0700 Subject: [PATCH 18/36] Extracts another function for reusability purposes. --- .../src/components/Shimmer/Shimmer.base.tsx | 114 ++++++++++-------- 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx index b8d81dfc70c39..dcad510313d92 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx +++ b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx @@ -39,54 +39,17 @@ export class ShimmerBase extends BaseComponent { public render(): JSX.Element { const { getStyles, width, lineElements, children, isDataLoaded, isBaseStyle } = this.props; + const maxLineHeight: number | undefined = lineElements ? findMaxHeight(lineElements) : undefined; + this._classNames = getClassNames(getStyles!, { width, maxLineHeight, 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: - return ( - - ); - case ShimmerElementType.GAP: - const gapWidth = elem.widthInPercentage || elem.widthInPixel ? - elem.widthInPercentage ? elem.widthInPercentage + '%' : elem.widthInPixel + 'px' - : '5px'; - return ( -
- ); - case ShimmerElementType.LINE: - return ( - - ); - } - }) : ( - - ); + const renderedElements: JSX.Element[] | JSX.Element = getRenderedElements(lineElements, maxLineHeight); return (
- { !!isBaseStyle ? children : elements } + { !!isBaseStyle ? children : renderedElements }
{ !!isDataLoaded && @@ -99,7 +62,52 @@ export class ShimmerBase extends BaseComponent { } } -export function getBorderAlignStyles(maxLineHeight: number | undefined, elem: ICircle | IGap | ILine): IStyleSet | undefined { +export function getRenderedElements(lineElements?: Array, maxLineHeight?: number): JSX.Element[] | JSX.Element { + const renderedElements: JSX.Element[] | JSX.Element = lineElements ? + lineElements.map((elem: ICircle | ILine | IGap, index: number): JSX.Element => { + switch (elem.type) { + case ShimmerElementType.CIRCLE: + return ( + + ); + case ShimmerElementType.GAP: + const gapWidth = elem.widthInPercentage || elem.widthInPixel ? + elem.widthInPercentage ? elem.widthInPercentage + '%' : elem.widthInPixel + 'px' + : '5px'; + return ( +
+ ); + case ShimmerElementType.LINE: + return ( + + ); + } + }) : ( + + ); + + return renderedElements; +} + +export function getBorderAlignStyles(elem: ICircle | IGap | ILine, maxLineHeight?: number): IStyleSet | undefined { const elemHeight: number | undefined = elem.height; const dif: number = maxLineHeight && elemHeight ? maxLineHeight - elemHeight : 0; @@ -125,26 +133,27 @@ export function getBorderAlignStyles(maxLineHeight: number | undefined, elem: IC borderTop: `${dif ? dif : 0}px solid ${DefaultPalette.white}` }; } + return borderStyle; } -export function findMaxHeight(items: Array): number { - const itemsDefaulted: Array = items.map((item: ICircle | IGap | ILine): ICircle | IGap | ILine => { - switch (item.type) { +export function findMaxHeight(elements: Array): number { + const itemsDefaulted: Array = elements.map((elem: ICircle | IGap | ILine): ICircle | IGap | ILine => { + switch (elem.type) { case ShimmerElementType.CIRCLE: - if (!item.height) { - item.height = CIRCLE_DEFAULT_HEIGHT; + if (!elem.height) { + elem.height = CIRCLE_DEFAULT_HEIGHT; } case ShimmerElementType.LINE: - if (!item.height) { - item.height = LINE_DEFAULT_HEIGHT; + if (!elem.height) { + elem.height = LINE_DEFAULT_HEIGHT; } case ShimmerElementType.GAP: - if (!item.height) { - item.height = GAP_DEFAULT_HEIGHT; + if (!elem.height) { + elem.height = GAP_DEFAULT_HEIGHT; } } - return item; + return elem; }); const maxLineHeight = itemsDefaulted.reduce((acc: number, next: ICircle | IGap | ILine): number => { @@ -152,5 +161,6 @@ export function findMaxHeight(items: Array): number { next.height > acc ? next.height : acc : acc; }, 0); + return maxLineHeight; } \ No newline at end of file From 880c58df6fc38fc3af9e26f59fee6f977a178b85 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Sat, 7 Apr 2018 18:18:37 -0700 Subject: [PATCH 19/36] Renames again a prop for semantics reasons. --- .../src/components/Shimmer/Shimmer.base.tsx | 22 +++++++++---------- .../src/components/Shimmer/Shimmer.styles.ts | 7 ++++-- .../src/components/Shimmer/Shimmer.types.ts | 2 +- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx index dcad510313d92..2061abd450817 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx +++ b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx @@ -40,11 +40,11 @@ export class ShimmerBase extends BaseComponent { public render(): JSX.Element { const { getStyles, width, lineElements, children, isDataLoaded, isBaseStyle } = this.props; - const maxLineHeight: number | undefined = lineElements ? findMaxHeight(lineElements) : undefined; + const rowHeight: number | undefined = lineElements ? findMaxHeight(lineElements) : undefined; - this._classNames = getClassNames(getStyles!, { width, maxLineHeight, isDataLoaded, isBaseStyle }); + this._classNames = getClassNames(getStyles!, { width, rowHeight, isDataLoaded, isBaseStyle }); - const renderedElements: JSX.Element[] | JSX.Element = getRenderedElements(lineElements, maxLineHeight); + const renderedElements: JSX.Element[] | JSX.Element = getRenderedElements(lineElements, rowHeight); return (
@@ -62,7 +62,7 @@ export class ShimmerBase extends BaseComponent { } } -export function getRenderedElements(lineElements?: Array, maxLineHeight?: number): JSX.Element[] | JSX.Element { +export function getRenderedElements(lineElements?: Array, rowHeight?: number): JSX.Element[] | JSX.Element { const renderedElements: JSX.Element[] | JSX.Element = lineElements ? lineElements.map((elem: ICircle | ILine | IGap, index: number): JSX.Element => { switch (elem.type) { @@ -71,7 +71,7 @@ export function getRenderedElements(lineElements?: Array ); case ShimmerElementType.GAP: @@ -84,7 +84,7 @@ export function getRenderedElements(lineElements?: Array // tslint:disable-next-line:jsx-ban-props style={ { width: gapWidth, - height: maxLineHeight + 'px', + height: rowHeight + 'px', backgroundColor: `${DefaultPalette.white}` } } /> @@ -94,7 +94,7 @@ export function getRenderedElements(lineElements?: Array ); } @@ -107,10 +107,10 @@ export function getRenderedElements(lineElements?: Array return renderedElements; } -export function getBorderAlignStyles(elem: ICircle | IGap | ILine, maxLineHeight?: number): IStyleSet | undefined { +export function getBorderAlignStyles(elem: ICircle | IGap | ILine, rowHeight?: number): IStyleSet | undefined { const elemHeight: number | undefined = elem.height; - const dif: number = maxLineHeight && elemHeight ? maxLineHeight - elemHeight : 0; + const dif: number = rowHeight && elemHeight ? rowHeight - elemHeight : 0; let borderStyle: IStyleSet | undefined; @@ -156,11 +156,11 @@ export function findMaxHeight(elements: Array): number { return elem; }); - const maxLineHeight = itemsDefaulted.reduce((acc: number, next: ICircle | IGap | ILine): number => { + const rowHeight = itemsDefaulted.reduce((acc: number, next: ICircle | IGap | ILine): number => { return next.height ? next.height > acc ? next.height : acc : acc; }, 0); - return maxLineHeight; + return rowHeight; } \ No newline at end of file diff --git a/packages/experiments/src/components/Shimmer/Shimmer.styles.ts b/packages/experiments/src/components/Shimmer/Shimmer.styles.ts index ef294896bd3b5..bfffee0668f16 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.styles.ts +++ b/packages/experiments/src/components/Shimmer/Shimmer.styles.ts @@ -7,7 +7,7 @@ import { export function getStyles(props: IShimmerStyleProps): IShimmerStyles { const { width, - maxLineHeight, + rowHeight, isDataLoaded, isBaseStyle } = props; @@ -31,7 +31,7 @@ export function getStyles(props: IShimmerStyleProps): IShimmerStyles { margin: '10px', width: 'auto', boxSizing: 'content-box', - minHeight: maxLineHeight ? `${maxLineHeight}px` : '16px' + minHeight: rowHeight ? `${rowHeight}px` : '16px' }, isBaseStyle && { margin: '0', @@ -46,6 +46,9 @@ export function getStyles(props: IShimmerStyleProps): IShimmerStyles { display: 'flex', position: 'absolute', top: '0', + bottom: '0', + left: '0', + right: '0', alignItems: 'center', alignContent: 'space-between', width: `${width}%`, diff --git a/packages/experiments/src/components/Shimmer/Shimmer.types.ts b/packages/experiments/src/components/Shimmer/Shimmer.types.ts index dcf2f04113ad6..baaf7bbc61be8 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.types.ts +++ b/packages/experiments/src/components/Shimmer/Shimmer.types.ts @@ -125,7 +125,7 @@ export interface IGap extends IShimmerElement { export interface IShimmerStyleProps { width?: number; - maxLineHeight?: number; + rowHeight?: number; isDataLoaded?: boolean; isBaseStyle?: boolean; } From 7cfe4aa737976948158d4d91568e9ba6a4e5eb94 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Sat, 7 Apr 2018 19:14:24 -0700 Subject: [PATCH 20/36] Cleans up code. --- .../src/components/Shimmer/Shimmer.base.tsx | 13 +++++-------- .../src/components/Shimmer/Shimmer.types.ts | 2 +- .../Shimmer/ShimmerGap/ShimmerGap.base.tsx | 4 ---- .../Shimmer/ShimmerGap/ShimmerGap.styles.ts | 6 +++--- .../Shimmer/ShimmerGap/ShimmerGap.types.ts | 8 +------- .../Shimmer/ShimmerLine/ShimmerLine.base.tsx | 4 ---- .../Shimmer/ShimmerLine/ShimmerLine.styles.ts | 1 - .../Shimmer/ShimmerLine/ShimmerLine.types.ts | 6 ------ 8 files changed, 10 insertions(+), 34 deletions(-) diff --git a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx index 2061abd450817..31713720f1c74 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx +++ b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx @@ -40,7 +40,7 @@ export class ShimmerBase extends BaseComponent { public render(): JSX.Element { const { getStyles, width, lineElements, children, isDataLoaded, isBaseStyle } = this.props; - const rowHeight: number | undefined = lineElements ? findMaxHeight(lineElements) : undefined; + const rowHeight: number | undefined = lineElements ? findMaxElementHeight(lineElements) : undefined; this._classNames = getClassNames(getStyles!, { width, rowHeight, isDataLoaded, isBaseStyle }); @@ -71,7 +71,7 @@ export function getRenderedElements(lineElements?: Array ); case ShimmerElementType.GAP: @@ -94,7 +94,7 @@ export function getRenderedElements(lineElements?: Array ); } @@ -107,7 +107,7 @@ export function getRenderedElements(lineElements?: Array return renderedElements; } -export function getBorderAlignStyles(elem: ICircle | IGap | ILine, rowHeight?: number): IStyleSet | undefined { +export function getBorderStyles(elem: ICircle | IGap | ILine, rowHeight?: number): IStyleSet | undefined { const elemHeight: number | undefined = elem.height; const dif: number = rowHeight && elemHeight ? rowHeight - elemHeight : 0; @@ -116,19 +116,16 @@ export function getBorderAlignStyles(elem: ICircle | IGap | ILine, rowHeight?: n if (!elem.verticalAlign || elem.verticalAlign === ShimmerElementVerticalAlign.CENTER) { borderStyle = { - alignSelf: 'center', borderBottom: `${dif ? dif / 2 : 0}px solid ${DefaultPalette.white}`, borderTop: `${dif ? dif / 2 : 0}px solid ${DefaultPalette.white}` }; } else if (elem.verticalAlign && elem.verticalAlign === ShimmerElementVerticalAlign.TOP) { borderStyle = { - alignSelf: 'top', borderBottom: `${dif ? dif : 0}px solid ${DefaultPalette.white}`, borderTop: `0px solid ${DefaultPalette.white}` }; } else if (elem.verticalAlign && elem.verticalAlign === ShimmerElementVerticalAlign.BOTTOM) { borderStyle = { - alignSelf: 'bottom', borderBottom: `0px solid ${DefaultPalette.white}`, borderTop: `${dif ? dif : 0}px solid ${DefaultPalette.white}` }; @@ -137,7 +134,7 @@ export function getBorderAlignStyles(elem: ICircle | IGap | ILine, rowHeight?: n return borderStyle; } -export function findMaxHeight(elements: Array): number { +export function findMaxElementHeight(elements: Array): number { const itemsDefaulted: Array = elements.map((elem: ICircle | IGap | ILine): ICircle | IGap | ILine => { switch (elem.type) { case ShimmerElementType.CIRCLE: diff --git a/packages/experiments/src/components/Shimmer/Shimmer.types.ts b/packages/experiments/src/components/Shimmer/Shimmer.types.ts index baaf7bbc61be8..6fe6293f99841 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.types.ts +++ b/packages/experiments/src/components/Shimmer/Shimmer.types.ts @@ -118,7 +118,7 @@ export interface IGap extends IShimmerElement { /** * Sets the width of the Gap to an exact value in pixels. - * @default 5px + * @default 10px */ widthInPixel?: number; } diff --git a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.base.tsx b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.base.tsx index 57f057798bc2c..1b8bfd6936016 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.base.tsx +++ b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.base.tsx @@ -8,14 +8,10 @@ import { IShimmerGapStyleProps, IShimmerGapStyles } from './ShimmerGap.types'; -import { ShimmerElementVerticalAlign } from 'experiments/lib/Shimmer'; const getClassNames = classNamesFunction(); export class ShimmerGapBase extends BaseComponent { - public static defaultProps: IShimmerGapProps = { - verticalAlign: ShimmerElementVerticalAlign.CENTER, - }; private _classNames: {[key in keyof IShimmerGapStyles]: string}; constructor(props: IShimmerGapProps) { diff --git a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts index f7eba4b93ceab..ea99b5bd484f4 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts @@ -2,7 +2,7 @@ import { IShimmerGapStyleProps, IShimmerGapStyles } from './ShimmerGap.types'; -import { IStyleSet } from 'office-ui-fabric-react/lib/Styling'; +import { IStyleSet, DefaultPalette } from 'office-ui-fabric-react/lib/Styling'; export function getStyles(props: IShimmerGapStyleProps): IShimmerGapStyles { const { @@ -13,13 +13,13 @@ export function getStyles(props: IShimmerGapStyleProps): IShimmerGapStyles { } = props; const styles: IStyleSet = !!borderAlignStyle ? borderAlignStyle : {}; - const ACTUAL_WIDTH = widthInPercentage ? widthInPercentage + '%' : widthInPixel ? widthInPixel + 'px' : '100%'; + const ACTUAL_WIDTH = widthInPercentage ? widthInPercentage + '%' : widthInPixel ? widthInPixel + 'px' : '10px'; return { root: [ 'ms-ShimmerGap-line', { - color: 'transparent', + backgroundColor: `${DefaultPalette.white}`, width: ACTUAL_WIDTH, height: `${height}px`, boxSizing: 'content-box', diff --git a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.types.ts b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.types.ts index cd141fcb904c8..029382c52a457 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.types.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.types.ts @@ -20,7 +20,7 @@ export interface IShimmerGapProps extends React.AllHTMLAttributes { componentRef?: (component: IShimmerGap | null) => void; /** - * Sets the height of the rectangle. + * Sets the height of the gap. * @default 16px */ height?: number; @@ -37,11 +37,6 @@ export interface IShimmerGapProps extends React.AllHTMLAttributes { */ widthInPixel?: number; - /** - * @default center - */ - verticalAlign?: string; - /** * Sets custom styling of the rectangle. */ @@ -55,7 +50,6 @@ export interface IShimmerGapProps extends React.AllHTMLAttributes { export interface IShimmerGapStyleProps { height?: number; - verticalAlign?: string; widthInPercentage?: number; widthInPixel?: number; borderAlignStyle?: IStyleSet; diff --git a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx index 2f708b8fac860..28fcf4f4ecf67 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx +++ b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx @@ -8,14 +8,10 @@ import { 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) { diff --git a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts index 2199c92478948..379b7224a3ad1 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts @@ -19,7 +19,6 @@ export function getStyles(props: IShimmerLineStyleProps): IShimmerLineStyles { root: [ 'ms-ShimmerLine-line', { - color: 'transparent', width: ACTUAL_WIDTH, height: `${height}px`, boxSizing: 'content-box', diff --git a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.types.ts b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.types.ts index 12306c1f21f45..0c7fa6f169420 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.types.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.types.ts @@ -37,11 +37,6 @@ export interface IShimmerLineProps extends React.AllHTMLAttributes */ widthInPixel?: number; - /** - * @default center - */ - verticalAlign?: string; - /** * Sets custom styling of the rectangle. */ @@ -55,7 +50,6 @@ export interface IShimmerLineProps extends React.AllHTMLAttributes export interface IShimmerLineStyleProps { height?: number; - verticalAlign?: string; widthInPercentage?: number; widthInPixel?: number; borderAlignStyle?: IStyleSet; From 6d1b5a09af0496f035c180c825ee8e472c390d6b Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Sat, 7 Apr 2018 19:40:47 -0700 Subject: [PATCH 21/36] Renames a prop for semantics. --- .../src/components/Shimmer/Shimmer.base.tsx | 18 ++--- .../ShimmerCircle/ShimmerCircle.base.tsx | 4 +- .../ShimmerCircle/ShimmerCircle.styles.ts | 4 +- .../ShimmerCircle/ShimmerCircle.types.ts | 4 +- .../Shimmer/ShimmerGap/ShimmerGap.base.tsx | 4 +- .../Shimmer/ShimmerGap/ShimmerGap.styles.ts | 4 +- .../Shimmer/ShimmerGap/ShimmerGap.types.ts | 6 +- .../Shimmer/ShimmerGap/ShimmerLine.types.ts | 66 +++++++++++++++++++ .../Shimmer/ShimmerLine/ShimmerLine.base.tsx | 4 +- .../Shimmer/ShimmerLine/ShimmerLine.styles.ts | 4 +- .../Shimmer/ShimmerLine/ShimmerLine.types.ts | 4 +- 11 files changed, 91 insertions(+), 31 deletions(-) create mode 100644 packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerLine.types.ts diff --git a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx index 31713720f1c74..7b16416a62f1e 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx +++ b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx @@ -18,6 +18,7 @@ import { IStyleSet } from '../../Styling'; import { ShimmerLine } from './ShimmerLine/ShimmerLine'; +import { ShimmerGap } from './ShimmerGap/ShimmerGap'; import { ShimmerCircle } from './ShimmerCircle/ShimmerCircle'; const LINE_DEFAULT_HEIGHT = 16; @@ -71,22 +72,15 @@ export function getRenderedElements(lineElements?: Array ); case ShimmerElementType.GAP: - const gapWidth = elem.widthInPercentage || elem.widthInPixel ? - elem.widthInPercentage ? elem.widthInPercentage + '%' : elem.widthInPixel + 'px' - : '5px'; return ( -
); case ShimmerElementType.LINE: @@ -94,7 +88,7 @@ export function getRenderedElements(lineElements?: Array ); } diff --git a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.base.tsx b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.base.tsx index 3c045acd15f1b..273d5d606f440 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.base.tsx +++ b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.base.tsx @@ -19,8 +19,8 @@ export class ShimmerCircleBase extends BaseComponent { } public render(): JSX.Element { - const { height, getStyles, borderAlignStyle } = this.props; - this._classNames = getClassNames(getStyles!, { height, borderAlignStyle }); + const { height, getStyles, borderStyle } = this.props; + this._classNames = getClassNames(getStyles!, { height, borderStyle }); return (
diff --git a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts index b2c9056b23fb0..a2a4d97e09e20 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts @@ -10,10 +10,10 @@ import { export function getStyles(props: IShimmerCircleStyleProps): IShimmerCircleStyles { const { height, - borderAlignStyle + borderStyle } = props; - const styles: IStyleSet = !!borderAlignStyle ? borderAlignStyle : {}; + const styles: IStyleSet = !!borderStyle ? borderStyle : {}; return { root: [ diff --git a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.types.ts b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.types.ts index 75b4dc9e80477..ce8294cc1fd27 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.types.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.types.ts @@ -28,7 +28,7 @@ export interface IShimmerCircleProps extends React.AllHTMLAttributes { } public render(): JSX.Element { - const { height, getStyles, widthInPercentage, widthInPixel, borderAlignStyle } = this.props; + const { height, getStyles, widthInPercentage, widthInPixel, borderStyle } = this.props; - this._classNames = getClassNames(getStyles!, { height, widthInPixel, widthInPercentage, borderAlignStyle }); + this._classNames = getClassNames(getStyles!, { height, widthInPixel, widthInPercentage, borderStyle }); return (
diff --git a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts index ea99b5bd484f4..1ab65355cd1af 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts @@ -9,10 +9,10 @@ export function getStyles(props: IShimmerGapStyleProps): IShimmerGapStyles { height, widthInPercentage, widthInPixel, - borderAlignStyle + borderStyle } = props; - const styles: IStyleSet = !!borderAlignStyle ? borderAlignStyle : {}; + const styles: IStyleSet = !!borderStyle ? borderStyle : {}; const ACTUAL_WIDTH = widthInPercentage ? widthInPercentage + '%' : widthInPixel ? widthInPixel + 'px' : '10px'; return { diff --git a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.types.ts b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.types.ts index 029382c52a457..325adaff895d0 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.types.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.types.ts @@ -38,9 +38,9 @@ export interface IShimmerGapProps extends React.AllHTMLAttributes { widthInPixel?: number; /** - * Sets custom styling of the rectangle. + * Sets custom styling of the gap. */ - borderAlignStyle?: IStyleSet; + borderStyle?: IStyleSet; /** * Call to provide customized styling that will layer on top of the variant rules. @@ -52,7 +52,7 @@ export interface IShimmerGapStyleProps { height?: number; widthInPercentage?: number; widthInPixel?: number; - borderAlignStyle?: IStyleSet; + borderStyle?: IStyleSet; } export interface IShimmerGapStyles { diff --git a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerLine.types.ts b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerLine.types.ts new file mode 100644 index 0000000000000..af51b456683a3 --- /dev/null +++ b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerLine.types.ts @@ -0,0 +1,66 @@ +import * as React from 'react'; +import { + IStyle, + IStyleSet +} from '../../../Styling'; +import { IStyleFunction } from '../../../Utilities'; + +export interface IShimmerGap { + +} + +/** + * ShimmerGap component props. + */ +export interface IShimmerGapProps extends React.AllHTMLAttributes { + /** + * Optional callback to access the IShimmerGap interface. Use this instead of ref for accessing + * the public methods and properties of the component. + */ + componentRef?: (component: IShimmerGap | null) => 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. + */ + borderStyle?: IStyleSet; + + /** + * Call to provide customized styling that will layer on top of the variant rules. + */ + getStyles?: IStyleFunction; +} + +export interface IShimmerGapStyleProps { + height?: number; + verticalAlign?: string; + widthInPercentage?: number; + widthInPixel?: number; + borderStyle?: IStyleSet; +} + +export interface IShimmerGapStyles { + root?: 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 index 28fcf4f4ecf67..65a15a793e3cd 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx +++ b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx @@ -19,9 +19,9 @@ export class ShimmerLineBase extends BaseComponent { } public render(): JSX.Element { - const { height, getStyles, widthInPercentage, widthInPixel, borderAlignStyle } = this.props; + const { height, getStyles, widthInPercentage, widthInPixel, borderStyle } = this.props; - this._classNames = getClassNames(getStyles!, { height, widthInPixel, widthInPercentage, borderAlignStyle }); + this._classNames = getClassNames(getStyles!, { height, widthInPixel, widthInPercentage, borderStyle }); return (
diff --git a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts index 379b7224a3ad1..9bffb32fc240c 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts @@ -9,10 +9,10 @@ export function getStyles(props: IShimmerLineStyleProps): IShimmerLineStyles { height, widthInPercentage, widthInPixel, - borderAlignStyle + borderStyle } = props; - const styles: IStyleSet = !!borderAlignStyle ? borderAlignStyle : {}; + const styles: IStyleSet = !!borderStyle ? borderStyle : {}; const ACTUAL_WIDTH = widthInPercentage ? widthInPercentage + '%' : widthInPixel ? widthInPixel + 'px' : '100%'; return { diff --git a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.types.ts b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.types.ts index 0c7fa6f169420..1d8c2262c19fd 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.types.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.types.ts @@ -40,7 +40,7 @@ export interface IShimmerLineProps extends React.AllHTMLAttributes /** * Sets custom styling of the rectangle. */ - borderAlignStyle?: IStyleSet; + borderStyle?: IStyleSet; /** * Call to provide customized styling that will layer on top of the variant rules. @@ -52,7 +52,7 @@ export interface IShimmerLineStyleProps { height?: number; widthInPercentage?: number; widthInPixel?: number; - borderAlignStyle?: IStyleSet; + borderStyle?: IStyleSet; } export interface IShimmerLineStyles { From d13db7412e10858f6b5613b760af83ef9ef0968a Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Sat, 7 Apr 2018 20:16:51 -0700 Subject: [PATCH 22/36] Duplicates a folder as base for ShimmerTile component. --- .../ShimmerCircle/ShimmerCircle.styles.ts | 2 +- .../Shimmer/ShimmerGap/ShimmerGap.styles.ts | 2 +- .../Shimmer/ShimmerLine/ShimmerLine.styles.ts | 2 +- .../Shimmer/ShimmerTile/ShimmerTile.base.tsx | 30 +++++++++++++++++++ .../Shimmer/ShimmerTile/ShimmerTile.styles.ts | 29 ++++++++++++++++++ .../Shimmer/ShimmerTile/ShimmerTile.tsx | 15 ++++++++++ .../ShimmerTile.types.ts} | 22 +++++--------- 7 files changed, 85 insertions(+), 17 deletions(-) create mode 100644 packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx create mode 100644 packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.styles.ts create mode 100644 packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.tsx rename packages/experiments/src/components/Shimmer/{ShimmerGap/ShimmerLine.types.ts => ShimmerTile/ShimmerTile.types.ts} (60%) diff --git a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts index a2a4d97e09e20..872d0586ba60f 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts @@ -17,7 +17,7 @@ export function getStyles(props: IShimmerCircleStyleProps): IShimmerCircleStyles return { root: [ - 'ms-ShimmerCircle-wrapper', + 'ms-ShimmerCircle-root', { width: `${height}px`, height: `${height}px`, diff --git a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts index 1ab65355cd1af..2cb14db58a6e2 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts @@ -17,7 +17,7 @@ export function getStyles(props: IShimmerGapStyleProps): IShimmerGapStyles { return { root: [ - 'ms-ShimmerGap-line', + 'ms-ShimmerGap-root', { backgroundColor: `${DefaultPalette.white}`, width: ACTUAL_WIDTH, diff --git a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts index 9bffb32fc240c..60015d7b943fd 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts @@ -17,7 +17,7 @@ export function getStyles(props: IShimmerLineStyleProps): IShimmerLineStyles { return { root: [ - 'ms-ShimmerLine-line', + 'ms-ShimmerLine-root', { width: ACTUAL_WIDTH, height: `${height}px`, diff --git a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx new file mode 100644 index 0000000000000..546022ad0b9ad --- /dev/null +++ b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx @@ -0,0 +1,30 @@ +import * as React from 'react'; +import { + BaseComponent, + classNamesFunction, +} from '../../../Utilities'; +import { + IShimmerTileProps, + IShimmerTileStyleProps, + IShimmerTileStyles +} from './ShimmerTile.types'; + +const getClassNames = classNamesFunction(); + +export class ShimmerTileBase extends BaseComponent { + private _classNames: {[key in keyof IShimmerTileStyles]: string}; + + constructor(props: IShimmerTileProps) { + super(props); + } + + public render(): JSX.Element { + const { height, getStyles, widthInPercentage, widthInPixel, borderStyle } = this.props; + + this._classNames = getClassNames(getStyles!, { height, widthInPixel, widthInPercentage, borderStyle }); + + return ( +
+ ); + } +} \ No newline at end of file diff --git a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.styles.ts new file mode 100644 index 0000000000000..fd082d42b4b01 --- /dev/null +++ b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.styles.ts @@ -0,0 +1,29 @@ +import { + IShimmerTileStyleProps, + IShimmerTileStyles +} from './ShimmerTile.types'; +import { IStyleSet } from 'office-ui-fabric-react/lib/Styling'; + +export function getStyles(props: IShimmerTileStyleProps): IShimmerTileStyles { + const { + height, + widthInPercentage, + widthInPixel, + borderStyle + } = props; + + const styles: IStyleSet = !!borderStyle ? borderStyle : {}; + const ACTUAL_WIDTH = widthInPercentage ? widthInPercentage + '%' : widthInPixel ? widthInPixel + 'px' : '100%'; + + return { + root: [ + 'ms-ShimmerTile-line', + { + width: ACTUAL_WIDTH, + height: `${height}px`, + boxSizing: 'content-box', + }, + styles + ] + }; +} diff --git a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.tsx b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.tsx new file mode 100644 index 0000000000000..4244fd0d72900 --- /dev/null +++ b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.tsx @@ -0,0 +1,15 @@ +import { + styled +} from '../../../Utilities'; +import { + IShimmerTileProps, + IShimmerTileStyleProps, + IShimmerTileStyles +} from './ShimmerTile.types'; +import { ShimmerTileBase } from './ShimmerTile.base'; +import { getStyles } from './ShimmerTile.styles'; + +export const ShimmerTile = styled( + ShimmerTileBase, + getStyles +); diff --git a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerLine.types.ts b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts similarity index 60% rename from packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerLine.types.ts rename to packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts index af51b456683a3..65eeaaba9b21a 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerGap/ShimmerLine.types.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts @@ -5,19 +5,19 @@ import { } from '../../../Styling'; import { IStyleFunction } from '../../../Utilities'; -export interface IShimmerGap { +export interface IShimmerTile { } /** - * ShimmerGap component props. + * ShimmerTile component props. */ -export interface IShimmerGapProps extends React.AllHTMLAttributes { +export interface IShimmerTileProps extends React.AllHTMLAttributes { /** - * Optional callback to access the IShimmerGap interface. Use this instead of ref for accessing + * Optional callback to access the IShimmerTile interface. Use this instead of ref for accessing * the public methods and properties of the component. */ - componentRef?: (component: IShimmerGap | null) => void; + componentRef?: (component: IShimmerTile | null) => void; /** * Sets the height of the rectangle. @@ -37,11 +37,6 @@ export interface IShimmerGapProps extends React.AllHTMLAttributes { */ widthInPixel?: number; - /** - * @default center - */ - verticalAlign?: string; - /** * Sets custom styling of the rectangle. */ @@ -50,17 +45,16 @@ export interface IShimmerGapProps extends React.AllHTMLAttributes { /** * Call to provide customized styling that will layer on top of the variant rules. */ - getStyles?: IStyleFunction; + getStyles?: IStyleFunction; } -export interface IShimmerGapStyleProps { +export interface IShimmerTileStyleProps { height?: number; - verticalAlign?: string; widthInPercentage?: number; widthInPixel?: number; borderStyle?: IStyleSet; } -export interface IShimmerGapStyles { +export interface IShimmerTileStyles { root?: IStyle; } \ No newline at end of file From 384780f7ad61974e094df8db94020dc58572279e Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Sat, 7 Apr 2018 21:01:03 -0700 Subject: [PATCH 23/36] Sets up props for ShimmerTile --- .../Shimmer/ShimmerTile/ShimmerTile.base.tsx | 4 +-- .../Shimmer/ShimmerTile/ShimmerTile.types.ts | 35 ++++++++++++------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx index 546022ad0b9ad..053c4e5d14296 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx +++ b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx @@ -19,9 +19,9 @@ export class ShimmerTileBase extends BaseComponent { } public render(): JSX.Element { - const { height, getStyles, widthInPercentage, widthInPixel, borderStyle } = this.props; + const { getStyles, } = this.props; - this._classNames = getClassNames(getStyles!, { height, widthInPixel, widthInPercentage, borderStyle }); + this._classNames = getClassNames(getStyles!, {}); return (
diff --git a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts index 65eeaaba9b21a..e071da7d637dd 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts @@ -2,8 +2,12 @@ import * as React from 'react'; import { IStyle, IStyleSet -} from '../../../Styling'; -import { IStyleFunction } from '../../../Utilities'; +} from 'office-ui-fabric-react/lib/Styling'; +import { + ISize, + IStyleFunction +} from 'office-ui-fabric-react/lib/Utilities'; +import { TileSize } from 'experiments/lib/Tile'; export interface IShimmerTile { @@ -20,27 +24,32 @@ export interface IShimmerTileProps extends React.AllHTMLAttributes componentRef?: (component: IShimmerTile | null) => void; /** - * Sets the height of the rectangle. - * @default 16px + * The intended dimensions for the Tile. */ - height?: number; + contentSize?: ISize; /** - * Sets width of the element in percentages. - * @default 100% + * The breakpoint size for the Tile. */ - widthInPercentage?: number; + tileSize?: TileSize; /** - * Sets width of the element in pixels. - * @default 50px + * Set to false if you choose not to display a name on the nameplate for the tile. + * @default true */ - widthInPixel?: number; + itemName?: boolean; /** - * Sets custom styling of the rectangle. + * Set to false if you choose not to display a activity on the nameplate for the tile. + * @default true */ - borderStyle?: IStyleSet; + itemActivity?: boolean; + + /** + * Set to false if you choose not to display a thumbnail of item type above the nameplate for the tile. + * @default true + */ + itemThumbnail?: boolean; /** * Call to provide customized styling that will layer on top of the variant rules. From 1398e9c0812d06a087e2f4164d4602852105955b Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Sat, 7 Apr 2018 21:06:17 -0700 Subject: [PATCH 24/36] Exports a const for reusability. --- packages/experiments/src/components/Tile/Tile.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/experiments/src/components/Tile/Tile.tsx b/packages/experiments/src/components/Tile/Tile.tsx index ce904749d0435..80c91a494ecfd 100644 --- a/packages/experiments/src/components/Tile/Tile.tsx +++ b/packages/experiments/src/components/Tile/Tile.tsx @@ -29,7 +29,7 @@ export interface ITileState { isModal?: boolean; } -const SIZES: { +export const SIZES: { [P in TileSize]: { nameplatePadding: number; nameplateNameHeight: number; From 19fc899a5e9c0724ac717163b40024292b282aa7 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Sun, 8 Apr 2018 12:12:17 -0700 Subject: [PATCH 25/36] Creates a new example for ShimmerTile. --- .../src/components/Shimmer/examples/Shimmer.TilesList.Example.tsx | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/experiments/src/components/Shimmer/examples/Shimmer.TilesList.Example.tsx diff --git a/packages/experiments/src/components/Shimmer/examples/Shimmer.TilesList.Example.tsx b/packages/experiments/src/components/Shimmer/examples/Shimmer.TilesList.Example.tsx new file mode 100644 index 0000000000000..e69de29bb2d1d From c6d2c780c0d3d8b68e99de5a969d029db3c380ee Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Sun, 8 Apr 2018 12:19:30 -0700 Subject: [PATCH 26/36] Removes a file. --- .../src/components/Shimmer/examples/Shimmer.TilesList.Example.tsx | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/experiments/src/components/Shimmer/examples/Shimmer.TilesList.Example.tsx diff --git a/packages/experiments/src/components/Shimmer/examples/Shimmer.TilesList.Example.tsx b/packages/experiments/src/components/Shimmer/examples/Shimmer.TilesList.Example.tsx deleted file mode 100644 index e69de29bb2d1d..0000000000000 From ebfbea3a6d2724dee8e2d9734beb5e8f30f3d9a7 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Sun, 8 Apr 2018 15:07:54 -0700 Subject: [PATCH 27/36] Adds initial elements for testing --- .../Shimmer/ShimmerTile/ShimmerTile.base.tsx | 116 +++++++++++++++++- .../Shimmer/ShimmerTile/ShimmerTile.styles.ts | 24 ++-- .../Shimmer/ShimmerTile/ShimmerTile.types.ts | 7 +- 3 files changed, 128 insertions(+), 19 deletions(-) diff --git a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx index 053c4e5d14296..1d97786c03463 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx +++ b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx @@ -8,6 +8,52 @@ import { IShimmerTileStyleProps, IShimmerTileStyles } from './ShimmerTile.types'; +import { SIZES, TileSize } from 'experiments/lib/Tile'; +import { ShimmerGap } from '../ShimmerGap/ShimmerGap'; +import { ShimmerLine } from '../ShimmerLine/ShimmerLine'; + +const enum ShimmerTileLayoutValues { + largeSquareWidth = 96, + largeSquareHeight = 96, + largeNameWidth = 144, + largeNameHeight = 7, + largeActivityWidth = 96, + largeActivityHeight = 7, + smallSquareWidth = 62, + smallSquareHeight = 61, + smallNameWidth = 106, + smallNameHeight = 5, + smallActivityWidth = 62, + smallActivityHeight = 5, +} + +const PLACEHOLDER_SIZES: { + [P in TileSize]: { + squareWidth: number; + squareHeight: number; + nameWidth: number; + nameHeight: number; + activityWidth: number; + activityHeight: number; + }; +} = { + small: { + squareWidth: ShimmerTileLayoutValues.smallSquareWidth, + squareHeight: ShimmerTileLayoutValues.smallSquareHeight, + nameWidth: ShimmerTileLayoutValues.smallNameWidth, + nameHeight: ShimmerTileLayoutValues.smallNameHeight, + activityWidth: ShimmerTileLayoutValues.smallActivityWidth, + activityHeight: ShimmerTileLayoutValues.smallActivityHeight + }, + large: { + squareWidth: ShimmerTileLayoutValues.largeSquareWidth, + squareHeight: ShimmerTileLayoutValues.largeSquareHeight, + nameWidth: ShimmerTileLayoutValues.largeNameWidth, + nameHeight: ShimmerTileLayoutValues.largeNameHeight, + activityWidth: ShimmerTileLayoutValues.largeActivityWidth, + activityHeight: ShimmerTileLayoutValues.largeActivityHeight + } + }; const getClassNames = classNamesFunction(); @@ -19,12 +65,78 @@ export class ShimmerTileBase extends BaseComponent { } public render(): JSX.Element { - const { getStyles, } = this.props; + const { + getStyles, + contentSize = { width: 176, height: 171 }, + itemActivity = true, + itemName = true, + itemThumbnail = true, + tileSize = 'large' + } = this.props; + + const { + nameplatePadding, + nameplateMargin, + nameplateActivityHeight, + nameplateNameHeight, + foregroundMargin + } = SIZES[tileSize]; + + const { + squareWidth, + squareHeight, + nameWidth, + nameHeight, + activityWidth, + activityHeight + } = PLACEHOLDER_SIZES[tileSize]; + + let nameplateHeight = 0; + + if (itemName || itemActivity) { + nameplateHeight += nameplatePadding * 2; + if (itemName) { + nameplateHeight += nameplateNameHeight; + } + if (itemActivity) { + nameplateHeight += nameplateActivityHeight + nameplateMargin; + } + } this._classNames = getClassNames(getStyles!, {}); return ( -
+
+ +
+ + { + itemThumbnail ? + : + + } + +
+
); } } \ No newline at end of file diff --git a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.styles.ts index fd082d42b4b01..5ac43c0ac581e 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.styles.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.styles.ts @@ -2,28 +2,26 @@ import { IShimmerTileStyleProps, IShimmerTileStyles } from './ShimmerTile.types'; -import { IStyleSet } from 'office-ui-fabric-react/lib/Styling'; export function getStyles(props: IShimmerTileStyleProps): IShimmerTileStyles { const { - height, - widthInPercentage, - widthInPixel, - borderStyle } = props; - const styles: IStyleSet = !!borderStyle ? borderStyle : {}; - const ACTUAL_WIDTH = widthInPercentage ? widthInPercentage + '%' : widthInPixel ? widthInPixel + 'px' : '100%'; - return { root: [ - 'ms-ShimmerTile-line', + 'ms-ShimmerTile-root', { - width: ACTUAL_WIDTH, - height: `${height}px`, - boxSizing: 'content-box', + width: '100%', + height: '100%', + display: 'flex', + flexDirection: 'column' }, - styles + ], + thumbnail: [ + 'ms-ShimmerTile-flexRow', + { + display: 'flex' + } ] }; } diff --git a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts index e071da7d637dd..25c0e629b2f67 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts @@ -30,6 +30,7 @@ export interface IShimmerTileProps extends React.AllHTMLAttributes /** * The breakpoint size for the Tile. + * @default large */ tileSize?: TileSize; @@ -58,12 +59,10 @@ export interface IShimmerTileProps extends React.AllHTMLAttributes } export interface IShimmerTileStyleProps { - height?: number; - widthInPercentage?: number; - widthInPixel?: number; - borderStyle?: IStyleSet; + contentSize?: ISize } export interface IShimmerTileStyles { root?: IStyle; + thumbnail?: IStyle; } \ No newline at end of file From ede7db7fb99b5de63ec346f8921a646f4c714c57 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Mon, 9 Apr 2018 13:12:02 -0700 Subject: [PATCH 28/36] Brings logic in TilesList and sets up an example. --- .../Shimmer/ShimmerTile/ShimmerTile.base.tsx | 122 +++++++++++++++--- .../Shimmer/ShimmerTile/ShimmerTile.styles.ts | 2 +- .../Shimmer/ShimmerTile/ShimmerTile.types.ts | 7 +- .../src/components/TilesList/TilesList.scss | 1 + .../src/components/TilesList/TilesList.tsx | 88 +++++++++---- .../components/TilesList/TilesList.types.ts | 8 ++ .../components/TilesList/TilesListPage.tsx | 26 ++-- .../TilesList/examples/ExampleHelpers.tsx | 32 ++++- .../examples/TilesList.Document.Example.tsx | 82 +++++++++++- .../TilesList/examples/TilesList.Example.scss | 9 ++ 10 files changed, 305 insertions(+), 72 deletions(-) diff --git a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx index 1d97786c03463..3632dba713941 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx +++ b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx @@ -10,7 +10,8 @@ import { } from './ShimmerTile.types'; import { SIZES, TileSize } from 'experiments/lib/Tile'; import { ShimmerGap } from '../ShimmerGap/ShimmerGap'; -import { ShimmerLine } from '../ShimmerLine/ShimmerLine'; +import { getRenderedElements } from '../Shimmer.base'; +import { ShimmerElementType as ElemType } from 'experiments/lib/Shimmer'; const enum ShimmerTileLayoutValues { largeSquareWidth = 96, @@ -78,8 +79,7 @@ export class ShimmerTileBase extends BaseComponent { nameplatePadding, nameplateMargin, nameplateActivityHeight, - nameplateNameHeight, - foregroundMargin + nameplateNameHeight } = SIZES[tileSize]; const { @@ -114,28 +114,108 @@ export class ShimmerTileBase extends BaseComponent { height={ contentSize.height - squareHeight - nameplateHeight } />
- { - itemThumbnail ? - : - + getRenderedElements( + [ + { + type: ElemType.GAP, + widthInPixel: (contentSize.width - squareWidth) / 2, + height: squareHeight + }, + itemThumbnail ? + { + type: ElemType.LINE, + widthInPixel: squareWidth, + height: squareHeight + } : + { + type: ElemType.GAP, + widthInPixel: squareWidth, + height: squareHeight + }, + { + type: ElemType.GAP, + widthInPixel: (contentSize.width - squareWidth) / 2, + height: squareHeight + } + ], + squareHeight + ) } -
+ { + itemActivity || itemName ? +
+ + { + itemName ? +
+ { + getRenderedElements( + [ + { + type: ElemType.GAP, + widthInPixel: (contentSize.width - nameWidth) / 2, + height: nameplateNameHeight + }, + { + type: ElemType.LINE, + widthInPixel: nameWidth, + height: nameHeight + }, + { + type: ElemType.GAP, + widthInPixel: (contentSize.width - nameWidth) / 2, + height: nameplateNameHeight + } + ], + nameplateNameHeight + ) + } +
: null + } + { + itemActivity ? +
+ { + getRenderedElements( + [ + { + type: ElemType.GAP, + widthInPixel: (contentSize.width - activityWidth) / 2, + height: nameplateActivityHeight + }, + { + type: ElemType.LINE, + widthInPixel: activityWidth, + height: activityHeight + }, + { + type: ElemType.GAP, + widthInPixel: (contentSize.width - activityWidth) / 2, + height: nameplateActivityHeight + } + ], + nameplateActivityHeight + ) + } +
: null + } + +
: null + }
); } diff --git a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.styles.ts b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.styles.ts index 5ac43c0ac581e..5eb5def859bc8 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.styles.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.styles.ts @@ -17,7 +17,7 @@ export function getStyles(props: IShimmerTileStyleProps): IShimmerTileStyles { flexDirection: 'column' }, ], - thumbnail: [ + flexDiv: [ 'ms-ShimmerTile-flexRow', { display: 'flex' diff --git a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts index 25c0e629b2f67..111897b785bba 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts +++ b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.types.ts @@ -1,7 +1,6 @@ import * as React from 'react'; import { - IStyle, - IStyleSet + IStyle } from 'office-ui-fabric-react/lib/Styling'; import { ISize, @@ -59,10 +58,10 @@ export interface IShimmerTileProps extends React.AllHTMLAttributes } export interface IShimmerTileStyleProps { - contentSize?: ISize + contentSize?: ISize; } export interface IShimmerTileStyles { root?: IStyle; - thumbnail?: IStyle; + flexDiv?: IStyle; } \ No newline at end of file diff --git a/packages/experiments/src/components/TilesList/TilesList.scss b/packages/experiments/src/components/TilesList/TilesList.scss index a20f279914f55..dc4afa3fca990 100644 --- a/packages/experiments/src/components/TilesList/TilesList.scss +++ b/packages/experiments/src/components/TilesList/TilesList.scss @@ -4,6 +4,7 @@ .listCell { display: block; margin: 0; + border-color: $ms-color-white; } .listPage { diff --git a/packages/experiments/src/components/TilesList/TilesList.tsx b/packages/experiments/src/components/TilesList/TilesList.tsx index 97aadcceac4ff..2d97d161ac18a 100644 --- a/packages/experiments/src/components/TilesList/TilesList.tsx +++ b/packages/experiments/src/components/TilesList/TilesList.tsx @@ -5,6 +5,7 @@ import { List, IPageProps } from 'office-ui-fabric-react/lib/List'; import { FocusZone, FocusZoneDirection } from 'office-ui-fabric-react/lib/FocusZone'; import { css, IRenderFunction, IRectangle } from 'office-ui-fabric-react/lib/Utilities'; import * as TilesListStylesModule from './TilesList.scss'; +import { Shimmer } from '../Shimmer/Shimmer'; // tslint:disable-next-line:no-any const TilesListStyles: any = TilesListStylesModule; @@ -14,6 +15,8 @@ const CELLS_PER_PAGE = 100; const MIN_ASPECT_RATIO = 0.5; const MAX_ASPECT_RATIO = 3; +const ROW_OF_PLACEHOLDER_CELLS = 3; + export interface ITilesListState { cells: ITileCell[]; } @@ -26,6 +29,7 @@ export interface ITileGrid { marginTop: number; marginBottom: number; key: string; + isPlaceholder?: boolean; } export interface ITileCell { @@ -33,6 +37,7 @@ export interface ITileCell { content: TItem; aspectRatio: number; grid: ITileGrid; + isPlaceholder?: boolean; onRender(content: TItem, finalSize: { width: number; height: number; }): React.ReactNode | React.ReactNode[]; } @@ -201,10 +206,14 @@ export class TilesList extends React.Component, IT let currentRow: IRowData | undefined; + let shimmerWrapperWidth = 0; + for (let i = 0; i < endIndex;) { // For each cell at the start of a grid. const grid = cells[i].grid; + const isPlaceholder = grid.isPlaceholder; + const renderedCells: React.ReactNode[] = []; const width = data.pageWidths[page.startIndex + i]; @@ -257,21 +266,36 @@ export class TilesList extends React.Component, IT } } - renderedCells.push( -
- { this._onRenderCell(cell, finalSize) } -
- ); + const renderedCell = (offset?: number): JSX.Element => { + return ( +
+ { this._onRenderCell(cell, finalSize) } +
+ ); + }; + + if (cell.isPlaceholder && grid.mode !== TilesGridMode.none) { + let cellsPerRow = Math.floor(width / (grid.spacing + finalSize.width)); + let totalPlaceholderItems = cellsPerRow * ROW_OF_PLACEHOLDER_CELLS; + shimmerWrapperWidth = (cellsPerRow * finalSize.width) + (grid.spacing * (cellsPerRow - 1)); + for (let j = 0; j < totalPlaceholderItems; j++) { + renderedCells.push(renderedCell(j)); + } + } else { + renderedCells.push(renderedCell()); + } } const isOpenStart = previousCell && previousCell.grid === grid; @@ -279,7 +303,7 @@ export class TilesList extends React.Component, IT const margin = grid.spacing / 2; - grids.push( + const finalGrid: JSX.Element = (
extends React.Component, IT { renderedCells }
); + + grids.push( + isPlaceholder ? + ( + + { finalGrid } + + ) : + finalGrid + ); } return ( @@ -534,7 +572,9 @@ export class TilesList extends React.Component, IT return { flex: isFill ? `${itemWidthOverHeight} ${itemWidthOverHeight} ${width}px` : `0 0 ${width}px`, maxWidth: `${maxWidth}px`, - margin: `${margin}px` + margin: !item.isPlaceholder ? `${margin}px` : 0, + borderStyle: item.isPlaceholder ? 'solid' : 'none', + borderWidth: item.isPlaceholder ? `${margin}px` : 0 }; } @@ -564,8 +604,9 @@ export class TilesList extends React.Component, IT mode: item.mode, key: `grid-${item.key}`, maxScaleFactor: maxScaleFactor, - marginTop: marginTop, - marginBottom: marginBottom + marginTop: item.isPlaceholder ? 0 : marginTop, + marginBottom: item.isPlaceholder ? 0 : marginBottom, + isPlaceholder: item.isPlaceholder }; for (const gridItem of item.items) { @@ -584,7 +625,8 @@ export class TilesList extends React.Component, IT content: gridItem.content, onRender: gridItem.onRender, grid: grid, - key: gridItem.key + key: gridItem.key, + isPlaceholder: gridItem.isPlaceholder }); } } else { @@ -600,9 +642,11 @@ export class TilesList extends React.Component, IT key: `grid-header-${item.key}`, maxScaleFactor: 1, marginBottom: 0, - marginTop: 0 + marginTop: 0, + isPlaceholder: item.isPlaceholder }, - key: `header-${item.key}` + key: `header-${item.key}`, + isPlaceholder: item.isPlaceholder }); } } diff --git a/packages/experiments/src/components/TilesList/TilesList.types.ts b/packages/experiments/src/components/TilesList/TilesList.types.ts index d61e6d3ebcb0f..8d98a021d4b7c 100644 --- a/packages/experiments/src/components/TilesList/TilesList.types.ts +++ b/packages/experiments/src/components/TilesList/TilesList.types.ts @@ -19,6 +19,10 @@ export interface ITilesGridItem { * If not provided, this is assumed to be a square equivalent to the current row height. */ desiredSize?: { width: number; height: number; }; + /** + * Set to true if the item is intended to be a placeholder + */ + isPlaceholder?: boolean; /** * Invoked to render the virtual DOM for the item. * This content will be rendered inside the cell allocated for the item. @@ -88,6 +92,10 @@ export interface ITilesGridSegment { * The maximum aspect ratio for an item in the grid. */ maxAspectRatio?: number; + /** + * Set to true if the item is intended to be a placeholder + */ + isPlaceholder?: boolean; } export { ISize as ITileSize }; diff --git a/packages/experiments/src/components/TilesList/TilesListPage.tsx b/packages/experiments/src/components/TilesList/TilesListPage.tsx index 4f1c39c13df01..7a56d537ff6b9 100644 --- a/packages/experiments/src/components/TilesList/TilesListPage.tsx +++ b/packages/experiments/src/components/TilesList/TilesListPage.tsx @@ -8,21 +8,21 @@ import { } from '@uifabric/example-app-base'; /* tslint:disable:max-line-length */ -import { TilesListBasicExample } from './examples/TilesList.Basic.Example'; -const TilesListBasicExampleCode = require( - '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Basic.Example.tsx' -) as string; +// import { TilesListBasicExample } from './examples/TilesList.Basic.Example'; +// const TilesListBasicExampleCode = require( +// '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Basic.Example.tsx' +// ) as string; import { TilesListDocumentExample } from './examples/TilesList.Document.Example'; const TilesListDocumentExampleCode = require( '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx' ) as string; -import { TilesListMediaExample } from './examples/TilesList.Media.Example'; +// import { TilesListMediaExample } from './examples/TilesList.Media.Example'; -const TilesListMediaExampleCode = require( - '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Media.Example.tsx' -) as string; +// const TilesListMediaExampleCode = require( +// '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Media.Example.tsx' +// ) as string; export class TilesListPage extends React.Component { public render(): JSX.Element { @@ -32,15 +32,15 @@ export class TilesListPage extends React.Component componentName='TilesListExample' exampleCards={
- + {/* - - + */} + - + {/* - + */}
} propertiesTables={ diff --git a/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx b/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx index c6267a4d0974d..7ecf9572dbda6 100644 --- a/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx +++ b/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx @@ -79,11 +79,13 @@ export function createGroup(items: IExampleItem[], type: 'document' | 'media', i export function getTileCells(groups: IExampleGroup[], { onRenderCell, onRenderHeader, - size = 'large' + size = 'large', + shimmerMode = false }: { onRenderHeader: (item: IExampleItem) => JSX.Element; onRenderCell: (item: IExampleItem, finalSize?: ITileSize) => JSX.Element; - size?: 'large' | 'small' + size?: 'large' | 'small'; + shimmerMode?: boolean; }): (ITilesGridSegment | ITilesGridItem)[] { const items: (ITilesGridSegment | ITilesGridItem)[] = []; @@ -96,7 +98,8 @@ export function getTileCells(groups: IExampleGroup[], { name: group.name, index: group.index }, - onRender: onRenderHeader + onRender: onRenderHeader, + isPlaceholder: shimmerMode }; items.push(header); @@ -113,20 +116,37 @@ export function getTileCells(groups: IExampleGroup[], { width: 171 * item.aspectRatio, height: 171 }, - onRender: onRenderCell + onRender: onRenderCell, + isPlaceholder: shimmerMode }; }), spacing: 8, - marginBottom: 40, + marginBottom: shimmerMode ? 0 : 40, minRowHeight: 171, mode: group.type === 'document' ? size === 'small' ? TilesGridMode.fillHorizontal : TilesGridMode.stack : TilesGridMode.fill, - key: group.key + key: group.key, + isPlaceholder: shimmerMode }); } return items; } + +export function createShimmerGroups(type: 'document' | 'media', index: number): IExampleGroup[] { + return [{ + items: [{ + key: `shimmerItem-${index}`, + name: lorem(4), + index: index, + aspectRatio: 1 + }], + index: index, + name: lorem(4), + key: `shimmerGroup-${index}`, + type: type + }]; +} diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx index db7ccc2fc8287..4da8c7784f374 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx @@ -5,12 +5,27 @@ import { ITilesGridItem, ITilesGridSegment } from '../../TilesList'; -import { Tile } from '../../../Tile'; +import { + Tile +} from '../../../Tile'; import { Toggle } from 'office-ui-fabric-react/lib/Toggle'; import { Selection, SelectionZone } from 'office-ui-fabric-react/lib/Selection'; import { MarqueeSelection } from 'office-ui-fabric-react/lib/MarqueeSelection'; import { AnimationClassNames } from 'office-ui-fabric-react/lib/Styling'; -import { IExampleGroup, IExampleItem, createGroup, createDocumentItems, getTileCells } from './ExampleHelpers'; +import { + IExampleGroup, + IExampleItem, + createGroup, + createDocumentItems, + getTileCells, + createShimmerGroups +} from './ExampleHelpers'; +import { ISize } from 'experiments/lib/Utilities'; +import { ShimmerTile } from '../../Shimmer/ShimmerTile/ShimmerTile'; +import * as TilesListExampleStylesModule from './TilesList.Example.scss'; + +// tslint:disable-next-line:no-any +const TilesListExampleStyles = TilesListExampleStylesModule as any; function createGroups(): IExampleGroup[] { let offset = 0; @@ -30,6 +45,8 @@ function createGroups(): IExampleGroup[] { const GROUPS = createGroups(); +const SHIMMER_GROUPS = createShimmerGroups('document', 0); + const ITEMS = ([] as IExampleItem[]).concat(...GROUPS.map((group: { items: IExampleItem[]; }) => group.items)); declare class TilesListClass extends TilesList { } @@ -38,6 +55,7 @@ const TilesListType: typeof TilesListClass = TilesList; export interface ITilesListDocumentExampleState { isModalSelection: boolean; + isDataLoaded: boolean; cells: (ITilesGridItem | ITilesGridSegment)[]; } @@ -56,9 +74,11 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu this.state = { isModalSelection: this._selection.isModal(), - cells: getTileCells(GROUPS, { - onRenderCell: this._onRenderDocumentCell, - onRenderHeader: this._onRenderHeader + isDataLoaded: false, + cells: getTileCells(SHIMMER_GROUPS, { + onRenderCell: this._onRenderShimmerCell, + onRenderHeader: this._onRenderShimmerHeader, + shimmerMode: true }) }; } @@ -74,6 +94,13 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu onText='Modal' offText='Normal' /> + { + const { isDataLoaded } = this.state; + let { cells } = this.state; + + if (cells.length && !cells[0].isPlaceholder) { + cells = getTileCells(SHIMMER_GROUPS, { + onRenderCell: this._onRenderShimmerCell, + onRenderHeader: this._onRenderShimmerHeader, + shimmerMode: true + }); + } else { + cells = getTileCells(GROUPS, { + onRenderCell: this._onRenderDocumentCell, + onRenderHeader: this._onRenderHeader + }); + } + + this.setState({ + isDataLoaded: !isDataLoaded, + cells: cells + }); + } + private _onSelectionChange = (): void => { this.setState({ isModalSelection: this._selection.isModal() @@ -139,6 +189,18 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu ); } + private _onRenderShimmerCell(item: IExampleItem, finalSize: ISize): JSX.Element { + return ( + + ); + } + private _onRenderHeader = (item: IExampleItem): JSX.Element => { return (
@@ -146,4 +208,14 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu
); } + + private _onRenderShimmerHeader = (item: IExampleItem): JSX.Element => { + return ( +
+

{ item.name }

+
+ ); + } } diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Example.scss b/packages/experiments/src/components/TilesList/examples/TilesList.Example.scss index 221bbc222dc32..50970b29c2221 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Example.scss +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Example.scss @@ -2,3 +2,12 @@ .tileImage { display: block; } + +.shimmerHeader { + width: 100%; + height: 100%; + box-sizing: border-box; + border-style: solid; + border-color: white; + border-width: calc(100% - 10px) calc(100% - 50%) calc(100% - 10px) 10px; +} From 0f7825b1b2fde8402adaab3aaf73b427ead42973 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Mon, 9 Apr 2018 15:15:17 -0700 Subject: [PATCH 29/36] Updates some styling in the TilesList example. --- .../src/components/TilesList/TilesList.tsx | 5 +-- .../examples/TilesList.Document.Example.tsx | 36 ++++++++++++++----- .../TilesList/examples/TilesList.Example.scss | 9 ----- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/packages/experiments/src/components/TilesList/TilesList.tsx b/packages/experiments/src/components/TilesList/TilesList.tsx index 2d97d161ac18a..72e7a7d3b5bfa 100644 --- a/packages/experiments/src/components/TilesList/TilesList.tsx +++ b/packages/experiments/src/components/TilesList/TilesList.tsx @@ -266,10 +266,10 @@ export class TilesList extends React.Component, IT } } - const renderedCell = (offset?: number): JSX.Element => { + const renderedCell = (keyOffset?: number): JSX.Element => { return (
extends React.Component, IT renderedCells.push(renderedCell(j)); } } else { + shimmerWrapperWidth = finalSize.width / 3; renderedCells.push(renderedCell()); } } diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx index 4da8c7784f374..ad697ca8179d6 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx @@ -22,10 +22,13 @@ import { } from './ExampleHelpers'; import { ISize } from 'experiments/lib/Utilities'; import { ShimmerTile } from '../../Shimmer/ShimmerTile/ShimmerTile'; -import * as TilesListExampleStylesModule from './TilesList.Example.scss'; +import { getRenderedElements } from '../../Shimmer/Shimmer.base'; +import { + ShimmerElementType as ElemType, +} from 'experiments/lib/Shimmer'; -// tslint:disable-next-line:no-any -const TilesListExampleStyles = TilesListExampleStylesModule as any; +const HEADER_VERTICAL_PADDING = 13; +const HEADER_FONT_SIZE = 18; function createGroups(): IExampleGroup[] { let offset = 0; @@ -203,18 +206,33 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu private _onRenderHeader = (item: IExampleItem): JSX.Element => { return ( -
-

{ item.name }

+
+ { item.name }
); } private _onRenderShimmerHeader = (item: IExampleItem): JSX.Element => { return ( -
-

{ item.name }

+
+ { + getRenderedElements( + [ + { type: ElemType.LINE, height: HEADER_FONT_SIZE, widthInPercentage: 100 }, + ], + HEADER_VERTICAL_PADDING * 2 + HEADER_FONT_SIZE + ) + }
); } diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Example.scss b/packages/experiments/src/components/TilesList/examples/TilesList.Example.scss index 50970b29c2221..221bbc222dc32 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Example.scss +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Example.scss @@ -2,12 +2,3 @@ .tileImage { display: block; } - -.shimmerHeader { - width: 100%; - height: 100%; - box-sizing: border-box; - border-style: solid; - border-color: white; - border-width: calc(100% - 10px) calc(100% - 50%) calc(100% - 10px) 10px; -} From 7142ef305c7917538bf454e88e6e7d5a3bfeb051 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Mon, 9 Apr 2018 15:25:35 -0700 Subject: [PATCH 30/36] Change name of a constant for semantics. --- .../src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx | 4 ++-- packages/experiments/src/components/Tile/Tile.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx index 3632dba713941..ec32842026ae1 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx +++ b/packages/experiments/src/components/Shimmer/ShimmerTile/ShimmerTile.base.tsx @@ -8,7 +8,7 @@ import { IShimmerTileStyleProps, IShimmerTileStyles } from './ShimmerTile.types'; -import { SIZES, TileSize } from 'experiments/lib/Tile'; +import { TileLayoutSizes, TileSize } from 'experiments/lib/Tile'; import { ShimmerGap } from '../ShimmerGap/ShimmerGap'; import { getRenderedElements } from '../Shimmer.base'; import { ShimmerElementType as ElemType } from 'experiments/lib/Shimmer'; @@ -80,7 +80,7 @@ export class ShimmerTileBase extends BaseComponent { nameplateMargin, nameplateActivityHeight, nameplateNameHeight - } = SIZES[tileSize]; + } = TileLayoutSizes[tileSize]; const { squareWidth, diff --git a/packages/experiments/src/components/Tile/Tile.tsx b/packages/experiments/src/components/Tile/Tile.tsx index 80c91a494ecfd..6f86d42cc5f77 100644 --- a/packages/experiments/src/components/Tile/Tile.tsx +++ b/packages/experiments/src/components/Tile/Tile.tsx @@ -29,7 +29,7 @@ export interface ITileState { isModal?: boolean; } -export const SIZES: { +export const TileLayoutSizes: { [P in TileSize]: { nameplatePadding: number; nameplateNameHeight: number; @@ -401,7 +401,7 @@ export function getTileLayout(tileElement: JSX.Element): ITileLayout { nameplateActivityHeight, nameplateNameHeight, foregroundMargin - } = SIZES[tileSize]; + } = TileLayoutSizes[tileSize]; let nameplateHeight = 0; From 5942fa5dae3273a5a883cdb1e837b6609e83564b Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Mon, 9 Apr 2018 23:13:38 -0700 Subject: [PATCH 31/36] Sets a checkbox to toggle sizes. Fixes Firefox border rounding decimal value of pixels. --- .../src/components/Shimmer/Shimmer.base.tsx | 4 +- .../components/TilesList/TilesListPage.tsx | 60 ++++++++++++---- .../TilesList/examples/ExampleHelpers.tsx | 13 ++-- .../examples/TilesList.Document.Example.tsx | 68 +++++++++++++++---- 4 files changed, 107 insertions(+), 38 deletions(-) diff --git a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx index f66dce6871d8e..1e7836fa8f06b 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx +++ b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx @@ -109,8 +109,8 @@ export function getBorderStyles(elem: ICircle | IGap | ILine, rowHeight?: number if (!elem.verticalAlign || elem.verticalAlign === ShimmerElementVerticalAlign.CENTER) { borderStyle = { - borderBottom: `${dif ? dif / 2 : 0}px solid ${DefaultPalette.white}`, - borderTop: `${dif ? dif / 2 : 0}px solid ${DefaultPalette.white}` + borderBottom: `${dif ? Math.floor(dif / 2) : 0}px solid ${DefaultPalette.white}`, + borderTop: `${dif ? Math.ceil(dif / 2) : 0}px solid ${DefaultPalette.white}` }; } else if (elem.verticalAlign && elem.verticalAlign === ShimmerElementVerticalAlign.TOP) { borderStyle = { diff --git a/packages/experiments/src/components/TilesList/TilesListPage.tsx b/packages/experiments/src/components/TilesList/TilesListPage.tsx index 7a56d537ff6b9..919bde9b67efe 100644 --- a/packages/experiments/src/components/TilesList/TilesListPage.tsx +++ b/packages/experiments/src/components/TilesList/TilesListPage.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import { Link } from 'office-ui-fabric-react/lib/Link'; +import { Checkbox } from 'office-ui-fabric-react/lib/Checkbox'; import { ExampleCard, IComponentDemoPageProps, @@ -8,39 +9,62 @@ import { } from '@uifabric/example-app-base'; /* tslint:disable:max-line-length */ -// import { TilesListBasicExample } from './examples/TilesList.Basic.Example'; -// const TilesListBasicExampleCode = require( -// '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Basic.Example.tsx' -// ) as string; +import { TilesListBasicExample } from './examples/TilesList.Basic.Example'; +const TilesListBasicExampleCode = require( + '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Basic.Example.tsx' +) as string; import { TilesListDocumentExample } from './examples/TilesList.Document.Example'; const TilesListDocumentExampleCode = require( '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx' ) as string; -// import { TilesListMediaExample } from './examples/TilesList.Media.Example'; +import { TilesListMediaExample } from './examples/TilesList.Media.Example'; + +const TilesListMediaExampleCode = require( + '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Media.Example.tsx' +) as string; + +export interface ITilesListPageState { + size: 'small' | 'large'; +} + +export class TilesListPage extends React.Component { + constructor(props: {}) { + super(props); -// const TilesListMediaExampleCode = require( -// '!raw-loader!experiments/src/components/TilesList/examples/TilesList.Media.Example.tsx' -// ) as string; + this.state = { + size: 'large' + }; + } -export class TilesListPage extends React.Component { public render(): JSX.Element { + const { size } = this.state; + return ( - {/* + - */} - - - {/* + + + + + - */} +
} propertiesTables={ @@ -83,4 +107,10 @@ export class TilesListPage extends React.Component /> ); } + + private _onIsLargeChanged = (event: React.FormEvent, checked: boolean): void => { + this.setState({ + size: checked ? 'large' : 'small' + }); + } } diff --git a/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx b/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx index 7ecf9572dbda6..29d7b4076ece3 100644 --- a/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx +++ b/packages/experiments/src/components/TilesList/examples/ExampleHelpers.tsx @@ -88,6 +88,7 @@ export function getTileCells(groups: IExampleGroup[], { shimmerMode?: boolean; }): (ITilesGridSegment | ITilesGridItem)[] { const items: (ITilesGridSegment | ITilesGridItem)[] = []; + const isLargeSize: boolean = size === 'large' ? true : false; for (const group of groups) { const header: ITilesGridItem = { @@ -110,19 +111,19 @@ export function getTileCells(groups: IExampleGroup[], { key: item.key, content: item, desiredSize: group.type === 'document' ? { - width: 176, - height: 171 + width: isLargeSize ? 176 : 138, + height: isLargeSize ? 171 : 135 } : { - width: 171 * item.aspectRatio, - height: 171 + width: isLargeSize ? 171 * item.aspectRatio : 135 * item.aspectRatio, + height: isLargeSize ? 171 : 135 }, onRender: onRenderCell, isPlaceholder: shimmerMode }; }), - spacing: 8, + spacing: isLargeSize ? 8 : 12, marginBottom: shimmerMode ? 0 : 40, - minRowHeight: 171, + minRowHeight: isLargeSize ? 171 : 135, mode: group.type === 'document' ? size === 'small' ? TilesGridMode.fillHorizontal : diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx index ad697ca8179d6..9851c1c915905 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx @@ -62,10 +62,14 @@ export interface ITilesListDocumentExampleState { cells: (ITilesGridItem | ITilesGridSegment)[]; } -export class TilesListDocumentExample extends React.Component<{}, ITilesListDocumentExampleState> { +export interface ITilesListDocumentExampleProps { + tileSize: 'large' | 'small'; +} + +export class TilesListDocumentExample extends React.Component { private _selection: Selection; - constructor(props: {}) { + constructor(props: ITilesListDocumentExampleProps) { super(props); this._selection = new Selection({ @@ -81,11 +85,36 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu cells: getTileCells(SHIMMER_GROUPS, { onRenderCell: this._onRenderShimmerCell, onRenderHeader: this._onRenderShimmerHeader, + size: props.tileSize, shimmerMode: true }) }; } + public componentDidUpdate(previousProps: ITilesListDocumentExampleProps) { + const { isDataLoaded } = this.state; + if (this.props.tileSize !== previousProps.tileSize) { + if (!isDataLoaded) { + this.setState({ + cells: getTileCells(SHIMMER_GROUPS, { + onRenderCell: this._onRenderShimmerCell, + onRenderHeader: this._onRenderShimmerHeader, + size: this.props.tileSize, + shimmerMode: true + }) + }); + } else { + this.setState({ + cells: getTileCells(GROUPS, { + onRenderCell: this._onRenderDocumentCell, + onRenderHeader: this._onRenderHeader, + size: this.props.tileSize + }) + }); + } + } + } + public render(): JSX.Element { return ( // tslint:disable-next-line:jsx-ban-props @@ -98,7 +127,7 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu offText='Normal' /> { + const { tileSize } = this.props; const { isDataLoaded } = this.state; let { cells } = this.state; @@ -132,18 +162,20 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu cells = getTileCells(SHIMMER_GROUPS, { onRenderCell: this._onRenderShimmerCell, onRenderHeader: this._onRenderShimmerHeader, - shimmerMode: true + shimmerMode: true, + size: tileSize }); } else { cells = getTileCells(GROUPS, { onRenderCell: this._onRenderDocumentCell, - onRenderHeader: this._onRenderHeader + onRenderHeader: this._onRenderHeader, + size: tileSize }); } this.setState({ isDataLoaded: !isDataLoaded, - cells: cells + cells: cells, }); } @@ -161,6 +193,9 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu } private _onRenderDocumentCell = (item: IExampleItem): JSX.Element => { + const { tileSize } = this.props; + let imgSize = tileSize === 'large' ? 64 : 48; + return ( @@ -188,18 +223,21 @@ export class TilesListDocumentExample extends React.Component<{}, ITilesListDocu showForegroundFrame={ true } itemName={ item.name } itemActivity={ item.key } + tileSize={ tileSize } /> ); } - private _onRenderShimmerCell(item: IExampleItem, finalSize: ISize): JSX.Element { + private _onRenderShimmerCell = (item: IExampleItem, finalSize: ISize): JSX.Element => { + const { tileSize } = this.props; + return ( ); } From 971a6ecb6d16559128f1ab268f50e2a0202793ab Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Mon, 9 Apr 2018 23:31:45 -0700 Subject: [PATCH 32/36] Fixes build errors. --- .../TilesList/examples/TilesList.Document.Example.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx index 9851c1c915905..bb457ddae2d39 100644 --- a/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx +++ b/packages/experiments/src/components/TilesList/examples/TilesList.Document.Example.tsx @@ -91,7 +91,7 @@ export class TilesListDocumentExample extends React.Component Date: Mon, 9 Apr 2018 23:49:01 -0700 Subject: [PATCH 33/36] Rush change log. --- .../v-vibr-PlaceholderTile_2018-04-10-06-48.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@uifabric/experiments/v-vibr-PlaceholderTile_2018-04-10-06-48.json diff --git a/common/changes/@uifabric/experiments/v-vibr-PlaceholderTile_2018-04-10-06-48.json b/common/changes/@uifabric/experiments/v-vibr-PlaceholderTile_2018-04-10-06-48.json new file mode 100644 index 0000000000000..a9a6c24c8de69 --- /dev/null +++ b/common/changes/@uifabric/experiments/v-vibr-PlaceholderTile_2018-04-10-06-48.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@uifabric/experiments", + "comment": "Refactoring Shimmer and adding ShimmerTile + Implements Shimmer in TilesList.", + "type": "minor" + } + ], + "packageName": "@uifabric/experiments", + "email": "v-vibr@microsoft.com" +} \ No newline at end of file From 89d64c70cf2931e29d07226f72687f892b2b09c8 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Tue, 10 Apr 2018 15:57:30 -0700 Subject: [PATCH 34/36] Changes type 'JSX.Element[] | JSX.Elelment' to React.ReactNode. --- .../experiments/src/components/Shimmer/Shimmer.base.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx index 1e7836fa8f06b..af50bd05af2d1 100644 --- a/packages/experiments/src/components/Shimmer/Shimmer.base.tsx +++ b/packages/experiments/src/components/Shimmer/Shimmer.base.tsx @@ -32,7 +32,7 @@ export class ShimmerBase extends BaseComponent { isDataLoaded: false, isBaseStyle: false }; - private _classNames: {[key in keyof IShimmerStyles]: string}; + private _classNames: { [key in keyof IShimmerStyles]: string }; constructor(props: IShimmerProps) { super(props); } @@ -44,7 +44,7 @@ export class ShimmerBase extends BaseComponent { this._classNames = getClassNames(getStyles!, { width, rowHeight, isDataLoaded, isBaseStyle }); - const renderedElements: JSX.Element[] | JSX.Element = getRenderedElements(lineElements, rowHeight); + const renderedElements: React.ReactNode = getRenderedElements(lineElements, rowHeight); return (
@@ -62,8 +62,8 @@ export class ShimmerBase extends BaseComponent { } } -export function getRenderedElements(lineElements?: Array, rowHeight?: number): JSX.Element[] | JSX.Element { - const renderedElements: JSX.Element[] | JSX.Element = lineElements ? +export function getRenderedElements(lineElements?: Array, rowHeight?: number): React.ReactNode { + const renderedElements: React.ReactNode = lineElements ? lineElements.map((elem: ICircle | ILine | IGap, index: number): JSX.Element => { switch (elem.type) { case ShimmerElementType.CIRCLE: From 5a84fed96392571ddf2a6e79a2b5c2f728be5337 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Tue, 10 Apr 2018 22:31:05 -0700 Subject: [PATCH 35/36] Removes import. --- .../src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx index 65a15a793e3cd..6fe9ad6c3bfcb 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx +++ b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx @@ -12,7 +12,7 @@ import { const getClassNames = classNamesFunction(); export class ShimmerLineBase extends BaseComponent { - private _classNames: {[key in keyof IShimmerLineStyles]: string}; + private _classNames: { [key in keyof IShimmerLineStyles]: string }; constructor(props: IShimmerLineProps) { super(props); From 1e42457189a89f186b1c00c1e64bb755fa2996e6 Mon Sep 17 00:00:00 2001 From: Vitalie Braga Date: Tue, 10 Apr 2018 22:32:41 -0700 Subject: [PATCH 36/36] Removes the import statement. --- .../src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx index 3c1e3b3c660de..6fe9ad6c3bfcb 100644 --- a/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx +++ b/packages/experiments/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx @@ -8,7 +8,6 @@ import { IShimmerLineStyleProps, IShimmerLineStyles } from './ShimmerLine.types'; -import { ShimmerElementVerticalAlign } from '../Shimmer.types'; const getClassNames = classNamesFunction();