Skip to content
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

feat(LEMS-2664): update use control point and movable point with optional props #1906

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ exports[`Rendering Does NOT render extensions of line when option is disabled 1`
>
<g
aria-label="Point 1 at -1 comma -1"
aria-live="assertive"
aria-live="polite"
class="movable-point__focusable-handle"
data-testid="movable-point__focusable-handle"
role="button"
Expand Down Expand Up @@ -61,7 +61,7 @@ exports[`Rendering Does NOT render extensions of line when option is disabled 1`
</g>
<g
aria-label="Point 2 at 1 comma 1"
aria-live="assertive"
aria-live="polite"
class="movable-point__focusable-handle"
data-testid="movable-point__focusable-handle"
role="button"
Expand Down Expand Up @@ -156,7 +156,7 @@ exports[`Rendering Does NOT render extensions of line when option is not provide
>
<g
aria-label="Point 1 at -1 comma -1"
aria-live="assertive"
aria-live="polite"
class="movable-point__focusable-handle"
data-testid="movable-point__focusable-handle"
role="button"
Expand Down Expand Up @@ -201,7 +201,7 @@ exports[`Rendering Does NOT render extensions of line when option is not provide
</g>
<g
aria-label="Point 2 at 1 comma 1"
aria-live="assertive"
aria-live="polite"
class="movable-point__focusable-handle"
data-testid="movable-point__focusable-handle"
role="button"
Expand Down Expand Up @@ -296,7 +296,7 @@ exports[`Rendering Does render extensions of line when option is enabled 1`] = `
>
<g
aria-label="Point 1 at -1 comma -1"
aria-live="assertive"
aria-live="polite"
class="movable-point__focusable-handle"
data-testid="movable-point__focusable-handle"
role="button"
Expand Down Expand Up @@ -395,7 +395,7 @@ exports[`Rendering Does render extensions of line when option is enabled 1`] = `
</g>
<g
aria-label="Point 2 at 1 comma 1"
aria-live="assertive"
aria-live="polite"
class="movable-point__focusable-handle"
data-testid="movable-point__focusable-handle"
role="button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {useControlPoint} from "./use-control-point";
import type {CSSCursor} from "./css-cursor";
import type {KeyboardMovementConstraint} from "../use-draggable";
import type {vec} from "mafs";
import { AriaLive } from "../../types";

type Props = {
point: vec.Vector2;
Expand All @@ -17,13 +18,16 @@ type Props = {
* interactive figure on the graph.
*/
sequenceNumber: number;
onMove?: (newPoint: vec.Vector2) => unknown;
onClick?: () => unknown;
ariaDescribedBy?: string;
ariaLabel?: string;
ariaLive?: AriaLive;
color?: string;
cursor?: CSSCursor | undefined;
constrain?: KeyboardMovementConstraint;
onFocus?: ((event: React.FocusEvent) => unknown) | undefined;
cursor?: CSSCursor | undefined;
onBlur?: ((event: React.FocusEvent) => unknown) | undefined;
onClick?: () => unknown;
onFocus?: ((event: React.FocusEvent) => unknown) | undefined;
onMove?: (newPoint: vec.Vector2) => unknown;
};

export const MovablePoint = React.forwardRef(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ import {MovablePointView} from "./movable-point-view";
import type {CSSCursor} from "./css-cursor";
import type {KeyboardMovementConstraint} from "../use-draggable";
import type {vec} from "mafs";
import { AriaLive } from "../../types";

type Params = {
point: vec.Vector2;
color?: string | undefined;
cursor?: CSSCursor | undefined;
/**
* Represents where this point stands in the overall point sequence.
* This is used to provide screen readers with context about the point.
Expand All @@ -26,13 +25,18 @@ type Params = {
* interactive figure on the graph.
*/
sequenceNumber: number;
ariaDescribedBy?: string;
ariaLabel?: string;
ariaLive?: AriaLive;
color?: string | undefined;
cursor?: CSSCursor | undefined;
constrain?: KeyboardMovementConstraint;
// The focusableHandle element is assigned to the forwarded ref.
forwardedRef?: React.ForwardedRef<SVGGElement | null> | undefined;
onMove?: ((newPoint: vec.Vector2) => unknown) | undefined;
onClick?: (() => unknown) | undefined;
onFocus?: ((event: React.FocusEvent) => unknown) | undefined;
onBlur?: ((event: React.FocusEvent) => unknown) | undefined;
// The focusableHandle element is assigned to the forwarded ref.
forwardedRef?: React.ForwardedRef<SVGGElement | null> | undefined;
};

type Return = {
Expand All @@ -47,6 +51,9 @@ export function useControlPoint(params: Params): Return {
const {
point,
sequenceNumber,
ariaDescribedBy,
ariaLabel,
ariaLive = "polite",
Copy link
Contributor Author

@anakaren-rojas anakaren-rojas Nov 23, 2024

Choose a reason for hiding this comment

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

Only removing point or moving out of bounds should be assertive per design doc

color,
cursor,
constrain = (p) => snap(snapStep, p),
Expand Down Expand Up @@ -76,6 +83,13 @@ export function useControlPoint(params: Params): Return {
constrainKeyboardMovement: constrain,
});

// if custom aria label is not provided, will use default of sequence number and point coordinates
const pointAriaLabel = ariaLabel || strings.srPointAtCoordinates({
num: sequenceNumber,
x: srFormatNumber(point[X], locale),
y: srFormatNumber(point[Y], locale),
})

useLayoutEffect(() => {
setForwardedRef(forwardedRef, focusableHandleRef.current);
}, [forwardedRef]);
Expand All @@ -87,14 +101,9 @@ export function useControlPoint(params: Params): Return {
tabIndex={disableKeyboardInteraction ? -1 : 0}
ref={focusableHandleRef}
role="button"
aria-label={strings.srPointAtCoordinates({
num: sequenceNumber,
x: srFormatNumber(point[X], locale),
y: srFormatNumber(point[Y], locale),
})}
// aria-live="assertive" causes the new location of the point to be
// announced immediately on move.
aria-live="assertive"
aria-describedby={ariaDescribedBy}
aria-label={pointAriaLabel}
aria-live={ariaLive}
onFocus={(event) => {
onFocus(event);
setFocused(true);
Expand Down
2 changes: 2 additions & 0 deletions packages/perseus/src/widgets/interactive-graphs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,5 @@ export type GraphDimensions = {
width: number; // pixels
height: number; // pixels
};

export type AriaLive = "off" | "assertive" | "polite" | undefined;
Loading