I tried using vue-styled-compoenents to style a simple button with some text inside but the styles dont work and I get a scopedSlots issue in the parent component.
This is the code for the button and the text components in component.js
import styled from 'vue-styled-components';
export const sLabel = styled.label`
color: #000;
`;
export const sButton = styled.div`
height: 1rem;
width: 2rem;
background-color: #000;
${sLabel} {
color: #fff;
}
`;
This is my code in my page.
<template>
<sButton>
<sLabel>Button</sLabel>
</sButton>
</template>
<script>
import { sButton, sLabel } from './component.js'
export default {
components: {
sButton,
sLabel
}
}
</script>
This is the result I get under the sButton styles and nothing under sLabel
), scopedSlots: this.$scopedSlots
But Instead if I just use this code it works.
export const sButton = styled.div`
height: 1rem;
width: 2rem;
background-color: #000;
label {
color: #fff;
}
`;
The styles are applied to the parent component if I declare the parent component before the child even if the styles are under the child.
export const sButton = styled.div`
height: 1rem;
width: 2rem;
background-color: #000;
${sLabel} {
color: #fff;
}
`;
export const sLabel = styled.label`
color: #000;
`;
Can someone tell me where my code is incorrect and what is causing these issues ?
Related
I am trying to create a floating label select component, So the select box will have a label on click of that it will show a dropdown options. Like this With an icon and override the native browser options.
I was able to achieve using input field, but i am not able to understand how to create such a like component.
Dropdown.js
import React from "react";
import {
DropdownWrapper,
StyledSelect,
StyledOption,
StyledLabel
} from "./style";
export function Dropdown(props) {
return (
<DropdownWrapper onChange={props.onChange}>
<StyledLabel htmlFor={props.id}>{props.formLabel}</StyledLabel>
<StyledSelect id={props.id} name={props.id}>
{props.children}
</StyledSelect>
</DropdownWrapper>
);
}
export function Option(props) {
return <StyledOption selected={props.selected}>{props.value}</StyledOption>;
}
Style.js
import styled from "#emotion/styled";
export const DropdownWrapper = styled.div`
display: flex;
flex-flow: column;
justify-content: flex-start;
`;
export const StyledSelect = styled.select`
height: 100%;
padding: 0.5rem 0;
margin-bottom: 1rem;
border: none;
border-bottom: 1px solid black;
outline: none;
-webkit-appearance: none;
-moz-appearance: none;
text-indent: 1px;
text-overflow: "";
`;
export const StyledOption = styled.option`
color: ${(props) => (props.selected ? "lightgrey" : "black")};
`;
export const StyledLabel = styled.label`
margin-bottom: 1rem;
`;
Any help appreciated, here is what i have tried so far. link
So, I am trying to add controls to my Storybook components. I am having trouble figuring out how to change the css styling. I've set up proptypes to help me handle the background color of the component, but I don't know how to bring that into my stories. Right now, my background color is nothing. I would like it to be a specific color to start. I am using React. I added my code below, any help is appreciated!
Style.js:
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { colors } from '../utilities';
export const StyledButton = styled.button`
color: ${colors.text500};
text-transform: uppercase;
width: 300px;
height: 50px;
font-size: 1.1em;
letter-spacing: 0.1em;
margin: 1em;
padding: 0.25em 1em;
border-radius: 5px;
border: none;
background: ${props => props.color};
`;
StyledButton.PropTypes = {
color: PropTypes.string.isRequired,
};
export default StyledButton;
Button.stories.js
import React from "react";
import Button from "./Button";
import { colors } from '../utilities';
export default {
title: "Button",
component: Button
};
export const Primary = (args) => <Button {...args} />;
Primary.args = {
label: 'Download',
color: '${colors.primary500}',
};
What is the best way to style the Link using the styled-components library in the code that follows.
I can find lots of examples to work with anchor tag but none to work with react-router link.
Am I going about the correct way.
import React from "react";
import { Link } from "react-router-dom";
import styled from "styled-components";
const Nav = ({ className }) => {
return (
<div className={className}>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
</div>
);
};
export default styled(Nav)`
color: white;
text-align: left;
background: teal;
width: 100%;
ul {
color: red;
display: flex;
flex-direction: row;
border: 1px solid green;
list-style: none;
li {
padding: 15px 15px;
border: 2px solid purple;
}
}
`;
Thanks
Joseph Shanahan
Yes thanks for your help. A slimmed down version of what I will implement is as follows.
It also has the advantage in that I did not have to implement an unordered list.
import React from "react";
import { Link } from "react-router-dom";
import styled from "styled-components";
const Nav = ({ className }) => {
return (
<div className={className}>
<NavLink to="/">Home</NavLink>
<NavLink to="/about">About</NavLink>
</div>
);
};
const NavLink = styled(Link)`
padding: 20px;
color: white;
text-decoration: none;
&:hover {
color: red;
background: blue;
}
`;
export default styled(Nav)`
color: white;
width: 100%;
display: flex;
justify-content: flex-end;
`;
Thanks Joseph Shanahan
You are in the right way, but little wrong, instead of using ul you just pass the component reference.
export default styled(Nav)`
color: white;
text-align: left;
background: teal;
width: 100%;
${Link} {
/* style for Link Component */
}
`;
Check this answer, it's very familiar.
react-router link translates to after all in <a> tags so style them in the same way you would style an <a> tag
so let's say, you need to change their color to red then:
ul {
color: red;
}
won't work, you will need to do:
ul a {
color: red;
}
If you just want to style the Link component, then the usual way in my experience is to create a styled component like so:
const NavLink = styled(Link)`
/* Link styles */
`
And then just render it like <NavLink>Home</NavLink>.
This also makes it easy to reuse this styled component.
I've been trying to find the solution to my problem.
I have several Heading Tags (H1, H2 etc) each in their own file.
I would like to add some css when calling them based on a prop. Some headings have a small border-bottom and some don't. So, in order to refractor my code, I want to add some css based on a prop. I can't seem to find a way.
Here's an example of Heading H2:
import styled from 'styled-components';
import colors from '../../../../colors';
import fonts from '../../../../fonts';
import fontWeights from '../../../../fontWeights';
const HeadingH2 = styled.h2`
color: ${colors.text};
font-family: ${fonts.montSerrat};
font-size: 1.6em;
font-weight: ${fontWeights.light};
letter-spacing: 0.2em;
padding-bottom: 0.7em;
position: relative;
text-transform: uppercase;
text-align: center;
&:after{
content: "";
display: block;
height: 3px;
width: 45px;
background-color: currentColor;
/* position */
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
}
`;
export default HeadingH2
Example of calling Heading H2:
import React from 'react';
import HeadingH2 from '../../common/headings/heading_h2';
import HeadingBaseline from '../../common/headings_baseline';
// Features
import {SectionContainer, FeaturesContainer} from './features.style';
import Feature from './feature';
import feature1 from '../../../img/features/feature1.png';
import feature2 from '../../../img/features/feature2.png';
import feature3 from '../../../img/features/feature3.png';
// Text
import Text from '../../../content';
const Features = () => {
return(
<SectionContainer id={"what"}>
<HeadingH2>
What We Do
</HeadingH2>
<HeadingBaseline>
{Text.headingBaseline}
</HeadingBaseline>
<FeaturesContainer>
<Feature
src={feature1}
headingText={Text.feature1.heading}
paragraph={Text.feature1.paragraph}
/>
<Feature
src={feature2}
headingText={Text.feature2.heading}
paragraph={Text.feature2.paragraph}
/>
<Feature
src={feature3}
headingText={Text.feature3.heading}
paragraph={Text.feature3.paragraph}
/>
</FeaturesContainer>
</SectionContainer>
)
};
export default Features;
I want to extract the following CSS properties
position: relative;
text-transform: uppercase;
text-align: center;
&:after{
content: "";
display: block;
height: 3px;
width: 45px;
background-color: currentColor;
/* position */
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
So, assuming I have the above CSS rule in a separate file, how do I add/import them using props on my styled component HeadingH2.
Thanks for the help :)
You can also use css helper from styled-components to create a SharedStyles.js file.
In the demo you can see it in action.
Just using it in a style of an inherited component is not working as expected. If I'm adding it to StyledBase then the variables are not correctly added afterwards (hover style override stops working).
That's why I copied ${borderBottom} to each styled component Heading1 / Heading2 instead of adding it to StyledBase.
I think having a level prop for the heading is a good idea but I would handle it differently by creating a HeadingBase component and add your styles to a StyledBase component (also see code in the demo).
The HeadingBase code looks like this:
const HeadingBase = ({ className, children, level = 1 }) =>
React.createElement(`h${level}`, { className }, children);
It's a component that renders h1,h2,... tags based on the prop level passed (defaults to h1). The h-tag receives className as props (needed for styled-components) and contains the children passed to the component.
SharedStyles.js
import { css } from "styled-components";
export const borderBottom = css`
&:after{
content: "";
display: block;
height: 3px;
width: 200px;
background-color: ${props => props.color || "black"};
/* position */
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
`;
Then you can import it with import { borderBottom } from "./SharedStyles"; and add it to your styled-component like following:
const Heading1= styled.h1`
${borderBottom}
`;
Something like this works:
const HeadingH2 = styled.h2`
position: ${props => props.relative && 'relative'};
padding: ${props => props.paddingBottom ? '0 0 20px 0' : '0'};
}
`;
Then use like this:
<HeadingH2 relative paddingBottom />
Possible answer:
I add the following CSS rules in a separate file like so.
I create a function which returns a string of text. I can import this function and add those rules to any component I wish.
export const borderBottom = () => {
return `
position: relative;
text-transform: uppercase;
text-align: center;
&:after{
content: "";
display: block;
height: 3px;
width: 45px;
background-color: currentColor;
/* position */
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
}
`
}
And use it like so on any heading or component that I wish:
import styled from 'styled-components';
import colors from '../../../../colors';
import fonts from '../../../../fonts';
import fontWeights from '../../../../fontWeights';
import {borderBottom} from '../../../../css';
const HeadingH5 = styled.h5`
color: ${colors.black};
font-family: ${fonts.montSerrat};
font-size: 1em;
font-weight: ${fontWeights.light};
letter-spacing: 0.1em;
padding-bottom: 0.45em;
margin-bottom: 25px;
${borderBottom}
`
;
export default HeadingH5;
This works for me. Any other suggestions are welcome.
You should definely check this: typestyle
the best way you can write dynamic css (for me). Works perfectly with react, even with ssr if you need it...
Why not just have a headingLevel prop? and then pass it into the styled component? And just have one StyledHeader styled component as I'm guessing the code is the mostly the same in all the heading styles files? Which is a big no no, you want to always try not to repeat your code.
const Features = () => {
return(
<SectionContainer id={"what"}>
<StyledHeader
headingLevel={headingLevel}
>
What We Do
</StyledHeader>
<HeadingBaseline>
{Text.headingBaseline}
</HeadingBaseline>
<FeaturesContainer>
<Feature
src={feature1}
headingText={Text.feature1.heading}
paragraph={Text.feature1.paragraph}
/>
<Feature
src={feature2}
headingText={Text.feature2.heading}
paragraph={Text.feature2.paragraph}
/>
<Feature
src={feature3}
headingText={Text.feature3.heading}
paragraph={Text.feature3.paragraph}
/>
</FeaturesContainer>
</SectionContainer>
)
};
export default Features;
And in your StyledHeader file
The below function will take your passed in heading level of h1, h2, h3 and will apply a border, if not the above 3 heading level it will be 0 value. I'd do some checks to ensure the value is lower case e.g. toLowerCase()
const getBorder = ({ headingLevel } ) => {
const headingLevelMap = {
h1: 0.7,
h2: 0.6,
h3: 0.6,
};
return headingLevelMap[headingLevel] || 0;
}
const HeadingH2 = styled.headingLevel`
color: ${colors.text};
font-family: ${fonts.montSerrat};
font-size: 1.6em;
font-weight: ${fontWeights.light};
letter-spacing: 0.2em;
padding-bottom: 0.7em;
border-bottom: ${getCorrectBorderBottom}em solid black
position: relative;
text-transform: uppercase;
text-align: center;
&:after{
content: "";
display: block;
height: 3px;
width: 45px;
background-color: currentColor;
/* position */
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
}
`;
I'd also check that if the value of the passed in headingLevel is not any of the 6 heading levels it should have a default value of whatever you want.
The above was just quick pseudo code, but hopefully get the general idea here? Let me know it comments if not.
I'd also recommend that you split your Title component out into a separate component.
I am beginner to ReactJS, Currently I am using styled-component for style some module. Actually I created 2 files in one folder. One is style.js where I am making 2,3 object and now I want to export these 3 object to my another file which name is 2nd.js but it not working for me Could you please help me How I can import style.js object to my file .
Style.js Code
import styled from 'styled-components';
export const SubText = styled.div`
font-size: 20px;
text-align: center;
padding-bottom: 30px;
width: 330px;
color: #012653;
margin: 0 auto;
font-weight: 440;
`;
export const GeneralText = styled.div`
color: red;
font-size: 26px;
font-weight: 600;
text-align: center;
min-width: 266px;
padding-bottom: 30px;
font-family: Lato, sans-serif;
margin-top: 50px;
color: #012653;
`;
export const ButtonWrapper = styled.div`
text-align: center;
margin-top: 26px;
`;
2nd.js Code
import Style from './Style';
<GeneralText>This is dummy text </GeneralText>
You can do this by:-
import {SubText, GeneralText, ButtonWrapper} from './style'
Actually,there are many ways to solve this:
import * as Style from './style'
Or the above answers says:
import {SubText, GeneralText, ButtonWrapper} from './style'