Skip to content

fix(F0Alert): stability audit BLOCKING fixes#3900

Open
eliseo-juan wants to merge 1 commit intomainfrom
fix/stability-3873-f0alert
Open

fix(F0Alert): stability audit BLOCKING fixes#3900
eliseo-juan wants to merge 1 commit intomainfrom
fix/stability-3873-f0alert

Conversation

@eliseo-juan
Copy link
Copy Markdown
Contributor

Summary

Applies all BLOCKING findings from stability audit issue #3873.

  • alertVariantOptions const array — export from types.ts, derive AlertVariant from it; use in stories argTypes
  • variant now optional — has default "neutral" in component, type must match
  • Remove dead useRef/containerRef — created but never read
  • role on alert containerrole="alert" for critical/warning, role="status" otherwise (WCAG 4.1.3)
  • sr-only new-tab warning<span className="sr-only"> (opens in new tab)</span> on target="_blank" link (WCAG 2.4.4)
  • Stories: satisfies Meta<typeof F0Alert>, StoryObj<typeof meta>, alertVariantOptions in argTypes, Snapshot story with all 5 variants
  • Create __tests__/F0Alert.test.tsx — 13 tests covering all behaviors

Related

Quality gate

  • pnpm tsc --noEmit
  • pnpm lint
  • pnpm vitest:ci src/components/F0Alert ✅ (13/13 passing)

- Add alertVariantOptions const array, derive AlertVariant from it
- Make variant optional in F0AlertProps (has default in component)
- Remove dead useRef / containerRef
- Add role=alert (critical/warning) or role=status to alert container
- Add sr-only new-tab warning to target=_blank link
- Fix meta to use satisfies pattern, StoryObj<typeof meta>
- Import alertVariantOptions for argTypes options
- Add withSnapshot import and Snapshot story (all 5 variants)
- Create __tests__/F0Alert.test.tsx (13 tests, full coverage)
Copilot AI review requested due to automatic review settings April 8, 2026 16:17
@eliseo-juan eliseo-juan requested a review from a team as a code owner April 8, 2026 16:17
@github-actions github-actions bot added the fix label Apr 8, 2026
@github-actions github-actions bot added the react Changes affect packages/react label Apr 8, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

✅ No New Circular Dependencies

No new circular dependencies detected. Current count: 0

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

📦 Alpha Package Version Published

Use pnpm i github:factorialco/f0#npm/alpha-pr-3900 to install the package

Use pnpm i github:factorialco/f0#b57f598f3090e44d9d48cea519faf521e0c35a0d to install this specific commit

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Addresses the BLOCKING findings from the F0Alert stability audit (#3873) by aligning types with component defaults, improving accessibility semantics, updating Storybook patterns, and adding behavioral tests for the component.

Changes:

  • Export alertVariantOptions and derive AlertVariant from it; make variant optional to match the component default.
  • Add variant-derived ARIA role to the alert container and add an sr-only “opens in new tab” warning for _blank links.
  • Update Storybook meta/story typings and add Snapshot story; add a new Vitest test suite covering core behaviors.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
packages/react/src/components/F0Alert/types.ts Introduces exported alertVariantOptions, derives AlertVariant, and makes variant optional.
packages/react/src/components/F0Alert/F0Alert.tsx Removes dead ref, adds container role logic, and adds sr-only new-tab warning in link.
packages/react/src/components/F0Alert/stories/F0Alert.stories.tsx Updates Storybook meta/story typing patterns, uses alertVariantOptions in argTypes, and adds Snapshot story.
packages/react/src/components/F0Alert/tests/F0Alert.test.tsx Adds a new test suite covering rendering, actions/links, roles, default variant, and dataTestId.

Comment on lines +53 to +58
const alertRole =
variant === "critical" || variant === "warning" ? "alert" : "status"

return (
<div ref={containerRef} className="@container">
<div className={alertVariants({ variant })}>
<div className="@container">
<div role={alertRole} className={alertVariants({ variant })}>
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new container role={alertRole} may not have the intended effect because F0AvatarAlert renders role="alert" unconditionally. That means info/positive variants still expose a nested role="alert" region (and critical/warning may expose multiple). Consider hiding the avatar/icon wrapper from the accessibility tree (e.g., aria-hidden) and/or ensuring F0AvatarAlert doesn’t set role="alert" when used decoratively inside an alert container.

Copilot uses AI. Check for mistakes.
Comment on lines +91 to +113
it("renders role=alert for critical variant", () => {
render(<F0Alert title="Critical" description="Urgent" variant="critical" />)

// The alert container and F0AvatarAlert both use role="alert" for critical/warning
const alertRegions = screen.getAllByRole("alert")
expect(alertRegions.length).toBeGreaterThanOrEqual(1)
})

it("renders role=alert for warning variant", () => {
render(
<F0Alert title="Warning" description="Be careful" variant="warning" />
)

// The alert container and F0AvatarAlert both use role="alert" for warning
const alertRegions = screen.getAllByRole("alert")
expect(alertRegions.length).toBeGreaterThanOrEqual(1)
})

it("renders role=status for info variant", () => {
render(<F0Alert title="Info" description="FYI" variant="info" />)

expect(screen.getByRole("status")).toBeInTheDocument()
})
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The role-related tests are currently too permissive: getAllByRole("alert") can pass due to F0AvatarAlert’s own role="alert", even if the alert container role logic regresses. Consider asserting the role on the specific container element (e.g., the element wrapping title/description), and for non-critical/warning variants assert there are no role="alert" regions rendered.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

🔍 Visual review for your branch is published 🔍

Here are the links to:

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

Coverage Report for packages/react

Status Category Percentage Covered / Total
🔵 Lines 45.42% 11170 / 24589
🔵 Statements 44.67% 11516 / 25777
🔵 Functions 37.16% 2510 / 6753
🔵 Branches 37.43% 7351 / 19635
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/react/src/components/F0Alert/F0Alert.tsx 100% 100% 100% 100%
packages/react/src/components/F0Alert/types.ts 100% 100% 100% 100%
Generated in workflow #12669 for commit b4d0437 by the Vitest Coverage Report Action

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

Labels

fix react Changes affect packages/react

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Stability audit] F0Alert

2 participants