From 3fef1463214548839bc14bffed4c49bc826c59c2 Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Fri, 29 Sep 2023 13:04:09 +0300 Subject: [PATCH 01/15] feat: aside header top block --- .../AsideHeader/AsideHeader.old.tsx | 70 +++++++++++++++++++ .../__stories__/AsideHeader.stories.tsx | 17 +++++ .../__stories__/AsideHeaderShowcase.tsx | 9 ++- .../AsideHeader/components/FirstPanel.tsx | 11 ++- .../AsideHeader/components/TopPanel.tsx | 27 +++++++ .../AsideHeader/components/index.ts | 1 + src/components/AsideHeader/types.tsx | 9 ++- src/components/Content/Content.tsx | 13 ++-- src/components/types.ts | 11 ++- 9 files changed, 157 insertions(+), 11 deletions(-) create mode 100644 src/components/AsideHeader/AsideHeader.old.tsx create mode 100644 src/components/AsideHeader/components/TopPanel.tsx diff --git a/src/components/AsideHeader/AsideHeader.old.tsx b/src/components/AsideHeader/AsideHeader.old.tsx new file mode 100644 index 0000000..72387b0 --- /dev/null +++ b/src/components/AsideHeader/AsideHeader.old.tsx @@ -0,0 +1,70 @@ +import React from 'react'; +import debounceFn from 'lodash/debounce'; + +import {Content} from '../Content'; + +import {AsideHeaderContextProvider, AsideHeaderInnerContextProvider} from './AsideHeaderContext'; +import {AsideHeaderProps} from './types'; + +import {FirstPanel, TopPanel} from './components'; +import {b} from './utils'; + +import './AsideHeader.scss'; +import {ASIDE_HEADER_COMPACT_WIDTH, ASIDE_HEADER_EXPANDED_WIDTH} from '../constants'; +import {useAsideHeaderInnerContextValue} from './useAsideHeaderInnerContextValue'; + +export const AsideHeader = React.forwardRef((props, ref) => { + const {className, compact, topAlert} = props; + const size = compact ? ASIDE_HEADER_COMPACT_WIDTH : ASIDE_HEADER_EXPANDED_WIDTH; + const asideHeaderContextValue = React.useMemo(() => ({size, compact}), [compact, size]); + const asideHeaderInnerContextValue = useAsideHeaderInnerContextValue({...props, size}); + + const topRef = React.useRef(null); + + const [maxHeightWithTop, setMaxHeightWithTop] = React.useState(); + const topHeight = topRef.current ? topRef.current.clientHeight : 0; + + React.useLayoutEffect(() => { + const updateTopSize = debounceFn( + () => { + if (topRef.current) { + setMaxHeightWithTop(`calc(100vh - ${topRef.current.clientHeight}px)`); + } + }, + 200, + {leading: true}, + ); + if (topAlert) { + window.addEventListener('resize', updateTopSize); + updateTopSize(); + } + return () => window.removeEventListener('resize', updateTopSize); + }, [topAlert, topRef, topHeight]); + + return ( + + +
+ {/* Top Panel */} + {topAlert && } +
+ {/* First Panel */} + + {/* Second Panel */} + +
+
+
+
+ ); +}); diff --git a/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx b/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx index 62fb07d..d01f597 100644 --- a/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx +++ b/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx @@ -1,6 +1,7 @@ import React from 'react'; import type {Meta, StoryFn} from '@storybook/react'; +import {Alert} from '@gravity-ui/uikit'; import {AsideHeader} from '../AsideHeader'; import {AsideHeaderShowcase} from './AsideHeaderShowcase'; @@ -58,3 +59,19 @@ AdvancedUsage.args = { multipleTooltip: false, initialCompact: true, }; + +const TopAlertTemplate: StoryFn = (args) => ; +export const HeaderAlert = TopAlertTemplate.bind({}); +HeaderAlert.args = { + topAlert: { + title: 'Maintenance', + view: 'filled', + message: 'Scheduled maintenance is being performed', + actions: [ + { + text: 'More...', + handler: () => alert('More information about top alert'), + }, + ], + }, +}; diff --git a/src/components/AsideHeader/__stories__/AsideHeaderShowcase.tsx b/src/components/AsideHeader/__stories__/AsideHeaderShowcase.tsx index 4033bd0..71464a0 100644 --- a/src/components/AsideHeader/__stories__/AsideHeaderShowcase.tsx +++ b/src/components/AsideHeader/__stories__/AsideHeaderShowcase.tsx @@ -1,4 +1,4 @@ -import React, {FC, useState} from 'react'; +import React, {FC} from 'react'; import { Button, @@ -11,7 +11,7 @@ import { } from '@gravity-ui/uikit'; import {Bug, Gear, Magnifier} from '@gravity-ui/icons'; -import {AsideHeader, FooterItem} from '../..'; +import {AsideHeader, FooterItem, AsideHeaderTopAlertProps} from '../..'; import {cn} from '../../utils/cn'; import {menuItemsShowcase, text as placeholderText} from './moc'; import {MenuItem, OpenModalSubscriber} from '../../types'; @@ -38,11 +38,13 @@ enum Panel { interface AsideHeaderShowcaseProps { multipleTooltip?: boolean; initialCompact?: boolean; + topAlert?: AsideHeaderTopAlertProps; } export const AsideHeaderShowcase: FC = ({ multipleTooltip = false, initialCompact = false, + topAlert, }) => { const ref = React.useRef(null); const [popupVisible, setPopupVisible] = React.useState(false); @@ -64,7 +66,7 @@ export const AsideHeaderShowcase: FC = ({ }); }; - const [menuItems, setMenuItems] = useState([ + const [menuItems, setMenuItems] = React.useState([ ...menuItemsShowcase, { id: 'components', @@ -138,6 +140,7 @@ export const AsideHeaderShowcase: FC = ({ compact={compact} multipleTooltip={multipleTooltip} openModalSubscriber={openModalSubscriber} + topAlert={topAlert} renderFooter={({compact, asideRef}) => ( ((_props, ref) => { +export const FirstPanel = React.forwardRef((props, ref) => { const { size, onItemClick, @@ -25,13 +25,20 @@ export const FirstPanel = React.forwardRef((_props, ref) => { const asideRef = useRef(null); + const {maxHeight} = props; + const style: React.CSSProperties = {width: size}; + + if (maxHeight) { + style.maxHeight = maxHeight; + } + React.useEffect(() => { setRef(ref, asideRef.current); }, [ref]); return ( <> -
+
diff --git a/src/components/AsideHeader/components/TopPanel.tsx b/src/components/AsideHeader/components/TopPanel.tsx new file mode 100644 index 0000000..e6d675d --- /dev/null +++ b/src/components/AsideHeader/components/TopPanel.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import {Alert} from '@gravity-ui/uikit'; + +import {useAsideHeaderInnerContext} from '../AsideHeaderContext'; +import {b} from '../utils'; + +export const TopPanel = React.forwardRef((_, ref) => { + const {topAlert} = useAsideHeaderInnerContext(); + + if (!topAlert) { + return null; + } + + return ( +
+ +
+ ); +}); diff --git a/src/components/AsideHeader/components/index.ts b/src/components/AsideHeader/components/index.ts index 6b3499c..90c9941 100644 --- a/src/components/AsideHeader/components/index.ts +++ b/src/components/AsideHeader/components/index.ts @@ -1 +1,2 @@ export {FirstPanel} from './FirstPanel'; +export {TopPanel} from './TopPanel'; diff --git a/src/components/AsideHeader/types.tsx b/src/components/AsideHeader/types.tsx index cb65754..45d21da 100644 --- a/src/components/AsideHeader/types.tsx +++ b/src/components/AsideHeader/types.tsx @@ -1,6 +1,12 @@ import {RenderContentType} from '../Content'; import {DrawerItemProps} from '../Drawer/Drawer'; -import {LogoProps, MenuItem, SubheaderMenuItem, OpenModalSubscriber} from '../types'; +import { + LogoProps, + MenuItem, + SubheaderMenuItem, + OpenModalSubscriber, + AsideHeaderTopAlertProps, +} from '../types'; import {AsideHeaderContextType} from './AsideHeaderContext'; export interface LayoutProps { @@ -16,6 +22,7 @@ export interface AsideHeaderGeneralProps { collapseTitle?: string; expandTitle?: string; menuMoreTitle?: string; + topAlert?: AsideHeaderTopAlertProps; renderContent?: RenderContentType; renderFooter?: (data: { size: number; diff --git a/src/components/Content/Content.tsx b/src/components/Content/Content.tsx index be24541..1f3b954 100644 --- a/src/components/Content/Content.tsx +++ b/src/components/Content/Content.tsx @@ -8,6 +8,7 @@ export interface ContentProps { size: number; className?: string; cssSizeVariableName?: string; + maxHeight?: string; renderContent?: RenderContentType; } @@ -25,15 +26,19 @@ RenderContent.displayName = 'RenderContent'; export const Content: React.FC = ({ size, // TODO: move to context when MobileHeader will support it className, + maxHeight, cssSizeVariableName = '--gn-aside-header-size', renderContent, children, }) => { + const style: React.CSSProperties = {[cssSizeVariableName]: `${size}px`}; + if (maxHeight) { + style.maxHeight = maxHeight; + style.overflowY = 'auto'; + } + return ( -
+
{typeof renderContent === 'function' ? ( ) : ( diff --git a/src/components/types.ts b/src/components/types.ts index 51be84b..6605985 100644 --- a/src/components/types.ts +++ b/src/components/types.ts @@ -1,5 +1,5 @@ import React from 'react'; -import {IconProps} from '@gravity-ui/uikit'; +import {IconProps, AlertProps} from '@gravity-ui/uikit'; import {ItemProps} from 'src/components/CompositeBar/Item/Item'; @@ -67,3 +67,12 @@ export interface LogoProps { wrapper?: (node: React.ReactNode, compact: boolean) => React.ReactNode; onClick?: (event: React.MouseEvent) => void; } + +export type AsideHeaderTopAlertProps = { + message: AlertProps['message']; + title?: AlertProps['title']; + icon?: AlertProps['icon']; + view?: AlertProps['view']; + theme?: AlertProps['theme']; + actions?: AlertProps['actions']; +}; From fccba6b650b698d1bddf5026b938858e8df58058 Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Mon, 2 Oct 2023 16:01:21 +0300 Subject: [PATCH 02/15] fix: fix top aside header logic for use static alert --- src/components/AsideHeader/__stories__/AsideHeader.stories.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx b/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx index d01f597..10cfb7c 100644 --- a/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx +++ b/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx @@ -1,7 +1,6 @@ import React from 'react'; import type {Meta, StoryFn} from '@storybook/react'; -import {Alert} from '@gravity-ui/uikit'; import {AsideHeader} from '../AsideHeader'; import {AsideHeaderShowcase} from './AsideHeaderShowcase'; From e5c736386ded6e92ba1941a48a27d0d913ced252 Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Tue, 17 Oct 2023 16:48:43 +0300 Subject: [PATCH 03/15] fix: add divider to top alert --- src/components/AsideHeader/AsideHeader.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/AsideHeader/AsideHeader.scss b/src/components/AsideHeader/AsideHeader.scss index a403647..ed5191c 100644 --- a/src/components/AsideHeader/AsideHeader.scss +++ b/src/components/AsideHeader/AsideHeader.scss @@ -192,6 +192,10 @@ $block: '.#{variables.$ns}aside-header'; flex-direction: row; } + &__pane-top { + border-bottom: 1px solid var(--gn-aside-header-collapse-button-divider-line-color); + } + &_reverse #{$block}__pane-container { flex-direction: row-reverse; } From d4a3e7653bf83caf7fc5dc99b8238ba1daa18a8a Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Thu, 26 Oct 2023 15:42:11 +0300 Subject: [PATCH 04/15] feat: add centered and closable props --- src/components/AsideHeader/AsideHeader.scss | 11 ++++++- .../__stories__/AsideHeader.stories.tsx | 16 ++++++---- .../AsideHeader/components/TopPanel.tsx | 30 ++++++++++++------- src/components/types.ts | 2 ++ 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/components/AsideHeader/AsideHeader.scss b/src/components/AsideHeader/AsideHeader.scss index ed5191c..7906639 100644 --- a/src/components/AsideHeader/AsideHeader.scss +++ b/src/components/AsideHeader/AsideHeader.scss @@ -193,7 +193,16 @@ $block: '.#{variables.$ns}aside-header'; } &__pane-top { - border-bottom: 1px solid var(--gn-aside-header-collapse-button-divider-line-color); + &_opened { + border-bottom: 1px solid var(--gn-aside-header-collapse-button-divider-line-color); + } + } + + &__pane-top-alert { + &_centered { + display: flex; + justify-content: space-around; + } } &_reverse #{$block}__pane-container { diff --git a/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx b/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx index 10cfb7c..6b090be 100644 --- a/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx +++ b/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx @@ -66,11 +66,15 @@ HeaderAlert.args = { title: 'Maintenance', view: 'filled', message: 'Scheduled maintenance is being performed', - actions: [ - { - text: 'More...', - handler: () => alert('More information about top alert'), - }, - ], + closable: true, + }, +}; + +export const HeaderAlertCentered = TopAlertTemplate.bind({}); +HeaderAlertCentered.args = { + topAlert: { + view: 'filled', + message: 'Scheduled maintenance is being performed', + centered: true, }, }; diff --git a/src/components/AsideHeader/components/TopPanel.tsx b/src/components/AsideHeader/components/TopPanel.tsx index e6d675d..42ae673 100644 --- a/src/components/AsideHeader/components/TopPanel.tsx +++ b/src/components/AsideHeader/components/TopPanel.tsx @@ -7,21 +7,31 @@ import {b} from '../utils'; export const TopPanel = React.forwardRef((_, ref) => { const {topAlert} = useAsideHeaderInnerContext(); + const [opened, setOpened] = React.useState(true); + + const handleClose = React.useCallback(() => { + setOpened(false); + }, []); + if (!topAlert) { return null; } return ( -
- +
+ {opened && ( + + )}
); }); diff --git a/src/components/types.ts b/src/components/types.ts index 6605985..5e77154 100644 --- a/src/components/types.ts +++ b/src/components/types.ts @@ -75,4 +75,6 @@ export type AsideHeaderTopAlertProps = { view?: AlertProps['view']; theme?: AlertProps['theme']; actions?: AlertProps['actions']; + closable?: boolean; + centered?: boolean; }; From 6e9e767f12ef42cf13f19e0f026777e831ff0657 Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Fri, 27 Oct 2023 18:30:41 +0300 Subject: [PATCH 05/15] fix: divider color with alpha chanel --- src/components/AsideHeader/AsideHeader.scss | 8 ++-- .../AsideHeader/components/TopPanel.tsx | 37 +++++++++++++------ 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/components/AsideHeader/AsideHeader.scss b/src/components/AsideHeader/AsideHeader.scss index 7906639..dd24ae1 100644 --- a/src/components/AsideHeader/AsideHeader.scss +++ b/src/components/AsideHeader/AsideHeader.scss @@ -192,10 +192,10 @@ $block: '.#{variables.$ns}aside-header'; flex-direction: row; } - &__pane-top { - &_opened { - border-bottom: 1px solid var(--gn-aside-header-collapse-button-divider-line-color); - } + &__pane-top-divider { + height: 1px; + background-color: var(--gn-aside-header-collapse-button-divider-line-color); + margin-top: -1px; } &__pane-top-alert { diff --git a/src/components/AsideHeader/components/TopPanel.tsx b/src/components/AsideHeader/components/TopPanel.tsx index 42ae673..b0a6454 100644 --- a/src/components/AsideHeader/components/TopPanel.tsx +++ b/src/components/AsideHeader/components/TopPanel.tsx @@ -4,7 +4,11 @@ import {Alert} from '@gravity-ui/uikit'; import {useAsideHeaderInnerContext} from '../AsideHeaderContext'; import {b} from '../utils'; -export const TopPanel = React.forwardRef((_, ref) => { +type Props = { + onClose: () => void; +}; + +export const TopPanel = React.forwardRef(({onClose}, ref) => { const {topAlert} = useAsideHeaderInnerContext(); const [opened, setOpened] = React.useState(true); @@ -13,6 +17,12 @@ export const TopPanel = React.forwardRef((_, ref) => { setOpened(false); }, []); + React.useEffect(() => { + if (!opened) { + onClose(); + } + }, [opened, onClose]); + if (!topAlert) { return null; } @@ -20,17 +30,20 @@ export const TopPanel = React.forwardRef((_, ref) => { return (
{opened && ( - + + +
+
)}
); From a1929bd094d7ad7558e8ec3d8a468d947a29fb6b Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Wed, 8 Nov 2023 15:30:27 +0300 Subject: [PATCH 06/15] fix: refactor top alert with new layout scheme --- .../AsideHeader/AsideHeader.old.tsx | 70 ------------------- src/components/AsideHeader/AsideHeader.tsx | 20 ++++-- .../components/PageLayout/PageLayout.tsx | 26 +++++-- .../components/PageLayout/PageLayoutAside.tsx | 10 ++- .../AsideHeader/components/TopPanel.tsx | 11 ++- src/components/AsideHeader/types.tsx | 3 + .../AsideHeader/useAsideHeaderTopPanel.tsx | 35 ++++++++++ 7 files changed, 86 insertions(+), 89 deletions(-) delete mode 100644 src/components/AsideHeader/AsideHeader.old.tsx create mode 100644 src/components/AsideHeader/useAsideHeaderTopPanel.tsx diff --git a/src/components/AsideHeader/AsideHeader.old.tsx b/src/components/AsideHeader/AsideHeader.old.tsx deleted file mode 100644 index 72387b0..0000000 --- a/src/components/AsideHeader/AsideHeader.old.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import React from 'react'; -import debounceFn from 'lodash/debounce'; - -import {Content} from '../Content'; - -import {AsideHeaderContextProvider, AsideHeaderInnerContextProvider} from './AsideHeaderContext'; -import {AsideHeaderProps} from './types'; - -import {FirstPanel, TopPanel} from './components'; -import {b} from './utils'; - -import './AsideHeader.scss'; -import {ASIDE_HEADER_COMPACT_WIDTH, ASIDE_HEADER_EXPANDED_WIDTH} from '../constants'; -import {useAsideHeaderInnerContextValue} from './useAsideHeaderInnerContextValue'; - -export const AsideHeader = React.forwardRef((props, ref) => { - const {className, compact, topAlert} = props; - const size = compact ? ASIDE_HEADER_COMPACT_WIDTH : ASIDE_HEADER_EXPANDED_WIDTH; - const asideHeaderContextValue = React.useMemo(() => ({size, compact}), [compact, size]); - const asideHeaderInnerContextValue = useAsideHeaderInnerContextValue({...props, size}); - - const topRef = React.useRef(null); - - const [maxHeightWithTop, setMaxHeightWithTop] = React.useState(); - const topHeight = topRef.current ? topRef.current.clientHeight : 0; - - React.useLayoutEffect(() => { - const updateTopSize = debounceFn( - () => { - if (topRef.current) { - setMaxHeightWithTop(`calc(100vh - ${topRef.current.clientHeight}px)`); - } - }, - 200, - {leading: true}, - ); - if (topAlert) { - window.addEventListener('resize', updateTopSize); - updateTopSize(); - } - return () => window.removeEventListener('resize', updateTopSize); - }, [topAlert, topRef, topHeight]); - - return ( - - -
- {/* Top Panel */} - {topAlert && } -
- {/* First Panel */} - - {/* Second Panel */} - -
-
-
-
- ); -}); diff --git a/src/components/AsideHeader/AsideHeader.tsx b/src/components/AsideHeader/AsideHeader.tsx index 97246d6..41a6abb 100644 --- a/src/components/AsideHeader/AsideHeader.tsx +++ b/src/components/AsideHeader/AsideHeader.tsx @@ -3,6 +3,7 @@ import React from 'react'; import {AsideHeaderProps} from './types'; import {PageLayout} from './components/PageLayout/PageLayout'; import {PageLayoutAside} from './components/PageLayout/PageLayoutAside'; +import {useAsideHeaderTopPanel} from './useAsideHeaderTopPanel'; /** * Simply usage of AsideHeader: @@ -20,11 +21,22 @@ import {PageLayoutAside} from './components/PageLayout/PageLayoutAside'; * */ export const AsideHeader = React.forwardRef( - ({compact, className, ...props}, ref) => { + ({compact, className, topAlert, ...props}, ref) => { + const {topRef, maxHeightWithTop, updateTopSize} = useAsideHeaderTopPanel({topAlert}); + return ( - - - + + + ); }, diff --git a/src/components/AsideHeader/components/PageLayout/PageLayout.tsx b/src/components/AsideHeader/components/PageLayout/PageLayout.tsx index 449b89a..d2985f8 100644 --- a/src/components/AsideHeader/components/PageLayout/PageLayout.tsx +++ b/src/components/AsideHeader/components/PageLayout/PageLayout.tsx @@ -1,6 +1,7 @@ import React, {PropsWithChildren, useMemo} from 'react'; import {AsideHeaderContextProvider, useAsideHeaderContext} from '../../AsideHeaderContext'; import {Content, ContentProps} from '../../../Content'; +import {TopPanel} from '..'; import {ASIDE_HEADER_COMPACT_WIDTH, ASIDE_HEADER_EXPANDED_WIDTH} from '../../../constants'; import {LayoutProps} from '../../types'; import {b} from '../../utils'; @@ -11,7 +12,15 @@ export interface PageLayoutProps extends PropsWithChildren { reverse?: boolean; } -const Layout = ({compact, reverse, className, children}: PageLayoutProps) => { +const Layout = ({ + compact, + reverse, + className, + children, + topAlert, + updateTopSize, + topRef, +}: PageLayoutProps) => { const size = compact ? ASIDE_HEADER_COMPACT_WIDTH : ASIDE_HEADER_EXPANDED_WIDTH; const asideHeaderContextValue = useMemo(() => ({size, compact}), [compact, size]); @@ -23,20 +32,25 @@ const Layout = ({compact, reverse, className, children}: PageLayoutProps) => { ...({'--gn-aside-header-size': `${size}px`} as React.CSSProperties), }} > + {topAlert && }
{children}
); }; -const ConnectedContent: React.FC>> = ({ - children, - renderContent, -}) => { +const ConnectedContent: React.FC< + PropsWithChildren> +> = ({children, renderContent, maxHeight}) => { const {size} = useAsideHeaderContext(); return ( - + {children} ); diff --git a/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx b/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx index 29c91e2..1002ae5 100644 --- a/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx +++ b/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx @@ -4,16 +4,20 @@ import {useAsideHeaderInnerContextValue} from '../../useAsideHeaderInnerContextV import {AsideHeaderInnerContextProvider, useAsideHeaderContext} from '../../AsideHeaderContext'; import {AsideHeaderProps} from '../../types'; -type Props = Omit; +type Props = Omit & {maxHeight?: string}; export const PageLayoutAside = React.forwardRef((props, ref) => { const {size, compact} = useAsideHeaderContext(); - const asideHeaderInnerContextValue = useAsideHeaderInnerContextValue({size, compact, ...props}); + const asideHeaderInnerContextValue = useAsideHeaderInnerContextValue({ + size, + compact, + ...props, + }); return ( - + ); }); diff --git a/src/components/AsideHeader/components/TopPanel.tsx b/src/components/AsideHeader/components/TopPanel.tsx index b0a6454..02757a4 100644 --- a/src/components/AsideHeader/components/TopPanel.tsx +++ b/src/components/AsideHeader/components/TopPanel.tsx @@ -1,16 +1,15 @@ import React from 'react'; import {Alert} from '@gravity-ui/uikit'; -import {useAsideHeaderInnerContext} from '../AsideHeaderContext'; import {b} from '../utils'; +import {AsideHeaderTopAlertProps} from '../../types'; type Props = { - onClose: () => void; + topAlert?: AsideHeaderTopAlertProps; + onClose?: () => void; }; -export const TopPanel = React.forwardRef(({onClose}, ref) => { - const {topAlert} = useAsideHeaderInnerContext(); - +export const TopPanel = React.forwardRef(({topAlert, onClose}, ref) => { const [opened, setOpened] = React.useState(true); const handleClose = React.useCallback(() => { @@ -19,7 +18,7 @@ export const TopPanel = React.forwardRef(({onClose}, ref) React.useEffect(() => { if (!opened) { - onClose(); + onClose?.(); } }, [opened, onClose]); diff --git a/src/components/AsideHeader/types.tsx b/src/components/AsideHeader/types.tsx index 45d21da..cf9c608 100644 --- a/src/components/AsideHeader/types.tsx +++ b/src/components/AsideHeader/types.tsx @@ -12,6 +12,9 @@ import {AsideHeaderContextType} from './AsideHeaderContext'; export interface LayoutProps { compact: boolean; className?: string; + topRef?: React.RefObject; + topAlert?: AsideHeaderTopAlertProps; + updateTopSize?: () => void; } export interface AsideHeaderGeneralProps { diff --git a/src/components/AsideHeader/useAsideHeaderTopPanel.tsx b/src/components/AsideHeader/useAsideHeaderTopPanel.tsx new file mode 100644 index 0000000..25eb232 --- /dev/null +++ b/src/components/AsideHeader/useAsideHeaderTopPanel.tsx @@ -0,0 +1,35 @@ +import React from 'react'; + +import debounceFn from 'lodash/debounce'; +import {AsideHeaderTopAlertProps} from '../types'; + +export const useAsideHeaderTopPanel = ({topAlert}: {topAlert?: AsideHeaderTopAlertProps}) => { + const topRef = React.useRef(null); + + const [maxHeightWithTop, setMaxHeightWithTop] = React.useState(); + const topHeight = topRef.current ? topRef.current.clientHeight : 0; + + const updateTopSize = React.useCallback(() => { + if (topRef.current || maxHeightWithTop) { + const clientHeight = topRef.current?.clientHeight || 0; + + setMaxHeightWithTop(`calc(100vh - ${clientHeight}px)`); + } + }, [maxHeightWithTop]); + + React.useLayoutEffect(() => { + const updateTopSizeDebounce = debounceFn(updateTopSize, 200, {leading: true}); + + if (topAlert) { + window.addEventListener('resize', updateTopSizeDebounce); + updateTopSizeDebounce(); + } + return () => window.removeEventListener('resize', updateTopSizeDebounce); + }, [topAlert, topRef, topHeight, updateTopSize]); + + return { + topRef, + maxHeightWithTop, + updateTopSize, + }; +}; From fec3a004617fefcb70929986e4f68503902c97b8 Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Thu, 9 Nov 2023 13:44:50 +0300 Subject: [PATCH 07/15] fix: fix topAlert props passing --- src/components/AsideHeader/AsideHeader.scss | 5 ++++ src/components/AsideHeader/AsideHeader.tsx | 17 +++--------- .../components/PageLayout/PageLayout.tsx | 12 ++------- .../AsideHeader/components/TopPanel.tsx | 16 ++++++----- src/components/AsideHeader/types.tsx | 2 -- .../AsideHeader/useAsideHeaderTopPanel.tsx | 27 +++++++++++++------ src/components/types.ts | 4 +++ 7 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/components/AsideHeader/AsideHeader.scss b/src/components/AsideHeader/AsideHeader.scss index dd24ae1..cf287c5 100644 --- a/src/components/AsideHeader/AsideHeader.scss +++ b/src/components/AsideHeader/AsideHeader.scss @@ -203,6 +203,11 @@ $block: '.#{variables.$ns}aside-header'; display: flex; justify-content: space-around; } + + &_dense { + padding-top: var(--g-spacing-2); + padding-bottom: var(--g-spacing-2); + } } &_reverse #{$block}__pane-container { diff --git a/src/components/AsideHeader/AsideHeader.tsx b/src/components/AsideHeader/AsideHeader.tsx index 41a6abb..0a422c6 100644 --- a/src/components/AsideHeader/AsideHeader.tsx +++ b/src/components/AsideHeader/AsideHeader.tsx @@ -22,21 +22,12 @@ import {useAsideHeaderTopPanel} from './useAsideHeaderTopPanel'; */ export const AsideHeader = React.forwardRef( ({compact, className, topAlert, ...props}, ref) => { - const {topRef, maxHeightWithTop, updateTopSize} = useAsideHeaderTopPanel({topAlert}); + const {maxHeight, ...topAlertValue} = useAsideHeaderTopPanel({topAlert}); return ( - - - + + + ); }, diff --git a/src/components/AsideHeader/components/PageLayout/PageLayout.tsx b/src/components/AsideHeader/components/PageLayout/PageLayout.tsx index d2985f8..f51c7f1 100644 --- a/src/components/AsideHeader/components/PageLayout/PageLayout.tsx +++ b/src/components/AsideHeader/components/PageLayout/PageLayout.tsx @@ -12,15 +12,7 @@ export interface PageLayoutProps extends PropsWithChildren { reverse?: boolean; } -const Layout = ({ - compact, - reverse, - className, - children, - topAlert, - updateTopSize, - topRef, -}: PageLayoutProps) => { +const Layout = ({compact, reverse, className, children, topAlert}: PageLayoutProps) => { const size = compact ? ASIDE_HEADER_COMPACT_WIDTH : ASIDE_HEADER_EXPANDED_WIDTH; const asideHeaderContextValue = useMemo(() => ({size, compact}), [compact, size]); @@ -32,7 +24,7 @@ const Layout = ({ ...({'--gn-aside-header-size': `${size}px`} as React.CSSProperties), }} > - {topAlert && } + {topAlert && }
{children}
diff --git a/src/components/AsideHeader/components/TopPanel.tsx b/src/components/AsideHeader/components/TopPanel.tsx index 02757a4..9d5c59d 100644 --- a/src/components/AsideHeader/components/TopPanel.tsx +++ b/src/components/AsideHeader/components/TopPanel.tsx @@ -6,10 +6,9 @@ import {AsideHeaderTopAlertProps} from '../../types'; type Props = { topAlert?: AsideHeaderTopAlertProps; - onClose?: () => void; }; -export const TopPanel = React.forwardRef(({topAlert, onClose}, ref) => { +export const TopPanel = React.forwardRef(({topAlert}) => { const [opened, setOpened] = React.useState(true); const handleClose = React.useCallback(() => { @@ -18,20 +17,23 @@ export const TopPanel = React.forwardRef(({topAlert, onCl React.useEffect(() => { if (!opened) { - onClose?.(); + topAlert?.onCloseTopAlert?.(); } - }, [opened, onClose]); + }, [opened, topAlert]); - if (!topAlert) { + if (!topAlert || !topAlert.message) { return null; } return ( -
+
{opened && ( ; topAlert?: AsideHeaderTopAlertProps; - updateTopSize?: () => void; } export interface AsideHeaderGeneralProps { diff --git a/src/components/AsideHeader/useAsideHeaderTopPanel.tsx b/src/components/AsideHeader/useAsideHeaderTopPanel.tsx index 25eb232..f0de09a 100644 --- a/src/components/AsideHeader/useAsideHeaderTopPanel.tsx +++ b/src/components/AsideHeader/useAsideHeaderTopPanel.tsx @@ -3,19 +3,28 @@ import React from 'react'; import debounceFn from 'lodash/debounce'; import {AsideHeaderTopAlertProps} from '../types'; -export const useAsideHeaderTopPanel = ({topAlert}: {topAlert?: AsideHeaderTopAlertProps}) => { +export const useAsideHeaderTopPanel = ({ + topAlert, +}: { + topAlert?: AsideHeaderTopAlertProps; +}): AsideHeaderTopAlertProps => { const topRef = React.useRef(null); - const [maxHeightWithTop, setMaxHeightWithTop] = React.useState(); + const [maxHeight, setMaxHeight] = React.useState(); const topHeight = topRef.current ? topRef.current.clientHeight : 0; const updateTopSize = React.useCallback(() => { - if (topRef.current || maxHeightWithTop) { + if (topRef.current || maxHeight) { const clientHeight = topRef.current?.clientHeight || 0; - setMaxHeightWithTop(`calc(100vh - ${clientHeight}px)`); + setMaxHeight(`calc(100vh - ${clientHeight}px)`); } - }, [maxHeightWithTop]); + }, [maxHeight]); + + const onCloseTopAlert = React.useCallback(() => { + updateTopSize(); + topAlert?.onCloseTopAlert?.(); + }, [topAlert, updateTopSize]); React.useLayoutEffect(() => { const updateTopSizeDebounce = debounceFn(updateTopSize, 200, {leading: true}); @@ -28,8 +37,10 @@ export const useAsideHeaderTopPanel = ({topAlert}: {topAlert?: AsideHeaderTopAle }, [topAlert, topRef, topHeight, updateTopSize]); return { - topRef, - maxHeightWithTop, - updateTopSize, + ...(topAlert || {}), + message: topAlert?.message || '', + ref: topRef, + maxHeight, + onCloseTopAlert, }; }; diff --git a/src/components/types.ts b/src/components/types.ts index 5e77154..d1a3b29 100644 --- a/src/components/types.ts +++ b/src/components/types.ts @@ -77,4 +77,8 @@ export type AsideHeaderTopAlertProps = { actions?: AlertProps['actions']; closable?: boolean; centered?: boolean; + dense?: boolean; + ref?: React.RefObject; + maxHeight?: string; + onCloseTopAlert?: () => void; }; From e15a01694aaf7b3ba4e99a617fbdca717acffcfd Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Wed, 15 Nov 2023 18:12:09 +0300 Subject: [PATCH 08/15] fix: aside header top alert css var trick --- src/components/AsideHeader/AsideHeader.scss | 5 +++ src/components/AsideHeader/AsideHeader.tsx | 9 ++-- .../AsideHeader/components/FirstPanel.tsx | 11 +---- .../components/PageLayout/PageLayout.tsx | 14 +++--- .../components/PageLayout/PageLayoutAside.tsx | 2 +- .../AsideHeader/components/TopPanel.tsx | 16 ++++--- src/components/AsideHeader/types.tsx | 1 - .../AsideHeader/useAsideHeaderTopPanel.tsx | 45 +++++++++++-------- src/components/Content/Content.tsx | 11 +++-- src/components/types.ts | 2 - 10 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/components/AsideHeader/AsideHeader.scss b/src/components/AsideHeader/AsideHeader.scss index cf287c5..429f625 100644 --- a/src/components/AsideHeader/AsideHeader.scss +++ b/src/components/AsideHeader/AsideHeader.scss @@ -2,6 +2,10 @@ $block: '.#{variables.$ns}aside-header'; +:root { + --gn-aside-top-panel-height: 0px; +} + .g-root { --gn-aside-header-background-color: var(--g-color-base-warning-light); --gn-aside-header-collapse-button-divider-line-color: var( @@ -43,6 +47,7 @@ $block: '.#{variables.$ns}aside-header'; flex-direction: column; background-color: var(--g-color-base-background); z-index: 100; + max-height: calc(100vh - var(--gn-aside-top-panel-height)); box-sizing: border-box; diff --git a/src/components/AsideHeader/AsideHeader.tsx b/src/components/AsideHeader/AsideHeader.tsx index 0a422c6..9f45eef 100644 --- a/src/components/AsideHeader/AsideHeader.tsx +++ b/src/components/AsideHeader/AsideHeader.tsx @@ -3,7 +3,6 @@ import React from 'react'; import {AsideHeaderProps} from './types'; import {PageLayout} from './components/PageLayout/PageLayout'; import {PageLayoutAside} from './components/PageLayout/PageLayoutAside'; -import {useAsideHeaderTopPanel} from './useAsideHeaderTopPanel'; /** * Simply usage of AsideHeader: @@ -22,12 +21,10 @@ import {useAsideHeaderTopPanel} from './useAsideHeaderTopPanel'; */ export const AsideHeader = React.forwardRef( ({compact, className, topAlert, ...props}, ref) => { - const {maxHeight, ...topAlertValue} = useAsideHeaderTopPanel({topAlert}); - return ( - - - + + + ); }, diff --git a/src/components/AsideHeader/components/FirstPanel.tsx b/src/components/AsideHeader/components/FirstPanel.tsx index c6757e5..dd5929c 100644 --- a/src/components/AsideHeader/components/FirstPanel.tsx +++ b/src/components/AsideHeader/components/FirstPanel.tsx @@ -11,7 +11,7 @@ import {Header} from './Header'; import {CollapseButton} from './CollapseButton'; import {Panels} from './Panels'; -export const FirstPanel = React.forwardRef((props, ref) => { +export const FirstPanel = React.forwardRef((_props, ref) => { const { size, onItemClick, @@ -25,20 +25,13 @@ export const FirstPanel = React.forwardRef const asideRef = useRef(null); - const {maxHeight} = props; - const style: React.CSSProperties = {width: size}; - - if (maxHeight) { - style.maxHeight = maxHeight; - } - React.useEffect(() => { setRef(ref, asideRef.current); }, [ref]); return ( <> -
+
diff --git a/src/components/AsideHeader/components/PageLayout/PageLayout.tsx b/src/components/AsideHeader/components/PageLayout/PageLayout.tsx index f51c7f1..b0acd78 100644 --- a/src/components/AsideHeader/components/PageLayout/PageLayout.tsx +++ b/src/components/AsideHeader/components/PageLayout/PageLayout.tsx @@ -31,18 +31,14 @@ const Layout = ({compact, reverse, className, children, topAlert}: PageLayoutPro ); }; -const ConnectedContent: React.FC< - PropsWithChildren> -> = ({children, renderContent, maxHeight}) => { +const ConnectedContent: React.FC>> = ({ + children, + renderContent, +}) => { const {size} = useAsideHeaderContext(); return ( - + {children} ); diff --git a/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx b/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx index 1002ae5..6c3bde5 100644 --- a/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx +++ b/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx @@ -17,7 +17,7 @@ export const PageLayoutAside = React.forwardRef((props, r return ( - + ); }); diff --git a/src/components/AsideHeader/components/TopPanel.tsx b/src/components/AsideHeader/components/TopPanel.tsx index 9d5c59d..0cd422f 100644 --- a/src/components/AsideHeader/components/TopPanel.tsx +++ b/src/components/AsideHeader/components/TopPanel.tsx @@ -3,30 +3,34 @@ import {Alert} from '@gravity-ui/uikit'; import {b} from '../utils'; import {AsideHeaderTopAlertProps} from '../../types'; +import {useAsideHeaderTopPanel} from '../useAsideHeaderTopPanel'; type Props = { topAlert?: AsideHeaderTopAlertProps; }; -export const TopPanel = React.forwardRef(({topAlert}) => { +export const TopPanel = ({topAlert}: Props) => { + const {topRef, updateTopSize} = useAsideHeaderTopPanel({topAlert}); + const [opened, setOpened] = React.useState(true); const handleClose = React.useCallback(() => { setOpened(false); - }, []); + topAlert?.onCloseTopAlert?.(); + }, [topAlert]); React.useEffect(() => { if (!opened) { - topAlert?.onCloseTopAlert?.(); + updateTopSize(); } - }, [opened, topAlert]); + }, [opened, updateTopSize]); if (!topAlert || !topAlert.message) { return null; } return ( -
+
{opened && ( (({topAlert}) => )}
); -}); +}; diff --git a/src/components/AsideHeader/types.tsx b/src/components/AsideHeader/types.tsx index c96dff5..45d21da 100644 --- a/src/components/AsideHeader/types.tsx +++ b/src/components/AsideHeader/types.tsx @@ -12,7 +12,6 @@ import {AsideHeaderContextType} from './AsideHeaderContext'; export interface LayoutProps { compact: boolean; className?: string; - topAlert?: AsideHeaderTopAlertProps; } export interface AsideHeaderGeneralProps { diff --git a/src/components/AsideHeader/useAsideHeaderTopPanel.tsx b/src/components/AsideHeader/useAsideHeaderTopPanel.tsx index f0de09a..149783f 100644 --- a/src/components/AsideHeader/useAsideHeaderTopPanel.tsx +++ b/src/components/AsideHeader/useAsideHeaderTopPanel.tsx @@ -3,28 +3,40 @@ import React from 'react'; import debounceFn from 'lodash/debounce'; import {AsideHeaderTopAlertProps} from '../types'; +type AsideHeaderTopPanel = { + topRef: React.RefObject; + updateTopSize: () => void; +}; + +const useRefHeight = (ref: React.RefObject) => { + const [topHeight, setTopHeight] = React.useState(0); + React.useEffect(() => { + if (ref.current) { + const {current} = ref; + setTopHeight(current.clientHeight); + } + }, [ref]); + return topHeight; +}; + export const useAsideHeaderTopPanel = ({ topAlert, }: { topAlert?: AsideHeaderTopAlertProps; -}): AsideHeaderTopAlertProps => { +}): AsideHeaderTopPanel => { const topRef = React.useRef(null); - - const [maxHeight, setMaxHeight] = React.useState(); - const topHeight = topRef.current ? topRef.current.clientHeight : 0; + const topHeight = useRefHeight(topRef); const updateTopSize = React.useCallback(() => { - if (topRef.current || maxHeight) { + if (topRef.current) { const clientHeight = topRef.current?.clientHeight || 0; - setMaxHeight(`calc(100vh - ${clientHeight}px)`); + document.documentElement.style.setProperty( + '--gn-aside-top-panel-height', + clientHeight + 'px', + ); } - }, [maxHeight]); - - const onCloseTopAlert = React.useCallback(() => { - updateTopSize(); - topAlert?.onCloseTopAlert?.(); - }, [topAlert, updateTopSize]); + }, []); React.useLayoutEffect(() => { const updateTopSizeDebounce = debounceFn(updateTopSize, 200, {leading: true}); @@ -34,13 +46,10 @@ export const useAsideHeaderTopPanel = ({ updateTopSizeDebounce(); } return () => window.removeEventListener('resize', updateTopSizeDebounce); - }, [topAlert, topRef, topHeight, updateTopSize]); + }, [topAlert, topHeight, topRef, updateTopSize]); return { - ...(topAlert || {}), - message: topAlert?.message || '', - ref: topRef, - maxHeight, - onCloseTopAlert, + topRef, + updateTopSize, }; }; diff --git a/src/components/Content/Content.tsx b/src/components/Content/Content.tsx index 1f3b954..2346a95 100644 --- a/src/components/Content/Content.tsx +++ b/src/components/Content/Content.tsx @@ -26,16 +26,15 @@ RenderContent.displayName = 'RenderContent'; export const Content: React.FC = ({ size, // TODO: move to context when MobileHeader will support it className, - maxHeight, cssSizeVariableName = '--gn-aside-header-size', renderContent, children, }) => { - const style: React.CSSProperties = {[cssSizeVariableName]: `${size}px`}; - if (maxHeight) { - style.maxHeight = maxHeight; - style.overflowY = 'auto'; - } + const style: React.CSSProperties = { + [cssSizeVariableName]: `${size}px`, + maxHeight: 'calc(100vh - var(--gn-aside-top-panel-height))', + overflowY: 'auto', + }; return (
diff --git a/src/components/types.ts b/src/components/types.ts index d1a3b29..86410c0 100644 --- a/src/components/types.ts +++ b/src/components/types.ts @@ -78,7 +78,5 @@ export type AsideHeaderTopAlertProps = { closable?: boolean; centered?: boolean; dense?: boolean; - ref?: React.RefObject; - maxHeight?: string; onCloseTopAlert?: () => void; }; From 3d4f002c2b2330f931f490690c50af6f3cad9d9d Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Wed, 15 Nov 2023 18:13:48 +0300 Subject: [PATCH 09/15] fix: remove useless changes --- .../AsideHeader/components/PageLayout/PageLayoutAside.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx b/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx index 6c3bde5..29c91e2 100644 --- a/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx +++ b/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx @@ -4,16 +4,12 @@ import {useAsideHeaderInnerContextValue} from '../../useAsideHeaderInnerContextV import {AsideHeaderInnerContextProvider, useAsideHeaderContext} from '../../AsideHeaderContext'; import {AsideHeaderProps} from '../../types'; -type Props = Omit & {maxHeight?: string}; +type Props = Omit; export const PageLayoutAside = React.forwardRef((props, ref) => { const {size, compact} = useAsideHeaderContext(); - const asideHeaderInnerContextValue = useAsideHeaderInnerContextValue({ - size, - compact, - ...props, - }); + const asideHeaderInnerContextValue = useAsideHeaderInnerContextValue({size, compact, ...props}); return ( From 0a1ce0c6b0707ad32b571039aafe26d7da2636b6 Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Wed, 15 Nov 2023 18:15:04 +0300 Subject: [PATCH 10/15] fix: remove maxHeight from Content widget --- src/components/Content/Content.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Content/Content.tsx b/src/components/Content/Content.tsx index 2346a95..df98603 100644 --- a/src/components/Content/Content.tsx +++ b/src/components/Content/Content.tsx @@ -8,7 +8,6 @@ export interface ContentProps { size: number; className?: string; cssSizeVariableName?: string; - maxHeight?: string; renderContent?: RenderContentType; } From 2a945794c5a0a94ebbf32d12804fd60e87b8a998 Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Wed, 15 Nov 2023 18:19:06 +0300 Subject: [PATCH 11/15] fix: top ref callback update --- src/components/AsideHeader/useAsideHeaderTopPanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AsideHeader/useAsideHeaderTopPanel.tsx b/src/components/AsideHeader/useAsideHeaderTopPanel.tsx index 149783f..88a3805 100644 --- a/src/components/AsideHeader/useAsideHeaderTopPanel.tsx +++ b/src/components/AsideHeader/useAsideHeaderTopPanel.tsx @@ -36,7 +36,7 @@ export const useAsideHeaderTopPanel = ({ clientHeight + 'px', ); } - }, []); + }, [topRef]); React.useLayoutEffect(() => { const updateTopSizeDebounce = debounceFn(updateTopSize, 200, {leading: true}); From 18b751edec9e74e5b2ad23b0fbb3884029c6fcfa Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Wed, 15 Nov 2023 18:21:51 +0300 Subject: [PATCH 12/15] fix: fix type LayoutProps --- src/components/AsideHeader/types.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/AsideHeader/types.tsx b/src/components/AsideHeader/types.tsx index 45d21da..c96dff5 100644 --- a/src/components/AsideHeader/types.tsx +++ b/src/components/AsideHeader/types.tsx @@ -12,6 +12,7 @@ import {AsideHeaderContextType} from './AsideHeaderContext'; export interface LayoutProps { compact: boolean; className?: string; + topAlert?: AsideHeaderTopAlertProps; } export interface AsideHeaderGeneralProps { From a0c63d221dcc909d8dc7e998f55a6292724875f8 Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Wed, 22 Nov 2023 16:12:17 +0300 Subject: [PATCH 13/15] fix: drawer panel height --- src/components/AsideHeader/AsideHeader.scss | 3 ++- .../__stories__/AsideHeaderShowcase.scss | 2 +- .../AsideHeader/useAsideHeaderTopPanel.tsx | 21 ++++++++++++------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/components/AsideHeader/AsideHeader.scss b/src/components/AsideHeader/AsideHeader.scss index 429f625..2debc5d 100644 --- a/src/components/AsideHeader/AsideHeader.scss +++ b/src/components/AsideHeader/AsideHeader.scss @@ -181,8 +181,9 @@ $block: '.#{variables.$ns}aside-header'; left: 0; right: 0; bottom: 0; - top: 0; + top: var(--gn-aside-top-panel-height); overflow: auto; + max-height: calc(100vh - var(--gn-aside-top-panel-height)); } &__panel { diff --git a/src/components/AsideHeader/__stories__/AsideHeaderShowcase.scss b/src/components/AsideHeader/__stories__/AsideHeaderShowcase.scss index a4f320e..3f10888 100644 --- a/src/components/AsideHeader/__stories__/AsideHeaderShowcase.scss +++ b/src/components/AsideHeader/__stories__/AsideHeaderShowcase.scss @@ -80,7 +80,7 @@ body { &__settings-panel, &__search-panel { width: 300px; - height: 100%; + height: calc(100% - 40px); padding: 20px; } } diff --git a/src/components/AsideHeader/useAsideHeaderTopPanel.tsx b/src/components/AsideHeader/useAsideHeaderTopPanel.tsx index 88a3805..f8e97a2 100644 --- a/src/components/AsideHeader/useAsideHeaderTopPanel.tsx +++ b/src/components/AsideHeader/useAsideHeaderTopPanel.tsx @@ -27,16 +27,18 @@ export const useAsideHeaderTopPanel = ({ const topRef = React.useRef(null); const topHeight = useRefHeight(topRef); + const setAsideTopPanelHeight = React.useCallback((clientHeight: number) => { + document.documentElement.style.setProperty( + '--gn-aside-top-panel-height', + clientHeight + 'px', + ); + }, []); + const updateTopSize = React.useCallback(() => { if (topRef.current) { - const clientHeight = topRef.current?.clientHeight || 0; - - document.documentElement.style.setProperty( - '--gn-aside-top-panel-height', - clientHeight + 'px', - ); + setAsideTopPanelHeight(topRef.current?.clientHeight || 0); } - }, [topRef]); + }, [topRef, setAsideTopPanelHeight]); React.useLayoutEffect(() => { const updateTopSizeDebounce = debounceFn(updateTopSize, 200, {leading: true}); @@ -45,7 +47,10 @@ export const useAsideHeaderTopPanel = ({ window.addEventListener('resize', updateTopSizeDebounce); updateTopSizeDebounce(); } - return () => window.removeEventListener('resize', updateTopSizeDebounce); + return () => { + window.removeEventListener('resize', updateTopSizeDebounce); + setAsideTopPanelHeight(0); + }; }, [topAlert, topHeight, topRef, updateTopSize]); return { From 48daab39aa00f5087b1f89d79dd97ff84abd9e7b Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Wed, 22 Nov 2023 16:54:44 +0300 Subject: [PATCH 14/15] fix: import FC from React --- .../AsideHeader/__stories__/AsideHeaderShowcase.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/AsideHeader/__stories__/AsideHeaderShowcase.tsx b/src/components/AsideHeader/__stories__/AsideHeaderShowcase.tsx index 71464a0..cd89e50 100644 --- a/src/components/AsideHeader/__stories__/AsideHeaderShowcase.tsx +++ b/src/components/AsideHeader/__stories__/AsideHeaderShowcase.tsx @@ -1,4 +1,4 @@ -import React, {FC} from 'react'; +import React from 'react'; import { Button, @@ -41,7 +41,7 @@ interface AsideHeaderShowcaseProps { topAlert?: AsideHeaderTopAlertProps; } -export const AsideHeaderShowcase: FC = ({ +export const AsideHeaderShowcase: React.FC = ({ multipleTooltip = false, initialCompact = false, topAlert, From d041c19f97b8f3ea56d5b56eb76bf94ae83433d6 Mon Sep 17 00:00:00 2001 From: Georgy Malkov Date: Wed, 22 Nov 2023 17:34:14 +0300 Subject: [PATCH 15/15] fix: change root element var --- src/components/AsideHeader/AsideHeader.scss | 6 ++---- src/components/AsideHeader/useAsideHeaderTopPanel.tsx | 10 ++++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/AsideHeader/AsideHeader.scss b/src/components/AsideHeader/AsideHeader.scss index 2debc5d..f722e75 100644 --- a/src/components/AsideHeader/AsideHeader.scss +++ b/src/components/AsideHeader/AsideHeader.scss @@ -2,10 +2,6 @@ $block: '.#{variables.$ns}aside-header'; -:root { - --gn-aside-top-panel-height: 0px; -} - .g-root { --gn-aside-header-background-color: var(--g-color-base-warning-light); --gn-aside-header-collapse-button-divider-line-color: var( @@ -14,6 +10,8 @@ $block: '.#{variables.$ns}aside-header'; --gn-aside-header-footer-item-icon-color: var(--g-color-text-primary); --gn-aside-header-subheader-item-icon-color: var(--g-color-text-primary); --gn-aside-header-item-icon-background-size: 38px; + + --gn-aside-top-panel-height: 0px; } .g-root_theme_light, diff --git a/src/components/AsideHeader/useAsideHeaderTopPanel.tsx b/src/components/AsideHeader/useAsideHeaderTopPanel.tsx index f8e97a2..17c5d69 100644 --- a/src/components/AsideHeader/useAsideHeaderTopPanel.tsx +++ b/src/components/AsideHeader/useAsideHeaderTopPanel.tsx @@ -8,6 +8,8 @@ type AsideHeaderTopPanel = { updateTopSize: () => void; }; +const G_ROOT_CLASS_NAME = 'g-root'; + const useRefHeight = (ref: React.RefObject) => { const [topHeight, setTopHeight] = React.useState(0); React.useEffect(() => { @@ -28,10 +30,10 @@ export const useAsideHeaderTopPanel = ({ const topHeight = useRefHeight(topRef); const setAsideTopPanelHeight = React.useCallback((clientHeight: number) => { - document.documentElement.style.setProperty( - '--gn-aside-top-panel-height', - clientHeight + 'px', - ); + const gRootElement = document + .getElementsByClassName(G_ROOT_CLASS_NAME) + .item(0) as HTMLElement | null; + gRootElement?.style.setProperty('--gn-aside-top-panel-height', clientHeight + 'px'); }, []); const updateTopSize = React.useCallback(() => {