GrValue
Берут, когда пишете свой компонент с величиной.
Когда брать
- пишете свой компонент с величиной — плитку, ячейку, строку отчёта: приписки оформятся так же, как в остальном пакете, без копирования классов;
- валюта стоит справа —
100 ₽, а не$100: сторона задаётся тем, в какую приписку положить символ; - величина не число — «2 ч 15 мин», «—», «н/д» выводятся как есть;
- нужна своя вёрстка вокруг значения — знак, стрелка, скрытая подпись ложатся в слоты между частями записи.
Когда взять другое
| Нужно | Берите |
|---|---|
| Знак и тон по знаку внутри строки текста | GrDelta |
| Крупный показатель плиткой, с подписью и динамикой | GrStatistic |
| Значение как статус или метка | GrBadge |
| Пара «характеристика → значение» | GrDescriptionList |
| Форматирование числа по локали | formatStatisticValue из GrStatistic |
Величина приходит готовой
Примитив ничего не форматирует: разряды, точность и разделители — забота того,
кто передаёт значение. Это не экономия, а граница ответственности: «2 ч 15 мин»
и «—» такие же величины, как 1 284 500, и компонент, который попытался бы их
разобрать, испортил бы обе.
Форматирование по локали в пакете есть — formatStatisticValue; оно доступно
отдельно и складывается с примитивом как угодно.
Приписка — не обязательно единица измерения
Компонент не решает, чем является приписка. Это и есть его смысл: $, ₽,
%, мс, «за заказ» — разные вещи, и одно правило на всех однажды соврёт.
Дефолты выбраны по частоте, а не по истине:
| Префикс | Суффикс | |
|---|---|---|
| цвет | как у величины | приглушённый |
| кегль | как у величины | мельче |
| отбивка | нет | есть |
За ними стоит наблюдение: слева чаще пишут валюту, и она часть суммы; справа
чаще единицу, и она величине не принадлежит. $14,99 и 42 % получаются сами.
Валюта справа — снимите приглушение
Рубль пишут после числа, но он такая же часть суммы, как $ перед ней. Поэтому
дефолт суффикса ему не подходит, и его меняют токенами:
<GrValue
:value="formatted"
suffix="₽"
style="--gr-value-suffix-color: currentColor; --gr-value-suffix-size: 1em"
/>
Приложению, где так всегда, удобнее объявить это классом один раз:
.amount { --gr-value-suffix-color: currentColor; --gr-value-suffix-size: 1em; }
Именно currentColor и 1em, а не inherit. У пользовательского свойства
inherit — ключевое слово наследования самой переменной: оно означает «возьми
её значение у родителя», а у родителя её нет, и токен остаётся неопределённым.
Фолбэк тогда срабатывает как обычно, и приписка выглядит нетронутой — правка
молча не даёт ничего. currentColor и 1em — настоящие значения, и они
означают ровно то, что нужно: цвет и кегль величины.
Сторону символа компонент не выбирает. Соблазн вывести её из локали есть, но
Intl расставляет валюту по локали, а не по валюте: в ru-RU справа
оказываются все, включая доллар (1 284 500,50 $), в en-US слева все, включая
рубль (RUB 1,284,500.50). Привычное «₽ справа, $ и € слева» — правило
смешанное и продуктовое, вывести его неоткуда. Решает потребитель, выбирая
приписку.
Тон доезжает до приписки сам
Цвет префикса по умолчанию — inherit, а не копия роли тона. Разница видна на
отрицательной сумме: краснеет вся запись, а не число без символа валюты.
Поэтому тон задаётся один раз на родителе — так делает GrStatistic, — и
примитиву о нём знать не нужно.
Тем же способом наследуется кегль: своей шкалы размеров у примитива нет, величина набирается кеглем места, где стоит.
Границы
Позиции приписок фиксированы: префикс слева, суффикс справа. Порядок не меняется ни пропом, ни локалью — величина, у которой приписки переставляются местами, это две разные записи, и выбрать между ними может только автор экрана.
Playground 2
Загружается…
<GrValue />Установка
npm i @feugene/granularityИмпорт
import { GrValue } from '@feugene/granularity/components/GrValue'API
Props
| Prop | Type | по умолчанию | Описание |
|---|---|---|---|
value | string | number | null | undefined | — | Готовое к показу значение. Не форматируется: «2 ч 15 мин» и «—» тоже величины. |
prefix | string | undefined | — | Приписка перед значением: валюта, знак приближения. |
suffix | string | undefined | — | Приписка после значения: единица измерения, валюта справа. |
Slots
| Slot | Type | Описание |
|---|---|---|
default | any | Значение вместо пропа. |
prefix | any | Приписка перед значением. |
suffix | any | Приписка после значения. |
lead | any | Перед префиксом: знак величины у `GrDelta`, стрелка направления. Слотом, а не пропом, — разметка там принадлежит потребителю. |
trail | any | После значения: скрытый узел для диктора у `GrStatistic`. |
Примеры 1
Валюта слева, валюта справа, единица
Компонент не решает, чем является приписка. Дефолты выбраны по частоте: слева обычно валюта — она набирается как число; справа обычно единица измерения — она приглушается и отбивается. Рубль пишут справа, но он часть суммы, и дефолт ему не подходит: снимается двумя токенами --gr-value-suffix-color и --gr-value-suffix-size.
<script setup lang="ts">
import { GrCard, GrValue } from '@feugene/granularity'
const amount = new Intl.NumberFormat('ru-RU', { maximumFractionDigits: 2 }).format(1284500.5)
</script>
<template>
<div class="grid gap-4 sm:grid-cols-3">
<GrCard variant="outlined" padding="md" body-class="grid gap-1">
<span class="text-[length:var(--gr-text-xs)] text-[var(--gr-muted-fg)]">Валюта слева</span>
<span class="text-[length:var(--gr-text-2xl)] font-semibold">
<GrValue :value="amount" prefix="$" />
</span>
<span class="text-[length:var(--gr-text-xs)] text-[var(--gr-muted-fg)]">
Дефолт: приписка слева набирается как число
</span>
</GrCard>
<!--
Рубль пишут справа, но он такая же часть суммы. Дефолт суффикса ему не
подходит, и его снимают токенами — компонент за потребителя не решает.
-->
<GrCard variant="outlined" padding="md" body-class="grid gap-1">
<span class="text-[length:var(--gr-text-xs)] text-[var(--gr-muted-fg)]">Валюта справа</span>
<span
class="text-[length:var(--gr-text-2xl)] font-semibold"
style="--gr-value-suffix-color: currentColor; --gr-value-suffix-size: 1em"
>
<GrValue :value="amount" suffix="₽" />
</span>
<span class="text-[length:var(--gr-text-xs)] text-[var(--gr-muted-fg)]">
Два токена — и приписка стала частью суммы
</span>
</GrCard>
<GrCard variant="outlined" padding="md" body-class="grid gap-1">
<span class="text-[length:var(--gr-text-xs)] text-[var(--gr-muted-fg)]">Единица измерения</span>
<span class="text-[length:var(--gr-text-2xl)] font-semibold">
<GrValue :value="42" suffix="%" />
</span>
<span class="text-[length:var(--gr-text-xs)] text-[var(--gr-muted-fg)]">
Дефолт: приписка справа приглушена и отбита
</span>
</GrCard>
</div>
</template>Сторону символа компонент не выбирает: Intl расставляет валюту по локали, а не по валюте — в ru-RU справа оказываются все, включая доллар. Привычное «₽ справа, $ слева» — правило продуктовое, и решает его потребитель, выбирая приписку.