npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cloud-ru/ds-field-decorator

v1.0.4

Published

Структурная обёртка label/caption/hint/error/length для нестандартных input'ов и сложных композиций.

Readme

FieldDecorator

@cloud-ru/ds-field-decorator — Структурная обёртка label/caption/hint/error/length для нестандартных input'ов и сложных композиций.

Низкоуровневый каркас для полей: рендерит блоки label, caption, hint, error, счётчик length и звёздочку required, а в children подставляется любой input или композиция (@cloud-ru/ds-input-private, дата-пикеры, селекты).

Пакет отдаёт три публичных компонента:

  • Label — строка заголовка: текст, звёздочка required, question-tooltip и подпись caption.
  • Hint — подвал поля: подсказка/ошибка со статус-иконкой по валидации и счётчик length.
  • FieldDecorator — композиция Label + children + Hint в единой сетке.

Когда использовать

  • Когда нужно обернуть нестандартный input в типовую разметку поля.
  • Когда FieldText / FieldSecure не подходят:
    • отдельный date-picker;
    • masked input;
    • кастомная композиция со счётчиком length или валидационной подсказкой.

Анатомия

Size (default m)

| Значение | Когда | |----------|-------| | s | Плотные таблицы, inline-редактирование | | m | Стандартные формы (по умолчанию) | | l | Лендинги, primary-формы |

ValidationState (default default)

Управляет цветом подсказки и иконкой showHintIcon. Проп error форсит error поверх любого validationState. На неактивном поле (disabled / readonly) иконка валидации не выводится — подсказка нейтральна.

| Значение | Когда | |----------|-------| | default | Нет валидации — нейтральный baseline: подсказка в textTertiary, без иконки и без заливки | | error | Не прошло валидацию | | warning | Предупреждение | | success | Подтверждение |

Состояния (disabled / readonly)

Оси неактивного поля. Не комбинируются с цветом валидации: на неактивном поле иконка валидации не выводится, счётчик length скрыт.

| Значение | Поведение | |----------|-----------| | disabled | Поле выключено: счётчик скрыт, подсказка нейтральна | | readonly | Только для чтения: то же поведение подвала, что у disabled |

Заголовок (Label)

Шапка поля складывается из слотов:

  • label — текст заголовка; labelFor связывает его с input через HTML-атрибут for.
  • required — звёздочка * рядом с заголовком, маркирует обязательное поле.
  • labelTooltip — иконка вопроса с подсказкой (QuestionTooltip) после заголовка. Требует PortalContextProvider в дереве.
  • caption — вспомогательная подпись справа в шапке.

Подвал (Hint)

Под содержимым выводится:

  • hint / error — текст подсказки. error имеет приоритет над hint и форсит validationState='error'.
  • length — счётчик длины current/max. Когда current превышает max, счётчик подсвечивается (data-limit-exceeded). На disabled / readonly счётчик скрыт.

Установка

pnpm add @cloud-ru/ds-field-decorator
import { FieldDecorator, Label, Hint } from '@cloud-ru/ds-field-decorator'

Примеры использования

Базовая обёртка

FieldDecorator оборачивает InputPrivate в типовую разметку label/hint.

import { FieldDecorator } from '@cloud-ru/ds-field-decorator';
import { InputPrivate } from '@cloud-ru/ds-input-private';
import { useState } from 'react';

export function DecoratorBasic() {
  const [value, setValue] = useState('');
  return (
    <FieldDecorator label='Custom field' hint='FieldDecorator оборачивает любой input' showHintIcon>
      <InputPrivate value={value} onChange={setValue} placeholder='Type here' />
    </FieldDecorator>
  );
}

Счётчик длины

Length показывает «текущая/максимум», обновляется по изменению значения.

import { FieldDecorator } from '@cloud-ru/ds-field-decorator';
import { InputPrivate } from '@cloud-ru/ds-input-private';
import { useState } from 'react';

export function DecoratorLength() {
  const [value, setValue] = useState('');
  return (
    <FieldDecorator
      label='Bio'
      caption='Опционально'
      hint='Кратко расскажите о себе'
      length={{ current: value.length, max: 120 }}
    >
      <InputPrivate value={value} onChange={setValue} maxLength={120} placeholder='Hi there' />
    </FieldDecorator>
  );
}

Превышение лимита

Когда current больше max, счётчик подсвечивается (data-limit-exceeded).

import { FieldDecorator } from '@cloud-ru/ds-field-decorator';
import { InputPrivate } from '@cloud-ru/ds-input-private';
import { useState } from 'react';

export function DecoratorLimitExceeded() {
  const [value, setValue] = useState('Слишком длинное значение, которое превышает лимит');
  return (
    <FieldDecorator
      label='Заголовок'
      hint='Счётчик подсвечивается, когда current превышает max'
      length={{ current: value.length, max: 20 }}
    >
      <InputPrivate value={value} onChange={setValue} placeholder='Введите текст' />
    </FieldDecorator>
  );
}

Подсказка к заголовку

labelTooltip добавляет иконку вопроса после label; required рисует звёздочку. Требует PortalContextProvider.

import { FieldDecorator } from '@cloud-ru/ds-field-decorator';
import { InputPrivate } from '@cloud-ru/ds-input-private';
import { useState } from 'react';

export function DecoratorLabelTooltip() {
  const [value, setValue] = useState('');
  return (
    <FieldDecorator
      label='Идентификатор'
      required
      labelTooltip={{ tip: 'Уникальный идентификатор ресурса. Наведите на иконку рядом с заголовком.' }}
      hint='Подсказка к заголовку выводится через иконку вопроса'
    >
      <InputPrivate value={value} onChange={setValue} placeholder='res-id' />
    </FieldDecorator>
  );
}

