From 1099f6830b25ceb393e3a4b51d33f92bc5b16760 Mon Sep 17 00:00:00 2001 From: ldrv565 <40745264+ldrv565@users.noreply.github.com> Date: Fri, 3 Nov 2023 12:31:29 +0300 Subject: [PATCH 1/3] feat: split AsideHeader to compound components (#140) * feat: split AsideHeader to compound components * fix: typecheck * fix: split bundle by chunks * Update README.md * Update README.md * Update README.md * fix: rollup config with @rollup/plugin-typescript * chore: conflict in package-lock.json * chore: mv PageLayout to components * fix: input entries * fix: lint errors in readme --- README.md | 27 ++++++++ package-lock.json | 2 +- package.json | 4 +- rollup.config.js | 58 ++++++++++++---- src/components/AsideHeader/AsideHeader.scss | 4 ++ src/components/AsideHeader/AsideHeader.tsx | 69 ++++++++----------- .../AsideHeader/AsideHeaderContext.ts | 3 +- .../__stories__/AsideHeader.stories.tsx | 33 +++++++++ .../AsideHeader/__stories__/moc.tsx | 1 + .../components/PageLayout/PageLayout.tsx | 49 +++++++++++++ .../components/PageLayout/PageLayoutAside.tsx | 19 +++++ src/components/AsideHeader/types.tsx | 14 +++- src/components/Content/Content.tsx | 7 +- src/components/index.ts | 2 + 14 files changed, 227 insertions(+), 65 deletions(-) create mode 100644 src/components/AsideHeader/components/PageLayout/PageLayout.tsx create mode 100644 src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx diff --git a/README.md b/README.md index 0325b42..65ca513 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,33 @@ npm install --dev @gravity-ui/uikit@^3.0.2 @bem-react/classname@1.6.0 react@^16. - MobileHeaderFooterItem - Drawer - DrawerItem +- PageLayout +- PageLayoutAside + +## 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})), ++); + +- ++ ++ ++ ++ ++ ++ ++ ++ ++ +``` ## Imports diff --git a/package-lock.json b/package-lock.json index 65f48bb..0fe430f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "@gravity-ui/navigation", - "version": "0.19.0", + "version": "1.1.3", "license": "MIT", "dependencies": { "@gravity-ui/i18n": "^1.1.0", diff --git a/package.json b/package.json index 2d14a17..d4bc5b5 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "type": "git", "url": "https://github.com/gravity-ui/navigation" }, - "main": "build/cjs/index.js", - "module": "build/esm/index.js", + "main": "build/cjs", + "module": "build/esm", "types": "build/esm/index.d.ts", "sideEffects": [ "*.css", diff --git a/rollup.config.js b/rollup.config.js index 63f0bfc..05d1c97 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -8,32 +8,60 @@ import peerDepsExternal from 'rollup-plugin-peer-deps-external'; const packageJson = require('./package.json'); +const input = [ + 'src/index.ts', + 'src/components/ActionBar/index.ts', + 'src/components/Title/index.ts', + 'src/components/HotkeysPanel/index.ts', + 'src/components/Settings/index.ts', + 'src/components/MobileHeader/index.ts', + 'src/components/AsideHeader/AsideHeader.tsx', + 'src/components/AsideHeader/AsideHeaderContext.ts', + 'src/components/Drawer/Drawer.tsx', + 'src/components/FooterItem/FooterItem.tsx', + 'src/components/AsideHeader/components/PageLayout/PageLayout.tsx', + 'src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx', +]; + +const getPlugins = (outDir) => { + return [ + peerDepsExternal(), + json(), + resolve(), + commonjs(), + typescript({ + typescript: require('typescript'), + tsconfig: './tsconfig.publish.json', + outDir, + }), + postcss({ + minimize: true, + }), + svgr(), + ]; +}; + export default [ { - input: 'src/index.ts', + input, output: [ { - file: packageJson.module, + dir: packageJson.module, format: 'esm', sourcemap: true, }, + ], + plugins: getPlugins(packageJson.module), + }, + { + input, + output: [ { - file: packageJson.main, + dir: packageJson.main, format: 'cjs', sourcemap: true, }, ], - plugins: [ - peerDepsExternal(), - json(), - resolve(), - commonjs(), - typescript({ - typescript: require('typescript'), - tsconfig: './tsconfig.publish.json', - }), - postcss(), - svgr(), - ], + plugins: getPlugins(packageJson.main), }, ]; diff --git a/src/components/AsideHeader/AsideHeader.scss b/src/components/AsideHeader/AsideHeader.scss index f61bf89..b8de621 100644 --- a/src/components/AsideHeader/AsideHeader.scss +++ b/src/components/AsideHeader/AsideHeader.scss @@ -202,6 +202,10 @@ $block: '.#{variables.$ns}aside-header'; flex-direction: row; } + &_reverse #{$block}__pane-container { + flex-direction: row-reverse; + } + &__content { width: calc(100% - var(--gn-aside-header-size)); z-index: 95; diff --git a/src/components/AsideHeader/AsideHeader.tsx b/src/components/AsideHeader/AsideHeader.tsx index bb971d8..97246d6 100644 --- a/src/components/AsideHeader/AsideHeader.tsx +++ b/src/components/AsideHeader/AsideHeader.tsx @@ -1,44 +1,31 @@ -import React, {useMemo} from 'react'; +import React from 'react'; -import {Content} from '../Content'; - -import {AsideHeaderContextProvider, AsideHeaderInnerContextProvider} from './AsideHeaderContext'; import {AsideHeaderProps} from './types'; +import {PageLayout} from './components/PageLayout/PageLayout'; +import {PageLayoutAside} from './components/PageLayout/PageLayoutAside'; -import {FirstPanel} 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} = props; - - const size = compact ? ASIDE_HEADER_COMPACT_WIDTH : ASIDE_HEADER_EXPANDED_WIDTH; - const asideHeaderContextValue = useMemo(() => ({size, compact}), [compact, size]); - const asideHeaderInnerContextValue = useAsideHeaderInnerContextValue({...props, size}); - return ( - - - - - {/* First Panel */} - - {/* Second Panel */} - - - - - - ); -}); +/** + * Simply usage of AsideHeader: + * @example + * + * + * Advanced usage of AsideHeader: + * @example + * + * + * + * + * + * + * + */ +export const AsideHeader = React.forwardRef( + ({compact, className, ...props}, ref) => { + return ( + + + + + ); + }, +); diff --git a/src/components/AsideHeader/AsideHeaderContext.ts b/src/components/AsideHeader/AsideHeaderContext.ts index 6c7a5f6..838aa57 100644 --- a/src/components/AsideHeader/AsideHeaderContext.ts +++ b/src/components/AsideHeader/AsideHeaderContext.ts @@ -5,7 +5,6 @@ import {AsideHeaderInnerProps} from './types'; export interface AsideHeaderInnerContextType extends AsideHeaderInnerProps { menuItems: MenuItem[]; allPagesIsAvailable: boolean; - size: number; onItemClick: ( item: MenuItem, collapsed: boolean, @@ -30,7 +29,7 @@ export const useAsideHeaderInnerContext = (): AsideHeaderInnerContextType => { }; export interface AsideHeaderContextType { - compact?: boolean; + compact: boolean; size: number; } diff --git a/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx b/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx index c721f70..62fb07d 100644 --- a/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx +++ b/src/components/AsideHeader/__stories__/AsideHeader.stories.tsx @@ -4,6 +4,10 @@ import type {Meta, StoryFn} from '@storybook/react'; import {AsideHeader} from '../AsideHeader'; import {AsideHeaderShowcase} from './AsideHeaderShowcase'; +import {PageLayout} from '../components/PageLayout/PageLayout'; +import {PageLayoutAside} from '../components/PageLayout/PageLayoutAside'; +import logoIcon from '../../../../.storybook/assets/logo.svg'; +import {menuItemsShowcase} from './moc'; export default { title: 'components/AsideHeader', @@ -25,3 +29,32 @@ MultipleTooltip.args = { multipleTooltip: true, initialCompact: true, }; + +const AdvancedUsageTemplate: StoryFn = (args) => { + const [compact, setCompact] = React.useState(args.initialCompact); + + return ( + + PageContent + alert('click on logo'), + }} + onChangeCompact={setCompact} + {...args} + /> + + ); +}; + +export const AdvancedUsage = AdvancedUsageTemplate.bind({}); + +AdvancedUsage.args = { + multipleTooltip: false, + initialCompact: true, +}; diff --git a/src/components/AsideHeader/__stories__/moc.tsx b/src/components/AsideHeader/__stories__/moc.tsx index a7991db..77f3049 100644 --- a/src/components/AsideHeader/__stories__/moc.tsx +++ b/src/components/AsideHeader/__stories__/moc.tsx @@ -11,6 +11,7 @@ function renderTag(tag: string) { export const EMPTY_CONTEXT_VALUE: AsideHeaderContextType = { size: ASIDE_HEADER_EXPANDED_WIDTH, + compact: true, }; export const menuItemsShowcase: MenuItem[] = [ diff --git a/src/components/AsideHeader/components/PageLayout/PageLayout.tsx b/src/components/AsideHeader/components/PageLayout/PageLayout.tsx new file mode 100644 index 0000000..449b89a --- /dev/null +++ b/src/components/AsideHeader/components/PageLayout/PageLayout.tsx @@ -0,0 +1,49 @@ +import React, {PropsWithChildren, useMemo} from 'react'; +import {AsideHeaderContextProvider, useAsideHeaderContext} from '../../AsideHeaderContext'; +import {Content, ContentProps} from '../../../Content'; +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 { + reverse?: boolean; +} + +const Layout = ({compact, reverse, className, children}: PageLayoutProps) => { + const size = compact ? ASIDE_HEADER_COMPACT_WIDTH : ASIDE_HEADER_EXPANDED_WIDTH; + const asideHeaderContextValue = useMemo(() => ({size, compact}), [compact, size]); + + return ( + + + {children} + + + ); +}; + +const ConnectedContent: React.FC>> = ({ + children, + renderContent, +}) => { + const {size} = useAsideHeaderContext(); + + return ( + + {children} + + ); +}; + +const PageLayout = Object.assign(Layout, { + Content: ConnectedContent, +}); + +export {PageLayout}; diff --git a/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx b/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx new file mode 100644 index 0000000..29c91e2 --- /dev/null +++ b/src/components/AsideHeader/components/PageLayout/PageLayoutAside.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import {FirstPanel} from '..'; +import {useAsideHeaderInnerContextValue} from '../../useAsideHeaderInnerContextValue'; +import {AsideHeaderInnerContextProvider, useAsideHeaderContext} from '../../AsideHeaderContext'; +import {AsideHeaderProps} from '../../types'; + +type Props = Omit; + +export const PageLayoutAside = React.forwardRef((props, ref) => { + const {size, compact} = useAsideHeaderContext(); + + const asideHeaderInnerContextValue = useAsideHeaderInnerContextValue({size, compact, ...props}); + + return ( + + + + ); +}); diff --git a/src/components/AsideHeader/types.tsx b/src/components/AsideHeader/types.tsx index e636923..cb65754 100644 --- a/src/components/AsideHeader/types.tsx +++ b/src/components/AsideHeader/types.tsx @@ -1,11 +1,17 @@ import {RenderContentType} from '../Content'; import {DrawerItemProps} from '../Drawer/Drawer'; import {LogoProps, MenuItem, SubheaderMenuItem, OpenModalSubscriber} from '../types'; +import {AsideHeaderContextType} from './AsideHeaderContext'; + +export interface LayoutProps { + compact: boolean; + className?: string; +} export interface AsideHeaderGeneralProps { logo: LogoProps; - compact: boolean; multipleTooltip?: boolean; + reverse?: boolean; className?: string; collapseTitle?: string; expandTitle?: string; @@ -29,9 +35,13 @@ export interface AsideHeaderDefaultProps { headerDecoration?: boolean; } -export type AsideHeaderInnerProps = AsideHeaderGeneralProps & AsideHeaderDefaultProps; +export type AsideHeaderInnerProps = AsideHeaderGeneralProps & + AsideHeaderDefaultProps & + AsideHeaderContextType; + export interface AsideHeaderProps extends AsideHeaderGeneralProps, + LayoutProps, Partial {} export enum InnerPanels { diff --git a/src/components/Content/Content.tsx b/src/components/Content/Content.tsx index a251e24..be24541 100644 --- a/src/components/Content/Content.tsx +++ b/src/components/Content/Content.tsx @@ -4,7 +4,7 @@ import React from 'react'; export type RenderContentType = (data: {size: number}) => React.ReactNode; -interface ContentProps { +export interface ContentProps { size: number; className?: string; cssSizeVariableName?: string; @@ -27,14 +27,17 @@ export const Content: React.FC = ({ className, cssSizeVariableName = '--gn-aside-header-size', renderContent, + children, }) => { return ( - {typeof renderContent === 'function' && ( + {typeof renderContent === 'function' ? ( + ) : ( + children )} ); diff --git a/src/components/index.ts b/src/components/index.ts index b91dd75..7774b35 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -3,6 +3,8 @@ export type {AsideHeaderProps} from './AsideHeader/types'; export {AsideHeaderContextProvider, useAsideHeaderContext} from './AsideHeader/AsideHeaderContext'; 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 * from './ActionBar'; export * from './Title'; export * from './HotkeysPanel'; From 06b058827298ea3e78be7c7bc896b9c290b4ae86 Mon Sep 17 00:00:00 2001 From: Gravity UI Bot <111915794+gravity-ui-bot@users.noreply.github.com> Date: Fri, 3 Nov 2023 13:49:38 +0300 Subject: [PATCH 2/3] chore(main): release 1.2.0 (#143) --- CHANGELOG.md | 7 +++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad7194e..61b8e75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.2.0](https://github.com/gravity-ui/navigation/compare/v1.1.3...v1.2.0) (2023-11-03) + + +### Features + +* split AsideHeader to compound components ([#140](https://github.com/gravity-ui/navigation/issues/140)) ([1099f68](https://github.com/gravity-ui/navigation/commit/1099f6830b25ceb393e3a4b51d33f92bc5b16760)) + ## [1.1.3](https://github.com/gravity-ui/navigation/compare/v1.1.2...v1.1.3) (2023-10-24) diff --git a/package-lock.json b/package-lock.json index 0fe430f..fe8c3e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@gravity-ui/navigation", - "version": "1.1.3", + "version": "1.2.0", "lockfileVersion": 1, "requires": true, "packages": { diff --git a/package.json b/package.json index d4bc5b5..aaba999 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gravity-ui/navigation", - "version": "1.1.3", + "version": "1.2.0", "description": "Gravity UI Navigation components", "license": "MIT", "repository": { From 1e7dc8249fd869853eeabab45a08c306c95448de Mon Sep 17 00:00:00 2001 From: sunduckcow <83990793+sunduckcow@users.noreply.github.com> Date: Fri, 10 Nov 2023 16:08:29 +0300 Subject: [PATCH 3/3] feat: updated vertical divider (#144) --- README.md | 2 +- src/components/AsideHeader/AsideHeader.scss | 12 +----------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 65ca513..3e36229 100644 --- a/README.md +++ b/README.md @@ -72,4 +72,4 @@ Used for themization Navigation's components | `--gn-aside-header-footer-item-icon-color` | | `--g-color-text-primary` | | `--gn-aside-header-subheader-item-icon-color` | | `--g-color-text-primary` | | `--gn-aside-header-item-icon-background-size` | Background size used when `AsideHeader` is compact | `38px` | -| `--gn-aside-header-divider-line-color` | Vertical color divider between `AsideHeader` and content | Light theme: `transparent`, Dark theme: `--g-color-line-generic-solid` | +| `--gn-aside-header-divider-line-color` | Vertical color divider between `AsideHeader` and content | Light theme: `--g-color-line-generic`, Dark theme: `--g-color-line-generic-solid` | diff --git a/src/components/AsideHeader/AsideHeader.scss b/src/components/AsideHeader/AsideHeader.scss index b8de621..a403647 100644 --- a/src/components/AsideHeader/AsideHeader.scss +++ b/src/components/AsideHeader/AsideHeader.scss @@ -14,7 +14,7 @@ $block: '.#{variables.$ns}aside-header'; .g-root_theme_light, .g-root_theme_light-hc { - --gn-aside-header-divider-line-color: transparent; + --gn-aside-header-divider-line-color: var(--g-color-line-generic); --gn-aside-header-subheader-divider-line-color: var(--g-color-line-generic); } @@ -78,16 +78,6 @@ $block: '.#{variables.$ns}aside-header'; z-index: 2; user-select: none; - &::after { - position: absolute; - top: 0; - right: -100px; - bottom: 0; - width: 100px; - content: ''; - box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.1), 0px 0px 24px rgba(0, 0, 0, 0.08); - } - & > #{$class}-logo { margin: 8px 0; }