Using hooks inside createGlobalStyle - javascript

Hey I am trying to use hooks inside styled-components - createGlobalStyle.
I know that this is not possible, because createGlobalStyle is a function and neither a component nor a custom hook.
Maybe someone knows a workaround or a solution :).
export const GlobalStyle = createGlobalStyle`
p {
padding: ${p => useMediaQuery('min-width(768px)') && 12px};
}
`

One workaround can be to add a media query hook anywhere in your code, catch the screen size, send value in props (prop drilling, context Api, redux) to make your styled components adapt to your screen.
You may go through this link

You are not need to use hooks outside of functional components. Poof
Two ways, which i see, how you can do your task.
add media query directly in createGlobalStyle.
export const GlobalStyle = createGlobalStyle`
#media only screen and (min-width: 768px) {
p {
padding: 12px;
}
}
`
make separate function with some logic
const minWidthMedia = (minWidth: string) => {
const size = getScreenSize()
const isValid = minWidth > size.width
if (!isValid) return
return css`
p {
padding: 12px;
}
`
// or
// without validation logic
// return css`
// #media only screen and (min-width: ${minWidth}px) {
// p {
// padding: 12px;
// }
// }
}
export const GlobalStyle = createGlobalStyle`
${minWidthMedia('768px')}
`

Related

media query inside styled components - result not showing in console

I am coding in Js and for the responsive design I created a responsible.js file:
import { css } from "styled-components";
export const mobile = (props) => {
return css`
#media only screen and (max-width: 380px) {
${props}
}
`;
};
For each component I wrote props in this way :
${mobile({height: "20vh"})}
But I can't see the result in the console and don't know why.
Did I miss something?
Thank you for any help!

Arrow function is null inside tagged template literal function

I'm trying to decipher how styled components work. I get most parts, but interpolations.
Consider this component:
const display = 'flex'
const Container = styled.div`
background-color: red;
color: ${(props) => props.color};
display: ${display};
`
The function that receives the styles is something like this:
const styled = {
div: (string, ...values) => {
return ({children, ...props}) => {
const styles = tag(string, props, ...values);
return <div style={styles}>{children}</div>
}
}
}
string in this case is: ["\n background-color: red;\n color: ",";\n display: ",";\n"]
values are logged as: [null,"flex"]
The first interpolation (the arrow function) is null.
How does styled-components manage to solve this?
It seems it is working properly in Chrome. I tried it inside a playground in VSCode where I got the null value.

How to dynamically update styled-components in React?

So on a project I'm working on I want to be able to update the theme of my website when a user changes the currentTheme variable which is set up using useState, and references some objects I have in another file with predefined styles. I am having trouble updating and setting these styles up using styled-components.
I currently have it so whenever the user changes the theme(which is done in another component) it will update the current chosen theme. As you can see there's a console.log there, and the background colour does update accordingly, it just doesn't work with the styled-components. I would like to state that I have tried moving the styled.div into my CodeContainer component and it worked there, but the performance of the app was HORRIBLE when I made that change.
I basically need to know how to update a variable in the styled.div. Should I pass through props instead? Should I move it in another way? Not too sure what to do here. Thanks in advance for any help!
import React, { useState } from "react";
import Editor from "./Editor";
import { monokai, solarizedDark, terminal, textmate } from "./ui/themes";
import styled from "styled-components";
const CodeContainer = ({ setHtml, setCss, setJs, setRenderDoc, theme }) => {
let currentTheme = monokai;
if (theme === "textmate") {
currentTheme = textmate;
} else if (theme === "solarized_dark") {
currentTheme = solarizedDark;
} else if (theme === "terminal") {
currentTheme = terminal;
}
return (
<Container background={currentTheme}>
<Editor
setHtml={setHtml}
setRenderDoc={setRenderDoc}
languageName="html"
theme={theme}
/>
<Editor
setCss={setCss}
setRenderDoc={setRenderDoc}
languageName="css"
theme={theme}
/>
<Editor
setJs={setJs}
setRenderDoc={setRenderDoc}
languageName="javascript"
theme={theme}
/>
</Container>
);
};
export default CodeContainer;
const Container = styled.div`
background: ${(currentTheme) => currentTheme.background};
height: 40vh;
border-bottom: 4px #211e1c solid;
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 15px;
`;
Use the following syntax. Docs.
const Container = styled.div((props) => ({
background: props.background,
height: "40vh",
borderBottom: "4px #211e1c solid",
//..
}));
Note: Make sure to use the camelCase syntax with CSS properties.

