Skip to content

Commit

Permalink
docs(website): include multiple choice pattern page
Browse files Browse the repository at this point in the history
  • Loading branch information
cafrias committed Apr 4, 2024
1 parent 6f219aa commit 112cdd4
Show file tree
Hide file tree
Showing 14 changed files with 230 additions and 4 deletions.
1 change: 1 addition & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"microbundle",
"mixins",
"multiselect",
"multiplechoice",
"Myxococcus",
"Patil",
"popperjs",
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/components/FeedbackModal/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { FeedbackModal } from './FeedbackModal';
export type { FeedbackModalProps } from './types';
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,14 @@ export const ResponseIndicator: React.FC<ResponseIndicatorProps> = ({
const uniqueId = useId();
const id = idProp || uniqueId;

const containerClassName = classNames(BASE_NAME, `${BASE_NAME}--${variant}`, {
[`${BASE_NAME}--${placementIcon}`]: withIcon,
}, className);
const containerClassName = classNames(
BASE_NAME,
`${BASE_NAME}--${variant}`,
{
[`${BASE_NAME}--${placementIcon}`]: withIcon,
},
className,
);

return (
<div className={containerClassName}>
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from './Checkbox';
export * from './ChoiceField';
export * from './Disclosure';
export * from './Dropdown';
export * from './FeedbackModal';
export * from './Field';
export * from './Icon';
export * from './Link';
Expand Down
2 changes: 2 additions & 0 deletions packages/react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export * from './providers';

// Public utilities
export * from './utilities';

export * from './patterns';
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { styles } from './styles';
import { LabelType, OnSelectInput } from './types';
import { resolveLabelType } from './utils';

interface MultipleChoiceProps {
export interface MultipleChoiceProps {
stem: string | React.ReactElement<void, typeof Stem>;
intro?: string | React.ReactElement<void, typeof Intro>;
instructions?: string | React.ReactElement<void, typeof Instructions>;
Expand Down
2 changes: 2 additions & 0 deletions packages/react/src/patterns/MultipleChoice/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './MultipleChoice';
export * from './useMultipleChoice';
1 change: 1 addition & 0 deletions packages/react/src/patterns/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './MultipleChoice';
16 changes: 16 additions & 0 deletions website/docs/patterns/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: Patterns
slug: /patterns
---

import { Features, FeatureCard } from '@website/components';

> Components organized to offer an optimal UI solution based on best practices.
Our patterns classify and document reusable solutions built to respond to common user scenarios. Following these guidelines allows us to create experiences that are consistent, accessible, and natural for users as they move between our digital products ensuring that our approach aligns with industry standards.

<Features basePath="/docs/patterns/" columns={3}>
<FeatureCard title="Multiple Choice Question" slug="multiple-choice-pattern">
A multiple choice question presents a question and set of predefined answer options, allowing for one answer choice submission.
</FeatureCard>
</Features>
188 changes: 188 additions & 0 deletions website/docs/patterns/multiple-choice-pattern.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
---
title: Multiple Choice Pattern
description: A multiple choice question presents a question and set of predefined answer options, allowing for one answer choice submission.
---

import useBaseUrl from '@docusaurus/useBaseUrl';
import { MultipleChoice, FeedbackModal } from '@wwnds/react';
import { PropsTable } from '@website/components';

> A multiple choice question presents a question and set of predefined answer options, allowing for one answer choice submission.
:::warning
This Multiple-Choice Pattern documentation has been released in Beta format. Questions or concerns? [Please let us know.](mailto:[email protected])
:::

## Anatomy

<img
alt="Anatomy of the Multiple Choice Pattern"
src={useBaseUrl('/img/multiple-choice-anatomy.png')}
/>

<img
alt="Anatomy of the Multiple Choice Pattern"
src={useBaseUrl('/img/anatomy-feedback-modal.png')}
/>

1. **Question Intro** (optional) - introductory content that helps frame the question.
1. **Question Stem** - the prompt the user responds to.
1. **Instructions** (optional) - text displaying how many attempts a user may submit an answer and instructions to how to complete a question*, ideally located after the question stem.
1. **[Radio Button](../components/radio-group)** - an input that allows the user to select one answer and reflects the selection state.
1. **Answer Choice Identifier** - a letter or number that identifies each answer choice.
1. **Answer Choice** - a choice in response to the question stem that allows the user to select an answer.
1. **Response Indicator** (optional) - a label that signifies whether a selected response is correct or incorrect which appears next to the selected option after an answer has been submitted.
1. **Submit [Button](../components/button)** - a button that submits the chosen answer.
1. **Feedback [Modal](../components/modal)** - a modal dialog that provides feedback about the chosen answer after it is submitted.
1. Feedback Modal Options:
1. General Feedback - the chosen answer and whether it is correct or incorrect 1. Supplementary Feedback (optional) - additional answer-specific content



## Usage

- Multiple choice questions only have one correct answer, and use radio buttons (not buttons or dropdowns) to display answer choices.

**Why:** The consistent use of radio buttons for answer choices, though beneficial for all users, has particular accessibility benefits:
- Screen reader users know when they encounter radio buttons that they can only make one choice.
- Since screen magnification users experience smaller portions of the screen at once,  they benefit from the visual consistency of always using radio buttons for answer choices.
- For users who experience difficulty with attention and working memory, cognitive load is reduced when the same component is encountered repeatedly. See the [Accessibility Notes](#accessibility-notes) section for more information on how consistent navigation benefits users with disabilities.
- Limit *answer choices* to a maximum of 5.

**Why:** Too much content can cause cognitive overload, loss of focus, and anxiety for students with disabilities, i.e. those with processing, attention, or working memory challenges.
- Feedback should be delivered in a modal after the answer is submitted, as opposed to in-line.*

**Why:** In-line feedback presents challenges for many users:
- Screen magnification users may miss that the screen content changed.
- In-line feedback can make the screen visually overwhelming and increase cognitive load reducing the user's ability to gain the information intended by the in-line feedback.
- Implementing in-line feedback presents challenges for screen reader users because you have to manage focus in ways that are unanticipated. See the [Accessibility Notes](#accessibility-notes) section for more information on the impact of in-line feedback on users with disabilities.
- If more than one attempt is available, this should be clearly defined in the Instructions. The limit and the number of attempts they’ve already made should be indicated to the user.

**Why:** Transparency and clear expectations are important to ensure all users can complete the task to the best of their ability. It would be frustrating for a user to find out there was a limit only after they reached it.
- Provide clear instructions on how to complete a question.

**Why:** Providing clear instructions to users on how to complete the question is key to ensure all users can complete the assigned task.
- Multiple choice questions require a submit button either at the end of the answer choices or at the platform level. Selecting a response should never trigger a submit action.

**Why:** Radio buttons are meant to make a selection only, not to submit an answer. For users with disabilities, the use of a submit button is anticipated and gives them control over when their context changes.

:::danger Don't
Don’t use color alone for signifying correct and incorrect answers. INSTEAD include a visible “correct” or “incorrect” label for [response indicators](../components/response-indicator).

**Why:** Users who can’t differentiate colors, such as colorblind users or those with visual impairments, won’t know which color is correct or incorrect. All users must have access to the same information.
- Text is the only way to guarantee that the meaning of the response indicator will be understood by all users. This supports low-vision users, English language learners, and those with cognitive disabilities.
:::

:::danger Don't
Don’t use dropdowns within multiple choice questions. INSTEAD use a [radio button](../components/radio-group).

**Why:** Using a component like a dropdown doesn’t signal to the user that they can make only one choice and increases cognitive load by hiding answer choices. *Anticipated behavior by using the same design/consistency.
:::

## Content Guidelines

- Question stems should be kept as brief as possible.

**Why:** Clear and concise language ensures that all users understand what they are being asked to do.
- Each answer option should be preceded by a corresponding letter or number, with a few exceptions (where the answer label could be confused with part of the answer choice).
- The format of the answer label should be applied consistently throughout all multiple choice questions in an application.

**Why:** This allows users to reference the option they’ve selected without reading the full answer text and allows users to easily differentiate between answer choices. For users who experience difficulty with attention and working memory, cognitive load is reduced when the same component is encountered repeatedly.
- Answer-specific feedback should be concise and text-only is recommended. Refer to the [Accessibility Notes](#accessibility-notes) when including imagery or other media is necessary.

**Why:** Users are less likely to consume the content if there’s too much of it, thus defeating the purpose of giving feedback.

## Accessibility Notes

This section expands on the design decisions and considerations made to ensure an inclusive and accessible experience for all users.

### Inline Feedback

Relying solely on in-line feedback can present challenges for users with disabilities for the following reasons:
- Easily missed by users utilizing screen magnification: In-line feedback, particularly subtle visual cues or color changes, may become too small to notice when content is magnified. This can make it difficult for users relying on screen magnification to perceive and interpret the feedback, potentially leading to confusion or incomplete understanding.
- Limited perceptual cues in complex interfaces: In-line feedback, especially in interfaces with a lot of visual elements or complexity, may be too subtle for users with visual impairments or cognitive disabilities. These users may require more prominent or distinct cues to effectively grasp and comprehend the feedback provided.
- Potential Challenges in Screen Reader Navigation and Perception of In-Line Feedback: Screen reader users rely on auditory feedback to navigate interfaces. If they are not anticipating in-line feedback to appear, they may miss the alert or cue from the screen reader, resulting in a potential loss of understanding about the feedback's presence and location.

### Alternative to Including Images or Other Media in Answer-Specific Feedback

When possible, it is advisable to redirect students to relevant content in their eBook rather than embedding media or imagery within the feedback modal, as this approach enhances accessibility. However, if images or media are deemed absolutely essential, they must meet the following criteria:

- **No Two-Way Scrolling:** In order to enhance accessibility, feedback should not require two-way scrolling, especially for screen magnification users. This restriction helps reduce cognitive load and completion time for all students.
- **No Color-Dependent Information:** It is strictly prohibited to use color alone in images or media to communicate information. This ensures accessibility for users with color blindness or other visual impairments.
- **Color Contrast Requirements:** Ensure that any images used are compliant with color contrast requirements, as they serve as informative elements rather than decorative features.
- **Alternative Text (Alt Text):** All images within feedback must have informative alt text to facilitate accessibility for users who rely on screen readers.
- **Embedded Media Caution:** It is generally discouraged to embed other media types in feedback. If required, follow these guidelines:
- **Labeling Controls:** Ensure all controls for embedded media are properly labeled.
- **WCAG 2.1 AA Compliance:** Embedded media (audio or video) should meet WCAG 2.1 AA requirements, including:
- Audio descriptions or descriptive transcripts for video content.
- Closed captions for audio or video content.
- Visible labels for any media player controls.
- Compliance with other relevant WCAG criteria.

## Implementation Example

The following example demonstrates how to implement the Multiple Choice Pattern in a React application.

A live demo can be found in the storybook for the <a href={useBaseUrl('/storybook/?path=/story/patterns-multiplechoice--pattern-example')}>Multiple Choice Pattern</a>.

```tsx
import React, { useCallback } from 'react';
import { useMultipleChoice, MultipleChoice, FeedbackModal, Button } from '@wwnds/react';

const choices = [
'Jayvon, who had opened a checking account at the branch that same day',
'Ibrahim, who is taking propranolol to control his blood pressure',
'Huong, who was born with Urbach-Wiethe syndrome and lacks an amygdala',
];

export function PatternExample() {
const { questionState, setStatus, modalState } = useMultipleChoice(choices);

const handleSubmit = useCallback(
(event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();

if (questionState.selected === 1) {
setStatus('correct');
} else {
setStatus('incorrect');
}
},
[setStatus, questionState.selected],
);

return (
<form onSubmit={handleSubmit}>
<MultipleChoice
intro="Three people are present when a pregnant person suddenly goes into labor and gives birth in a bank lobby."
stem="Which of the people is likely to best remember the event afterward?"
instructions="Select one that applies. You have 2 attempts remaining."
{...questionState}
/>
<FeedbackModal {...modalState} />
<div>
<Button type="submit" variant="solid" color="primary">
Submit
</Button>
</div>
</form>
);
}
```

### useMultipleChoice Hook

The `useMultipleChoice` hook is used to manage the state of the multiple choice question. It accepts an array of answer choices and returns the state shared by the `FeedbackModal` and `MultipleChoice` components.

### MultipleChoice Component

The `MultipleChoice` component is used to render the multiple choice question. It accepts the following props:

<PropsTable from={MultipleChoice} />

### FeedbackModal Component

The `FeedbackModal` component is used to render the feedback modal. It accepts the following props:

<PropsTable from={FeedbackModal} />

5 changes: 5 additions & 0 deletions website/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ const config = {
label: "Components",
position: "left",
},
{
to: "docs/patterns",
label: "Patterns",
position: "left",
},
{
to: "docs/guides",
label: "Guides",
Expand Down
4 changes: 4 additions & 0 deletions website/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ const Home = (): JSX.Element => {
The building blocks for composing applications and content with
the Norton Design System.
</FeatureCard>
<FeatureCard title="Patterns" slug="patterns" linkArrow>
Components organized to offer an optimal UI solution based on best
practices.
</FeatureCard>
<FeatureCard title="Guides" slug="guides" linkArrow>
Tutorials and examples to help designers, developers, and editors
learn how get the most out of the Norton Design System.
Expand Down
Binary file added website/static/img/anatomy-feedback-modal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/static/img/multiple-choice-anatomy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 112cdd4

Please sign in to comment.