atom
atom copied to clipboard
WIP: add automated lit integration
Just a PR containing the stuff that was in #2
Implementing an "auto" version of the lit integration which tracks atoms and observes the right ones automatically.
Usage:
export class MyElement extends AtomLitElement {
render() {
return html`
<button @click="${() => setCount(old => old - 1)}">-</button>
<span>${count.getState()}</span>
<button @click="${() => setCount(old => old + 1)}">+</button>
`;
}
}
Couple of thoughts:
- Can it be typescript? pretty please 😆
- I named it
AtomLitElement
to follow the same convention lit-mobx and a few others did (*LitElement
) - we should align the two integrations some way (name them similar or combine them into one configurable integration)
- a formatter like prettier or clang might be nice
- i tried to add tests but wtr doesn't work on chromeos so i have no clue if they fail
Something I was thinking the other night: Would it maybe be easier to 'patch' the html
tagged template literal instead of hacking into the atoms.get
?
e.g.:
// very very pseudocode
import { html as lithtml } from 'lit-html';
const isAtomOrSelector = (value) => /* implement logic to see if a value is an atom or selector */ true;
const html = (strings, ...values) => {
values.forEach((value) => {
if(isAtomOrSelector(value)) {
// subscribe it to the class somehow?
}
});
// call 'original' html
return lithtml(strings, values);
}
I think the auto-detection is really nice, but I cant help but feel like we could improve the developer ergonomics a bit. Do you know how lit-mobx handles this? Also selectors
dont have a getState
method, so that wont actually work for selectors 😔
I named it AtomLitElement to follow the same convention lit-mobx and a few others did (*LitElement) we should align the two integrations some way (name them similar or combine them into one configurable integration)
Yeah agree, I think for now we can try to finetune both implementations and then just see which one we/users like best
a formatter like prettier or clang might be nice
Yep, agree, will get to that at some point™️
i tried to add tests but wtr doesn't work on chromeos so i have no clue if they fail
np 👍
i see what you mean but i think you'd be getting into some really messy territory by doing that. as you'd require consumers to use your html
rather than lit's, which isn't a normal thing to do. whereas this way, the consumer needs no extra code other than what they access and we do the heavy lifting.
also, a selector must ultimately drill down to an atom, right? its a computed value from what i could gather, which means it should still result in an atom (or many atoms) being accessed? maybe i just misunderstood
Yeah, a selector is always dependent on an atom, but the actual return value of the selector()
function doesnt return that selectors value, its just an object with a key, like:
const doubleCount = selector({
key: 'doubleCount',
get: /* etc */ () => {},
});
doubleCount; // {key: 'doubleCount'}
maybe a selector should instead match the interface atom() returns?
like {key, getState}
so it is interacted with just the same way. would make it more consistent that way imo