I'm trying to use CircularProgress provided by Material.
I created this component in order to change its color:
import React, { Component } from 'react';
import { withStyles } from '#material-ui/core/styles';
import { CircularProgress } from '#material-ui/core';
class ColoredCircularProgress extends Component {
render() {
const { classes } = this.props;
return <CircularProgress {...this.props} classes={{colorPrimary: classes.colorPrimary}}/>;
}
}
const styles = props => ({
colorPrimary: {
backgroundColor: '#FD8907',
}
});
export default withStyles(styles)(ColoredCircularProgress);
However on my site it looks like this:
My questions are :
I want the circle to look orange and instead the circle looks still blue and it adds a square orange box behind.
It also displays at the top left corner of my site. How can I place it right in the center?
To change the color you can simple do this:
<CircularProgress style={{'color': 'yellow'}}/>
It works for Material-UI v4.x (I didn't try with minor versions)
You can override the style by applying css on .MuiCircularProgress-colorPrimary class.
Try this, hope this will work.
Example
.MuiCircularProgress-colorPrimary {
color: green !important;
}
.MuiCircularProgress-root {
left: 43%;
position: absolute;
top: 44vh;
}
Add this to the overrides in your theme. To make the color change globally.
MuiCircularProgress:{circle:{color:"green"},}
You don't need to override css.
Here's my solution:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import { CircularProgress } from '#material-ui/core';
const defaultSize = 50;
class ColoredCircularProgressComponent extends Component {
render() {
const { classes, size } = this.props;
return <CircularProgress {...this.props} classes={classes} size={size} />;
}
}
class ColoredCircularProgress extends Component {
render() {
const WithStylesComponent = withStyles(theme => ({
colorPrimary: {
color: this.props.foreColor
},
root: {
top: `calc(50% - ${this.props.size / 2}px)`,
left: `calc(50% - ${this.props.size / 2}px)`,
position: 'absolute'
}
}))(ColoredCircularProgressComponent);
return <WithStylesComponent {...this.props} />;
}
}
ColoredCircularProgress.propTypes = {
classes: PropTypes.object,
size: PropTypes.number,
foreColor: PropTypes.string
};
ColoredCircularProgress.defaultProps = {
size: defaultSize,
foreColor: 'green'
};
export default ColoredCircularProgress;
Related
I am new to redux with intermediate experience in React. I have two components ButtonAppBar and CriticalIssues. I am trying to reveal the CriticalIssues component on click of a button in ButtonAppBar. ButtonAppBar is throwing Cannot read property 'props' of undefined when the button is clicked. I have been stuck on this for a long time, any help would be appreciated.
My code is:
ButtonAppBar.js
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import styled from 'styled-components'
import CriticalIssues from '../CriticalIssues'
import { showCriticalBugs } from 'containers/App/actions';
import { connect } from 'react-redux';
import { show_critical } from '../../containers/App/sagas';
const styles = {
root: {
flexGrow: 1,
},
grow: {
flexGrow: 1,
textAlign: "left"
},
menuButton: {
marginLeft: -12,
marginRight: 20,
},
};
const Button = styled.button`
background: linear-gradient(45deg, #fe6b8b 30%, #ff8e53 90%);
border-radius: 3px;
border: 0;
color: white;
height: 48px;
padding: 0 30px;
box-shadow: 0 3px 5px 2px rgba(255, 105, 135, .3);
`
export class ButtonAppBar extends React.Component {
constructor(props) {
super(props);
}
componentDidMount(){
this.showCritical();
}
showCritical(){
this.props.dispatch(showCriticalBugs());
}
render() {
return (
<div>
<AppBar position="static">
<Toolbar>
<Typography variant="h6" color="inherit">
Regression 360
</Typography>
<Button onClick={this.showCritical} color="inherit">Predict Critical Bugs</Button>
</Toolbar>
</AppBar>
</div>
);
};
}
ButtonAppBar.propTypes = {
dispatch: PropTypes.func,
};
export default connect()(ButtonAppBar);
sagas.js
import {showCriticalBugs} from './actions'
import { call, cancel, select, take, takeLatest, put } from 'redux-saga/effects';
export function* show_critical (){
yield put(showCriticalBugs());
}
actions.js
export const SHOW_CRITICAL = 'SHOW_CRITICAL';
export function showCriticalBugs() {
return {
type: SHOW_CRITICAL,
};
}
reducer.js
import SHOW_CRITICAL from './actions'
const initialState = fromJS({
visible: false
});
function appReducer(state = initialState, action) {
switch (action.type) {
case SHOW_CRITICAL:
console.log("m here");
return state.set('visible', true);
}
}
export default appReducer;
CriticalIssue.js
import React from 'react';
import PropTypes from 'prop-types'
import { connect } from 'react-redux';
import { Card, Typography, Button } from '#material-ui/core'
var mainDiv = {
padding: 10,
width: "auto",
fontFamily: "monospace",
textAlign: "center"
};
class CriticalIssues extends React.Component {
componentDidMount(){
console.log(this.props.visible)
}
render() {
if (this.props.visible) {
return (
<Card>
<div style={mainDiv}>
<Typography variant={'h1'} color={"error"}>3</Typography>
<Typography component={"h3"}>Critical Issues</Typography>
</div>
</Card>
);
}
else return (null);
}
}
function mapStateToProps(state) {
return {
visible: state.getIn(['global', 'visible']),
};
}
export default connect(mapStateToProps)(CriticalIssues);
You must bind your function to access 'this' keyword in your method
you can use this
<Button onClick={this.showCritical.bind(this)} color="inherit">Predict Critical Bugs</Button>
or you can also bind your methods in constructor like below
constructor(props){
super(props)
this.showCritical = this.showCritical.bind(this)
}
How can I access the ThemeProvider props in global.js when using styled-components?
For example in theme.js I have ${props => props.theme.fonts.fontSize} calling a default font size of 16px
const theme = {
fonts: {
fontSize : '16px',
}
}
export default theme
This is provided in /layouts/index.js as
import React from 'react'
import { ThemeProvider } from 'styled-components'
import '../style/global';
import theme from '../style/theme'
class Template extends React.Component {
render() {
const { children } = this.props
return (
<ThemeProvider theme={theme}>
...
{children()}
...
</ThemeProvider>
)
}
}
export default Template
From here I can access the ${props => props.theme.fonts.fontSize} within each component or child page.
But how can I pass to global.js in the same way when global is technically a level above theme.js? So that I could create a global style as
injectGlobal`
html {
font-size: (${props => props.theme.fonts.fontSize} / 16px) * 1em;
}
`
The easiest way off solving this is by creating a top level component that injects your desired styling like this:
import { Children } from 'react';
import { withTheme, injectGlobal } from 'styled-components';
const GlobalComponent = ({ theme, children }) => {
injectGlobal`
font-size: ${theme.fonts.fontSize}
}
`;
return Children.only(children);
};
export default withTheme(Global);
This will make sure all Components that have this Component as a parent will have the desired globalStyling. Hope this helped
Late but now we can actually create a Global Component and pass it as a child of ThemeProvider. It will allow you to access all the props of current theme.
Example for applying font family:
Your Global.js / Global.ts
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
html,
body {
padding: 0;
margin: 0;
font-family: ${(props) => props.theme.font.family}
}
a {
color: inherit;
text-decoration: none;
}
* {
box-sizing: border-box;
}
`;
export default GlobalStyle;
Your Main component app.tsx / app.jsx
import theme...
import { ThemeProvider } ...
imort GlobalStyle from '../path-to-global-file';
const App ...
.
.
return(
<>
<ThemeProvider theme={theme}>
<GlobalStyle />
{ /* Root component */ }
<Component/>
</ThemeProvider>
</>
);
You can use the props easily now.
Wizard and WizardPage
I am trying to build a generic Wizard and WizardPages to be generic a reusable across my app. I think the Wizard component as the one in charge of managing the state, and the WizardPage that is going to work as a wrapper, and will render Back, Cancel and Next buttons. It's suppose that the Next button (maybe the Back too) should dispatch an redux action. This action, could be different depending on the component being wrapped. This is what i have (not complete version):
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import withWizardLayout from '../../hoc/WithWizardLayout';
class Wizard extends Component {
constructor(props) {
super(props);
this.state = {
page: 0,
};
}
nextPage = () => {
this.setState({ page: this.state.page + 1 });
};
previousPage = () => {
this.setState({ page: this.state.page - 1 });
};
render() {
const { wizardPages } = this.props;
const { page } = this.state;
const wizardItem = wizardPages[page];
const nextPage = this.nextPage;
const previousPage = this.previousPage;
const ComponentWrapped = withWizardLayout(wizardItem.ComponentWrapped, nextPage, previousPage);
return (
<ComponentWrapped />
);
}
}
export default Wizard;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { compose } from 'react-apollo';
import { connect } from 'react-redux';
import { Flex, Box } from 'reflexbox';
import { BlueRoundButton, GreyRoundButton } from '../components/Button';
export default function withWizardLayout(ComponentDependent, nextPageCallBack, previousPageCallback) {
class WizardPage extends Component {
previousPage = () => {
};
nextPage = () => {
this.props.test();
};
render() {
const { ComponentWrapped, isFirstPage, isLastPage } = ComponentDependent;
return (
<Flex column>
<ComponentWrapped
isLastPage={isLastPage}
isFirstPage={isFirstPage}
>
<Flex justify='flex-end'>
<Flex mr='auto' w={0.1}>
<GreyRoundButton style={{ fontWeight: '500', position: 'relative', top: '10%' }}>Back</GreyRoundButton>
</Flex>
<Flex w={0.08} mr={2} align='center' justify='center' style={{ textAlign: 'center' }}>
<span>Cancel</span>
</Flex>
<Flex w={0.15} justify='center'>
<BlueRoundButton onClick={this.nextPage} style={{ position: 'relative', top: '10%', fontWeight: '500' }}>Continue</BlueRoundButton>
</Flex>
</Flex>
</ComponentWrapped>
</Flex>
);
}
}
CustomersContainer
import { compose } from 'react-apollo';
import { connect } from 'react-redux';
import CustomerImport from '../components/Settings/CustomerImport';
import { withWizardLayout } from '../hoc/WithWizardLayout';
const mapStateToProps = null;
const mapDispatchToProps = dispatch => (
{
test: () => (dispatch(console.log("hi"))),
}
);
export default compose(connect(null, mapDispatchToProps))(CustomerImport);
Connected Component
import React, { Component } from 'react';
import styled from 'styled-components';
import {
SettingBlock,
NotifyBlock,
SuccessMessage,
ErrorMessage,
Instructions,
} from './styles';
import ExcelUploader from '../ExcelUploader';
const ProgressBar = styled.div`
width: 0;
height: 30px;
background-color: Green;
`;
const ExcelWrapper = styled.div`
margin-bottom: 4rem;
`;
export default class CustomerImport extends Component {
constructor(props) {
super(props);
this.state = {
progress: 0,
notify: {
success: {
message: '',
active: false,
},
error: {
message: '',
active: false,
},
},
};
}
render() {
const { success, error } = this.state.notify;
const ButtonsWrapper = this.props.children;
return (
<div>
<NotifyBlock>
<SuccessMessage className={success.active ? 'active' : null}>{success.message}</SuccessMessage>
<ErrorMessage className={error.active ? 'active' : null}>{error.message}</ErrorMessage>
</NotifyBlock>
<SettingBlock>
<h3>
Import your customers
</h3>
<ProgressBar style={{ width: `${this.state.progress}%` }} />
<Instructions>
Select an Excel file containing your customer information.
Need a template? Grab one here.
</Instructions>
<ExcelWrapper>
<ExcelUploader />
</ExcelWrapper>
{ButtonsWrapper}
</SettingBlock>
</div>
);
}
}
This is how i am supposed to render the Generic Wizard, we can have X wizardPages:
const wizardPages = [
{
ComponentWrapped: CustomersContainer,
isFirstPage: false,
isLastPage: false,
},
];
<Wizard wizardPages={wizardPages} />
The problem with this approach, is that i want on the onClick of the buttons in withWizardLayout:
1) Execute the callback on the Father (that's possible, i am passing as prop the handler)
2) Call the dispatch action received of the container. (i am not able not access the dispatched action, in this case, this.props.test)
How can i refactor this, to think a generic way to handle this? I think another ways to refactor this (having different withWizardLayout functions, but i am having render problems on the console).
Maybe i didn't architect this in the best way.
Help!
I'm trying to achieve dark and light themes in my React app. I know how themes work, so I'm configuring my button like below, for example :
const Button = styled.button`
/* some styles */
color: ${props => props.theme.main}
`;
Then I'm defining themes as consts:
const dark = {
main: 'black',
text: 'switch to light mode'
};
const light = {
main: 'white',
text: 'switch to dark mode'
};
And when I want to use the theme somewhere I do it like this:
<ThemeProvider theme={dark}>
<Button>{dark.text}</Button>
</ThemeProvider>
But what I want to achieve is to change the theme dynamically (on a click function on the button probably). I'm kind of new to React so please don't be mean to me.
Something like this? Demo
import React, { Component } from 'react';
import { render } from 'react-dom';
import styled, { ThemeProvider } from 'styled-components';
const themes = {
'light': {
main: '#EFEFEF',
},
'dark': {
main: '#666',
}
}
const DynamicDiv = styled.div`
background: ${({ theme }) => theme.main};
`
class App extends Component {
constructor() {
super();
this.state = {
name: 'React',
theme: themes['light']
};
}
handleDark = () => {
this.setState({ theme: themes['dark'] })
}
render() {
return (
<ThemeProvider theme={this.state.theme}>
<div>
<DynamicDiv>{this.state.name}</DynamicDiv>
<div onClick={this.handleDark}>Change to Dark</div>
</div>
</ThemeProvider>
);
}
}
render(<App />, document.getElementById('root'));
How do I remove the white spaces around my dashboard header on reactjs
Anyone can help first time doing react and css. not sure what is need to make this work.
The full source code is here.
Header.js
import React, { Component, PropTypes } from 'react'
class Header extends Component {
render() {
const { todos, actions } = this.props
return (
<div style = {divStyle}>
<h1>
Dashboard
</h1>
</div>
)
}
}
var divStyle = {
background: "black",
textAlign: "center",
color: "white"
}
export default Header
App.js
import React, { Component, PropTypes } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import * as TodoActions from '../actions/todos'
import Header from '../components/Header'
class App extends Component {
render() {
const { todos, actions } = this.props
return (
<div style = {divStyle}>
<Header/>
</div>
)
}
}
var divStyle = {
margin: 0,
padding: 0
}
App.propTypes = {
todos: PropTypes.array.isRequired,
actions: PropTypes.object.isRequired
}
function mapStateToProps(state) {
return {
todos: state.todos
}
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(TodoActions, dispatch)
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(App)
I am not sure about your React Code. But this is an issue with CSS, you are not reseting stuff. It is caused by margin or body or something else. Use the following reset.
* {
margin: 0;
padding: 0;
}
Got it!
var divStyle = {
position: "absolute",
top: 0,
right: 0,
bottom: 0,
left: 0,
margin: 0,
padding: 0
}