diff --git a/src/components/subnavigation/subnavigation.jsx b/src/components/subnavigation/subnavigation.jsx index e9d964975..b04ae38cb 100644 --- a/src/components/subnavigation/subnavigation.jsx +++ b/src/components/subnavigation/subnavigation.jsx @@ -20,6 +20,7 @@ const SubNavigation = props => ( 'sub-nav-align-right': props.align === 'right' } )} + role={props.role} > {props.children} @@ -27,6 +28,7 @@ const SubNavigation = props => ( SubNavigation.propTypes = { align: PropTypes.string, + role: PropTypes.string, children: PropTypes.node, className: PropTypes.string }; diff --git a/src/components/tabs/tabs.jsx b/src/components/tabs/tabs.jsx index d9a4d79b4..07553ef13 100644 --- a/src/components/tabs/tabs.jsx +++ b/src/components/tabs/tabs.jsx @@ -1,56 +1,92 @@ -const classNames = require('classnames'); const PropTypes = require('prop-types'); -const { useRef } = require('react'); +const {useRef} = require('react'); const React = require('react'); const SubNavigation = require('../../components/subnavigation/subnavigation.jsx'); require('./tabs.scss'); -const TabItem = ({ children, ...props }) => { - const tabItemRef = useRef() - - return
  • {children}
  • -} - /* * Container for a custom, horizontal list of navigation elements * that can be displayed within a view or component. */ -const Tabs = ({ items, activeTabName }) => { - let activeIndex - const itemsRendered = items.map(({ name, onTrigger, getContent }, index) => { - const isActive = name === activeTabName - activeIndex = index +const Tabs = ({items, activeTabName}) => { + const tabElementRefs = useRef({}); + + const itemsRendered = items.map(({name, onTrigger, getContent}) => { + const isActive = name === activeTabName; + + let tabRef; + if (tabElementRefs.current[name]) { + tabRef = tabElementRefs.current[name]; + } else { + tabRef = React.createRef(); + tabElementRefs.current[name] = tabRef; + } + return ( -
  • {getContent(isActive)} -
  • - ) - }) + + ); + }); const handleKeyDown = event => { if (!['ArrowLeft', 'ArrowRight', 'Home', 'End', 'Enter', ' '].includes(event.key)) { - return + return; } - event.preventDefault() - console.log( - 'hi' - ) - } - + event.preventDefault(); + const focusedIndex = Object.values(tabElementRefs.current) + .findIndex(tabElementRef => + document.activeElement === tabElementRef.current + ); + if (event.key === 'ArrowLeft') { + let nextIndex; + if (focusedIndex === 0) { + nextIndex = Object.values(tabElementRefs.current).length - 1; + } else { + nextIndex = focusedIndex - 1; + } + Object.values(tabElementRefs.current)[nextIndex].current.focus(); + } else if (event.key === 'ArrowRight') { + let nextIndex; + if (focusedIndex === Object.values(tabElementRefs.current).length - 1) { + nextIndex = 0; + } else { + nextIndex = focusedIndex + 1; + } + Object.values(tabElementRefs.current)[nextIndex].current.focus(); + } else if (event.key === 'Home') { + Object.values(tabElementRefs.current)[0].current.focus(); + } else if (event.key === 'End') { + const lastTab = Object.values(tabElementRefs.current).length - 1; + Object.values(tabElementRefs.current)[lastTab].current.focus(); + } else if (event.key === 'Enter' || event.key === ' ') { + items[focusedIndex].onTrigger(); + } + }; + return ( -
    - +
    + {itemsRendered}
    - ) + ); }; Tabs.propTypes = { @@ -61,7 +97,7 @@ Tabs.propTypes = { getContent: PropTypes.func.isRequired }) ).isRequired, - activeTabName: PropTypes.string.isRequired, + activeTabName: PropTypes.string.isRequired }; module.exports = Tabs; diff --git a/src/components/tabs/tabs.scss b/src/components/tabs/tabs.scss index a612c3f76..791e9723f 100644 --- a/src/components/tabs/tabs.scss +++ b/src/components/tabs/tabs.scss @@ -14,13 +14,14 @@ justify-content: center; } -.tabs li { +.tabs button { margin: 0; border: 0; border-radius: 0; width: $cols2; text-align: center; color: $header-gray; + background-color: transparent; &.active { border-bottom: 3px solid $ui-aqua; diff --git a/src/views/explore/explore.jsx b/src/views/explore/explore.jsx index f39ec6ed6..c2e143023 100644 --- a/src/views/explore/explore.jsx +++ b/src/views/explore/explore.jsx @@ -26,7 +26,7 @@ class Explore extends React.Component { 'getExploreState', 'handleGetExploreMore', 'handleChangeSortMode', - 'getBubble', + 'getBubble' ]); this.state = this.getExploreState(); @@ -128,22 +128,25 @@ class Explore extends React.Component { items={[ { name: 'projects', - onTrigger: () => { - window.location = `${window.location.origin}/explore/projects/${this.state.category}/${this.state.mode}`; + onTrigger: () => { + window.location = `${window.location.origin}/explore/projects/` + + `${this.state.category}/${this.state.mode}`; }, - getContent: (isActive) => ( + getContent: isActive => (
    {isActive ? ( - - ) : ( - - ) + + ) : ( + + ) }
    @@ -151,29 +154,32 @@ class Explore extends React.Component { }, { name: 'studios', - onTrigger: () => { - window.location = `${window.location.origin}/explore/studios/${this.state.category}/${this.state.mode}`; + onTrigger: () => { + window.location = `${window.location.origin}/explore/studios/` + + `${this.state.category}/${this.state.mode}`; }, - getContent: (isActive) => ( + getContent: isActive => (
    {isActive ? ( - - ) : ( - - ) + + ) : ( + + ) }
    ) } ]} - activeTabName={ this.state.itemType } + activeTabName={this.state.itemType} />
    diff --git a/src/views/search/search.jsx b/src/views/search/search.jsx index 036f78105..0036f52b9 100644 --- a/src/views/search/search.jsx +++ b/src/views/search/search.jsx @@ -30,8 +30,7 @@ class Search extends React.Component { bindAll(this, [ 'getSearchState', 'handleChangeSortMode', - 'handleGetSearchMore', - 'getTab' + 'handleGetSearchMore' ]); this.state = this.getSearchState(); this.state.loaded = []; @@ -150,38 +149,6 @@ class Search extends React.Component { }); }); } - getTab (type) { - const termText = this.encodeSearchTerm(); - let targetUrl = `/search/${type}`; - if (termText) { - targetUrl += `?q=${termText}`; - } - let allTab = ( - -
  • - - -
  • -
    - ); - if (this.state.tab === type) { - allTab = ( - -
  • - - -
  • -
    - ); - } - return allTab; - } getProjectBox () { const results = (
    - - {this.getTab('projects')} - {this.getTab('studios')} - + { + const termText = this.encodeSearchTerm(); + let targetUrl = `/search/projects`; + if (termText) targetUrl += `?q=${termText}`; + window.location = targetUrl; + }, + getContent: isActive => ( +
    + {isActive ? ( + + ) : ( + + ) + } + +
    + ) + }, + { + name: 'studios', + onTrigger: () => { + const termText = this.encodeSearchTerm(); + let targetUrl = `/search/studios`; + if (termText) targetUrl += `?q=${termText}`; + window.location = targetUrl; + }, + getContent: isActive => ( +
    + {isActive ? ( + + ) : ( + + ) + } + +
    + ) + } + ]} + activeTabName={this.state.tab} + />