Skip to content

feat: draft UI for prerequisite summary#4401

Open
jloh02 wants to merge 4 commits into
masterfrom
feat/support-new-api-fields
Open

feat: draft UI for prerequisite summary#4401
jloh02 wants to merge 4 commits into
masterfrom
feat/support-new-api-fields

Conversation

@jloh02
Copy link
Copy Markdown
Member

@jloh02 jloh02 commented May 20, 2026

Closes #4301

@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
nusmods-export Ignored Ignored Preview May 21, 2026 3:04pm
nusmods-website Ignored Ignored Preview May 21, 2026 3:04pm

Request Review

@codecov
Copy link
Copy Markdown

codecov Bot commented May 21, 2026

Codecov Report

❌ Patch coverage is 87.50000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 56.48%. Comparing base (988c6fd) to head (3a74cc1).
⚠️ Report is 229 commits behind head on master.

Files with missing lines Patch % Lines
website/src/views/modules/ModulePageContent.tsx 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4401      +/-   ##
==========================================
+ Coverage   54.52%   56.48%   +1.95%     
==========================================
  Files         274      318      +44     
  Lines        6076     6970     +894     
  Branches     1455     1684     +229     
==========================================
+ Hits         3313     3937     +624     
- Misses       2763     3033     +270     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jloh02 jloh02 marked this pull request as ready for review May 21, 2026 12:51
@jloh02
Copy link
Copy Markdown
Member Author

jloh02 commented May 21, 2026

@greptile

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 21, 2026

Confidence Score: 4/5

Safe to merge; changes are additive UI-only with no data mutations or API calls.

The implementation is straightforward and well-tested for its two primary branches. The only concern is the removal of the focus outline on the trigger button without a visible replacement, which could affect keyboard accessibility. Everything else — the CSS variable extraction, the guard logic in the component, and the layout change — looks correct.

website/src/views/components/module-info/RequisiteRulePopup.scss — the focus style on the trigger button.

Important Files Changed

Filename Overview
website/src/views/components/module-info/RequisiteRulePopup.tsx New component that conditionally renders an info icon tooltip showing the raw prerequisite rule; logic is clean and defensive.
website/src/views/components/module-info/RequisiteRulePopup.scss Styles for the popup trigger and content; outline: none on focus removes keyboard focus indicator without a replacement.
website/src/styles/utils/css-variables.scss Adds --tooltip-bg and --tooltip-color CSS variables for both light and dark modes, replacing the repurposed --gray/--body-bg usage in tippy.css.
website/src/styles/tippy/tippy.css Arrow and background colors updated to use the new dedicated --tooltip-bg / --tooltip-color CSS variables; straightforward rename.
website/src/views/modules/ModulePageContent.tsx Wraps the "Prerequisite Tree" heading in a flex row and conditionally renders RequisiteRulePopup when prerequisiteRule is present.
website/src/views/modules/ModulePageContent.scss Adds sectionHeadingRow flex container that properly nests and overrides the existing sectionHeading styles.
website/src/views/components/module-info/RequisiteRulePopup.test.tsx Tests cover the two key render branches: no-op when rule equals summary, and info button rendered when they differ.
website/src/views/modules/ModuleTree.tsx Minor wording change in the beta-warning banner from "prerequisite text" to "prerequisite information" to match the new UI.
website/src/views/modules/snapshots/ModuleTree.test.tsx.snap Snapshot updated to reflect the wording change in the warning banner.

Sequence Diagram

sequenceDiagram
    participant User
    participant ModulePageContent
    participant RequisiteRulePopup
    participant Tooltip
    participant LinkModuleCodes

    ModulePageContent->>ModulePageContent: Check module.prerequisiteRule
    alt prerequisiteRule exists
        ModulePageContent->>RequisiteRulePopup: rule, summary
        RequisiteRulePopup->>RequisiteRulePopup: rule.trim() empty? return null
        RequisiteRulePopup->>RequisiteRulePopup: "summary === rule? return null"
        RequisiteRulePopup->>Tooltip: Render info button trigger
        User->>Tooltip: Hover / hold (touch)
        Tooltip->>LinkModuleCodes: Render rule string
        LinkModuleCodes->>User: Rule text with clickable module code links
    else no prerequisiteRule
        ModulePageContent->>ModulePageContent: Render heading only
    end
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
website/src/views/components/module-info/RequisiteRulePopup.scss:19-23
**Focus outline removed without replacement**

`outline: none` on `:focus` discards the browser's default focus ring for keyboard users. The icon color change alone (from `--gray-light` to `theme-color()`) is unlikely to meet WCAG 2.1 SC 2.4.11's visible focus requirement, and many custom themes may have low contrast between these two values. Consider replacing with a visible focus-visible outline (e.g., `outline: 2px solid currentColor`) instead of suppressing it.

Reviews (1): Last reviewed commit: "Merge branch 'master' into feat/support-..." | Re-trigger Greptile

