Composition of react-emotion and external css (eg. bootstrap) classes - reactjs

Is there a way to add external (eg. bootstrap) classes along with react-emotion styling?
import React, { Component } from 'react';
import { css } from 'react-emotion';
const MyStyle = css`
STYLE
`
export default class MyComponent extends Component {
render() {
return (<button className={css`${MyStyle}` /* add in some way `btn btn-default` */ }>Text</button>);
}
}
Thanks!

Yes you can. Below is the link where i had made a small example, the font colour is coming from react-emotion and background colour is coming from bootstrap.
import React, { Component } from 'react';
import { render } from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import styled, { css } from 'react-emotion'
const myStyle = css`
color: rebeccapurple;
`;
class App extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
}
render() {
return (
<div className={myStyle + ' bg-primary'}>Hello World</div>
);
}
}
render(<App />, document.getElementById('root'));

Related

How to render a random trajectory animation infinitely, on some interval?

What I would like is to create a code that 'shoots' out some image from the center of the screen to some random trajectory.
Here is the descriptional code I would like to achieve:
class Name extends React.Component{
render(){
return (
<img animation moving from centre to some random trajectory>
after few seconds...
<another img animation (the same one) moving from centre to some other random trajectory>
<do it many more times, until event occurs that will stop it>
);
}
}
I have made components that create interface, and that render an image animation of movement from centre to some random trajectory, but only once. I don't know how to make it repeatedly.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import "./bootstrap/css/bootstrap.css";
import {CreateEnvironment} from './components/createEnvironment';
import {SheepsStart} from './components/sheepsStart';
class MainComponent extends React.Component {
render(){
return (
<React.Fragment>
<CreateEnvironment />
<SheepsStart />
</React.Fragment>
);
}
}
ReactDOM.render(<MainComponent/>, document.getElementById('root'));
Component CreateEnvironment is irrelevant, it creates 3 drawing divs.
Component SheepsStart:
import React from 'react';
import {CreateSheeps} from './createSheeps';
import sheep from '../images/sheep.png';
export class SheepsStart extends React.Component {
render(){
return (
<React.Fragment>
<CreateSheeps src = {sheep} alt = "Sheep"/>
</React.Fragment>
);
}
}
Styled component, which I needed so I could insert random #keyframes:
import styled from 'styled-components';
import { sheepWantsToEscape } from './KeyFrames';
export const CreateSheeps = styled.img`
width:2.5%;
z-index: 1;
position:absolute;
left:48.75%;
bottom:48.75%;
animation: ${sheepWantsToEscape} 4s;
animation-iteration-count:1;
animation-timing-function:linear;
`
export default CreateSheeps;
Component with #keyframes with random trajectory coordinates.Function createTrajectory calculates coordinates, and returns an array of two.
import styled, { keyframes } from 'styled-components';
import {createTrajectory} from './helperFunction';
let coordinates = createTrajectory();
export const sheepWantsToEscape = keyframes`
0% {
left:48.75%;
bottom:48.75%;
}
100% {
left:${coordinates[0]}%;
bottom:${coordinates[1]}%;
}
This is only an example, if you point out what you've tried out I'll can be more specific:
const base = 100;
class Hello extends React.Component {
state = {
myStyle : {
marginTop: base,
marginLeft: -base,
}
}
plusMinus = () => Math.random() < 0.5 ? -1 : 1;
randomize = () => {
this.setState({
myStyle: {
marginTop: Math.random()*base*this.plusMinus(),
marginBottom: Math.random()*base*this.plusMinus(),
},
});
}
render() {
return <div><img
style={{...this.state.myStyle}} src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/React-icon.svg/200px-React-icon.svg.png" />
<button onClick={this.randomize}>move</button>
</div>;
}
}
ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);
https://jsfiddle.net/vya19fz2/

How to pass Styled-Component theme variables to Components?

Within my React+StyledComponent app, I have a theme file like so:
theme.js:
const colors = {
blacks: [
'#14161B',
'#2E2E34',
'#3E3E43',
],
};
const theme = {
colors,
};
export default theme;
Currently, I can easily use these colors to style my components like so:
const MyStyledContainer = styled.div`
background-color: ${(props) => props.theme.colors.blacks[1]};
`;
The problem is, how do I pass blacks[1] to a Component as the prop of the color to use like so:
<Text color="black[1]">Hello</Text>
Where Text.js is:
const StyledSpan = styled.span`
color: ${(props) => props.theme.colors[props.color]};
`;
const Text = ({
color,
}) => {
return (
<StyledSpan
color={color}
>
{text}
</StyledSpan>
);
};
Text.propTypes = {
color: PropTypes.string,
};
export default Text;
Currently the above is silently failing and rending the following in the DOM:
<span class="sc-brqgn" color="blacks[1]">Hello</span>
Any ideas on how I can get this to work? Thank you
EDIT: Updated to use styled-components withTheme HOC
New answer
You could wrap the component rendering <Text> in the higher order component (HOC) withTheme provided by styled-components. This enables you to use the theme given to the <ThemeProvider> directly in the React component.
Example (based on the styled-components docs):
import React from 'react'
import { withTheme } from 'styled-components'
import Text from './Text.js'
class MyComponent extends React.Component {
render() {
<Text color={this.props.theme.colors.blacks[1]} />;
}
}
export default withTheme(MyComponent)
Then you could do
const MyStyledContainer = styled.div`
background-color: ${(props) => props.color};
`;
Old answer
You could import the theme where you render and pass <Text color={theme.blacks[1]} />.
import theme from './theme.js'
...
<Text color={theme.colors.blacks[1]} />
Then you could do
const MyStyledContainer = styled.div`
background-color: ${(props) => props.color};
`;
You can use defaultProps
import PropTypes from 'prop-types'
MyStyledContainer.defaultProps = { theme }
App.js
App gets theme and passes color to Text
import React, { Component } from 'react'
import styled from 'styled-components'
const Text = styled.div`
color: ${props => props.color || 'inherit'}
`
class App extends Component {
render() {
const { theme } = this.props
return (
<Text color={theme.colors.black[1]} />
)
}
}
export default App
Root.js
Root component passes theme to entire application.
import React, { Component } from 'react'
import { ThemeProvider } from 'styled-components'
import theme from './theme'
import App from './App'
class Root extends Component {
render() {
return (
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>
)
}
}
export default Root
If you're using functional components in React and v4.x and higher styled-components, you need to leverage useContext and styled-components' ThemeContext. Together, these allow you to use your theme settings inside of components that aren't styled-components.
import { useContext } from 'react'
import { ThemeContext } from 'styled-components'
export default function MyComponent() {
// place ThemeContext into a context that is scoped to just this component
const themeProps = useContext(ThemeContext)
return(
<>
{/* Example here is a wrapper component that needs sizing params */}
{/* We access the context and all of our theme props are attached to it */}
<Wrapper maxWidth={ themeProps.maxWidth }>
</Wrapper>
</>
)
}
Further reading in the styled-components docs: https://styled-components.com/docs/advanced#via-usecontext-react-hook

Does PureComponent work well with style array in React Native?

I know that the following snippet gets optimized if styles are created by Stylesheet.create() and Child extends PureComponent.
import React, { Component } from 'react'
import { View } from 'react-native'
import Child from './Child'
import styles from './stylesheets'
export default class Parent extends Component {
render() {
return (
<View>
<Child style={styles.x} />
</View>
)
}
}
Does it also works with multiple styles? I'm afraid that [] literals prevent optimization.
import React, { Component } from 'react'
import { View } from 'react-native'
import Child from './Child'
import styles from './stylesheets'
export default class Parent extends Component {
render() {
return (
<View>
<Child style={[styles.x, styles.y]} />
</View>
)
}
}
Or do I need to define combined style statically?
import React, { Component } from 'react'
import { View } from 'react-native'
import Child from './Child'
import styles from './stylesheets'
const childStyles = [styles.x, styles.y]
export default class Parent extends Component {
render() {
return (
<View>
<Child style={childStyles} />
</View>
)
}
}
I confirmed that array literal spoils PureComponent optimization.

Children component gets props as undefined

I'm trying to pass props to my children components which are under the controller. I'm using redux and react-router for navigation. The problem is that everything is fine in the controller, it gets its initial props, but when I'm passing them to a child I have an undefined either the constructor or in render function. Here is my code:
import React, { Component } from 'react'
import { connect } from 'react-redux'
import moment from 'moment'
import LawsuitSchedule from '../components/LawsuitSchedule'
import LawsuitCalendar from '../components/LawsuitCalendar'
class LawsuitScheduleContainer extends Component {
constructor (props) {
super(props)
}
render () {
let {schedule} = this.props
console.log(schedule)
return (
<LawsuitCalendar initialDate={schedule.initialDate}
selectedDate={schedule.selectedDate}
scheduledDates={schedule.scheduledDates}/>,
<LawsuitSchedule/>
)
}
}
const mapStateToProps = state => ({
schedule: state.schedule,
})
export default connect(mapStateToProps)(LawsuitScheduleContainer)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import momentPropTypes from 'react-moment-proptypes'
import moment from 'moment'
import DatePicker from 'react-datepicker'
import 'react-datepicker/dist/react-datepicker.css'
import '../styles/lawsuitCalendar.css'
export default class LawsuitCalendar extends Component {
constructor (props) {
super(props)
console.log(props)
}
propTypes = {
selectedDate: momentPropTypes.momentString,
scheduledDates: PropTypes.array.isRequired,
}
handleChange = (date) => {
this.setState({
selectedDate: date,
})
}
render () {
let {selectedDate, scheduledDates} = this.props
let highlightWithRanges = [
{
'scheduled-date': scheduledDates,
},
]
return (
<DatePicker
inline
selected={selectedDate}
onChange={this.handleChange}
highlightDates={highlightWithRanges}
/>
)
}
}
The problem was in another component, which renders LawsuitCalendar too. I have no clue why it was displayed only once, but I have solved my problem with props -- I just didn't pass them. I've added it, maybe someone can answer why has that happened?
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Grid, Row, Col } from 'react-bootstrap'
import { Link } from 'react-router-dom'
import ReactTable from 'react-table'
import matchSorter from 'match-sorter'
import LawsuitCalendar from '../components/LawsuitCalendar'
import '../styles/lawsuitGrid.css'
import data from '../utils/data.json'
export default class LawsuitSchedule extends Component {
render () {
return (
<Grid>
<Row className="show-grid">
<Col md={4}><LawsuitCalendar/></Col>
<Col md={8}>
<ReactTable data={data}
...
/>
</Col>
</Row>
</Grid>
)
}
}

How to apply custom theme in material ui

I am trying to apply a custom theme to my React component after reading this tutorial
http://www.material-ui.com/#/customization/themes
I wrote my theme in a separate javascript file like this
import Colors from 'material-ui/lib/styles/colors';
import ColorManipulator from 'material-ui/lib/utils/color-manipulator';
import Spacing from 'material-ui/lib/styles/spacing';
import zIndex from 'material-ui/lib/styles/zIndex';
export default {
spacing: Spacing,
zIndex: zIndex,
fontFamily: 'Roboto, sans-serif',
palette: {
primary1Color: Colors.cyan500,
primary2Color: Colors.cyan700,
primary3Color: Colors.lightBlack,
accent1Color: Colors.pinkA200,
accent2Color: Colors.grey100,
accent3Color: Colors.grey500,
textColor: Colors.deepPurpleA700,
alternateTextColor: Colors.white,
canvasColor: Colors.white,
borderColor: Colors.grey300,
disabledColor: ColorManipulator.fade(Colors.darkBlack, 0.3),
pickerHeaderColor: Colors.cyan500,
}
};
I apply this theme to my component in the follow way
import React from 'react';
import mui from 'material-ui';
import injectTapEventPlugin from 'react-tap-event-plugin';
import ThemeManager from 'material-ui/lib/styles/theme-manager';
import Colors from 'material-ui/lib/styles/colors';
import MyTheme from './theme.js';
injectTapEventPlugin();
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
messages : [{id: 1, text: 'Hi'}, {id: 2, text: 'Hello'}]
};
}
getChildContext() {
return {
muiTheme: ThemeManager.getMuiTheme(MyTheme)
};
}
componentWillMount() {
let newMuiTheme = this.state.muiTheme;
this.setState({
muiTheme: newMuiTheme,
});
}
render() {
var messageNodes = this.state.messages.map((message) => {
return (<div key={message.id}>{message.text}</div>);
});
return (<div>{messageNodes}</div>);
}
}
App.childContextTypes = {
muiTheme: React.PropTypes.object
};
export default App;
According to my theme when my control renders it should have a "deepPurpleA700" color .... but my control text is always black. So my theme is not applied.
My full code is available at https://github.com/abhitechdojo/MovieLensReact
You should first import your color from 'material-ui/styles/colors'
and then use them in palette object like this :
import React, { Component } from 'react';
import {render} from 'react-dom';
import {indigo500, indigo700, redA200} from 'material-ui/styles/colors';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();
import Main from './Main';
const muiTheme = getMuiTheme({
palette: {
primary1Color: indigo500,
primary2Color: indigo700,
accent1Color: redA200,
pickerHeaderColor: indigo500,
},
});
class App extends Component {
render() {
return (
<div>
<MuiThemeProvider muiTheme={muiTheme}>
<Main />
</MuiThemeProvider>
</div>
);
}
}
render(<App/>, document.getElementById('app')); //you should be having a div with an id of app in your index.html file
and the Main.js file is
import React, { Component } from 'react';
import FloatingActionButton from 'material-ui/FloatingActionButton';
export default class Main extends Component {
render() {
return (
<div>
<AppBar title="Title"/>
<FloatingActionButton secondary={true} />
</div>
);
}
}
For me it worked with:
import React, {Component} from 'react';
import {createMuiTheme} from '#material-ui/core/styles';
import MuiThemeProvider from '#material-ui/core/styles/MuiThemeProvider';
const theme = createMuiTheme({
palette: {
primary: {
main: '#0b5994',
},
secondary: {
main: '#1d83c6',
},
},
});
class App extends Component {
render() {
return (
<div className="App">
<MuiThemeProvider theme={theme}>
/* content here! */
</MuiThemeProvider>
</div>
);
}
}
export default App;
I am pretty sure you need to have
static childContextTypes = {
muiTheme: React.PropTypes.object,
};
before your
getChildContext()
method. Once that is done you should be able to remove any theme related stuff from
componentWillMount()
Now, this won't work for base text. But I can confirm that the theme is being applied. I tested it by adding an appBar component and changing the color in your theme.js file. I also added a List with ListItems and that text style is what you are looking for.
Here is a link to the gist of your modified App.jsx file.
Also, as a side note in you server.js you have a small typo on line 5 you should have
new webpackDevServer(webpack(config), {
not
new WebpackDevServer(webpack(config), {

Resources