React-router links don't get visited style - javascript

I've got a small website I'm building with React Router. I've noticed that only the homepage link gets the visited styles. The other link does not get the visited style, even when you visit it.
https://jsfiddle.net/dfzkavbd/2/
Javascript:
var dom = React.DOM;
var Router = React.createFactory(ReactRouter.Router);
var Link = React.createFactory(ReactRouter.Link);
var NavItem = React.createFactory(React.createClass({
render: function() {
var item = {
marginLeft: "15px",
marginRight: "15px",
position: "relative",
height: "100%",
display: "flex",
alignItems: "center"
};
return dom.div({ style: item }, this.props.children);
}
}));
var NavBar = React.createFactory(React.createClass({
render: function() {
var navBarStyle = {
backgroundColor: "black",
height: "50px",
display: "flex"
};
var innerNavBarStyle = {
display: "flex",
alignItems: "center",
justifyContent: "initial",
flexGrow: "1",
color: "#777"
};
return dom.div({ style: navBarStyle },
dom.div({ style: innerNavBarStyle },
this.renderRightSide()
));
},
renderRightSide: function() {
var rightStyle = {
marginLeft: "auto",
display: "flex",
height: "100%"
};
return dom.div({ style: rightStyle },
NavItem(null, Link({ to: "/Blog" }, "Blog")),
NavItem(null, Link({ to: "/" }, "Home"))
);
}
}));
var Blog = React.createClass({
render: function() {
return dom.span(null, "Blog");
}
});
var App = React.createClass({
render: function() {
return dom.div(null,
NavBar(),
this.props.children
);
}
});
var Home = React.createClass({
render: function() {
return dom.span(null, "Home");
}
});
const routes = {
component: App,
childRoutes: [
{ path: 'Blog', component: Blog },
{ path: '/', component: Home }
]
};
ReactDOM.render(Router({ routes: routes }), document.getElementById("App"));
HTML:
<html class=""><head>
<meta charset="UTF-8">
<script src="https://fb.me/react-with-addons-0.14.3.js"></script>
<script src="https://fb.me/react-dom-0.14.3.js"></script>
<script src="https://npmcdn.com/react-router/umd/ReactRouter.min.js"></script>
</head>
<body style="margin: 0px;">
<div id="App" class="app"></div>
</body></html>
CSS:
.app a:link {
text-decoration: none;
}
.app a:visited {
color: red;
}
.app a:hover {
color: white;
text-decoration: underline;
}
How can I apply my visited style to all the visited links?

I think you could use the classnames package and set the class for visited links to true in an onClick event handler. That would not persist across reloads though. If you wanted that you would need to save the setting to local storage or something.

Related

Show/Hide React Component based on State

