Open anzorb opened 4 years ago
The reason this doesn't work is because styled system interpolates both the declaration name and the value. With linaria, you should only interpolate the value.
Styled System adds a lot of complexity to your components. If that is something that you want, you are better off pairing it with emotion, where everything is handled at runtime.
@brandonkal genuinely wondering how hard would it be to implement support for it in Linaria. I've been toying with this idea for quite some time and wondering if Linaria could be extended to support it. Since styled-system has a spec, I guess that change could only accommodate the spec?
@okonet The Styled System approach encourages all properties to be interpolated at which point the benefits of something like linaria start to become less attractive. If you manage to get it working, I'll accept a PR on my fork.
So the idea I had in mind was to get the permutations of all tokens from the theme since it's a finite number so I think it should work as long as it's just styled-system props without some custom interpolations, right?
Supporting this in linaria would be tricky. It would end up with support for runtime assigned styles since we cannot statically generate the output for each possible value of props. It's somehow related to #409, #234 and #244
@jayu
Would it be possible to support the responsive props however?
in the example from your readme:
import { styled } from 'linaria/react';
import { families, sizes } from './fonts';
// Write your styles in `styled` tag
const Title = styled.h1`
font-family: ${families.serif};
`;
const Container = styled.div`
font-size: ${sizes.medium}px;
color: ${props => props.color};
border: 1px solid red;
&:hover {
border-color: blue;
}
${Title} {
margin-bottom: 24px;
}
`;
// Then use the resulting component
<Container color="#333">
<Title>Hello world</Title>
</Container>;
It is explained that behind the scenes color is handled as a CSS variable. If breakpoints were declared in some manner for linaria, would it be possible to support something like this:
const Container = styled.div`
padding: ${props => props.padding};
`;
<Container padding={[ '4px', '10px' ]}>
<Title>Hello world</Title>
</Container>;
which still relies on CSS variables behind the scenes?
I think something effectively similar to styled-system could be built on linaria, but styled-system (whether using styled-components or emotion) depends on passing the theme via React Context, so that the style-prop functions have access to it. To do this in linaria would require fundamentally retooling the way the style-prop functions are generated AFAIK
@lunelson Yea, the theme system would require context like you said, but supporting the responsive props themeless seems theoretically possible no?
I think the one implicit "themeing" required would be the breakpoints. This could be declared globally in some manner for linaria, but it could also instead be handled by deviating from the shorthand and requiring the breakpoints to be included
<Container padding={{ '767px': '4px', '1023px': '10px' }} />
In either case, behind the scenes a css var could be used normally with the css var itself being changed for the different screen sizes.
@mauleb yes but you could also make your theme available in a different way, if you generated the style prop functions within the same closure where you process the theme, and returned them together. But this is of course rebuilding styled-system
in a different way
function setupTheme(userTheme) {
const baseTheme = {
breakpoints: {
s: 20,
m: 40,
l: 60,
}
}
const theme = _.mergeDeep({}, userTheme, baseTheme);
return {
theme,
padding(arg) {
/* set padding based on arg relative to theme.breakpoints */
}
}
}
const { theme, padding } = setupTheme({});
const Box = styled.div`
${props => props.p && padding(props.p)}
`;
styled-system provides a future direction for react components api design,
because it allows developers to pass styling property and value directly to the Component instead of passing traditional css properties inline to Component via style
object.
I think it's on the right way to standardize components api, because google flutter ui widgets and apple swiftui view is providing their ui apis this way.
I really want linaria to support styled-system like api for react components, if it's difficult to integrate with styled-system directly.
One more thing, styled-system is based on a predefined theme object with finite and similar number of props according to theme specification, just like
// simple theme.js
export default {
colors: {
black: '#000e1a',
white: '#fff',
blue: '#007ce0',
navy: '#004175',
},
}
// complex theme.js
export const bulmaTheme = {
colors,
fonts,
fontSizes,
fontWeights,
space,
styles,
}
some examples for theme.js: styled-system site theme.js, theme-ui bulma theme.js.
I have used styled-components and styled-system, but I'm unfamiliar with the source code.
Again, I really want u to integrate styled-system with linaria, or reimplement a styled-system like api for linaria.
reimplement a styled-system like api for linaria.
@uptonking what are your requirements for such a system? We've been theming with Linaria at my company using CSS custom props. It looks like everything in https://github.com/styled-system/styled-system/blob/master/docs/src/gatsby-plugin-theme-ui/index.js could be defined that way. Perhaps with some sugar for namespaces. (E.g. flattening nested JSON props like JSON {styles {h5: {a { textDecoration: 'none'
--> prop --styles.h5.a.textDecoration: 'none'
)
@turadg
The current react component api and usage built with linaria is like this:
const Container = styled.div`
font-size: ${sizes.medium}px;
color: ${props => props.color};
border: 1px solid red;
`;
// Then use the resulting component
// here color can only be valid css values
<Container color="#333"></Container>;
But I want the api and usage like this:
// ${space}, such style functions may be reimplemented in linaria-core or linaria-extension
// here is just copied from styled-system, but can be implemented in some other form
const Container = styled.div`
border: 1px solid red;
${color}
${space}
${layout}
`
// Then use the component
// here we can directly pick values from colors props in theme.js, even use alias
<Container color="primary" p="10px"></Container>;
// this structure is similar to flutter/swiftui api:
React.createElement(
Container,
{color: 'blue', padding: '10px'},
children:{
//...
}
)
I think it's on the way to standardize components api. It saves my repeated work to define the Color
,Padding
type for ContainerType
again and again.
Of course I can write many props.styles.h5.a.textDecoration
to pick values, but it's boring and repeated.
I hope linaria can handle the repeated work for me, just like styled-components+styled-system, but styled-components has runtime cost.
I really want linaria to take in these two benefits.
I see that you want to indicate a color by name instead of by literal. Would this work for you?
const Container = styled.div`
font-size: ${sizes.medium}px;
color: var(--color-${props => props.colorName});
border: 1px solid red;
`;
<Container colorName="primary" p="10px"></Container>;
Then instead of storing your colors in themes.js
you'd just have to define a CSS custom property, --color-primary
. (I'm not sure the above works but I'm exploring what might.)
I'm trying to achieve a similar API of styled-system, the responsive props, and especially the <Box/>
primitive component.
I know the build time libs like linaria or treat are not in the same league of run time ones.
Concerning treat, the people who develop it also developed a design system using treat (who is similar to linaria) and it has responsive props, Box, etc..
I found in the source code several files related to styled props, Box and so, but I admit, I get lost in the typescript thing :S
Could we get some cues from that? Is treat so different than linaria and we don't have anything to do?
Box: https://github.com/seek-oss/braid-design-system/tree/master/lib/components/Box
Utils for responsive props: https://github.com/seek-oss/braid-design-system/tree/master/lib/utils
Describe the feature
https://github.com/styled-system/styled-system
Styled System is getting a lot of attention, and currently works with Emotion and Styled Components. Something to keep in mind for future dev.
This currently results in
--c155nh7h-0: [object Object];
on the element (I am guessing ${space} isn't being executed as a function, like it does in Emotion/SC