Правила Поведения Полей В Формах-Редакторах
Назначение
Документ задаёт правила поведения, отображения и состояний полей в дескриптор-ориентированных формах frontend-приложений Pin (стек HeroUI v3 + Tailwind 4), где набор и вид под-контролов поля определяется его типом. Эталон — редактор схемы каталога («Новая схема каталога» / «Редактировать схему каталога»). Правила обязательны для новых и изменяемых форм такого класса и обеспечивают единообразный, предсказуемый UX.
Область применения
Формы, где пользователь описывает или заполняет поля по типу:
- Редактор поля схемы каталога —
src/entities/structured-forms/catalog-schema/CreateCatalogSchemaFieldRow.tsx,UpdateCatalogSchemaFieldRow.tsx,FieldTypeNameInput.tsx. - Редактор поля схемы справочника —
src/entities/structured-forms/dictionary-schema/*FieldRow.tsx. - Ввод значения записи по типу поля —
src/entities/structured-forms/catalog-entry-fields/CatalogEntryFieldValueInput.tsx. - Любые будущие формы, где «тип» (enum) управляет составом контролов.
Термины
| Термин | Значение |
|---|---|
| Поле-дескриптор | Описание поля схемы (тип, название, флаги, валидация, ссылка, формула). |
| Тип поля | Значение enum FieldType (см. реестр enum'ов); главный «переключатель» состава контролов. |
| Под-контрол | Зависимая секция/ввод (значение по умолчанию, источник ссылки, формула, валидация, счётчик, пакеты). |
| Универсальный контрол | Контрол, отображаемый для всех типов (флаги, пользовательские правила, пакеты проверок). |
| Состояние поля | Editable / Invalid / Disabled / ReadOnlyComputed / Reference-pending (см. ниже). |
Граф отображения по типу поля
Правила отображения (тип → контролы)
| Тип поля | Значение по умолч. | Спец-секция | Валидация |
|---|---|---|---|
Text | текст | — | Мин/Макс длина, Pattern, флаги regex |
Number, Decimal, Money, Percentage, Temperature, Weight, Volume, Duration | число | — | Минимум / Максимум |
Boolean | Выпадающий список Да/Нет | — | — |
Date | пикер даты | — | —¹ |
Time | пикер времени | — | —¹ |
DateTime | пикер даты-времени | — | —¹ |
Counter | скрыто | «Счётчик» (префикс, суффикс, seed, increment, reset policy) | — |
Dictionary, Employee, Responsible, File, Image, Qr | скрыто | «Источник ссылки» (тип источника, снимок, обновление, поведение при удалении; для Dictionary — выбор справочника) | — |
Enum | текст | — | — |
MultiSelect | текст | — | Мин/Макс количество |
Computed | скрыто | «Выражение (NCalc)» — вне аккордеона, сразу под флагами | — |
Для всех типов: единый ввод «Тип и название», «Флаги», секция «UI». «Пользовательские правила» и «Пакеты проверок» (RulePackIds, ThresholdPackId) — для всех типов, кроме File, Image, Qr, Dictionary, Counter, Employee.
¹ У дат нет числовых границ: в унифицированном SchemaFieldValidationDto поля Min/Max имеют тип decimal и не выражают дату — границы для дат на уровне контракта не поддерживаются.
Значение по умолчанию (Default)
- Контрол адаптируется под тип (см. таблицу):
Boolean→ выпадающий список «Да/Нет»;Date/Time/DateTime→ нативные пикеры (type="date|time|datetime-local"); числовые →type="number"; прочие скаляры → текст. - Поле «Значение по умолчанию» скрыто для
Computed(вычисляется формулой),Counter(выделяется системой) и ссылочных типов (Dictionary,Employee,Responsible,File,Image,Qr— значение задаётся в записи). - Значение хранится строкой (контракт
Default: string?):Booleanпишет"true"/"false"; пустой ввод →null. - Не использовать «сырой» текст там, где есть типизированный контрол (дата как текст, bool как текст — запрещено).
Валидация по типу
- Состав полей валидации зависит от типа и секция скрывается целиком, если для типа нет применимых правил.
- Строки (
Text): минимальная/максимальная длина,Pattern(регулярное выражение) и его флаги (RegexFlag[]черезRegexFlagMultiSelect). - Массивы (
MultiSelect): минимальное/максимальное количество элементов (подписи «Мин./Макс. кол-во»). - Числовые типы: «Минимум»/«Максимум» (
Min/Max). - Флаги regex показываются только вместе с
Pattern. - Доменные ограничения и пер-полевые правила — см. strict-typed-documentation-rules.md и серверные FluentValidation-правила (
Expressionтолько дляComputed,PatternFlagsтолько сPattern, и т. п.).
Пользовательские правила и пакеты проверок
- Секции «Пользовательские правила» (
CustomRules) и «Пакеты проверок» (RulePackIds,ThresholdPackId) показываются для большинства типов, но скрыты дляFile,Image,Qr,Dictionary,Counter,Employee— у этих полей пер-полевые правила и пороги не применяются. - Список скрытия задаётся явным набором типов (
NO_RULES_PACKS_TYPES) в field-row; изменение состава типов меняется в одном месте и зеркалится между Create/Update.
Состояния поля
| Состояние | Когда | Поведение UI |
|---|---|---|
| Editable | Черновик схемы, поле редактируемо | Все контролы активны |
| Invalid | Есть ошибка из fieldErrors по пути поля | Подсветка isInvalid, текст ошибки под контролом (FieldErrorText/getNestedFieldError) |
| Disabled | disabled пробрасывается сверху (схема опубликована/в процессе компиляции) или поле имеет флаг System/Readonly | Все вводы isDisabled |
| ReadOnlyComputed | Type = Computed | «Значение по умолчанию» скрыто; на форме записи вычисляемое значение только для чтения |
| ReferencePending | Выбран id ссылки/пакета, которого нет в текущем списке | Async-lookup догидрирует подпись по id (см. AsyncSingleSelect/AsyncMultiSelect) |
Правила состояний:
disabledвсегда пробрасывается во все вложенные контролы поля (единый источник — проп строки).- Ошибки берутся из карты
fieldErrorsпо строковому пути (${pathPrefix}.<Свойство>) черезgetNestedFieldError; локального состояния ошибок поле не держит. - Поле контролируемо: только
value+onChange; внутреннего состояния, расходящегося с моделью, нет.
Идентичность поля: ключ и название
- Машинный ключ поля (
FieldKey) не вводится отдельно — форма показывает единый ввод «Название», а ключ формируется из него (зеркалится вFieldKey) до удаленияFieldKeyиз контракта на бэке. - Тип и название объединены в один визуальный блок (HeroUI
InputGroup): тип —InputGroup.Prefix(выпадающий список в начале), название —InputGroup.Input.
Компоненты и переиспользование
Выбор контрола определяется семантикой данных, а не типом «на глаз»:
| Данные | Контрол | Источник |
|---|---|---|
| Одиночный enum | EnumSelectField + dedicated-обёртка с русскими подписями | src/shared/ui/enum-selects/ |
| Набор enum/флагов | MultiEnumSelectField (HeroUI ToggleButtonGroup — checkbox-кнопки) | src/shared/ui/enum-selects/MultiEnumSelectField.tsx |
| Ссылка по id (один/много) | AsyncSingleSelect / AsyncMultiSelect + lookup-обёртка | src/shared/ui/async-select/, src/shared/ui/lookups/ |
| Список свободных строк | TagsInput | src/shared/ui/document-editors/TagsInput.tsx |
| Текст/число/дата | FormField (HeroUI TextField/Input, type по семантике) | src/shared/ui/FormField.tsx |
| Сворачиваемая секция | CollapsibleSection | src/shared/ui/document-editors/CollapsibleSection.tsx |
| Массив под-объектов | DocumentArrayEditor | src/shared/ui/document-editors/DocumentArrayEditor.tsx |
- Новые dedicated enum-селекты добавляются в
enum-selects/поверхEnumSelectField/MultiEnumSelectField, с русскими подписями опций и значениями из<Enum>Valuesсгенерированного клиента. - Набор флагов рендерится как checkbox-кнопки (
ToggleButtonGroupselectionMode="multiple",isDetached), не как «голые» чекбоксы.
Раскладка и ширины (grid)
- Поля не растягиваются на всю ширину без нужды. Верх строки поля —
grid grid-cols-12: «Тип и название» занимает 7–8 колонок, «Значение по умолчанию» — 4–5. - Числовые и короткие вводы группируются в узкие секции: внутренние сетки ограничиваются
sm:max-w-md(валидация) /sm:max-w-lg/max-w-2xl(счётчик, UI, ссылка),grid grid-cols-2. - Только токены/контентные размеры (см. frontend-design-system-rules.md); произвольные
w-[…px]запрещены. - Пикеры даты/времени и числовые вводы — компактные (по содержимому), не во всю строку.
Доступность (A11Y)
- Каждый контрол имеет видимую подпись (
Label) илиaria-label(компактные контексты — таблицы, префиксыInputGroup). - Состояние ошибки доступно (
isInvalid+ связанный текст ошибки). - Тёмная тема и контраст WCAG AA обязательны (см. ui-accessibility-rules.md).
Запрещено
- Свободный текст для значения из фиксированного набора — только enum-селект (см. code-quality-standards.md).
- Показ нерелевантных типу контролов (например, «Минимум/Максимум» у строки, «длина» у числа, «Значение по умолчанию» у формулы).
- «Голые» чекбоксы для набора флагов вместо checkbox-кнопок.
- Полноширинные числовые/датовые вводы без ограничения сетки.
- Локальное состояние поля, расходящееся с
value/onChangeмодели. - Произвольные hex-цвета/размеры в JSX (только токены).
Обратные ссылки
Автоссылки: где используется этот документ.
- frontend-design-system-rules.md (1): Правила Frontend Design System
Связанные документы
- frontend-design-system-rules.md — HeroUI/Tailwind, токены, сетка, breakpoints.
- frontend-fsd-and-atomic-rules.md — слои FSD и Atomic, размещение компонентов.
- frontend-state-management-rules.md — TanStack Query/Zustand, контролируемые формы.
- ui-responsive-design-rules.md — адаптивность и breakpoints.
- ui-accessibility-rules.md — A11Y.
- code-quality-standards.md — строгая типизация, enum вместо строк.
- Реестр enum'ов — значения
FieldType,RegexFlag,RoleKind,AccessLevel, reference-enum'ы. - Полная документация HeroUI —
.claude/docs/heroui/llms-full.txt(TextField,InputGroup,ToggleButtonGroup,Select, и т. д.).