Migrate tabs to sass

old
Javi Velasco 2015-10-11 22:27:59 +02:00
parent 06f1b866b3
commit f4f537b7f4
7 changed files with 122 additions and 83 deletions

View File

@ -0,0 +1,72 @@
@import "../variables";
$tab-text: $color-black !default;
$tab-text-color: unquote("rgb(#{$tab-text})") !default;
$tab-text-inactive-color: unquote("rgba(#{$tab-text}, 0.70)") !default;
$tab-pointer-height: .2 * $unit;
$tab-pointer-color: unquote("rgb(#{$color-primary})") !default;
$tab-navigation-border-color: $color-divider;
$tab-text-height: 1.4 * $unit;
$tab-label-height: 4.8 * $unit;
$tab-label-h-padding: 1.2 * $unit;
$tab-label-v-padding: ($tab-label-height - $tab-text-height) / 2;
$tab-label-disabled-opacity: .2;
.root {
position: relative;
}
.navigation {
box-shadow: inset 0 -1px $tab-navigation-border-color;
}
.label {
padding: $tab-label-v-padding $tab-label-h-padding;
font-size: $tab-text-height;
font-weight: $font-weight-semi-bold;
line-height: 1;
color: $tab-text-inactive-color;
text-transform: uppercase;
transition-timing-function: $animation-curve-default;
transition-duration: $animation-duration;
transition-property: box-shadow, color;
&.active {
color: $tab-text-color;
}
&.disabled {
opacity: $tab-label-disabled-opacity;
}
&:not(.disabled) {
cursor: pointer;
}
&.hidden {
display: none;
}
}
.pointer {
position: absolute;
width: 0;
height: $tab-pointer-height;
margin-top: - $tab-pointer-height;
background-color: $tab-pointer-color;
transition-timing-function: $animation-curve-default;
transition-duration: $animation-duration;
transition-property: left, width;
}
.tab {
padding: $tab-label-v-padding $tab-label-h-padding;
&:not(.active) {
display: none;
}
&.active {
display: block;
}
}

View File

@ -1,43 +0,0 @@
@import '../constants'
:local(.root)
position : relative
> nav
box-shadow : inset 0 -1px DIVIDER
> label
padding : (OFFSET / 2) OFFSET
font-size : FONT_SIZE_TINY
font-weight : FONT_WEIGHT_BOLD
text-transform : Uppercase
color : TEXT_SECONDARY
transition-property : box-shadow, color
transition-duration : ANIMATION_DURATION
transition-timing-function : ANIMATION_EASE
&.active
color : TEXT
// box-shadow : inset 0 (-(OFFSET / 10)) PRIMARY
&.disabled
opacity : 0.2
&:not(.disabled)
cursor : pointer
&.hidden
display : none
:local(.pointer)
HEIGHT = (OFFSET / 10)
position : absolute
margin-left : -(OFFSET)
margin-top : -(HEIGHT)
height : HEIGHT
width : 128px
background-color : PRIMARY
transition-property : left, width
transition-duration : ANIMATION_DURATION
transition-timing-function : ANIMATION_EASE
:local(.tab)
padding : (OFFSET / 2) OFFSET
&:not(.active)
display : none
&.active
display : block

View File

