Skip to content

Commit

Permalink
feat(menus): Added Dropmenu component
Browse files Browse the repository at this point in the history
  • Loading branch information
Temzasse committed Sep 12, 2017
1 parent 8a5cb8b commit 8eb5f41
Show file tree
Hide file tree
Showing 7 changed files with 228 additions and 9 deletions.
67 changes: 62 additions & 5 deletions docs/src/components/Navigation.js → docs/src/components/Menus.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ import {
Button,
ToggleSwitch,
Text,
Divider,
Dropmenu,
Icon,
} from 'react-components-kit';

import Properties from './common/Properties';
import CodeBlock from './common/CodeBlock';
import { drawerExample } from './codeSnippets';
import { drawerProperties } from './compProperties';
import { drawerExample, dropmenuExample } from './codeSnippets';
import { drawerProperties, dropmenuProperties } from './compProperties';

class Navigation extends Component {
class Menus extends Component {
state = {
drawerOpen: false,
drawerSide: 'left',
Expand All @@ -35,7 +38,7 @@ class Navigation extends Component {

return (
<div>
<Heading>Navigation</Heading>
<Heading>Menus</Heading>

<Heading h2>Drawer</Heading>

Expand Down Expand Up @@ -90,9 +93,63 @@ class Navigation extends Component {
<Layout>
<Properties properties={drawerProperties} />
</Layout>

<Divider />

<Heading h2>Dropmenu</Heading>

<Gutter vertical amount='16px' />

<Layout justify='space-around' align='center'>
<Dropmenu
trigger={
<Button primary>
Open menu&nbsp;
<Icon
name='android-more-vertical'
color='#fff'
style={{ padding: 6 }}
/>
</Button>
}
>
<Dropmenu.Item>Foo</Dropmenu.Item>
<Dropmenu.Item>Bar</Dropmenu.Item>
<Dropmenu.Item>Baz</Dropmenu.Item>
<Divider amount='0px' />
<Dropmenu.Item>Baz</Dropmenu.Item>
</Dropmenu>

<Dropmenu
trigger={
<Icon
name='grid'
size='32px'
color='rebeccapurple'
touchable
/>
}
>
<Dropmenu.Item>Foo</Dropmenu.Item>
<Dropmenu.Item>Bar</Dropmenu.Item>
<Dropmenu.Item>Baz</Dropmenu.Item>
<Divider amount='0px' />
<Dropmenu.Item>Baz</Dropmenu.Item>
</Dropmenu>
</Layout>

<Gutter vertical amount='16px' />

<Layout>
<CodeBlock code={dropmenuExample} />
</Layout>

<Layout>
<Properties properties={dropmenuProperties} />
</Layout>
</div>
);
}
}

export default Navigation;
export default Menus;
4 changes: 2 additions & 2 deletions docs/src/components/Sections.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Form from './Form';
import Utilities from './Utilities';
import Other from './Other';
import Cards from './Cards';
import Navigation from './Navigation';
import Menus from './Menus';

const propTypes = {
something: PropTypes.any,
Expand All @@ -32,7 +32,7 @@ class Sections extends Component {
<Route path='/buttons' component={Buttons} />
<Route path='/cards' component={Cards} />
<Route path='/form' component={Form} />
<Route path='/navigation' component={Navigation} />
<Route path='/menus' component={Menus} />
<Route path='/structure' component={Structure} />
<Route path='/typography' component={Typography} />
<Route path='/utilities' component={Utilities} />
Expand Down
5 changes: 3 additions & 2 deletions docs/src/components/Sidemenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ class Sidemenu extends Component {

<Gutter vertical />

<SectionTitle to='/navigation'>Navigation</SectionTitle>
<MenuItem to='/navigation#drawer'>Drawer</MenuItem>
<SectionTitle to='/menus'>Menus</SectionTitle>
<MenuItem to='/menus#drawer'>Drawer</MenuItem>
<MenuItem to='/menus#dropmen'>Dropmenu</MenuItem>

<Gutter vertical />

Expand Down
25 changes: 25 additions & 0 deletions docs/src/components/codeSnippets.js
Original file line number Diff line number Diff line change
Expand Up @@ -368,3 +368,28 @@ const Example = () => (
</div>
);
`;

export const dropmenuExample = `
import { Dropmenu } from 'react-components-kit';
const Example = () => (
<div>
<Dropmenu
trigger={
<Icon
name='grid'
size='32px'
color='rebeccapurple'
touchable
/>
}
>
<Dropmenu.Item>Foo</Dropmenu.Item>
<Dropmenu.Item>Bar</Dropmenu.Item>
<Dropmenu.Item>Baz</Dropmenu.Item>
<Divider amount='0px' />
<Dropmenu.Item>Baz</Dropmenu.Item>
</Dropmenu>
</div>
);
`;
13 changes: 13 additions & 0 deletions docs/src/components/compProperties.js
Original file line number Diff line number Diff line change
Expand Up @@ -497,4 +497,17 @@ export const drawerProperties = [
},
];

export const dropmenuProperties = [
{
name: 'trigger *',
type: 'any',
description: 'A valid React component that triggers showing the menu on click',
},
{
name: 'children *',
type: 'any',
description: 'Menu content (note that you can use Dropmenu.Item here)',
},
];

/* eslint-enable max-len */
122 changes: 122 additions & 0 deletions src/Dropmenu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled, { css } from 'styled-components';
import withRipple from './withRipple';
import OutsideReactor from './OutsideReactor';

const propTypes = {
trigger: PropTypes.any.isRequired,
children: PropTypes.any,
};

const ItemEl = styled.div`
padding: 8px 12px;
color: #222;
font-size: 16px;
`;

const Item = withRipple(ItemEl);

class Dropmenu extends Component {
static Item = Item;

state = {
isOpen: false,
}

closeMenu = () => {
if (this.state.isOpen) this.setState({ isOpen: false });
};

toggleMenu = () => {
this.setState(prev => ({ isOpen: !prev.isOpen }));
};

render() {
const { children, trigger } = this.props;
const { isOpen } = this.state;

return (
<Wrapper onClickedOutside={this.closeMenu}>
<Trigger onClick={this.toggleMenu}>
{trigger}
</Trigger>

<MenuWrapper isOpen={isOpen}>
<Menu>
{children}
</Menu>
</MenuWrapper>
</Wrapper>
);
}
}

const ARROW_HEIGHT = 12;

const Wrapper = styled(OutsideReactor)`
position: relative;
display: inline-block;
`;

const MenuWrapper = styled.div`
position: absolute;
background-color: #fff;
box-shadow: 0px 2px 8px rgba(0,0,0,0.2);
bottom: 0;
left: 50%;
border-radius: 6px;
z-index: 99;
transform: translate(-50%, calc(100% + 40px));
transition:
transform 0.3s cubic-bezier(0.2, 0.71, 0.14, 0.91),
opacity 0.3s ease;
${props => props.isOpen && css`
opacity: 1;
visibility: visible;
transform: translate(-50%, calc(100% + 12px));
`}
${props => !props.isOpen && css`
visibility: hidden;
pointer-events: none;
opacity: 0;
`}
`;

const Menu = styled.div`
position: relative;
display: flex;
flex-direction: column;
min-width: 200px;
& > div {
width: 100%;
}
&:after {
content: "";
width: 0px;
height: 0px;
position: absolute;
border-bottom: ${`${ARROW_HEIGHT}px solid`};
border-left: ${`${ARROW_HEIGHT}px solid transparent`};
border-right: ${`${ARROW_HEIGHT}px solid transparent`};
border-bottom-color: #f5f5f5;
left: ${`calc(50% - ${ARROW_HEIGHT}px)`};
top: -${ARROW_HEIGHT}px;
}
`;

const Trigger = styled.div`
position: relative;
display: inline-block;
border: none;
background: none;
padding: 0;
`;

Dropmenu.propTypes = propTypes;

export default Dropmenu;
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ export { default as Table } from './Table';
export { default as TextField } from './TextField';
export { default as OutsideReactor } from './OutsideReactor';
export { default as Drawer } from './Drawer';
export { default as Dropmenu } from './Dropmenu';

0 comments on commit 8eb5f41

Please sign in to comment.