Como usar as habilidades de código do Claude para criar interface do usuário

Ashley Goolam

Ashley Goolam

21 janeiro 2026

Como usar as habilidades de código do Claude para criar interface do usuário

Descrever componentes de interface de usuário manualmente para o Claude Code a cada nova funcionalidade é como escrever CSS sem classes: repetitivo, inconsistente e impossível de escalar entre equipes. As Habilidades do Claude Code para construção de UI transformam seu sistema de design em ferramentas executáveis que geram componentes, layouts e estilos com parâmetros previsíveis e zero *boilerplate*.

O que são as Habilidades do Claude Code para Construção de UI?

As Habilidades do Claude Code empacotam a lógica de geração de UI em ferramentas reutilizáveis e versionadas que o Claude Code pode descobrir e invocar via Model Context Protocol (MCP). Em vez de criar *prompts* prolixos como *“Crie um componente de cartão responsivo com Tailwind, uma imagem alinhada à esquerda, texto alinhado à direita e um botão primário,”* você define uma habilidade `building-ui` uma vez e a chama com parâmetros concisos: `component: "card", layout: "image-left"`.

Cada habilidade consiste em um arquivo `SKILL.md` que define:

A habilidade `building-ui` do repositório oficial fornece padrões para componentes, layouts, temas e formulários. Ela transforma a geração *ad-hoc* de UI em um processo sistemático e repetível.

Habilidades do Claude Code

Principais Vantagens sobre a Criação de *Prompts* Pura

💡
Quer uma ótima ferramenta de Teste de API que gera documentação de API bonita?

Quer uma plataforma integrada, All-in-One para sua Equipe de Desenvolvimento trabalhar em conjunto com máxima produtividade?

Apidog entrega todas as suas demandas e substitui o Postman por um preço muito mais acessível!
botão

Configurando a Habilidade *building-ui*

Passo 1: Instale o Claude Code e Habilite o MCP

Se você ainda não instalou o Claude Code CLI:

npm install -g @anthropic-ai/claude-code
claude --version  # Deve ser >= 2.0.70

Crie o diretório e o arquivo de configuração do MCP:

# macOS/Linux
mkdir -p ~/.config/claude-code
touch ~/.config/claude-code/config.json

# Windows
mkdir %APPDATA%\claude-code
echo {} > %APPDATA%\claude-code\config.json
claude code

Passo 2: Clone e Construa a Habilidade *building-ui*

git clone https://github.com/anthropics/skills.git
cd skills/skills/building-ui
npm install
npm run build

Isso compila os manipuladores TypeScript para `dist/index.js`.

Passo 3: Configure o MCP para Carregar a Habilidade

Edite `~/.config/claude-code/config.json`:

{
  "mcpServers": {
    "building-ui": {
      "command": "node",
      "args": ["/caminho/absoluto/para/skills/building-ui/dist/index.js"],
      "env": {
        "UI_LIBRARY": "react",
        "STYLE_SYSTEM": "tailwind",
        "THEME_CONFIG": "~/projeto/design-tokens.json"
      }
    }
  }
}

Crítico:

Passo 4: Verifique a Instalação

claude

Uma vez carregado, execute:

/list-tools

Você deve ver:

Ferramentas disponíveis:
- building-ui:generate-component
- building-ui:create-layout
- building-ui:apply-theme
- building-ui:generate-form

Se as ferramentas não aparecerem, verifique os logs:

# macOS/Linux
tail -f ~/.cache/claude-code/logs/mcp.log

# Windows
type %APPDATA%\claude-code\logs\mcp.log

Problemas comuns:

Padrões Essenciais de Construção de UI com Habilidades

A habilidade `building-ui` exporta quatro ferramentas primárias. Cada uma aceita parâmetros estruturados e retorna código gerado.

1. Ferramenta Gerar Componente

Nome da ferramenta: `building-ui:generate-component`
Caso de uso: Criar componentes de UI reutilizáveis

Parâmetros:

Exemplo: Crie um botão com variantes

Use a ferramenta generate-component para criar um componente de botão com as variantes primary, secondary e outline, tamanho médio, e suporte para estado desabilitado.

Saída gerada (React + Tailwind):

// Button.tsx
import React from 'react';
import clsx from 'clsx';

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'primary' | 'secondary' | 'outline';
  size?: 'small' | 'medium' | 'large';
}

