Поле количества принимает число с клавиатуры или меняет его кнопками «минус» и
«плюс» на заданный шаг. Подходит для количества товаров, мест, участников и
других ограниченных числовых величин; для произвольного текста берите
текстовое поле.
Минимальную разметку показывает пример выше. Части вложены так:
label.sf-quantity → подпись sf-quantity-label и sf-quantity-wrap с
кнопкой уменьшения, нативным <input> и кнопкой увеличения.
Оболочка — <label class="sf-quantity"> с классом размера и утилитами
flex flex-col. Скрипт компонента находит поля по .sf-quantity.
Подпись — sf-quantity-text внутри sf-quantity-label; звёздочка
sf-quantity-required отмечает обязательное поле. Скрипт связывает подпись с
полем через aria-labelledby.
Две кнопки sf-quantity-count — первая уменьшает, вторая увеличивает. Это
кнопки с иконкой (sf-icon-button) с type="button" и собственным
aria-label. Их цвет и размер задаёт sf-quantity, поэтому класса
sf-icon-button--icon им не нужно. Отдельная кнопка-иконка вне
sf-quantity получает цвета только вместе с sf-icon-button--icon.
<input type="text"> с inputmode="numeric" или "decimal" хранит значение
и name; min, max и step задают диапазон и шаг. Тип text выбран
потому, что поле показывает число в формате языка страницы.
Варианты
Размер
Три ступени — sf-quantity--size-1/2, sf-quantity--size-1 и
sf-quantity--size-2, как у текстового поля. Размер меняет подпись, поле и
кнопки вместе.
min, max и step на input задают диапазон и шаг кнопок. Кнопка
становится недоступной, когда значение дошло до своей границы. Введённое
вручную значение при потере фокуса ограничивается диапазоном, но не
округляется до шага. Пустое поле остаётся пустым. Число знаков после
разделителя по умолчанию берётся из step.
Поле показывает число в формате языка страницы. data-locale задаёт другую
локаль в формате Intl.NumberFormat, data-precision — число знаков после
разделителя, data-grouping="false" выключает группировку разрядов.
По умолчанию поле убирает из ввода всё, что не может быть числом.
data-input-mode="strict" не даёт напечатать или вставить недопустимый символ.
data-allow-negative="true" разрешает минус, data-allow-decimal="true" —
дробную часть; без него дробная часть разрешена, когда точность больше нуля.
data-mask="true" подключает числовую маску Framework: она держит значение в
границах min и max и с нужным числом знаков, но разряды не группирует.
Состояния задают нативные атрибуты input; класс на оболочке нужен только
ошибке. Доступность кнопок скрипт выставляет сам по состоянию input и
значению. Наведение компонент показывает сам.
На границе
Когда значение равно min, недоступна кнопка уменьшения; когда равно max —
кнопка увеличения.
Класс error на оболочке окрашивает рамку и кнопки цветом ошибки. Своего узла
для сообщения у компонента нет: добавьте текст ошибки под полем и свяжите его с
input через aria-describedby, сам input получает aria-invalid="true".
HTML
<divclass="grid grid-col-1 md:grid-col-2 gap-4">
<divclass="flex flex-col gap-1">
<labelclass="sf-quantity sf-quantity--size-1 error flex flex-col"><spanclass="sf-quantity-label flex"><spanclass="sf-quantity-text">Участники</span><spanclass="sf-quantity-required"aria-hidden="true">*</span></span><spanclass="sf-quantity-wrap flex content-main-center items-cross-center"><buttontype="button"class="sf-quantity-count sf-icon-button sf-icon-button--secondary sf-icon-button--tonal sf-icon-button--size-1/3 flex"aria-label="Уменьшить число участников"><iclass="sf-icon"aria-hidden="true">remove</i></button><inputtype="text"value="0"inputmode="numeric"min="0"requiredaria-invalid="true"aria-describedby="participants-error"><buttontype="button"class="sf-quantity-count sf-icon-button sf-icon-button--secondary sf-icon-button--tonal sf-icon-button--size-1/3 flex"aria-label="Увеличить число участников"><iclass="sf-icon"aria-hidden="true">add</i></button></span><spanid="participants-error"class="color-error text-1/2">Укажите хотя бы одного участника</span></label>
<codeclass="text-1/2 color-on-surface-variant">error</code>
</div>
</div>
Фокус
При переходе клавишей Tab рамка поля или кнопка получает кольцо фокуса по
:focus-visible. При нажатии мышью скрипт ставит оболочке
sf-quantity--pointer-focus, и кольцо не рисуется. В примере фокус показан
классом focus-visible на input.
Видимая подпись называет поле, а каждая кнопка получает свой aria-label,
который говорит, что она меняет: «Уменьшить количество мест».
Кнопки и поле стоят в порядке фокуса; значение меняется вводом с клавиатуры
или нажатием кнопки пробелом и Enter.
Недоступную на границе кнопку экранный диктор объявляет недоступной; границы
диапазона назовите в подписи или подсказке.
Ошибку сообщайте текстом: одного цвета недостаточно. Серверная проверка
значения остаётся задачей приложения.
В режиме принудительных цветов кольцо фокуса рисуется системным цветом.
JavaScript
Нажатие кнопки меняет значение на шаг и создаёт на input всплывающее событие
change; ввод с клавиатуры создаёт обычные input и change. Внутри формы
сброс возвращает начальное значение input; отменённый обработчиком reset
значение не меняет.
Компонент регистрирует класс Quantity. SF.Loader появляется к событию
sf-loader-init на window; SF.Loader.ready('Quantity', callback) передаёт
класс, когда он зарегистрирован.
Классы и переменные собраны из CSS выпуска и обновляются вместе с ним.
Переменные
Компонент читает свои переменные, а модификаторы задают им значения; таблица показывает, из чего складывается вид. Переменные компонента — его внутренняя проводка, а не поверхность настройки: их имена и устройство могут меняться. Вид проекта меняют общие токены, а глубокий вид Smart-компонента — его шаблон (см. Переменные компонента). Значение по умолчанию — из базового правила блока (.sf-quantity); переменную без него задают только модификаторы.
Переменная
По умолчанию
Задаёт
--sf-quantity-input--background-color
не задана; задают модификаторы, например .sf-quantity .sf-quantity-wrap input: transparent
background-color
--sf-quantity-input--color
не задана; задают модификаторы, например .sf-quantity input: var(--sf-on-surface)
color
--sf-quantity-input--font-family
не задана; задают модификаторы, например .sf-quantity.sf-quantity--size-1 input: var(--sf-text--family)
font-family
--sf-quantity-input--font-size
не задана; задают модификаторы, например .sf-quantity.sf-quantity--size-1 input: var(--sf-text-size-1)
font-size
--sf-quantity-input--font-weight
не задана; задают модификаторы, например .sf-quantity.sf-quantity--size-1 input: var(--sf-font-weight-regular)
font-weight
--sf-quantity-input--line-height
не задана; задают модификаторы, например .sf-quantity.sf-quantity--size-1 input: var(--sf-text-height-1)
line-height
--sf-quantity-input--padding-inline-end
не задана; задают модификаторы, например .sf-quantity.sf-quantity--size-1 input: var(--sf-ui-1--text-space-x)
padding-inline-end
--sf-quantity-input--padding-inline-start
не задана; задают модификаторы, например .sf-quantity.sf-quantity--size-1 input: var(--sf-ui-1--text-space-x)
padding-inline-start
--sf-quantity-label--background-color
не задана; задают модификаторы, например .sf-quantity .sf-quantity-label: transparent
background-color
--sf-quantity-label--gap
не задана; задают модификаторы, например .sf-quantity .sf-quantity-label: var(--sf-space-1/4)
gap
--sf-quantity-placeholder--color
не задана; задают модификаторы, например .sf-quantity .sf-quantity-wrap input::-webkit-input-placeholder: var(--sf-on-surface-variant)
color
--sf-quantity-placeholder--font-family
не задана; задают модификаторы, например .sf-quantity .sf-quantity-wrap input::-webkit-input-placeholder: var(--sf-text--family)
font-family
--sf-quantity-placeholder--font-size
не задана; задают модификаторы, например .sf-quantity--size-1 .sf-quantity-wrap input::-webkit-input-placeholder: var(--sf-text-size-1)
font-size
--sf-quantity-placeholder--line-height
не задана; задают модификаторы, например .sf-quantity--size-1 .sf-quantity-wrap input::-webkit-input-placeholder: var(--sf-text-height-1)
line-height
--sf-quantity-required--color
не задана; задают модификаторы, например .sf-quantity .sf-quantity-required: var(--sf-error)
color
--sf-quantity-required--font-family
не задана; задают модификаторы, например .sf-quantity .sf-quantity-required: var(--sf-text--family)
font-family
--sf-quantity-required--font-size
не задана; задают модификаторы, например .sf-quantity.sf-quantity--size-1 .sf-quantity-required: var(--sf-text-size-1/2)
font-size
--sf-quantity-required--font-weight
не задана; задают модификаторы, например .sf-quantity .sf-quantity-required: var(--sf-font-weight-regular)
font-weight
--sf-quantity-required--line-height
не задана; задают модификаторы, например .sf-quantity.sf-quantity--size-1 .sf-quantity-required: var(--sf-text-height-1/2)
line-height
--sf-quantity-text--color
не задана; задают модификаторы, например .sf-quantity .sf-quantity-text: var(--sf-on-surface-variant)
color
--sf-quantity-text--font-family
не задана; задают модификаторы, например .sf-quantity .sf-quantity-text: var(--sf-text--family)
font-family
--sf-quantity-text--font-size
не задана; задают модификаторы, например .sf-quantity.sf-quantity--size-1 .sf-quantity-text: var(--sf-text-size-1/2)
font-size
--sf-quantity-text--font-weight
не задана; задают модификаторы, например .sf-quantity .sf-quantity-text: var(--sf-font-weight-regular)
font-weight
--sf-quantity-text--line-height
не задана; задают модификаторы, например .sf-quantity.sf-quantity--size-1 .sf-quantity-text: var(--sf-text-height-1/2)
line-height
--sf-quantity-wrap--background-color
не задана; задают модификаторы, например .sf-quantity .sf-quantity-wrap: var(--sf-surface-0)
background-color
--sf-quantity-wrap--border
не задана; задают модификаторы, например .sf-quantity .sf-quantity-wrap: var(--sf-px) solid