1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-08-04 20:37:29 +02:00

Refactor settings. Add switches and tabs. fixes #339

This commit is contained in:
Kushagra Gour
2018-11-07 01:39:24 +05:30
parent ec4ce2be29
commit f2a96b3ec2
4 changed files with 409 additions and 294 deletions

79
src/components/Tabs.jsx Normal file
View File

@@ -0,0 +1,79 @@
import { h, Component } from 'preact';
function hyphenate(text) {
return text.replace(/\s/g, '-');
}
const ID_PREFIX = 'tab-panel-';
export function TabPanel({ label }) {
return (
<div
class="tabs__tabpanel"
role="tabpanel"
id={`${ID_PREFIX}${hyphenate(label)}`}
>
{this.props.children}
</div>
);
}
function Tab({ label, isSelected, onKeyUp, onClick }) {
return (
<button
class={`tabs__tab ${isSelected ? 'tabs__tab--selected' : ''}`}
role="tab"
tabindex={isSelected ? null : -1}
aria-selected={isSelected}
aria-controls={`${ID_PREFIX}${hyphenate(label)}`}
onKeyUp={onKeyUp}
onClick={onClick}
>
{label}
</button>
);
}
export default class Tabs extends Component {
constructor(props) {
super(props);
this.state = {
selectedTab: 0
};
}
isSelected(index) {
return this.state.selectedTab === index;
}
keyUpHandler(e) {
let { selectedTab } = this.state;
if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
selectedTab--;
selectedTab = selectedTab < 0 ? this.props.length - 1 : selectedTab;
this.setState({ selectedTab: selectedTab });
e.preventDefault();
} else if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
selectedTab++;
selectedTab %= this.props.children.length;
this.setState({ selectedTab: selectedTab });
e.preventDefault();
}
}
render() {
const tabs = this.props.children;
return (
<div class="tabs">
<div class="tabs__tablist" role="tablist">
{tabs.map((child, index) => (
<Tab
isSelected={this.isSelected(index)}
label={child.props.label}
onKeyUp={this.keyUpHandler.bind(this)}
onClick={() => this.setState({ selectedTab: index })}
/>
))}
</div>
<div class="tabs__tabpanel-wrap">
{tabs.map(
(child, index) => (this.state.selectedTab === index ? child : null)
)}
</div>
</div>
);
}
}