Skip to content

Refactor icon components#760

Open
mkernohanbc wants to merge 10 commits into
mainfrom
614-icon-refactor
Open

Refactor icon components#760
mkernohanbc wants to merge 10 commits into
mainfrom
614-icon-refactor

Conversation

@mkernohanbc

@mkernohanbc mkernohanbc commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

This PR closes #436 and #614. It refactors our entire set of icon components to:

  1. Add props for each component to set size and title and leverage React.SVGProps
  2. Support basic accessibility requirements via role, aria-labelledby, aria-hidden and focusable attributes

Rationale

These icon components are primarily intended to be consumed by other components, which own the accessibility context. However, we are also exporting them as standalone components, meaning people may use them elsewhere — this change makes them more robust and less likely to cause accessibility issues when doing so.

Sizing

Sizing for most icon components is now handled via a new getIconSize hook. This maps the size prop on each component to the correct design token value (--icons-size-xsmall to --icons-size-xlarge.) The values are hardcoded in getIconSize.ts, because CSS variables can't be evaluated in SVG presentation attributes.

Sizing is now set in an inline style attribute, rather than in width and height SVG presentation attributes. This means that CSS variables can be properly evaluated, and we can leverage the tokens without hardcoding their values. Changed in 40ef335, see #760 (comment)

These components are currently excluded from the new sizing pattern, because they have non-uniform aspect ratios and/or specialized use-cases:

  • SvgBcLogo
  • SvgDashIcon
  • SvgTooltipArrowUp

Titles and roles

Icon components now support a title prop, which populates a <title> element. <title> receives an ID generated via useId, which is used to set aria-labelledby.

The presence or absence of title is a trigger for various other attributes:

  • If title is present, the icon is considered non-decorative. role="img" and aria-labelledby are set automatically
  • If title is absent, role is not set and aria-hidden is applied

@mkernohanbc mkernohanbc added this to the Components v0.9.0 milestone Jun 26, 2026
@mkernohanbc mkernohanbc self-assigned this Jun 26, 2026
@mkernohanbc mkernohanbc added the react-components Changes or issues affecting the design-system-react-components package label Jun 26, 2026
@mkernohanbc mkernohanbc requested a review from a team as a code owner June 26, 2026 00:08
@mkernohanbc mkernohanbc linked an issue Jun 26, 2026 that may be closed by this pull request

Copilot AI left a comment

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.

Pull request overview

Refactors the React icon components to standardize their props, introduce token-driven sizing, and add baseline SVG accessibility support (title/role/aria attributes), and updates Storybook docs/usages accordingly.

Changes:

  • Added size/title props to multiple SVG icon components and standardized them on React.SVGProps<SVGSVGElement> forwarding.
  • Introduced getIconSize to map semantic sizes (xsmallxlarge) to design token CSS variables and updated icon usages in MDX/examples to pass semantic sizes.
  • Updated the build config to include the new hooks directory.

Reviewed changes

Copilot reviewed 45 out of 45 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/react-components/src/stories/Tooltip.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/ToggleButtonGroup.mdx Updates icon size usage to semantic size (two links).
packages/react-components/src/stories/TimeField.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/TextField.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/TextArea.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/TagGroup.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/Switch.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/Select.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/RadioGroup.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/ProgressBar.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/NumberField.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/MenuTrigger.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/MenuItem.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/Menu.mdx Updates icon size usage to semantic size (two links).
packages/react-components/src/stories/Dialogs.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/DatePicker.mdx Updates icon size usage to semantic size (two links).
packages/react-components/src/stories/CheckboxGroup.mdx Updates icon size usage to semantic size (two links).
packages/react-components/src/stories/Calendar.mdx Updates icon size usage to semantic size (two links).
packages/react-components/src/stories/Button.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/AlertDialog.mdx Updates icon size usage to semantic size.
packages/react-components/src/stories/AccordionGroup.mdx Updates icon size usage to semantic size (two links).
packages/react-components/src/pages/Button/ButtonPrimary.tsx Updates placeholder icon usage to semantic size.
packages/react-components/src/hooks/getIconSize.ts Adds IconSize + token mapping helper used by icons.
packages/react-components/src/components/Icons/SvgUpRightFromSquareIcon/SvgUpRightFromSquareIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgTooltipArrowUp/SvgTooltipArrowUp.tsx Adds title + accessibility attrs (keeps fixed dimensions).
packages/react-components/src/components/Icons/SvgReactAriaIcon/SvgReactAriaIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgPlusIcon/SvgPlusIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgPlaceholderIcon/SvgPlaceholderIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgMinusIcon/SvgMinusIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgInfoIcon/SvgInfoIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgExclamationIcon/SvgExclamationIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgExclamationCircleIcon/SvgExclamationCircleIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgDashIcon/SvgDashIcon.tsx Adds title + accessibility attrs (keeps fixed dimensions).
packages/react-components/src/components/Icons/SvgCloseIcon/SvgCloseIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgChevronUpIcon/SvgChevronUpIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgChevronRightIcon/SvgChevronRightIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgChevronLeftIcon/SvgChevronLeftIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgChevronDownIcon/SvgChevronDownIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgCheckIcon/SvgCheckIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgCheckCircleIcon/SvgCheckCircleIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgCalendarIcon/SvgCalendarIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgBetaIcon/SvgBetaIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgBcOutlineIcon/SvgBcOutlineIcon.tsx Adds size/title, accessibility attrs, token sizing.
packages/react-components/src/components/Icons/SvgBcLogo/SvgBcLogo.tsx Adds title + accessibility attrs (keeps existing sizing/CSS).
packages/react-components/rollup.config.js Includes src/hooks/**/* in the build inputs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +3 to +4
import { useId } from "react";
import getIconSize, { IconSize } from "../../../hooks/getIconSize";
Comment on lines +12 to +16
export default function SvgCheckIcon({
size = "medium",
title,
id,
...props
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

react-components Changes or issues affecting the design-system-react-components package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Icon components: standardize props and styling Add accessible titles and aria-hidden support to React icon components

2 participants