[whatwg/dom] matchMedia-like API for element matches (Issue #1225)

It would be useful to receive an event when an element's `matches(selector)` changes, similar to how you can do so with `matchMedia`.

The ability to reactively change styles based on selector changes in CSS is a powerful feature we do not have in the DOM. Instead to achieve similar reactivity we need to account for the variety of ways in which state may change that includes things like:

- User events
- Network events (fetch(), web sockets, SSE)
- Cross-frame / cross-window `message` events

And probably a lot more.

## Use-case

You want to mark a submit button as disabled when the form is invalid. You might naively write this code:

```js
const form = document.querySelector('form');
const submit = document.querySelector('input[type=submit]');

submit.disabled = form.matches(':invalid');

const checkValid = () => {
  submit.disabled = form.matches(':invalid');
};

form.addEventListener('input', checkValid);
```

This works pretty well, but if the requirements change and say you do something like:

- Clear an input if server-side validation fails via an asynchronous fetch request.
- Clear an input if the form times out (5 minute timeout).

These things will not trigger an `input` so the submit button might be incorrectly enabled. Here's an example codepen that demonstrates this problem: https://codepen.io/matthewp/pen/MWZpBYd

## Proposal 1

This is inspired by `matchMedia`, Element.prototype.match:

```js
const query = form.match(':invalid');

submit.disabled = query.matches;
query.addEventListener('change', () => {
  submit.disabled = query.matches;
});
```

## Proposal 2

I prefer proposal 1, but there might be issues with it and I'm not sure if this style API is still in style. I defer to the experts here. My second proposal would follow the observer pattern:

```js
const observer = new QueryObserver((entries) => {
  form.disabled = entries.at(-1).matches;
});

observer.observe(form, ':invalid');
```

-- 
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/dom/issues/1225
You are receiving this because you are subscribed to this thread.

Message ID: <whatwg/dom/issues/1225@github.com>

Received on Sunday, 10 September 2023 15:55:56 UTC