Maybe there are a large number of people have written navigation bar, which is an important part of a website. However, have you written a navigation for single page application? without Bootstrap
of another style framework ? this time , I will try to write an excellently useful navigation with React
and Sass
for you .
First of all,
Navigation.js
renderNav() {
return this.props.path.map((item, idx) =>
<Tab
key={idx}
active={location.pathname === item.path}
label={item.label}
path={item.path}
updatePointer={this.updatePointer}
/>
);
}
render() {
return (
<header>
<div>
<nav className="navigation" ref="navigation">
{this.renderNav()}
</nav>
<span className="pointer" style={this.state.pointer} />
</div>
</header>
);
}
it likes that .
I posted the rendering part just now, you known the pointer is also the important part of a navigation, sometimes if the tab is active will the pointer be more lightful or some other signs of it . This time, the pointer is material style, a rectangle under the tab.
Don't fear , it's not difficult like you now envisioning. When actually begin to write something , you will find that easier than you have ever considered. Of course, I mean that when to begin to do it you will touch the real uncomfortable difficulties , and you will try to consider it with your brain your intelligence instead of anxiety.
You must find that we need states to maintain the pointer' s styles .
constructor() {
super();
this.state = {
index: -1,
pointer: {},
};
}
This the initial state, index stands for which tab is active , -1 means nothing active. the object naming pointer is for the style of the pointer.
After writing states within the constructor function , try to think how to know the pointer is in the right place and right styles.
We need a function to get its place and update its styles.
updatePointers(idx) {
if (idx < 0) {
this.setState({
pointer: {
top: `${this.refs.navigation.getBoundingClientRect().height}px`,
left: '1500px',
width: '0px',
},
});
return;
}
const label = this.refs.navigation.children[idx].getBoundingClientRect();
this.setState({
pointer: {
top: `${this.refs.navigation.getBoundingClientRect().height}px`,
left: `${label.left}px`,
width: `${label.width}px`,
},
});
}
For those codes , we make the pointer go away when the state.index is -1 and use the index to choose the right active tab, then setState will update its style.
It's worth to mention that the getBoundingClientRect(), which function is to grapple the pointer 's position and width for update the pointer style.
Don 't forget to bind the function to its class for geting its context.
that 's all .Now look the Sass
file.
.navigation {
display: flex;
flex-direction: row;
}
.pointer {
position: absolute;
width: 0px;
height: 3px;
margin-top: -3px;
background-color: $button;
transition-timing-function: $animation-curve-default;
transition-duration: $animation-duration;
transition-property: left, width;
}
OK, I will give you more informations next article.