Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sticky ScrollablePane new props 7.x #9525

Closed
Closed
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
9b0ff4b
prop to opt for placeholder vs. actual element
tharshada Jun 19, 2019
d1ee070
ScrollablePane doesn't listen to events or observe mutations if no St…
tharshada Jun 19, 2019
c243fdb
caching scroll values; no scroll sync needed if component
tharshada Jun 19, 2019
b4c4979
fix non sticky placeholder logic
tharshada Jun 19, 2019
c63cbf8
minimize reflow due to scrollbar height/width
tharshada Jun 19, 2019
f85060f
horizontal & vertical scrollbars are visible independent of content o…
tharshada Jun 19, 2019
62383a6
adding prop 'order' for Sticky to arrange stickies (top to bottom)
tharshada Jun 19, 2019
53028e4
adding containerBehavior prop
tharshada Jun 20, 2019
0b3a8f1
adding example with new sticky/scrollablePane props
tharshada Jun 20, 2019
3a99a03
updating api
tharshada Jun 20, 2019
3a992f0
updating snapshot for ScrollablePane and
tharshada Jun 20, 2019
0482462
adding screener test
tharshada Jun 20, 2019
8b82da3
change file
tharshada Jun 20, 2019
de5093c
updating test
tharshada Jun 20, 2019
e63a6dc
updating screener
tharshada Jun 20, 2019
e6c2f16
Merge branch 'master' of https://github.com/OfficeDev/office-ui-fabri…
tharshada Jun 20, 2019
01637c3
read scrollbar height/width from local storage
tharshada Jun 21, 2019
1b70cd3
read scrollbar height/width if available before mounting
tharshada Jun 21, 2019
a2da775
adding example
tharshada Jun 24, 2019
c15dc54
Merge branch 'master' of https://github.com/OfficeDev/office-ui-fabri…
tharshada Jul 3, 2019
303b2d1
updating change files
tharshada Jul 3, 2019
59b19f0
fix ssr test for ScrollablePane
tharshada Jul 3, 2019
b4fc80e
changing prop names
tharshada Jul 3, 2019
2e92014
updating api
tharshada Jul 3, 2019
a88c38c
updating snapshots
tharshada Jul 3, 2019
d7a1753
updating props name
tharshada Jul 3, 2019
ee5cfb6
fixing screeners
tharshada Jul 3, 2019
424f814
updating prop name
tharshada Jul 9, 2019
37e02fe
Merge branch 'master' of https://github.com/OfficeDev/office-ui-fabri…
tharshada Jul 9, 2019
c512e45
Merge branch 'master' of https://github.com/OfficeDev/office-ui-fabri…
tharshada Jul 9, 2019
0d5a4aa
changing props for scrollablePane
tharshada Jul 18, 2019
565f138
fix scrollablePane example
tharshada Jul 19, 2019
267feda
Merge branch 'master' of https://github.com/OfficeDev/office-ui-fabri…
tharshada Jul 19, 2019
f188640
updating screener
tharshada Jul 23, 2019
f37e9d7
Merge branch 'master' of https://github.com/OfficeDev/office-ui-fabri…
tharshada Jul 23, 2019
7ede1f0
Change files
tharshada Jul 23, 2019
1769213
updating change file
tharshada Jul 23, 2019
904b2ea
adding documentation, removing enum for StickyContainerBehaviorType, …
tharshada Aug 5, 2019
360bafa
sort copy of input array
tharshada Aug 5, 2019
aaa3b63
fixing build error
tharshada Aug 5, 2019
d587838
Merge branch 'master' of https://github.com/OfficeDev/office-ui-fabri…
tharshada Aug 5, 2019
5967552
updating screener test
tharshada Aug 5, 2019
2568b17
Merge branch 'master' of https://github.com/OfficeDev/office-ui-fabri…
tharshada Aug 7, 2019
bc11aa2
removing localStorage
tharshada Aug 8, 2019
3fe5a89
Merge branch 'master' of https://github.com/OfficeDev/office-ui-fabri…
tharshada Aug 13, 2019
ba7989b
adding new UI state for ScrollabePane
tharshada Aug 13, 2019
82b2240
using saferequestanimationframe while reading scrollTop and scrollLef…
tharshada Aug 19, 2019
3d89668
fixing typos; removing safe rAF;
tharshada Aug 20, 2019
abeca76
adding comments for IStickyContainerBehavior
tharshada Aug 20, 2019
633197e
1. renaming opt-in perf variable to experimentalLayoutImprovements
tharshada Aug 29, 2019
60c1e27
Update ScrollablePane.test.tsx
dzearing Sep 4, 2019
ca65dab
adding uts
tharshada Sep 4, 2019
d56093a
Merge branch 'sticky-scrollablePane-newProps-7.x' of https://github.c…
tharshada Sep 4, 2019
e42a6b4
update setStickyContainerHeight
tharshada Sep 4, 2019
3ab11e9
updating unit test
tharshada Sep 4, 2019
20f89f4
fixing import
tharshada Sep 4, 2019
9dd2983
Merge branch 'master' of https://github.com/OfficeDev/office-ui-fabri…
tharshada Sep 4, 2019
3ffa093
adding UI state
tharshada Sep 4, 2019
6d84fd3
Merge branch 'master' of https://github.com/OfficeDev/office-ui-fabri…
tharshada Oct 16, 2019
9959ae5
refactoring code to minimize bundle size
tharshada Oct 16, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
/*! Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. */
import * as React from 'react';
import Screener from 'screener-storybook/src/screener';
import { storiesOf } from '@storybook/react';
import { FabricDecorator } from '../utilities';
import { TextField } from 'office-ui-fabric-react/lib/TextField';
import {
DetailsList,
DetailsListLayoutMode,
IDetailsHeaderProps,
Selection,
IColumn,
ConstrainMode,
IDetailsFooterProps,
DetailsRow
} from 'office-ui-fabric-react/lib/DetailsList';
import { IRenderFunction } from 'office-ui-fabric-react/lib/Utilities';
import { TooltipHost, ITooltipHostProps } from 'office-ui-fabric-react/lib/Tooltip';
import {
ScrollablePane,
ScrollbarVisibility,
IStickyContainerBehavior,
StickyContainerBehaviorType
} from 'office-ui-fabric-react/lib/ScrollablePane';
import { Sticky, StickyPositionType } from 'office-ui-fabric-react/lib/Sticky';
import { MarqueeSelection } from 'office-ui-fabric-react/lib/MarqueeSelection';
import { SelectionMode } from 'office-ui-fabric-react/lib/utilities/selection/index';
import { Fabric } from 'office-ui-fabric-react/lib/Fabric';
import { getTheme, mergeStyleSets } from 'office-ui-fabric-react/lib/Styling';