@ -1,5 +1,4 @@
import React from 'react';
import style from './style';
export default React.createClass({
@ -32,9 +31,9 @@ export default React.createClass({
render () {
let className = `${style.tab} ${this.props.className}`;
if (this.props.active) className += ' active';
if (this.props.disabled) className += ' disabled';
if (this.props.hidden) className += ' hidden';
if (this.props.active) className += ` ${style.active}`;
if (this.props.disabled) className += ` ${style.disabled}`;
if (this.props.hidden) className += ` ${style.hidden}`;
return (
<section

View File

@ -1,17 +1,7 @@
import React from 'react';
import React from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import style from './style';
function _pointerPosition (index = 0, navigation) {
const label = navigation.children[index].getBoundingClientRect();
return {
top: `${navigation.getBoundingClientRect().height}px`,
left: `${label.left}px`,
width: `${label.width}px`
};
}
export default React.createClass({
mixins: [PureRenderMixin],
@ -39,7 +29,7 @@ export default React.createClass({
componentDidMount () {
this.setState({
pointer: _pointerPosition(this.state.index, this.refs.navigation.getDOMNode())
pointer: this._pointerPosition(this.state.index, this.refs.navigation)
});
},
@ -47,27 +37,45 @@ export default React.createClass({
const index = next_props.index || this.state.index;
this.setState({
index: index,
pointer: _pointerPosition(index, this.refs.navigation.getDOMNode())
pointer: this._pointerPosition(index, this.refs.navigation)
});
},
_pointerPosition (index = 0, navigation) {
const startPoint = this.refs.tabs.getBoundingClientRect().left;
const label = navigation.children[index].getBoundingClientRect();
return {
top: `${navigation.getBoundingClientRect().height}px`,
left: `${label.left - startPoint}px`,
width: `${label.width}px`
};
},
onClick (index) {
this.setState({
index: index,
pointer: _pointerPosition(index, this.refs.navigation.getDOMNode())
pointer: this._pointerPosition(index, this.refs.navigation)
});
if (this.props.onChange) this.props.onChange(this);
},
renderLabels (labels) {
return labels.map((props) => {
return <label {...props}>{ props.label }</label>;
});
},
render () {
let labels = [];
const tabs = this.props.children.map((tab, index) => {
let active = this.state.index === index;
let className = `${style.label} ${tab.props.className}`;
let className = tab.props.className;
if (active) className += ' active';
if (tab.props.disabled) className += ' disabled';
if (tab.props.hidden) className += ' hidden';
if (active) className += ` ${style.active}`;
if (tab.props.disabled) className += ` ${style.disabled}`;
if (tab.props.hidden) className += ` ${style.hidden}`;
labels.push({
className: className,
@ -79,16 +87,15 @@ export default React.createClass({
return React.cloneElement(tab, {active: active, key: index, tabIndex: index });
});
let className = style.root;
if (this.props.className) className += ` ${this.props.className}`;
return (
<div
data-react-toolbox='tabs'
className={style.root + ' ' + this.props.className}
data-flex='vertical'
>
<nav ref='navigation' data-flex='horizontal'>
{ labels.map((props) => { return <label {...props}>{props.label}</label>; }) }
<div data-react-toolbox='tabs' ref='tabs' className={className} data-flex='vertical'>
<nav className={style.navigation} ref='navigation' data-flex='horizontal'>
{ this.renderLabels(labels) }
</nav>
<span className={style.pointer} style={this.state.pointer}></span>
<span className={style.pointer} style={this.state.pointer} />
{ tabs }
</div>
);

View File

@ -33,6 +33,7 @@ $font-size-normal: $font-size !default;
$font-size-big: 1.8 * $unit !default;
$font-weight-thin: 300 !default;
$font-weight-normal: 400 !default;
$font-weight-semi-bold: 500 !default;
$font-weight-bold: 700 !default;
//-- Shadows

View File

@ -1,6 +1,5 @@
import React from 'react';
import { Tabs } from '../../components/tabs';
import { Tab } from '../../components/tabs';
import { Tabs, Tab } from '../../components/tabs';
export default React.createClass({
displayName: 'TabsTest',
@ -8,13 +7,15 @@ export default React.createClass({
render () {
return (
<section>
<h2>Tabs</h2>
<Tabs>
<Tab label='Primary'><small>primary</small></Tab>
<Tab label='Secondary'><small>secondary</small></Tab>
<Tab label='Third' disabled><small>third</small></Tab>
<Tab label='Fourth' hidden><small>Fourth</small></Tab>
<Tab label='Fifth'><small>Fifth</small></Tab>
<h5>Tabs</h5>
<p>This tabs can be disabled or hidden</p>
<Tabs>
<Tab label='Primary'><small>Primary content</small></Tab>
<Tab label='Secondary'><small>Secondary content</small></Tab>
<Tab label='Third' disabled><small>Disabled content</small></Tab>
<Tab label='Fourth' hidden><small>Fourth content hidden</small></Tab>
<Tab label='Fifth'><small>Fifth content</small></Tab>
</Tabs>
</section>
);

View File

@ -14,9 +14,10 @@ import Progress from './components/progress';
import RadioGroup from './components/radio_group';
import Slider from './components/slider';
import Switch from './components/switch';
import Tabs from './components/tabs';
// import FontIcon from './components/font_icon';
// import Form from './components/form';
// import Tabs from './components/tabs';
const Test = React.createClass({
displayName: 'App',
@ -39,6 +40,7 @@ const Test = React.createClass({
<RadioGroup />
<Slider />
<Switch />
<Tabs />
</app>
);
}