I am very new to React and am trying to create a page where clicking on the color square will show the hex code for that color. I've tried a bunch of different things and I can't figure out if my problem is in the event handling, in the state handling, both, or in something else altogether. I can get the hex code to either be there or not, but not have it change when I click.
Here is my main:
<main>
<h1>Dynamic Hex Code Display</h1>
<div id="container"></div>
<script type="text/babel">
class ColorSquare extends React.Component {
render() {
var blockStyle = {
height: 150,
backgroundColor: this.props.color,
};
return <div style={blockStyle} onClick = {this.props.onClick}></div>;
}
}
class HexDisplay extends React.Component {
render() {
var hexText = {
fontFamily: "arial",
fontWeight: "bold",
padding: 15,
margin: 0,
textAlign: "center",
};
var hexTextVis = {
...hexText,
visibility: "visible"
}
var hexTextInvis = {
...hexText,
visibility: "hidden"
}
var isVisible = this.props.isVisible;
if (isVisible) {
return <p style={hexTextVis}>{this.props.color}</p>;
} else {
return <p style={hexTextInvis}>{this.props.color}</p>;
}
}
}
class HexParent extends React.Component {
constructor(props) {
super(props);
this.state = {
isVisible: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
this.setState(currentVis => ({isVisible: !currentVis.isVisible}));
console.log(this.state);
console.log('clicking');
}
render() {
var fullBoxStyle = {
padding: 0,
margin: 10,
backgroundColor: "#fff",
boxShadow: "3px 3px 5px #808080",
boxRadius: "5px 5px",
height: 200,
width: 150,
};
var buttonStyle = {
width:150,
backgroundColor: this.props.color
}
return (
<div style={fullBoxStyle}>
<span onClick={(e) => this.handleClick()}>
<ColorSquare color={this.props.color} />
<span style={{
isVisible: this.state.isVisible ? "true" : "false",
}}>
<HexDisplay color={this.props.color} />
</span>
</span>
</div>
);
}
}
ReactDOM.render(
<div class="colorRow">
<HexParent color="#ba2c9d" />
<HexParent color="#2cba90" />
<HexParent color="#2c9dba" />
</div>,
document.querySelector("#container")
);
</script>
When the object is created, it's a hexTextVis object. When you click, isVisible changes, but it's still a hexTextVis object and so the render doesn't change. You could either do something like:
<HexDisplay visibility={state.isVisible}/>
or
{state.isVisible ? <div/> : <HexDisplay />}
style={{
isVisible: this.state.isVisible ? "true" : "false",
}}
There isn't a css property with this name. Perhaps you meant to use visibility?
style={{
visibility: this.state.isVisible ? "visible" : "hidden"
}}
Try wrapping the span and and using a ternary operator to render the span element, based on if the condition of isVisible is equal to true, otherwise it should not return anything
{this.state.isVisible && <span><HexDisplay /></span>}

How to make Data and Vuex reactive?

There is such a code:
<template>
<div class="chart"
v-bind:style="chartStyleObject">
</div>
</template>
<script>
export default{
data () {
return {
chartStyleObject: {
width: this.$store.state.chartStyleObject.width,
height: this.$store.state.chartStyleObject.height,
marginTop: this.$store.state.chartStyleObject.marginTop,
marginRight: this.$store.state.chartStyleObject.marginRight,
marginBottom: this.$store.state.chartStyleObject.marginBottom,
marginLeft: this.$store.state.chartStyleObject.marginLeft,
},
},
}
}
And such a repository:
const axios = require("axios");
export const state = () => ({
chartStyleObject: {
height: '247px',
width: '500px',
marginTop: '15px',
marginRight: '0px',
marginBottom: '0px',
marginLeft: '15px',
},
});
export const mutations = {
changeChartDraggableEventState (state, EventState) {
state.chartDraggableEventState = EventState;
},
changeChartHeight (state, height) {
state.chartStyleObject.height = height;
},
changeHeightWrapper (state, HeightWrapper) {
state.chartStyleObject.HeightWrapper = HeightWrapper;
},
changeWidthWrapper (state, WidthWrapper) {
state.chartStyleObject.WidthWrapper = WidthWrapper;
},
changeChartMarginLeft (state, MarginLeft) {
state.chartStyleObject.marginLeft = MarginLeft;
},
changeChartMarginTop (state, MarginTop) {
state.chartStyleObject.marginTop = MarginTop;
},
};
Problem:
If I change the state of the repository through mutations, then the properties of the repository change correctly.
But!
The data properties on which the same storage properties are tied for some reason does not change.
(Despite the fact that repository property was changed)
My question is:
Why does this happen - if dates property, as well as repositories property, in theory, should be reactive?
And which approach is the most correct in this case to solve this problem? (writing directly the storage properties in the code seems like a very cumbersome decision.)
When you assign the values in
chartStyleObject: {
width: this.$store.state.chartStyleObject.width, // here
height: this.$store.state.chartStyleObject.height,
marginTop: this.$store.state.chartStyleObject.marginTop,
marginRight: this.$store.state.chartStyleObject.marginRight,
marginBottom: this.$store.state.chartStyleObject.marginBottom,
marginLeft: this.$store.state.chartStyleObject.marginLeft,
},
you are assigning values to the width, height and so on. You assign to them the current values of the state variables.
If you want the properties of chartStyleObject to change whenever the store's state changes, either map the state directly in the template (or wheverever you use it) or create a computed:
export default {
computed: {
chartStyleObject() {
return {
width: this.$store.state.chartStyleObject.width,
height: this.$store.state.chartStyleObject.height,
marginTop: this.$store.state.chartStyleObject.marginTop,
marginRight: this.$store.state.chartStyleObject.marginRight,
marginBottom: this.$store.state.chartStyleObject.marginBottom,
marginLeft: this.$store.state.chartStyleObject.marginLeft,
};
},
},
}

How to create sticky header with flexbox and REACT

I have created a header component in REACT and the Header uses flexbox for layout. Now I need to make the Header stick. I tried using position: fixed but that messes up the flexbox styling. Does anyone have any ideas on how I can solve this?
The code is shown below. The height of the header varies depending on whether mobile menu is displayed or not.
Thanks.
import React, { Component } from 'react';
import Logo from './Logo'
import logo from '../images/transparent.png';
import MenuItem from "./MenuItem";
import MenuItemBurger from "./MenuItemBurger";
class Header extends Component {
constructor(props) {
super(props);
this.headerStyle = {
height: 'auto',
padding: 10,
display: 'flex',
justifyContent: 'space-between',
zIndex: 10,
backgroundColor: 'white'
};
this.burgerMenuIconStyle = {
color: '#757c8b',
};
this.mobileMenuStyle = {
zIndex: 20,
justifyContent: 'center',
alignItems: 'center'
};
this.state = {
windowWidth: window.innerWidth,
mobileNavVisible: false,
navItems : [
{text: 'Home', selected: true, id:'home'},
{text: 'Our Services', selected: false, id: 'services'},
{text: 'Contact Us', selected: false, id: 'contact'}
]
};
}
handleResize() {
this.setState({windowWidth: window.innerWidth});
}
componentDidMount() {
window.addEventListener('resize', this.handleResize.bind(this));
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize.bind(this));
}
toggleMenuOnClick() {
if (this.state.mobileNavVisible) {
this.setState({...this.state, mobileNavVisible: false});
}
else {
this.setState({...this.state, mobileNavVisible: true});
}
}
renderMobileHeader() {
const navItemsMappedBurger = this.state.navItems.map(item => <MenuItemBurger text={item.text} id={item.id} onClick={() => this.toggleMenuOnClick()}/>);
if (this.state.mobileNavVisible) {
return (
<div className="mobileHeader">
<div style={this.headerStyle}>
<Logo logo={logo}/>
<i className="fa fa-bars fa-2x" onClick={() => this.toggleMenuOnClick()} style={this.burgerMenuIconStyle}></i>
</div>
<hr></hr>
<div className="navItems" style={this.mobileMenuStyle}> {navItemsMappedBurger} </div>
</div>
)
}
return (
<div className="mobileHeader">
<div style={this.headerStyle}>
<Logo logo={logo}/>
<i className="fa fa-bars fa-2x" onClick={() => this.toggleMenuOnClick()} style={this.burgerMenuIconStyle}></i>
</div>
</div>
)
}
renderWideHeader() {
const navItemsMapped = this.state.navItems.map(item => <MenuItem text={item.text} id={item.id}/>);
return (
<div className="wideHeader" style={this.headerStyle}>
<Logo logo={logo}/>
<div className="navItems">{navItemsMapped}</div>
</div>
)
}
render() {
if (this.state.windowWidth < 1000) {
return (
this.renderMobileHeader()
)
}
return (
this.renderWideHeader()
);
}
};
export default Header;
try to add a container to deal with the fixed position.
Something like this:
this.fixedHeader = {
position: fixed;
width: 100%;
top: 0;
left: 0;
z-index: 1000;
}
const FixedHeader = (children) => {
return <div style={this.fixedHeader}>{children}</div>
}
render() {
if (this.state.windowWidth < 1000) {
return <FixedHeader>{ this.renderMobileHeader() }</FixedHeader>
}
return <FixedHeader>{ this.renderWideHeader() }</FixedHeader>
}

