I'm using Radium to write inline css in React and i have the following error when i want to use "hover":
Uncaught TypeError: Cannot read property '_currentElement' of null
Did i do something wrong ?
import React from 'react';
import Radium from 'radium';
class Header extends React.Component {
render() {
var styles = {
base: {
backgroundColor: 'white',
':hover': {
backgroundColor: 'black'
}
},
anchor: {
color: 'black',
':hover': {
color: 'white',
}
}
}
return (
<div>
<div style={styles.base}>
<a style={styles.anchor}>Some text</a>
</div>
</div>
);
}
}
Header = Radium(Header);
export default Header;
In fact, if i didn't use styles.anchor, it worked. So i don't understand why it doesn't work with styles.anchor.
Another problem, when i try to add the prefix #Radium before the class Header extends React.Component, i got a compilation's error.
Thank you !
If you're using babel you have to install plugin-transform-decorators-legacy in order for the #Radium to work properly but it's currently deprecated and I doubt it will be coming back anytime soon so I would stick with wrapping your component export default Radium(Header).
Related
I defined a object useStyle and called it in the component SecondTest defined background color, is it possible to add hover in the object useStyle
const useStyle = {
backgroundColor: "red",
};
function SecondTest() {
return <div style={useStyle}>SecondTest go down</div>;
}
export default SecondTest;
You can use Radium React Library
import React from "react";
import Radium from "radium";
const style = {
color: "#000000",
":hover": {
color: "#ffffff"
}
};
const MyComponent = () => {
return <section style={style}>hello world</section>;
};
const MyStyledComponent = Radium(MyComponent);
export default function App() {
return (
<>
<MyStyledComponent />
</>
);
}
You can accomplish it with events like onMouseEnter & onMouseLeave if you wish to use javascript to solve your issue. Easier way to do it would be just to give an element className like
<section className='myClass'>hello world</section>
and then just to add desired properties in your .css file which you can import in your component or globally.
.myClass {
color: #000000;
}
.myClass:hover {
color: #ffffff;
}
It is not possible to add hover with in-line styles.
I completed my project now I want to set my custom font to all Text component.
I think the best way is to create a custom Text component and replace it with default Text of react-native.
now how can I creating a custom Text component with default style?
To achieve that, you need to have a react native component that is configurable via style or other properties once instantiated.
For example you can have your custom react native component CustomText like this:
1. Function component
If you prefer the new way and you'll use it with hooks, use this part:
// CustomText.js
import React from 'react';
import {
Text,
StyleSheet,
} from 'react-native';
export default function CustomText(props) {
return (
<Text style={[styles.defaultStyle, props.style]}>
{props.children}
</Text>
);
}
const styles = StyleSheet.create({
// ... add your default style here
defaultStyle: {
},
});
2. Class component
If you prefer the old way with classes use this part:
// CustomText.js
import React from 'react';
import {
Text,
StyleSheet,
} from 'react-native';
export default class CustomText extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<Text style={[styles.defaultStyle, this.props.style]}>
{this.props.children}
</Text>
);
}
}
const styles = StyleSheet.create({
// ... add your default style here
defaultStyle: {
},
});
And then on your main component you import and call that custom component, something like this:
import CustomText from './CustomText';
//... other imports go here.
// in the render method you call your CustomText component.
render(){
//...
<CustomText style={{ fontWeight: 60, }}>
This is custom Text
</CustomText>
}
Note: If you want only to change the style I think #Yanush solution is the best for that case.
I hope this is helpful.
I would suggest using a style instead of a custom component but it's up to you.
In my project I have created a file named "commonStyles.js" that looks like this:
export default StyleSheet.create({
textTitle: {
fontSize: 20,
color: '#dddddd',
fontFamily: 'YourCustomFont',
},
});
then I'm importing this file wherever needed using:
import stylesCommon from './styles/stylesCommon';
and each text that needs to be changed should look like this:
<Text style={stylesCommon.textTitle}>
This is my title
</Text>
this guide will help you on how to apply custom fonts, I have been using the method in my apps.
To create a custom text component
export default Text = (props)=>{
return(
<Text style={[styles.defaultStyles,props.style]}>{props.children}</Text>
)
}
Now in all the files where you have used Text from react native remove import from react native and add
import Text from './path/to/component'
I’m using Draft.js for a project. I created a component that allows you to choose a font from a menu, then apply that font to the selected text in the Draft.js editor.
The way I need to do this:
Dynamically add a #font-face rule for the selected font that includes the font name and file location;
Create a new CSS class containing the font-family property that uses the font name from the #font-face rule that was added; and
Apply that new CSS class to the selection.
I’ve gotten everything but #2 figured out. For #2, I’m not finding any clear methods or tools to use that allow me to create new CSS classes in the global space. I’m reading a lot about css-in-js, but everything seems bloated or overly complex.
I’m formatting the #font-face rule and class like this:
const newClass = {
'#font-face': [
{
fontFamily: `${font.label} ${FONT_FAMILY_PREFIX}-A`,
src: `url(/fonts/${font.value}-TD-Space.woff)`,
fontWeight: 'normal',
fontStyle: 'normal',
}, {
fontFamily: `${font.label} ${FONT_FAMILY_PREFIX}-B`,
src: `url(/fonts/${font.value}-TD.woff)`,
fontWeight: 'normal',
fontStyle: 'normal',
},
],
[`.${font.value}`]: {
fontFamily: `${font.label} ${FONT_FAMILY_PREFIX}-A, ${font.label} ${FONT_FAMILY_PREFIX}-B`,
},
})
But I’m just not sure where to put it so it’s accessible across the app.
Does this require the help of some package or is there a simpler way I can manage it without?
The simplest way is probably to use React's Context feature (docs here)
Basically, you define a context like this:
// style-context.js
export const Styles = {
style1: {
fontFamily: '"Times New Roman", Times, serif',
fontSize: '12px'
},
style2: {
fontFamily: 'Arial, Helvetica, sans-serif',
fontSize: '16px'
},
};
export const StyleContext = React.createContext({
theme: styles.style1, // default value
changeTheme: (newTheme) => {}
}
);
Then, you wrap your App like this:
// App.js
import React, { Component } from 'react'
import { FontContext, styles } from './style-context'
class App extends Component {
constructor(props) {
super(props)
// Function to change the theme
this.chooseTheme = (newTheme) => {
this.setState({
theme: styles[newTheme]
})
}
// State includes the current theme and function to change it
this.state = {
theme: styles.style1,
chooseTheme: this.chooseTheme
}
}
render() {
return (
// Wrap with the context's Provider, and pass in the theme from
// the state. Those state values will be available from all
// children, no matter how deep.
<StyleContext.Provider value={this.state}>
<div className="App">
{/* components */}
</div>
</StyleContext.Provider>
);
}
}
There are two ways to use the context, then. First, you can reference it in any child component like this:
// SomeComponent.js
import React, { Component } from 'react'
import {StyleContext} from './style-context'
class SomeComponent extends Component {
render() {
return (
<div style={
this.context.theme
}>
{/* ... */}
</div>
)
}
}
SomeComponent.contextType = StyleContext
export default SomeComponent
Really simple. The other way to access it is like this, which is useful if you have multiple Contexts you're combining on a single Component:
// TestButton.js
import React, {Component} from 'react'
import {StyleContext} from './style-context'
class TestButton extends Component {
render() {
return (
<StyleContext.Consumer>
{
// The contents of the Consumer tag will receive the
// 'value' prop set at the Provider level, which is,
// in this case, the App state containing the current
// theme and function to change it
({theme, chooseTheme}) => (
<button onClick={() => {chooseTheme('style2')}} style={theme}>Change Font</button>
)
}
</StyleContext.Consumer>
)
}
}
export default TestButton
Doing that will mean you don't need to programmatically change the classes that different divs are given, nor need to generate CSS classes in the first place.
Also, one of my favorite tricks for assigning styles is to use Object.assign() to do so, like this:
...
<div style={Object.assign(
{ backgroundColor: 'red', fontSize: '16px' },
this.context.theme
)}>
...
That way, you can set default values, decoupling the Context from the Component, and allows the theme's style attributes to only override matching keys, combining the rest.
I am trying out React-Jss from cssinjs.org/react.jss and this is what I've done upto now:
Installation:
npm install --save react-jss
I then tested this file where I added a Hover to the footer just to give this a test:
import React from 'react';
import injectSheet from 'react-jss';
const style = {
Footer: {
backgroundColor: '#000000',
},
'&:hover': {
backgroundColor: '#ff0000',
}
};
export class Footer extends React.Component {
render() {
return (
<Footer>This is the footer</Footer>
);
}
}
export default injectSheet(style);
When I hover over the Footer component I would expect the footer to turn red but nothing is happening.
I'm I missing something or is something wrong in the syntax?
There's a handful of reasons the code above isn't working. There's issues with your React code beyond the JSS syntax.
In regards to the JSS style declaration specifically, let's first make sure you understand what you're declaring in the style object. The properties of the style object (in your case Footer, are the class names that you want to define and as such should probably be all lowercase. The value of each of those properties is an object containing the CSS styles that you want applied by that class. If you want to define a hover styles for a given class then you would declare those styles inside of the class's style object like so:
const style = {
footer: {
backgroundColor: '#000000',
'&:hover': {
backgroundColor: '#ff0000',
}
}
};
I suspect you're attempting to follow the first code example under 'Usage' in the package's readme. Here's a working example that follows that approach.
import React from 'react'
import injectSheet from 'react-jss'
const style = {
footer: {
backgroundColor: '#000000',
'&:hover': {
backgroundColor: '#ff0000'
}
}
}
const Footer = ({sheet}) => (
<div className={sheet.classes.footer}>This is the footer</div>
)
export default injectSheet(style)(Footer)
Below is a working example that utilizes the advantages of ES6 in case you're interested.
import React, {PropTypes} from 'react';
import injectSheet from 'react-jss';
const style = {
footer: {
backgroundColor: '#000000',
'&:hover': {
backgroundColor: '#ff0000'
}
}
};
#injectSheet(style)
export default class Footer extends React.Component {
static propTypes = {
sheet: PropTypes.object.isRequired
}
render() {
const {sheet} = this.props
return (
<div className={sheet.classes.footer}>This is the footer</div>
);
}
}
I'm using react-bootstrap NPM package to make my React components look properly. I need to customize some of them, so I'm following the official React-Bootstrap documentation, but the code throws the error index.jsx:5 Uncaught TypeError: Cannot read property 'addStyle' of undefined.
This is my custom Button component code:
import React from "react";
import Button from 'react-bootstrap/lib/Button';
import bootstrapUtils from 'react-bootstrap/lib/utils/bootstrapUtils';
bootstrapUtils.addStyle(Button, 'custom');
export default class MediaItemButton extends React.Component {
render() {
return (
<div>
<style type="text/css">{`
.btn-custom {
background-color: purple;
color: white;
}
`}</style>
<Button bsStyle="primary">Custom</Button>
</div>
);
}
}
Change to this:
import { bootstrapUtils } from 'react-bootstrap/lib/utils';
You can do this as well:
import React from "react";
import Button from 'react-bootstrap/lib/Button';
import bootstrapUtils from 'react-bootstrap/lib/utils/bootstrapUtils';
bootstrapUtils.addStyle(Button, 'custom');
export default class MediaItemButton extends React.Component {
render() {
var styles={
"backgroundColor" : "purple",
"color" : "white"
};
return (
<div>
<Button style={styles} bsStyle="primary">Custom</Button>
</div>
);
}
}
bootstrapUtils is a named export and not a default therefore you need to use {} around it.
Try using:
import { bootstrapUtils } from 'react-bootstrap/lib/utils/bootstrapUtils';