Перейти к основному содержимому

Правила Поведения Полей В Формах-Редакторах

Назначение

Документ задаёт правила поведения, отображения и состояний полей в дескриптор-ориентированных формах 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)
Disableddisabled пробрасывается сверху (схема опубликована/в процессе компиляции) или поле имеет флаг System/ReadonlyВсе вводы isDisabled
ReadOnlyComputedType = Computed«Значение по умолчанию» скрыто; на форме записи вычисляемое значение только для чтения
ReferencePendingВыбран id ссылки/пакета, которого нет в текущем спискеAsync-lookup догидрирует подпись по id (см. AsyncSingleSelect/AsyncMultiSelect)

Правила состояний:

  • disabled всегда пробрасывается во все вложенные контролы поля (единый источник — проп строки).
  • Ошибки берутся из карты fieldErrors по строковому пути (${pathPrefix}.<Свойство>) через getNestedFieldError; локального состояния ошибок поле не держит.
  • Поле контролируемо: только value + onChange; внутреннего состояния, расходящегося с моделью, нет.

Идентичность поля: ключ и название

  • Машинный ключ поля (FieldKey) не вводится отдельно — форма показывает единый ввод «Название», а ключ формируется из него (зеркалится в FieldKey) до удаления FieldKey из контракта на бэке.
  • Тип и название объединены в один визуальный блок (HeroUI InputGroup): тип — InputGroup.Prefix (выпадающий список в начале), название — InputGroup.Input.

Компоненты и переиспользование

Выбор контрола определяется семантикой данных, а не типом «на глаз»:

ДанныеКонтролИсточник
Одиночный enumEnumSelectField + 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/
Список свободных строкTagsInputsrc/shared/ui/document-editors/TagsInput.tsx
Текст/число/датаFormField (HeroUI TextField/Input, type по семантике)src/shared/ui/FormField.tsx
Сворачиваемая секцияCollapsibleSectionsrc/shared/ui/document-editors/CollapsibleSection.tsx
Массив под-объектовDocumentArrayEditorsrc/shared/ui/document-editors/DocumentArrayEditor.tsx
  • Новые dedicated enum-селекты добавляются в enum-selects/ поверх EnumSelectField/MultiEnumSelectField, с русскими подписями опций и значениями из <Enum>Values сгенерированного клиента.
  • Набор флагов рендерится как checkbox-кнопки (ToggleButtonGroup selectionMode="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 (только токены).

Обратные ссылки

Автоссылки: где используется этот документ.

Связанные документы