Corp/docs/guides/frontend/07-DEVELOPER-WORKFLOW.md

8.5 KiB
Raw Permalink Blame History

Frontend Guide: Developer Workflow

Этот документ отвечает на вопрос: как practically разрабатывать новый UI в этом проекте.

1. Порядок работы над новой UI-задачей

Рекомендуемый порядок:

  1. определить жанр экрана: operational workspace, profile-like page, dashboard/feed или auth/legal flow
  2. понять, это новый паттерн или существующий
  3. найти ближайшие shared primitives
  4. определить уровень поверхности и геометрии
  5. собрать layout из существующих слоёв
  6. вынести тяжёлые feature-блоки из page-level файла, если экран уже растёт за счёт list row / detail modal / compose workspace
  7. только потом добавлять локальные override

Неправильный порядок:

  1. сразу писать JSX с локальными utility-классами
  2. потом пытаться “подогнать под проект”

2. Как делать новый экран

Перед началом нового экрана:

  • определить, это обычная app-page или отдельный auth/legal flow
  • определить, это рабочий модуль, profile-like page или обзорный dashboard/feed
  • понять, нужен ли AppShell
  • определить основной primary panel
  • определить, сколько secondary blocks реально нужно

Практический шаблон:

  1. взять AppShell, если это обычная страница приложения
  2. использовать PageHeader, если нужен стандартный page intro
  3. построить крупные контейнеры как app-surface rounded-2xl
  4. вложенные секции делать через app-surface-muted rounded-xl
  5. поля формы строить на 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-поле

Порядок решения:

  1. если это простой одиночный выбор без поиска, можно использовать app-select
  2. если нужен поиск, chips, multi-select или compose-поведение, брать SearchableSelect*
  3. если хочется “чуть-чуть допилить стрелочку”, сначала проверить, не означает ли это, что нужен shared pattern, а не local fix

Красный флаг:

  • локальная стилизация native select, чтобы он выглядел как shared dropdown, почти всегда означает неправильный выбор primitive

6. Как делать модалку

Если нужен обычный dialog:

  • использовать Modal

Перед реализацией определить:

  • это modal dialog, drawer или workspace?
  • нужен ли sticky footer?
  • нужна ли длинная scrollable content area?

Нормальный modal workflow:

  1. взять Modal
  2. определить размер
  3. собрать shell на app-surface-elevated
  4. выстроить content hierarchy
  5. проверить 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