Skip to content

fix(apollo-wind): quality pass across the component library (coverage gate, exports, a11y, tokens, API consistency) - #1075

Open
snuziale wants to merge 10 commits into
mainfrom
claude/apollo-wind-components-ryttd5
Open

fix(apollo-wind): quality pass across the component library (coverage gate, exports, a11y, tokens, API consistency)#1075
snuziale wants to merge 10 commits into
mainfrom
claude/apollo-wind-components-ryttd5

Conversation

@snuziale

Copy link
Copy Markdown
Collaborator

Summary

A quality pass over packages/apollo-wind addressing seven audit findings. No breaking API changes; all existing exports keep their signatures (a few gain refs, variants, or data-slot attributes).

1. The coverage gate was a silent no-op

vitest.config.ts declared lines/functions/branches/statements: 80 directly under coverage, where Vitest ignores them, so coverage never failed CI. They now live under coverage.thresholds as a ratcheting floor (lines 60, functions 63, branches 54, statements 58) calibrated just below current coverage, with Storybook-only src/templates excluded from the metric (they are already excluded from the published build).

2. Finished components were unreachable

  • chart (341-line Recharts wrapper) and drawer (vaul) are now exported from the ui barrel and the package root.
  • portal-container, lockable-value-field, and variable-picker were missing from the ui barrel.
  • src/foundation design tokens (colors, spacing, radius, shadows, strokes, typography, responsive) got an index and a new ./foundation exports subpath, so tokens are importable from JS for the first time.

3. Story and test gaps closed

  • New stories: avatar, chart, drawer, editable-cell, table, collapsible, portal-container, canvas-studio, flow-properties-simple, viewport-guard, form-state-viewer, schema-viewer.
  • New tests: chart, drawer, editable-cell, button-group, command, datetime-picker, layout row/column/grid, all 14 custom/ components, form-designer (previously the largest untested file), form-plugins, form-state-viewer, schema-viewer. Every new test file includes a jest-axe check.
  • Package suite grows from ~800 to 1402 tests across 92 files, all green; statements coverage rises from 43% to 62%, functions from 42% to 68%.

4. Accessibility

  • Named every icon-only control that lacked an accessible name: tree-view expand/actions/details buttons, form-designer move/delete/edit buttons, section chevrons, the Always-required checkbox, rule-builder selects, panel-flow rail nav, and the field-renderer/flow-properties select triggers.
  • The prompt-editor Edit/Preview switcher is now a labelled fieldset with aria-pressed state instead of color-only indication.
  • The form-designer axe test now enforces button-name; only two structural exclusions remain (documented in the test).

