Зміст
Коротко
На Dev.to автор DashForge розповідає, як проблема «форм у React» виявилася не CSS, а проводкою: Controller, watch, useEffect на кожне поле. Відповідь — typed props замість className-супу, міст до React Hook Form і компоненти, які самі знають форму, видимість і права доступу.
Що сталося
Початковий біль знайомий: Tailwind вирішує cascade і мертві стилі, але візуальна частина живе в непрозорому рядку без автодоповнення й рефакторингу. Автор запитав: що якщо variant, color, size — звичайні типізовані props, а за кадром — utilities через tailwind-variants і design tokens?
Наступний шар — форми. Патерн RHF з Controller і render prop на 50-му полі виснажує. TextField з name="email" сам читає value, помилки й blur/submit-логіку через context-міст — без ручної проводки.
Далі — оркестрація бізнес-UI:
- visibleWhen — поле описує умову показу, без
watch+useEffectна кожне правило. - access на кнопці —
invoice:updateвсередині компонента, а неpermissions.includesна кожному екрані.
Архітектурний поворот: дві UI-бібліотеки (MUI і Tailwind + Radix) з однаковими props оркестрації, але спільним headless-движком (міст форм, видимість полів, RBAC).
Чому це важливо
В enterprise-формах основна вартість — не пікселі, а glue-код: зв'язати поле з формою, валідацією, правами, умовною видимістю. Typed visual API знижує клас помилок у стилях; application-aware components — повторюваний boilerplate на сотнях екранів.
DashForge у alpha, але ідея — винести повторювану оркестрацію в декларативні props, залишивши Radix/React Aria для a11y.
На практиці
- Visual API — props-first поверх Tailwind; один escape hatch
sxз tailwind-merge. - Поля —
<TextField name="…" label="…" />замістьController+ error plumbing. - Умови —
visibleWhen={{ field, equals }}замість watch/effect. - Права —
access="resource:action"на інтерактивних вузлах.
Підсумок
Історія — про зміщення фокусу з «як стилізувати» на «як компонент бере участь у застосунку». Якщо втомилися від copy-paste проводки форм — має сенс подивитися DashForge як експеримент.