Repository navigation
Conversation
…d to event tabs The + New Event Button was a direct child of the ul element, which is invalid HTML (only li elements are permitted as direct children). Assistive technologies and validators flag this as a structure violation. Additionally, tab links had no ARIA roles — screen readers announced them as plain links in a list rather than interactive tab controls. Moving role=tab and aria-selected to the anchor elements (the actual interactive controls) and consolidating styles onto the Link give screen readers the correct semantics, while wrapping the Button in an li element restores valid HTML. Co-Authored-By: AgenticDiego <noreply@carvallo.io>
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
This branch had an error being deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
$(cat <<'EOF'
Daily Product Improvement
📝 TLDR
Fix invalid HTML and add ARIA tab roles in the guest-list event tabs component.
📝 Description
The
EventsTabscomponent in the guest list rendered a<Button>as a direct child of the<ul>element. Only<li>elements are permitted as direct children of<ul>— this is an HTML validity violation that some browsers and assistive technologies handle unpredictably.At the same time, the tab links had no ARIA semantics: screen readers announced them as plain links in a list rather than as interactive tab controls.
This Change
+ New Event<Button>in a<li>element to restore valid HTML structurerole="tab"andaria-selectedonto the<Link>elements (the actual interactive controls) so assistive technologies correctly identify the tab navigation<li>to the<Link>(addingblockdisplay) so visual behavior is unchangedevents.map()callback from a block return to an implicit returnNo visual change is produced. The fix is structural and semantic only.
Recommendations Reviewed
Area:
guest-list/event-tabs.tsxIssue:
<Button>is a direct child of<ul>— invalid HTML. Tab links have norole="tab"oraria-selected.Recommendation: Wrap Button in
<li>, add tab ARIA roles to Link elements.Type: Frontend cleanup + UX/Accessibility
Priority: High
Effort: Small
Area:
vendors/page.tsxIssue: Any API error (including network timeouts) causes a silent redirect to
/.Recommendation: Redirect only on auth/access errors; show an error state for other failures.
Type: Backend/product flow
Priority: High
Effort: Small
Area:
guest-form.tsxIssue:
mode: 'onChange'triggers validation on every keystroke, causing "invalid" flashes mid-input.Recommendation: Switch to
mode: 'onBlur'ormode: 'onTouched'.Type: UX/UI
Priority: Medium
Effort: Small
Area:
planning-overview.tsx→MilestonesCardIssue: When no milestones exist the card renders an empty body with no explanation or CTA.
Recommendation: Add an empty state with a short description of what milestones are.
Type: UX/UI
Priority: Medium
Effort: Small
Area:
task-dialog.tsxIssue:
type="date"input shows "Use YYYY-MM-DD" as a validation error, but the native date picker never requires manual format entry.Recommendation: Reword to "Please select a valid date" or remove the format hint.
Type: UX/UI
Priority: Medium
Effort: Small
Area:
dashboard-topbar.tsxIssue:
todaystring initialises as''and is set inuseEffect, causing a hydration layout shift.Recommendation: Use
suppressHydrationWarningwith a server-formatted date, or render a fixed-width placeholder.Type: UX/UI
Priority: Medium
Effort: Small
Area:
sidebar-nav.tsxIssue:
isActiveusespathname.startsWith(href), which could match/eventsfor a hypothetical/events-legacyroute.Recommendation: Guard with
pathname === href || pathname.startsWith(href + '/').Type: Frontend cleanup
Priority: Medium
Effort: Small
Area:
guests-view.tsxIssue: Filtered-empty state ("No households yet") is identical to the zero-guests state, conflating two distinct situations.
Recommendation: Show "No guests match your search" with a clear-filters button when filters are active.
Type: UX/UI
Priority: Medium
Effort: Small–Medium
Area:
guests-view.tsxIssue: Tags are silently truncated to 4 with no
+N moreindicator.Recommendation: Add a
+Nbadge whenuniqueTagIds.length > 4.Type: UX/UI
Priority: Low
Effort: Small
Area:
vendor-card.tsxIssue:
priceDisplay()is called twice in the same JSX expression (once in the condition, once to render the value).Recommendation: Capture in a
const price = priceDisplay()variable.Type: Frontend cleanup
Priority: Low
Effort: Tiny
Selected Improvement
Fix
event-tabs.tsx: wrap the+ New EventButton in a<li>(valid HTML) and addrole="tab"+aria-selectedto the Link elements (ARIA tab semantics).Why This Was Selected
This was the highest-priority unfixed issue across both the HTML validity and accessibility dimensions. The
<Button>as a direct child of<ul>is a structural HTML violation (WCAG SC 1.3.1 Info and Relationships) and the missing ARIA tab roles mean screen readers cannot navigate the guest list event filter as a tab control. The change is confined to a single 57-line file, produces no visual change, passes all existing tests, and is easy to verify.Changes Made
<li>wrapper around the+ New Event<Button>elementrole="tab"andaria-selectedto each<Link>tab elementborder-b-2,py-3,text-sm, and hover/active className from<li>to<Link>, withblockadded so the anchor fills its list-item containerevents.map()from a block-body return to an implicit arrow-function returnFiles Changed
src/components/guest-list/event-tabs.tsxVerification
tsc --noEmit) passes with zero errorsFuture Recommendations
Recommendation: Redirect only on auth errors in vendors and budget pages; show a proper error state for transient API failures.
Priority: High
Effort: Small
Reason not included: Separate concern from today's accessibility fix; warrants its own targeted PR.
Should become GitHub issue: Yes
Recommendation: Switch guest-form validation to
mode: 'onBlur'to eliminate mid-keystroke "invalid" flashes.Priority: Medium
Effort: Small
Reason not included: Form behaviour change; best reviewed in isolation.
Should become GitHub issue: No
Recommendation: Add empty state to
MilestonesCardwhen no milestones exist.Priority: Medium
Effort: Small
Reason not included: Dashboard UI change best batched with related dashboard improvements.
Should become GitHub issue: No
Recommendation: Fix
isActivegreedy prefix match insidebar-nav.tsx.Priority: Medium
Effort: Small
Reason not included: Low immediate risk; no known route collision today. Good candidate for a future cleanup PR.
Should become GitHub issue: No
Recommendation: Distinguish filtered-empty from zero-guests empty state in
guests-view.tsx.Priority: Medium
Effort: Small–Medium
Reason not included: Requires copy changes and a clear-filters action; better handled as part of a broader guest-list UX improvement pass.
Should become GitHub issue: Yes
GitHub Issues Created or Proposed
No issues created this run. The two High/Medium candidates (vendor error redirect, guest-list empty-state distinction) are noted under Future Recommendations and should be tracked as issues in the next triage pass.
Generated by Claude Code