Skip to content
Back to skills

Pf State Audit

ASecurity

Audit PatternFly React components for missing UI states — loading, error, empty, and unauthorized. Use when reviewing data-dependent components or auditing a page for production readiness.

  • 9 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 21, 2026
designreactapidocumentation

Works with

  • api

Security analysis

A100/100

Pro scans all 10 files and shows the line behind each finding

Scanned September 21, 2026

npx -y skills add rh-uxd/ai-helpers --skill pf-state-audit --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Pf State Audit?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Pf State Audit
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/rh-uxd-pf-state-audit/badge)](https://www.skillsdirectory.com/skills/rh-uxd-pf-state-audit)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: pf-state-audit
description: Audit PatternFly React components for missing UI states — loading, error, empty, and unauthorized. Use when reviewing data-dependent components or auditing a page for production readiness.
---

# PF State Audit

Audit PatternFly React components for missing UI states. Every data-dependent component should handle four states: **loading**, **error**, **empty**, and **unauthorized**. Teams consistently miss 2 of 4 — this skill finds the gaps and recommends the right PF6 component for each.

## PatternFly API documentation

If PatternFly documentation tools are available, use them to verify component props and variant values before recommending. Without documentation available, rely on the component recommendations and signal tables in this skill.

## Input

The user provides a directory, file path, or set of components to audit. Default to the current working directory. Limit scope to files importing from `@patternfly/*` packages.

## Audit procedure

1. **Identify data-dependent components** — components that fetch, receive, or display dynamic data (API responses, query results, user-generated content). Look for:
   - `useEffect` / `useQuery` / `useSWR` / `fetch` / `axios` calls
   - Props typed as arrays or objects that come from parent data-fetching
   - Components rendering `.map()` over data arrays
   - Components with loading/error state variables

2. **Check each component for all four states:**

### Loading state

The component should show a loading indicator while data is being fetched.

| Signal | What to flag |
|--------|-------------|
| `isLoading` / `loading` state exists but no loading UI rendered | Missing loading UI |
| Data fetch starts on mount but component renders data immediately | No loading guard |
| Loading state exists but uses a bare "Loading..." text string | Should use PF component |

**PF6 recommendation:**
- **`Spinner`** — indeterminate loading, no content shape known
- **`Skeleton`** — content placeholder when layout shape is known (tables, cards, text blocks)
- Use `Skeleton` for page loads where layout is predictable; `Spinner` for actions and modals

### Error state

The component should display an error when data fetching fails.

| Signal | What to flag |
|--------|-------------|
| `.catch()` or `onError` exists but error state isn't rendered | Swallowed error |
| Error state renders `null` or empty fragment | Silent failure |
| Error shown as raw `error.message` without formatting | Should use PF component |
| Error state doesn't offer a retry action | Missing recovery path |

**PF6 recommendation:**
- **`Alert`** with `variant="danger"` — inline error within a page section
- **`EmptyState`** with error icon — full-page or panel-level error
- Include a retry action: `Alert` with `actionLinks` or `EmptyState` with primary action button

### Empty state

The component should communicate when data exists but the result set is empty.

| Signal | What to flag |
|--------|-------------|
| `.map()` on data array with no empty guard | Renders nothing when array is `[]` |
| `data?.length === 0` check exists but renders `null` | Silent empty |
| Empty state shows raw text without structure | Should use PF component |
| Table renders headers with no rows and no explanation | Confusing empty table |

**PF6 recommendation:**
- **`EmptyState`** with `titleText` and descriptive body — always
- For filtered results: add a "Clear filters" action
- For first-time use: add a "Get started" primary action
- Use `EmptyStateIcon` with contextual icon (search, plus-circle, cubes)

### Unauthorized state

The component should handle cases where the user lacks permission to view or modify data.

| Signal | What to flag |
|--------|-------------|
| API returns 401/403 but component shows generic error | Missing authz-specific UI |
| Role-based UI gating exists but no explanation shown when gated | Silent permission denial |
| Admin-only actions visible but disabled without explanation | Confusing disabled state |

**PF6 recommendation:**
- **`EmptyState`** with lock icon and "You don't have access" message
- Include a "Request access" action when applicable
- Use `Alert` with `variant="warning"` for partial access (can view but not edit)

## Rules

- Only flag components that are **data-dependent** — pure layout components, icons, and static content don't need all four states
- Do not flag components where a parent already handles the state (e.g., a page wrapper shows a Spinner while child components wait)
- When a component handles 3 of 4 states, flag only the missing one — don't repeat what's working
- Treat `unauthorized` as lower priority than loading/error/empty — not all components have permission concerns
- Distinguish between `Spinner` and `Skeleton` recommendations — `Skeleton` is the better choice when the content layout is known

## Report format

```markdown
## State Audit: [directory or component]

### Missing States

| Component | File | Missing | Recommendation |
|-----------|------|---------|---------------|
| UserList | src/UserList.tsx:15 | empty | `EmptyState` with search icon and "No users found" |
| DashboardCards | src/Dashboard.tsx:42 | loading, error | `Skeleton` for cards; `Alert variant="danger"` for fetch errors |

### Coverage Summary

| State | Covered | Missing | Coverage |
|-------|---------|---------|----------|
| Loading | 8 | 2 | 80% |
| Error | 6 | 4 | 60% |
| Empty | 5 | 5 | 50% |
| Unauthorized | 3 | 7 | 30% |

**Components audited:** [N] | **Fully covered:** [N] | **Gaps found:** [N]
```

Do not fabricate file paths or line numbers — read the actual source files before reporting.

Files in this skill

  • SKILL.md5.6 KB
  • eval/cases/all-states-covered/annotations.yaml19 B
  • eval/cases/all-states-covered/input.yaml1.6 KB
  • eval/cases/missing-error-with-retry/annotations.yaml54 B
  • eval/cases/missing-error-with-retry/input.yaml840 B
  • eval/cases/missing-loading-and-empty/annotations.yaml56 B
  • eval/cases/missing-loading-and-empty/input.yaml1020 B
  • eval/cases/missing-unauthorized/annotations.yaml51 B
  • eval/cases/missing-unauthorized/input.yaml1.2 KB
  • eval/eval.yaml4.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.