Claude Code Plugins

Community-maintained marketplace

Feedback

React component patterns with Ark UI, forwardRef, and TypeScript for the design system

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name component-patterns
description React component patterns with Ark UI, forwardRef, and TypeScript for the design system

Component Patterns

When to Use This Skill

  • Creating a new component
  • Wrapping Ark UI primitives
  • Setting up TypeScript types for variants
  • Understanding the component → recipe relationship

Standard Component Structure

src/components/Button/
├── Button.tsx           # Component implementation
├── Button.stories.tsx   # Storybook stories
└── index.ts             # Barrel export

Component Template

// src/components/Button/Button.tsx
import { forwardRef } from 'react';
import { Button as ArkButton } from '@ark-ui/react';
import { button, type ButtonVariantProps } from 'styled-system/recipes';
import { cx } from 'styled-system/css';

export interface ButtonProps
  extends React.ComponentPropsWithoutRef<typeof ArkButton>,
          ButtonVariantProps {
  /** Optional left icon */
  leftIcon?: React.ReactNode;
  /** Optional right icon */
  rightIcon?: React.ReactNode;
}

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  (
    {
      variant,
      size,
      leftIcon,
      rightIcon,
      className,
      children,
      ...props
    },
    ref
  ) => {
    return (
      <ArkButton
        ref={ref}
        className={cx(button({ variant, size }), className)}
        {...props}
      >
        {leftIcon}
        {children}
        {rightIcon}
      </ArkButton>
    );
  }
);

Button.displayName = 'Button';

Barrel Export Pattern

// src/components/Button/index.ts
export { Button } from './Button';
export type { ButtonProps } from './Button';

// src/components/index.ts
export * from './Button';
export * from './Card';
export * from './Dialog';

Ark UI Component Patterns

Simple Components (Button, Card)

import { Button as ArkButton } from '@ark-ui/react';

// Ark Button is a simple primitive, just wrap and style
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  (props, ref) => (
    <ArkButton ref={ref} className={button(props)} {...props} />
  )
);

Compound Components (Dialog, Menu)

import { Dialog as ArkDialog } from '@ark-ui/react';

// Ark Dialog is compound - has Trigger, Content, etc.
export const Dialog = {
  Root: ArkDialog.Root,
  Trigger: forwardRef<HTMLButtonElement, DialogTriggerProps>(
    ({ className, ...props }, ref) => (
      <ArkDialog.Trigger
        ref={ref}
        className={cx(dialogTrigger(), className)}
        {...props}
      />
    )
  ),
  Content: forwardRef<HTMLDivElement, DialogContentProps>(
    ({ className, ...props }, ref) => (
      <ArkDialog.Positioner>
        <ArkDialog.Content
          ref={ref}
          className={cx(dialogContent(), className)}
          {...props}
        />
      </ArkDialog.Positioner>
    )
  ),
  // ... other parts
};

TypeScript Patterns

Variant Props from Recipe

import type { ButtonVariantProps } from 'styled-system/recipes';

// ButtonVariantProps is auto-generated by Panda CSS
// It includes: { variant?: 'filled' | 'outlined' | ... ; size?: 'sm' | 'md' | 'lg' }

Polymorphic Components (as prop)

// For components that can render as different elements
type AsProps<T extends React.ElementType> = {
  as?: T;
};

type PolymorphicProps<T extends React.ElementType, Props = {}> = 
  Props & AsProps<T> & Omit<React.ComponentPropsWithoutRef<T>, keyof Props | 'as'>;

Ref Forwarding with generics

// When the element type can change
const Card = forwardRef(
  <T extends React.ElementType = 'div'>(
    { as, ...props }: CardProps<T>,
    ref: React.ForwardedRef<Element>
  ) => {
    const Component = as || 'div';
    return <Component ref={ref} {...props} />;
  }
) as <T extends React.ElementType = 'div'>(
  props: CardProps<T> & { ref?: React.ForwardedRef<Element> }
) => React.ReactElement;

Storybook Stories Pattern

// src/components/Button/Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';

const meta: Meta<typeof Button> = {
  title: 'Components/Button',
  component: Button,
  tags: ['autodocs'],
  argTypes: {
    variant: {
      control: 'select',
      options: ['filled', 'outlined', 'text', 'elevated', 'tonal'],
    },
    size: {
      control: 'select',
      options: ['sm', 'md', 'lg'],
    },
  },
};

export default meta;
type Story = StoryObj<typeof Button>;

export const Filled: Story = {
  args: {
    children: 'Button',
    variant: 'filled',
  },
};

export const Outlined: Story = {
  args: {
    children: 'Button',
    variant: 'outlined',
  },
};

// Story for all variants
export const AllVariants: Story = {
  render: () => (
    <div style={{ display: 'flex', gap: '1rem', flexWrap: 'wrap' }}>
      <Button variant="filled">Filled</Button>
      <Button variant="outlined">Outlined</Button>
      <Button variant="text">Text</Button>
      <Button variant="elevated">Elevated</Button>
      <Button variant="tonal">Tonal</Button>
    </div>
  ),
};

Files to Reference