React button does not show up

I'm beginner on React, and trying to learn and improve, here i have a button which is needed to be clicked and after that should appear bunch of numbers like this 1:1 1:2 1:3, but here i seem to have a problem, my button does not appear, just numbers from URL appears, and i also have css to my button which is not working either when refreshing the page css works just for 1 second then disappear and im not getting any error message...
Here is the code:
import React, { Component } from 'react'
class Button extends Component {
componentWillMount() {
var proxyurl = "https://cors-anywhere.herokuapp.com/";
var url = "http://*****.******.com/numbers.txt";
fetch(proxyurl + url) // https://cors-anywhere.herokuapp.com/https://example.com
.then(response => response.text())
.then(contents => document.write(contents))
}
render() {
return (
<div className="whole">
<button onClick={this.componentWillMount} >Increment</button>
</div>
)
}
}
export default Button;
.whole {
background-color: blue;
color: red;
margin: 50px 0;
padding: 0px;
text-align: center;
}
#root {
white-space: pre;
}
english is not my mother language so sorry for mistakes.
componentWillMount is a lifecycle event of the component and shouldn't be used like this (also it is recommended that componentWillMount is no longer used).
If you want the button to retrieve data you need to create a new function and assign it to the onClick prop of the button. eg:
handleClick = () => {
var proxyurl = "https://cors-anywhere.herokuapp.com/";
// more code
.then(contents => this.setState({ responseText: contents }))
}
render() {
return (
<div className="whole">
<button onClick={this.handleClick}>Increment</button>
</div>
<div>{this.state.responseText}</div>
);
}

Combine multiple styled elements with styled-components

I know that we can extend or add styling to existing components with styled-components like the Link component of react-router-dom. The said feature is indicated here. But, my problem is, how can I combine two or more existing components then add some more styles?
In my case, I have a reusable component for text elements like span, p and a with standard font-size, font-weight, etc. At the same time, I want to use the react-router-dom's Link component. Currently, I have something like this:
import styled from 'styled-components';
import { Link } from 'react-router-dom';
import { TextElement } from '../common';
/*
Can I do something like this?
const MyLink = styled(Link, TextElement)`
margin: 10px 0;
`;
or this?
const MyLink = styled([Link, TextElement])`
margin: 10px 0;
`;
*/
const MyPage = props => (
<>
<MyLink to="/next-page" />
</>
);
Any suggestion would be appreciated.
EDIT
My TextElement component is just something like this:
const Element = styled.span`
font-size: 13px;
font-weight: 500;
`;
// These styles are sample only. Actual styles depend on a "variant" prop.
// I did not show it here since it doesn't have to do with the question I'm asking.
export default ({ tag }) => (<Element as={tag} />);
You can use mixin for this using css helper.
Let's say you put the code for TextElement in a spaced mixin like:
import { css } from 'styled-components';
const spaced = css`
margin: 10px 0;
`;
And another mixin for Link
const styledLink = css`
color: blue;
`;
Then you can define your MyLink as:
import styled from 'styled-components'
const MyLink = styled(Link)`
${spaced}
${styledLink}
`;
The style component could be the wrapper of your custom component. For example:
Your style component:
export const CustomSpanWrapper = styled.div`
span {
...your-styles
}
`;
Your other component:
<CustomSpanWrapper>
<CustomSpan>
</CustomSpanWrapper>

Categories