Rams MCP · The full engine, now in your coding agent
skeletonlabs on GitHub

skeletonlabs/skeleton

Reviewed against Rams quality heuristics: accessibility, color, typography, spacing, components, motion, UX, and craft.

30 files reviewed·August 1, 2026

View on GitHub

Elevated

Design risk in this codebase.

6issues
Critical, Serious & Moderate · top 5 shown below

Top fix

Add aria-labels to icon-only app bar buttons

See the fix

Verdict

Icon-only controls define the look here, and none of them announce themselves to assistive tech. The pattern repeats across app bar, panel, and upload examples, so fixing accessible names once and reusing it is the highest-leverage move available.

Files Rams reviewed

playgrounds/skeleton-react/app/components/steps/page.tsx

playgrounds/skeleton-react/src/routes/components/app-bar/index.tsx

playgrounds/skeleton-react/src/routes/components/carousel/index.tsx

playgrounds/skeleton-react/src/routes/components/combobox/index.tsx

playgrounds/skeleton-react/src/routes/components/date-picker/index.tsx

playgrounds/skeleton-react/src/routes/components/file-upload/index.tsx

playgrounds/skeleton-react/src/routes/components/floating-panel/index.tsx

playgrounds/skeleton-react/src/routes/components/listbox/index.tsx

playgrounds/skeleton-react/src/routes/components/marquee/index.tsx

playgrounds/skeleton-react/src/routes/components/menu/index.tsx

playgrounds/skeleton-react/src/routes/components/navigation/index.tsx

playgrounds/skeleton-react/src/routes/components/progress-linear/index.tsx

playgrounds/skeleton-react/src/routes/components/segmented-control/index.tsx

playgrounds/skeleton-react/src/routes/components/toast/index.tsx

playgrounds/skeleton-react/src/routes/components/tree-view/index.tsx

sites/skeleton.dev/src/components/examples/framework-components/popover/react/z-index.tsx

sites/skeleton.dev/src/components/examples/integrations/code-block/react/page.tsx

packages/skeleton-common/src/components/carousel.css

packages/skeleton-common/src/components/combobox.css

packages/skeleton-common/src/components/date-picker.css

packages/skeleton-common/src/components/file-upload.css

packages/skeleton-common/src/components/floating-panel.css

packages/skeleton-common/src/components/listbox.css

packages/skeleton-common/src/components/marquee.css

packages/skeleton-common/src/components/navigation.css

packages/skeleton-common/src/components/progress.css

packages/skeleton-common/src/components/segmented-control.css

packages/skeleton-common/src/components/steps.css

packages/skeleton-common/src/components/switch.css

packages/skeleton-common/src/components/tabs.css

92/100

Accessibility

2 critical1 serious
AccessibilityCritical

playgrounds/skeleton-react/src/routes/components/app-bar/index.tsx:25

Icon-only app bar buttons announce nothing to screen readers

The menu button in `AppBar.Lead` and the search, calendar, and profile buttons in `AppBar.Trail` are all icon-only (`<MenuIcon />`, `<SearchIcon />`, `<CalendarIcon />`, `<CircleUserIcon />`) with no `aria-label` or visible text. A screen reader reaches four buttons in the toolbar with nothing to announce.

Why it matters

Screen reader users can't tell what any of these four controls do, so the entire app bar becomes unusable without sight.

Fix

Add an aria-label describing each icon button's action.

<button type="button" className="btn-icon btn-icon-lg hover:preset-tonal">
	<MenuIcon />
</button>
<button type="button" aria-label="Open menu" className="btn-icon btn-icon-lg hover:preset-tonal">
	<MenuIcon />
</button>
AccessibilityCritical

playgrounds/skeleton-react/src/routes/components/floating-panel/index.tsx:21

Panel control buttons have no accessible name for minimize, maximize, or close

`FloatingPanel.StageTrigger` (minimized, maximized, default) and `FloatingPanel.CloseTrigger` each render a bare icon (`MinusIcon`, `MaximizeIcon`, `MinimizeIcon`, `XIcon`) with no `aria-label`.

Why it matters

A keyboard or screen reader user opens the floating panel but has no way to identify which of the four header buttons closes it versus resizes it, so managing the panel becomes guesswork or impossible.

Fix

Add an aria-label to every stage and close trigger stating its action.

