One of the challenges with PCF controls is getting them to reflow to the available space that they are stretched to fill the available space. Doing this using standard HTML involves using the flexbox. The really nice aspect of the Fluent UI react library is that it comes with an abstraction of the flexbox called the ‘Stack’.
The aim of this post is to layout a dataset PCF as follows:
The main challenges of this exercise are:
verticalFill
and height:100%
DetailsList
header row is always visible when scrolling – this is done using the onRenderDetailsHeader
event of the DetailsList
in combination with Sticky
and ScrollablePane
Here is the React component for the layout:
/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import * as React from "react"; import { Stack, ScrollablePane, DetailsList, TooltipHost, IRenderFunction, IDetailsColumnRenderTooltipProps, IDetailsHeaderProps, StickyPositionType, Sticky, ScrollbarVisibility, } from "office-ui-fabric-react"; export class DatasetLayout extends React.Component { private onRenderDetailsHeader: IRenderFunction<IDetailsHeaderProps> = (props, defaultRender) => { if (!props) { return null; } const onRenderColumnHeaderTooltip: IRenderFunction<IDetailsColumnRenderTooltipProps> = tooltipHostProps => ( <TooltipHost {...tooltipHostProps} /> ); return ( <Sticky stickyPosition={StickyPositionType.Header} isScrollSynced> {defaultRender!({ ...props, onRenderColumnHeaderTooltip, })} </Sticky> ); }; private columns = [ { key: "name", name: "Name", isResizable: true, minWidth: 100, onRender: (item: string) => { return <span>{item}</span>; }, }, ]; render() { return ( <> <Stack horizontal styles={{ root: { height: "100%" } }}> <Stack.Item> {/*Left column*/} <Stack verticalFill> <Stack.Item verticalFill styles={{ root: { textAlign: "left", width: "150px", paddingLeft: "8px", paddingRight: "8px", overflowY: "auto", overflowX: "hidden", height: "100%", background: "#DBADB1", }, }} > <Stack> <Stack.Item>Left Item 1</Stack.Item> <Stack.Item>Left Item 2</Stack.Item> </Stack> </Stack.Item> </Stack> </Stack.Item> <Stack.Item styles={{ root: { width: "100%" } }}> {/*Right column*/} <Stack grow styles={{ root: { width: "100%", height: "100%", }, }} > <Stack.Item verticalFill> <Stack grow styles={{ root: { height: "100%", width: "100%", background: "#65A3DB", }, }} > <Stack.Item>Top Bar</Stack.Item> <Stack.Item verticalFill styles={{ root: { height: "100%", overflowY: "auto", overflowX: "auto", }, }} > <div style={{ position: "relative", height: "100%" }}> <ScrollablePane scrollbarVisibility={ScrollbarVisibility.auto}> <DetailsList onRenderDetailsHeader={this.onRenderDetailsHeader} compact={true} items={[...Array(200)].map((_, i) => `Item ${i + 1}`)} columns={this.columns} ></DetailsList> </ScrollablePane> </div> </Stack.Item> <Stack.Item align="center">Footer</Stack.Item> </Stack> </Stack.Item> </Stack> </Stack.Item> </Stack> </> ); } }
Here is the css:
div[id^="ViewSelector"]{ z-index: 20; } #__flyoutRootNode .flexbox { z-index: 20; }
Hope this helps!
Original Post https://develop1.net/public/post/2020/05/11/pcf-detailslist-layout-with-fluent-ui