mcpbeat

Component Library Patterns

vibeeval/component-library-patterns

Design system token management, component API design, Storybook, and visual regression testing patterns

764 tokens
context cost
the whole folder, loaded on every use
1
files
instructions only
0
copies elsewhere
how many repositories repackaged it
521
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/vibeeval/vibecosystem --skill component-library-patterns

The instruction itself

8 sections, as written by the author

Component Library Patterns

Design Tokens

// tokens.ts - Single source of truth
export const tokens = {
  color: {
    primary: { 50: '#eff6ff', 500: '#3b82f6', 900: '#1e3a5f' },
    semantic: { success: '#22c55e', error: '#ef4444', warning: '#f59e0b' }
  },
  spacing: { xs: '4px', sm: '8px', md: '16px', lg: '24px', xl: '32px' },
  font: {
    size: { sm: '0.875rem', base: '1rem', lg: '1.125rem', xl: '1.25rem' },
    weight: { normal: 400, medium: 500, semibold: 600, bold: 700 }
  },
  radius: { sm: '4px', md: '8px', lg: '12px', full: '9999px' },
  shadow: {
    sm: '0 1px 2px rgba(0,0,0,0.05)',
    md: '0 4px 6px rgba(0,0,0,0.1)'
  }
} as const

Component API Design

// Composition pattern > prop explosion
// YANLIS:
<Button icon="check" iconPosition="left" loading loadingText="..." />

// DOGRU:
<Button>
  <Button.Icon><CheckIcon /></Button.Icon>
  <Button.Text>Save</Button.Text>
  <Button.Spinner />
</Button>

// Polymorphic component
interface ButtonProps<T extends ElementType = 'button'> {
  as?: T
  variant: 'primary' | 'secondary' | 'ghost'
  size: 'sm' | 'md' | 'lg'
}

Storybook Patterns

// Component.stories.tsx
const meta: Meta<typeof Button> = {
  component: Button,
  argTypes: {
    variant: { control: 'select', options: ['primary', 'secondary'] },
    size: { control: 'radio', options: ['sm', 'md', 'lg'] }
  }
}

export const Playground: Story = { args: { variant: 'primary', children: 'Click' } }
export const AllVariants: Story = {
  render: () => (
    <div style={{ display: 'flex', gap: 8 }}>
      {(['primary', 'secondary', 'ghost'] as const).map(v => (
        <Button key={v} variant={v}>{v}</Button>
      ))}
    </div>
  )
}

Visual Regression Testing

// Chromatic veya Percy ile
test('Button variants match snapshot', async ({ page }) => {
  await page.goto('/iframe.html?id=button--all-variants')
  await expect(page).toHaveScreenshot('button-variants.png', {
    maxDiffPixelRatio: 0.01
  })
})

Theming

/* CSS Custom Properties */
:root {
  --color-primary: #3b82f6;
  --color-bg: #ffffff;
  --color-text: #1f2937;
}

[data-theme="dark"] {
  --color-primary: #60a5fa;
  --color-bg: #111827;
  --color-text: #f9fafb;
}

Checklist

  • [ ] Design tokens single source of truth
  • [ ] Component API composition-based (slot pattern)
  • [ ] Her component'te Storybook story var
  • [ ] Visual regression test aktif
  • [ ] Accessibility: keyboard nav + ARIA + contrast
  • [ ] Theming: CSS variables ile dark/light
  • [ ] Semantic versioning + CHANGELOG
  • [ ] Prop documentation (JSDoc veya MDX)
  • [ ] Bundle size per-component tracked

Anti-Patterns

  • Prop explosion (10+ prop → composition kullan)
  • Token'sız hardcoded değerler
  • Component'te global CSS
  • Story'siz component
  • Theme switch'te flash (FOUC)
  • Circular dependency between components

How to use it

Copy the folder

Take vibeeval/component-library-patterns from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.