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}
+ />