Skip to content

Commit

Permalink
WIP navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
EranNL committed Dec 28, 2020
1 parent 34a4a16 commit 820ab58
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 59 deletions.
46 changes: 27 additions & 19 deletions src/components/Navigation/Vertical/ListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { NavigationContext } from './NavigationContext';

interface NavigationListItemProps extends React.HTMLAttributes<HTMLDivElement> {
active?: boolean;
content?: React.ReactNode;
icon?: React.ReactElement;
}

Expand All @@ -15,25 +17,31 @@ const NavigationListItem = React.forwardRef<HTMLDivElement, NavigationListItemPr
icon
},
ref
): React.ReactElement => (
<div
ref={ref}
className={clsx(
'vertical-navigation-list-item',
active && 'active',
className
)}
>
{icon && (
<div className="vertical-navigation-list-item-icon">
{icon}
</div>
)}
<span className="vertical-navigation-list-item-text">
{children}
</span>
</div>
));
): React.ReactElement => {
return (
<NavigationContext.Consumer>
{() => (
<div
ref={ref}
className={clsx(
'vertical-navigation-list-item',
active && 'active',
className
)}
>
{icon && (
<div className="vertical-navigation-list-item-icon">
{icon}
</div>
)}
<span className="vertical-navigation-list-item-text">
{children}
</span>
</div>
)}
</NavigationContext.Consumer>
)
});

