Redesign shared frontend UX primitives #434
No reviewers
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:open_issues
agents
agent:security_audit
agent:verify
area
timecurve
arena
arena-v2
audit
block:feature_review
block:security
bug
contracts
design
devops
docs
documentation
enhancement
epic
feature
frontend
indexer
low priority
megaeth
operations
ops
performance
QA
qa checklist
referrals
removal
security
smart-contracts
tech-debt
testing
time-arena
timecurve
visual-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
code/yieldomega!434
Loading…
Reference in a new issue
No description provided.
Delete branch "cursor/frontend-shared-ux-primitives-86f7"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
SharedUxPrimitives.test.tsx, refreshes the/arenaPlaywright selector for the current production buy surface, and documents the #294 design/invariant/manual-QA contract.Related issues
Related to #294. Leave issue open until maintainer acceptance.
Layers touched
contracts/)indexer/)frontend/)scripts/,.cursor/, CI)bots/)Design review notes
Acceptance checklist
/arena,/referrals, and other routescd frontend && npm run typecheck && npm run lint && npm test;CI=1 npm run test:e2e -- --workers=5 e2e/arena.spec.ts e2e/referrals-surface.spec.tsWalletProfileModalSections.test.tsxinnpm test; shared placeholder markup inWalletProfileModalSections.tsxSharedUxPrimitives.test.tsxasserts blockie + visible last-six label and profile action behaviorchainMismatchWriteGuard.test.tsPASS;bash scripts/verify-rabby-chain-mismatch.shattempted twicecd frontend && npm run typecheck && npm run lint && npm test; focused Playwright with 5 workersbash scripts/check-doc-anchors.sh; manual review of design, arena views, invariants, manual QAVerification details
cd frontend && npm run typecheck && npm run lint && npm testbash scripts/check-doc-anchors.shbash scripts/qa/build-frontend-for-rabby.shcast block-number --rpc-url http://127.0.0.1:8545;curl -sf http://127.0.0.1:3100/v1/statusCI=1 npm run test:e2e -- --workers=5 e2e/arena.spec.ts e2e/referrals-surface.spec.tsbash scripts/verify-rabby-chain-mismatch.sh(twice); directeth_requestAccountsRabby probepage.evaluate: Target page, context or browser has been closedatrequestSwitchChain; direct approval probe also closed contextVisual/design verification checklist for third parties
/arena: buy panel, live-buy rows, podium rows, amount displays, empty/loading states, and indexer status use dark tactical glass, compact copy, and no stale sale/redemption framing.switch-to-target-chainremains reachable. Blocked for full sign-off in this agent run by Rabby context closure; re-run on a stable Rabby profile/desktop./referrals: register gate, leaderboard address rows, empty states, and status messages match shared primitive styling without changing explorer-link behavior.Accessibility / responsive notes
StatusMessageandEmptyDataPlaceholdernow forward ARIA/test attributes cleanly./arenaand/referrals; manual QA should still cover 390x844 and desktop widths for visual sign-off.Blockers
wallet_switchEthereumChain/ account approval. The app, Anvil, indexer, and non-mock preview were healthy; this appears isolated to the Rabby extension/profile automation path.Licensing and compliance
Notes for reviewers
Invariant added:
INV-FRONTEND-294-SHARED-PRIMITIVES.Author checklist
added 1 commit
1e1d4cfa- Allow data attributes on status messagesCompare with previous version
added 1 commit
d0a2ee92- Refine shared primitive address testCompare with previous version
Security review
Commit reviewed:
d0a2ee9206c13217a0a947642551404d32a57735Scope: Frontend presentation-only UX primitive redesign (
StatusMessage,EmptyDataPlaceholder, chain-mismatch gate copy, indexer status bar, wallet profile empty/loading states, shared CSS). Docs/tests only outsidefrontend/.Outcome:
FINDINGS: 0medium+Summary: Security review: no medium+ findings on this diff.
Traced attacker-controlled input paths for the modified components:
StatusMessage/EmptyDataPlaceholdernow forwardHTMLAttributes(data-*,role, etc.) via...rest. No caller spreads untrusted props; dynamic copy still flows only through React-escapedchildren. NodangerouslySetInnerHTMLusage in the repo.ChainMismatchWriteBarrierrendersconfiguredChain()name/id from build-timeVITE_*env — not runtime user input.IndexerStatusBardisplays indexerschema_version/ block in text nodes (React-escaped); copy-only change.Inline threads: none (no medium+ findings).
added 1 commit
3bcd1873- Update arena E2E buy surface assertionCompare with previous version
Security review
Commit reviewed:
3bcd1873ff0a1a58462e8f2cab2f97a07b782b05Scope: Full MR diff vs
main— shared frontend UX primitives (StatusMessage,EmptyDataPlaceholder, chain-mismatch gate, indexer status bar, wallet profile states, shared CSS, docs/tests). Incremental delta since prior review (d0a2ee9):frontend/e2e/arena.spec.tsassertion update only.Outcome:
FINDINGS: 0medium+Summary: Security review: no medium+ findings on this diff.
Attacker-input tracing on modified runtime paths:
StatusMessage/EmptyDataPlaceholderforwardHTMLAttributesvia...rest(commit1e1d4cf). Call sites pass only staticdata-testid/role/className; dynamic copy (indexer notes, validation errors, API error strings) flows exclusively through React-escapedchildren. NodangerouslySetInnerHTMLin the frontend tree.ChainMismatchWriteBarriertitlestrings interpolateconfiguredChain()name/id from build-timeVITE_*env — not runtime user or indexer input.overlayBodyis unused by callers.IndexerStatusBarrenders indexerschema_version/ block inside a text node (<span>{line}</span>); copy-only styling change.3bcd187adjusts Playwright visibility assertions only — no production code.Inline threads: none (no medium+ findings).
Security review
Commit reviewed:
3bcd1873ff0a1a58462e8f2cab2f97a07b782b05Scope: Frontend presentation-only UX primitive redesign (
StatusMessage,EmptyDataPlaceholder, chain-mismatch gate copy, indexer status bar, wallet profile empty/loading states, shared CSS), plus E2E assertion update infrontend/e2e/arena.spec.ts. Docs/tests only outside runtime behavior.Outcome:
FINDINGS: 0medium+Summary: Security review: no medium+ findings on this diff.
Re-reviewed since prior pass on
d0a2ee92(new commit3bcd1873adjusts Playwright selectors only; no new runtime sinks).Traced attacker-controlled input paths for modified components:
StatusMessage/EmptyDataPlaceholderforwardHTMLAttributes(data-*,role, etc.) via...rest. No caller spreads untrusted props; dynamic copy still flows only through React-escapedchildren. NodangerouslySetInnerHTMLusage in the frontend.ChainMismatchWriteBarrierrendersconfiguredChain()name/id from build-timeVITE_*env — not runtime user input; React escapes attribute/text interpolation.IndexerStatusBardisplays indexerschema_version/ block in text nodes (React-escaped); copy-only change.Inline threads: none (no medium+ findings).
changed the description
Security review
Commit reviewed:
3bcd1873ff0a1a58462e8f2cab2f97a07b782b05Scope: MR !434 full diff vs
main— shared frontend UX primitives (StatusMessage,EmptyDataPlaceholder,ChainMismatchWriteBarrier,IndexerStatusBar,WalletProfileModalSections, shared CSS inindex.css), docs/invariants/QA,SharedUxPrimitives.test.tsx, andfrontend/e2e/arena.spec.tsselector update.Outcome:
FINDINGS: 0medium+Summary: Security review: no medium+ findings on this diff.
Re-reviewed prior security threads on this MR; none reported medium+ issues and all still hold on the current SHA.
Attacker-input tracing on modified runtime paths:
StatusMessage/EmptyDataPlaceholder: widen props to forwardHTMLAttributesvia...rest(data-*,role, etc.). Call sites pass static developer props only; dynamic strings (indexer errors, validation copy) remain React-escapedchildren. NodangerouslySetInnerHTMLintroduced; no caller spreads untrusted attribute objects.ChainMismatchWriteBarrier:configuredChain()name/id come from build-timeVITE_CHAIN_ID/VITE_CHAIN_NAME— not end-user runtime input. JSX text/titleinterpolation is React-escaped.IndexerStatusBar: indexerschema_version/ block values are rendered as plain text nodes (React-escaped); presentation copy change only.index.css: static design tokens and glass styling; no dynamicurl(),content:, or user-controlled CSS variables.Inline threads: none (no medium+ findings).
mentioned in commit
dd2be31eb8mentioned in commit
60a5232ff3