feat(Stat): Label wrapper for statistics
This commit is contained in:
136
src/shared/ui/Stat/Stat.stories.svelte
Normal file
136
src/shared/ui/Stat/Stat.stories.svelte
Normal file
@@ -0,0 +1,136 @@
|
||||
<script module>
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import Stat from './Stat.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Shared/Stat',
|
||||
component: Stat,
|
||||
tags: ['autodocs'],
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: 'A single key:value pair in Space Mono. Optional trailing divider.',
|
||||
},
|
||||
story: { inline: false },
|
||||
},
|
||||
layout: 'centered',
|
||||
},
|
||||
argTypes: {
|
||||
label: {
|
||||
control: 'text',
|
||||
description: 'Stat label/key',
|
||||
defaultValue: 'Label',
|
||||
},
|
||||
value: {
|
||||
control: 'text',
|
||||
description: 'Stat value',
|
||||
defaultValue: 'Value',
|
||||
},
|
||||
variant: {
|
||||
control: 'select',
|
||||
options: ['default', 'accent', 'muted', 'success', 'warning', 'error'],
|
||||
description: 'Value variant',
|
||||
defaultValue: 'default',
|
||||
},
|
||||
separator: {
|
||||
control: 'boolean',
|
||||
description: 'Show trailing divider',
|
||||
defaultValue: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<Story
|
||||
name="Default/Basic"
|
||||
args={{ label: 'Label', value: 'Value' }}
|
||||
parameters={{ docs: { description: { story: 'Standard stat with label and value' } } }}
|
||||
>
|
||||
{#snippet template()}
|
||||
<Stat label="Label" value="Value" />
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="With string value"
|
||||
args={{ label: 'Font', value: 'Inter' }}
|
||||
>
|
||||
{#snippet template()}
|
||||
<Stat label="Font" value="Inter" />
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="With number value"
|
||||
args={{ label: 'Weight', value: 400 }}
|
||||
>
|
||||
{#snippet template()}
|
||||
<Stat label="Weight" value={400} />
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="With separator"
|
||||
args={{ label: 'Size', value: '16px', separator: true }}
|
||||
>
|
||||
{#snippet template()}
|
||||
<div class="flex items-center">
|
||||
<Stat label="Size" value="16px" separator />
|
||||
<Stat label="Line" value="1.5" />
|
||||
</div>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Default variant"
|
||||
args={{ variant: 'default', label: 'Status', value: 'Active' }}
|
||||
>
|
||||
{#snippet template()}
|
||||
<Stat label="Status" value="Active" variant="default" />
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Accent variant"
|
||||
args={{ variant: 'accent', label: 'Status', value: 'Active' }}
|
||||
>
|
||||
{#snippet template()}
|
||||
<Stat label="Status" value="Active" variant="accent" />
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Muted variant"
|
||||
args={{ variant: 'muted', label: 'Status', value: 'Inactive' }}
|
||||
>
|
||||
{#snippet template()}
|
||||
<Stat label="Status" value="Inactive" variant="muted" />
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Success variant"
|
||||
args={{ variant: 'success', label: 'Status', value: 'Success' }}
|
||||
>
|
||||
{#snippet template()}
|
||||
<Stat label="Status" value="Success" variant="success" />
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Warning variant"
|
||||
args={{ variant: 'warning', label: 'Status', value: 'Warning' }}
|
||||
>
|
||||
{#snippet template()}
|
||||
<Stat label="Status" value="Warning" variant="warning" />
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Error variant"
|
||||
args={{ variant: 'error', label: 'Status', value: 'Error' }}
|
||||
>
|
||||
{#snippet template()}
|
||||
<Stat label="Status" value="Error" variant="error" />
|
||||
{/snippet}
|
||||
</Story>
|
||||
34
src/shared/ui/Stat/Stat.svelte
Normal file
34
src/shared/ui/Stat/Stat.svelte
Normal file
@@ -0,0 +1,34 @@
|
||||
<!--
|
||||
Component: Stat
|
||||
A single key:value pair in Space Mono. Optional trailing divider.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { cn } from '$shared/shadcn/utils/shadcn-utils';
|
||||
import { Label } from '$shared/ui';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
|
||||
interface Props extends Pick<ComponentProps<typeof Label>, 'variant'> {
|
||||
label: string;
|
||||
value: string | number;
|
||||
/** Renders a 1px vertical divider after the stat. */
|
||||
separator?: boolean;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
let {
|
||||
label,
|
||||
value,
|
||||
variant = 'default',
|
||||
separator = false,
|
||||
class: className,
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<div class={cn('flex items-center gap-1', className)}>
|
||||
<Label variant="muted" size="xs">{label}:</Label>
|
||||
<Label {variant} size="xs" bold>{value}</Label>
|
||||
</div>
|
||||
|
||||
{#if separator}
|
||||
<div class="w-px h-2 bg-black/10 dark:bg-white/10"></div>
|
||||
{/if}
|
||||
Reference in New Issue
Block a user