Skip to content

Commit

Permalink
feat: new TopBar and SideBar (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
schne324 authored May 6, 2020
1 parent a31e095 commit f8337ed
Show file tree
Hide file tree
Showing 29 changed files with 768 additions and 615 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ module.exports = {
allowChildren: true
}
],
'@typescript-eslint/camelcase': 'off'
'@typescript-eslint/camelcase': 'off',
'@typescript-eslint/explicit-function-return-type': 'off'
},
settings: {
react: {
Expand Down
109 changes: 109 additions & 0 deletions docs/assets/img/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions docs/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,28 @@ code {
.dqpl-pointer-wrap:not(.dqpl-ftpo-auto) {
position: relative;
}

.dqpl-logo-item {
padding: 0;
}

.dqpl-logo-item img {
width: 38px;
}

[role='menubar'] .dqpl-options-menu {
width: 140px;
top: calc(var(--top-bar-height) - 6px);
}

.dqpl-top-bar-thin [role='menubar'] .dqpl-options-menu {
top: calc(var(--top-bar-height-thin) - 6px);
}

.dropdown-arrow-down::after {
content: '';
border: 6px solid transparent;
border-top: 7px solid;
border-bottom: 0 none;
margin-left: 5px;
}
142 changes: 91 additions & 51 deletions docs/index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import React, { Component } from 'react';
import React, { Component, createRef, Fragment } from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import { Helmet } from 'react-helmet';
import classNames from 'classnames';
import Home from './Home';
import {
TopBar,
Workspace,
TopBarTrigger,
TopBarItem,
Workspace,
SideBar,
SideBarItem,
SkipLink,
MenuItem,
OptionsMenuList,
TopBarMenu
TopBarMenu,
Icon
} from '../packages/react/src';
import logo from './assets/img/logo.svg';

// styles
import '../packages/styles';
Expand Down Expand Up @@ -41,21 +45,38 @@ const componentsList = [
].sort();

class App extends Component {
state = { show: false };
state = { show: false, thin: false };
constructor() {
super();
this.onTriggerClick = this.onTriggerClick.bind(this);
this.topBarTrigger = createRef();
}

componentDidMount() {
document.addEventListener('focusTopBarMenu', this.focusTopBarMenuItem);
}

componentWillUnmount() {
document.removeEventListener('focusTopBarMenu', this.focusTopBarMenuItem);
}

focusTopBarMenuItem = () => {
if (!this.topBarMenuItem) {
return;
}

this.topBarMenuItem.focus();
};

onTriggerClick(e) {
const { show } = this.state;

if (e) {
e.preventDefault();
}

if (show && this.topBarTrigger) {
this.topBarTrigger.focus();
if (show && this.topBarTrigger.current) {
this.topBarTrigger.current.focus();
}

this.setState({ show: !show });
Expand All @@ -71,21 +92,13 @@ class App extends Component {
this.setState({ menuOpen: false });
};

toggleTopBarMenu = () => {
this.setState(({ showTopBarMenu }) => ({
showTopBarMenu: !showTopBarMenu
}));
onSettingsSelect = e => {
this.setState({
thin: e.target.innerText === 'Thin top bar'
});
};

componentDidMount() {
document.addEventListener('topbarmenutoggle', this.toggleTopBarMenu);
}

componentWillUnmount() {
document.removeEventListener('topbarmenutoggle', this.toggleTopBarMenu);
}

renderSideBarLink(pathname, text) {
renderSideBarLink(pathname, text, isCurrent) {
return (
<Link
to={{
Expand All @@ -96,15 +109,15 @@ class App extends Component {
this.setState({ show: false });
this.workspace.focus();
}}
tabIndex={-1}
aria-current={isCurrent ? 'page' : null}
>
{text}
</Link>
);
}

render() {
const { showTopBarMenu } = this.state;
const { show, thin } = this.state;

/* eslint-disable jsx-a11y/anchor-has-content */
return (
Expand All @@ -115,45 +128,72 @@ class App extends Component {
defaultTitle="Deque Cauldron React"
/>
<SkipLink target={'#main-content'} />
<TopBar hasTrigger={true}>
<TopBarTrigger
onClick={this.onTriggerClick}
menuItemRef={el => (this.topBarTrigger = el)}
/>
<MenuItem>
<Link tabIndex={-1} to="/">
Cauldron
<TopBar thin={thin} hasTrigger>
<TopBarTrigger onClick={this.onTriggerClick}>
<button
tabIndex={-1}
aria-label="Menu"
aria-haspopup="true"
ref={this.topBarTrigger}
aria-expanded={show}
>
<Icon type="fa-bars" />
</button>
</TopBarTrigger>
<TopBarItem>
<Link to="/" className="dqpl-logo-item" tabIndex={-1}>
<img src={logo} alt="" /> <span>Cauldron</span>
</Link>
</MenuItem>
</TopBarItem>

{/* The below line demonstrates the ability to conditionally include menu item children. */}
{false && <MenuItem>Potato</MenuItem>}

{showTopBarMenu && (
<TopBarMenu id="topbar-menu" className="dqpl-right-aligned">
{`I'm a menu thingy`}
<OptionsMenuList>
<li>Item 1</li>
<li>Item 2</li>
</OptionsMenuList>
</TopBarMenu>
)}

<MenuItem className={showTopBarMenu ? '' : 'dqpl-right-aligned'}>
{false && <TopBarItem>Potato</TopBarItem>}

<TopBarMenu
id="topbar-menu"
className="dqpl-right-aligned dqpl-separator dropdown-arrow-down"
menuItemRef={el => (this.topBarMenuItem = el)}
>
<div className="dqpl-top-bar-icon-item">
{thin ? (
<Icon type="fa-cog" label="Settings" />
) : (
<Fragment>
<Icon type="fa-cog" />
<div>Settings</div>
</Fragment>
)}
</div>
<OptionsMenuList onSelect={this.onSettingsSelect}>
<li>Default top bar</li>
<li>Thin top bar</li>
</OptionsMenuList>
</TopBarMenu>

<TopBarItem className="dqpl-separator">
<a
tabIndex={-1}
href="https://github.com/dequelabs/cauldron-react"
className="fa fa-github"
aria-label="Cauldron React on GitHub"
tabIndex={-1}
/>
</MenuItem>
</TopBarItem>
</TopBar>
<SideBar show={this.state.show} onDismiss={this.onTriggerClick}>
{componentsList.map(name => (
<MenuItem key={name}>
{this.renderSideBarLink(`/components/${name}`, name)}
</MenuItem>
))}
{componentsList.map(name => {
const pathname = `/components/${name}`;
const isActive = pathname === location.pathname;
return (
<SideBarItem
key={name}
className={classNames({
'dqpl-menuitem-selected': isActive
})}
>
{this.renderSideBarLink(pathname, name, isActive)}
</SideBarItem>
);
})}
</SideBar>
<Workspace
id="main-content"
Expand Down
4 changes: 2 additions & 2 deletions docs/patterns/components/TopBarMenu/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class TopBarMenuDemo extends React.Component {
buttonRef = React.createRef();

handleClick = () => {
const event = new Event('topbarmenutoggle', { bubbles: true });
const event = new Event('focusTopBarMenu', { bubbles: true });
this.buttonRef.current.dispatchEvent(event);
};

Expand All @@ -21,7 +21,7 @@ class TopBarMenuDemo extends React.Component {
</p>
<h2>Demo</h2>
<Button buttonRef={buttonRef} onClick={handleClick}>
Toggle TopBar Menu
Focus TopBar Menu
</Button>
<h2>Code Sample</h2>
<Code language="javascript">
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"babel-loader": "^8.0.5",
"babel-plugin-module-resolver": "^3.0.0",
"babel-plugin-transform-export-extensions": "^6.22.0",
"classnames": "^2.2.6",
"closest": "0.0.1",
"css-loader": "^0.28.7",
"enzyme": "^3.2.0",
Expand Down
Loading

0 comments on commit f8337ed

Please sign in to comment.