feature/project-redesign #28

Merged
ilia merged 88 commits from feature/project-redesign into main 2026-03-02 19:46:39 +00:00
2 changed files with 125 additions and 0 deletions
Showing only changes of commit 089dc73abe - Show all commits

View File

@@ -0,0 +1,80 @@
<script module>
import { defineMeta } from '@storybook/addon-svelte-csf';
import StatusIndicator from './StatusIndicator.svelte';
const { Story } = defineMeta({
title: 'Shared/StatusIndicator',
component: StatusIndicator,
tags: ['autodocs'],
parameters: {
docs: {
description: {
component: 'Coloured dot with optional label. Dot can pulse for live states.',
},
story: { inline: false },
},
layout: 'centered',
},
argTypes: {
status: {
control: 'select',
options: ['active', 'inactive', 'warning', 'error'],
description: 'Status type',
},
label: {
control: 'text',
description: 'Optional label text',
},
pulse: {
control: 'boolean',
description: 'Enable pulsing animation',
defaultValue: false,
},
},
});
</script>
<Story
name="Active status"
args={{ status: 'active', label: 'Active' }}
>
{#snippet template()}
<StatusIndicator status="active" label="Active" />
{/snippet}
</Story>
<Story
name="Inactive status"
args={{ status: 'inactive', label: 'Inactive' }}
>
{#snippet template()}
<StatusIndicator status="inactive" label="Inactive" />
{/snippet}
</Story>
<Story
name="Warning status"
args={{ status: 'warning', label: 'Warning' }}
>
{#snippet template()}
<StatusIndicator status="warning" label="Warning" />
{/snippet}
</Story>
<Story
name="Error status"
args={{ status: 'error', label: 'Error' }}
>
{#snippet template()}
<StatusIndicator status="error" label="Error" />
{/snippet}
</Story>
<Story
name="With pulse"
args={{ status: 'active', label: 'Connected', pulse: true }}
>
{#snippet template()}
<StatusIndicator status="active" label="Connected" pulse={true} />
{/snippet}
</Story>

View File

@@ -0,0 +1,45 @@
<!--
Component: StatusIndicator
Coloured dot with optional label. Dot can pulse for live states.
-->
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils';
import { Label } from '$shared/ui';
type Status = 'active' | 'inactive' | 'warning' | 'error';
const statusConfig: Record<Status, string> = {
active: 'bg-green-500',
inactive: 'bg-neutral-400',
warning: 'bg-yellow-500',
error: 'bg-brand',
};
interface Props {
status: Status;
label?: string;
pulse?: boolean;
class?: string;
}
let {
status,
label,
pulse = false,
class: className,
}: Props = $props();
</script>
<div class={cn('flex items-center gap-2', className)}>
<span
class={cn(
'w-1.5 h-1.5 rounded-full',
statusConfig[status],
pulse && 'animate-pulse',
)}
></span>
{#if label}
<Label variant="muted" size="xs">{label}</Label>
{/if}
</div>