NavigationListItem.displayName = 'NavigationListItem';
NavigationListItem.propTypes = {
Expand Down
10 changes: 10 additions & 0 deletions src/components/Navigation/Vertical/NavigationContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { createContext } from 'react';
export interface NavigationContextProps {
tooltipsWhenCollapsed: boolean;
collapsed: boolean;
}

export const NavigationContext = createContext<NavigationContextProps>({
tooltipsWhenCollapsed: true,
collapsed: false
});
71 changes: 53 additions & 18 deletions src/components/Navigation/VerticalNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import NavigationTop from '@/components/Navigation/Vertical/Top';
import NavigationList from '@/components/Navigation/Vertical/List';
import NavigationListItem from '@/components/Navigation/Vertical/ListItem';
import NavigationDivider from '@/components/Navigation/Vertical/Divider';
import { useState } from 'react';
import { VerticalNavigationScope } from './Vertical/VerticalNavigationScope';
import { useEffect, useState } from 'react';
import { VerticalNavigationScope } from '@/components/Navigation/Vertical/VerticalNavigationScope';
import { NavigationContext } from './Vertical/NavigationContext';

export interface VerticalNavigationStatics {
Top: typeof NavigationTop;
Expand All @@ -17,26 +18,51 @@ export interface VerticalNavigationStatics {
Divider: typeof NavigationDivider;
}

export interface SideNavigationProps extends React.HTMLAttributes<HTMLDivElement> {
export interface VerticalNavigationProps extends React.HTMLAttributes<HTMLDivElement> {
/**
* Variant of the menu. With this prop, the color of the menu can be set.
*/
variant?: Variant | string;
/**
* Indicates whether the menu collapse is controllable.
*/
collapsable?: boolean;
/**
* Indicating whether the menu is collapsed. Can be used to make the navigation a controllable component
*/
collapsed?: boolean;
/**
* Indicates whether a tooltip with the menu text must be shown when menu is collapsed. Default: true
*/
tooltipsWhenCollapsed?: boolean;
/**
* Children of the menu. This can be either a React ChildNode or callback function to access various actions
*/
children: React.ReactNode | ((scope: VerticalNavigationScope) => React.ReactNode);
}

// @ts-ignore
const VerticalNavigation: ForwardComponentWithStatics<HTMLDivElement, SideNavigationProps, VerticalNavigationStatics> =
const VerticalNavigation: ForwardComponentWithStatics<HTMLDivElement, VerticalNavigationProps, VerticalNavigationStatics> =
React.forwardRef((
{
children,
className,
variant
variant,
collapsed,
tooltipsWhenCollapsed = true
},
ref
): React.ReactElement => {
const [collapsed, setCollapsed] = useState<boolean>(false);
const [isCollapsed, setCollapsed] = useState<boolean>(false);

useEffect(() => {
if (collapsed) {
setCollapsed(collapsed);
}
}, [collapsed])

const makeScope = (): VerticalNavigationScope => ({
collapsed,
collapsed: isCollapsed,
collapse: () => setCollapsed(!collapsed)
});

Expand All @@ -45,25 +71,34 @@ const VerticalNavigation: ForwardComponentWithStatics<HTMLDivElement, SideNaviga
: children;

return (
<div
ref={ref}
className={clsx(
'vertical-navigation-container',
collapsed && 'is-collapsed',
variant && `navigation-${variant}`,
className
)}
<NavigationContext.Provider
value={{
tooltipsWhenCollapsed: tooltipsWhenCollapsed,
collapsed: isCollapsed
}}
>
{children}
</div>
<div
ref={ref}
className={clsx(
'vertical-navigation-container',
isCollapsed && 'is-collapsed',
variant && `navigation-${variant}`,
className
)}
>
{children}
</div>
</NavigationContext.Provider>
)
});

VerticalNavigation.displayName = 'VerticalNavigation';
VerticalNavigation.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
variant: PropTypes.string
variant: PropTypes.string,
collapsed: PropTypes.bool,
tooltipsWhenCollapsed: PropTypes.bool
}

VerticalNavigation.Top = NavigationTop;
Expand Down
6 changes: 5 additions & 1 deletion src/components/Overlay/OverlayTrigger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Overlay from '@/components/Overlay/index';
import { Placement, PositioningStrategy } from '@popperjs/core';
import { Trigger, triggerPropTypes } from '@/components/Overlay/Trigger';
import { AnimatePresence } from 'framer-motion';
import { Modifier } from '@popperjs/core/lib/types';

interface OverlayTriggerProps {
arrow?: boolean;
Expand All @@ -15,6 +16,7 @@ interface OverlayTriggerProps {
className?: string;
trigger?: Trigger | string;
motion?: string;
config?: Array<Partial<Modifier<any, any>>>;
}

const OverlayTrigger = ({
Expand All @@ -25,7 +27,8 @@ const OverlayTrigger = ({
placement,
positionStrategy,
trigger = 'hover',
motion
motion,
config
}: OverlayTriggerProps): React.ReactElement => {
const [shown, setShown] = useState<boolean>(false);
const triggerRef = useRef<HTMLElement>();
Expand Down Expand Up @@ -71,6 +74,7 @@ const OverlayTrigger = ({
placement={placement}
positionStrategy={positionStrategy}
className={className}
config={config}
>
{overlay}
</Overlay>
Expand Down
7 changes: 5 additions & 2 deletions src/components/Overlay/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ interface OverlayProps {
arrow?: boolean;
positionStrategy?: PositioningStrategy;
motion?: string;
config?: Array<Partial<Modifier<any, any>>>;
}

const Overlay = ({
Expand All @@ -29,7 +30,8 @@ const Overlay = ({
placement = 'top',
arrow = true,
positionStrategy = 'absolute',
motion: triggerMotion
motion: triggerMotion,
config
}: React.PropsWithChildren<OverlayProps>): React.ReactElement => {
const ref = useRef<HTMLDivElement | null>(null);
const popper = useRef<PopperInstance>();
Expand All @@ -40,7 +42,8 @@ const Overlay = ({
options: {
element: '.arrow'
}
}] : [])
}] : []),
...(config || [])
]);

const createPopperOptions = (): PopperOptions => ({
Expand Down
13 changes: 5 additions & 8 deletions src/style/components/_navigation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,6 @@
.vertical-navigation-list-item-text {
display: none;
}

&:hover {
white-space: nowrap;

.vertical-navigation-list-item-text {
display: block;
}
}
}
}
}
Expand All @@ -98,3 +90,8 @@
background: var(--primary-color-light-background);
}
}

.vertical-navigation-tooltip {
margin-left: 0.5rem;
background: #000;
}
29 changes: 18 additions & 11 deletions www/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { useState } from 'react';
import * as ReactDom from 'react-dom';
import '../../src/style/index.scss';
import { Button, Card, Col, Grid, Icon, Page, Row, SelectField, Tag, TextField, Variant } from '../../src';
import logo from '@/images/coderan/logo.svg';
import logoFull from '@/images/coderan/logo.svg';
import logoLetter from '@/images/coderan/logo-letter.svg';
import Container from '../../src/components/Container/Container';
import FormGroup from '../../src/components/Form/Group';
import FormLabel from '../../src/components/Form/Label';
Expand Down Expand Up @@ -36,21 +37,27 @@ const TestControllable = () => {
ReactDom.render(
<Page>
<Page.Left fixed>
<VerticalNavigation collapsable>
{({ collapse }) => (
<VerticalNavigation collapsed>
{({ collapse, collapsed }) => (
<>
<VerticalNavigation.Top className="justify-content-center mb-4">
<button onClick={collapse}></button>
<img src={logo} width={160} className="mb-8" />
{collapsed ? (
<img src={logoLetter} height={36} />
) : (
<img src={logoFull} height={36} />
)}
</VerticalNavigation.Top>
<VerticalNavigation.Divider />
<VerticalNavigation.List>
<VerticalNavigation.Item active icon={<Icon icon="home" />}>
Home
</VerticalNavigation.Item>
<VerticalNavigation.Item icon={<Icon icon="user" />}>
User
</VerticalNavigation.Item>
<VerticalNavigation.Item
active
icon={<Icon icon="home" />}
content="Home"
/>
<VerticalNavigation.Item
icon={<Icon icon="user" />}
content="Tooltips"
/>
</VerticalNavigation.List>
</>
)}
Expand Down

0 comments on commit 820ab58

Please sign in to comment.