From cfed264ed53b752f6c074f111b0013c60c5f032e Mon Sep 17 00:00:00 2001 From: Sheelah Brennan <1900318+sheelah@users.noreply.github.com> Date: Fri, 7 Aug 2026 10:24:32 -0600 Subject: [PATCH 1/6] docs: Update readme for v16 (#4127) Add-on to #4100. Adds upgrade guide links to the README for v15 and v16 and a link to our older fonts package README in the fonts guide. [category:Documentation] --- README.md | 2 ++ modules/docs/mdx/FONTS.mdx | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8c8387d0b5..59cb1454b9 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,8 @@ recommend against using it in production until the first stable version has been - [v12.0 Upgrade Guide](https://workday.github.io/canvas-kit/?path=/docs/guides-upgrade-guides-v12-0--docs) - [v13.0 Upgrade Guide](https://workday.github.io/canvas-kit/?path=/docs/guides-upgrade-guides-v13-0--docs) - [v14.0 Upgrade Guide](https://workday.github.io/canvas-kit/?path=/docs/guides-upgrade-guides-v14-0-overview--docs) + - [v15.0 Upgrade Guide](https://workday.github.io/canvas-kit/?path=/docs/guides-upgrade-guides-v15-0-overview--docs) + - [v16.0 Upgrade Guide](https://workday.github.io/canvas-kit/?path=/docs/guides-upgrade-guides-v16-0-overview--docs) - Code Style / Best Practices: - [API & Pattern Guidelines](https://workday.github.io/canvas-kit/?path=/docs/guides-api-pattern-guidelines--docs) - [Compound Components](https://workday.github.io/canvas-kit/?path=/docs/guides-compound-components--docs) diff --git a/modules/docs/mdx/FONTS.mdx b/modules/docs/mdx/FONTS.mdx index 171f84ec0d..c7192aaf35 100644 --- a/modules/docs/mdx/FONTS.mdx +++ b/modules/docs/mdx/FONTS.mdx @@ -105,8 +105,8 @@ is set. ## Roboto If your application doesn't have the Sana Canvas theme enabled, install -`@workday/canvas-kit-react-fonts` to load Roboto instead. This module also includes Roboto Mono, -used for `system.fontFamily.mono`. +[`@workday/canvas-kit-react-fonts`](https://github.com/Workday/canvas-kit/blob/master/modules/react-fonts/README.md) +to load Roboto instead. This module also includes Roboto Mono, used for `system.fontFamily.mono`. ### Installation From 28626e60008775fce9a562944be73c9a7207a0db Mon Sep 17 00:00:00 2001 From: alanbsmith Date: Fri, 7 Aug 2026 16:26:48 +0000 Subject: [PATCH 2/6] chore: Release v16.0.5 [skip release] --- CHANGELOG.md | 7 +++++++ lerna.json | 2 +- modules/codemod/package.json | 2 +- modules/css/package.json | 2 +- modules/docs/package.json | 10 +++++----- modules/labs-css/package.json | 2 +- modules/labs-react/package.json | 6 +++--- modules/mcp/package.json | 2 +- modules/popup-stack/package.json | 2 +- modules/preview-css/package.json | 2 +- modules/preview-react/package.json | 6 +++--- modules/react-fonts/package.json | 2 +- modules/react/package.json | 6 +++--- modules/styling-transform/package.json | 4 ++-- modules/styling/package.json | 2 +- 15 files changed, 32 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24ed02a8cd..3f2d8ba1fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [v16.0.5](https://github.com/Workday/canvas-kit/releases/tag/v16.0.5) (2026-08-07) + +### Documentation + +- docs: Update readme for v16 ([#4127](https://github.com/Workday/canvas-kit/pull/4127)) ([@sheelah](https://github.com/sheelah)) + + ## [v16.0.4](https://github.com/Workday/canvas-kit/releases/tag/v16.0.4) (2026-08-05) ### Documentation diff --git a/lerna.json b/lerna.json index ea77bd30a0..cc3bafa7d7 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "packages": [ "modules/**" ], - "version": "16.0.4", + "version": "16.0.5", "npmClient": "yarn", "command": { "version": { diff --git a/modules/codemod/package.json b/modules/codemod/package.json index c65624e492..a0f5e33347 100644 --- a/modules/codemod/package.json +++ b/modules/codemod/package.json @@ -2,7 +2,7 @@ "name": "@workday/canvas-kit-codemod", "author": "Workday, Inc. (https://www.workday.com)", "license": "Apache-2.0", - "version": "16.0.4", + "version": "16.0.5", "description": "A collection of codemods for use on Workday Canvas Kit packages.", "main": "dist/es6/index.js", "sideEffects": false, diff --git a/modules/css/package.json b/modules/css/package.json index 0a6fec6900..3516649d44 100644 --- a/modules/css/package.json +++ b/modules/css/package.json @@ -1,6 +1,6 @@ { "name": "@workday/canvas-kit-css", - "version": "16.0.4", + "version": "16.0.5", "type": "module", "description": "The parent module that contains all Workday Canvas Kit CSS components", "author": "Workday, Inc. (https://www.workday.com)", diff --git a/modules/docs/package.json b/modules/docs/package.json index c88e17dc30..4fda802aaf 100644 --- a/modules/docs/package.json +++ b/modules/docs/package.json @@ -1,6 +1,6 @@ { "name": "@workday/canvas-kit-docs", - "version": "16.0.4", + "version": "16.0.5", "description": "Documentation components of Canvas Kit components", "author": "Workday, Inc. (https://www.workday.com)", "license": "Apache-2.0", @@ -47,10 +47,10 @@ "@stackblitz/sdk": "^1.11.0", "@storybook/csf": "0.0.1", "@workday/canvas-expressive-icons-web": "1.0.2", - "@workday/canvas-kit-labs-react": "^16.0.4", - "@workday/canvas-kit-preview-react": "^16.0.4", - "@workday/canvas-kit-react": "^16.0.4", - "@workday/canvas-kit-styling": "^16.0.4", + "@workday/canvas-kit-labs-react": "^16.0.5", + "@workday/canvas-kit-preview-react": "^16.0.5", + "@workday/canvas-kit-react": "^16.0.5", + "@workday/canvas-kit-styling": "^16.0.5", "@workday/canvas-system-icons-web": "^5.0.3", "@workday/canvas-tokens-web": "^4.4.0", "markdown-to-jsx": "^7.2.0", diff --git a/modules/labs-css/package.json b/modules/labs-css/package.json index f557f2b109..7b79f1dc9d 100644 --- a/modules/labs-css/package.json +++ b/modules/labs-css/package.json @@ -1,6 +1,6 @@ { "name": "@workday/canvas-kit-labs-css", - "version": "16.0.4", + "version": "16.0.5", "type": "module", "description": "The parent module that contains all Workday Canvas Kit Labs CSS components", "author": "Workday, Inc. (https://www.workday.com)", diff --git a/modules/labs-react/package.json b/modules/labs-react/package.json index fd457fd73e..060e43fb10 100644 --- a/modules/labs-react/package.json +++ b/modules/labs-react/package.json @@ -1,6 +1,6 @@ { "name": "@workday/canvas-kit-labs-react", - "version": "16.0.4", + "version": "16.0.5", "description": "Canvas Kit Labs is an incubator for new and experimental components. Since we have a rather rigorous process for getting components in at a production level, it can be valuable to make them available earlier while we continuously iterate on the API/functionality. The Labs modules allow us to do that as needed.", "author": "Workday, Inc. (https://www.workday.com)", "license": "Apache-2.0", @@ -48,8 +48,8 @@ "dependencies": { "@emotion/react": "^11.7.1", "@emotion/styled": "^11.6.0", - "@workday/canvas-kit-react": "^16.0.4", - "@workday/canvas-kit-styling": "^16.0.4", + "@workday/canvas-kit-react": "^16.0.5", + "@workday/canvas-kit-styling": "^16.0.5", "@workday/canvas-system-icons-web": "^5.0.3", "@workday/canvas-tokens-web": "^4.4.0", "@workday/design-assets-types": "^0.3.0", diff --git a/modules/mcp/package.json b/modules/mcp/package.json index 139065c232..e68eb3b663 100644 --- a/modules/mcp/package.json +++ b/modules/mcp/package.json @@ -1,6 +1,6 @@ { "name": "@workday/canvas-kit-mcp", - "version": "16.0.4", + "version": "16.0.5", "description": "MCP package for Canvas Kit", "author": "Workday, Inc. (https://www.workday.com)", "license": "Apache-2.0", diff --git a/modules/popup-stack/package.json b/modules/popup-stack/package.json index 1163676bf2..fa34861b75 100644 --- a/modules/popup-stack/package.json +++ b/modules/popup-stack/package.json @@ -1,6 +1,6 @@ { "name": "@workday/canvas-kit-popup-stack", - "version": "16.0.4", + "version": "16.0.5", "description": "Stack for managing popup UIs to coordinate global concerns like escape key handling and rendering order", "author": "Workday, Inc. (https://www.workday.com)", "license": "Apache-2.0", diff --git a/modules/preview-css/package.json b/modules/preview-css/package.json index 84309a82e3..72f3b5ab49 100644 --- a/modules/preview-css/package.json +++ b/modules/preview-css/package.json @@ -1,6 +1,6 @@ { "name": "@workday/canvas-kit-preview-css", - "version": "16.0.4", + "version": "16.0.5", "description": "The parent module that contains all Workday Canvas Kit Preview CSS components", "author": "Workday, Inc. (https://www.workday.com)", "license": "Apache-2.0", diff --git a/modules/preview-react/package.json b/modules/preview-react/package.json index c4cd6d6c7b..4712797470 100644 --- a/modules/preview-react/package.json +++ b/modules/preview-react/package.json @@ -1,6 +1,6 @@ { "name": "@workday/canvas-kit-preview-react", - "version": "16.0.4", + "version": "16.0.5", "description": "Canvas Kit Preview is made up of components that have the full design and a11y review, are part of the DS ecosystem and are approved for use in product. The API's could be subject to change, but not without strong communication and migration strategies.", "author": "Workday, Inc. (https://www.workday.com)", "license": "Apache-2.0", @@ -48,8 +48,8 @@ "dependencies": { "@emotion/react": "^11.7.1", "@emotion/styled": "^11.6.0", - "@workday/canvas-kit-react": "^16.0.4", - "@workday/canvas-kit-styling": "^16.0.4", + "@workday/canvas-kit-react": "^16.0.5", + "@workday/canvas-kit-styling": "^16.0.5", "@workday/canvas-system-icons-web": "^5.0.3", "@workday/canvas-tokens-web": "^4.4.0", "@workday/design-assets-types": "^0.3.0" diff --git a/modules/react-fonts/package.json b/modules/react-fonts/package.json index 399bc44ba6..6801f05432 100644 --- a/modules/react-fonts/package.json +++ b/modules/react-fonts/package.json @@ -1,6 +1,6 @@ { "name": "@workday/canvas-kit-react-fonts", - "version": "16.0.4", + "version": "16.0.5", "description": "Fonts for canvas-kit-react", "author": "Workday, Inc. (https://www.workday.com)", "license": "Apache-2.0", diff --git a/modules/react/package.json b/modules/react/package.json index 69a6c5a52d..3f0b43179f 100644 --- a/modules/react/package.json +++ b/modules/react/package.json @@ -1,6 +1,6 @@ { "name": "@workday/canvas-kit-react", - "version": "16.0.4", + "version": "16.0.5", "description": "The parent module that contains all Workday Canvas Kit React components", "author": "Workday, Inc. (https://www.workday.com)", "license": "Apache-2.0", @@ -53,8 +53,8 @@ "@tanstack/react-virtual": "^3.13.9", "@workday/canvas-colors-web": "^2.0.0", "@workday/canvas-expressive-icons-web": "1.0.2", - "@workday/canvas-kit-popup-stack": "^16.0.4", - "@workday/canvas-kit-styling": "^16.0.4", + "@workday/canvas-kit-popup-stack": "^16.0.5", + "@workday/canvas-kit-styling": "^16.0.5", "@workday/canvas-system-icons-web": "^5.0.3", "@workday/canvas-tokens-web": "^4.4.0", "@workday/design-assets-types": "^0.3.0", diff --git a/modules/styling-transform/package.json b/modules/styling-transform/package.json index 628afbc34d..15eab08856 100644 --- a/modules/styling-transform/package.json +++ b/modules/styling-transform/package.json @@ -1,6 +1,6 @@ { "name": "@workday/canvas-kit-styling-transform", - "version": "16.0.4", + "version": "16.0.5", "description": "The custom CSS in JS solution that takes JS styles and turns them into static CSS", "author": "Workday, Inc. (https://www.workday.com)", "license": "Apache-2.0", @@ -45,7 +45,7 @@ ], "dependencies": { "@emotion/serialize": "^1.0.2", - "@workday/canvas-kit-styling": "^16.0.4", + "@workday/canvas-kit-styling": "^16.0.5", "@workday/canvas-tokens-web": "^4.4.0", "stylis": "4.3.6", "ts-node": "^10.9.1", diff --git a/modules/styling/package.json b/modules/styling/package.json index 95b14c6712..f6f6ad1eb8 100644 --- a/modules/styling/package.json +++ b/modules/styling/package.json @@ -1,6 +1,6 @@ { "name": "@workday/canvas-kit-styling", - "version": "16.0.4", + "version": "16.0.5", "description": "The custom CSS in JS solution that takes JS styles and turns them into static CSS", "author": "Workday, Inc. (https://www.workday.com)", "license": "Apache-2.0", From 9e8d88bfef076d1cdba4288be3b650046724ffd9 Mon Sep 17 00:00:00 2001 From: William Stanton Date: Thu, 13 Aug 2026 13:39:16 -0400 Subject: [PATCH 3/6] docs(modal): expand accessibility guidance for AI codegen Co-authored-by: Cursor --- modules/react/modal/stories/Modal.mdx | 261 +++++++++++++++++++++----- 1 file changed, 212 insertions(+), 49 deletions(-) diff --git a/modules/react/modal/stories/Modal.mdx b/modules/react/modal/stories/Modal.mdx index edbb61640c..4fcbeb943d 100644 --- a/modules/react/modal/stories/Modal.mdx +++ b/modules/react/modal/stories/Modal.mdx @@ -33,7 +33,7 @@ yarn add @workday/canvas-kit-react ## Usage -### Basic +### Basic Example The basic behavior of a modal is to hide all content from all users that is "behind" the modal dialog. @@ -42,7 +42,7 @@ dialog. ### Without Close Icon -If you wish to remove the close icon button, you can simply omit the `Modal.CloseButton` +If you wish to remove the close icon button, you can simply omit the `Modal.CloseIcon` subcomponent. If you have a modal dialog that requires the user to accept instead of dismiss through an escape key or clicking outside the modal, you must create a new `PopupModel` without those behaviors and hand that model to the Modal dialog component. @@ -138,55 +138,218 @@ hoisted to allow for form validation and allow you to control when the modal clo ## Accessibility -`Modal` uses the default modal model (`useModalModel`), which composes **`useInitialFocus`**, -**`useReturnFocus`**, **`useCloseOnOverlayClick`**, **`useCloseOnEscape`**, **`useFocusTrap`**, -**`useAssistiveHideSiblings`**, and **`useDisableBodyScroll`**. - -**`Modal.Card`** exposes **`role="dialog"`** and **`aria-labelledby`** referencing the `id` on -**`Modal.Heading`**, so the dialog has an accessible name that matches the visible heading. If you -do not use **`Modal.Heading`**, add an **`aria-label`** on **`Modal.Card`** instead. - -**`aria-modal`:** The card sets **`aria-modal="false"`**. When **`aria-modal`** is `true`, some -assistive technologies hide everything outside the dialog—including portaled UI owned by the dialog -(such as a Select menu rendered as a sibling of the modal). Canvas Kit keeps -**`aria-modal="false"`** for a better VoiceOver experience while **`useAssistiveHideSiblings`** -applies **`aria-hidden`** to siblings of the modal stack so background content stays hidden from -assistive technology while the modal is open. - -Unlike [**Dialog**](/components/popups/dialog/), Modal does **not** add the sibling **`aria-owns`** -pattern used to remap reading order for portaled non-modal dialogs. Focus moves into the modal when -it opens, and sibling hiding reduces exposure to content behind the overlay. For portals, reading -order, and related tradeoffs, see +Ensure users of assistive technology can discover, name, and operate a **modal** dialog: the rest of +the page is blocked by an overlay, background content is hidden from assistive technology via sibling +**`aria-hidden`**, keyboard focus is trapped inside the modal, the dialog has an accessible name that +matches its visible heading, and keyboard users can open and dismiss it predictably. + +Use **Modal** when the user must complete or acknowledge a task before continuing with the page. For +non-blocking tasks, use +[**Dialog**](https://workday.github.io/canvas-kit/?path=/docs/components-popups-dialog--docs) +instead. Prefer **Modal** for the standard blocking dialog; use +[**Popup**](https://workday.github.io/canvas-kit/?path=/docs/components-popups-popup--docs) with +composed hooks when you need a custom popup stack or to omit behaviors (for example Escape or overlay +dismiss). For portals, reading order, and related tradeoffs, see [Guides > Accessibility > Inline Popups](https://workday.github.io/canvas-kit/?path=/docs/guides-accessibility-inline-popups--docs). +See also the +[Modal Dialog Pattern | APG | WAI | W3C](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/). + +### Minimum Accessible Structure + +The following matches the [Basic Example](#basic-example) layout: **`Modal.CloseIcon`** before +**`Modal.Heading`** so open focus lands on the dismiss control first; primary actions use +**`Modal.CloseButton`** (which closes the modal on activate). + +```tsx +import {PrimaryButton} from '@workday/canvas-kit-react/button'; +import {Modal} from '@workday/canvas-kit-react/modal'; + + + Open + + + + Title + Content + + Cancel + Acknowledge + + + +; +``` + +Include a dismiss control: **`Modal.CloseButton`** with visible text (for example "Cancel" or +"Close"), and/or **`Modal.CloseIcon`** when the design uses an icon-only dismiss (requires +**`aria-label`** or **`Tooltip`**). Use **`Modal.CloseButton`** for actions that should also close +the modal. Compose with **`Modal.Overlay` → `Modal.Card`** (or **`Modal.OverflowOverlay`** when the +entire overlay should scroll). + +### Built-in Behaviors + +Canvas Kit applies these automatically via `useModalModel` and Modal subcomponents. **Do not +duplicate them** in consuming code. + +**Popup behaviors** (_composed on the default model_): + +- `useInitialFocus` — moves focus into the modal when it opens (default: first focusable element in + DOM order; optional override via `initialFocusRef` on the model) +- `useReturnFocus` — returns focus to `Modal.Target` (or configured return target) when it closes +- `useCloseOnOverlayClick` — pointer interaction on the overlay (outside the dialog) closes the modal +- `useCloseOnEscape` — Escape closes the modal +- `useFocusTrap` — Tab / Shift+Tab cycle focus **inside** the modal + (keyboard focus does not leave the dialog) +- `useAssistiveHideSiblings` — applies **`aria-hidden`** to siblings of the modal stack while open +- `useDisableBodyScroll` — prevents background page scroll while the modal is open + +**ARIA and DOM** (_applied by hooks/subcomponents_): + +- `Modal.Card`: `role="dialog"`, `aria-labelledby` referencing the heading `id`, and + **`aria-modal="false"`** +- `Modal.Heading`: `id` wired to `Modal.Card`'s `aria-labelledby`; when there is no icon-only close + button before the heading, `useModalHeading` may temporarily set **`tabindex="0"`** on the heading + so initial focus still lands near the start of the dialog +- `Modal.CloseIcon` / `Modal.CloseButton`: `onClick` that calls `model.events.hide()` +- `Modal.Target`: `ref` and `onClick` to open and to receive return focus + +**Keyboard** (_trigger is `Modal.Target`, default `SecondaryButton`_): + +- Enter / Space on the trigger opens the modal (standard button behavior) +- On open and close, focus is managed by **`useInitialFocus`** and **`useReturnFocus`** (application + overrides: see **Focus management** in Accessibility Requirements) +- Tab / Shift+Tab move focus through interactive elements **inside** + the modal; focus stays trapped within the dialog +- Escape closes the modal and returns focus per `useReturnFocus` (unless Escape dismiss is + omitted via a custom model—see **Accept-only / no Escape dismiss**) + +**Screen reader expectations** (_when built-in behaviors are used as intended_): + +- On open, assistive technology should announce the first focused control (often a dismiss control), + the dialog name (`Modal.Heading`), and `dialog` role +- Sibling elements of the modal stack receive **`aria-hidden="true"`** while the modal is visible, + which hides the rest of the page from many assistive technologies +- Trapping **keyboard** focus does not stop all screen reader virtual-cursor movement outside the + dialog; treat the trap as the primary keyboard affordance, not a hard boundary—verify behavior in + your supported browser and screen reader combinations + +### Accessibility Requirements + +Required in application code for an accessible Modal. Hoist **`useModalModel`** when you need to +configure focus targets, open without **`Modal.Target`**, or control when the modal closes (for +example form validation). Rows marked _(conditional)_ apply only when the situation matches—otherwise +omit. + +**If no design spec is provided:** use default focus behavior; include a dismiss control and +**`Modal.Heading`**; omit **`initialFocusRef`**, **`returnFocusRef`**, **`aria-describedby`**, +**`aria-expanded`**, and **`aria-haspopup`**. Do not remove Escape or overlay dismiss unless the +design requires accept-only confirmation. + +**Focus management — defaults and developer prompts:** Canvas Kit handles open and close focus +automatically. **State the default to the developer first.** Only set **`initialFocusRef`** or +**`returnFocusRef`** after the developer (or an explicit design spec) chooses a non-default target. +**Do not generate focus refs by default.** + +| When | Default behavior | Ask the developer before overriding | +| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Modal **opens** | **`useInitialFocus`** moves focus to the **first focusable element** in DOM order inside the modal (often **`Modal.CloseIcon`** or **`Modal.CloseButton`**). Omit **`initialFocusRef`**. | _Which element should receive focus when the modal opens?_ (Only when the default first focusable element is wrong for the design.) Attach **`initialFocusRef`** to that element on **`useModalModel`**. | +| Modal **closes** | **`useReturnFocus`** moves focus to **`Modal.Target`**. Omit **`returnFocusRef`**. | _Which element should receive focus when the modal closes?_ (Only when return focus should land somewhere other than **`Modal.Target`**.) | + +If close **removes the trigger from the DOM**, **`returnFocusRef`** alone is not enough—move focus +after the UI updates (for example with **`useLayoutEffect`**). See [Return Focus](#return-focus). + +**Custom targets** _(conditional)_: Apply when using a custom **`as`** component on +**`Modal.Target`**. **`Modal.Target`** adds **`onClick`** and **`ref`**. Custom targets must forward +both to a **keyboard-focusable** element (prefer a native **` -)); - - - - {/* ... */} -; -``` +**Custom targets** _(conditional)_: Apply when using a custom **`as`** component on +**`Dialog.Target`**. **`Dialog.Target`** adds **`onClick`** and **`ref`**. Custom targets must +forward both to a **keyboard-focusable** element (prefer a native **`