Skip to content
tcpsystemsui

Theme

Colour scheme
Accent
Density
Radius
Esc

EmptyState

First-use, filtered, error, forbidden and unavailable states.

beta

Examples

First use

No projects yet

Create a project to deploy your first service.

First use.svelte
<script lang="ts">
	import EmptyState from '@tcpsystems/ui/foundation/EmptyState';
	import Button from '@tcpsystems/ui/foundation/Button';
	import Banner from '@tcpsystems/ui/foundation/Banner';
	import Stack from '@tcpsystems/ui/foundation/Stack';
	let created = $state(false);
</script>

<Stack gap="sm">
	<EmptyState title="No projects yet" text="Create a project to deploy your first service.">
		{#snippet actions()}
			<Button variant="primary" icon="plus" onclick={() => (created = true)}>New project</Button>
			<Button href="/components/">Read the setup guide</Button>
		{/snippet}
	</EmptyState>
	{#if created}<Banner mode="notice" tone="ok">payments-api is provisioning.</Banner>{/if}
</Stack>

Filtered

No deployments match “payments”

Check the spelling or clear the search.

Filtered.svelte
<script lang="ts">
	import EmptyState from '@tcpsystems/ui/foundation/EmptyState';
	import Button from '@tcpsystems/ui/foundation/Button';
	import Input from '@tcpsystems/ui/foundation/Input';
	import Stack from '@tcpsystems/ui/foundation/Stack';
	import Text from '@tcpsystems/ui/foundation/Text';
	const deployments = ['api-gateway', 'worker-pool', 'scheduler'];
	let q = $state('payments');
	const matches = $derived(deployments.filter((d) => d.includes(q.toLowerCase())));
</script>

<Stack gap="sm">
	<Input type="search" bind:value={q} placeholder="Search deployments" aria-label="Search deployments" />
	{#if matches.length}
		<Stack gap="sm">{#each matches as d (d)}<Text>{d}</Text>{/each}</Stack>
	{:else}
		<EmptyState kind="filtered" title="No deployments match “{q}”" text="Check the spelling or clear the search.">
			{#snippet actions()}<Button onclick={() => (q = '')}>Clear search</Button>{/snippet}
		</EmptyState>
	{/if}
</Stack>

Error states

503

Deployments are unavailable

The deployment service did not respond. Try again in a moment.

You need the deploy role

Ask a workspace owner to grant access to this project.

Region eu-west is offline

Deployments stay paused until the region recovers.

Error states.svelte
<script lang="ts">
	import EmptyState from '@tcpsystems/ui/foundation/EmptyState';
	import Button from '@tcpsystems/ui/foundation/Button';
	import Stack from '@tcpsystems/ui/foundation/Stack';
	let retried = $state(false);
</script>

<Stack gap="lg">
	<EmptyState kind="error" code="503" title="Deployments are unavailable" text="The deployment service did not respond. Try again in a moment.">
		{#snippet actions()}
			<Button onclick={() => (retried = true)}>{retried ? 'Retry requested' : 'Try again'}</Button>
		{/snippet}
	</EmptyState>
	<EmptyState kind="forbidden" title="You need the deploy role" text="Ask a workspace owner to grant access to this project." />
	<EmptyState kind="unavailable" title="Region eu-west is offline" text="Deployments stay paused until the region recovers." />
</Stack>

API

Import
import EmptyState from '@tcpsystems/ui/foundation/EmptyState';
PropTypeDefault
mode?'empty' | 'result''empty'
kind?Kind'first-use'
titlestringnone
text?stringnone
code?stringnone
requestId?stringnone
as?'h1' | 'h2' | 'h3'none
Snippet
actions
HookKind
.tcp-resultRoot class
data-kindData attribute