score:0
when dealing with styled component variants here is what i like to do to keep things organised and scalable.
if the variants are stored within the same file i am using the inheritance properties:
const defaultbutton = styled.button`
color: ${(props) => props.theme.primary};
`;
const buttonflashy = styled(defaultbutton)`
color: fuchsia;
`;
const buttondisabled = styled(defaultbutton)`
color: ${(props) => props.theme.grey};
`;
if if we are talking about a reusable components i would use this technique:
import styled from 'styled-components';
// note that having a default class is important
const styledcta = ({ classname = 'default', children }) => {
return <wrapper classname={classname}>{children}</wrapper>;
};
/*
* default button styles
*/
const wrapper = styled.button`
color: #000;
`;
/*
* custom button variant 1
*/
export const styledctafushia = styled(styledcta)`
&& {
color: fuchsia;
}
`;
/*
* custom button variant 2
*/
export const styledctadisabled = styled(styledcta)`
&& {
color: ${(props) => props.theme.colors.grey.light};
}
`;
export default styledcta;
usage:
import styledcta, { styledctadisabled, styledctafushia } from 'components/styledcta';
const page = () => {
return (
<>
<styledcta>default cta</styledcta>
<styledctadisabled>disable cta</styledctadisabled>
<styledctafushia>fuchsia cta</styledctafushia>
</>
)
};
read more about this in the blog posts i created on the subject here and there.
score:0
there are many ways to do this. one simple way is to use the package called styled-components-modifiers. documentation is simple and straightforward.
https://www.npmjs.com/package/styled-components-modifiers
simple usage example:
import { applystylemodifiers } from 'styled-components-modifiers';
export const text_modifiers = {
success: () => `
color: #118d4e;
`,
warning: () => `
color: #dbc72a;
`,
error: () => `
color: #db2a30;
`,
};
export const heading = styled.h2`
color: #28293d;
font-weight: 600;
${applystylemodifiers(text_modifiers)};
`;
in the component - import heading and use modifier prop to select the variants.
<heading modifiers='success'>
hello buddy!!
</heading>
score:0
styled components are usually used with styled system that supports variants and other nice features that enhance styled components. in the example below button prop variant automatically is mapped to keys of variants object:
const buttonvariant = ({ theme }) =>
variant({
variants: {
header: {
backgroundcolor: theme.colors.lightblue,
color: theme.colors.white,
active: theme.colors.blue,
},
white: {
backgroundcolor: 'white',
color: theme.colors.lightblue,
active: theme.colors.blue,
},
},
})
const button = styled.button`
${(props) => buttonvariant(props)}
`
styled system variants: https://styled-system.com/variants
score:0
use the variant api to apply styles to a component based on a single prop. this can be a handy way to support slight stylistic variations in button or typography components.
import the variant function and pass variant style objects in your component definition. when defining variants inline, you can use styled system like syntax to pick up values from your theme.
// example button with variants
import styled from 'styled-components'
import { variant } from 'styled-system'
const button = styled('button')(
{
appearance: 'none',
fontfamily: 'inherit',
},
variant({
variants: {
primary: {
color: 'white',
bg: 'primary',
},
secondary: {
color: 'white',
bg: 'secondary',
},
}
})
)
score:2
this is just my opinion:
i don't think we can do anything very different from what you did.
a different way that i thought, would be to create an options object to map the possibilities of the variant, like this:
const variantoptions = {
header: {
backgroundcolor: theme.colors.lightblue,
color: theme.colors.white,
active: theme.colors.blue,
},
white: {
backgroundcolor: "white",
color: theme.colors.lightblue,
active: theme.colors.blue,
},
};
and use it in your style component like this:
const buttonstyle = styled.button`
padding: 8px 20px;
border: none;
outline: none;
font-weight: ${(props) => props.theme.font.headerfontweight};
font-size: ${(props) => props.theme.font.headerfontsize};
display: block;
&:hover {
cursor: pointer;
}
${({ variant }) =>
variant &&
variantoptions[variant] &&
css`
background-color: ${variantoptions[variant].backgroundcolor};
color: ${variantoptions[variant].color};
&:active {
color: ${variantoptions[variant].active};
}
`}
`;
and all of this buttons will work:
<buttonstyle variant="*wrong*">button</buttonstyle>
<buttonstyle variant="header">button</buttonstyle>
<buttonstyle variant="white">button</buttonstyle>
<buttonstyle>button</buttonstyle>
score:3
inspired by previous solutions, i want to share what i came up with:
import styled, { css, defaulttheme } from 'styled-components';
const variantstyles = (theme: defaulttheme, variant = 'primary') =>
({
primary: css`
color: ${theme.colors.light};
background: ${theme.colors.primary};
border: 1px solid ${theme.colors.primary};
`,
}[variant]);
const button = styled.button<{ variant: string }>`
padding: 1rem;
font-size: 0.875rem;
transition: all 0.3s;
cursor: pointer;
${({ theme, variant }) => variantstyles(theme, variant)}
&:active {
transform: translatey(1.5px);
}
`;
export default button;
for now it contains only primary and its the default one, by you can add more variants by adding new object to variantstyles
object
then you can use it by passing the variant as a prop or keep the default by not passing any variant.
import { button } from './herosection.styles';
<button variant="primary">start learning</button>
Source: stackoverflow.com
Related Query
- Approach to creating variants with styled components
- Warning: Prop `className` did not match. when using styled components with semantic-ui-react
- Using styled components with Typescript, prop does not exist?
- Can't get Jest to work with Styled Components which contain theming
- Style a Slider Thumb with Styled Components
- Using styled components "as" prop with typescript
- styled components :hover with react-native and react-native-web
- Overriding react components styles with styled component
- Target specific CSS classes with Styled Components
- Styling Material-UI Drawer component with Styled Components
- Media queries not working with styled components in React App
- Jest with styled components themeProvider
- Share the same styles between two types of component with React Styled Components
- using react tooltip with styled components
- Warning: Prop `className` did not match in Next.JS site with Styled Components
- Warning with function components cannot be given refs - even though using forwardRef() with Styled Components
- How to work with styled components in my react app?
- How to use custom props and theme with material-ui styled components API (Typescript)?
- Jest/Enzyme with styled components
- Converting css with nested classes to styled components problem
- Import fonts to react project with webpack and styled components
- Can't import Google Fonts with Styled Components and Next.js
- Using Typescript with Styled Components and Material UI
- create-react-library not working with styled components
- Creating custom variants with Material-UI
- Testing styled components with react-testing-library
- Styled Components - two different elements with the same styles
- Child Components have no props.theme for Styled Components with React Router
- Style Link with styled components
- Using memoized callbacks in React, when also creating multiple components with .map
More Query from same tag
- Which way to use to replace a complete object with useState()?
- chrome devtools debug react, hit "refresh" cause debug stuck
- How to get rid of border and add background color to MUI TextField variant outlined
- using google fonts in nextjs with sass, css and semantic ui react
- setState to window variable once on componentDidUpdate
- populate array variable from json url without promise
- Flow type Generic types
- Reactjs - How to make components aware of the current view state?
- One Instance of useState() Overriding the Other in React App
- Error in CSS font loader when using webpack 2.2.0
- Private Route React Router And Redux
- How to convert File into Tensor in JavaScript
- Why isn't the state being passed down to child here (TypeScript/React/SPFX)
- Open a table on click of the another td in react js
- Typescript and React: Type 'Element' is not assignable to type 'FunctionComponent<{}>'
- Pass child state value to Parent state array
- Type '(isOpen: boolean) => void' is not assignable to type 'boolean'. Error when using Modal in reactjs
- How to prevent my Page render when I click on the button
- How to link an image to a page dynamically with React Router Dom?
- Arrow function not working in react class component
- React - Cannot read property 'state' of undefined
- fetching data from graphql to react
- Generate element from submit React.js
- Graphql query returning null for relational document, field missing from query but present in primsa admin
- Is it possible to pass variables (props/states) to an already-created React instance
- localStorage is saving my data but after refresh is reseting and empty it
- Checking parameter types in Typescript
- Borrowing a JSDoc comment from external interface property
- React-Redux, cannot set a value to an empty string
- Adding html class in react dynamically using function?