Skip to content

Commit f927ab3

Browse files
authored
feat(ObjectPage): Enable selecting a subSection by prop (#213)
* feat(ObjectPage): adding selectedSubSectionId prop * feat(ObjectPage): expose reference to scroller object via prop
1 parent db6d5d6 commit f927ab3

File tree

5 files changed

+53
-181
lines changed

5 files changed

+53
-181
lines changed

packages/main/src/components/ObjectPage/ObjectPageAnchorButton.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export const ObjectPageAnchorButton: FC<ObjectPageAnchorPropTypes> = (props) =>
7878
const subSection = section.props.children
7979
.filter((item) => item.props && item.props.isSubSection)
8080
.find((item) => item.props.id === selectedId);
81-
if (open && subSection) {
81+
if (subSection) {
8282
onSubSectionSelected(Event.of(null, e.getOriginalEvent(), { section, subSection, sectionIndex: index }));
8383
}
8484
closeModal();
@@ -137,7 +137,7 @@ export const ObjectPageAnchorButton: FC<ObjectPageAnchorPropTypes> = (props) =>
137137
onSetActive={onScrollActive}
138138
activeClass={classes.selected}
139139
alwaysToTop={index === 0}
140-
scrollOffset={collapsedHeader ? 45 : 0}
140+
scrollOffset={45}
141141
>
142142
<span className={classes.button}>{section.props.title}</span>
143143
</ObjectPageLink>
@@ -159,6 +159,7 @@ export const ObjectPageAnchorButton: FC<ObjectPageAnchorPropTypes> = (props) =>
159159
placementType={PlacementType.Bottom}
160160
openBy={navigationIcon}
161161
onAfterClose={closeModal}
162+
onBeforeOpen={openModal}
162163
noArrow
163164
>
164165
<List onItemClick={onSubSectionClick}>

packages/main/src/components/ObjectPage/ObjectPageHeader.tsx

Lines changed: 0 additions & 171 deletions
This file was deleted.

packages/main/src/components/ObjectPage/demo.stories.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const renderDemo = () => {
4545
imageShapeCircle={boolean('imageShapeCircle', false)}
4646
showHideHeaderButton={boolean('showHideHeaderButton', true)}
4747
selectedSectionId={text('selectedSectionId', '1')}
48+
selectedSubSectionId={text('selectedSubSectionId', undefined)}
4849
onSelectedSectionChanged={action('onSelectedSectionChanged')}
4950
noHeader={boolean('noHeader', false)}
5051
alwaysShowContentHeader={boolean('alwaysShowContentHeader', true)}

packages/main/src/components/ObjectPage/index.tsx

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,13 @@ import styles from './ObjectPage.jss';
2525
import { ObjectPageAnchorButton } from './ObjectPageAnchorButton';
2626
import { Button } from '@ui5/webcomponents-react/lib/Button';
2727
import { CollapsedAvatar } from './CollapsedAvatar';
28-
import { ObjectPageScroller } from './scroll/ObjectPageScroller';
28+
import { IScroller, ObjectPageScroller } from './scroll/ObjectPageScroller';
2929
import { AvatarSize } from '@ui5/webcomponents-react/lib/AvatarSize';
3030
import { ContentDensity } from '@ui5/webcomponents-react/lib/ContentDensity';
3131
import '@ui5/webcomponents/dist/icons/navigation-up-arrow.js';
3232
import { getScrollBarWidth } from '@ui5/webcomponents-react-base/lib/Utils';
3333
import '@ui5/webcomponents/dist/icons/navigation-down-arrow.js';
34+
import { ObjectPageSubSectionPropTypes } from '../ObjectPageSubSection';
3435

3536
export interface ObjectPagePropTypes extends CommonProps {
3637
title?: string;
@@ -42,11 +43,13 @@ export interface ObjectPagePropTypes extends CommonProps {
4243
children?: ReactNode | ReactNodeArray;
4344
mode?: ObjectPageMode;
4445
selectedSectionId?: string;
46+
selectedSubSectionId?: string;
4547
onSelectedSectionChanged?: (event: Event) => void;
4648
showHideHeaderButton?: boolean;
4749
alwaysShowContentHeader?: boolean;
4850
noHeader?: boolean;
4951
showTitleInHeaderContent?: boolean;
52+
scrollerRef?: RefObject<IScroller>;
5053
}
5154

5255
const useStyles = createUseStyles<JSSTheme, keyof ReturnType<typeof styles>>(styles, { name: 'ObjectPage' });
@@ -81,11 +84,12 @@ const ObjectPage: FC<ObjectPagePropTypes> = forwardRef((props: ObjectPagePropTyp
8184
selectedSectionId,
8285
noHeader,
8386
alwaysShowContentHeader,
84-
showTitleInHeaderContent
87+
showTitleInHeaderContent,
88+
scrollerRef
8589
} = props;
8690

8791
const [selectedSectionIndex, setSelectedSectionIndex] = useState(findSectionIndexById(children, selectedSectionId));
88-
const [selectedSubSectionId, setSelectedSubSectionId] = useState(null);
92+
const [selectedSubSectionId, setSelectedSubSectionId] = useState(props.selectedSubSectionId);
8993
const [expandHeaderActive, setExpandHeaderActive] = useState(false);
9094
const [isMounted, setIsMounted] = useState(false);
9195
const [collapsedHeader, setCollapsedHeader] = useState(false);
@@ -104,7 +108,7 @@ const ObjectPage: FC<ObjectPagePropTypes> = forwardRef((props: ObjectPagePropTyp
104108
const hideHeaderButtonPressed = useRef(false);
105109
const stableContentOnScrollRef = useRef(null);
106110
const stableBarOnScrollRef = useRef(null);
107-
const scroller = useRef(null);
111+
const scroller = useConsolidatedRef(scrollerRef);
108112
const [scrollbarWidth, setScrollbarWidth] = useState(defaultScrollbarWidth);
109113

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

355359
useEffect(() => {
356-
if (selectedSubSectionId && mode === ObjectPageMode.IconTabBar && scroller.current) {
357-
scroller.current.scrollToElementById(`ObjectPageSubSection-${selectedSubSectionId}`, collapsedHeader ? 45 : 0);
360+
if (selectedSubSectionId && scroller.current) {
361+
scroller.current.scrollToElementById(`ObjectPageSubSection-${selectedSubSectionId}`, 45);
358362
}
359363
}, [selectedSubSectionId]);
360364

365+
useEffect(() => {
366+
if (props.selectedSubSectionId) {
367+
setSelectedSubSectionId(props.selectedSubSectionId);
368+
if (mode === ObjectPageMode.IconTabBar) {
369+
// get section index
370+
371+
let index;
372+
React.Children.toArray(children).forEach((section, sectionIndex) => {
373+
if (React.isValidElement(section) && section.props && section.props.children) {
374+
React.Children.toArray(section.props.children).forEach(
375+
(subSection: ReactElement<ObjectPageSubSectionPropTypes>) => {
376+
if (
377+
React.isValidElement(subSection) &&
378+
subSection.props &&
379+
subSection.props.id === props.selectedSubSectionId
380+
) {
381+
index = sectionIndex;
382+
}
383+
}
384+
);
385+
}
386+
});
387+
388+
if (index) {
389+
setSelectedSectionIndex(index);
390+
}
391+
}
392+
}
393+
}, [props.selectedSubSectionId, scroller.current, setSelectedSectionIndex, setSelectedSubSectionId, children, mode]);
394+
361395
useEffect(() => {
362396
if (!isMounted && selectedSectionIndex < 1) return;
363397

@@ -366,7 +400,7 @@ const ObjectPage: FC<ObjectPagePropTypes> = forwardRef((props: ObjectPagePropTyp
366400
// @ts-ignore
367401
const id = Children.toArray(children)[selectedSectionIndex].props.id;
368402
if (id) {
369-
scroller.current.scrollToElementById(`ObjectPageSection-${id}`, collapsedHeader ? 45 : 0);
403+
scroller.current.scrollToElementById(`ObjectPageSection-${id}`, 45);
370404
}
371405
} else {
372406
scroller.current.scrollToTop();

packages/main/src/components/ObjectPage/scroll/ObjectPageScroller.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
import React, { forwardRef, RefObject, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
2+
import { Event } from '@ui5/webcomponents-react-base/lib/Event';
23
import { ScrollContentProvider } from './ScrollContextProvider';
34
import { scrollTo } from './ScrollHelper';
45

6+
export interface IScroller {
7+
scroll: (e: Event) => void;
8+
scrollToElementById: (id: string, scrollOffset?: number) => void;
9+
scrollToTop: () => void;
10+
}
11+
512
export interface Props {
613
scrollContainer: RefObject<HTMLDivElement>;
714
children: any;
815
forceSelection?: boolean;
916
}
1017

11-
export const ObjectPageScroller = forwardRef((props: Props, ref) => {
18+
export const ObjectPageScroller = forwardRef((props: Props, ref: RefObject<IScroller>) => {
1219
const { children, scrollContainer, forceSelection = true } = props;
1320

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

0 commit comments

Comments
 (0)