I am not sure if this is the correct way of using CSS in gatsby but for some reason my external syles are not being applied in gatsby project.
This is what I am doing it
import { Link } from "gatsby"
import PropTypes from "prop-types"
import React from "react"
import "./header.css"
const Header = (props) => {
return (
<header
style={{
background: `black`,
marginBottom: `1.45rem`,
}}
>
<div
style={{
margin: `0 auto`,
maxWidth: 960,
padding: `1.45rem 1.0875rem`,
}}
>
<h1 style={{ margin: 0 }}>
<Link
to="/"
style={{
color: `white`,
textDecoration: `none`,
}}
>
{props.siteTitle} <span className="header-description"> {props.description} </span>
</Link>
</h1>
</div>
</header>
)
}
Header.propTypes = {
siteTitle: PropTypes.string,
}
Header.defaultProps = {
siteTitle: ``,
}
export default Header
and this is my header.css
.header-description {
font-size: 12;
}
Your css is invalid. font-size can't have unitless values except for 0.
Maybe you wanted it to be 12px?
what i usually do is create and import index.css into layer component (or any other wrapping component) aaaand then import individual/uniques/modules to that index.css. So the main index.css becomes sort of like a hub for css files which then is being imported only in once place. well, obviously if you would use css modules you would have to import them into your react components, but by the looks of it you are just using classnames. so...yea, try my method, maybe that helps? Theres also like 4 tutorials on how to import and use css and various styling methodologies in gatsby docs.
Related
I am using this api to create customize google calendar.
https://github.com/ericz1803/react-google-calendar
Here are the codeSandbox for demo, the tooltip is perfectly working.
https://codesandbox.io/s/cocky-rgb-2y3t7?file=/src/App.js
Then, I copied the same code into mine project with all path, API ... changed.
Every things works well, but the tooltip doesn't appear any more.
import React from "react";
import "./styles.css";
import Calendar from "#ericz1803/react-google-calendar";
import { css } from "#emotion/react";
const API_KEY = "AIzaSyAKzScoADeBmp6qUsEzrwZhLqb6WARNFOo";
//replace calendar id with one you want to test
let calendars = [
{ calendarId: "c_7q0ai3mn1p9b880f7llhbnv364#group.calendar.google.com" }
];
let styles = {
//you can use object styles
calendar: {
borderWidth: "3px" //make outer edge of calendar thicker
},
today: css`
/* highlight today by making the text red and giving it a red border */
color: red;
border: 1px solid red;
`
};
export default function App() {
return (
<div className="App">
<body>
<div
style={{
width: "90%",
paddingTop: "50px",
paddingBottom: "50px",
margin: "auto",
maxWidth: "1200px"
}}
>
<Calendar apiKey={API_KEY} calendars={calendars} styles={styles} />
</div>
</body>
</div>
);
}
There is open issue for same on github.
Till it gets fixed, use the same version of the package which is used in the sandbox demo, it doesn't have that bug.
"#ericz1803/react-google-calendar": "4.0.1"
I see that it is possible to embed React components with MDX:
https://v2.docusaurus.io/docs/markdown-features/#embedding-react-components-with-mdx
However, this method works for a specific page. How can I make it work for all markdown files in the docs? I am trying to add a similar component as in the link above to change the style of some inline text. I tried to edit src/pages/index.js but it didn't work.
const HighlightGreen = (children) => (
<span
style={{
backgroundColor: '#00a400', // green,
borderRadius: '2px',
color: '#fff',
padding: '0.2rem',
}}>
{children}
</span>
);
It seems now you could "swizzle" the root component, by creating a website/src/theme/Root.js file, according to: https://docusaurus.io/docs/using-themes#wrapper-your-site-with-root
yarn swizzle #docusaurus/theme-classic MDXComponents --danger
In src/theme/MDXComponents/index.js:
import {MyComponent} from "/src/components/MyComponent";
...
const MDXComponents = {
MyComponent,
...
I need to create a React component that is a Horizontal Divider with a content like text In between. All the resources I have online is unable to help me get this done. I tried a material-ui divider by creating a Divider component and placing my text in-between like the example below:
<Divider>Or</Divider>
But I get the error:
hr is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.
I need to achieve this in the image below:
Any help will be appreciated.
These are my codes below:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import List from '#material-ui/core/List';
import Divider from '#material-ui/core/Divider';
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
maxWidth: 360,
backgroundColor: theme.palette.background.paper,
},
}));
export default function ListDividers() {
const classes = useStyles();
return (
<List component="nav" className={classes.root} aria-label="mailbox
folders">
<Divider>Or</Divider>
</List>
);
}
Using Material UI.
import React from "react";
import { makeStyles } from "#material-ui/core";
const useStyles = makeStyles(theme => ({
container: {
display: "flex",
alignItems: "center"
},
border: {
borderBottom: "2px solid lightgray",
width: "100%"
},
content: {
paddingTop: theme.spacing(0.5),
paddingBottom: theme.spacing(0.5),
paddingRight: theme.spacing(2),
paddingLeft: theme.spacing(2),
fontWeight: 500,
fontSize: 22,
color: "lightgray"
}
}));
const DividerWithText = ({ children }) => {
const classes = useStyles();
return (
<div className={classes.container}>
<div className={classes.border} />
<span className={classes.content}>{children}</span>
<div className={classes.border} />
</div>
);
};
export default DividerWithText;
You can import and use it like the below
<DividerWithText>Or</DividerWithText>
Result
Here a custom example of what you could do : repro on stackblitz
import React, { Component } from "react";
import { render } from "react-dom";
import Hello from "./Hello";
import "./style.css";
const App = () => {
return <Divider>Or</Divider>;
};
const Divider = ({ children }) => {
return (
<div className="container">
<div className="border" />
<span className="content">
{children}
</span>
<div className="border" />
</div>
);
};
render(<App />, document.getElementById("root"));
And the CSS:
.container{
display: flex;
align-items: center;
}
.border{
border-bottom: 1px solid black;
width: 100%;
}
.content {
padding: 0 10px 0 10px;
}
Update 29/03/2022
That's now possible with Material UI 🔥
https://mui.com/components/dividers/#dividers-with-text
You may want different spacing sometime
<Divider spacing={1}>Hello World</Divider>
Or
<Divider spacing={2}>Hello World</Divider>
For a configurable spacing here a Github Gist
Or a playground in codesandbox if you prefer
The current answer causes any text with spaces in-between to wrap:
If that happens, changing width: 100% to flexGrow: 1 should solve it:
border: {
borderBottom: "2px solid lightgray",
flexGrow: 1,
}
Unfortunately for now, having Divider with text on it in MUI is only available in v5, which is still in alpha stage. If you would like to try, you can download the alpha package, but be warned that it is still highly unstable and a lot of changes might be needed to migrate to v5, which is not very worth it.
GitHub discussion: https://github.com/mui-org/material-ui/issues/24036
Is it possible to override scss variables in react. I have for example a theme.scss with some scss variables. Is it possible to change these scss variables with the props of the Container. I know I could change style={{
backgroundColor: style.backgroundColor }} into style={{ backgroundColor: this.props.backgroundColor }} but then the $primary-font-color would'nt change, because I set $primary-font-color: $item-color; in my theme.scss. Is it possible to OVERRIDE my scss variable $item-color so that also $primary-font-color change?
This is only some example-code to explain what i mean:
theme.scss
$background-color: white;
$item-color: gray;
$primary-font-color: $item-color; // I want to override $item-color so that also $primary-font-color changes
$secondary-font-color: darken($primary-font-color, 15%);
export: {
backgroundColor: $background-color;
itemColor: $item-color;
primaryFontColor: $primary-fonty-color;
secondaryFontColor: $secondary-font-color;
}
index.js
ReactDOM.render(
<Container
backgroundColor: 'gray,
itemColor: 'black' // I want to change my scss variable to this value
/>,
document.getElementById('root')
);
Container
import style from '../style/_theme.scss';
class Container extends Component {
render(){
<div style={{ backgroundColor: style.backgroundColor }} >
<div className='item' style={{ backgroundColor: style.itemColor }} >
<p style={{ backgroundColor: style.itemColor }} >Some Text.. </p>
</div>
</div>
}
As I said in the comment manipulating CSS (SCSS so on) with React is generally not a good idea, because it will become hard to maintain. The preferred way to do this would be using classes, as they are reusable and more readable.
In your case what you can do is to define different theme classes, for example:
.whiteTheme {
.backgroundColor {
color: white;
}
.itemColor {
color: white;
}
.primaryFontColor {
color: white;
}
}
.greyTheme {
.backgroundColor {
color: black;
}
.itemColor {
color: grey;
}
.primaryFontColor {
color: grey;
}
}
And then manipulate the theme class name with React (this can happen only once, or per component, if you need it):
class Container extends Component {
render() {
<div className={this.props.isWhiteTheme ? 'whiteTheme' : 'greyTheme'}>
<div style="backgroundColor">
<div className='item' style="itemColor">
<p style="primaryFontColor">Some Text.. </p>
</div>
</div>
</div>
}
}
P.S Naming props or CSS class backgroundColor is not desirable, it's just for general direction.
I'm having some trouble following the docs on how to get this to work
I have a component that has some styles created, for the most part, all of these styles will apply to wherever this component is rendered but sometimes depending on what page the app is routed to I will want to change the overall height of the component on those pages. I figured I could just do this by passing in some new height props of some sort to follow a more theme centric approach. How would I get this to work with my current setup?
The styles file
const styles = theme => ({
root: {
backgroundSize: 'cover',
padding: '25px 20px',
boxSizing: 'border-box',
backgroundPosition: '50% 0',
backgroundColor: 'rgba(40,70,94,.7)',
backgroundBlendMode: 'multiply',
...theme.root
}
});
export default styles;
The component file
import React from 'react';
import styles from './EventTop.styles';
import injectSheet, { ThemeProvider } from 'react-jss';
const EventTop = (props) => (
<ThemeProvider theme={props.theme}>
<aside className={props.classes.root} style={{ backgroundImage: `url(${props.event.event_logo})` }}>
<div className="wrapper">
<div className="event-info">
<span className="event-time">
7:00 PM
</span>
<span className="event-date">
27 Jun 2020
</span>
<span className="event-end-time">
Ends at 10:00 PM
</span>
<span className="event-title">
Bidr Gala
</span>
<span className="event-attire">
Cocktail Attire
</span>
</div>
</div>
</aside>
</ThemeProvider>
);
export default injectSheet(styles)(EventTop);
And then when I render it I pictured something like this
<EventTop event={this.props.events.currentEvent} theme={{ height: 'calc(100vh - 64px)' }}/>
But when I try to console log out the theme getting passed to the style generator I don't see the theme coming in.
I have Material UI installed and the whole app is wrapped in it's MuiThemeProvider
<Provider store={store}>
<MuiThemeProvider theme={theme}>
<App>
<Reboot />
<AppRouter />
</App>
</MuiThemeProvider>
</Provider>
And this is the theme I'm actually seeing the material theme and not my own merged anywhere in it.
Here is how I got this to work
First I moved the stateless component into a new file
EventTop.component.jsx
import React from 'react';
import Moment from 'react-moment';
import styles from './EventTop.styles';
import themableWrapper from '../Themable';
const EventTopComponent = (props) => (
<aside className={props.classes.root} style={{ backgroundImage: `url(${props.event.event_logo})` }}>
<div className="wrapper">
<div className={props.classes.eventInfo}>
<span className={props.classes.eventTime}>
<Moment parse="HH:mm:ss" format="h:mm A">{props.event.start_time}</Moment>
</span>
<span className={props.classes.eventDate}>
<Moment parse="YYYY-MM-DD" format="D MMM YYYY">{props.event.event_date}</Moment>
</span>
<span className={props.classes.eventEndTime}>
Ends at <Moment parse="HH:mm:ss" format="h:mm A">{props.event.end_time}</Moment>
</span>
<span className={props.classes.eventTitle}>
{props.event.auction_title}
</span>
<span className={props.classes.eventAttire}>
{props.event.attire}
</span>
</div>
</div>
</aside>
);
export default themableWrapper(styles)(EventTopComponent);
Then in the EventTop.jsx I import the stateless component and return another stateless component but this one is wrapped in a new themable wrapper
import React from 'react';
import EventTopComponent from './EventTop.component';
import { Themable } from '../Themable';
const EventTop = ({ theme, ...rest }) => (
<Themable theme={theme}>
<EventTopComponent {...rest} />
</Themable>
);
export default EventTop;
Inside the new themable file, I have some exports setup
import injectSheet, { createTheming } from 'react-jss';
export const theming = createTheming('__NEW_THEME_NAMESPACE__');
export const { ThemeProvider: Themable } = theming;
export default (styles) => injectSheet(styles, { theming });
And then in the style generator, I can use something like lodash to merge my incoming theme with the default styles setup
EventTop.styles.js
import { merge } from 'lodash';
const styles = theme => {
return merge({
root: {
backgroundSize: 'cover',
padding: '25px 20px',
boxSizing: 'border-box',
backgroundPosition: '50% 0',
backgroundColor: 'rgba(40,70,94,.7)',
backgroundBlendMode: 'multiply',
},
eventInfo: {
flexGrow: '1',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-end',
textAlign: 'left',
paddingTop: '20px',
fontWeight: '700',
color: 'white'
},
eventTime: {
fontSize: '55px'
},
eventDate: {
fontSize: '43px'
},
eventEndTime: {
fontSize: '30px'
},
eventTitle: {
fontSize: '70px'
},
eventAttire: {
fontSize: '30px'
}
}, theme);
};
export default styles;
In order for this to work with MuiThemeProvider wrapping the whole app I have to set up a new namespace, and then use the createTheme to make a new theme provider instance. This then needs to wrap the actual component code which is why I opted to create essentially a "container" component and the actual component as separate pieces so I could keep the logic separate. Plus this still allows me to make one stateless and the other not if I so choose
You are confusing MuiThemeProvider and the one from react-jss.