Migrate tabs to sass
parent
06f1b866b3
commit
f4f537b7f4
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue