GrEmptyState

  • ядро
  • Обратная связь
  • API · 6 props

Берут, когда список пуст с самого начала.

import { GrEmptyState } from '@feugene/granularity/components/GrEmptyState'

Обзор

Когда брать

  • список пуст с самого начала — «пока нет выплат»: объяснение и следующий шаг вместо пустого прямоугольника;
  • фильтр ничего не нашёл — текст и действие тут другие: сбросить фильтр, а не создать первую запись;
  • раздел ещё не настроен — иконка, заголовок, описание и кнопка вместо инструкции в поддержке;
  • состояние встроено в другой компонент — списки, таблицы и графики показывают его слотом #empty.

Когда взять другое

НужноБерите
Данные грузятсяGrSkeleton / GrLoading
Запрос упалGrResponseErrorBanner
Предупреждение в потоке страницыGrAlert
Нужен просто текст без иллюстрацииGrCard

Пустой экран без объяснения читается как поломка. Разница между «здесь пока ничего нет» и «по этому фильтру ничего не нашлось» — важна: в первом случае предлагают создать, во втором — снять фильтр.

Варианты все тона и виды — настоящим компонентом

variant

  • ghost
  • outlined

Размеры

  • xs
  • sm
  • md
  • lg

Playground контролы выводятся из API, а не пишутся руками

Сцена

Загружается…

0 изменено· состояние — в адресе

Примеры 3 у каждого — живое демо и его код

  • Первый день списка счетов

    Там, где будут строки, пустое состояние предлагает действия, которые их заполнят: кнопки — в слоте по умолчанию, а описание говорит, что будет дальше, а не что список пуст. variant="ghost" — список уже рамка; как только счёт создан, список занимает место пустоты.

    Invoices

    No invoices yet

    Create the first one, or bring last year's from a CSV. Clients get each invoice by email with a payment link.
  • Пустая карточка — хорошая новость

    Внутри карточки size="sm" с variant="ghost" не дают пустоте нарисовать вторую рамку и крупную картинку. Слот icon ставит зелёный щит вместо пустого листа — отсутствие споров и есть ответ, которого ждали, — а heading-level следует за заголовком карточки.

    Recent payments

    Northwind2 min ago€1,284.50
    Contoso1 h ago€432.00
    Fabrikamyesterday€96.00

    Open disputes

    No open disputes

    Chargebacks appear here within an hour of the bank's notice.

API порождается из пакета · разойтись не может

Props

PropTypeпо умолчаниюОписание
variant"ghost" | "outlined" | undefinedundefined`ghost` снимает рамку и фон: карточка внутри карточки рисует вторую рамку.
titlestring | undefinedundefinedЗаголовок. Не задан — берётся из локали; слот `#title` сильнее обоих.
size"xs" | "sm" | "md" | "lg" | undefinedundefinedМасштаб иконки, текста и отступов. По умолчанию `md`; берётся из `GrConfigProvider`.
descriptionstring | undefinedundefinedПояснение под заголовком: почему пусто и что сделать. Слот `#description` сильнее.
headingLevel2 | 3 | 4 | 5 | 6 | undefinedundefinedУровень заголовка (`h2`…`h6`) — под структуру страницы. По умолчанию `3`.
kind"search" | "empty" | undefined"empty"Что за пустота: ещё ничего не создано (`empty`) или под запросом ничего не нашлось (`search`). Меняет иконку и заголовок по умолчанию; заданный `title` сильнее в обоих случаях.

Слоты

SlotTypeОписание
iconanyИконка вместо встроенной.
titleanyЗаголовок разметкой: ссылка, выделение, счётчик.
descriptionanyПояснение разметкой — со ссылкой или выделением; сильнее `description`.
defaultanyДействия под текстом: центрируются.

Типы

Все экспортируемые типы подпути, по файлам, где они объявлены. Имена, дженерики и тела читаются из файлов деклараций пакета и разойтись не могут.

Импорт
import type { GrEmptyStateProps, GrEmptyStateConfigurableProps, GrEmptyStateSize } from '@feugene/granularity/components/GrEmptyState'

Файлdist/types/components/GrEmptyState/GrEmptyState.vue.d.ts

GrEmptyStatePropsinterface

GrEmptyState — карточка пустого состояния: иконка, заголовок, описание и слот действий. Заголовок — настоящий heading: без него пустое состояние не находится навигацией по заголовкам, а именно оно и объясняет, почему на экране ничего нет.

