Stateful tabs example

by Rico Sta. Cruz

HTML

<!-- [email protected] -->
<script src="//brcdn.org/QTvPCWkAGiRy0REgwOicxSQdOjs.js"></script>
<!-- [email protected] -->
<script src="//brcdn.org/chNyoR6KxEYtlBeH20QltJSxqoY.js"></script>
<!-- [email protected] -->
<script src="//brcdn.org/EPVFpXdToey7uo2hObA9lIYHIbg.js"></script>
<div id="app"></div>

CSS

html, body {
  height: 100%;
}
html {
  font-family: sans-serif;
}
body {
  display: flex;
  align-items: center;
  justify-content: center;
}
#app {
  flex: 0 0 auto;
  margin: auto;
  width: 200px;
}
.tabs { width: 200px; border: solid 1px #ccc; border-radius: 4px; }
.tabs-headings { box-shadow: inset 0 -1px 0 #ccc; background: #eee; padding: 3px 3px 0 3px; overflow: hidden; }
.tabs-heading { height: 32px; line-height: 32px; background: #fff; border: solid 1px #ccc; display: block; float: left; padding: 0 10px; margin-right: 3px; }
.tabs-heading-active { border-bottom-color: #fff; }
.tabs-content { padding: 20px; background: #fff; }
.tab { display: none; }
.tab-active { display: block; }

Babel + JSX

/** @jsx element */
var { element, createApp } = deku
var stateful = dekuStateful
var c = classnames

const log = console.log.bind(console)

function initialState() {
	return {
		activeTab: 0
	}
}

function onCreate({ props, state, setState }) {
	const {items} = props

  log('onCreate', props, state)

	items.forEach((el, i) => {
		if (el.active === true) {
			setState({ activeTab: i })
		}
	})
}

function render({ props, state, setState }) {

  log('render',props,state)

	const { items } = props
	const { activeTab } = state

	function getHeadings() {
		return items.map(({ heading }, i) => (
			<div class={ c(['tabs-heading', {'tabs-heading-active': activeTab === i}]) }
           onClick={() => setState({ activeTab: i })}>
				<span>{heading}</span>
			</div>
		));
	}

	function getTabs() {
		return items.map(({content}, i) => (
			<div class={c(['tab', {'tab-active': activeTab === i}])}>
				{content}
			</div>
		));
	}

	return (
		<div class={c(['tabs', props.class])}>
			<div class='tabs-headings'>
				{getHeadings()}
			</div>
			<div class='tabs-content'>
				{getTabs()}
			</div>
		</div>
	);
}

var Component = stateful({ initialState, onCreate, render })

function update () {
  render(<Component items={[
    { heading: 'hello', content: 'this is the first tab' },
    { heading: 'world', content: 'second tab, hi' }
  ]} />, {})
}
var render = createApp(document.getElementById('app'), update)
update()