glamor
glamor copied to clipboard
Respect array/arguments order of css()
New issue from https://github.com/threepointone/glamor/issues/226#issuecomment-318631505
An array or multiple arguments can passed to the css()
function but that order is not respected when the css is generated. The style objects are just merged into a one object which is then used to generate the css. This makes the style ordering bit random when existing style keys are being overridden.
Example: https://codesandbox.io/s/qjG2XvykR
In real world code I've hit this with glamorous when I have wanted to extend a component and change it's media query behaviour.
Example: https://codesandbox.io/s/VPAvP6mGO
Fixing this would also make the infamous shorthand properties less brittle when extending components in glamorous. Ie. this would work as expected https://codesandbox.io/s/jzgxvZov
It think it comes down to the fact that when a key is being overridden in an object it's position stays the same.
For example here foo
is the first key even thou it's the last one set.
> Object.keys(Object.assign({foo: 1}, {bar: 2}, {foo: 3}))
[ 'foo', 'bar' ]
Deleting existing properties before assignment might solve the problem.
function preserveOrder(...styles) {
return styles.reduce((acc, style) => {
Object.entries(style).forEach(([prop, val]) => {
if (prop in acc) { delete acc[prop] }
acc[prop] = val
})
return acc
}, {})
}
const mergedStyles = preserveOrder({foo: 1}, {bar: 2}, {foo: 3})
Object.keys(mergedStyles) // => [ 'bar', 'foo' ]