Shoutem change default fontFamily not work

im newbie in react native! I'm used shoutem/ui in my project.
I have problem when modify default fontFamily. here is my code, please check then help me some solution to handle this.
thanks so much guys.
const theme = _.merge(getTheme(), {
defaultFont: {
fontFamily: 'Rubik-Italic',
},
'shoutem.ui.NavigationBar': {
'.clear': {
container: {
backgroundColor: params.primaryColor,
borderBottomColor: 'transparent',
position: 'relative',
},
'shoutem.ui.Title': {
color: 'white',
fontSize: 16,
},
},
'.normal': {
container: {
position: 'relative'
},
'shoutem.ui.Button': {
'shoutem.ui.Icon': {
color: params.colorTextAlpha,
},
'shoutem.ui.Text': {
color: params.colorTextAlpha,
},
},
'shoutem.ui.Title': {
color: params.colorText,
},
}
},
'shoutem.ui.Row': {
'.fix': {
paddingHorizontal: 10,
paddingVertical: 10,
}
}
});
What you want to do is override the theme variables.
Import the default theme variables and the getTheme function:
import {
getTheme,
defaultThemeVariables,
} from '#shoutem/ui';
Then define your custom variables:
const myThemeVariables = {
...defaultThemeVariables,
title: { fontFamily: 'MyFont' },
};
And then define your custom theme that uses those variables:
const myTheme = getTheme(myThemeVariables);
There is no more defaultFont setting you can override, so you'll have to be specific unfortunately.
Furthermore, you have to import the StyleProvider:
import { StyleProvider } from '#shoutem/theme';
And use it to control the style of your components:
render() {
return (
<StyleProvider style={myTheme}>
// your components here
</StyleProvider>
);
}
}

