UI Component Audit (DataConnect)
Scope
Use this skill to audit or refactor React components to align with:
docs/260202-ui-implementation-typography.md
AGENTS.md (no comment overwrites; do not change styles/classes unless asked)
- Vercel React best practices + composition patterns
Quick Start (Audit)
- Read target component(s).
- Read
docs/260202-ui-implementation-typography.md and AGENTS.md.
- List violations by file with terse bullets.
- If asked to fix, apply minimal diff.
- If you touched any
Text props, run a scoped check on touched files for verbose color props (color="mutedForeground" and color="foregroundDim"), then replace with boolean props (muted and dim respectively) unless a specific semantic color token is required.
Primary principle
Read the component source, understand its API, then apply it correctly.
Before using any project component (Text, Button, etc.), read its source
to learn its props, variants, and default values. Do not hard-code assumptions
about component internals — verify them. Do not pass props that match defaults.
UI Implementation Rules (must enforce)
- All user-visible text should use
Text (src/components/typography/text.tsx) where appropriate. Exceptions include button labels inside Button, form labels, and aria-only content. When unsure, read the Text source to check if it fits.
- Buttons must use
Button; do not add custom focus rings.
Text uses intent for type size/role (e.g. title, heading, subtitle, eyebrow). Read the component source to check default prop values and do not pass props that match the default (e.g. if intent defaults to "body", omit it for body text).
- Use
as to keep semantic HTML (h1, p, li, etc.).
- Prefer
muted/dim boolean props on Text for muted/dim copy; avoid verbose color="mutedForeground" unless a specific semantic color token is required.
Text has props for icon layout (withIcon) and link styling (link). Read the component source to understand how they work before using them — do not guess at prop values or manually replicate behavior the component already handles.
- When
Text uses withIcon, do not add icon sizing classes (size-*) to nested icons by default; Text already applies fallback icon sizing for nested SVGs. Only add size-* when design explicitly requires a non-default icon size.
- For links, use
Text as="a" and pass link props (href, target, rel) directly; do not wrap Text in an <a>.
- Use typographic ellipsis (
…) in user-visible UI copy for in-progress/loading/truncated labels (e.g. Loading…, Refreshing…, Testing…), not three periods (...).
- Do not set
weight unless the Figma design explicitly shows non-normal weight. Models tend to over-apply font-medium and font-bold — normal weight is almost always correct.
- No inline styles; use Tailwind classes + tokens.
- Do not introduce
cn as a formatting tool. Use cn only when class names are dynamic or need conditional logic. For static classes (even 5-7 of them), prefer a plain string literal className="...". Only group into cn(...) arrays when the element has 8+ classes (per Tailwind sort rule) or when classes are extracted into a reusable constant.
- Use tokenized colors (
text-foreground, bg-muted, etc.), not hex.
- No raw colors anywhere outside
src/styles/vars.css (no hex/rgb/hsl/oklch in components or CSS).
- No palette classes like
text-gray-*, bg-slate-*, etc. Use tokens only.
- Prefer layout spacing via
gap-*, space-*; avoid margins on text.
- Defer to base component styles (padding, radius, borders) unless the UI markup explicitly specifies an override.
- Use semantic radius/color tokens (e.g.,
rounded-button, tokenized color classes) instead of raw Tailwind radius/color classes.
- Icon sizing: use
size-* for square icons instead of paired w-*/h-*.
- Icons inside
Button: do not set explicit icon sizing classes by default. Button already sizes nested SVGs via its base styles; only add size-* when the design explicitly requires an override.
- SVG sizing:
useBoxSize sets inline width/height (1em by default). Use it when icons should scale with text; avoid mixing with size-* in the same element.
- Lucide icon imports must end with
Icon suffix (e.g., DownloadIcon).
- Loading indicators: prefer the shared
Spinner (src/components/elements/spinner.tsx) over Lucide LoaderIcon/LoaderCircleIcon for in-progress UI. First verify Spinner fits the surface; only use a Lucide loader when Spinner cannot satisfy a specific visual requirement.
- Do not add
animate-spin/motion classes to Spinner instances. Spinner owns its animation internally; only pass sizing/color/layout classes (for example size-*, spacing, tokenized text color).
- Component filenames are kebab-case.
Typography Notes
Text runs formatting on string children (smart quotes). Pass a ReactNode if you need raw text.
- Display typography uses Inter Variable optical sizing:
title, display, and hero auto-apply display opsz; override with optical="auto" or force with optical="display".
- The typography system is defined in
textVariants inside src/components/typography/text.tsx.
- When introducing new theme tokens (spacing, text, color, radius), update the custom Tailwind merge in
src/lib/classes.ts so cn handles them correctly.
- Lucide stroke width is globally set to
1.5 via .lucide in src/styles/index.css.
React + Composition Rules
For React architecture, composition patterns, and performance (memoization,
barrel imports, etc.), defer to the vercel-react-best-practices and
vercel-composition-patterns skills when available. This skill focuses on
UI implementation correctness, not general React guidance.
- Barrel files are a tool, not a default. Follow
vercel-react-best-practices
rule 2.1 (anti-barrel by default): prefer direct imports, especially for
third-party packages.
- Exception: allow tiny, explicit, feature-local curated barrels (no
export *) when they define a stable boundary (for example, section ->
shared settings components) and reduce fragile relative paths.
- Never create broad catch-all barrels for large folders or app-wide UI
exports as part of UI audit refactors.
Fix Workflow (when asked to refactor)
- Convert inline styles → Tailwind classes + tokens.
- Replace raw text nodes with
Text (skip button labels inside Button).
- Convert raw
<button> to Button and drop custom focus rings.
- If a file is not kebab-case, flag it and suggest the new name — do not rename automatically. Wait for confirmation before renaming and updating imports.
- Enforce icon suffix and direct imports.
- If import ergonomics are poor, prefer alias-based direct imports; only introduce a curated local barrel when it is intentionally tiny and boundary-scoped.
- For icon + text rows, use
Text with withIcon; remove manual layout classes where possible.
- Add
type="button" to non-submit buttons.
- Verify null-safe rendering for optional fields.
- Run lints for touched files.
Output Format
Group findings by file.
## src/components/example.tsx
src/components/example.tsx:12 - inline style; use Tailwind tokens
src/components/example.tsx:21 - raw text; use Text
Notes
- Do not overwrite comments.
- Do not change styles/classes unless user asks for refactor.
Structural refactor guardrails
- If the intended change is structural or ownership-only, treat existing spacing, headings, wrapper structure, and class rhythm as part of the contract.
- Do not "clean up" layout wrappers or heading structure unless the visual change is intentional and reviewed.
- In tabbed UIs, do not repeat the active tab label as a second visible heading below the tabs. Keep the visible title in the tab label; use an sr-only route heading if semantic structure still requires an
h1.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: ui-component-audit3description: Audit and refactor React UI components to match DataConnect UI implementation rules (Text component, tokens, Tailwind, naming) and Vercel React/composition guidance. Use when the user asks for a UI audit, React audit, composition review, or to fix UI implementation issues in components. Use when this capability is needed.4---56# UI Component Audit (DataConnect)78## Scope910Use this skill to audit or refactor React components to align with:1112- `docs/260202-ui-implementation-typography.md`13- `AGENTS.md` (no comment overwrites; do not change styles/classes unless asked)14- Vercel React best practices + composition patterns1516## Quick Start (Audit)17181. Read target component(s).192. Read `docs/260202-ui-implementation-typography.md` and `AGENTS.md`.203. List violations by file with terse bullets.214. If asked to fix, apply minimal diff.225. If you touched any `Text` props, run a scoped check on touched files for verbose color props (`color="mutedForeground"` and `color="foregroundDim"`), then replace with boolean props (`muted` and `dim` respectively) unless a specific semantic color token is required.2324## Primary principle2526**Read the component source, understand its API, then apply it correctly.**27Before using any project component (`Text`, `Button`, etc.), read its source28to learn its props, variants, and default values. Do not hard-code assumptions29about component internals — verify them. Do not pass props that match defaults.3031## UI Implementation Rules (must enforce)3233- All user-visible text should use `Text` (`src/components/typography/text.tsx`) where appropriate. Exceptions include button labels inside `Button`, form labels, and aria-only content. When unsure, read the `Text` source to check if it fits.34- Buttons must use `Button`; do not add custom focus rings.35- `Text` uses `intent` for type size/role (e.g. `title`, `heading`, `subtitle`, `eyebrow`). Read the component source to check default prop values and do not pass props that match the default (e.g. if `intent` defaults to `"body"`, omit it for body text).36- Use `as` to keep semantic HTML (`h1`, `p`, `li`, etc.).37- Prefer `muted`/`dim` boolean props on `Text` for muted/dim copy; avoid verbose `color="mutedForeground"` unless a specific semantic color token is required.38- `Text` has props for icon layout (`withIcon`) and link styling (`link`). Read the component source to understand how they work before using them — do not guess at prop values or manually replicate behavior the component already handles.39- When `Text` uses `withIcon`, do not add icon sizing classes (`size-*`) to nested icons by default; `Text` already applies fallback icon sizing for nested SVGs. Only add `size-*` when design explicitly requires a non-default icon size.40- For links, use `Text as="a"` and pass link props (`href`, `target`, `rel`) directly; do not wrap `Text` in an `<a>`.41- Use typographic ellipsis (`…`) in user-visible UI copy for in-progress/loading/truncated labels (e.g. `Loading…`, `Refreshing…`, `Testing…`), not three periods (`...`).42- Do not set `weight` unless the Figma design explicitly shows non-normal weight. Models tend to over-apply `font-medium` and `font-bold` — normal weight is almost always correct.43- No inline styles; use Tailwind classes + tokens.44- **Do not introduce `cn` as a formatting tool.** Use `cn` only when class names are dynamic or need conditional logic. For static classes (even 5-7 of them), prefer a plain string literal `className="..."`. Only group into `cn(...)` arrays when the element has 8+ classes (per Tailwind sort rule) or when classes are extracted into a reusable constant.45- Use tokenized colors (`text-foreground`, `bg-muted`, etc.), not hex.46- No raw colors anywhere outside `src/styles/vars.css` (no hex/rgb/hsl/oklch in components or CSS).47- No palette classes like `text-gray-*`, `bg-slate-*`, etc. Use tokens only.48- Prefer layout spacing via `gap-*`, `space-*`; avoid margins on text.49- Defer to base component styles (padding, radius, borders) unless the UI markup explicitly specifies an override.50- Use semantic radius/color tokens (e.g., `rounded-button`, tokenized color classes) instead of raw Tailwind radius/color classes.51- Icon sizing: use `size-*` for square icons instead of paired `w-*`/`h-*`.52- Icons inside `Button`: do not set explicit icon sizing classes by default. `Button` already sizes nested SVGs via its base styles; only add `size-*` when the design explicitly requires an override.53- SVG sizing: `useBoxSize` sets inline `width/height` (`1em` by default). Use it when icons should scale with text; avoid mixing with `size-*` in the same element.54- Lucide icon imports must end with `Icon` suffix (e.g., `DownloadIcon`).55- Loading indicators: prefer the shared `Spinner` (`src/components/elements/spinner.tsx`) over Lucide `LoaderIcon`/`LoaderCircleIcon` for in-progress UI. First verify `Spinner` fits the surface; only use a Lucide loader when `Spinner` cannot satisfy a specific visual requirement.56- Do not add `animate-spin`/motion classes to `Spinner` instances. `Spinner` owns its animation internally; only pass sizing/color/layout classes (for example `size-*`, spacing, tokenized text color).57- Component filenames are kebab-case.5859## Typography Notes6061- `Text` runs formatting on string children (smart quotes). Pass a ReactNode if you need raw text.62- Display typography uses Inter Variable optical sizing: `title`, `display`, and `hero` auto-apply display opsz; override with `optical="auto"` or force with `optical="display"`.63- The typography system is defined in `textVariants` inside `src/components/typography/text.tsx`.64- When introducing new theme tokens (spacing, text, color, radius), update the custom Tailwind merge in `src/lib/classes.ts` so `cn` handles them correctly.65- Lucide stroke width is globally set to `1.5` via `.lucide` in `src/styles/index.css`.6667## React + Composition Rules6869For React architecture, composition patterns, and performance (memoization,70barrel imports, etc.), defer to the **vercel-react-best-practices** and71**vercel-composition-patterns** skills when available. This skill focuses on72UI implementation correctness, not general React guidance.7374- Barrel files are a tool, not a default. Follow `vercel-react-best-practices`75 rule 2.1 (anti-barrel by default): prefer direct imports, especially for76 third-party packages.77- Exception: allow tiny, explicit, feature-local curated barrels (no78 `export *`) when they define a stable boundary (for example, section ->79 shared settings components) and reduce fragile relative paths.80- Never create broad catch-all barrels for large folders or app-wide UI81 exports as part of UI audit refactors.8283## Fix Workflow (when asked to refactor)84851. Convert inline styles → Tailwind classes + tokens.862. Replace raw text nodes with `Text` (skip button labels inside `Button`).873. Convert raw `<button>` to `Button` and drop custom focus rings.884. If a file is not kebab-case, flag it and suggest the new name — do not rename automatically. Wait for confirmation before renaming and updating imports.895. Enforce icon suffix and direct imports.906. If import ergonomics are poor, prefer alias-based direct imports; only introduce a curated local barrel when it is intentionally tiny and boundary-scoped.917. For icon + text rows, use `Text` with `withIcon`; remove manual layout classes where possible.928. Add `type="button"` to non-submit buttons.939. Verify null-safe rendering for optional fields.9410. Run lints for touched files.9596## Output Format9798Group findings by file.99100```101## src/components/example.tsx102src/components/example.tsx:12 - inline style; use Tailwind tokens103src/components/example.tsx:21 - raw text; use Text104```105106## Notes107108- Do not overwrite comments.109- Do not change styles/classes unless user asks for refactor.110111## Structural refactor guardrails112113- If the intended change is structural or ownership-only, treat existing spacing, headings, wrapper structure, and class rhythm as part of the contract.114- Do not "clean up" layout wrappers or heading structure unless the visual change is intentional and reviewed.115- In tabbed UIs, do not repeat the active tab label as a second visible heading below the tabs. Keep the visible title in the tab label; use an sr-only route heading if semantic structure still requires an `h1`.116117---118> Converted and distributed by [TomeVault](https://tomevault.io/claim/vana-com) — claim your Tome and manage your conversions.119<!-- tomevault:4.0:skill_md:2026-04-13 -->