From ac2eb6ba0bf83299292f107016c84bd16918cd82 Mon Sep 17 00:00:00 2001 From: Ilia Mashkov Date: Fri, 6 Mar 2026 23:13:43 +0300 Subject: [PATCH] feat(shared/ui): add Badge component with brutalist variants and Storybook story --- src/shared/ui/Badge/Badge.stories.svelte | 55 ++++++++++++++++++++++++ src/shared/ui/Badge/Badge.svelte | 37 ++++++++++++++++ src/shared/ui/Badge/Badge.test.ts | 20 +++++++++ src/shared/ui/Badge/index.ts | 2 + src/shared/ui/Badge/types.ts | 1 + 5 files changed, 115 insertions(+) create mode 100644 src/shared/ui/Badge/Badge.stories.svelte create mode 100644 src/shared/ui/Badge/Badge.svelte create mode 100644 src/shared/ui/Badge/Badge.test.ts create mode 100644 src/shared/ui/Badge/index.ts create mode 100644 src/shared/ui/Badge/types.ts diff --git a/src/shared/ui/Badge/Badge.stories.svelte b/src/shared/ui/Badge/Badge.stories.svelte new file mode 100644 index 0000000..8da64df --- /dev/null +++ b/src/shared/ui/Badge/Badge.stories.svelte @@ -0,0 +1,55 @@ + + + + {#snippet template(args)} + Tag + {/snippet} + + + + {#snippet template(args)} + Primary + {/snippet} + + + + {#snippet template(args)} + Secondary + {/snippet} + + + + {#snippet template(args)} + Outline + {/snippet} + + + + {#snippet template()} +
+ Default + Primary + Secondary + Outline +
+ {/snippet} +
diff --git a/src/shared/ui/Badge/Badge.svelte b/src/shared/ui/Badge/Badge.svelte new file mode 100644 index 0000000..f11717a --- /dev/null +++ b/src/shared/ui/Badge/Badge.svelte @@ -0,0 +1,37 @@ + + + + + {#if children} + {@render children()} + {/if} + diff --git a/src/shared/ui/Badge/Badge.test.ts b/src/shared/ui/Badge/Badge.test.ts new file mode 100644 index 0000000..c914755 --- /dev/null +++ b/src/shared/ui/Badge/Badge.test.ts @@ -0,0 +1,20 @@ +import { render } from '@testing-library/svelte'; +import { describe, expect, it } from 'vitest'; +import Badge from './Badge.svelte'; + +describe('Badge', () => { + it('renders children text', () => { + const { getByText } = render(Badge, { props: { children: 'hello' } }); + expect(getByText('hello')).toBeTruthy(); + }); + + it('applies default variant class', () => { + const { container } = render(Badge, { props: { variant: 'default' } }); + expect(container.querySelector('span')?.className).toContain('bg-carbon-black'); + }); + + it('applies primary variant class', () => { + const { container } = render(Badge, { props: { variant: 'primary' } }); + expect(container.querySelector('span')?.className).toContain('bg-burnt-oxide'); + }); +}); diff --git a/src/shared/ui/Badge/index.ts b/src/shared/ui/Badge/index.ts new file mode 100644 index 0000000..f5b5cee --- /dev/null +++ b/src/shared/ui/Badge/index.ts @@ -0,0 +1,2 @@ +export { default as Badge } from './Badge.svelte'; +export type { BadgeVariant } from './types'; diff --git a/src/shared/ui/Badge/types.ts b/src/shared/ui/Badge/types.ts new file mode 100644 index 0000000..abec614 --- /dev/null +++ b/src/shared/ui/Badge/types.ts @@ -0,0 +1 @@ +export type BadgeVariant = 'default' | 'primary' | 'secondary' | 'outline';