Skip to content
tcpsystemsui

Theme

Colour scheme
Accent
Density
Radius
Esc

SaveStatus

Inline save indicator showing idle, saving, saved, or error state.

beta

Examples

Autosave

Autosave.svelte
<script lang="ts">
	import SaveStatus from '@tcpsystems/ui/foundation/SaveStatus';
	import Button from '@tcpsystems/ui/foundation/Button';
	import Cluster from '@tcpsystems/ui/foundation/Cluster';
	let state = $state<'idle' | 'saving' | 'saved'>('idle');
	const save = () => {
		state = 'saving';
		setTimeout(() => (state = 'saved'), 900);
	};
</script>

<Cluster>
	<Button variant="primary" loading={state === 'saving'} loadingLabel="Saving" onclick={save}>Save draft</Button>
	<SaveStatus {state} savedAt={state === 'saved' ? 'just now' : undefined} />
</Cluster>

States

Saving... Saved 12:04 Not saved
States.svelte
<script lang="ts">
	import SaveStatus from '@tcpsystems/ui/foundation/SaveStatus';
	import Stack from '@tcpsystems/ui/foundation/Stack';
</script>

<Stack gap="sm">
	<SaveStatus state="idle" />
	<SaveStatus state="saving" />
	<SaveStatus state="saved" savedAt="12:04" />
	<SaveStatus state="error" />
</Stack>

Retry

Not saved
Retry.svelte
<script lang="ts">
	import SaveStatus from '@tcpsystems/ui/foundation/SaveStatus';
	import Button from '@tcpsystems/ui/foundation/Button';
	let state = $state<'saving' | 'saved' | 'error'>('error');
	const retry = () => {
		state = 'saving';
		setTimeout(() => (state = 'saved'), 900);
	};
</script>

<SaveStatus {state} savedAt={state === 'saved' ? '13:20' : undefined}>
	{#snippet retry()}
		<Button size="sm" variant="ghost" onclick={retry}>Retry</Button>
	{/snippet}
</SaveStatus>

API

Import
import SaveStatus from '@tcpsystems/ui/foundation/SaveStatus';
PropTypeDefault
state'idle' | 'saving' | 'saved' | 'error'none
savedAt?stringnone
Snippet
retry
HookKind
.tcp-save-statusRoot class
data-stateData attribute