Skip to content

Commit

Permalink
feat(ObjectPage): Enable selecting a subSection by prop (#213)
Browse files Browse the repository at this point in the history
* feat(ObjectPage): adding selectedSubSectionId prop

* feat(ObjectPage): expose reference to scroller object via prop
  • Loading branch information
vbersch authored Oct 31, 2019
1 parent db6d5d6 commit f927ab3
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 181 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export const ObjectPageAnchorButton: FC<ObjectPageAnchorPropTypes> = (props) =>
const subSection = section.props.children
.filter((item) => item.props && item.props.isSubSection)
.find((item) => item.props.id === selectedId);
if (open && subSection) {
if (subSection) {
onSubSectionSelected(Event.of(null, e.getOriginalEvent(), { section, subSection, sectionIndex: index }));
}
closeModal();
Expand Down Expand Up @@ -137,7 +137,7 @@ export const ObjectPageAnchorButton: FC<ObjectPageAnchorPropTypes> = (props) =>
onSetActive={onScrollActive}
activeClass={classes.selected}
alwaysToTop={index === 0}
scrollOffset={collapsedHeader ? 45 : 0}
scrollOffset={45}
>
<span className={classes.button}>{section.props.title}</span>
</ObjectPageLink>
Expand All @@ -159,6 +159,7 @@ export const ObjectPageAnchorButton: FC<ObjectPageAnchorPropTypes> = (props) =>
placementType={PlacementType.Bottom}
openBy={navigationIcon}
onAfterClose={closeModal}
onBeforeOpen={openModal}
noArrow
>
<List onItemClick={onSubSectionClick}>
Expand Down
171 changes: 0 additions & 171 deletions packages/main/src/components/ObjectPage/ObjectPageHeader.tsx

This file was deleted.

1 change: 1 addition & 0 deletions packages/main/src/components/ObjectPage/demo.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const renderDemo = () => {
imageShapeCircle={boolean('imageShapeCircle', false)}
showHideHeaderButton={boolean('showHideHeaderButton', true)}
selectedSectionId={text('selectedSectionId', '1')}
selectedSubSectionId={text('selectedSubSectionId', undefined)}
onSelectedSectionChanged={action('onSelectedSectionChanged')}
noHeader={boolean('noHeader', false)}
alwaysShowContentHeader={boolean('alwaysShowContentHeader', true)}
Expand Down
48 changes: 41 additions & 7 deletions packages/main/src/components/ObjectPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ import styles from './ObjectPage.jss';
import { ObjectPageAnchorButton } from './ObjectPageAnchorButton';
import { Button } from '@ui5/webcomponents-react/lib/Button';
import { CollapsedAvatar } from './CollapsedAvatar';
import { ObjectPageScroller } from './scroll/ObjectPageScroller';
import { IScroller, ObjectPageScroller } from './scroll/ObjectPageScroller';
import { AvatarSize } from '@ui5/webcomponents-react/lib/AvatarSize';
import { ContentDensity } from '@ui5/webcomponents-react/lib/ContentDensity';
import '@ui5/webcomponents/dist/icons/navigation-up-arrow.js';
import { getScrollBarWidth } from '@ui5/webcomponents-react-base/lib/Utils';
import '@ui5/webcomponents/dist/icons/navigation-down-arrow.js';
import { ObjectPageSubSectionPropTypes } from '../ObjectPageSubSection';

export interface ObjectPagePropTypes extends CommonProps {
title?: string;
Expand All @@ -42,11 +43,13 @@ export interface ObjectPagePropTypes extends CommonProps {
children?: ReactNode | ReactNodeArray;
mode?: ObjectPageMode;
selectedSectionId?: string;
selectedSubSectionId?: string;
onSelectedSectionChanged?: (event: Event) => void;
showHideHeaderButton?: boolean;
alwaysShowContentHeader?: boolean;
noHeader?: boolean;
showTitleInHeaderContent?: boolean;
scrollerRef?: RefObject<IScroller>;
}

const useStyles = createUseStyles<JSSTheme, keyof ReturnType<typeof styles>>(styles, { name: 'ObjectPage' });
Expand Down Expand Up @@ -81,11 +84,12 @@ const ObjectPage: FC<ObjectPagePropTypes> = forwardRef((props: ObjectPagePropTyp
selectedSectionId,
noHeader,
alwaysShowContentHeader,
showTitleInHeaderContent
showTitleInHeaderContent,
scrollerRef
} = props;

const [selectedSectionIndex, setSelectedSectionIndex] = useState(findSectionIndexById(children, selectedSectionId));
const [selectedSubSectionId, setSelectedSubSectionId] = useState(null);
const [selectedSubSectionId, setSelectedSubSectionId] = useState(props.selectedSubSectionId);
const [expandHeaderActive, setExpandHeaderActive] = useState(false);
const [isMounted, setIsMounted] = useState(false);
const [collapsedHeader, setCollapsedHeader] = useState(false);
Expand All @@ -104,7 +108,7 @@ const ObjectPage: FC<ObjectPagePropTypes> = forwardRef((props: ObjectPagePropTyp
const hideHeaderButtonPressed = useRef(false);
const stableContentOnScrollRef = useRef(null);
const stableBarOnScrollRef = useRef(null);
const scroller = useRef(null);
const scroller = useConsolidatedRef(scrollerRef);
const [scrollbarWidth, setScrollbarWidth] = useState(defaultScrollbarWidth);

const classes = useStyles();
Expand Down Expand Up @@ -353,11 +357,41 @@ const ObjectPage: FC<ObjectPagePropTypes> = forwardRef((props: ObjectPagePropTyp
}, [noHeader, mode, alwaysShowContentHeader]);

useEffect(() => {
if (selectedSubSectionId && mode === ObjectPageMode.IconTabBar && scroller.current) {
scroller.current.scrollToElementById(`ObjectPageSubSection-${selectedSubSectionId}`, collapsedHeader ? 45 : 0);
if (selectedSubSectionId && scroller.current) {
scroller.current.scrollToElementById(`ObjectPageSubSection-${selectedSubSectionId}`, 45);
}
}, [selectedSubSectionId]);

useEffect(() => {
if (props.selectedSubSectionId) {
setSelectedSubSectionId(props.selectedSubSectionId);
if (mode === ObjectPageMode.IconTabBar) {
// get section index

let index;
React.Children.toArray(children).forEach((section, sectionIndex) => {
if (React.isValidElement(section) && section.props && section.props.children) {
React.Children.toArray(section.props.children).forEach(
(subSection: ReactElement<ObjectPageSubSectionPropTypes>) => {
if (
React.isValidElement(subSection) &&
subSection.props &&
subSection.props.id === props.selectedSubSectionId
) {
index = sectionIndex;
}
}
);
}
});

if (index) {
setSelectedSectionIndex(index);
}
}
}
}, [props.selectedSubSectionId, scroller.current, setSelectedSectionIndex, setSelectedSubSectionId, children, mode]);

useEffect(() => {
if (!isMounted && selectedSectionIndex < 1) return;

Expand All @@ -366,7 +400,7 @@ const ObjectPage: FC<ObjectPagePropTypes> = forwardRef((props: ObjectPagePropTyp
// @ts-ignore
const id = Children.toArray(children)[selectedSectionIndex].props.id;
if (id) {
scroller.current.scrollToElementById(`ObjectPageSection-${id}`, collapsedHeader ? 45 : 0);
scroller.current.scrollToElementById(`ObjectPageSection-${id}`, 45);
}
} else {
scroller.current.scrollToTop();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import React, { forwardRef, RefObject, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
import { Event } from '@ui5/webcomponents-react-base/lib/Event';
import { ScrollContentProvider } from './ScrollContextProvider';
import { scrollTo } from './ScrollHelper';

export interface IScroller {
scroll: (e: Event) => void;
scrollToElementById: (id: string, scrollOffset?: number) => void;
scrollToTop: () => void;
}

export interface Props {
scrollContainer: RefObject<HTMLDivElement>;
children: any;
forceSelection?: boolean;
}

export const ObjectPageScroller = forwardRef((props: Props, ref) => {
export const ObjectPageScroller = forwardRef((props: Props, ref: RefObject<IScroller>) => {
const { children, scrollContainer, forceSelection = true } = props;

const [selectedElementId, setSelectedElementId] = useState(null);
Expand Down

0 comments on commit f927ab3

Please sign in to comment.