-
Notifications
You must be signed in to change notification settings - Fork 361
feat: draft UI for prerequisite summary #4401
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
9c8fa06
b041ec0
c80a112
3a74cc1
6ae0745
718b325
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| @import '~styles/utils/modules-entry'; | ||
|
|
||
| .tooltip { | ||
| padding: 0.75rem 1rem; | ||
| } | ||
|
|
||
| .trigger { | ||
| display: inline-flex; | ||
| flex-shrink: 0; | ||
| justify-content: center; | ||
| align-items: center; | ||
| padding: 0.15rem; | ||
| border: 0; | ||
| line-height: 0; | ||
| color: var(--gray-light); | ||
| background: transparent; | ||
| cursor: pointer; | ||
|
|
||
| &:hover, | ||
| &:focus { | ||
| outline: none; | ||
| color: theme-color(); | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Prompt To Fix With AIThis 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.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same fix as above — addressed in 3a74cc1. |
||
|
|
||
| :global(.svg) { | ||
| display: block; | ||
| width: 1.1rem; | ||
| height: 1.1rem; | ||
| } | ||
| } | ||
|
|
||
| .content { | ||
| max-width: 28rem; | ||
| font-size: $font-size-sm; | ||
| text-align: left; | ||
| white-space: pre-wrap; | ||
| word-break: break-word; | ||
| color: var(--tooltip-color); | ||
|
|
||
| :global(a) { | ||
| color: theme-color(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| import { screen } from '@testing-library/react'; | ||
| import { Provider } from 'react-redux'; | ||
|
|
||
| import { initAction } from 'test-utils/redux'; | ||
| import reducers from 'reducers'; | ||
| import configureStore from 'bootstrapping/configure-store'; | ||
| import renderWithRouterMatch from 'test-utils/renderWithRouterMatch'; | ||
| import RequisiteRulePopup from './RequisiteRulePopup'; | ||
|
|
||
| describe(RequisiteRulePopup, () => { | ||
| function make(rule: string, summary?: string) { | ||
| const initialState = reducers(undefined, initAction()); | ||
| const { store } = configureStore(initialState); | ||
|
|
||
| return renderWithRouterMatch( | ||
| <Provider store={store}> | ||
| <RequisiteRulePopup rule={rule} summary={summary} /> | ||
| </Provider>, | ||
| {}, | ||
| ); | ||
| } | ||
|
|
||
| it('renders nothing when rule matches summary', () => { | ||
| const rule = 'CS1010 or its equivalent'; | ||
| const { view } = make(rule, rule); | ||
| expect(view.container).toBeEmptyDOMElement(); | ||
| }); | ||
|
|
||
| it('renders info icon with accessible label', () => { | ||
| make('PROGRAM_TYPES IF_IN Undergraduate Degree THEN (COURSES (1) CS1010:D)', 'CS1010'); | ||
|
|
||
| expect( | ||
| screen.getByRole('button', { name: 'View detailed prerequisite rule' }), | ||
| ).toBeInTheDocument(); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| import { Info } from 'react-feather'; | ||
|
|
||
| import LinkModuleCodes from 'views/components/LinkModuleCodes'; | ||
| import Tooltip from 'views/components/Tooltip'; | ||
| import styles from './RequisiteRulePopup.scss'; | ||
|
|
||
| type Props = { | ||
| rule: string; | ||
| summary?: string; | ||
| label?: string; | ||
| }; | ||
|
|
||
| /** | ||
| * Info icon that shows the full structured requisite rule in a popup. | ||
| */ | ||
| export default function RequisiteRulePopup({ | ||
| rule, | ||
| summary, | ||
| label = 'View detailed prerequisite rule', | ||
| }: Props) { | ||
| if (!rule.trim()) return null; | ||
| if (summary?.trim() === rule.trim()) return null; | ||
|
|
||
| const content = ( | ||
| <div className={styles.content}> | ||
| <LinkModuleCodes>{rule}</LinkModuleCodes> | ||
| </div> | ||
| ); | ||
|
|
||
| return ( | ||
| <Tooltip | ||
| content={content} | ||
| interactive | ||
| arrow | ||
| placement="bottom" | ||
| maxWidth="none" | ||
| touch="hold" | ||
| className={styles.tooltip} | ||
| > | ||
| <button type="button" className={styles.trigger} aria-label={label}> | ||
| <Info className="svg svg-small" size={18} strokeWidth={2} /> | ||
| </button> | ||
| </Tooltip> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
outline: noneon:focusdiscards the browser's default focus ring for keyboard users. The icon color change alone (from--gray-lighttotheme-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
There was a problem hiding this comment.
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-visibleoutline (2px solid currentColorwith offset) while keepingoutline: noneonly for:focus:not(:focus-visible).