interface GrEmptyStateProps {
    /** Заголовок. Не задан — берётся из локали; слот `#title` сильнее обоих. */
    title?: string;
    /** Пояснение под заголовком: почему пусто и что сделать. Слот `#description` сильнее. */
    description?: string;
    /** Масштаб иконки, текста и отступов. По умолчанию `md`; берётся из `GrConfigProvider`. */
    size?: GrEmptyStateSize;
    /** `ghost` снимает рамку и фон: карточка внутри карточки рисует вторую рамку. */
    variant?: GrEmptyStateVariant;
    /** Уровень заголовка (`h2`…`h6`) — под структуру страницы. По умолчанию `3`. */
    headingLevel?: GrEmptyStateHeadingLevel;
    /**
     * Что за пустота: ещё ничего не создано (`empty`) или под запросом ничего не
     * нашлось (`search`). Меняет иконку и заголовок по умолчанию; заданный
     * `title` сильнее в обоих случаях.
     */
    kind?: GrEmptyStateKind;
}

Файлdist/types/components/GrEmptyState/config.d.ts

grEmptyStateConfigconst
const grEmptyStateConfig: import("@feugene/granum/contract").GranumComponentDescriptor<"GrEmptyState">;

Файлdist/types/components/GrEmptyState/defaults.d.ts

GrEmptyStateConfigurablePropsinterface

Пропы GrEmptyState, настраиваемые глобально через <GrConfigProvider :component-defaults="{ GrEmptyState: { … } }">. Только оформление — см. GrButton/defaults.ts.

interface GrEmptyStateConfigurableProps {
    size: GrEmptyStateSize;
    variant: GrEmptyStateVariant;
    headingLevel: GrEmptyStateHeadingLevel;
}

Файлdist/types/components/GrEmptyState/grEmptyStateStyles.d.ts

GrEmptyStateSizetype
type GrEmptyStateSize = GrComponentSize;
GrEmptyStateVarianttype
type GrEmptyStateVariant = typeof GR_EMPTY_STATE_VARIANTS[number];
GrEmptyStateKindtype
type GrEmptyStateKind = typeof GR_EMPTY_STATE_KINDS[number];
GrEmptyStateHeadingLeveltype
type GrEmptyStateHeadingLevel = typeof GR_EMPTY_STATE_HEADING_LEVELS[number];

Файлdist/types/components/GrEmptyState/safelist.d.ts

grEmptyStateSafelistconst
const grEmptyStateSafelist: string[];

Использование из прозы библиотеки

Две пустоты, а не одна

kind различает то, что пользователь видит по-разному:

kindКогдаЗаголовок и иконка по умолчанию
empty (по умолчанию)ещё ничего не создано«Пока пусто», ящик
searchпод запросом или фильтром ничего не нашлось«Ничего не найдено», лупа с крестом

Разница не косметическая. Под фильтром «Пока пусто» дезинформирует: данные есть, просто не совпали, и следующий шаг у пользователя другой — не «создать», а «ослабить запрос».

Значений ровно два, потому что столько повторяется. Ошибка загрузки сюда не входит намеренно: у неё в пакете свои компоненты — GrResponseErrorBanner.

Описание по умолчанию не подставляется ни в одном из видов: оно всегда про конкретный экран, и угадать его нечем.

Заголовок
vue
<GrEmptyState title="Пока нет выплат" description="Создайте первую выплату, чтобы отслеживать согласования.">
  <GrButton size="sm">Создать выплату</GrButton>
</GrEmptyState>

Заголовок — настоящий heading: без него пустое состояние не находится навигацией по заголовкам, а объясняет происходящее на экране именно оно. Уровень задаётся headingLevel (2…6, по умолчанию 3) и настраивается глобально через componentDefaults.GrEmptyState.headingLevel. h1 в наборе нет намеренно: пустое состояние живёт внутри уже существующей структуры страницы, а не задаёт её.

title необязателен: без него и без слота берётся строка из локали (gr.emptyState.title), так что <GrEmptyState /> не превращается в пустую карточку.

Слоты
СлотЗачем
titleзаголовок разметкой: ссылка, выделение, счётчик
descriptionописание разметкой
iconсвоя иконка вместо встроенной lucide/inbox
по умолчаниюдействия под текстом, центрируются

Слот сильнее одноимённого пропа. Встроенная иконка декоративна (aria-hidden) — смысл несёт текст.

Поверхность
vue
<GrCard>
  <GrEmptyState variant="ghost" title="Никого не пригласили" />
</GrCard>

variant (outlined по умолчанию, ghost) повторяет словарь GrCard: ghost снимает рамку, фон и радиус. Он нужен внутри уже существующей карточки — в GrDataTable #empty, GrList #empty или в своём макете, где outlined даёт вторую рамку вокруг той же поверхности.

Размер

size (xs…lg, по умолчанию md, читается из GrConfigProvider) двигает падинг карточки, коробку иконки, саму иконку, кегль заголовка и вертикальные отступы. xs и sm — для пустой ячейки таблицы и панели дропдауна, где полноразмерное состояние занимает весь список.

Оформление

Всё берётся из токенов: радиус — --gr-radius-md/--gr-radius-lg по ступени, кегли — --gr-text-xs/--gr-text-sm/--gr-text-base, цвета — --gr-card, --gr-brd, --gr-muted, --gr-muted-fg.