const classNames = mergeStyleSets({
wrapper: {
height: '80vh',
tharshada marked this conversation as resolved.
Show resolved Hide resolved
position: 'relative'
},
filter: {
paddingBottom: 20,
maxWidth: 300
},
header: {
margin: 0
},
row: {
display: 'inline-block'
}
});

const _footerItem: IScrollablePaneDetailsListExampleItem = {
key: 'footer',
test1: 'Footer 1',
test2: 'Footer 2',
test3: 'Footer 3'
};

interface IScrollablePaneDetailsListExampleItem {
key: number | string;
test1: string;
test2: string;
test3: string;
}

interface IScrollablePaneDetailsListExampleState {
items: IScrollablePaneDetailsListExampleItem[];
}

export class ScrollablePaneDetailsListExample extends React.Component<
{},
IScrollablePaneDetailsListExampleState
> {
private _selection: Selection;
private _allItems: IScrollablePaneDetailsListExampleItem[];
private _columns: IColumn[];

constructor(props: {}) {
super(props);

this._selection = new Selection();

this._allItems = [];
let rowData = '';
for (let i = 0; i < 200; i++) {
rowData = 'row ' + (i + 1).toString() + ', column ';
this._allItems.push({
key: i,
test1: rowData + '1',
test2: rowData + '2',
test3: rowData + '3'
});
}

this._columns = [];
for (let i = 1; i < 4; i++) {
this._columns.push({
key: 'column' + i,
name: 'Test ' + i,
fieldName: 'test' + i,
minWidth: 100,
maxWidth: 200,
isResizable: true
});
}

this.state = {
items: this._allItems
};
}

public render(): JSX.Element {
const { items } = this.state;
const stickyAboveContainer: IStickyContainerBehavior = {
arrangeStickiesBasedOnOrder: true,
containerBehavior: StickyContainerBehaviorType.StickyOnScroll,
notUsePlaceHolder: true
};
const stickyBelowContainer: IStickyContainerBehavior = {
arrangeStickiesBasedOnOrder: true,
containerBehavior: StickyContainerBehaviorType.StickyAlways,
notUsePlaceHolder: true
};
const stickyBackgroundColor = getTheme().palette.white;
return (
<div
style={{
height: '80vh',
position: 'relative',
maxHeight: 'inherit',
width: '900px'
}}
>
<Fabric>
<div className={classNames.wrapper}>
<ScrollablePane
style={{ maxWidth: '900px', border: '1px solid #edebe9' }}
scrollbarVisibility={ScrollbarVisibility.always}
stickyAboveContainerBehavior={stickyAboveContainer}
stickyBelowContainerBehavior={stickyBelowContainer}
>
<Sticky
stickyPosition={StickyPositionType.Header}
order={1}
tharshada marked this conversation as resolved.
Show resolved Hide resolved
stickyBackgroundColor={stickyBackgroundColor}
>
<TextField
className={classNames.filter}
label="Filter by name:"
onChange={this._onFilterChange}
/>
</Sticky>
<Sticky
stickyPosition={StickyPositionType.Header}
order={2}
stickyBackgroundColor={stickyBackgroundColor}
>
<h1 className={classNames.header}>Item list</h1>
</Sticky>
<MarqueeSelection selection={this._selection}>
<DetailsList
items={items}
columns={this._columns}
setKey="set"
layoutMode={DetailsListLayoutMode.fixedColumns}
constrainMode={ConstrainMode.unconstrained}
onRenderDetailsHeader={onRenderDetailsHeader}
onRenderDetailsFooter={onRenderDetailsFooter}
selection={this._selection}
selectionPreservedOnEmptyClick={true}
ariaLabelForSelectionColumn="Toggle selection"
ariaLabelForSelectAllCheckbox="Toggle selection for all items"
onItemInvoked={_onItemInvoked}
/>
</MarqueeSelection>
</ScrollablePane>
</div>
</Fabric>
</div>
);
}

private _onFilterChange = (ev: React.FormEvent<HTMLElement>, text: string) => {
this.setState({
items: text
? this._allItems.filter((item: IScrollablePaneDetailsListExampleItem) =>
hasText(item, text)
)
: this._allItems
});
};
}

