Closed quarkus closed 1 year ago
I really like the idea of reactive controllers that lit added in v2. https://lit.dev/docs/composition/controllers/
As far as I understand it they are also supposed to work cross framework: https://github.com/lit/lit/issues/1682
I think it is a really neat solution to composing UI classes/elements. Would this maybe make sense for us to try to make this pattern work for element-js as well?
That looks cool, but i think it would be quite a change if we'd introduce these... I mean we could replace the entire event map with these kind of controllers.
For now i had sth like this in mind:
events() {
return {
window : {
'media(max-width: 600px)': () => {
//did change
}
}
}
}
Thats way simpler but and would play nicely with what we have right now. But it has the downside that you can't compare an initial "matches" or access the mq instance ...
No I was just thinking if this controllers thing could be something that we would like for element-js in general as well 👍
But yeah - for this specific feature we can think of something for now.
How about something like this?
isMobile = window.matchMedia('(max-width: 600px)');
connected() {
console.log('connected', this.isMobile.matches);
}
events() {
return {
'media:isMobile': {
'change': (e) => {
console.log('change', e);
}
}
}
}
Where element-js would know if the "selector" starts with "media:" it will look for the property on the instance and add the listener.
We could also provide a matchMediaQuery helper:
import { BaseElement, matchMediaQuery } from '@webtides/element-js';
class ExampleElement extends BaseElement {
isMobile = matchMediaQuery('(max-width: 600px)', (e) => {
console.log('change', e);
});
connected() {
console.log('connected', this.isMobile.matches);
}
}
Or we could do something like the controller pattern and call the lifecycle implicitly:
import { TemplateElement, matchMediaQuery } from '@webtides/element-js';
class ExampleElement extends TemplateElement {
isMobile = matchMediaQuery(this, '(max-width: 600px)');
connected() {
console.log('connected', this.isMobile.matches);
}
template() {
return html`<div>${this.isMobile.matches ? 'is mobile' : 'is not mobile'}</div>`;
}
}
In this case the helper function would add the listener behind the scenes and call the "requestUpdate" method on the element.
I like the idea, but i don't like putting it inside the event map, or at least not on the window. That could be confusing as they are not really these classic events.
window already is a special key, maybe we can put media
as another special key?
events() {
return {
'media': {
'(min-width: 300px)': (matcher) => { },
}
}
}
Or another map:
media() {
return {
'(min-width: 300px)': (matcher) => { },
};
}
@eddyloewen For now i think i would like to stay in the element-js
pattern and not introduce a whole new concept of doing things. But for the future this controller pattern seem to be worth a shot. 👍
How would we handle the initial state?
MediaStore Example is now in docs: https://github.com/webtides/element-js/commit/5718c085813b6a51d12a13e93edba8e42e87a09c
come up with a solution to listen to media changes in JS
i.e.