export const Button: React.FC<ButtonProps> = ({ 
  variant = 'primary', 
  size = 'medium',
  disabled,
  children,
  className,
  ...props 
}) => {
  const baseClasses = 'font-semibold rounded-lg transition-colors';
  const variantClasses = {
    primary: 'bg-blue-600 text-white hover:bg-blue-700',
    secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300',
    outline: 'border-2 border-blue-600 text-blue-600 hover:bg-blue-50'
  };
  const sizeClasses = {
    small: 'px-3 py-1.5 text-sm',
    medium: 'px-4 py-2 text-base',
    large: 'px-6 py-3 text-lg'
  };
  
  return (
    <button
      disabled={disabled}
      className={clsx(
        baseClasses,
        variantClasses[variant],
        sizeClasses[size],
        disabled && 'opacity-50 cursor-not-allowed',
        className
      )}
      {...props}
    >
      {children}
    </button>
  );
};

A habilidade infere tipos TypeScript, atributos de acessibilidade e classes de estilo com base em suas variáveis de ambiente.

2. Ferramenta Criar Layout

Nome da ferramenta: `building-ui:create-layout`
Caso de uso: Gerar layouts de página responsivos

Parâmetros:

Exemplo: Layout de painel com barra lateral responsiva

Use create-layout para gerar um layout de painel responsivo com uma barra lateral recolhível, cabeçalho, área de conteúdo principal e rodapé. Use gap-4 e faça a barra lateral ter 256px de largura no desktop, largura total no celular.

Saída gerada:

// DashboardLayout.tsx
import React, { useState } from 'react';
import clsx from 'clsx';

interface DashboardLayoutProps {
  header?: React.ReactNode;
  sidebar?: React.ReactNode;
  main: React.ReactNode;
  footer?: React.ReactNode;
}

export const DashboardLayout: React.FC<DashboardLayoutProps> = ({ 
  header, 
  sidebar, 
  main, 
  footer 
}) => {
  const [sidebarOpen, setSidebarOpen] = useState(false);

  return (
    <div className="min-h-screen flex flex-col">
      {/* Header */}
      <header className="bg-white shadow-sm border-b border-gray-200 z-10">
        <div className="px-4 sm:px-6 lg:px-8 py-4">
          {header}
        </div>
      </header>

      <div className="flex flex-1">
        {/* Mobile menu button */}
        <button
          className="lg:hidden fixed bottom-4 right-4 bg-blue-600 text-white p-3 rounded-full shadow-lg z-20"
          onClick={() => setSidebarOpen(!sidebarOpen)}
        >
          ☰
        </button>

        {/* Sidebar */}
        <aside className={clsx(
          'bg-gray-50 border-r border-gray-200',
          'fixed lg:relative inset-y-0 left-0 z-30',
          'w-64 transform transition-transform lg:translate-x-0',
          sidebarOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'
        )}>
          <div className="p-4">
            {sidebar}
          </div>
        </aside>

        {/* Main content */}
        <main className="flex-1 p-4 sm:p-6 lg:p-8">
          {main}
        </main>
      </div>

      {/* Footer */}
      {footer && (
        <footer className="bg-gray-50 border-t border-gray-200 mt-auto">
          <div className="px-4 sm:px-6 lg:px-8 py-4">
            {footer}
          </div>
        </footer>
      )}
    </div>
  );
};

A habilidade adiciona automaticamente a lógica do menu móvel, classes sensíveis ao *breakpoint* e atributos acessíveis.

3. Ferramenta Aplicar Tema

Nome da ferramenta: `building-ui:apply-theme`
Caso de uso: Aplicar *design tokens* em componentes

Parâmetros:

Exemplo: Aplique o tema escuro a um componente de cartão

Use apply-theme para configurar um componente Card para o modo escuro com paleta de cores slate, escala de espaçamento 4 e família de fontes Inter.

Saída gerada:

// card-theme.ts
export const cardTheme = {
  light: {
    background: 'bg-white',
    border: 'border-gray-200',
    text: 'text-gray-900',
    subText: 'text-gray-600'
  },
  dark: {
    background: 'bg-slate-800',
    border: 'border-slate-700',
    text: 'text-slate-100',
    subText: 'text-slate-400'
  }
};

