Skip to content

Commit

Permalink
[www] Sidebar: Add "Expand/Collapse All" button, store state in local…
Browse files Browse the repository at this point in the history
…Storage (#7019)

* First shot

* Store state in localStorage

* move „Expand/Collapse All“ button to component
* fix „Features“ sidebar (item.disableAccordions)
* no need to pass down isScrollSync from scrollSyncSidebar to Sidebar, and from Sidebar to Item
* no need to pass down activeItemHash from Sidebar to Item, either
* rename sectionHash to openSectionHash
* console.logs

* Butcher site showcase yaml so this builds on Netlify

* Try again

* Write to local storage on „Collapse All“

* Position „Expand/Collapse All“ button above the sidebar navigation

* not floating, prevents the button conflicting with the „selected“ state of the sidebar navigation items
* had to revert „hidden until hover“ scrollbar
* hide button on mobile
* hide button for „Features“ via `disableExpandAll` in `utils/sidebar/item-list`

* Only bookkeep items that have subitems ;)

* Test if global.localStorage is available

Fixes issue with iOS Safari’s private session mode

* Move getInitialState up

* Update state.expandAll, fixes „Expand/Collapse All“ button behavior

* Tidy

* Fix isParentOfActiveItem

* Make all but the top-level item active link parents bold

* Enable accordions for mobile/below presets.Tablet

* Fix sidebar mobile height

* Compensate for iOS Safari „dead zone“

* Compensate moar
  • Loading branch information