Disabled и Readonly

На неактивном поле счётчик скрыт, а иконка валидации не выводится — подсказка нейтральна.

import { FieldDecorator } from '@cloud-ru/ds-field-decorator';
import { InputPrivate } from '@cloud-ru/ds-input-private';

export function DecoratorDisabledReadonly() {
  return (
    <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'flex-start' }}>
      <FieldDecorator
        label='Disabled'
        hint='На неактивном поле счётчик скрыт, подсказка нейтральна'
        validationState='error'
        showHintIcon
        disabled
        length={{ current: 5, max: 20 }}
      >
        <InputPrivate value='value' onChange={() => undefined} disabled />
      </FieldDecorator>
      <FieldDecorator
        label='Readonly'
        hint='Readonly также нейтрализует подсказку и прячет счётчик'
        validationState='warning'
        showHintIcon
        readonly
        length={{ current: 5, max: 20 }}
      >
        <InputPrivate value='value' onChange={() => undefined} readonly />
      </FieldDecorator>
    </div>
  );
}

Label отдельно

Строку заголовка можно рендерить самостоятельно — например, над кастомной композицией.

import { Label } from '@cloud-ru/ds-field-decorator';

export function LabelStandalone() {
  return (
    <Label
      label='Заголовок поля'
      caption='Опционально'
      required
      labelTooltip={{ tip: 'Пояснение к заголовку через иконку вопроса' }}
    />
  );
}

Hint по состояниям валидации

Подсказка меняет цвет и статус-иконку по validationState.

import { Hint } from '@cloud-ru/ds-field-decorator';

export function HintStandalone() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
      <Hint hint='Нейтральная подсказка под полем' length={{ current: 12, max: 100 }} />
      <Hint hint='Ошибка валидации' validationState='error' showHintIcon />
      <Hint hint='Предупреждение' validationState='warning' showHintIcon />
      <Hint hint='Проверка пройдена' validationState='success' showHintIcon />
    </div>
  );
}

Props

FieldDecorator

FieldDecoratorProps

| Prop | Type | Default | Description | |------|------|---------|-------------| | caption | string | — | Вторичная подпись справа | | children | ReactNode | — | Содержимое (декорируемое поле) | | className | string | — | CSS-класс | | data-test-id | string | — | | | disabled | boolean | — | Поле выключено | | error | string | — | Ошибка (приоритетнее hint; форсит validationState=error) | | hint | string | — | Подсказка | | innerRef | Ref<HTMLDivElement> | — | Ref на корневой DOM-элемент | | label | string | — | Заголовок | | labelFor | string | — | HTML-атрибут for для <label> | | labelTooltip | QuestionTooltipProps | — | Подсказка (question-tooltip) у заголовка | | length | FieldLength | — | Счётчик длины current/max | | readonly | boolean | — | Только для чтения | | required | boolean | — | Показать знак обязательности * | | showHintIcon | boolean | true | Отображение статус-иконки у подсказки (по умолчанию true) | | size | "l" | "m" | "s" | m | Размер | | validationState | "default" | "error" | "success" | "warning" | default | Состояние валидации |

Related types

FieldLength

| Prop | Type | Default | Description | |------|------|---------|-------------| | current | number | — | Текущая длина текста | | max | number \| undefined | — | Максимально допустимая длина |

  • Size = "l" | "m" | "s"

  • ValidationState = "default" | "error" | "success" | "warning"

Label

LabelProps

| Prop | Type | Default | Description | |------|------|---------|-------------| | caption | string | — | Вторичная подпись справа | | className | string | — | CSS-класс | | data-test-id | string | — | | | disabled | boolean | — | Поле выключено | | innerRef | Ref<HTMLDivElement> | — | Ref на корневой DOM-элемент | | label | string | — | Заголовок | | labelFor | string | — | HTML-атрибут for для <label> | | labelTooltip | QuestionTooltipProps | — | Подсказка (question-tooltip) у заголовка | | required | boolean | — | Показать знак обязательности * | | size | "l" | "m" | "s" | m | Размер |

Related types

  • Size = "l" | "m" | "s"

Hint

HintProps

| Prop | Type | Default | Description | |------|------|---------|-------------| | className | string | — | CSS-класс | | data-test-id | string | — | | | disabled | boolean | — | Поле выключено | | error | string | — | Ошибка (приоритетнее hint; форсит validationState=error) | | hint | string | — | Подсказка | | innerRef | Ref<HTMLDivElement> | — | Ref на корневой DOM-элемент | | length | FieldLength | — | Счётчик длины current/max | | maxLines | number | — | Обрезать подсказку до N строк многоточием (через TruncateString, с тултипом полного текста на ховере). Без значения подсказка переносится без ограничения (дефолт поля). Нужно для карточек фиксированной высоты (@cloud-ru/ds-attachment), где длинный текст ошибки иначе выходит за границы. | | readonly | boolean | — | Только для чтения | | showHintIcon | boolean | true | Отображение статус-иконки у подсказки (по умолчанию true) | | size | "l" | "m" | "s" | m | Размер | | validationState | "default" | "error" | "success" | "warning" | default | Состояние валидации |

Related types

FieldLength

| Prop | Type | Default | Description | |------|------|---------|-------------| | current | number | — | Текущая длина текста | | max | number \| undefined | — | Максимально допустимая длина |

  • Size = "l" | "m" | "s"

  • ValidationState = "default" | "error" | "success" | "warning"