Skip to content

Commit

Permalink
feat: add standalone navigation (#693)
Browse files Browse the repository at this point in the history
* feat: add standalone navigation
  • Loading branch information
gorgeousvlad authored Nov 15, 2023
1 parent c683873 commit 38d5b88
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 21 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,16 @@ const Page: React.FC<PageProps> = ({children}) => (
);
```

### Navigation

Page navigation can also be used separately from the constructor:

```jsx
import {Navigation} from '@gravity-ui/page-constructor';

const Page: React.FC<PageProps> = ({data, logo}) => <Navigation data={data} logo={logo} />;
```

### Blocks

Each block is an atomic top-level component. They're stored in the `src/units/constructor/blocks` directory.
Expand Down
13 changes: 13 additions & 0 deletions src/components/RootCn/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React, {PropsWithChildren} from 'react';

import {useTheme} from '../../context/theme';
import {ClassNameProps} from '../../models';
import {rootCn} from '../../utils';

const RootCn = ({className, children}: PropsWithChildren<ClassNameProps>) => {
const theme = useTheme();

return <div className={rootCn({theme}, className)}>{children}</div>;
};

export default RootCn;
8 changes: 3 additions & 5 deletions src/containers/PageConstructor/PageConstructor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, {useMemo} from 'react';
import '@doc-tools/transform/dist/js/yfm';

import BackgroundMedia from '../../components/BackgroundMedia/BackgroundMedia';
import {UIKIT_ROOT_CLASS} from '../../components/constants';
import RootCn from '../../components/RootCn';
import {blockMap, navItemMap, subBlockMap} from '../../constructor-items';
import {AnimateContext} from '../../context/animateContext';
import {InnerContext} from '../../context/innerContext';
Expand All @@ -23,7 +23,6 @@ import {
} from '../../models';
import Layout from '../../navigation/containers/Layout/Layout';
import {
cn as blockOrigin,
block as cnBlock,
getCustomItems,
getCustomTypes,
Expand All @@ -39,7 +38,6 @@ import {ConstructorRow} from './components/ConstructorRow';
import './PageConstructor.scss';

const b = cnBlock('page-constructor');
const ycr = blockOrigin(UIKIT_ROOT_CLASS);

export type ItemMap = typeof blockMap & typeof subBlockMap & CustomItems;

Expand Down Expand Up @@ -99,7 +97,7 @@ export const Constructor = (props: PageConstructorProps) => {

return (
<InnerContext.Provider value={context}>
<div className={b(null, ycr({theme}))}>
<RootCn>
<div className={b('wrapper')}>
{themedBackground && (
<BackgroundMedia {...themedBackground} className={b('background')} />
Expand All @@ -118,7 +116,7 @@ export const Constructor = (props: PageConstructorProps) => {
</Grid>
</Layout>
</div>
</div>
</RootCn>
</InnerContext.Provider>
);
};
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ export * from './utils';
export * from './schema';
export * from './hooks';
export * from './icons';
export * from './navigation';

export {BREAKPOINTS} from './constants';
7 changes: 0 additions & 7 deletions src/navigation/components/Navigation/Navigation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@
$block: '.#{$ns}navigation';

#{$block} {
$root: &;
$navigationZIndex: 98;

position: sticky;
z-index: $navigationZIndex;
top: 0;

display: flex;
justify-content: center;
align-items: center;
Expand Down
8 changes: 4 additions & 4 deletions src/navigation/components/Navigation/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import debounce from 'lodash/debounce';

import OutsideClick from '../../../components/OutsideClick/OutsideClick';
import {Col, Grid, Row} from '../../../grid';
import {HeaderData, ThemedNavigationLogoData} from '../../../models';
import {ClassNameProps, HeaderData, ThemedNavigationLogoData} from '../../../models';
import {block} from '../../../utils';
import {getNavigationItemWithIconSize} from '../../utils';
import DesktopNavigation from '../DesktopNavigation/DesktopNavigation';
Expand All @@ -14,12 +14,12 @@ import './Navigation.scss';

const b = block('navigation');

export interface NavigationProps {
export interface NavigationProps extends ClassNameProps {
logo: ThemedNavigationLogoData;
data: HeaderData;
}

export const Navigation: React.FC<NavigationProps> = ({data, logo}) => {
export const Navigation: React.FC<NavigationProps> = ({data, logo, className}) => {
const {leftItems, rightItems, iconSize = 20, withBorder = false} = data;
const [isSidebarOpened, setIsSidebarOpened] = useState(false);
const [activeItemId, setActiveItemId] = useState<string | undefined>(undefined);
Expand Down Expand Up @@ -56,7 +56,7 @@ export const Navigation: React.FC<NavigationProps> = ({data, logo}) => {
});

return (
<Grid className={b({'with-border': showBorder})}>
<Grid className={b({'with-border': showBorder}, className)}>
<Row>
<Col>
<nav>
Expand Down
7 changes: 4 additions & 3 deletions src/navigation/components/NavigationItem/NavigationItem.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React, {useContext, useMemo} from 'react';
import React, {useMemo} from 'react';

import omit from 'lodash/omit';

import {BlockIdContext} from '../../../context/blockIdContext';
import {InnerContext} from '../../../context/innerContext';
import {CustomItem, NavigationItemType} from '../../../models';
import {block} from '../../../utils';
import {NavigationItemProps} from '../../models';

import {useNavigationItemMap} from './hooks/useNavigationItemMap';

import './NavigationItem.scss';

const b = block('navigation-item');
Expand All @@ -21,7 +22,7 @@ const NavigationItem: React.FC<NavigationItemProps> = ({
...props
}: NavigationItemProps) => {
const {type = NavigationItemType.Link} = data;
const {navItemMap} = useContext(InnerContext);
const navItemMap = useNavigationItemMap();
const Component = navItemMap[type] as CustomItem;
const componentProps = useMemo(() => {
const componentProperties = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {useContext} from 'react';

import isEmpty from 'lodash/isEmpty';

import {navItemMap as NavItemMapDefault} from '../../../../constructor-items';
import {InnerContext} from '../../../../context/innerContext';

export const useNavigationItemMap = () => {
const {navItemMap} = useContext(InnerContext);

return isEmpty(navItemMap) ? NavItemMapDefault : navItemMap;
};
13 changes: 13 additions & 0 deletions src/navigation/components/Standalone/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';

import RootCn from '../../../components/RootCn';

import Navigation, {NavigationProps} from './../../components/Navigation/Navigation';

const Standalone = (props: NavigationProps) => (
<RootCn>
<Navigation {...props} />
</RootCn>
);

export default Standalone;
12 changes: 11 additions & 1 deletion src/navigation/containers/Layout/Layout.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
.layout {
@import '../../../../styles/variables';

$block: '.#{$ns}layout';

#{$block} {
display: flex;
flex-direction: column;

Expand All @@ -9,4 +13,10 @@
flex-grow: 1;
flex-direction: column;
}

&__navigation {
position: sticky;
z-index: 98;
top: 0;
}
}
8 changes: 7 additions & 1 deletion src/navigation/containers/Layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ export interface LayoutProps {

const Layout: React.FC<LayoutProps> = ({children, navigation}) => (
<div className={b()}>
{navigation && <Navigation data={navigation.header} logo={navigation.logo} />}
{navigation && (
<Navigation
data={navigation.header}
logo={navigation.logo}
className={b('navigation')}
/>
)}
<main className={b('content')}>{children}</main>
</div>
);
Expand Down
1 change: 1 addition & 0 deletions src/navigation/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {default as Navigation} from './components/Standalone';
3 changes: 3 additions & 0 deletions src/utils/cn.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import {withNaming} from '@bem-react/classname';

import {UIKIT_ROOT_CLASS} from '../components/constants';

export const NAMESPACE = 'pc-';

export const cn = withNaming({e: '__', m: '_'});
export const block = withNaming({n: NAMESPACE, e: '__', m: '_'});
export const rootCn = cn(UIKIT_ROOT_CLASS);

export type CnBlock = ReturnType<typeof cn>;

0 comments on commit 38d5b88

Please sign in to comment.