Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added AsideHeaderContext #79

Merged
merged 9 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 36 additions & 20 deletions src/components/AsideHeader/AsideHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ export interface AsideHeaderProps

type AsideHeaderInnerProps = AsideHeaderGeneralProps & AsideHeaderDefaultProps;

interface AsideHeaderContextType {
compact: boolean;
size: number;
}

export const AsideHeaderContext = React.createContext<AsideHeaderContextType>({
compact: false,
size: ASIDE_HEADER_COMPACT_WIDTH,
});

export const useAsideHeaderContext = () => React.useContext(AsideHeaderContext);

export class AsideHeader extends React.Component<AsideHeaderInnerProps> {
static defaultProps: AsideHeaderDefaultProps = {
panelItems: [],
Expand All @@ -60,6 +72,8 @@ export class AsideHeader extends React.Component<AsideHeaderInnerProps> {
headerDecoration: true,
};

static contextType = AsideHeaderContext;

asideRef = React.createRef<HTMLDivElement>();

render() {
Expand All @@ -68,18 +82,20 @@ export class AsideHeader extends React.Component<AsideHeaderInnerProps> {
const size = compact ? ASIDE_HEADER_COMPACT_WIDTH : ASIDE_HEADER_EXPANDED_WIDTH;

return (
<div className={b({compact}, className)}>
<div className={b('pane-container')}>
{this.renderFirstPane(size)}
{this.renderSecondPane(size)}
<AsideHeaderContext.Provider value={{compact, size}}>
<div className={b({compact}, className)}>
<div className={b('pane-container')}>
{this.renderFirstPane()}
{this.renderSecondPane()}
</div>
</div>
</div>
</AsideHeaderContext.Provider>
);
}

private renderFirstPane = (size: number) => {
const {dict, menuItems, panelItems, compact, headerDecoration, multipleTooltip} =
this.props;
private renderFirstPane = () => {
const {dict, menuItems, panelItems, headerDecoration, multipleTooltip} = this.props;
const {size} = useAsideHeaderContext();

return (
<React.Fragment>
Expand All @@ -90,7 +106,6 @@ export class AsideHeader extends React.Component<AsideHeaderInnerProps> {
{menuItems?.length ? (
<CompositeBar
items={menuItems}
compact={compact}
enableCollapsing={true}
dict={dict}
onItemClick={this.onItemClick}
Expand All @@ -99,17 +114,18 @@ export class AsideHeader extends React.Component<AsideHeaderInnerProps> {
) : (
<div className={b('menu-items')} />
)}
{this.renderFooter(size)}
{this.renderFooter()}
{this.renderCollapseButton()}
</div>
</div>

{panelItems && this.renderPanels(size)}
{panelItems && this.renderPanels()}
</React.Fragment>
);
};

private renderSecondPane = (size: number) => {
private renderSecondPane = () => {
const {size} = useAsideHeaderContext();
return (
<Content
size={size}
Expand All @@ -119,17 +135,14 @@ export class AsideHeader extends React.Component<AsideHeaderInnerProps> {
);
};

private renderLogo = () => (
<Logo {...this.props.logo} compact={this.props.compact} onClick={this.onLogoClick} />
);
private renderLogo = () => <Logo {...this.props.logo} onClick={this.onLogoClick} />;

private renderHeader = () => (
<div className={b('header', {['with-decoration']: this.props.headerDecoration})}>
{this.renderLogo()}

<CompositeBar
items={this.props.subheaderItems}
compact={this.props.compact}
enableCollapsing={false}
onItemClick={this.onItemClick}
/>
Expand All @@ -143,8 +156,9 @@ export class AsideHeader extends React.Component<AsideHeaderInnerProps> {
</div>
);

private renderFooter = (size: number) => {
const {compact, renderFooter} = this.props;
private renderFooter = () => {
const {renderFooter} = this.props;
const {size, compact} = useAsideHeaderContext();

return (
<div className={b('footer')}>
Expand All @@ -157,8 +171,9 @@ export class AsideHeader extends React.Component<AsideHeaderInnerProps> {
);
};

private renderPanels = (size: number) => {
private renderPanels = () => {
const {panelItems} = this.props;
const {size} = useAsideHeaderContext();

return (
<Drawer
Expand All @@ -175,7 +190,8 @@ export class AsideHeader extends React.Component<AsideHeaderInnerProps> {
};

private renderCollapseButton = () => {
const {compact, dict} = this.props;
const {dict} = this.props;
const {compact} = useAsideHeaderContext();
const typeButton = compact ? Dict.ExpandButton : Dict.CollapseButton;

return (
Expand Down
8 changes: 2 additions & 6 deletions src/components/CompositeBar/CompositeBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ import './CompositeBar.scss';
import {MultipleTooltip, MultipleTooltipContext, MultipleTooltipProvider} from './MultipleTooltip';
import {COLLAPSE_ITEM_ID} from './constants';
import {ASIDE_HEADER_COMPACT_WIDTH} from '../constants';
import {useAsideHeaderContext} from '../AsideHeader/AsideHeader';

const b = block('composite-bar');

interface CompositeBarBaseProps {
items: MenuItem[];
compact: boolean;
onItemClick?: (item: MenuItem, collapsed: boolean) => void;
multipleTooltip?: boolean;
}
Expand All @@ -39,7 +39,6 @@ export interface CompositeBarProps extends CompositeBarBaseProps {

const CompositeBarView: FC<CompositeBarViewProps> = ({
items,
compact,
onItemClick,
collapseItems,
multipleTooltip = true,
Expand All @@ -52,6 +51,7 @@ const CompositeBarView: FC<CompositeBarViewProps> = ({
activeIndex,
lastClickedItemIndex,
} = useContext(MultipleTooltipContext);
const {compact} = useAsideHeaderContext();

const onTooltipMouseEnter = useCallback(
(e) => {
Expand Down Expand Up @@ -156,7 +156,6 @@ const CompositeBarView: FC<CompositeBarViewProps> = ({
onMouseEnter={onMouseEnterByIndex(itemIndex)}
onMouseLeave={onMouseLeave}
onItemClick={onItemClickByIndex(itemIndex)}
compact={compact}
collapseItems={collapseItems}
enableTooltip={!multipleTooltip}
/>
Expand All @@ -175,7 +174,6 @@ const CompositeBarView: FC<CompositeBarViewProps> = ({

export const CompositeBar: FC<CompositeBarProps> = ({
items,
compact,
enableCollapsing,
dict,
onItemClick,
Expand Down Expand Up @@ -203,7 +201,6 @@ export const CompositeBar: FC<CompositeBarProps> = ({
<div style={{width, height}}>
<CompositeBarView
items={listItems}
compact={compact}
onItemClick={onItemClick}
collapseItems={collapseItems}
multipleTooltip={multipleTooltip}
Expand All @@ -220,7 +217,6 @@ export const CompositeBar: FC<CompositeBarProps> = ({
<div className={b()}>
<CompositeBarView
items={items}
compact={compact}
onItemClick={onItemClick}
multipleTooltip={multipleTooltip}
/>
Expand Down
7 changes: 4 additions & 3 deletions src/components/CompositeBar/Item/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from '../constants';

import './Item.scss';
import {useAsideHeaderContext} from '../../AsideHeader/AsideHeader';

const b = block('composite-bar-item');

Expand All @@ -38,7 +39,6 @@ export interface ItemProps extends ItemPopup {
}

interface ItemInnerProps extends ItemProps {
compact: boolean;
className?: string;
collapseItems?: MenuItem[];
onMouseEnter?: () => void;
Expand Down Expand Up @@ -66,7 +66,6 @@ export const defaultPopupOffset: NonNullable<PopupProps['offset']> = [-20, 8];
export const Item: React.FC<ItemInnerProps> = (props) => {
const {
item,
compact,
className,
collapseItems,
onMouseLeave,
Expand All @@ -82,6 +81,8 @@ export const Item: React.FC<ItemInnerProps> = (props) => {
onItemClick,
} = props;

const {compact} = useAsideHeaderContext();

if (item.type === 'divider') {
return <div className={b('menu-divider')} />;
}
Expand Down Expand Up @@ -224,12 +225,12 @@ interface CollapsedPopupProps {
}

function CollapsedPopup({
compact,
onItemClick,
collapseItems,
anchorRef,
onClose,
}: ItemInnerProps & CollapsedPopupProps) {
const {compact} = useAsideHeaderContext();
return collapseItems?.length ? (
<Popup placement={POPUP_PLACEMENT} open={true} anchorRef={anchorRef} onClose={onClose}>
<div className={b('collapse-items-popup-content')}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {ASIDE_HEADER_COMPACT_WIDTH, ASIDE_HEADER_EXPANDED_WIDTH} from '../../con
import {menuItemsShowcase} from './moc';

import './CompositeBarShowcase.scss';
import {AsideHeaderContext} from '../../AsideHeader/AsideHeader';

export default {
title: 'Components/AsideHeader/CompositeBar',
Expand All @@ -29,12 +30,13 @@ export default {

const Template: StoryFn<CompositeBarProps> = (args) => (
<div className="composite-bar-showcase">
<CompositeBar {...args} />
<AsideHeaderContext.Provider value={{compact: false, size: ASIDE_HEADER_EXPANDED_WIDTH}}>
<CompositeBar {...args} />
</AsideHeaderContext.Provider>
</div>
);

export const Default = Template.bind({});
Default.args = {
compact: false,
items: menuItemsShowcase,
};
2 changes: 1 addition & 1 deletion src/components/Content/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const RenderContent: React.FC<RenderContentProps> = React.memo(({renderContent,
RenderContent.displayName = 'RenderContent';

export const Content: React.FC<ContentProps> = ({
size,
size, // TODO: move to context when MobileHeader will support it
className,
cssSizeVariableName = '--aside-header-size',
renderContent,
Expand Down
7 changes: 3 additions & 4 deletions src/components/Logo/Logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ import {LogoProps} from '../types';
import {Button, Icon} from '@gravity-ui/uikit';

import './Logo.scss';
import {useAsideHeaderContext} from '../AsideHeader/AsideHeader';

const b = block('logo');

interface LogoInnerProps extends LogoProps {
compact: boolean;
}
interface LogoInnerProps extends LogoProps {}
sunduckcow marked this conversation as resolved.
Show resolved Hide resolved

export const Logo: React.FC<LogoInnerProps> = ({
text,
compact,
icon,
iconSrc,
iconClassName,
Expand All @@ -23,6 +21,7 @@ export const Logo: React.FC<LogoInnerProps> = ({
wrapper,
onClick,
}) => {
const {compact} = useAsideHeaderContext();
const hasClickHandler = typeof onClick === 'function';
const hasWrapper = typeof wrapper === 'function';

Expand Down