fk authored Aug 7, 2018
1 parent 072d5ee commit edb13e2
Show file tree
Hide file tree
Showing 10 changed files with 374 additions and 129 deletions.
28 changes: 18 additions & 10 deletions www/src/components/sidebar/accordion.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const ItemWithSubitems = ({
activeItemLink,
createLink,
isExpanded,
isParentOfActiveItem,
item,
level,
location,
Expand All @@ -24,20 +25,23 @@ const ItemWithSubitems = ({
<Fragment>
{item.link ? (
<SplitButton
level={level}
createLink={createLink}
isActive={isActive}
isExpanded={isExpanded}
isParentOfActiveItem={isParentOfActiveItem}
item={item}
level={level}
location={location}
onLinkClick={onLinkClick}
onSectionTitleClick={onSectionTitleClick}
uid={uid}
createLink={createLink}
/>
) : (
<SectionTitleComponent
isActive={isActive}
isExpanded={isExpanded}
isParentOfActiveItem={isParentOfActiveItem}
item={item}
level={level}
onSectionTitleClick={onSectionTitleClick}
title={item.title}
Expand All @@ -54,18 +58,19 @@ class Accordion extends React.Component {

this.state = {
uid: (`` + Math.random()).replace(/\D/g, ``),
isExpanded: props.isExpanded || props.isActive || false,
}

this.handleClick = this.handleClick.bind(this)
}

handleClick(...args) {
this.setState({ isExpanded: !this.state.isExpanded })

if (this.props.onLinkClick) {
this.props.onLinkClick(...args)
}

if (this.props.onSectionTitleClick) {
this.props.onSectionTitleClick(...args)
}
}

render() {
Expand All @@ -74,14 +79,16 @@ class Accordion extends React.Component {
activeItemParents,
createLink,
isActive,
isExpanded = this.state.isExpanded,
isParentOfActiveItem,
item,
level,
location,
onLinkClick,
onSectionTitleClick,
openSectionHash,
} = this.props
const uid = `item_` + this.state.uid
const isExpanded = openSectionHash[item.title] || item.disableAccordions

return (
<li
Expand All @@ -97,24 +104,23 @@ class Accordion extends React.Component {
createLink={createLink}
isActive={isActive}
isExpanded={isExpanded}
isParentOfActiveItem={isParentOfActiveItem}
item={item}
level={level}
location={location}
onLinkClick={onLinkClick}
onSectionTitleClick={this.handleClick}
onSectionTitleClick={onSectionTitleClick}
uid={uid}
/>
<ul
id={uid}
css={{
...styles.ul,
display: isExpanded ? `block` : `none`,
paddingBottom: level === 0 && isExpanded ? 40 : false,
"& li": {
paddingLeft: paddingLeft(level),
},
[presets.Tablet]: {
display: isExpanded ? `block` : `none`,
},
}}
>
{item.items.map(subitem => (
Expand All @@ -127,7 +133,9 @@ class Accordion extends React.Component {
level={level + 1}
location={location}
onLinkClick={onLinkClick}
isExpanded={isExpanded}
onSectionTitleClick={onSectionTitleClick}
openSectionHash={openSectionHash}
styles={{
...(item.ui === `steps` && {
...styles.ulStepsUI,
Expand Down
59 changes: 59 additions & 0 deletions www/src/components/sidebar/button-expand-all.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { Fragment } from "react"
import GoFold from "react-icons/lib/go/fold"
import GoUnfold from "react-icons/lib/go/unfold"

import presets, { colors } from "../../utils/presets"
import { scale, options, rhythm } from "../../utils/typography"

const ExpandAllButton = ({ onClick, expandAll }) => (
<button
onClick={onClick}
css={{
...scale(-2 / 3),
lineHeight: 1,
background: `transparent`,
border: `none`,
borderRadius: presets.radius,
color: colors.gatsby,
display: `flex`,
cursor: `pointer`,
alignItems: `center`,
flexGrow: 0,
marginLeft: `auto`,
paddingTop: rhythm(options.blockMarginBottom / 3),
paddingBottom: rhythm(options.blockMarginBottom / 3),
fontFamily: options.systemFontFamily.join(`,`),
textAlign: `left`,
transition: `all .2s`,
"&:hover": {
background: colors.ui.bright,
},
}}
>
{expandAll ? (
<Fragment>
<span>Collapse All</span>
<span css={{ ...styles.icon }}>
<GoFold />
</span>
</Fragment>
) : (
<Fragment>
<span>Expand All</span>
<span css={{ ...styles.icon }}>
<GoUnfold />
</span>
</Fragment>
)}
</button>
)

export default ExpandAllButton

const styles = {
icon: {
display: `inline-block`,
fontSize: `.9rem`,
marginLeft: 8,
},
}
10 changes: 8 additions & 2 deletions www/src/components/sidebar/item.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class Item extends React.Component {
const {
activeItemLink,
activeItemParents,
isActive,
openSectionHash,
item,
level,
location,
Expand All @@ -26,6 +28,8 @@ class Item extends React.Component {
ui,
} = this.props

const isParentOfActiveItem = isItemActive(activeItemParents, item)

return (
<Fragment>
{item.items ? (
Expand All @@ -34,19 +38,21 @@ class Item extends React.Component {
activeItemParents={activeItemParents}
createLink={createLink}
isActive={
isActive ||
item.link === location.pathname ||
isItemActive(activeItemParents, item) ||
isParentOfActiveItem ||
item.disableAccordions
}
isParentOfActiveItem={isParentOfActiveItem}
item={item}
level={level}
location={location}
onLinkClick={onLinkClick}
openSectionHash={openSectionHash}
onSectionTitleClick={onSectionTitleClick}
/>
) : (
<li
className="item"
css={{
...this.props.styles,
paddingLeft: level === 0 ? 40 : false,
Expand Down
8 changes: 1 addition & 7 deletions www/src/components/sidebar/scroll-sync-sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,7 @@ class ScrollSyncSection extends Component {

render() {
const { activeItemHash } = this.state
return (
<SidebarBody
isScrollSync
activeItemHash={activeItemHash}
{...this.props}
/>
)
return <SidebarBody activeItemHash={activeItemHash} {...this.props} />
}
}

Expand Down
48 changes: 22 additions & 26 deletions www/src/components/sidebar/section-title.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
import React from "react"

import ChevronSvg from "./chevron-svg"
import presets, { colors } from "../../utils/presets"
import { colors } from "../../utils/presets"
import { options } from "../../utils/typography"

const paddingLeft = level => (level === 0 ? level + 1 * 40 : level + 1 * 20)

const Chevron = ({ isExpanded }) => (
<span
css={{
display: `none`,
[presets.Tablet]: {
alignItems: `center`,
display: `flex`,
flexShrink: 0,
marginLeft: `auto`,
minHeight: 40,
position: `relative`,
width: 40,
"&:before": {
...styles.ulHorizontalDivider,
bottom: 0,
left: `0 !important`,
top: `auto`,
},
alignItems: `center`,
display: `flex`,
flexShrink: 0,
marginLeft: `auto`,
minHeight: 40,
position: `relative`,
width: 40,
"&:before": {
...styles.ulHorizontalDivider,
bottom: 0,
left: `0 !important`,
top: `auto`,
},
}}
>
Expand All @@ -42,6 +39,7 @@ const Chevron = ({ isExpanded }) => (
const TitleButton = ({
isActive,
isExpanded,
item,
level,
onSectionTitleClick,
title,
Expand All @@ -63,7 +61,7 @@ const TitleButton = ({
top: `auto`,
},
}}
onClick={onSectionTitleClick}
onClick={() => onSectionTitleClick(item)}
>
<SectionTitle isExpanded={isExpanded} isActive={isActive} level={level}>
{title}
Expand All @@ -76,6 +74,7 @@ const SplitButton = ({
createLink,
isActive,
isExpanded,
isParentOfActiveItem,
item,
level,
location,
Expand All @@ -95,14 +94,13 @@ const SplitButton = ({
<span
css={{
flexGrow: 1,
[presets.Tablet]: {
borderRight: `1px solid ${colors.ui.border}`,
},
borderRight: `1px solid ${colors.ui.border}`,
}}
>
{createLink({
isActive,
isExpanded,
isParentOfActiveItem,
item,
location,
onLinkClick,
Expand All @@ -119,7 +117,7 @@ const SplitButton = ({
background: `white`,
},
}}
onClick={onSectionTitleClick}
onClick={() => onSectionTitleClick(item)}
>
<Chevron isExpanded={isExpanded} />
</button>
Expand Down Expand Up @@ -162,11 +160,9 @@ const SectionTitle = ({ children, isExpanded, isActive, disabled, level }) => (
textTransform: `uppercase`,
}),

[presets.Tablet]: {
color: isExpanded ? colors.gatsby : false,
"&:hover": {
color: disabled ? false : colors.gatsby,
},
color: isExpanded ? colors.gatsby : false,
"&:hover": {
color: disabled ? false : colors.gatsby,
},
}}
>
Expand Down
Loading

0 comments on commit edb13e2

Please sign in to comment.