5. Semantic tokens instead of raw palette values

  • Replaced green/red/orange/yellow/blue/gray-* classes with success/warning/error/info/muted tokens in form-designer, tree-view, stats-card, form-state-viewer, and form-examples.
  • Replaced the duplicated bg-[#0092b8] logo-tile hex in panel-delegate/panel-flow with the brand token.
  • Unified the dialog/alert-dialog/sheet/drawer overlays on the theme-aware bg-curtain scrim token (previously three different raw bg-black opacities, none dark-mode aware).

6. API consistency

  • Adopted the shadcn v4 data-slot convention across all ui/ components (51 files). This also fixes a latent bug: calendar.tsx shipped selectors targeting [data-slot=card-content] and [data-slot=popover-content] that never matched because card and popover did not set the attribute.
  • stats-card variants moved from a per-render object literal to cva; avatar gained a cva size variant (sm/default/lg, default unchanged).
  • combobox, date-picker, date-range-picker, datetime-picker, file-upload, and tree-view now forward refs like the rest of the library.

7. Packaging cleanups

  • tailwindcss removed from dependencies (nothing shipped imports it; @tailwindcss/cli and @tailwindcss/postcss bring their own), eliminating the duplicate-Tailwind risk in consumer graphs. @tailwindcss/postcss and autoprefixer stay in dependencies (required at consumer runtime by the ./postcss export) and lost their duplicate devDependency entries.
  • Audited react-hook-form/zod: kept as regular dependencies since the package ships unbundled and npm dedupe handles compatible ranges; promoting them to peers would break existing consumers.
  • Fixed the biome !templates exclusion that never matched src/templates, deleted the empty src/components/UiPath/ directory, and removed the deprecated fontFamily.sans alias (all call sites already use .base).

Validation

  • turbo run build --filter=@uipath/apollo-wind (including apollo-core) green; dist/foundation/ output verified.
  • biome format and biome lint: zero errors.
  • tsc --noEmit: clean.
  • check-dependency-version-consistency: clean; lockfile regenerated.
  • vitest run --coverage: 1402/1402 tests passing with the new thresholds enforced.

Notes for reviewers

  • The overlay scrim change (bg-black/50|80bg-curtain) is an intentional visual normalization: light theme gets a slightly lighter scrim (30%), dark theme a heavier one (75%), per the apollo-core semantic token.
  • Radix parts that were bare re-exports are now thin wrappers (forwardRef where they render DOM) to carry data-slot, matching shadcn v4; ResizablePanel was intentionally left as a re-export to avoid touching its imperative ref handle.

🤖 Generated with Claude Code

https://claude.ai/code/session_015n5YBa3rwBSxCUjkGNRKbG


Generated by Claude Code

claude added 10 commits August 21, 2026 22:40
…emos

Vitest only enforces limits nested under coverage.thresholds; the
previous top-level lines/functions/branches/statements keys were
silently ignored, so the 80% gate never ran. Nest them under
thresholds with a ratcheting floor based on current coverage, and
exclude src/templates (Storybook-only demos already excluded from the
published build) from the metric.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015n5YBa3rwBSxCUjkGNRKbG
chart and drawer were fully implemented but unreachable: neither the
ui barrel nor the package root exported them. Add both, plus the
missing ui barrel entries for portal-container, lockable-value-field
and variable-picker, and give src/foundation an index so the design
tokens (colors, spacing, radius, shadows, strokes, typography,
responsive) can be imported from JS via the new ./foundation subpath.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015n5YBa3rwBSxCUjkGNRKbG
- drop tailwindcss from dependencies: no shipped code imports it, and
  both @tailwindcss/cli (build) and @tailwindcss/postcss (consumer
  ./postcss export) depend on it themselves, so shipping it as a hard
  dependency only risked a duplicate Tailwind install in consumer
  graphs; it stays in devDependencies
- remove @tailwindcss/postcss and autoprefixer from devDependencies:
  they were duplicated in dependencies, where they must remain because
  postcss.config.export.js imports them at consumer runtime
- add the ./foundation exports subpath for the token barrel
- fix the biome linter exclusion for templates: the !templates glob
  never matched src/templates, so the demo apps were linted against
  the library rules despite the config's intent
- delete src/components/UiPath (an empty index.ts, referenced nowhere)
- remove the deprecated fontFamily.sans alias; all call sites already
  use fontFamily.base

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015n5YBa3rwBSxCUjkGNRKbG
Accessibility:
- tree-view: label the icon-only expand/collapse, actions and details
  buttons with the item name
- form-designer: label the remove-option, edit-rule and delete-rule
  icon buttons
- prompt-editor toolbar: expose the Edit/Preview switcher as a labelled
  group with aria-pressed state instead of color-only state

Semantic tokens:
- replace raw palette classes (green/red/orange/yellow/blue/gray) with
  success/warning/error/info/muted tokens in tree-view, stats-card,
  form-designer, form-state-viewer and form-examples
- replace the duplicated bg-[#0092b8] logo tile hex in panel-delegate
  and panel-flow with the brand token
- unify the dialog, alert-dialog, sheet and drawer overlays on the
  theme-aware bg-curtain scrim token (previously three different raw
  bg-black opacities)

API consistency:
- stats-card: move the per-render variant map into cva variants
- avatar: add a cva size variant (sm, default, lg) with the previous
  h-10 w-10 as the default
- forward refs from combobox, date-picker, date-range-picker,
  datetime-picker, file-upload and tree-view so consumers can manage
  focus, matching the rest of the library

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015n5YBa3rwBSxCUjkGNRKbG
Covers avatar (including the new size variants), chart, drawer,
editable-cell, table, collapsible and portal-container, which shipped
without any Storybook documentation.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015n5YBa3rwBSxCUjkGNRKbG
Adds tests for all 14 components in src/components/custom (106 tests,
each file including a jest-axe check), stories for the three components
that had none (canvas-studio, flow-properties-simple, viewport-guard),
and fixes the two accessibility gaps the new tests surfaced: the
panel-flow rail nav buttons had no resting accessible name (label was
tooltip-only) and the flow-properties-simple select trigger was not
associated with its field label.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015n5YBa3rwBSxCUjkGNRKbG
Adds tests for chart, drawer, editable-cell, button-group, command and
datetime-picker plus the layout row/column/grid primitives (113 tests,
each file including a jest-axe check). The datetime-picker suite also
pins the new ref forwarding to the trigger button.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015n5YBa3rwBSxCUjkGNRKbG
…s ui

data-slot was previously set by only 4 of ~70 components, and
calendar.tsx already shipped selectors targeting
[data-slot=card-content] and [data-slot=popover-content] that never
matched because card and popover did not set the attribute. Add
data-slot to the root element of every exported part in
src/components/ui (51 files), converting bare Radix re-exports to thin
wrappers exactly as shadcn v4 does (forwardRef wrappers wherever the
part renders DOM, so ref behavior is unchanged).

Also swap the prompt-editor mode switcher's role=group div for a
fieldset to satisfy biome's useSemanticElements rule.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015n5YBa3rwBSxCUjkGNRKbG
…a viewers

Adds tests for the previously untested form-designer (the package's
largest file), form-plugins, form-state-viewer and schema-viewer, each
with a jest-axe check, plus stories for form-state-viewer and
schema-viewer. Also re-wraps one over-long line in form-examples to
the biome line width.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015n5YBa3rwBSxCUjkGNRKbG
…coverage floor

Label the icon-only section and field move/delete buttons, the section
accordion chevron, the Always required checkbox and the rule-builder
selects in form-designer, and associate the field-renderer select
trigger with its field label. This lets the form-designer axe test
enforce the button-name rule (only the two structural exclusions
remain). With the new suites in place, raise the enforced coverage
floor to lines 60, functions 63, branches 54, statements 58 (current:
64.8, 67.7, 57.6, 62.3).

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015n5YBa3rwBSxCUjkGNRKbG
@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Apollo Coded App preview deployments are ready.

Project Status Preview Updated (PT)
apollo-design Ready Preview · Logs Aug 21, 2026, 04:15:27 PM
apollo-docs Ready Preview · Logs Aug 21, 2026, 04:15:27 PM
apollo-landing Ready Preview · Logs Aug 21, 2026, 04:15:27 PM
apollo-vertex Ready Preview · Logs Aug 21, 2026, 04:15:27 PM

@github-actions github-actions Bot added the size:XXL 1,000+ changed lines. label Aug 21, 2026
it('sanitizes unsafe characters out of ids and keys', () => {
const { container } = render(
<ChartStyle
id='evil"] { } <script>'
@github-actions

Copy link
Copy Markdown
Contributor

Dependency License Review

  • 1948 package(s) scanned
  • ✅ No license issues found
  • ⚠️ 2 package(s) excluded (see details below)
License distribution
License Packages
MIT 1719
ISC 88
Apache-2.0 55
BSD-3-Clause 27
BSD-2-Clause 23
BlueOak-1.0.0 8
MPL-2.0 4
MIT-0 3
CC0-1.0 3
MIT OR Apache-2.0 2
(MIT OR Apache-2.0) 2
Unlicense 2
LGPL-3.0-or-later 1
Python-2.0 1
CC-BY-4.0 1
(MPL-2.0 OR Apache-2.0) 1
Unknown 1
Artistic-2.0 1
(WTFPL OR MIT) 1
(BSD-2-Clause OR MIT OR Apache-2.0) 1
CC-BY-3.0 1
0BSD 1
(MIT OR CC0-1.0) 1
MIT AND ISC 1
Excluded packages
Package Version License Reason
@img/sharp-libvips-linux-x64 1.3.2 LGPL-3.0-or-later LGPL pre-built binary, not linked
khroma 2.1.0 Unknown MIT per GitHub repo, missing license field in package.json

@github-actions

Copy link
Copy Markdown
Contributor

📊 Coverage + size by package

Per-package coverage and bundle size on this PR. New-line coverage = of the source lines this PR adds or changes, the % hit by tests.

Package Coverage New-line coverage Packed (gzip) Unpacked vs main
@uipath/apollo-core 41.59 MB 49.70 MB ±0
@uipath/apollo-react 7.55 MB 29.08 MB −507 B
@uipath/apollo-ui-icons 2.85 MB 6.91 MB ±0
@uipath/apollo-wind — (no coverage report) 421.3 KB 2.71 MB +5.4 KB
@uipath/ap-chat 43.46 MB 56.09 MB ±0

"Coverage" is each package's own coverage.include scope (e.g. apollo-core instruments only scripts/). "Packed"/"Unpacked" come from npm pack --dry-run and only cover built packages — "—" means not measured this run (package not affected / not built). "vs main" is the packed (gzipped) delta against the last successful main build (the package-sizes artifact from the Release workflow); "—" there means no main baseline was available this run. The baseline is main's latest build, not this PR's exact merge-base, so it includes any drift since the branch diverged. Packages with no vitest config are omitted.

@github-actions

Copy link
Copy Markdown
Contributor

Storybook visual diff

⚠️ Visual changes detected: 62 changed, 38 added (of 946 compared, 846 unchanged). View report

Baseline is the deployed main Storybook, so changes merged to main after this branch was last updated can also appear here. Logs

Updated (PT): Aug 21, 2026, 04:36:14 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg:apollo-wind size:XXL 1,000+ changed lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants