linaria
linaria copied to clipboard
(atomic): string serialization for atomic styles produced
Describe the enhancement
Currently, atomic styles produces an object in the resulting code like this:
const atoms = css`
background: red;
width: 100%;
`;
// gets compiled to
const atoms = {
background: 'atm_foo',
width: 'atm_bar',
}
I would propose to change it to this:
const atoms = css`
background: red;
width: 100%;
`;
// gets compiled to
const atoms = 'atm_hash1-foo atm_hash2-bar';
Where hash1
is a hash of background
and hash2
is a hash of width
.
cx
can then be modified to do something like this:
const KEY_VALUE_SEPARATOR = '-';
const cx = function cx() {
const presentClassNames = Array.prototype.slice
.call(arguments)
.filter(Boolean);
// `cx` is passed all strings with encoded key:value, we need to dedupe
const map = {};
for (let str of presentClassNames) {
// className could be the output of a previous cx call, so split by ' ' first
const individualClassNames = str.split(' ')
for (let className of individualClassNames) {
const [key, value] = className.split(KEY_VALUE_SEPARATOR);
map[key] = `${key + KEY_VALUE_SEPARATOR + value}`;
}
}
return Object.values(map);
};
Motivation
The issue we have today is people using cx
multiple times, and not getting correct merging behavior. Generally this happens because people merge styles before passing them around. The issue is that effectively,
cx(a, cx(b, c)) !== cx(a, b, c)
Possible implementations
From benchmark testing, doing string manipulation isn't much worse than merging objects. However, if anyone felt strongly about it, we could:
- Provide an option to choose between the two representations
- Provide a different
cx
util
I don't think that extra complexity is needed though, so I'd recommend not adding that complexity
Related Issues
Is this issue already fixed and can be closed?