// Uso em Card.tsx
import { cardTheme } from './card-theme';

interface CardProps {
  variant?: 'light' | 'dark';
  children: React.ReactNode;
}

export const Card: React.FC<CardProps> = ({ variant = 'light', children }) => {
  const theme = cardTheme[variant];
  
  return (
    <div className={clsx(
      'rounded-lg p-4 border',
      theme.background,
      theme.border
    )}>
      {children}
    </div>
  );
};

A habilidade lê seu arquivo `THEME_CONFIG` e gera mapas de *tokens* específicos do tema. Se `THEME_CONFIG` apontar para um arquivo JSON:

{
  "colors": {
    "primary": "#3B82F6",
    "secondary": "#6B7280"
  },
  "fonts": {
    "sans": "Inter",
    "mono": "JetBrains Mono"
  }
}

O código gerado usa esses valores exatos em vez dos padrões do Tailwind.

4. Ferramenta Gerar Formulário

Nome da ferramenta: `building-ui:generate-form`
Caso de uso: Criar formulários validados a partir de esquemas

Parâmetros:

Exemplo: Formulário de registro de usuário com validação

Use generate-form para criar um formulário de registro de usuário com os campos: nome (texto, obrigatório), email (email, obrigatório), senha (senha, comprimento mínimo 8) e aceitarTermos (caixa de seleção). Envie para /api/register com validação onBlur.

Saída gerada:

// UserRegistrationForm.tsx
import React, { useState } from 'react';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm, SubmitHandler } from 'react-hook-form';

const schema = z.object({
  name: z.string().min(1, 'Name is required'),
  email: z.string().email('Invalid email address'),
  password: z.string().min(8, 'Password must be at least 8 characters'),
  acceptTerms: z.boolean().refine(val => val === true, {
    message: 'You must accept the terms'
  })
});

type FormData = z.infer<typeof schema>;

export const UserRegistrationForm: React.FC = () => {
  const [isSubmitting, setIsSubmitting] = useState(false);
  
  const {
    register,
    handleSubmit,
    formState: { errors },
    trigger
  } = useForm<FormData>({
    resolver: zodResolver(schema),
    mode: 'onBlur'
  });

  const onSubmit: SubmitHandler<FormData> = async (data) => {
    setIsSubmitting(true);
    try {
      const response = await fetch('/api/register', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data)
      });
      
      if (!response.ok) throw new Error('Registration failed');
      
      // Lidar com o sucesso
      console.log('User registered:', await response.json());
    } catch (error) {
      console.error('Registration error:', error);
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-4 max-w-md">
      <div>
        <label htmlFor="name" className="block text-sm font-medium text-gray-700">
          Nome
        </label>
        <input
          id="name"
          {...register('name')}
          className={clsx(
            'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500',
            errors.name && 'border-red-500'
          )}
        />
        {errors.name && (
          <p className="mt-1 text-sm text-red-600">{errors.name.message}</p>
        )}
      </div>

      <div>
        <label htmlFor="email" className="block text-sm font-medium text-gray-700">
          Email
        </label>
        <input
          id="email"
          type="email"
          {...register('email')}
          className={clsx(
            'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500',
            errors.email && 'border-red-500'
          )}
        />
        {errors.email && (
          <p className="mt-1 text-sm text-red-600">{errors.email.message}</p>
        )}
      </div>

      <div>
        <label htmlFor="password" className="block text-sm font-medium text-gray-700">
          Senha
        </label>
        <input
          id="password"
          type="password"
          {...register('password')}
          className={clsx(
            'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500',
            errors.password && 'border-red-500'
          )}
        />
        {errors.password && (
          <p className="mt-1 text-sm text-red-600">{errors.password.message}</p>
        )}
      </div>

      <div className="flex items-center">
        <input
          id="acceptTerms"
          type="checkbox"
          {...register('acceptTerms')}
          className="h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
        />
        <label htmlFor="acceptTerms" className="ml-2 block text-sm text-gray-900">
          Aceito os termos e condições
        </label>
      </div>
      {errors.acceptTerms && (
        <p className="text-sm text-red-600">{errors.acceptTerms.message}</p>
      )}

      <button
        type="submit"
        disabled={isSubmitting}
        className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50"
      >
        {isSubmitting ? 'Registrando...' : 'Registrar'}
      </button>
    </form>
  );
};