Comment on lines +19 to +23
&:hover,
&:focus {
outline: none;
color: theme-color();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Focus outline removed without replacement

outline: none on :focus discards the browser's default focus ring for keyboard users. The icon color change alone (from --gray-light to theme-color()) is unlikely to meet WCAG 2.1 SC 2.4.11's visible focus requirement, and many custom themes may have low contrast between these two values. Consider replacing with a visible focus-visible outline (e.g., outline: 2px solid currentColor) instead of suppressing it.

Prompt To Fix With AI
This is a comment left during a code review.
Path: website/src/views/components/module-info/RequisiteRulePopup.scss
Line: 19-23

Comment:
**Focus outline removed without replacement**

`outline: none` on `:focus` discards the browser's default focus ring for keyboard users. The icon color change alone (from `--gray-light` to `theme-color()`) is unlikely to meet WCAG 2.1 SC 2.4.11's visible focus requirement, and many custom themes may have low contrast between these two values. Consider replacing with a visible focus-visible outline (e.g., `outline: 2px solid currentColor`) instead of suppressing it.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in 3a74cc1 — split hover/focus styles and added a :focus-visible outline (2px solid currentColor with offset) while keeping outline: none only for :focus:not(:focus-visible).

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 21, 2026

Confidence Score: 4/5

Safe to merge; the new popup is an additive UI element and the CSS variable refactor corrects an existing dark-mode bug rather than introducing new regressions.

The only non-trivial concern is that the trigger button suppresses the browser focus ring entirely without a keyboard-accessible replacement, which could affect users navigating by keyboard. Everything else — the early-return guards, tooltip content rendering, CSS variable scoping, and test coverage — looks correct.

website/src/views/components/module-info/RequisiteRulePopup.scss — the .trigger focus styles warrant a second look for accessibility.

Important Files Changed

Filename Overview
website/src/views/components/module-info/RequisiteRulePopup.tsx New component that shows the raw structured prerequisite rule in an interactive Tippy tooltip when it differs from the human-readable summary. Logic is clean; early-return guards handle empty and identical strings correctly.
website/src/views/components/module-info/RequisiteRulePopup.scss Styles for the popup trigger and content. Focus outline is removed without a visible replacement, which is a keyboard accessibility concern.
website/src/styles/utils/css-variables.scss Adds --tooltip-bg and --tooltip-color CSS variables for both light and dark modes, fixing a pre-existing dark mode bug where tooltip text was dark-on-dark.
website/src/styles/tippy/tippy.css Migrates tooltip arrow and background references from --gray / --body-bg to the new --tooltip-bg / --tooltip-color variables, correcting dark-mode rendering.
website/src/views/modules/ModulePageContent.tsx Wraps the 'Prerequisite Tree' heading in a flex row and conditionally renders the new RequisiteRulePopup when module.prerequisiteRule is present.

Sequence Diagram

sequenceDiagram
    participant User
    participant ModulePageContent
    participant RequisiteRulePopup
    participant Tooltip
    participant LinkModuleCodes

    ModulePageContent->>ModulePageContent: render Prerequisite Tree section
    alt module.prerequisiteRule is set
        ModulePageContent->>RequisiteRulePopup: rule, summary
        alt "rule.trim() is empty OR summary === rule"
            RequisiteRulePopup-->>ModulePageContent: null
        else rule differs from summary
            RequisiteRulePopup-->>ModulePageContent: Info icon button
            User->>RequisiteRulePopup: hover / focus / hold
            RequisiteRulePopup->>Tooltip: show content
            Tooltip->>LinkModuleCodes: render rule string
            LinkModuleCodes-->>User: rule text with clickable module code links
        end
    end
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
website/src/views/components/module-info/RequisiteRulePopup.scss:19-23
**Focus outline removed without replacement**

`outline: none` on `:focus` suppresses the browser's default focus ring for keyboard users without a visible alternative. The color shift to `theme-color()` on a small icon button is unlikely to meet WCAG 2.4.7 Focus Visible. Consider using `outline: none` only on `:focus:not(:focus-visible)` and keeping the ring for `:focus-visible`, or adding an explicit `box-shadow`/`outline` replacement to keep keyboard navigation accessible.

Reviews (2): Last reviewed commit: "Merge branch 'master' into feat/support-..." | Re-trigger Greptile

Comment on lines +19 to +23
&:hover,
&:focus {
outline: none;
color: theme-color();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Focus outline removed without replacement

outline: none on :focus suppresses the browser's default focus ring for keyboard users without a visible alternative. The color shift to theme-color() on a small icon button is unlikely to meet WCAG 2.4.7 Focus Visible. Consider using outline: none only on :focus:not(:focus-visible) and keeping the ring for :focus-visible, or adding an explicit box-shadow/outline replacement to keep keyboard navigation accessible.

Prompt To Fix With AI
This is a comment left during a code review.
Path: website/src/views/components/module-info/RequisiteRulePopup.scss
Line: 19-23

Comment:
**Focus outline removed without replacement**

`outline: none` on `:focus` suppresses the browser's default focus ring for keyboard users without a visible alternative. The color shift to `theme-color()` on a small icon button is unlikely to meet WCAG 2.4.7 Focus Visible. Consider using `outline: none` only on `:focus:not(:focus-visible)` and keeping the ring for `:focus-visible`, or adding an explicit `box-shadow`/`outline` replacement to keep keyboard navigation accessible.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Same fix as above — addressed in 3a74cc1.

Use :focus-visible with a visible outline so keyboard users can see focus
while mouse clicks still suppress the default ring.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add PrerequisiteRule support to frontend

1 participant