Skip to content

Commit

Permalink
feat: add AsideFallback (#161)
Browse files Browse the repository at this point in the history
* feat: add AsideFallback

* chore: share HEADER_DIVIDER_HEIGHT
  • Loading branch information
ldrv565 authored Nov 27, 2023
1 parent 225aa7f commit 6e08a91
Show file tree
Hide file tree
Showing 13 changed files with 114 additions and 41 deletions.
27 changes: 20 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,43 @@ npm install --dev @gravity-ui/uikit@^3.0.2 @bem-react/[email protected] react@^16.
- DrawerItem
- PageLayout
- PageLayoutAside
- AsideFallback

## Optimization

If your app content needs to be rendered faster than by passing it throw `AsideHeader` props,
you may need to switch usage of `AsideHeader` to advanced style with `PageLayout` like this:

```diff
-import {AsideHeader} from '@gravity-ui/navigation';
+import {PageLayout} from '@gravity-ui/navigation';
+
+const PageLayoutAside = React.lazy(() =>
+ import('@gravity-ui/navigation').then((module) => ({default: module.PageLayoutAside})),
--- Main.tsx
+++ Main.tsx
-import {AsideHeader} from './AsideHeader'
+import {PageLayout, AsideFallback} from '@gravity-ui/navigation';
+const Aside = React.lazy(() =>
+ import('./Aside').then(({Aside}) => ({ default: Aside }))
+);

- <AsideHeader renderContent={renderContent} {...restProps} />
+ <PageLayout>
+ <Suspense fallback={null}>
+ <PageLayoutAside {...restProps} />
+ <Suspense fallback={<AsideFallback />}>
+ <Aside />
+ </Suspense>
+
+ <PageLayout.Content>
+ <ContentExample />
+ </PageLayout.Content>
+ </PageLayout>
--- Aside.tsx
+++ Aside.tsx
-import {AsideHeader} from '@gravity-ui/navigation';
+import {PageLayoutAside} from '@gravity-ui/navigation';

export const Aside: FC = () => {
return (
- <AsideHeader {...props}>
+ <PageLayoutAside {...props}/>
);
};
```

## Imports
Expand Down
1 change: 1 addition & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const input = [
'src/components/FooterItem/FooterItem.tsx',
'src/components/AsideHeader/components/PageLayout/PageLayout.tsx',
'src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx',
'src/components/AsideHeader/components/PageLayout/AsideFallback.tsx',
];

const getPlugins = (outDir) => {
Expand Down
4 changes: 0 additions & 4 deletions src/components/AsideHeader/AsideHeader.scss
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,6 @@ $block: '.#{variables.$ns}aside-header';
}
}

&_reverse #{$block}__pane-container {
flex-direction: row-reverse;
}