Using npm package in Meteor via cosmos:browserify

I'm trying to load Radium (which is a javascript library for inline css) following instructions here.
In app.browserify.js: Radium = require("radium");.
In package.json: "radium": "0.13.4"
However when I try to use Radium in js in the app, the inline css doesn't work. Chrome dev tool indicates that Radium = module.exports(ComposedComponent)..
I'm assuming this should be an object, considering that ReactPIXI that I loaded the same way, works just fine, and the dev tool says ReactPIXI = Object {factories: Object}.
Here is my code:
AppBody = React.createClass({
mixins: [ReactMeteorData, Navigation, State, Radium.StyleResolverMixin,
Radium.BrowserStateMixin],
render: function() {
var self = this;
var styles = {
base: {
color: this.state.fontColor,
background: 'red',
states: [
{hover: {background: 'blue', color: 'red'}},
{focus: {background: 'pink', outline: 'none', color: 'yellow'}}
]
//also tried
//':hover': {background: 'blue', color: 'red'},
//':focus': {background: 'pink', outline: 'none', color: 'yellow'}
},
primary: {
background: 'green'
},
warning: {
background: 'purple'
}
};
var items = this.state.items.map(function(item, i) {
return (
<div>
<div style= {[styles.base, styles['warning']]} key={item}>
// also tried <div style = {this.buildStyles(styles)} key={item}>
{item}
</div>
<button style = {[styles.base, styles['warning']]} onClick={update} >Remove</button>
</div>
);
}.bind(this));
return (
{items}
)
The issue was resolved by wrapping the React.createComponent with Radium as instructed in the Radium documentation. Instead of using the mixins, the code now looks like this and it works as intended.
AppBody = Radium(React.createClass({
mixins: [ReactMeteorData, Navigation, State],
render: function() {
var self = this;
var styles = {
base: {
color: this.state.fontColor,
background: 'red',
':hover': {background: 'blue', color: 'red'},
':focus': {background: 'pink', outline: 'none', color: 'yellow'}
},
primary: {
background: 'green'
},
warning: {
background: 'purple'
}
};
var items = this.state.items.map(function(item, i) {
return (
<div>
<div style= {[styles.base, styles['warning']]} key={item}>
{item}
</div>
<button style = {[styles.base, styles['warning']]} onClick={update} >Remove</button>
</div>
);
}.bind(this));
return (
{items}
)
)}));

Categories