<FloatingPanel.StageTrigger stage="minimized">
	<MinusIcon className="size-4" />
</FloatingPanel.StageTrigger>
<FloatingPanel.StageTrigger stage="minimized" aria-label="Minimize panel">
	<MinusIcon className="size-4" />
</FloatingPanel.StageTrigger>
AccessibilitySerious

playgrounds/skeleton-react/src/routes/components/file-upload/index.tsx:26

Delete button on uploaded files has no accessible name

`FileUpload.ItemDeleteTrigger` wraps only `<CircleXIcon />` with no `aria-label`, so the delete action for each uploaded file has no text alternative.

Why it matters

A screen reader user hears an unnamed button next to every file entry, so removing a specific file requires trial and error instead of a direct action.

Fix

Add an aria-label naming the delete action, ideally including the file name for context.

<FileUpload.ItemDeleteTrigger>
	<CircleXIcon />
</FileUpload.ItemDeleteTrigger>
<FileUpload.ItemDeleteTrigger aria-label={`Remove ${file.name}`}>
	<CircleXIcon />
</FileUpload.ItemDeleteTrigger>
98/100

Typography

1 serious
TypographySerious

playgrounds/skeleton-react/src/routes/components/file-upload/index.tsx:25

Raw byte count makes file size unreadable at a glance

`FileUpload.ItemSizeText` renders `{file.size} bytes` directly, so a 2MB file shows as "2097152 bytes" instead of a human-readable unit.

Why it matters

Users scanning a file list can't compare sizes at a glance and have to mentally parse large digit strings, which slows down file management decisions.

Fix

Format byte counts into KB/MB/GB with a shared formatter before rendering.

<FileUpload.ItemSizeText>{file.size} bytes</FileUpload.ItemSizeText>
<FileUpload.ItemSizeText>{formatBytes(file.size)}</FileUpload.ItemSizeText>

Get this score on every PR.

Rams reviews each pull request on your repo and posts inline one-click fixes — about a minute per review.

Install Rams free
98/100

Spacing

1 serious
Design SystemSerious

playgrounds/skeleton-react/src/routes/components/app-bar/index.tsx:24

Toolbar grid template hand-typed as an arbitrary value with no shared source

`AppBar.Toolbar` uses `className="grid-cols-[auto_1fr_auto]"` as a raw arbitrary Tailwind value. The same three-column pattern repeats across the default, centered, and other app bar variants in this file with no shared constant.

Why it matters

Because the grid definition is retyped instead of shared, one variant can silently drift to a different column layout during an edit and nobody notices until the header misaligns.

Fix

Extract the repeated grid template into a single named constant or utility class shared by all app bar variants.

<AppBar.Toolbar className="grid-cols-[auto_1fr_auto]">
const TOOLBAR_GRID = 'grid-cols-[auto_1fr_auto]';
// ...
<AppBar.Toolbar className={TOOLBAR_GRID}>

Color

No issues found

Components

No issues found

Motion

No issues found

UX

No issues found

Craft

No issues found

Working well

  • FileUpload uses the compound component pattern with a Context render-prop (`fileUpload.acceptedFiles.map`) to render each item, keeping file list logic declarative and letting the primitive own state instead of hand-rolling it.
  • The Control cluster in the floating panel groups minimize, maximize, restore, and close triggers together in the header, matching the familiar window-chrome convention users already know from OS windows.
  • All three app bar variants reuse the same `btn-icon`/`btn-icon-lg` utility classes for their icon buttons, keeping the icon button sizing and hover treatment visually consistent across examples.

Scored August 1, 2026 with Rams Engine v0.0.3 · Engine changelog
First scored July 29, 2026: 59/100. This rescore on v0.0.3: 59/100.

This page is an automated design review of skeletonlabs/skeleton’s UI code: 30 files read against 291 versioned rules covering accessibility, color, typography, spacing, components, UX, motion, and craft. The score is out of 100; confirmed criticals cap it — one at 59, two at 49, three or more at 39.

More design scores

Score your own repo.

Free on public repos, no account. The same engine that scored this page reads your UI code and mints a score page like this one.

Public repos only. The full engine reviews the UI code and mints a public score page — we email you the link too. Already-scored repos open instantly.

Or get a design review on every pull requestInstall Rams