8.5 KiB
8.5 KiB
Frontend Guide: Developer Workflow
Этот документ отвечает на вопрос: как practically разрабатывать новый UI в этом проекте.
1. Порядок работы над новой UI-задачей
Рекомендуемый порядок:
- определить жанр экрана: operational workspace, profile-like page, dashboard/feed или auth/legal flow
- понять, это новый паттерн или существующий
- найти ближайшие shared primitives
- определить уровень поверхности и геометрии
- собрать layout из существующих слоёв
- вынести тяжёлые feature-блоки из page-level файла, если экран уже растёт за счёт list row / detail modal / compose workspace
- только потом добавлять локальные override
Неправильный порядок:
- сразу писать JSX с локальными utility-классами
- потом пытаться “подогнать под проект”
2. Как делать новый экран
Перед началом нового экрана:
- определить, это обычная app-page или отдельный auth/legal flow
- определить, это рабочий модуль, profile-like page или обзорный dashboard/feed
- понять, нужен ли
AppShell - определить основной primary panel
- определить, сколько secondary blocks реально нужно
Практический шаблон:
- взять
AppShell, если это обычная страница приложения - использовать
PageHeader, если нужен стандартный page intro - построить крупные контейнеры как
app-surface rounded-2xl - вложенные секции делать через
app-surface-muted rounded-xl - поля формы строить на
app-input/app-select
3. Как делать новую карточку
Перед созданием карточки спросить:
- это primary container или secondary grouped block?
- карточка реально нужна, или это просто внутренний helper block?
- не создаём ли мы третью глубину вложенности без необходимости?
Норма:
- primary card:
app-surface rounded-2xl - secondary card:
app-surface-muted rounded-xl - маленький helper:
rounded-lgилиrounded-xl, но не новая “мини-основная карточка”
4. Как делать новую форму
Сначала определить тип формы:
- CRUD
- compose
- filters
- settings
- dialog action
После этого:
- выбрать подходящий form contract
- использовать общие primitives
- решить, какие поля главные, а какие вторичные
- если compose-форма превращается в workspace, вынести её из page-level JSX в feature component
Важно:
- не все формы должны выглядеть одинаково
- но все формы должны жить в одной визуальной системе
- page-level файл не должен оставаться местом для длинной compose-модалки, если она уже стала отдельным рабочим сценарием
То же правило для list/detail flow:
- если у страницы появились тяжёлые expandable rows, detail modal или participant-heavy blocks, это уже кандидат на feature components, а не на дальнейшее разрастание page-level JSX
- то же касается toolbar/filter block и attachment preview, если они уже стали самостоятельными зонами сценария
- router-sync, deep-link opening и dismissable menu state тоже можно выносить в feature hook, если это screen orchestration, а не данные домена
- если внутри одной зоны уже несколько leaf-компонентов, стоит ввести feature container вроде
*Sectionили*Panel, а не возвращать всё обратно в page-level JSX - если экран уже визуально удачный, первый шаг рефакторинга должен сохранять внешний контракт и чистить структуру под капотом, а не навязывать новый layout только ради декомпозиции
- если у toolbar/filter block пропсы начинают расползаться, можно группировать их локально, но это не должно само по себе заставлять перепридумывать успешный внешний вид блока
- если экран ощущается как “из другого проекта”, причина чаще всего не в одном radius или цвете, а в несовпадении screen genre; это нужно решать на уровне hierarchy, density и panel semantics, а не точечными utility-правками
5. Как делать dropdown-поле
Порядок решения:
- если это простой одиночный выбор без поиска, можно использовать
app-select - если нужен поиск, chips, multi-select или compose-поведение, брать
SearchableSelect* - если хочется “чуть-чуть допилить стрелочку”, сначала проверить, не означает ли это, что нужен shared pattern, а не local fix
Красный флаг:
- локальная стилизация native
select, чтобы он выглядел как shared dropdown, почти всегда означает неправильный выбор primitive
6. Как делать модалку
Если нужен обычный dialog:
- использовать
Modal
Перед реализацией определить:
- это modal dialog, drawer или workspace?
- нужен ли sticky footer?
- нужна ли длинная scrollable content area?
Нормальный modal workflow:
- взять
Modal - определить размер
- собрать shell на
app-surface-elevated - выстроить content hierarchy
- проверить mobile-скролл и footer actions
7. Когда выносить в shared
Выносить в shared, если:
- паттерн повторится минимум ещё раз
- это не доменная логика, а UI-механика
- локальный код начинает превращаться в новый mini-framework внутри страницы
Не выносить рано, если:
- решение ещё сырое
- паттерн пока узкоспецифичный
- компонент завязан на один домен и вряд ли станет общим
8. Когда можно делать локальный override
Локальный override допустим, если:
- нет подходящего primitive
- решение реально локально
- не ломается общий visual contract
- override не рождает новый незафиксированный паттерн
Если override начинает повторяться, это уже shared problem, а не local exception.
9. Что проверять до завершения работы
Перед тем как считать UI-задачу завершённой, проверить:
- поверхность и радиусы соответствуют guide
- нет лишнего custom radius
- поля используют
app-*primitives - dropdown affordance не локально придуман
- mobile layout выглядит естественно
- действия формы и карточки читаются по визуальному весу
- role-based фронтовые эвристики не подменяют API contract там, где источник истины должен приходить с backend