function _onItemInvoked(item: IScrollablePaneDetailsListExampleItem): void {
alert('Item invoked: ' + item.test1);
}

function onRenderDetailsHeader(
props: IDetailsHeaderProps,
defaultRender?: IRenderFunction<IDetailsHeaderProps>
): JSX.Element {
return (
<Sticky
stickyPosition={StickyPositionType.Header}
isScrollSynced={true}
order={3}
stickyBackgroundColor={getTheme().palette.white}
>
{defaultRender!({
...props,
onRenderColumnHeaderTooltip: (tooltipHostProps: ITooltipHostProps) => (
<TooltipHost {...tooltipHostProps} />
)
})}
</Sticky>
);
}

function onRenderDetailsFooter(
props: IDetailsFooterProps,
defaultRender?: IRenderFunction<IDetailsFooterProps>
): JSX.Element {
return (
<Sticky
stickyPosition={StickyPositionType.Footer}
isScrollSynced={true}
order={1}
stickyBackgroundColor={getTheme().palette.white}
>
<div className={classNames.row}>
<DetailsRow
columns={props.columns}
item={_footerItem}
itemIndex={-1}
selection={props.selection}
selectionMode={(props.selection && props.selection.mode) || SelectionMode.none}
viewport={props.viewport}
/>
</div>
</Sticky>
);
}

function hasText(item: IScrollablePaneDetailsListExampleItem, text: string): boolean {
return `${item.test1}|${item.test2}|${item.test3}`.indexOf(text) > -1;
}
const getElement = "document.getElementsByClassName('ms-ScrollablePane--contentContainer')[0]";
const cropTo = { cropTo: '.testWrapper' };

storiesOf('ScrollablePane-Sticky Details List', module)
.addDecorator(FabricDecorator)
.addDecorator(story => (
<Screener
steps={new Screener.Steps()
.snapshot('default', cropTo)
.executeScript(`${getElement}.scrollTop=2`)
.snapshot('scroll down by a small amount so that the first row is still visible', cropTo)
.executeScript(`${getElement}.scrollTop=999999`)
.snapshot('scroll down to the bottom', cropTo)
.executeScript(`${getElement}.scrollTop=0`)
.snapshot('scroll up to the top', cropTo)
.executeScript(`${getElement}.scrollLeft=500`)
.snapshot('scroll left', cropTo)
.end()}
>
{story()}
</Screener>
))
.addStory('ScrollablePane Details List with sticky header & footer (1)', () => (
<ScrollablePaneDetailsListExample />
));
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "office-ui-fabric-react",
"comment": "Adding new props for Sticky and ScrollablePane",
"type": "minor"
}
],
"packageName": "office-ui-fabric-react",
"email": "hatrived@microsoft.com"
}
Original file line number Diff line number Diff line change
Expand Up @@ -6310,6 +6310,10 @@ export interface IScrollablePaneContext {
sortSticky: (sticky: Sticky, sortAgain?: boolean) => void;
notifySubscribers: (sort?: boolean) => void;
syncScrollSticky: (sticky: Sticky) => void;
usePlaceholderForSticky: (placeholderPosition: PlaceholderPosition) => boolean;
getScrollPosition: (horizontal?: boolean) => number;
verifyStickyContainerBehavior: (stickyContainerPosition: StickyContainerPosition, stickyContainerBehavior: StickyContainerBehaviorType) => boolean;
getUserInteractionStatus: () => boolean;
};
}