A habilidade conecta automaticamente `react-hook-form`, validação `zod`, atributos de acessibilidade e estados de carregamento.

Geração Dinâmica de UI Usando Técnicas Avançadas

Lógica de Renderização Condicional

Algumas UIs precisam de seções condicionais com base em parâmetros. A habilidade suporta `conditions` nas definições de campo:

Gere um formulário de perfil de usuário onde o campo "empresa" aparece apenas se "tipoDeConta" for "negócio".

Isso produz um formulário com renderização condicional:

{accountType === 'business' && (
  <div>
    <label htmlFor="company">Empresa</label>
    <input id="company" {...register('company')} />
  </div>
)}

Composição de Componentes

Crie UIs complexas encadeando chamadas de habilidades:

Primeiro, gere um componente DashboardLayout com barra lateral e cabeçalho. Em seguida, gere um componente StatCard para métricas. Finalmente, aplique o tema escuro a ambos.

O Claude Code executa essas operações sequencialmente, passando o contexto entre as chamadas. O componente de layout está disponível ao gerar o cartão, garantindo a integração adequada.

Troca de Tema em Tempo de Execução

Configure a habilidade para emitir código sensível ao tema:

{
  "building-ui": {
    "command": "node",
    "args": ["dist/index.js"],
    "env": {
      "UI_LIBRARY": "react",
      "STYLE_SYSTEM": "tailwind",
      "THEME_CONFIG": "~/projeto/themes.json",
      "SUPPORT_THEME_TOGGLE": "true"
    }
  }
}

Agora, os componentes gerados incluem um *wrapper* `ThemeProvider`:

// App.tsx
import { ThemeProvider } from './ThemeProvider';
import { DashboardLayout } from './DashboardLayout';

function App() {
  return (
    <ThemeProvider defaultTheme="light" enableSystem>
      <DashboardLayout />
    </ThemeProvider>
  );
}

Depurando e Iterando Habilidades de Construção de UI

Visualize o Código Gerado em `.claude-cache`

O Claude Code armazena em cache as saídas das habilidades. Inspecione-as:

# macOS/Linux
cat ~/.cache/claude-code/last-skill-output.tsx

# Windows
type %APPDATA%\claude-code\last-skill-output.tsx

Se o código gerado não corresponder às expectativas, refine seus parâmetros. Adicione mais especificidade:

Em vez de: *“Gerar um cartão”*
Use: *“Gerar um cartão com preenchimento de 16px, raio de borda de 8px e uma sombra sutil”*

Substituir Padrões de Habilidade Por Projeto

Crie `.claude-ui-config.json` na raiz do seu projeto:

{
  "uiLibrary": "vue",
  "styleSystem": "css-modules",
  "themeConfig": "./design-tokens.json"
}

Isso substitui as configurações globais do MCP apenas para aquele projeto.

Versionando Habilidades

Ao atualizar a habilidade `building-ui`, marque as versões:

cd skills/building-ui
npm version patch  # Ou minor/major
git tag -a v1.1.0 -m "Adicionado suporte para Vue 3.5"

Atualize a configuração do Claude Code para fixar as versões:

{
  "mcpServers": {
    "building-ui": {
      "command": "node",
      "args": ["/caminho/para/skills/building-ui-v1.1.0/dist/index.js"]
    }
  }
}

Isso evita que mudanças que quebram a compatibilidade afetem os fluxos de trabalho de produção.

Conclusão

As Habilidades do Claude Code para construir UI convertem linguagem natural em componentes, layouts, temas e formulários prontos para produção com precisão cirúrgica. Ao investir 15 minutos na configuração, você obtém um kit de ferramentas reutilizável que impõe consistência de design, elimina o *boilerplate* e acelera o desenvolvimento de recursos. Comece com as quatro ferramentas principais—`generate-component`, `create-layout`, `apply-theme` e `generate-form`—e, em seguida, estenda-as para o seu sistema de design específico.

Quando suas habilidades geram UIs que consomem APIs, valide esses *endpoints* com o Apidog para garantir que suas interfaces construídas por IA se comuniquem com *backends* confiáveis.

botão

Pratique o design de API no Apidog

Descubra uma forma mais fácil de construir e usar APIs