&__content {
width: calc(100% - var(--gn-aside-header-size));
z-index: 95;
Expand Down
15 changes: 0 additions & 15 deletions src/components/AsideHeader/AsideHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,6 @@ import {AsideHeaderProps} from './types';
import {PageLayout} from './components/PageLayout/PageLayout';
import {PageLayoutAside} from './components/PageLayout/PageLayoutAside';

/**
* Simply usage of AsideHeader:
* @example
* <AsideHeader renderContent={renderContent} {...props} />
*
* Advanced usage of AsideHeader:
* @example
* <PageLayout reverse >
* <PageLayout.Content>
* <Content />
* </PageLayout.Content>
*
* <PageLayoutAside {...props} />
* </PageLayout>
*/
export const AsideHeader = React.forwardRef<HTMLDivElement, AsideHeaderProps>(
({compact, className, topAlert, ...props}, ref) => {
return (
Expand Down
37 changes: 35 additions & 2 deletions src/components/AsideHeader/__stories__/AsideHeader.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {PageLayout} from '../components/PageLayout/PageLayout';
import {PageLayoutAside} from '../components/PageLayout/PageLayoutAside';
import logoIcon from '../../../../.storybook/assets/logo.svg';
import {menuItemsShowcase} from './moc';
import {AsideFallback} from '../components/PageLayout/AsideFallback';
import {Button} from '@gravity-ui/uikit';

export default {
title: 'components/AsideHeader',
Expand All @@ -34,8 +36,7 @@ const AdvancedUsageTemplate: StoryFn = (args) => {
const [compact, setCompact] = React.useState(args.initialCompact);

return (
<PageLayout reverse compact={compact}>
<PageLayout.Content>PageContent</PageLayout.Content>
<PageLayout compact={compact}>
<PageLayoutAside
headerDecoration
menuItems={menuItemsShowcase}
Expand All @@ -48,6 +49,8 @@ const AdvancedUsageTemplate: StoryFn = (args) => {
onChangeCompact={setCompact}
{...args}
/>

<PageLayout.Content>PageContent</PageLayout.Content>
</PageLayout>
);
};
Expand Down Expand Up @@ -80,3 +83,33 @@ HeaderAlertCentered.args = {
dense: true,
},
};

const fallbackArgs = {
headerDecoration: true,
subheaderItemsCount: 2,
};

const FallbackTemplate: StoryFn<typeof fallbackArgs> = ({
headerDecoration,
subheaderItemsCount,
}) => {
const [compact, setCompact] = React.useState(false);

return (
<PageLayout compact={compact}>
<AsideFallback
headerDecoration={headerDecoration}
subheaderItemsCount={subheaderItemsCount}
/>

<PageLayout.Content>
<div style={{padding: 16}}>
<Button onClick={() => setCompact((prev) => !prev)}>Toggle compact</Button>
</div>
</PageLayout.Content>
</PageLayout>
);
};

export const Fallback = FallbackTemplate.bind({});
Fallback.args = fallbackArgs;
4 changes: 2 additions & 2 deletions src/components/AsideHeader/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, {useCallback} from 'react';
import {Icon} from '@gravity-ui/uikit';

import {SubheaderMenuItem} from '../../types';
import {ASIDE_HEADER_COMPACT_WIDTH} from '../../constants';
import {ASIDE_HEADER_COMPACT_WIDTH, HEADER_DIVIDER_HEIGHT} from '../../constants';
import {Logo} from '../../Logo/Logo';
import {CompositeBar} from '../../CompositeBar/CompositeBar';

Expand Down Expand Up @@ -40,7 +40,7 @@ export const Header = () => {
data={headerDividerCollapsedIcon}
className={b('header-divider')}
width={ASIDE_HEADER_COMPACT_WIDTH}
height="29"
height={HEADER_DIVIDER_HEIGHT}
/>
</div>
);
Expand Down
38 changes: 38 additions & 0 deletions src/components/AsideHeader/components/PageLayout/AsideFallback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import {useAsideHeaderContext} from '../../AsideHeaderContext';
import headerDividerCollapsedIcon from '../../../../../assets/icons/divider-collapsed.svg';
import {b} from '../../utils';
import {Icon} from '@gravity-ui/uikit';
import {ASIDE_HEADER_COMPACT_WIDTH, HEADER_DIVIDER_HEIGHT, ITEM_HEIGHT} from '../../../constants';

export interface Props {
headerDecoration?: boolean;
subheaderItemsCount?: number;
}

export const AsideFallback: React.FC<Props> = ({headerDecoration, subheaderItemsCount = 0}) => {
const {compact} = useAsideHeaderContext();

const widthVar = compact ? '--gn-aside-header-min-width' : '--gn-aside-header-size';

const subheaderHeight = (1 + subheaderItemsCount) * ITEM_HEIGHT;

return (
<div className={b('aside')} style={{width: `var(${widthVar})`}}>
<div className={b('aside-content', {'with-decoration': headerDecoration})}>
<div className={b('header', {'with-decoration': headerDecoration})}>
<div style={{height: subheaderHeight}} />
{compact ? (
<Icon
data={headerDividerCollapsedIcon}
className={b('header-divider')}
width={ASIDE_HEADER_COMPACT_WIDTH}
height={HEADER_DIVIDER_HEIGHT}
/>
) : null}
</div>
<div style={{flex: 1}} />
</div>
</div>
);
};
21 changes: 13 additions & 8 deletions src/components/AsideHeader/components/PageLayout/PageLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
import React, {PropsWithChildren, useMemo} from 'react';
import React, {PropsWithChildren, Suspense, 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';

import '../../AsideHeader.scss';

export interface PageLayoutProps extends PropsWithChildren<LayoutProps> {
reverse?: boolean;
}
const TopPanel = React.lazy(() =>
import('../TopPanel').then((module) => ({default: module.TopPanel})),
);

const Layout = ({compact, reverse, className, children, topAlert}: PageLayoutProps) => {
export interface PageLayoutProps extends PropsWithChildren<LayoutProps> {}

const Layout = ({compact, className, children, topAlert}: PageLayoutProps) => {
const size = compact ? ASIDE_HEADER_COMPACT_WIDTH : ASIDE_HEADER_EXPANDED_WIDTH;
const asideHeaderContextValue = useMemo(() => ({size, compact}), [compact, size]);

return (
<AsideHeaderContextProvider value={asideHeaderContextValue}>
<div
className={b({compact, reverse}, className)}
className={b({compact}, className)}
style={{
...({'--gn-aside-header-size': `${size}px`} as React.CSSProperties),
}}
>
{topAlert && <TopPanel topAlert={topAlert} />}
{topAlert && (
<Suspense fallback={null}>
<TopPanel topAlert={topAlert} />
</Suspense>
)}
<div className={b('pane-container')}>{children}</div>
</div>
</AsideHeaderContextProvider>
Expand Down
1 change: 0 additions & 1 deletion src/components/AsideHeader/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export interface LayoutProps {
export interface AsideHeaderGeneralProps {
logo: LogoProps;
multipleTooltip?: boolean;
reverse?: boolean;
className?: string;
collapseTitle?: string;
expandTitle?: string;
Expand Down
1 change: 0 additions & 1 deletion src/components/CompositeBar/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {PopupPlacement} from '@gravity-ui/uikit';

export const ITEM_HEIGHT = 40;
export const ITEM_TYPE_REGULAR = 'regular';
export const COLLAPSE_ITEM_ID = 'collapse-item-id';

Expand Down
3 changes: 2 additions & 1 deletion src/components/CompositeBar/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {Ellipsis} from '@gravity-ui/icons';
import {MenuItem} from './../types';
import {COLLAPSE_ITEM_ID, ITEM_HEIGHT} from './constants';
import {COLLAPSE_ITEM_ID} from './constants';
import {CompositeBarItem} from '../CompositeBar/CompositeBar';
import {ITEM_HEIGHT} from '../constants';

export function getItemHeight(item: CompositeBarItem) {
if (!isMenuItem(item)) {
Expand Down
2 changes: 2 additions & 0 deletions src/components/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const ASIDE_HEADER_ICON_SIZE = 18;
export const ASIDE_HEADER_COMPACT_WIDTH = 56;
export const ASIDE_HEADER_EXPANDED_WIDTH = 236;
export const ITEM_HEIGHT = 40;
export const HEADER_DIVIDER_HEIGHT = 29;
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export {Drawer, DrawerProps, DrawerItemProps, DrawerItem} from './Drawer/Drawer'
export {FooterItem, FooterItemProps} from './FooterItem/FooterItem';
export {PageLayout, type PageLayoutProps} from './AsideHeader/components/PageLayout/PageLayout';
export {PageLayoutAside} from './AsideHeader/components/PageLayout/PageLayoutAside';
export {AsideFallback} from './AsideHeader/components/PageLayout/AsideFallback';
export * from './ActionBar';
export * from './Title';
export * from './HotkeysPanel';
Expand Down

0 comments on commit 6e08a91

Please sign in to comment.