Expand All @@ -6318,8 +6322,9 @@ export interface IScrollablePaneProps extends React.HTMLAttributes<HTMLElement |
className?: string;
componentRef?: IRefObject<IScrollablePane>;
initialScrollPosition?: number;
// (undocumented)
scrollbarVisibility?: ScrollbarVisibility;
stickyAboveContainerBehavior?: IStickyContainerBehavior;
stickyBelowContainerBehavior?: IStickyContainerBehavior;
styles?: IStyleFunctionOrObject<IScrollablePaneStyleProps, IScrollablePaneStyles>;
theme?: ITheme;
}
Expand Down Expand Up @@ -7003,6 +7008,13 @@ export interface IStackTokens {
padding?: number | string;
}

// @public (undocumented)
export interface IStickyContainerBehavior {
arrangeStickiesBasedOnOrder: boolean;
containerBehavior: StickyContainerBehaviorType;
notUsePlaceHolder: boolean;
tharshada marked this conversation as resolved.
Show resolved Hide resolved
}

// @public (undocumented)
export interface IStickyContext {
// (undocumented)
Expand All @@ -7013,6 +7025,7 @@ export interface IStickyContext {
export interface IStickyProps extends React.Props<Sticky> {
componentRef?: IRefObject<IStickyProps>;
isScrollSynced?: boolean;
order?: number;
stickyBackgroundColor?: string;
stickyClassName?: string;
stickyPosition?: StickyPositionType;
Expand Down Expand Up @@ -8301,6 +8314,9 @@ export enum PivotLinkSize {
normal = 0
}

// @public (undocumented)
export type PlaceholderPosition = 'top' | 'bottom';

// @public (undocumented)
export const PlainCard: React.StatelessComponent<IPlainCardProps>;

Expand Down Expand Up @@ -8480,7 +8496,9 @@ export class ScrollablePaneBase extends BaseComponent<IScrollablePaneProps, IScr
// (undocumented)
forceLayoutUpdate(): void;
// (undocumented)
getScrollPosition: () => number;
getScrollPosition: (horizontal?: boolean | undefined) => number;
// (undocumented)
getUserInteractionStatus: () => boolean;
// (undocumented)
notifySubscribers: () => void;
// (undocumented)
Expand All @@ -8507,6 +8525,10 @@ export class ScrollablePaneBase extends BaseComponent<IScrollablePaneProps, IScr
unsubscribe: (handler: Function) => void;
// (undocumented)
updateStickyRefHeights: () => void;
// (undocumented)
usePlaceholderForSticky: (placeholderPosition: PlaceholderPosition) => boolean;
// (undocumented)
verifyStickyContainerBehavior: (stickyContainerPosition: StickyContainerPosition, stickyContainerBehavior: StickyContainerBehaviorType) => boolean;
}

// @public (undocumented)
Expand Down Expand Up @@ -8813,7 +8835,7 @@ export const StackItem: React.StatelessComponent<IStackItemProps>;
export class Sticky extends BaseComponent<IStickyProps, IStickyState> {
constructor(props: IStickyProps);
// (undocumented)
addSticky(stickyContent: HTMLDivElement): void;
addSticky(stickyContent: HTMLDivElement, placeholderPosition: PlaceholderPosition): void;
// (undocumented)
readonly canStickyBottom: boolean;
// (undocumented)
Expand Down Expand Up @@ -8850,6 +8872,16 @@ export class Sticky extends BaseComponent<IStickyProps, IStickyState> {
syncScroll: (container: HTMLElement) => void;
}

// @public (undocumented)
export enum StickyContainerBehaviorType {
Default = 0,
StickyAlways = 2,
StickyOnScroll = 1
tharshada marked this conversation as resolved.
Show resolved Hide resolved
}

// @public (undocumented)
export type StickyContainerPosition = 'above' | 'below';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Above" and "Below" what? You might want to be clearer here in documentation if nowhere else.


// @public (undocumented)
export enum StickyPositionType {
// (undocumented)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ const excludedExampleFiles: string[] = [
'Picker.CustomResult.Example.tsx',
'ScrollablePane.Default.Example.tsx',
'ScrollablePane.DetailsList.Example.tsx',
'SelectedPeopleList.Basic.Example.tsx'
'SelectedPeopleList.Basic.Example.tsx',
'ScrollablePane.Sticky.Optimized.DetailsList'
];

declare const global: any;
Expand Down
Loading