Skip to content

EmptyState ​

A compact "nothing found" placeholder with an optional action button. Useful for empty lists/tabs (with compact) and full-page "no results" states.

vue
<script setup lang="ts">
import RyderEmptyState from "@opeolluwa/ryder/components/feedback/EmptyState.vue"
</script>

<template>
  <RyderEmptyState
    title="Nothing matched"
    description="Adjust the filters and try again."
    action-label="Clear filters"
    @action="clear"
  />
</template>

Examples ​

vue
<script setup lang="ts">
import { ref } from "vue";
import EmptyState from "../../../src/components/feedback/EmptyState.vue";

const actionCount = ref(0);

function onAction() {
  actionCount.value += 1;
}
</script>

<template>
  <div class="space-y-3">
    <EmptyState
      icon="heroicons:magnifying-glass"
      title="Nothing matched"
      description="Adjust the filters and try again."
      action-label="Clear filters"
      @action="onAction"
    />

    <p class="text-center text-xs text-gray-400 dark:text-white/30">
      <code class="font-mono">action</code> emitted {{ actionCount }} time(s).
    </p>
  </div>
</template>

compact reduces the height from h-[60vh] to h-56 (use inside a panel):

vue
<script setup lang="ts">
import { ref } from "vue";
import EmptyState from "../../../src/components/feedback/EmptyState.vue";

const status = ref("");
</script>

<template>
  <div class="space-y-3">
    <EmptyState
      compact
      icon="heroicons:chat-bubble-left-right"
      title="No replies yet"
      description="Replies from your team show up here."
      action-label="Start a reply"
      :ui="{
        root: 'rounded-xl border border-dashed border-gray-200 dark:border-white/10',
        iconWrapper: 'ring-1 ring-primary-300/70',
        description: 'font-medium',
      }"
      @action="status = 'action emitted'"
    />

    <p class="text-center text-xs text-gray-400 dark:text-white/30">
      Last event: {{ status || "—" }}
    </p>
  </div>
</template>

Props ​

PropTypeDefaultDescription
titlestring—Required; heading text.
descriptionstring—Required; explanatory text.
iconstring"heroicons:users"Icon name rendered by Nuxt UI's UIcon.
actionLabelstring | undefinedundefinedWhen present, a RyderButton appears and emits action.
compactbooleanfalseIf true, h-56; else h-[60vh].
ui{ root?: string; title?: string; description?: string; iconWrapper?: string; icon?: string; actionLabel?: string }{}Class-concat map merged onto each element of the block.

Emits ​

EventPayloadWhen
action—The action button was tapped.

Slots ​

None.

Notes ​

  • title and description are required — rendering a label-less empty state would be confusing for screen readers.
  • The ui prop is a concatenation, not an override: a class that collides with the internal classes resolves by stylesheet order, so use the ! modifier to win. Within ui, icon is the glyph and iconWrapper the tinted square behind it — usually restyled together, and the square carries the tint.