-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding Component Attribute into Styled Components #29492
Comments
You can directly pass the available props in the host component (Grid) to the styled component. const ComponentStyled = styled(Grid)`
background-color: red;
`
<ComponentStyled item md={2}>
{* Content *}
</ComponentStyled> I hope this answer your question, feel free to close this issue if that works for you. |
Yeah @siriwatknp. He can use the const StyledGrid = styled(Grid).attrs({
item: true,
md: 2,
})`
background-color: red;
`
<StyledGrid /> |
|
|
I don't see a big value of adding this API. @emotion doesn't support it - emotion-js/emotion#821 It can be easily added in userland, for example - emotion-js/emotion#821 (comment) |
I had a similar issue with setting props on Virtuoso from https://virtuoso.dev/ Let's say I want to make a Virtuoso component that behaves in a certain way by default, and have an internal API, that's not possible without a similar api like const StyledVirtuoso = styled(Virtuoso)((({ theme }) => ({
listStyle: 'none',
padding: 0,
minHeight: '200px',
[theme.breakpoints.up('md')]: {
width: '50vw',
height: 'calc(100vh - 64px)',
margin: 0,
},
}))); <StyledVirtuoso
style={{ // override Virtuoso default values and set them with class
height: 'undefined',
overflowY: window.innerWidth < 900 ? 'visible' : 'auto',
}}
totalCount={items.length}
itemContent={(index:number) => (
<ItemRow
item={item[index]}
/>
)}
useWindowScroll={window.innerWidth < 900}
overscan={window.innerHeight * 0.5}
/> What I want: const StyledVirtuoso = styled(Virtuoso)((({ theme }) => ({
listStyle: 'none',
padding: 0,
minHeight: '200px',
[theme.breakpoints.up('md')]: {
width: '50vw',
height: 'calc(100vh - 64px)',
margin: 0,
},
})))
.attr({
style: { // override Virtuoso default values and set them with class
height: 'undefined',
overflowY: window.innerWidth < 900 ? 'visible' : 'auto',
},
useWindowScroll: window.innerWidth < 900,
overscan: window.innerHeight * 0.5
})
; <StyledVirtuoso
totalCount={items.length}
itemContent={(index:number) => (
<ItemRow
item={item[index]}
/>
)}
/> |
You can do that with different API, for example: const withAttrs = (Component, attrs) => props => <Component {...attrs} {...props}/>;
const BasicStyledVirtuoso = styled(Virtuoso)((({ theme }) => ({
listStyle: 'none',
padding: 0,
minHeight: '200px',
[theme.breakpoints.up('md')]: {
width: '50vw',
height: 'calc(100vh - 64px)',
margin: 0,
},
})));
const StyledVirtuoso = withAttrs(BasicStyledVirtuoso, {
style: { // override Virtuoso default values and set them with class
height: 'undefined',
overflowY: window.innerWidth < 900 ? 'visible' : 'auto',
},
useWindowScroll: window.innerWidth < 900,
overscan: window.innerHeight * 0.5
});
// And then use it
<StyledVirtuoso
totalCount={items.length}
itemContent={(index:number) => (
<ItemRow
item={item[index]}
/>
)}
/> |
For those of us that do "see a big value of adding this API" and like to keep decorative props with the rest of the styles where they belong: import React from "react"
import { styled as muiStyled } from "@mui/material/styles"
const styled = (StyledComponent, ...args) => {
const Component = muiStyled(StyledComponent, ...args)
Component.attrs = (defaultProps) =>
muiStyled(
React.memo((props) => <StyledComponent {...defaultProps(props)} {...props} />),
...args
)
return Component
}
export * from "@mui/material/styles"
export default styled |
Nice. Where should this file sit? |
While working on my side project I've realized I'm not mixing the theme in the props passed to import React from "react"
import { styled as muiStyled, useTheme } from "@mui/material/styles"
const styled = (StyledComponent, ...args) => {
const Component = muiStyled(StyledComponent, ...args)
Component.attrs = (defaultProps) =>
muiStyled(
React.memo((props) => {
const theme = useTheme()
return <StyledComponent {...defaultProps({ theme, ...props })} {...props} />
}),
...args
)
return Component
}
export * from "@mui/material/styles"
export default styled |
I am currently using a solution from the Storybook team to use an alternative to This also works very well: export const Paragraph = styled((props: Omit<React.ComponentProps<typeof Typography>, "variant">) => (
<Typography variant="body1" {...props} />
))`
margin: 12px 0;
padding-right: 24px;
`; But if I use the const Header = styled(
(props: Omit<React.ComponentProps<typeof ListSubheader>, "component" | "disableGutters" | "disableSticky'">) => (
<ListSubheader component="div" disableGutters disableSticky {...props} />
),
)`
line-height: 1em;
color: black;
`; The only solution at the moment is not to use typing, but I would like to avoid that: const Header = styled(
(props) => <ListSubheader component="div" disableGutters disableSticky {...props} />
)`
line-height: 1em;
color: black;
`; Does anyone here have an idea for a solution? |
Before, i use styling with styledlike this
component used as
but how if i want to styling from this form
in to styled version with passed md value or 'item' attribute?
The text was updated successfully, but these errors were encountered: