feature/project-redesign #28
213
src/shared/ui/Label/Label.stories.svelte
Normal file
213
src/shared/ui/Label/Label.stories.svelte
Normal file
@@ -0,0 +1,213 @@
|
||||
<script module>
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import Label from './Label.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Shared/Label',
|
||||
component: Label,
|
||||
tags: ['autodocs'],
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: 'Inline monospace label. The base primitive for all micrographic text.',
|
||||
},
|
||||
story: { inline: false },
|
||||
},
|
||||
layout: 'centered',
|
||||
},
|
||||
argTypes: {
|
||||
variant: {
|
||||
control: 'select',
|
||||
options: ['default', 'accent', 'muted', 'success', 'warning', 'error'],
|
||||
defaultValue: 'default',
|
||||
},
|
||||
size: {
|
||||
control: 'select',
|
||||
options: ['xs', 'sm', 'md'],
|
||||
defaultValue: 'sm',
|
||||
},
|
||||
uppercase: {
|
||||
control: 'boolean',
|
||||
defaultValue: true,
|
||||
},
|
||||
bold: {
|
||||
control: 'boolean',
|
||||
defaultValue: false,
|
||||
},
|
||||
iconPosition: {
|
||||
control: 'select',
|
||||
options: ['left', 'right'],
|
||||
defaultValue: 'left',
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import AlertTriangleIcon from '@lucide/svelte/icons/alert-triangle';
|
||||
import CheckIcon from '@lucide/svelte/icons/check';
|
||||
import CircleIcon from '@lucide/svelte/icons/circle';
|
||||
</script>
|
||||
|
||||
<Story
|
||||
name="Default/Basic"
|
||||
parameters={{ docs: { description: { story: 'Standard label with default styling' } } }}
|
||||
>
|
||||
{#snippet template(args)}
|
||||
<Label {...args}>Default Label</Label>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story name="All sizes">
|
||||
{#snippet template()}
|
||||
<div class="flex flex-col gap-4">
|
||||
<Label size="xs">Size XS Label</Label>
|
||||
<Label size="sm">Size SM Label</Label>
|
||||
<Label size="md">Size MD Label</Label>
|
||||
</div>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Default variant"
|
||||
args={{ variant: 'default', size: 'sm' }}
|
||||
>
|
||||
{#snippet template(args)}
|
||||
<Label {...args}>Default Label</Label>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Accent variant"
|
||||
args={{ variant: 'accent', size: 'sm' }}
|
||||
>
|
||||
{#snippet template(args)}
|
||||
<Label {...args}>Accent Label</Label>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Muted variant"
|
||||
args={{ variant: 'muted', size: 'sm' }}
|
||||
>
|
||||
{#snippet template(args)}
|
||||
<Label {...args}>Muted Label</Label>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Success variant"
|
||||
args={{ variant: 'success', size: 'sm' }}
|
||||
>
|
||||
{#snippet template(args)}
|
||||
<Label {...args}>Success Label</Label>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Warning variant"
|
||||
args={{ variant: 'warning', size: 'sm' }}
|
||||
>
|
||||
{#snippet template(args)}
|
||||
<Label {...args}>Warning Label</Label>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Error variant"
|
||||
args={{ variant: 'error', size: 'sm' }}
|
||||
>
|
||||
{#snippet template(args)}
|
||||
<Label {...args}>Error Label</Label>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story name="All variants">
|
||||
{#snippet template()}
|
||||
<div class="flex flex-col gap-4">
|
||||
<Label variant="default">Default</Label>
|
||||
<Label variant="accent">Accent</Label>
|
||||
<Label variant="muted">Muted</Label>
|
||||
<Label variant="success">Success</Label>
|
||||
<Label variant="warning">Warning</Label>
|
||||
<Label variant="error">Error</Label>
|
||||
</div>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Uppercase"
|
||||
args={{ uppercase: true, size: 'sm' }}
|
||||
>
|
||||
{#snippet template(args)}
|
||||
<Label {...args}>Uppercase Label</Label>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Lowercase"
|
||||
args={{ uppercase: false, size: 'sm' }}
|
||||
>
|
||||
{#snippet template(args)}
|
||||
<Label {...args}>lowercase label</Label>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="Bold"
|
||||
args={{ bold: true, size: 'sm' }}
|
||||
>
|
||||
{#snippet template(args)}
|
||||
<Label {...args}>Bold Label</Label>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="With icon (left)"
|
||||
args={{ variant: 'default', size: 'sm', iconPosition: 'left' }}
|
||||
>
|
||||
{#snippet template(args)}
|
||||
<Label {...args}>
|
||||
{#snippet icon()}
|
||||
<CircleIcon size={10} />
|
||||
{/snippet}
|
||||
Label with icon
|
||||
</Label>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="With icon (right)"
|
||||
args={{ variant: 'default', size: 'sm', iconPosition: 'right' }}
|
||||
>
|
||||
{#snippet template(args)}
|
||||
<Label {...args}>
|
||||
Label with icon
|
||||
{#snippet icon()}
|
||||
<CircleIcon size={10} />
|
||||
{/snippet}
|
||||
</Label>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story name="Success with check icon">
|
||||
{#snippet template()}
|
||||
<Label variant="success" size="sm">
|
||||
{#snippet icon()}
|
||||
<CheckIcon size={10} />
|
||||
{/snippet}
|
||||
Completed
|
||||
</Label>
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story name="Warning with alert icon">
|
||||
{#snippet template()}
|
||||
<Label variant="warning" size="sm">
|
||||
{#snippet icon()}
|
||||
<AlertTriangleIcon size={10} />
|
||||
{/snippet}
|
||||
Attention Required
|
||||
</Label>
|
||||
{/snippet}
|
||||
</Story>
|
||||
@@ -1,45 +1,60 @@
|
||||
<!--
|
||||
Component: Label
|
||||
Inline monospace label. The base primitive for all micrographic text.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { cn } from '$shared/shadcn/utils/shadcn-utils';
|
||||
import type { Snippet } from 'svelte';
|
||||
import {
|
||||
type LabelSize,
|
||||
type LabelVariant,
|
||||
labelSizeConfig,
|
||||
labelVariantConfig,
|
||||
} from './config';
|
||||
|
||||
interface Props {
|
||||
text?: string;
|
||||
align?: 'left' | 'right' | 'center';
|
||||
size?: 'sm' | 'md' | 'lg';
|
||||
onlyText?: boolean;
|
||||
variant?: LabelVariant;
|
||||
size?: LabelSize;
|
||||
uppercase?: boolean;
|
||||
bold?: boolean;
|
||||
icon?: Snippet;
|
||||
iconPosition?: 'left' | 'right';
|
||||
children?: Snippet;
|
||||
class?: string;
|
||||
}
|
||||
const {
|
||||
text,
|
||||
align = 'left',
|
||||
size = 'md',
|
||||
onlyText = false,
|
||||
|
||||
let {
|
||||
variant = 'default',
|
||||
size = 'sm',
|
||||
uppercase = true,
|
||||
bold = false,
|
||||
icon,
|
||||
iconPosition = 'left',
|
||||
children,
|
||||
class: className,
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
<span
|
||||
class={cn(
|
||||
'grid grid-rows-1 gap-2 items-center w-auto',
|
||||
align === 'left' && 'grid-cols-[max-content_1fr]',
|
||||
align === 'center' && 'grid-cols-[1fr_max-content_1fr]',
|
||||
align === 'right' && 'grig-cols-[1fr_max-content]',
|
||||
"font-['Space_Mono'] tracking-widest leading-none",
|
||||
'inline-flex items-center gap-1.5',
|
||||
labelSizeConfig[size],
|
||||
labelVariantConfig[variant],
|
||||
uppercase && 'uppercase',
|
||||
bold && 'font-bold',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{#if align !== 'left'}
|
||||
<div class={cn('h-px w-full bg-gray-400/50', onlyText && 'bg-transparent')}></div>
|
||||
{#if icon && iconPosition === 'left'}
|
||||
<span class="inline-flex">{@render icon()}</span>
|
||||
{/if}
|
||||
<div
|
||||
class={cn(
|
||||
'text-gray-400 uppercase',
|
||||
size === 'sm' && 'text-[0.5rem]',
|
||||
size === 'md' && 'text-[0.625rem]',
|
||||
size === 'lg' && 'text-[0.75rem]',
|
||||
)}
|
||||
>
|
||||
{text}
|
||||
</div>
|
||||
{#if align !== 'right'}
|
||||
<div class={cn('h-px w-full bg-gray-400/50', onlyText && 'bg-transparent')}></div>
|
||||
|
||||
{#if children}
|
||||
<span>{@render children()}</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if icon && iconPosition === 'right'}
|
||||
<span class="inline-flex">{@render icon()}</span>
|
||||
{/if}
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user