Годами ответ Angular был такой:
element.tagName === 'INPUT'
Строка. Сравнение. Всё.
В открытом PR #69452 он становится другим:
customElements.get(el.tagName.toLowerCase())
?.formAssociated === true
Разница не косметическая. Раньше фреймворк знал список нативных элементов — он был зашит в исходники. Теперь он идёт спрашивать у браузера, что умеет вот эта штука в DOM.
Повод: Signal Forms в упор не видят веб-компоненты. Сделал <my-range> с static formAssociated = true, честно поднял ElementInternals, всё по спеке — Angular считает его дивом.
Дальше самое любопытное. Как понять, поддерживает ли компонент min и max? Интерфейса нет, спросить не у кого. Решение — читаем статику класса и гадаем по списку наблюдаемых атрибутов:
observedAttributes?.includes('min')
&& observedAttributes?.includes('max')
Раз подписался на изменения min — наверное, как-то его обрабатываешь.
Наверное.
observedAttributes — это про реактивность, а не про возможности. Реализовал min/max свойствами, атрибуты не объявил — не прошёл. Молча. Без ворнинга. Просто атрибут не отрендерится, и ты час смотришь в DevTools.
Что тут произошло, если отойти на шаг: граница нативного в Angular перестала совпадать со спекой HTML. Раньше закрытый список. Теперь — проверяемое свойство, которое любой может себе выдать
Направление правильное. Реализация — эвристики поверх эвристик
🔗 github.com/angular/angular/pull/69452

