/shep-ui-component
Use when creating, modifying, or reviewing web UI components. Triggers include "new component", "add component", "create UI", "build a widget", "update component", working with files in src/presentation/web/components/, or when the user asks to build any React component for the
$ npx -y skills add shep-ai/shep --skill shep-ui-component --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/shep-ui-component
Context preview
The summary Claude sees to decide when to auto-load this skill.
Use when creating, modifying, or reviewing web UI components. Triggers include "new component", "add component", "create UI", "build a widget", "update component", working with files in src/presentation/web/components/, or when the user asks to build any React component for the
SKILL.md
shep-ui-component.SKILL.mdname: shep:ui-component
description: Use when creating, modifying, or reviewing web UI components. Triggers include "new component", "add component", "create UI", "build a widget", "update component", working with files in src/presentation/web/components/, or when the user asks to build any React component for the web UI. Part of the Shep autonomous SDLC platform — https://shep.bot
metadata:
version: '1.0.0'
author: Shep AI (https://shep.bot)
homepage: https://shep.bot
repository: https://github.com/shep-ai/shep
Web UI Component Development
Build React components following the four-tier architecture, with mandatory Storybook stories, `data-testid` attributes, and unit tests.
Four-Tier Hierarchy
Tier 0: ui/ -> shadcn/ui primitives (managed by CLI, rarely hand-edited)
Tier 1: common/ -> Reusable composed components (combine ui/ primitives)
Tier 2: layouts/ -> Page shells, structural wrappers (use ui/ + common/)
Tier 3: features/ -> Domain-specific views bound to routes (use all tiers)
**Import rule:** A tier may only import from lower tiers, never upward.
features/ -> layouts/, common/, ui/
layouts/ -> common/, ui/
common/ -> ui/
ui/ -> external packages only
File Structure
Tier 0 (ui/) — flat files, no subfolder
components/ui/
button.tsx
button.stories.tsx
Tier 1-3 — subfolder per component
components/common/feature-list-item/
feature-list-item.tsx # Implementation
feature-list-item.stories.tsx # Storybook stories (MANDATORY)
index.ts # Barrel export
**Barrel export template:**
export { FeatureListItem } from './feature-list-item';
export type { FeatureListItemProps } from './feature-list-item';After creating any Tier 1-3 component, add it to the tier-level barrel:
- `components/common/index.ts`
- `components/layouts/index.ts`
- `components/features/index.ts`
Component Template
'use client'; // Only if the component uses hooks, event handlers, or browser APIs
import { cn } from '@/lib/utils';
export interface MyComponentProps {
/** Brief prop description. */
label: string;
className?: string;
}
export function MyComponent({ label, className }: MyComponentProps) {
return (
<div
data-testid="my-component"
className={cn('base-classes', className)}
>
{label}
</div>
);
}Rules
1. **Named exports only** — no default exports for components. 2. **`'use client'`** — add only when the component uses hooks, event handlers, or browser APIs. Omit for pure render components. 3. **`className` prop** — accept and merge via `cn()` for composability. 4. **Props interface** — always export the interface alongside the component.
data-testid Convention
Every component MUST include `data-testid` on its root element for test targeting.
Naming scheme: `kebab-case`, scoped to the component
| Component | data-testid | | ----------------------- | ------------------------- | | `FeatureListItem` | `feature-list-item` | | `FeatureStatusGroup` | `feature-status-group` | | `SidebarCollapseToggle` | `sidebar-collapse-toggle` | | `PageHeader` | `page-header` |
Sub-elements: append a suffix
<div data-testid="feature-list-item">
<span data-testid="feature-list-item-label">{name}</span>
<span data-testid="feature-list-item-meta">{duration}</span>
</div>When to add data-testid
- Root element of every component: **always**
- Sub-elements: only when tests need to target them specifically (labels, meta, actions)
- Primitives in `ui/`: use `data-slot` instead (shadcn convention)
In tests, prefer data-testid queries
screen.getByTestId('feature-list-item');
screen.getByTestId('feature-list-item-meta');Fall back to role/text queries when `data-testid` is not set:
screen.getByRole('button', { name: /submit/i });
screen.getByText('Auth Module');Storybook Stories (MANDATORY)
Every component MUST have a colocated `.stories.tsx` file. This is non-negotiable.
Story template
import type { Meta, StoryObj } from '@storybook/react';
import { MyComponent } from './my-component';
// IMPORTANT: Use explicit type annotation, NOT `satisfies Meta<>`
const meta: Meta<typeof MyComponent> = {
title: 'Composed/MyComponent', // See title prefixes below
component: MyComponent,
parameters: {
layout: 'padded', // 'centered' | 'padded' | 'fullscreen'
},
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
label: 'Example',
},
};Title prefixes by tier
| Tier | Prefix | Example | | ----------- | ------------- | -------------------------- | | `ui/` | `Primitives/` | `Primitives/Button` | | `common/` | `Composed/` | `Composed/FeatureListItem` | | `layouts/` | `Layout/` | `Layout/AppSidebar` | | `features/` | `Features/` | `Features/VersionPage` |
Decorators for context-dependent components
If the component requires a React context (e.g. `SidebarProvider`), wrap it:
const meta: Meta<typeof SidebarNavItem> = {
// ...
decorators: [
(Story) => (
<SidebarProvider>
<SidebarMenu>
<Story />
</SidebarMenu>
</SidebarProvider>
),
],
};Story-level decorator overrides (e.g. for alternate states):
export const Collapsed: Story = {
args: { /* ... */ },
decorators: [
(Story) => (
<SidebarProvider defaultOpen={false}>
<Story />
</SidebarProvider>
),
],
};Args and Controls (CRITICAL)
Storybook controls only appear when stories define `args`. **Never use hardcoded render-only stories** — always define `args` so the Controls panel works.
**Standard components (fl
Read more
name: shep:ui-component description: Use when creating, modifying, or reviewing web UI components. Triggers include "new component", "add component", "create UI", "build a widget", "update component", working with files in src/presentation/web/components/, or when the user asks to build any React component for the web UI. Part of the Shep autonomous SDLC platform — https://shep.bot metadata: version: '1.0.0' author: Shep AI (https://shep.bot) homepage: https://shep.bot repository: https://github.com/shep-ai/shep
Web UI Component Development
Build React components following the four-tier architecture, with mandatory Storybook stories, `data-testid` attributes, and unit tests.
Four-Tier Hierarchy
Tier 0: ui/ -> shadcn/ui primitives (managed by CLI, rarely hand-edited) Tier 1: common/ -> Reusable composed components (combine ui/ primitives) Tier 2: layouts/ -> Page shells, structural wrappers (use ui/ + common/) Tier 3: features/ -> Domain-specific views bound to routes (use all tiers)
**Import rule:** A tier may only import from lower tiers, never upward.
features/ -> layouts/, common/, ui/ layouts/ -> common/, ui/ common/ -> ui/ ui/ -> external packages only
File Structure
Tier 0 (ui/) — flat files, no subfolder
components/ui/ button.tsx button.stories.tsx
Tier 1-3 — subfolder per component
components/common/feature-list-item/ feature-list-item.tsx # Implementation feature-list-item.stories.tsx # Storybook stories (MANDATORY) index.ts # Barrel export
**Barrel export template:**
export { FeatureListItem } from './feature-list-item';
export type { FeatureListItemProps } from './feature-list-item';After creating any Tier 1-3 component, add it to the tier-level barrel:
- `components/common/index.ts`
- `components/layouts/index.ts`
- `components/features/index.ts`
Component Template
'use client'; // Only if the component uses hooks, event handlers, or browser APIs
import { cn } from '@/lib/utils';
export interface MyComponentProps {
/** Brief prop description. */
label: string;
className?: string;
}
export function MyComponent({ label, className }: MyComponentProps) {
return (
<div
data-testid="my-component"
className={cn('base-classes', className)}
>
{label}
</div>
);
}Rules
1. **Named exports only** — no default exports for components. 2. **`'use client'`** — add only when the component uses hooks, event handlers, or browser APIs. Omit for pure render components. 3. **`className` prop** — accept and merge via `cn()` for composability. 4. **Props interface** — always export the interface alongside the component.
data-testid Convention
Every component MUST include `data-testid` on its root element for test targeting.
Naming scheme: `kebab-case`, scoped to the component
| Component | data-testid | | ----------------------- | ------------------------- | | `FeatureListItem` | `feature-list-item` | | `FeatureStatusGroup` | `feature-status-group` | | `SidebarCollapseToggle` | `sidebar-collapse-toggle` | | `PageHeader` | `page-header` |
Sub-elements: append a suffix
<div data-testid="feature-list-item">
<span data-testid="feature-list-item-label">{name}</span>
<span data-testid="feature-list-item-meta">{duration}</span>
</div>When to add data-testid
- Root element of every component: **always**
- Sub-elements: only when tests need to target them specifically (labels, meta, actions)
- Primitives in `ui/`: use `data-slot` instead (shadcn convention)
In tests, prefer data-testid queries
screen.getByTestId('feature-list-item');
screen.getByTestId('feature-list-item-meta');Fall back to role/text queries when `data-testid` is not set:
screen.getByRole('button', { name: /submit/i });
screen.getByText('Auth Module');Storybook Stories (MANDATORY)
Every component MUST have a colocated `.stories.tsx` file. This is non-negotiable.
Story template
import type { Meta, StoryObj } from '@storybook/react';
import { MyComponent } from './my-component';
// IMPORTANT: Use explicit type annotation, NOT `satisfies Meta<>`
const meta: Meta<typeof MyComponent> = {
title: 'Composed/MyComponent', // See title prefixes below
component: MyComponent,
parameters: {
layout: 'padded', // 'centered' | 'padded' | 'fullscreen'
},
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
label: 'Example',
},
};Title prefixes by tier
| Tier | Prefix | Example | | ----------- | ------------- | -------------------------- | | `ui/` | `Primitives/` | `Primitives/Button` | | `common/` | `Composed/` | `Composed/FeatureListItem` | | `layouts/` | `Layout/` | `Layout/AppSidebar` | | `features/` | `Features/` | `Features/VersionPage` |
Decorators for context-dependent components
If the component requires a React context (e.g. `SidebarProvider`), wrap it:
const meta: Meta<typeof SidebarNavItem> = {
// ...
decorators: [
(Story) => (
<SidebarProvider>
<SidebarMenu>
<Story />
</SidebarMenu>
</SidebarProvider>
),
],
};Story-level decorator overrides (e.g. for alternate states):
export const Collapsed: Story = {
args: { /* ... */ },
decorators: [
(Story) => (
<SidebarProvider defaultOpen={false}>
<Story />
</SidebarProvider>
),
],
};Args and Controls (CRITICAL)
Storybook controls only appear when stories define `args`. **Never use hardcoded render-only stories** — always define `args` so the Controls panel works.
**Standard components (fl
Ship features 10x faster. Built In Auto: Memory, K8S Agent & Security (SDD+SDLC) . 😇
Repo: shep-ai/shep
Other skills on shep.
- /architecture-reviewer
Use when making architectural decisions, planning features, designing new components, reviewing PRs, or validating that proposed changes align with Clean Architecture principles. Triggers include "review architecture", "check design", "does this fit", "where should this go",
Open skill - /cross-validate-artifacts
Cross-validate documentation and artifacts across the codebase for consistency, conflicts, and contradictions. Use when users ask to "cross-validate", "validate docs", "check documentation consistency", "audit documentation", or find conflicts/contradictions in docs. Supports
Open skill - /mermaid-diagrams
Comprehensive guide for creating software diagrams using Mermaid syntax. Use when users need to create, visualize, or document software through diagrams including class diagrams (domain modeling, object-oriented design), sequence diagrams (application flows, API interactions,
Open skill - /react-flow
React Flow (@xyflow/react) for workflow visualization with custom nodes and edges. Use when building graph visualizations, creating custom workflow nodes, implementing edge labels, or controlling viewport. Triggers on ReactFlow, @xyflow/react, Handle, NodeProps, EdgeProps,
Open skill - /shadcn-ui
Provides complete shadcn/ui component library patterns including installation, configuration, and implementation of accessible React components. Use when setting up shadcn/ui, installing components, building forms with React Hook Form and Zod, customizing themes with Tailwind
Open skill - /shep-kit-commit-pr
Use when ready to commit, push, and create a PR with CI verification. Triggers include "commit and pr", "push pr", "create pr", "ship it", or when implementation is complete and needs CI validation. Watches CI and auto-fixes failures. Part of the Shep autonomous SDLC platform —
Open skill

