Hi there, is the below Styled System syntax supported in Theme UI? It doesn't appear to be working when using the pragma like this: (none of the styles are being applied at all)
<div
sx={{
bg: { _: "green", sm: "red", md: "blue" },
}} >
Thanks!
https://github.com/styled-system/styled-system/blob/master/docs/responsive-styles.md#using-objects
Alternatively, is there a way to just call breakpoints on the fly?
My use case is that 99% of my layout simply uses 3 breakpoints, but things like the header navigation requires about 6.
Something like this would be a huge de-cluttering for my particular project :)
<nav
sx={{
bg: { 0: "green", 300: "red", 600: "blue", 1100 "yellow" },
}} >
Theme UI and @styled-system/css only support responsive array values. If you prefer using plain objects, use the standard media query syntax, e.g. '@media (min-width:40em)': {}
Hi @jxnblk.
Can you please explain why you only support responsive array values for breakpoints?
I feel like having an object map to min-widths is more resilient if we wanted to add _new_ breakpoints as well as being more declarative in the code.
I am also having the same issue, when adding new breakpoints. It's more resilient to break things
If you want to extra breakpoints in your SX objects, without writing a lot of boiler plate, you can utilize ES6 tag functions.
const bp = x => `@media (min-width:${x})`
Now when you're trying to make a custom breakpoint you can simply write
<SomeComponent sx={{
bp`600px`: {
width: "100px";
},
... otherStyles
}}/>
@jxnblk We're using theme-ui in our shared component library in our organisation and we really appreciate the { _: '12px', xl: '16px' } object style when using styled-system props. We get quite a few questions from devs regarding why this syntax doesn't exist with the sx prop.
It's a really nice syntax, as if you add/remove/change breakpoints, you don't need to update any arrays. It's also a lot more concise to code. We'd love to see it added :)
I came up with this helper function for parsing objects that have responsive breakpoints and converting them to an array.
You will probably need to play with it a bit to fit your setup, but it's been working great.
import theme from 'path/to/theme.js'
export const parseResponsiveObjects = obj => {
if (!obj) return obj
const breakpointKeys = [
'_',
...Object.keys(theme.breakpoints).filter(key => isNaN(parseInt(key))),
]
// Found object that needs updated
if (Object.keys(obj).filter(x => breakpointKeys.includes(x)).length > 0) {
return breakpointKeys.map(bp => obj[bp] || null)
} else {
// Iterate over the properties
for (var propertyName in obj) {
// Any object that is not a simple value
if (
obj[propertyName] !== null &&
typeof obj[propertyName] === 'object'
) {
// Recurse into the object and write back the result to the object
obj[propertyName] = parseResponsiveObjects(obj[propertyName])
}
}
}
return obj
}
We have it built into our components, so objects get parsed automatically, but you could use it something like this:
import { parseResponsiveObjects as pro } from 'path/to/helper/file'
<Box
sx={pro({
':hover': {
boxShadow: {
_: '0 0 0 5px lightgray',
sm: '0 0 0 5px gray',
lg: '0 0 0 5px black',
},
},
})}
/>
I created a custom helper function:
export const responsive = <T = number | string>(
breakpoints: {
[key in "xs" | "sm" | "md" | "lg"]?: T;
}
): (T | null)[] => {
return [
breakpoints.xs ?? null,
breakpoints.sm ?? null,
breakpoints.md ?? null,
breakpoints.lg ?? null,
];
};
which can be used in sx. For example:
sx={{
width: responsive({ xs: "40px", lg: "100%" }),
}}
I share the sentiment with others @jxnblk. While breakpoints array makes for a concise definition and usage, any refactoring can quickly get out of hand when these values shift by 1. I am not sure what the syntax would look like, but I'd personally find it better to explicitly define the array, e.g. [query.sm, query.md, query.lg].
I also find it very hard to read/maintain the array syntax [xx, yy, zz] - always have to go back to the theme and verify what were the responsive breakpoints values.
Most helpful comment
@jxnblk We're using
theme-uiin our shared component library in our organisation and we really appreciate the{ _: '12px', xl: '16px' }object style when using styled-system props. We get quite a few questions from devs regarding why this syntax doesn't exist with thesxprop.It's a really nice syntax, as if you add/remove/change breakpoints, you don't need to update any arrays. It's also a lot more concise to code. We'd love to see it added :)