From 4d04ed48956616edb172a0a2fb154114b14608b4 Mon Sep 17 00:00:00 2001 From: Viktor Bersch Date: Tue, 20 Aug 2019 11:58:39 +0200 Subject: [PATCH 1/9] WIP: implement Object Page Header collapse on scroll --- packages/base/src/hooks/useIsMounted.ts | 0 .../components/ObjectPage/CollapsedAvatar.tsx | 72 +++++ .../components/ObjectPage/ObjectPage.jss.ts | 169 ++++++++++- .../ObjectPage/ObjectPageAnchorButton.tsx | 41 ++- .../main/src/components/ObjectPage/index.tsx | 280 +++++++++++++++--- 5 files changed, 506 insertions(+), 56 deletions(-) create mode 100644 packages/base/src/hooks/useIsMounted.ts create mode 100644 packages/main/src/components/ObjectPage/CollapsedAvatar.tsx diff --git a/packages/base/src/hooks/useIsMounted.ts b/packages/base/src/hooks/useIsMounted.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/main/src/components/ObjectPage/CollapsedAvatar.tsx b/packages/main/src/components/ObjectPage/CollapsedAvatar.tsx new file mode 100644 index 00000000000..2c9f6cc4b02 --- /dev/null +++ b/packages/main/src/components/ObjectPage/CollapsedAvatar.tsx @@ -0,0 +1,72 @@ +import React, { ReactNode, useLayoutEffect, useMemo, useState, useRef } from 'react'; +import { createUseStyles } from 'react-jss'; +import { Avatar } from '../Avatar'; +import { AvatarShape, AvatarSize } from '../..'; +import { StyleClassHelper } from '@ui5/webcomponents-react-base'; + +const styles = { + base: { + marginRight: '1rem', + opacity: 0 + }, + hidden: { + opacity: 0 + }, + visible: { + transition: 'opacity 0.5s', + opacity: 1 + } +}; + +const useStyles = createUseStyles(styles); + +export interface CollapsedAvatarPropTypes { + image?: string | ReactNode; +} + +export function CollapsedAvatar(props: CollapsedAvatarPropTypes) { + const { image } = props; + const classes = useStyles(); + const [isMounted, setIsMounted] = useState(false); + const domRef = useRef(); + + const avatarContent = useMemo(() => { + if (!image) return null; + + if (typeof image === 'string') { + return ; + } else { + // @ts-ignore + return React.cloneElement(image, { + size: AvatarSize.S + }); + } + }, [image]); + + useLayoutEffect(() => { + requestAnimationFrame(() => { + setIsMounted(true); + // @ts-ignore + // setTimeout(() => { + // // @ts-ignore + // domRef.current.style.opacity = 1; + // domRef.current.style.transition = 'opacity 3s'; + // }, 1000); + }); + }, []); + + const containerClasses = StyleClassHelper.of(classes.base); + if (isMounted) { + // debugger; + containerClasses.put(classes.visible); + } else { + // debugger; + containerClasses.put(classes.hidden); + } + + return ( +
+ {avatarContent} +
+ ); +} diff --git a/packages/main/src/components/ObjectPage/ObjectPage.jss.ts b/packages/main/src/components/ObjectPage/ObjectPage.jss.ts index 58531bc300e..d040be81756 100644 --- a/packages/main/src/components/ObjectPage/ObjectPage.jss.ts +++ b/packages/main/src/components/ObjectPage/ObjectPage.jss.ts @@ -1,5 +1,6 @@ import { fonts } from '@ui5/webcomponents-react-base'; import { JSSTheme } from '../../interfaces/JSSTheme'; +import { ZIndex } from '../../enums/ZIndex'; const styles = ({ parameters }: JSSTheme) => ({ objectPage: { @@ -10,7 +11,36 @@ const styles = ({ parameters }: JSSTheme) => ({ flexDirection: 'column', isolation: 'isolate', whiteSpace: 'normal', - fontFamily: fonts.sapUiFontFamily + fontFamily: fonts.sapUiFontFamily, + backgroundColor: parameters.sapUiBaseBG, + '& ::-webkit-scrollbar': { + backgroundColor: '#ffffff', + '&:vertical': { + width: '0.75rem' + } + }, + '& ::-webkit-scrollbar-thumb': { + backgroundColor: '#949494', + '&:hover': { + backgroundColor: '#8c8c8c' + } + }, + '& ::-webkit-scrollbar-corner': { + backgroundColor: '#ffffff' + } + }, + contentContainer: { + overflow: 'hidden auto', + height: '100%', + position: 'relative', + flexGrow: 1 + }, + outerContentContainer: { + width: '100%', + overflow: 'hidden' + }, + contentScrollContainer: { + position: 'relative' }, anchorBar: { paddingLeft: '2rem', @@ -19,6 +49,143 @@ const styles = ({ parameters }: JSSTheme) => ({ display: 'flex', height: '2.75rem', minHeight: '2.75rem' + }, + sectionsContainer: { + '&:before': { + display: 'table', + content: '""' + }, + '& :first-child > div[role="heading"]': { + display: 'none' + }, + position: 'relative', + height: '100%', + // overflowX: 'hidden', + // overflowY: 'auto', + overflow: 'hidden', + backgroundColor: parameters.sapUiBaseBG, + '&:after': { + clear: 'both', + display: 'table', + content: '""' + } + }, + fillerDiv: { + backgroundColor: parameters.sapUiBaseBG + }, + outerScrollbar: { + position: 'absolute', + width: '12px', + right: 0, + overflow: 'hidden', + height: '100%', + zIndex: ZIndex.ResponsivePopover, + backgroundColor: parameters.sapUiObjectHeaderBackground + }, + innerScrollbar: { + width: '24px', + marginLeft: '-12px', + overflowY: 'scroll', + overflowX: 'hidden', + height: '100%' + }, + scrollbarContent: { + width: '12px' + }, + // header + header: { + flexShrink: 0, + position: 'relative', + backgroundColor: parameters.sapUiObjectHeaderBackground, + '&$stickied': { + '& $image': { + opacity: '1', + height: '3rem', + width: '3rem', + margin: '0.25rem 1rem 0.25rem 0' + } + }, + paddingRight: '12px' + }, + contentHeader: { + backgroundColor: parameters.sapUiObjectHeaderBackground + }, + titleBar: { + padding: '1.5rem 2rem', + display: 'block', + position: 'relative' + }, + container: { + display: 'inline-block', + lineHeight: 'normal', + verticalAlign: 'middle', + width: '70%', + boxSizing: 'border-box', + paddingTop: '1.5rem' + }, + title: { + fontSize: '1.375rem', + paddingRight: '1rem', + verticalAlign: 'baseline', + lineHeight: 'normal', + display: 'inline-block', + margin: '0', + fontWeight: 'normal', + color: parameters.sapUiBaseText + }, + subTitle: { + display: 'inline-block', + wordBreak: 'break-word', + verticalAlign: 'baseline', + paddingTop: '0.5rem', + fontSize: '0.875rem', + color: parameters.sapUiContentLabelColor + }, + actions: { + position: 'absolute', + top: '0', + paddingTop: '0.75rem', + right: '1.25rem', + display: 'inline-block', + float: 'right', + verticalAlign: 'top', + '& > *': { + marginLeft: '0.5rem', + padding: 0 + } + }, + stickied: {}, + image: { + height: '0', + width: '0', + opacity: '0', + display: 'inline-block', + verticalAlign: 'middle' + }, + headerContent: { + paddingTop: '1.5rem', + paddingBottom: '0.25rem', + transition: 'max-height 0.5s', + maxHeight: '500px', + overflow: 'hidden', + paddingLeft: '2rem', + position: 'relative' + }, + headerCustomContent: { + display: 'inline-block', + verticalAlign: 'top', + '& > *': { + marginRight: '2rem', + marginBottom: '1rem', + lineHeight: '1.5rem' + } + }, + headerImage: { + maxWidth: '5rem', + maxHeight: '5rem', + display: 'inline-block', + marginRight: '2rem', + marginBottom: '1rem' } }); diff --git a/packages/main/src/components/ObjectPage/ObjectPageAnchorButton.tsx b/packages/main/src/components/ObjectPage/ObjectPageAnchorButton.tsx index f0b53000448..95358f39ec4 100644 --- a/packages/main/src/components/ObjectPage/ObjectPageAnchorButton.tsx +++ b/packages/main/src/components/ObjectPage/ObjectPageAnchorButton.tsx @@ -16,6 +16,7 @@ interface ObjectPageAnchorPropTypes { onSubSectionSelected?: (event: Event) => void; index: number; selected: boolean; + collapsedHeader: boolean; mode: ObjectPageMode; } @@ -55,7 +56,7 @@ const useStyles = createUseStyles = (props) => { const classes = useStyles(); const [open, setOpen] = useState(); - const { section, index, onSubSectionSelected, onSectionSelected, selected, mode } = props; + const { section, index, collapsedHeader, onSubSectionSelected, onSectionSelected, selected, mode } = props; const openModal = useCallback(() => { setOpen(true); @@ -120,7 +121,7 @@ export const ObjectPageAnchorButton: FC = (props) => @@ -131,20 +132,28 @@ export const ObjectPageAnchorButton: FC = (props) => let sectionSelector = null; if (mode === ObjectPageMode.Default) { - sectionSelector = ( - - {section.props.title} - - ); + if (!collapsedHeader && index === 0) { + sectionSelector = ( +
+ {section.props.title} +
+ ); + } else { + sectionSelector = ( + + {section.props.title} + + ); + } } else { sectionSelector = ( diff --git a/packages/main/src/components/ObjectPage/index.tsx b/packages/main/src/components/ObjectPage/index.tsx index 5cf56fe6074..ecb934288d3 100644 --- a/packages/main/src/components/ObjectPage/index.tsx +++ b/packages/main/src/components/ObjectPage/index.tsx @@ -2,6 +2,7 @@ import { Event, StyleClassHelper, useConsolidatedRef } from '@ui5/webcomponents- import debounce from 'lodash.debounce'; import React, { Children, + FC, forwardRef, ReactElement, ReactNode, @@ -9,9 +10,9 @@ import React, { RefObject, useCallback, useEffect, + useLayoutEffect, useRef, - useState, - FC + useState } from 'react'; import { createUseStyles } from 'react-jss'; import { scroller } from 'react-scroll'; @@ -20,13 +21,13 @@ import { JSSTheme } from '../../interfaces/JSSTheme'; import { ObjectPageMode } from '../../lib/ObjectPageMode'; import styles from './ObjectPage.jss'; import { ObjectPageAnchorButton } from './ObjectPageAnchorButton'; -import { ObjectPageContent } from './ObjectPageContent'; -import { ObjectPageHeader } from './ObjectPageHeader'; +import { Button } from '../../webComponents/Button'; +import { CollapsedAvatar } from './CollapsedAvatar'; export interface ObjectPagePropTypes extends CommonProps { title?: string; subTitle?: string; - image?: string; + image?: string | ReactNode; imageShapeCircle?: boolean; headerActions?: Array>; renderHeaderContent?: () => JSX.Element; @@ -53,7 +54,7 @@ const findSectionIndexById = (sections, id) => { const scrollToSectionById = (id, index) => { requestAnimationFrame(() => { scroller.scrollTo(`ObjectPageSection-${id}`, { - containerId: 'ObjectPageSections', + containerId: 'ObjectPageContent', smooth: true, offset: index > 0 ? 45 : 0, duration: 400 @@ -83,9 +84,28 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp const [selectedSectionIndex, setSelectedSectionIndex] = useState(findSectionIndexById(children, selectedSectionId)); const [selectedSubSectionId, setSelectedSubSectionId] = useState(null); + const [expandHeaderActive, setExpandHeaderActive] = useState(false); + const [isMounted, setIsMounted] = useState(false); + const [collapsedHeader, setCollapsedHeader] = useState(false); const objectPage: RefObject = useConsolidatedRef(ref); const fillerDivDomRef: RefObject = useRef(); - const objectPageContent: RefObject = useRef(); + const scrollBar: RefObject = useRef(); + const contentContainer: RefObject = useRef(); + const topHeader: RefObject = useRef(); + const innerHeader: RefObject = useRef(); + const innerScrollBar: RefObject = useRef(); + const contentScrollContainer: RefObject = useRef(); + const hideHeaderButtonPressed = useRef(false); + const classes = useStyles(); + + const setScrollbarHeight = () => { + // @ts-ignore + debugger; + const scrollbarContainerHeight = + contentScrollContainer.current.getBoundingClientRect().height + topHeader.current.getBoundingClientRect().height; + // @ts-ignore + innerScrollBar.current.style.height = `${scrollbarContainerHeight}px`; + }; useEffect(() => { let selectedIndex = findSectionIndexById(children, selectedSectionId); @@ -118,22 +138,141 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp const lastSectionDomRef = sections[sections.length - 1]; const subSections = lastSectionDomRef.querySelectorAll('[id^="ObjectPageSubSection"]'); - let scrollOffset = 0; let domRef = null; if (subSections.length > 0) { domRef = subSections[subSections.length - 1]; } else { domRef = lastSectionDomRef; - scrollOffset = 45; + // scrollOffset = 45; } - let heightDiff = objectPageContent.current.offsetHeight - domRef.offsetHeight + scrollOffset; + let heightDiff = contentContainer.current.offsetHeight - domRef.offsetHeight; heightDiff = heightDiff > 0 ? heightDiff : 0; fillerDivDomRef.current.style.height = `${heightDiff}px`; + // fillerDivDomRef.current.style.height = `${0}px`; + setScrollbarHeight(); }); }; + const renderAnchorBar = () => { + return ( +
+ {Children.map(children, (section, index) => ( + + ))} +
+ ); + }; + + const changeHeader = useCallback(() => { + hideHeaderButtonPressed.current = true; + contentContainer.current.removeEventListener('scroll', onScroll); + + if (!expandHeaderActive && collapsedHeader) { + setExpandHeaderActive(true); + return; + } + + if (expandHeaderActive && collapsedHeader) { + setExpandHeaderActive(false); + return; + } + + setCollapsedHeader(!collapsedHeader); + + // if(!expandHeaderActive) { + // debugger; + // setCollapsedHeader(!collapsedHeader); + // setExpandHeaderActive(!expandHeaderActive); + // } + // + }, [collapsedHeader, expandHeaderActive]); + + const renderHideHeaderButton = () => { + if (!showHideHeaderButton) return null; + + return ( + , + + ]} + image={SampleImage} + renderHeaderContent={renderHeaderContent} + imageShapeCircle={false} + showHideHeaderButton={true} + style={{ height: '700px' }} + > + +
My Content 1
+
+ +
Test2
+
+ + Test1 + + +

Section 4

+ + Test 4 SubSection 1 + + + Test 4 SubSection 2 + +
+ + + Content of SubSection 5.1 + + + Content of SubSection 5.2 + + + {' '} + , + document.querySelector('body') +); diff --git a/demo/webpack.config.js b/demo/webpack.config.js new file mode 100644 index 00000000000..dda2ee1f44f --- /dev/null +++ b/demo/webpack.config.js @@ -0,0 +1,55 @@ +const PATHS = require('../config/paths'); +const path = require('path'); + +const tsLoader = { + test: /\.[tj]sx?$/, + use: [ + { + loader: require.resolve('babel-loader'), + options: { + presets: [[require.resolve('babel-preset-react-app'), { flow: false, typescript: true }]] + } + } + ] +}; + +process.env.NODE_ENV = 'development'; +process.env.BABEL_ENV = 'development'; + +const HtmlWebpackPlugin = require('html-webpack-plugin'); +module.exports = { + mode: 'development', + entry: './index.js', + module: { + rules: [ + tsLoader, + { + test: /\.png$/, + use: 'file-loader' + }, + { + test: /\.css$/, + use: ['style-loader', 'css-loader'], + exclude: { + test: [/test-resources/] + } + } + ] + }, + devServer: { + contentBase: __dirname, + compress: true, + port: 9000 + }, + output: { + path: __dirname + '/dist', + filename: 'index_bundle.js' + }, + plugins: [new HtmlWebpackPlugin()], + resolve: { + extensions: ['.ts', '.tsx', '.js', '.jsx', '.cjs', '.mjs', '.esm'], + alias: { + '@ui5/webcomponents-react/lib': path.join(PATHS.root, 'packages', 'main', 'src', 'lib') + } + } +}; diff --git a/package.json b/package.json index 2f3ae4b7433..82f2f637b41 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "global": "^4.4.0", "google-closure-compiler": "^20190415.0.0", "gzip-size": "^5.1.0", + "html-webpack-plugin": "^3.2.0", "husky": "^3.0.2", "identity-obj-proxy": "^3.0.0", "istanbul-instrumenter-loader": "^3.0.1", @@ -120,7 +121,8 @@ "util": "^0.12.0", "uuid": "^3.3.2", "webpack": "^4.39.1", - "webpack-cli": "^3.3.2" + "webpack-cli": "^3.3.2", + "webpack-dev-server": "^3.8.0" }, "resolutions": { "@types/react": "16.8.24" diff --git a/packages/main/src/components/ObjectPage/ObjectPageAnchorButton.tsx b/packages/main/src/components/ObjectPage/ObjectPageAnchorButton.tsx index 95358f39ec4..7a5cc0dede3 100644 --- a/packages/main/src/components/ObjectPage/ObjectPageAnchorButton.tsx +++ b/packages/main/src/components/ObjectPage/ObjectPageAnchorButton.tsx @@ -143,14 +143,14 @@ export const ObjectPageAnchorButton: FC = (props) => 0 ? 139 : 0} > - {section.props.title} +
+ {section.props.title} +
); } diff --git a/packages/main/src/components/ObjectPage/ObjectPageContent.tsx b/packages/main/src/components/ObjectPage/ObjectPageContent.tsx index 9f1b79a656c..20de291ba1e 100644 --- a/packages/main/src/components/ObjectPage/ObjectPageContent.tsx +++ b/packages/main/src/components/ObjectPage/ObjectPageContent.tsx @@ -15,6 +15,7 @@ const objectPageContentStyles = ({ parameters }: JSSTheme) => ({ height: '100%', overflowX: 'hidden', overflowY: 'auto', + overflow: 'hidden', backgroundColor: parameters.sapUiBaseBG, '&:after': { clear: 'both', diff --git a/packages/main/src/components/ObjectPage/demo.stories.tsx b/packages/main/src/components/ObjectPage/demo.stories.tsx index 97c695688cf..84ea81db130 100644 --- a/packages/main/src/components/ObjectPage/demo.stories.tsx +++ b/packages/main/src/components/ObjectPage/demo.stories.tsx @@ -14,6 +14,8 @@ import { ObjectPageSubSection } from '../../lib/ObjectPageSubSection'; import { Text } from '../../lib/Text'; // @ts-ignore import SampleImage from './DemoImage.png'; +import { ScrollDemo } from './ScrollDemo'; +import { ScrollSyncExample } from './scrollSync/ScrollSyncExample'; const renderHeaderContent = () => (
@@ -25,54 +27,56 @@ const renderHeaderContent = () => ( ); const renderDemo = () => { return ( - - Primary Action - , - - ]} - image={SampleImage} - renderHeaderContent={renderHeaderContent} - mode={select('mode', ObjectPageMode, ObjectPageMode.Default)} - imageShapeCircle={boolean('imageShapeCircle', false)} - showHideHeaderButton={boolean('showHideHeaderButton', true)} - selectedSectionId={text('selectedSectionId', '1')} - onSelectedSectionChanged={action('onSelectedSectionChanged')} - noHeader={boolean('noHeader', false)} - style={{ height: '700px' }} - > - - - - -
Test2
-
- - Test1 - - -

Section 4

- - Test 4 SubSection 1 - - - Test 4 SubSection 2 - -
- - - Content of SubSection 5.1 - - - Content of SubSection 5.2 - - -
+
+ + Primary Action + , + + ]} + image={SampleImage} + renderHeaderContent={renderHeaderContent} + mode={select('mode', ObjectPageMode, ObjectPageMode.Default)} + imageShapeCircle={boolean('imageShapeCircle', false)} + showHideHeaderButton={boolean('showHideHeaderButton', true)} + selectedSectionId={text('selectedSectionId', '1')} + onSelectedSectionChanged={action('onSelectedSectionChanged')} + noHeader={boolean('noHeader', false)} + style={{ height: '700px' }} + > + +
My Content 1
+
+ +
Test2
+
+ + Test1 + + +

Section 4

+ + Test 4 SubSection 1 + + + Test 4 SubSection 2 + +
+ + + Content of SubSection 5.1 + + + Content of SubSection 5.2 + + +
+
); }; @@ -98,6 +102,41 @@ const renderComponentWithSections = () => ( ); +const renderShortContent = () => { + return ( +
+ + Primary Action + , + + ]} + image={SampleImage} + renderHeaderContent={renderHeaderContent} + mode={select('mode', ObjectPageMode, ObjectPageMode.IconTabBar)} + imageShapeCircle={boolean('imageShapeCircle', false)} + showHideHeaderButton={boolean('showHideHeaderButton', true)} + selectedSectionId={text('selectedSectionId', '1')} + onSelectedSectionChanged={action('onSelectedSectionChanged')} + noHeader={boolean('noHeader', false)} + style={{ height: '700px' }} + > + +
My Content 1
+
+
+
+ ); +}; + +// const renderScrollDemo = () =>
; +// const renderScrollSync = () =>
; + storiesOf('Components | ObjectPage', module) .addParameters({ info: { @@ -106,4 +145,7 @@ storiesOf('Components | ObjectPage', module) } }) .add('Default', renderDemo) - .add('Only Sections', renderComponentWithSections); + .add('Short Content', renderShortContent); +// .add('Scroll Sync Example', renderScrollSync) +// .add('Scroll Demo', renderScrollDemo); +// .add('Only Sections', renderComponentWithSections); diff --git a/packages/main/src/components/ObjectPage/index.tsx b/packages/main/src/components/ObjectPage/index.tsx index ecb934288d3..7a963f66dc7 100644 --- a/packages/main/src/components/ObjectPage/index.tsx +++ b/packages/main/src/components/ObjectPage/index.tsx @@ -87,6 +87,7 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp const [expandHeaderActive, setExpandHeaderActive] = useState(false); const [isMounted, setIsMounted] = useState(false); const [collapsedHeader, setCollapsedHeader] = useState(false); + const objectPage: RefObject = useConsolidatedRef(ref); const fillerDivDomRef: RefObject = useRef(); const scrollBar: RefObject = useRef(); @@ -95,16 +96,19 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp const innerHeader: RefObject = useRef(); const innerScrollBar: RefObject = useRef(); const contentScrollContainer: RefObject = useRef(); + const collapsedHeaderFiller: RefObject = useRef(); + const expandedHeaderHeight = useRef(0); const hideHeaderButtonPressed = useRef(false); + const classes = useStyles(); const setScrollbarHeight = () => { - // @ts-ignore - debugger; - const scrollbarContainerHeight = - contentScrollContainer.current.getBoundingClientRect().height + topHeader.current.getBoundingClientRect().height; - // @ts-ignore - innerScrollBar.current.style.height = `${scrollbarContainerHeight}px`; + requestAnimationFrame(() => { + const scrollbarContainerHeight = + contentScrollContainer.current.getBoundingClientRect().height + + topHeader.current.getBoundingClientRect().height; + innerScrollBar.current.style.height = `${scrollbarContainerHeight}px`; + }); }; useEffect(() => { @@ -124,34 +128,51 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp } const adjustDummyDivHeight = () => { - requestAnimationFrame(() => { - if (!objectPage.current) { - // in case componentWillUnmount didn´t fire - window.removeEventListener('resize', adjustDummyDivHeight); - return; - } + return new Promise((resolve) => { + requestAnimationFrame(() => { + if (!objectPage.current) { + // in case componentWillUnmount didn´t fire + window.removeEventListener('resize', adjustDummyDivHeight); + return; + } - const sections = objectPage.current.querySelectorAll('[id^="ObjectPageSection"]'); - if (!sections || sections.length < 1) { - return; - } + const sections = objectPage.current.querySelectorAll('[id^="ObjectPageSection"]'); + if (!sections || sections.length < 1) { + return; + } - const lastSectionDomRef = sections[sections.length - 1]; - const subSections = lastSectionDomRef.querySelectorAll('[id^="ObjectPageSubSection"]'); + const lastSectionDomRef = sections[sections.length - 1]; + const subSections = lastSectionDomRef.querySelectorAll('[id^="ObjectPageSubSection"]'); - let domRef = null; - if (subSections.length > 0) { - domRef = subSections[subSections.length - 1]; - } else { - domRef = lastSectionDomRef; - // scrollOffset = 45; - } + let domRef = null; + if (subSections.length > 0) { + domRef = subSections[subSections.length - 1]; + } else { + domRef = lastSectionDomRef; + // scrollOffset = 45; + } - let heightDiff = contentContainer.current.offsetHeight - domRef.offsetHeight; - heightDiff = heightDiff > 0 ? heightDiff : 0; - fillerDivDomRef.current.style.height = `${heightDiff}px`; - // fillerDivDomRef.current.style.height = `${0}px`; - setScrollbarHeight(); + // const prevFillerHeight = fillerDivDomRef.current ? fillerDivDomRef.current.getBoundingClientRect().height : 0; + let heightDiff = contentContainer.current.offsetHeight - domRef.offsetHeight; + heightDiff = heightDiff > 0 ? heightDiff : 0; + // const totalHeight = objectPage.current.getBoundingClientRect().height; + // const headerHeight = topHeader.current.getBoundingClientRect().height; + // const scrollHeight = totalHeight - headerHeight; + // + // const scrollContainerHeight = contentScrollContainer.current.getBoundingClientRect().height; + // + // const scrollEnabled = (scrollContainerHeight - prevFillerHeight + heightDiff) > scrollHeight; + // let fillerHeight = 0; + // if(scrollEnabled) { + // fillerHeight = heightDiff + headerHeight; + // } else { + // fillerHeight = heightDiff; + // } + + fillerDivDomRef.current.style.height = `${heightDiff}px`; + setScrollbarHeight(); + resolve(); + }); }); }; @@ -240,6 +261,10 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp }; const renderTopHeader = () => { + if (noHeader) { + return renderAnchorBar(); + } + return ( <>
@@ -264,7 +289,7 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp }; const renderInnerHeader = () => { - if (collapsedHeader || expandHeaderActive) return null; + if (noHeader || collapsedHeader || expandHeaderActive) return null; return ( <> {renderContentHeader()} @@ -279,9 +304,10 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp return window.removeEventListener('resize', adjustDummyDivHeight); }, []); - useEffect(() => { + useLayoutEffect(() => { + if (!isMounted) return; adjustDummyDivHeight(); - }, [noHeader]); + }, [noHeader, mode]); // scroll to selected section after mount useEffect(() => { @@ -315,56 +341,50 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp } }, [selectedSectionIndex]); - // const timeoutId = useRef(null); + const addScrollListener = () => { + contentContainer.current.addEventListener('scroll', onScroll, { passive: true }); + }; const onScroll = (e) => { requestAnimationFrame(() => { - // if(hideHeaderButtonPressed.current) { - // if(timeoutId.current) { - // clearTimeout(timeoutId.current); - // } - // timeoutId.current = setTimeout(() => { - // hideHeaderButtonPressed.current = false; - // }, 10); - // - // return; - // } + if (noHeader) { + scrollBar.current.scrollTop = getProportionateScrollTop(e.target.scrollTop); + return; + } if (expandHeaderActive) { setExpandHeaderActive(false); } - const headerHeight = topHeader.current.getBoundingClientRect().height; - console.log(expandHeaderActive); - scrollBar.current.scrollTop = getProportionateScrollTop( - collapsedHeader && !expandHeaderActive ? e.target.scrollTop + headerHeight + 45 : e.target.scrollTop - ); const innerHeaderHeight = innerHeader.current.getBoundingClientRect().height; - const threshold = collapsedHeader ? 4 : innerHeaderHeight - 45; + const threshold = collapsedHeader ? expandedHeaderHeight.current + 4 : innerHeaderHeight - 45; const shouldBeCollapsed = e.target.scrollTop > threshold; if (collapsedHeader !== shouldBeCollapsed) { contentContainer.current.removeEventListener('scroll', onScroll); + if (shouldBeCollapsed) { + expandedHeaderHeight.current = innerHeaderHeight - 45; + collapsedHeaderFiller.current.style.height = `${expandedHeaderHeight.current}px`; + } else { + collapsedHeaderFiller.current.style.height = `${0}px`; + } setCollapsedHeader(shouldBeCollapsed); + } else { + scrollBar.current.scrollTop = collapsedHeader + ? e.target.scrollTop + : getProportionateScrollTop(e.target.scrollTop); } }); }; - const addScrollListener = () => { - contentContainer.current.addEventListener('scroll', onScroll, { passive: true }); - }; - useLayoutEffect(() => { if (!isMounted) return; - requestAnimationFrame(() => { - setScrollbarHeight(); - const headerHeight = topHeader.current.getBoundingClientRect().height; - + adjustDummyDivHeight().then(() => { if (!hideHeaderButtonPressed.current) { - const base = collapsedHeader ? 5 : headerHeight - 2; + const innerHeaderHeight = innerHeader.current.getBoundingClientRect().height; + const base = collapsedHeader ? expandedHeaderHeight.current + 5 : innerHeaderHeight - 50; contentContainer.current.scrollTop = base; - scrollBar.current.scrollTop = getProportionateScrollTop(collapsedHeader ? headerHeight : base); + scrollBar.current.scrollTop = collapsedHeader ? base : getProportionateScrollTop(base); } - adjustDummyDivHeight(); - addScrollListener(); hideHeaderButtonPressed.current = false; + addScrollListener(); }); }, [collapsedHeader]); @@ -409,7 +429,6 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp ); const getProportionateScrollTop = (base) => { - // @ts-ignore const contentContainerHeightFull = contentScrollContainer.current.getBoundingClientRect().height; const scrollBarHeight = innerScrollBar.current.getBoundingClientRect().height; @@ -417,6 +436,7 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp }; useEffect(() => { + adjustDummyDivHeight(); addScrollListener(); setIsMounted(true); }, []); @@ -446,6 +466,7 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp
+
{renderInnerHeader()}
{content}
diff --git a/yarn.lock b/yarn.lock index 7bb70f3ec2d..70f4505470a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3054,7 +3054,7 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -accepts@~1.3.4, accepts@~1.3.7: +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== @@ -3374,6 +3374,11 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + array-from@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" @@ -3534,6 +3539,11 @@ async-limiter@^1.0.0, async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== +async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + async@^2.1.4, async@^2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" @@ -4070,6 +4080,11 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + bcrypt-pbkdf@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" @@ -4148,6 +4163,18 @@ body-parser@1.19.0, body-parser@^1.16.1: raw-body "2.4.0" type-is "~1.6.17" +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + boolbase@^1.0.0, boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -4341,6 +4368,11 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -4385,6 +4417,11 @@ byte-size@^5.0.1: resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-5.0.1.tgz#4b651039a5ecd96767e71a3d7ed380e48bed4191" integrity sha512-/XuKeqWocKsYa/cBY1YbSJSWWqTi4cFgr9S6OyM7PBaPbr9zvNGwWP33vt0uqGhwDdN+y3yhbXVILEUpnwEWGw== +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + bytes@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" @@ -4483,7 +4520,7 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camel-case@^3.0.0: +camel-case@3.0.x, camel-case@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= @@ -4670,7 +4707,7 @@ cheerio@^1.0.0-rc.2: lodash "^4.15.0" parse5 "^3.0.1" -chokidar@^2.0.2, chokidar@^2.0.4: +chokidar@^2.0.2, chokidar@^2.0.4, chokidar@^2.1.6: version "2.1.6" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5" integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g== @@ -4749,7 +4786,7 @@ classnames@^2.2.5, classnames@^2.2.6: resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== -clean-css@^4.2.1: +clean-css@4.2.x, clean-css@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g== @@ -4986,11 +5023,21 @@ comma-separated-tokens@^1.0.0: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.7.tgz#419cd7fb3258b1ed838dc0953167a25e152f5b59" integrity sha512-Jrx3xsP4pPv4AwJUDWY9wOXGtwPXARej6Xd99h4TUGotmf8APuquKMpK+dnD3UgyxK7OEWaisjZz+3b5jtL6xQ== +commander@2.17.x: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + commander@^2.12.1, commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== +commander@~2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + common-tags@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" @@ -5034,6 +5081,26 @@ component-inherit@0.0.3: resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= +compressible@~2.0.16: + version "2.0.17" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1" + integrity sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw== + dependencies: + mime-db ">= 1.40.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -5074,6 +5141,11 @@ config-chain@^1.1.11: ini "^1.3.4" proto-list "~1.2.1" +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + connect@^3.6.0: version "3.7.0" resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" @@ -5813,6 +5885,11 @@ deep-equal-ident@^1.1.1: dependencies: lodash.isequal "^3.0" +deep-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -5833,6 +5910,14 @@ deepmerge@4.0.0, deepmerge@^4.0.0: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.0.0.tgz#3e3110ca29205f120d7cb064960a39c3d2087c09" integrity sha512-YZ1rOP5+kHor4hMAH+HRQnBQHg+wvS1un1hAOuIcxcBy0hzcUf6Jg2a1w65kpoOUnurOfZbERwjI1TfZxNjcww== +default-gateway@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" + integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== + dependencies: + execa "^1.0.0" + ip-regex "^2.1.0" + default-require-extensions@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" @@ -5876,6 +5961,19 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +del@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" + integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== + dependencies: + "@types/glob" "^7.1.1" + globby "^6.1.0" + is-path-cwd "^2.0.0" + is-path-in-cwd "^2.0.0" + p-map "^2.0.0" + pify "^4.0.1" + rimraf "^2.6.3" + del@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/del/-/del-5.0.0.tgz#4fa698b7a1ffb4e2ab3e8929ed699799654d6720" @@ -5952,6 +6050,11 @@ detect-newline@^2.1.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= +detect-node@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" + integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== + detect-port-alt@1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" @@ -6032,6 +6135,26 @@ discontinuous-range@1.0.0: resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" integrity sha1-44Mx8IRLukm5qctxx3FYWqsbxlo= +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" + integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + doctrine@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" @@ -6704,7 +6827,7 @@ expect@^24.8.0: jest-message-util "^24.8.0" jest-regex-util "^24.3.0" -express@^4.17.0: +express@^4.17.0, express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== @@ -6889,6 +7012,13 @@ fault@^1.0.2: dependencies: format "^0.2.2" +faye-websocket@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= + dependencies: + websocket-driver ">=0.5.1" + faye-websocket@~0.11.1: version "0.11.3" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" @@ -7647,6 +7777,17 @@ globby@^10.0.0: merge2 "^1.2.3" slash "^3.0.0" +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + globby@^9.2.0: version "9.2.0" resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" @@ -7767,6 +7908,11 @@ gzip-size@^5.1.0: duplexer "^0.1.1" pify "^4.0.1" +handle-thing@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" + integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ== + handlebars@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" @@ -7923,7 +8069,7 @@ hastscript@^5.0.0: property-information "^5.0.1" space-separated-tokens "^1.0.0" -he@1.2.0, he@^1.1.1, he@^1.2.0: +he@1.2.0, he@1.2.x, he@^1.1.1, he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== @@ -7976,6 +8122,16 @@ hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + hsl-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" @@ -8005,11 +8161,24 @@ html-encoding-sniffer@^1.0.2: dependencies: whatwg-encoding "^1.0.1" -html-entities@^1.2.0: +html-entities@^1.2.0, html-entities@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= +html-minifier@^3.2.3: + version "3.5.21" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" + integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== + dependencies: + camel-case "3.0.x" + clean-css "4.2.x" + commander "2.17.x" + he "1.2.x" + param-case "2.1.x" + relateurl "0.2.x" + uglify-js "3.4.x" + html-minifier@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-4.0.0.tgz#cca9aad8bce1175e02e17a8c33e46d8988889f56" @@ -8023,6 +8192,19 @@ html-minifier@^4.0.0: relateurl "^0.2.7" uglify-js "^3.5.1" +html-webpack-plugin@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b" + integrity sha1-sBq71yOsqqeze2r0SS69oD2d03s= + dependencies: + html-minifier "^3.2.3" + loader-utils "^0.2.16" + lodash "^4.17.3" + pretty-error "^2.0.2" + tapable "^1.0.0" + toposort "^1.0.0" + util.promisify "1.0.0" + html-webpack-plugin@^4.0.0-beta.2: version "4.0.0-beta.8" resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.8.tgz#d9a8d4322d8cf310f1568f6f4f585a80df0ad378" @@ -8052,6 +8234,11 @@ http-cache-semantics@3.8.1, http-cache-semantics@^3.8.1: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + http-errors@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" @@ -8063,6 +8250,16 @@ http-errors@1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + http-errors@~1.7.2: version "1.7.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" @@ -8087,7 +8284,17 @@ http-proxy-agent@^2.1.0: agent-base "4" debug "3.1.0" -http-proxy@^1.13.0: +http-proxy-middleware@^0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" + integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== + dependencies: + http-proxy "^1.17.0" + is-glob "^4.0.0" + lodash "^4.17.11" + micromatch "^3.1.10" + +http-proxy@^1.13.0, http-proxy@^1.17.0: version "1.17.0" resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a" integrity sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g== @@ -8352,6 +8559,14 @@ inquirer@^6.2.0, inquirer@^6.3.1: strip-ansi "^5.1.0" through "^2.3.6" +internal-ip@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" + integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== + dependencies: + default-gateway "^4.2.0" + ipaddr.js "^1.9.0" + interpret@1.2.0, interpret@^1.0.0, interpret@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" @@ -8387,7 +8602,7 @@ ip-regex@^2.1.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= -ip@^1.1.5: +ip@^1.1.0, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= @@ -8397,11 +8612,21 @@ ipaddr.js@1.9.0: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" integrity sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA== +ipaddr.js@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + is-absolute-url@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= +is-absolute-url@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.1.tgz#e315cbdcbbc3d6789532d591954ac78a0e5049f6" + integrity sha512-c2QjUwuMxLsld90sj3xYzpFYWJtuxkIn1f5ua9RTEYJt/vV2IsM+Py00/6qjV7qExgifUvt7qfyBGBBKm+2iBg== + is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" @@ -9876,6 +10101,11 @@ keyv@3.0.0: dependencies: json-buffer "3.0.0" +killable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== + kind-of@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5" @@ -10328,7 +10558,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.0.1, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.4, lodash@^4.2.1: +lodash@^4.0.1, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.1: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -10379,6 +10609,11 @@ log4js@^4.0.0: rfdc "^1.1.4" streamroller "^1.0.6" +loglevel@^1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.3.tgz#77f2eb64be55a404c9fd04ad16d57c1d6d6b1280" + integrity sha512-LoEDv5pgpvWgPF4kNYuIp0qqSJVWak/dML0RY74xlzMZiT9w77teNAwKYKWBTYjlokMirg+o3jBwp+vlLrcfAA== + loglevelnext@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/loglevelnext/-/loglevelnext-1.0.5.tgz#36fc4f5996d6640f539ff203ba819641680d75a2" @@ -10801,12 +11036,12 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.40.0: +mime-db@1.40.0, "mime-db@>= 1.40.0 < 2": version "1.40.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== -mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: version "2.1.24" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== @@ -10949,7 +11184,7 @@ mkdirp-promise@^5.0.1: dependencies: mkdirp "*" -mkdirp@*, mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@*, mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -11027,6 +11262,19 @@ ms@^2.0.0, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + multimatch@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-3.0.0.tgz#0e2534cc6bc238d9ab67e1b9cd5fcd85a6dbf70b" @@ -11188,6 +11436,11 @@ node-fetch@^2.3.0, node-fetch@^2.5.0, node-fetch@^2.6.0: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== +node-forge@0.7.5: + version "0.7.5" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" + integrity sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ== + node-gyp@^5.0.2: version "5.0.3" resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.0.3.tgz#80d64c23790244991b6d44532f0a351bedd3dd45" @@ -11597,6 +11850,11 @@ object.values@^1.0.4, object.values@^1.1.0: function-bind "^1.1.1" has "^1.0.3" +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + octokit-pagination-methods@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz#cf472edc9d551055f9ef73f6e42b4dbb4c80bea4" @@ -11609,6 +11867,11 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -11649,6 +11912,13 @@ opn@5.4.0: dependencies: is-wsl "^1.1.0" +opn@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== + dependencies: + is-wsl "^1.1.0" + optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" @@ -11843,6 +12113,13 @@ p-reduce@^1.0.0: resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= +p-retry@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" + integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w== + dependencies: + retry "^0.12.0" + p-timeout@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" @@ -11891,7 +12168,7 @@ parallel-transform@^1.1.0: inherits "^2.0.3" readable-stream "^2.1.5" -param-case@^2.1.1: +param-case@2.1.x, param-case@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= @@ -12279,6 +12556,15 @@ popper.js@^1.14.4, popper.js@^1.14.7: resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.15.0.tgz#5560b99bbad7647e9faa475c6b8056621f5a4ff2" integrity sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA== +portfinder@^1.0.21: + version "1.0.23" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.23.tgz#894db4bcc5daf02b6614517ce89cd21a38226b82" + integrity sha512-B729mL/uLklxtxuiJKfQ84WPxNw5a7Yhx3geQZdcA4GjNjZSTSSMMWyoennMVnTWSmAR0lMdzWYN0JLnHrg1KQ== + dependencies: + async "^1.5.2" + debug "^2.2.0" + mkdirp "0.5.x" + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -12738,7 +13024,7 @@ prettier@^1.0.0: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== -pretty-error@^2.1.1: +pretty-error@^2.0.2, pretty-error@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= @@ -13605,7 +13891,7 @@ read@1, read@~1.0.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" -"readable-stream@2 || 3", readable-stream@^3.0.2, readable-stream@^3.1.1: +"readable-stream@2 || 3", readable-stream@^3.0.2, readable-stream@^3.0.6, readable-stream@^3.1.1: version "3.4.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== @@ -13829,7 +14115,7 @@ regjsparser@^0.6.0: dependencies: jsesc "~0.5.0" -relateurl@^0.2.7: +relateurl@0.2.x, relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= @@ -14044,6 +14330,11 @@ retry@^0.10.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + reusify@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -14328,11 +14619,23 @@ schema-utils@^2.0.0, schema-utils@^2.0.1: ajv "^6.1.0" ajv-keywords "^3.1.0" +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + select@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0= +selfsigned@^1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.4.tgz#cdd7eccfca4ed7635d47a08bf2d5d3074092e2cd" + integrity sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw== + dependencies: + node-forge "0.7.5" + semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" @@ -14343,7 +14646,7 @@ semver-compare@^1.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== -semver@^6.0.0, semver@^6.1.1, semver@^6.2.0: +semver@^6.0.0, semver@^6.1.1, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -14388,6 +14691,19 @@ serve-favicon@^2.5.0: parseurl "~1.3.2" safe-buffer "5.1.1" +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + serve-static@1.14.1: version "1.14.1" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" @@ -14418,6 +14734,11 @@ setimmediate@^1.0.4, setimmediate@^1.0.5: resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + setprototypeof@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" @@ -14662,6 +14983,14 @@ sockjs-client@1.3.0: json3 "^3.3.2" url-parse "^1.4.3" +sockjs@0.3.19: + version "0.3.19" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d" + integrity sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw== + dependencies: + faye-websocket "^0.10.0" + uuid "^3.0.1" + socks-proxy-agent@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" @@ -14784,6 +15113,29 @@ spdx-license-ids@^3.0.0: resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.1.tgz#6f12ed1c5db7ea4f24ebb8b89ba58c87c08257f2" + integrity sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -14855,7 +15207,7 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= @@ -15394,6 +15746,11 @@ through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= +thunky@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.3.tgz#f5df732453407b09191dae73e2a8cc73f381a826" + integrity sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow== + timed-out@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -15512,6 +15869,11 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +toposort@^1.0.0: + version "1.0.7" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029" + integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk= + touch@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/touch/-/touch-2.0.2.tgz#ca0b2a3ae3211246a61b16ba9e6cbf1596287164" @@ -15724,6 +16086,14 @@ ua-parser-js@^0.7.18: resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.20.tgz#7527178b82f6a62a0f243d1f94fd30e3e3c21098" integrity sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw== +uglify-js@3.4.x: + version "3.4.10" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" + integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== + dependencies: + commander "~2.19.0" + source-map "~0.6.1" + uglify-js@^3.1.4, uglify-js@^3.5.1: version "3.6.0" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5" @@ -16168,6 +16538,13 @@ watchpack@^1.5.0, watchpack@^1.6.0: graceful-fs "^4.1.2" neo-async "^2.5.0" +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + wcwidth@^1.0.0, wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" @@ -16207,6 +16584,45 @@ webpack-dev-middleware@^3.7.0: range-parser "^1.2.1" webpack-log "^2.0.0" +webpack-dev-server@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.8.0.tgz#06cc4fc2f440428508d0e9770da1fef10e5ef28d" + integrity sha512-Hs8K9yI6pyMvGkaPTeTonhD6JXVsigXDApYk9JLW4M7viVBspQvb1WdAcWxqtmttxNW4zf2UFLsLNe0y87pIGQ== + dependencies: + ansi-html "0.0.7" + bonjour "^3.5.0" + chokidar "^2.1.6" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + debug "^4.1.1" + del "^4.1.1" + express "^4.17.1" + html-entities "^1.2.1" + http-proxy-middleware "^0.19.1" + import-local "^2.0.0" + internal-ip "^4.3.0" + ip "^1.1.5" + is-absolute-url "^3.0.0" + killable "^1.0.1" + loglevel "^1.6.3" + opn "^5.5.0" + p-retry "^3.0.1" + portfinder "^1.0.21" + schema-utils "^1.0.0" + selfsigned "^1.10.4" + semver "^6.3.0" + serve-index "^1.9.1" + sockjs "0.3.19" + sockjs-client "1.3.0" + spdy "^4.0.1" + strip-ansi "^3.0.1" + supports-color "^6.1.0" + url "^0.11.0" + webpack-dev-middleware "^3.7.0" + webpack-log "^2.0.0" + ws "^6.2.1" + yargs "12.0.5" + webpack-hot-middleware@^2.25.0: version "2.25.0" resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.0.tgz#4528a0a63ec37f8f8ef565cf9e534d57d09fe706" @@ -16502,7 +16918,7 @@ ws@^5.2.0: dependencies: async-limiter "~1.0.0" -ws@^6.1.0: +ws@^6.1.0, ws@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== @@ -16610,6 +17026,24 @@ yargs-unparser@1.5.0: lodash "^4.17.11" yargs "^12.0.5" +yargs@12.0.5, yargs@^12.0.1, yargs@^12.0.2, yargs@^12.0.5: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" + yargs@13.2.2: version "13.2.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.2.tgz#0c101f580ae95cea7f39d927e7770e3fdc97f993" @@ -16662,24 +17096,6 @@ yargs@^11.0.0: y18n "^3.2.1" yargs-parser "^9.0.2" -yargs@^12.0.1, yargs@^12.0.2, yargs@^12.0.5: - version "12.0.5" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" - integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== - dependencies: - cliui "^4.0.0" - decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^3.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^11.1.1" - yauzl@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" From fbcbe5ea0eb3cfc32a897d2192fc34c4dc144040 Mon Sep 17 00:00:00 2001 From: Viktor Bersch Date: Thu, 22 Aug 2019 17:13:24 +0200 Subject: [PATCH 3/9] feat(ObjectPage): collapse header on scroll --- packages/main/package.json | 1 - .../components/ObjectPage/CollapsedAvatar.tsx | 15 +- .../ObjectPage/ObjectPageAnchorButton.tsx | 50 +++--- .../main/src/components/ObjectPage/index.tsx | 156 ++++++++---------- .../scroll/ScrollContextProvider.tsx | 26 +++ .../ObjectPage/scroll/ScrollHelper.ts | 135 +++++++++++++++ .../ObjectPage/scroll/useScrollElement.ts | 19 +++ .../components/ObjectPageSection/index.tsx | 19 ++- .../components/ObjectPageSubSection/index.tsx | 14 +- 9 files changed, 302 insertions(+), 133 deletions(-) create mode 100644 packages/main/src/components/ObjectPage/scroll/ScrollContextProvider.tsx create mode 100644 packages/main/src/components/ObjectPage/scroll/ScrollHelper.ts create mode 100644 packages/main/src/components/ObjectPage/scroll/useScrollElement.ts diff --git a/packages/main/package.json b/packages/main/package.json index a36c2de65df..936df604c29 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -24,7 +24,6 @@ "@ui5/webcomponents": "1.0.0-rc.2", "@ui5/webcomponents-react-base": "0.5.0", "lodash.debounce": "^4.0.8", - "react-scroll": "^1.7.11", "react-table": "6.10.0", "react-toastify": "^5.0.1" }, diff --git a/packages/main/src/components/ObjectPage/CollapsedAvatar.tsx b/packages/main/src/components/ObjectPage/CollapsedAvatar.tsx index 2c9f6cc4b02..c1805d91bdd 100644 --- a/packages/main/src/components/ObjectPage/CollapsedAvatar.tsx +++ b/packages/main/src/components/ObjectPage/CollapsedAvatar.tsx @@ -1,4 +1,4 @@ -import React, { ReactNode, useLayoutEffect, useMemo, useState, useRef } from 'react'; +import React, { ReactNode, useLayoutEffect, useMemo, useRef, useState } from 'react'; import { createUseStyles } from 'react-jss'; import { Avatar } from '../Avatar'; import { AvatarShape, AvatarSize } from '../..'; @@ -22,10 +22,11 @@ const useStyles = createUseStyles(styles); export interface CollapsedAvatarPropTypes { image?: string | ReactNode; + imageShapeCircle?: boolean; } export function CollapsedAvatar(props: CollapsedAvatarPropTypes) { - const { image } = props; + const { image, imageShapeCircle } = props; const classes = useStyles(); const [isMounted, setIsMounted] = useState(false); const domRef = useRef(); @@ -34,14 +35,20 @@ export function CollapsedAvatar(props: CollapsedAvatarPropTypes) { if (!image) return null; if (typeof image === 'string') { - return ; + return ( + + ); } else { // @ts-ignore return React.cloneElement(image, { size: AvatarSize.S }); } - }, [image]); + }, [image, imageShapeCircle]); useLayoutEffect(() => { requestAnimationFrame(() => { diff --git a/packages/main/src/components/ObjectPage/ObjectPageAnchorButton.tsx b/packages/main/src/components/ObjectPage/ObjectPageAnchorButton.tsx index 7a5cc0dede3..6591e6cab43 100644 --- a/packages/main/src/components/ObjectPage/ObjectPageAnchorButton.tsx +++ b/packages/main/src/components/ObjectPage/ObjectPageAnchorButton.tsx @@ -1,7 +1,6 @@ import { Event, fonts } from '@ui5/webcomponents-react-base'; import React, { FC, useCallback, useState } from 'react'; import { createUseStyles } from 'react-jss'; -import { Link } from 'react-scroll'; import { JSSTheme } from '../../interfaces/JSSTheme'; import { Icon } from '../../lib/Icon'; import { List } from '../../lib/List'; @@ -9,6 +8,7 @@ import { ObjectPageMode } from '../../lib/ObjectPageMode'; import { PlacementType } from '../../lib/PlacementType'; import { Popover } from '../../lib/Popover'; import { StandardListItem } from '../../lib/StandardListItem'; +import { ObjectPageLink } from './scroll/ObjectPageLink'; interface ObjectPageAnchorPropTypes { section: any; @@ -33,7 +33,8 @@ const anchorButtonStyles = ({ parameters }: JSSTheme) => ({ button: { color: parameters.sapUiContentLabelColor, fontFamily: fonts.sapUiFontFamily, - fontSize: fonts.sapMFontMediumSize + fontSize: fonts.sapMFontMediumSize, + cursor: 'pointer' }, selected: { color: parameters.sapUiSelected, @@ -56,7 +57,7 @@ const useStyles = createUseStyles = (props) => { const classes = useStyles(); const [open, setOpen] = useState(); - const { section, index, collapsedHeader, onSubSectionSelected, onSectionSelected, selected, mode } = props; + const { section, collapsedHeader, index, onSubSectionSelected, onSectionSelected, selected, mode } = props; const openModal = useCallback(() => { setOpen(true); @@ -118,42 +119,29 @@ export const ObjectPageAnchorButton: FC = (props) => } return ( - {item.props.title} - + ); }; let sectionSelector = null; if (mode === ObjectPageMode.Default) { - if (!collapsedHeader && index === 0) { - sectionSelector = ( -
- {section.props.title} -
- ); - } else { - sectionSelector = ( - 0 ? 139 : 0} - > -
- {section.props.title} -
- - ); - } + sectionSelector = ( + + {section.props.title} + + ); } else { sectionSelector = ( diff --git a/packages/main/src/components/ObjectPage/index.tsx b/packages/main/src/components/ObjectPage/index.tsx index 7a963f66dc7..038be26b239 100644 --- a/packages/main/src/components/ObjectPage/index.tsx +++ b/packages/main/src/components/ObjectPage/index.tsx @@ -15,7 +15,6 @@ import React, { useState } from 'react'; import { createUseStyles } from 'react-jss'; -import { scroller } from 'react-scroll'; import { CommonProps } from '../../interfaces/CommonProps'; import { JSSTheme } from '../../interfaces/JSSTheme'; import { ObjectPageMode } from '../../lib/ObjectPageMode'; @@ -23,6 +22,10 @@ import styles from './ObjectPage.jss'; import { ObjectPageAnchorButton } from './ObjectPageAnchorButton'; import { Button } from '../../webComponents/Button'; import { CollapsedAvatar } from './CollapsedAvatar'; +import { ObjectPageScroller } from './scroll/ObjectPageScroller'; +import { Avatar } from '@ui5/webcomponents-react/lib/Avatar'; +import { AvatarSize } from '@ui5/webcomponents-react/lib/AvatarSize'; +import { AvatarShape } from '@ui5/webcomponents-react/lib/AvatarShape'; export interface ObjectPagePropTypes extends CommonProps { title?: string; @@ -51,17 +54,6 @@ const findSectionIndexById = (sections, id) => { return index; }; -const scrollToSectionById = (id, index) => { - requestAnimationFrame(() => { - scroller.scrollTo(`ObjectPageSection-${id}`, { - containerId: 'ObjectPageContent', - smooth: true, - offset: index > 0 ? 45 : 0, - duration: 400 - }); - }); -}; - const ObjectPage: FC = forwardRef((props: ObjectPagePropTypes, ref: RefObject) => { const { title, @@ -99,6 +91,7 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp const collapsedHeaderFiller: RefObject = useRef(); const expandedHeaderHeight = useRef(0); const hideHeaderButtonPressed = useRef(false); + const scroller = useRef(null); const classes = useStyles(); @@ -149,26 +142,10 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp domRef = subSections[subSections.length - 1]; } else { domRef = lastSectionDomRef; - // scrollOffset = 45; } - // const prevFillerHeight = fillerDivDomRef.current ? fillerDivDomRef.current.getBoundingClientRect().height : 0; let heightDiff = contentContainer.current.offsetHeight - domRef.offsetHeight; heightDiff = heightDiff > 0 ? heightDiff : 0; - // const totalHeight = objectPage.current.getBoundingClientRect().height; - // const headerHeight = topHeader.current.getBoundingClientRect().height; - // const scrollHeight = totalHeight - headerHeight; - // - // const scrollContainerHeight = contentScrollContainer.current.getBoundingClientRect().height; - // - // const scrollEnabled = (scrollContainerHeight - prevFillerHeight + heightDiff) > scrollHeight; - // let fillerHeight = 0; - // if(scrollEnabled) { - // fillerHeight = heightDiff + headerHeight; - // } else { - // fillerHeight = heightDiff; - // } - fillerDivDomRef.current.style.height = `${heightDiff}px`; setScrollbarHeight(); resolve(); @@ -179,18 +156,20 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp const renderAnchorBar = () => { return (
- {Children.map(children, (section, index) => ( - - ))} + {Children.map(children, (section, index) => { + return ( + + ); + })}
); }; @@ -242,17 +221,27 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp }; const renderContentHeader = () => { + let avatar; + if (typeof image === 'string') { + avatar = ( + + ); + } else { + // @ts-ignore + avatar = React.cloneElement(image, { + size: AvatarSize.L + }); + } + return (
- {image && ( - - - - )} + {avatar} {renderHeaderContent && {renderHeaderContent()}}
{!expandHeaderActive && renderHideHeaderButton()} @@ -271,7 +260,7 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp
{image && collapsedHeader && !expandHeaderActive && (
- +
)} @@ -309,32 +298,25 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp adjustDummyDivHeight(); }, [noHeader, mode]); - // scroll to selected section after mount - useEffect(() => { - if (mode !== ObjectPageMode.IconTabBar) { - if (selectedSectionId && selectedSectionIndex > 0) { - scrollToSectionById(selectedSectionId, selectedSectionIndex); - } - } - }, []); - useEffect(() => { - if (selectedSubSectionId && mode === ObjectPageMode.IconTabBar) { - requestAnimationFrame(() => { - scroller.scrollTo(`ObjectPageSubSection-${selectedSubSectionId}`, { - containerId: 'ObjectPageContent', - smooth: true, - offset: 36, - duration: 400 - }); - }); + if (selectedSubSectionId && mode === ObjectPageMode.IconTabBar && scroller.current) { + scroller.current.scrollToElementById(`ObjectPageSubSection-${selectedSubSectionId}`, collapsedHeader ? 0 : -45); } }, [selectedSubSectionId]); useEffect(() => { - if (mode === ObjectPageMode.Default) { - // @ts-ignore - scrollToSectionById(Children.toArray(children)[selectedSectionIndex].props.id, selectedSectionIndex); + if (!isMounted && selectedSectionIndex < 1) return; + + if (mode === ObjectPageMode.Default && scroller.current) { + if (selectedSectionIndex > 0) { + // @ts-ignore + const id = Children.toArray(children)[selectedSectionIndex].props.id; + if (id) { + scroller.current.scrollToElementById(`ObjectPageSection-${id}`, collapsedHeader ? 0 : -45); + } + } else { + scroller.current.scrollToTop(); + } } if (mode === ObjectPageMode.IconTabBar) { adjustDummyDivHeight(); @@ -349,6 +331,7 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp requestAnimationFrame(() => { if (noHeader) { scrollBar.current.scrollTop = getProportionateScrollTop(e.target.scrollTop); + scroller.current.scroll(e); return; } if (expandHeaderActive) { @@ -370,6 +353,7 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp scrollBar.current.scrollTop = collapsedHeader ? e.target.scrollTop : getProportionateScrollTop(e.target.scrollTop); + scroller.current.scroll(e); } }); }; @@ -455,24 +439,26 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp ref={objectPage} title={tooltip} > -
-
-
+ +
+
+
+
-
-
- {renderTopHeader()} -
-
-
-
-
-
{renderInnerHeader()}
-
{content}
-
+
+ {renderTopHeader()} +
+
+
+
+
+
{renderInnerHeader()}
+
{content}
+
+
-
+
); }); diff --git a/packages/main/src/components/ObjectPage/scroll/ScrollContextProvider.tsx b/packages/main/src/components/ObjectPage/scroll/ScrollContextProvider.tsx new file mode 100644 index 00000000000..6f8781de3d2 --- /dev/null +++ b/packages/main/src/components/ObjectPage/scroll/ScrollContextProvider.tsx @@ -0,0 +1,26 @@ +import React, { useMemo } from 'react'; +import { ScrollContext } from './ScrollContext'; + +export function ScrollContentProvider(props) { + const { + children, + scrollContainer, + registerElement, + unregisterElement, + scrollToElementById, + selectedElementId, + scrollToTop + } = props; + const context = useMemo(() => { + return { + scrollContainer, + registerElement, + unregisterElement, + scrollToElementById, + selectedElementId, + scrollToTop + }; + }, [scrollContainer, registerElement, unregisterElement, scrollToElementById, selectedElementId, scrollToTop]); + + return {children}; +} diff --git a/packages/main/src/components/ObjectPage/scroll/ScrollHelper.ts b/packages/main/src/components/ObjectPage/scroll/ScrollHelper.ts new file mode 100644 index 00000000000..1740ba22840 --- /dev/null +++ b/packages/main/src/components/ObjectPage/scroll/ScrollHelper.ts @@ -0,0 +1,135 @@ +const defaultEasing = (x) => { + if (x < 0.5) { + return Math.pow(x * 2, 2) / 2; + } + return 1 - Math.pow((1 - x) * 2, 2) / 2; +}; + +const cancelEvents = ['mousedown', 'mousewheel', 'touchmove', 'keydown']; +const subscribeCancelEvent = (cancelEvent) => + typeof document !== 'undefined' && cancelEvents.forEach((event) => document.addEventListener(event, cancelEvent)); + +const events = { + registered: {}, + scrollEvent: { + register: (evtName, callback) => { + events.registered[evtName] = callback; + }, + remove: (evtName) => { + events.registered[evtName] = null; + } + } +}; + +const functionWrapper = (value) => (typeof value === 'function' ? value : () => value); + +const makeData = () => ({ + currentPositionY: 0, + startPositionY: 0, + targetPositionY: 0, + progress: 0, + duration: 400, + cancel: false, + target: null, + scrollContainer: null, + to: null, + start: null, + deltaTop: null, + percent: null, + delayTimeout: null +}); + +function animateScroll(easing, options, timestamp) { + const data = options.data; + + // Cancel on specific events + if (!options.ignoreCancelEvents && data.cancel) { + // @ts-ignore + if (events.registered.end) { + // @ts-ignore + events.registered.end(data.to, data.target, data.currentPositionY); + } + return; + } + + data.deltaTop = Math.round(data.targetPositionY - data.startPositionY); + + if (data.start === null) { + data.start = timestamp; + } + + data.progress = timestamp - data.start; + + data.percent = data.progress >= data.duration ? 1 : easing(data.progress / data.duration); + + data.currentPositionY = data.startPositionY + Math.ceil(data.deltaTop * data.percent); + + const { scrollContainer } = options; + // @ts-ignore + if ( + scrollContainer && + scrollContainer.current && + scrollContainer.current !== document && + scrollContainer.current !== document.body + ) { + // @ts-ignore + scrollContainer.current.scrollTop = data.currentPositionY; + } else { + window.scrollTo(0, data.currentPositionY); + } + + if (data.percent < 1) { + const easedAnimate = animateScroll.bind(null, easing, options); + requestAnimationFrame(easedAnimate); + return; + } + + // @ts-ignore + if (events.registered.end) { + // @ts-ignore + events.registered.end(data.to, data.target, data.currentPositionY); + } +} + +function animateTopScroll(y, options, to, target) { + options.data = options.data || makeData(); + const { scrollContainer } = options; + + subscribeCancelEvent(() => { + options.data.cancel = true; + }); + + options.data.start = null; + options.data.cancel = false; + options.data.startPositionY = scrollContainer.current.scrollTop; + options.data.targetPositionY = options.absolute ? y : y + options.data.startPositionY; + + if (options.data.startPositionY === options.data.targetPositionY) { + // @ts-ignore + if (events.registered.end) { + // @ts-ignore + events.registered.end(options.data.to, options.data.target, options.data.currentPositionY); + } + return; + } + + options.data.deltaTop = Math.round(options.data.targetPositionY - options.data.startPositionY); + + options.data.duration = functionWrapper(options.duration)(options.data.deltaTop); + options.data.duration = isNaN(parseFloat(options.data.duration)) ? 400 : parseFloat(options.data.duration); + options.data.to = to; + options.data.target = target; + + const easedAnimate = animateScroll.bind(null, defaultEasing, options); + + // @ts-ignore + if (events.registered.begin) { + // @ts-ignore + events.registered.begin(options.data.to, options.data.target); + } + requestAnimationFrame(easedAnimate); +} + +export function scrollTo(toY, options, to, target) { + animateTopScroll(toY, options, to, target); +} diff --git a/packages/main/src/components/ObjectPage/scroll/useScrollElement.ts b/packages/main/src/components/ObjectPage/scroll/useScrollElement.ts new file mode 100644 index 00000000000..7ff865c7126 --- /dev/null +++ b/packages/main/src/components/ObjectPage/scroll/useScrollElement.ts @@ -0,0 +1,19 @@ +import { useContext, useEffect } from 'react'; +import { ScrollContext } from './ScrollContext'; + +export function useScrollElement(id, htmlRef, options = {}) { + const { registerElement, unregisterElement } = useContext(ScrollContext); + + useEffect(() => { + if (htmlRef.current) { + registerElement({ + id, + htmlRef, + ...options + }); + } + return () => { + unregisterElement(id); + }; + }, [htmlRef.current]); +} diff --git a/packages/main/src/components/ObjectPageSection/index.tsx b/packages/main/src/components/ObjectPageSection/index.tsx index c770bcf3381..cdde74d2f8d 100644 --- a/packages/main/src/components/ObjectPageSection/index.tsx +++ b/packages/main/src/components/ObjectPageSection/index.tsx @@ -1,10 +1,11 @@ -import { StyleClassHelper } from '@ui5/webcomponents-react-base'; +import { StyleClassHelper, useConsolidatedRef } from '@ui5/webcomponents-react-base'; import React, { forwardRef, ReactNode, ReactNodeArray, RefObject, FC } from 'react'; import { createUseStyles } from 'react-jss'; import { CommonProps } from '../../interfaces/CommonProps'; import { JSSTheme } from '../../interfaces/JSSTheme'; import { EmptyIdPropException } from '../ObjectPage/EmptyIdPropException'; import styles from './ObjectPageSection.jss'; +import { useScrollElement } from '../ObjectPage/scroll/useScrollElement'; export interface ObjectPageSectionPropTypes extends CommonProps { title?: string; @@ -24,20 +25,20 @@ const ObjectPageSection: FC = forwardRef( throw new EmptyIdPropException('ObjectPageSection requires a unique ID property!'); } + const sectionRef: RefObject = useConsolidatedRef(ref); + const htmlId = `ObjectPageSection-${id}`; + + useScrollElement(htmlId, sectionRef, { + spy: true + }); + const titleClasses = StyleClassHelper.of(classes.title); if (titleUppercase) { titleClasses.put(classes.uppercase); } return ( -
+
{title}
diff --git a/packages/main/src/components/ObjectPageSubSection/index.tsx b/packages/main/src/components/ObjectPageSubSection/index.tsx index 2963f44598f..d9d614ad565 100644 --- a/packages/main/src/components/ObjectPageSubSection/index.tsx +++ b/packages/main/src/components/ObjectPageSubSection/index.tsx @@ -1,9 +1,10 @@ -import { fonts, StyleClassHelper } from '@ui5/webcomponents-react-base'; +import { fonts, StyleClassHelper, useConsolidatedRef } from '@ui5/webcomponents-react-base'; import React, { forwardRef, ReactNode, ReactNodeArray, RefObject, FC } from 'react'; import { createUseStyles } from 'react-jss'; import { CommonProps } from '../../interfaces/CommonProps'; import { JSSTheme } from '../../interfaces/JSSTheme'; import { EmptyIdPropException } from '../ObjectPage/EmptyIdPropException'; +import { useScrollElement } from '../ObjectPage/scroll/useScrollElement'; export interface ObjectPageSubSectionPropTypes extends CommonProps { title?: string; @@ -39,6 +40,13 @@ const ObjectPageSubSection: FC = forwardRef( throw new EmptyIdPropException('ObjectPageSubSection requires a unique ID property!'); } + const htmlRef: RefObject = useConsolidatedRef(ref); + const htmlId = `ObjectPageSubSection-${id}`; + + useScrollElement(htmlId, htmlRef, { + spy: false + }); + const classes = useStyles(); const subSectionClassName = StyleClassHelper.of(classes.objectPageSubSection); if (className) { @@ -47,9 +55,9 @@ const ObjectPageSubSection: FC = forwardRef( return (
Date: Thu, 22 Aug 2019 17:20:53 +0200 Subject: [PATCH 4/9] WIP: fix hideHeaderButton positioning on cozy content density --- packages/main/src/components/ObjectPage/index.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/main/src/components/ObjectPage/index.tsx b/packages/main/src/components/ObjectPage/index.tsx index 038be26b239..16a5160977a 100644 --- a/packages/main/src/components/ObjectPage/index.tsx +++ b/packages/main/src/components/ObjectPage/index.tsx @@ -14,7 +14,7 @@ import React, { useRef, useState } from 'react'; -import { createUseStyles } from 'react-jss'; +import { createUseStyles, useTheme } from 'react-jss'; import { CommonProps } from '../../interfaces/CommonProps'; import { JSSTheme } from '../../interfaces/JSSTheme'; import { ObjectPageMode } from '../../lib/ObjectPageMode'; @@ -26,6 +26,7 @@ import { ObjectPageScroller } from './scroll/ObjectPageScroller'; import { Avatar } from '@ui5/webcomponents-react/lib/Avatar'; import { AvatarSize } from '@ui5/webcomponents-react/lib/AvatarSize'; import { AvatarShape } from '@ui5/webcomponents-react/lib/AvatarShape'; +import { ContentDensity } from '../..'; export interface ObjectPagePropTypes extends CommonProps { title?: string; @@ -79,6 +80,7 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp const [expandHeaderActive, setExpandHeaderActive] = useState(false); const [isMounted, setIsMounted] = useState(false); const [collapsedHeader, setCollapsedHeader] = useState(false); + const theme = useTheme(); const objectPage: RefObject = useConsolidatedRef(ref); const fillerDivDomRef: RefObject = useRef(); @@ -201,14 +203,16 @@ const ObjectPage: FC = forwardRef((props: ObjectPagePropTyp const renderHideHeaderButton = () => { if (!showHideHeaderButton) return null; + const { contentDensity } = theme as JSSTheme; + return ( - -
-
-
- -
- - - www.myurl.com - - - - - Address 1 - - - - - Address 2 - - - - - Address 3 - - -
-
+ + +
+
+
-
- - -
- -
  • - - - - - Test 1 - - - - -
  • -
    - -
  • - - - - - Test 2 - - - - -
  • -
    - -
  • - - - - - Test 3 - - - - -
  • -
    - -
  • - - - - - Test 4 - - - - - -
    - - - -
    - - - - - - - - - - SubSection 4.1 - - - - - - - - - - - SubSection 4.2 - - - - - - - - - -
    -
  • -
    - -
  • - - - - - Test 5 +
    +
    +
  • -
    -
    - -
    - -
    -
    -
    - Test 1 -
    +
    -
    -
    - -
    -
    -
    -
    - -
    -
    -
    - Test 2 -
    -
    -
    -
    -
    - Test2 + + + + + +
    +
    +
    +
    +
    +
    +
    + +
    + + + www.myurl.com + + + + + Address 1 + + + + + Address 2 + + + + + Address 3 + + +
    +
    +
    +
    +
    + +
  • + +
    + + Test 1 + +
    +
    +
  • +
    + +
  • + +
    + + Test 2 + +
    +
    +
  • +
    + +
  • + +
    + + Test 3 + +
    +
    +
  • +
    + +
  • + +
    + + Test 4 + +
    +
    + +
    + + + +
    + + + + + +
    + + + SubSection 4.1 + + +
    +
    + +
    + + + SubSection 4.2 + + +
    +
    +
    +
    +
    +
    +
    +
  • +
    + +
  • + +
    + + Test 5 + +
    +
    + +
    + + + +
    + + + + + +
    + + + SubSection 5.1 + + +
    +
    + +
    + + + SubSection 5.2 + + +
    +
    +
    +
    +
    +
    +
    +
  • +
    +
    -
    -
    -
    - -
    -
    -
    - Test 3 -
    -
    -
    -
    - Test1 -
    -
    -
    -
    - -
    -
    -
    - Test 4 -
    -
    -
    -
    -

    - Section 4 -

    - -
    -
    - SubSection 4.1 +
    + +
    +
    +
    + Test 1 +
    -
    - Test 4 SubSection 1 +
    +
    + +
    -
    - - -
    -
    - SubSection 4.2 +
    +
    + +
    +
    +
    + Test 2 +
    -
    - Test 4 SubSection 2 +
    +
    +
    + Test2 +
    +
    -
    - -
    -
    -
    -
    - -
    -
    -
    - Test 5 -
    -
    -
    -
    - -
    -
    - SubSection 5.1 +
    +
    + +
    +
    +
    + Test 3 +
    -
    - Content of SubSection 5.1 +
    +
    + Test1 +
    -
    - - -
    -
    - SubSection 5.2 +
    +
    + +
    +
    +
    + Test 4 +
    -
    - Content of SubSection 5.2 +
    +
    +

    + Section 4 +

    + +
    +
    + SubSection 4.1 +
    +
    + Test 4 SubSection 1 +
    +
    +
    + +
    +
    + SubSection 4.2 +
    +
    + Test 4 SubSection 2 +
    +
    +
    +
    -
    - -
    + + + +
    +
    +
    + Test 5 +
    +
    +
    +
    + +
    +
    + SubSection 5.1 +
    +
    + Content of SubSection 5.1 +
    +
    +
    + +
    +
    + SubSection 5.2 +
    +
    + Content of SubSection 5.2 +
    +
    +
    +
    +
    +
    +
    + +
    - - -
    - - +
    +
    + +
    @@ -338,155 +336,165 @@
    - -
    -
    - -

    - Fiori Object Page Title -

    - - Sub Title - -
    - - - -
    -
    -
    - -
    - - - www.myurl.com - - - - - Address 1 - - - - - Address 2 - - - - - Address 3 - - -
    -
    + + +
    +
    +
    -
    -
    -
    - -
  • - - - - - Test 1 - - - - -
  • -
    - -
  • - - - - - Test 2 - - - - -
  • -
    - -
  • - - - - - Test 3 +
    +
    +
  • -
    -
    - -
    - -
    -
    -
    - Test 1 -
    -
    -
    -
    - -
    -
    -
    -
    - -
    -
    -
    - Test 2 -
    +
    -
    -
    - -
    -
    -
    -
    - -
    -
    -
    - Test 3 -
    -
    -
    -
    - + + + + + +
    +
    +
    +
    +
    +
    +
    + +
    + + + www.myurl.com + + + + + Address 1 + + + + + Address 2 + + + + + Address 3 + + +
    +
    +
    +
    +
    + +
  • + +
    + + Test 1 + +
    +
    +
  • +
    + +
  • + +
    + + Test 2 + +
    +
    +
  • +
    + +
  • + +
    + + Test 3 + +
    +
    +
  • +
    +
    +
    + +
    +
    +
    + Test 1 +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    + Test 2 +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    + Test 3 +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    -
    -
    -
    -
    -
    +
    +
    + + @@ -502,168 +510,184 @@
    - -
    -
    - -

    - Fiori Object Page Title -

    - - Sub Title - -
    - - - -
    -
    -
    - -
    - - - www.myurl.com - - - - - Address 1 - - - - - Address 2 - - - - - Address 3 - - -
    -
    + + +
    +
    +
    -
    -
    -
    -
    - -
  • - - Test 1 - -
  • -
    - -
  • - - Test 2 - -
  • -
    - -
  • - - Test 3 - -
  • -
    - -
  • - - Test 4 - - -
    - - - -
    - - - - - - - SubSection 4.1 - - - - - SubSection 4.2 - - - - - - -
    -
  • -
    - -
  • - - Test 5 - - -
    - - - -
    - - - - - - - SubSection 5.1 - - - - - SubSection 5.2 - - - - - - -
    -
  • -
    -
    - -
    - -
    -
    -
    - Test 1 -
    +
    +
    +
    + +

    + Fiori Object Page Title +

    + + Sub Title + +
    -
    -
    - + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + www.myurl.com + + + + + Address 1 + + + + + Address 2 + + + + + Address 3 + + +
    +
    +
    + +
    +
    + +
  • + + Test 1 + +
  • +
    + +
  • + + Test 2 + +
  • +
    + +
  • + + Test 3 + +
  • +
    + +
  • + + Test 4 + + +
    + + + +
    + + + + + + + SubSection 4.1 + + + + + SubSection 4.2 + + + + + + +
    +
  • +
    + +
  • + + Test 5 + + +
    + + + +
    + + + + + + + SubSection 5.1 + + + + + SubSection 5.2 + + + + + + +
    +
  • +
    +
    +
    + +
    +
    +
    + Test 1 +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    -
    -
    -
    -
    -
    +
    + + +
    @@ -674,7 +698,7 @@ #### `Just Some Sections` ``` -

    Test
    +
    Test
    ``` #### `Not crashing with 1 section - Default Mode` @@ -685,50 +709,64 @@
    - -
    -
    - -

    - - - -

    -
    -
    + + +
    +
    +
    +
    -
    -
    -
    - -
  • - - - - - - - -
  • -
    -
    - -
    - -
    -
    -
    +
    +
    +
    + +

    + +

    -
    -
    - Test + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
  • + +
    + +
    +
    +
  • +
    +
    +
    + +
    +
    +
    +
    +
    +
    + Test +
    +
    +
    +
    +
    +
    -
    -
    -
    -
    -
    +
    + + +
    @@ -744,44 +782,60 @@
    - -
    -
    - -

    - - - -

    -
    -
    + + +
    +
    +
    +
    -
    -
    -
    - -
  • - -
  • -
    -
    - -
    - -
    -
    -
    +
    +
    +
    + +

    + +

    -
    -
    - Test + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
  • + +
  • +
    +
    +
    + +
    +
    +
    +
    +
    +
    + Test +
    +
    +
    +
    +
    +
    -
    -
    -
    -
    -
    +
    + + +
    @@ -797,26 +851,41 @@
    - -
    -
    - -

    - - - + + +
    +
    +
    +
    +
    +
    +
    +
    + +

    + + +

    + +
    -
    -
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    -

    - -
    - -
    -
    -
    -
    + +
    @@ -832,49 +901,65 @@
    - -
    -
    - -

    - - - -

    -
    -
    + + +
    +
    +
    +
    -
    -
    -
    - -
  • - -
  • -
    - -
  • - -
  • -
    -
    - -
    - -
    -
    -
    +
    +
    +
    + +

    + +

    -
    -
    - Test 2 + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
  • + +
  • +
    + +
  • + +
  • +
    +
    +
    + +
    +
    +
    +
    +
    +
    + Test 2 +
    +
    +
    +
    +
    +
    -
    -
    -
    -
    -
    +
    + + +
    @@ -890,59 +975,72 @@
    -
    - -
  • - - - - - - - -
  • -
    - -
  • - - - - - - - -
  • -
    -
    - -
    - -
    -
    -
    -
    -
    -
    - Test -
    -
    + + +
    +
    +
    +
    +
    +
    +
    + +
  • + +
    + +
    +
    +
  • +
    + +
  • + +
    + +
    +
    +
  • +
    - - -
    -
    -
    -
    -
    -
    - Test 2 -
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + Test +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + Test 2 +
    +
    +
    +
    +
    +
    -
    -
    -
    -
    -
    +
    + + +
    diff --git a/packages/main/__karma_snapshots__/Option.md b/packages/main/__karma_snapshots__/Option.md index 0872e9d94ac..41fb5b79255 100644 --- a/packages/main/__karma_snapshots__/Option.md +++ b/packages/main/__karma_snapshots__/Option.md @@ -3,8 +3,8 @@ #### `Basic Test (generated)` ``` - - + +