Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8ad3aff
feat: Update TextInput border radius
jamesfan Jun 15, 2026
b3f1b31
feat: Remove background color from Caution and Error states for TextI…
jamesfan Jun 15, 2026
bf299e6
fix: Preserve use of legacy tokens for TextInput
jamesfan Jun 16, 2026
cfea945
feat: Update styles for FormFieldGroupList
jamesfan Jun 22, 2026
459c285
Merge branch 'prerelease/major' into feat/2026-06-15-sc-text-input-ar…
jamesfan Jun 22, 2026
f07ad88
docs: Add visual changes to v16 Upgrade Guide
jamesfan Jun 24, 2026
fcac97f
Merge branch 'prerelease/major' of github.com:Workday/canvas-kit into…
jamesfan Jun 24, 2026
bcdef56
feat: Add cornerShapeStencil to TextInput, FormFieldGroupList, and Co…
jamesfan Jun 24, 2026
37afba8
docs: Update Upgrade Guide
jamesfan Jun 24, 2026
f7805dd
chore: Add Sana Theme Color Picker visual tests
jamesfan Jun 24, 2026
92518ad
docs: Fix Upgrade Guide
jamesfan Jun 24, 2026
ae9ae1e
chore: Revert update to Color Picker visual testing stories
jamesfan Jun 24, 2026
6f6ed4b
chore: Default Color Picker stories to Sana Canvas theme
jamesfan Jun 24, 2026
07db652
chore: Default Form Field, Text Area, and Text Input stories to Sana …
jamesfan Jun 24, 2026
9bde3e3
chore: Add v16 Upgrade Guide to routes file
jamesfan Jun 24, 2026
92b234c
docs: Add Sana Canvas example to Text Input
jamesfan Jun 24, 2026
646df83
docs: Add Sana Canvas example to Text Area
jamesfan Jun 24, 2026
d38721c
docs: Add Sana Canvas example to Form Field
jamesfan Jun 24, 2026
4188f45
docs: Add Sana Canvas example to Color Preview
jamesfan Jun 24, 2026
09245e9
docs: Add Sana Canvas example to Color Input
jamesfan Jun 24, 2026
8be501d
fix: Fix Color Preview stories
jamesfan Jun 25, 2026
4bce17f
chore: Revert addition of SanaCanvas examples
jamesfan Jun 25, 2026
7b5ab04
fix: Remove unnecessary data-theme from ColorPicker story
jamesfan Jun 25, 2026
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
3 changes: 3 additions & 0 deletions .storybook/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ const routes = {
'/help/upgrade-guides/canvas-v15-upgrade-guide/': 'guides-upgrade-guides-v15-0-overview--docs',
'/help/upgrade-guides/canvas-v15-upgrade-guide/#tab=visual-changes':
'guides-upgrade-guides-v15-0-visual-changes--docs',
'/help/upgrade-guides/canvas-v16-upgrade-guide/': 'guides-upgrade-guides-v16-0-overview--docs',
'/help/upgrade-guides/canvas-v16-upgrade-guide/#tab=visual-changes':
'guides-upgrade-guides-v16-0-visual-changes--docs',
Comment on lines +87 to +89

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.

ty for adding that 😎

};

export default routes;
53 changes: 52 additions & 1 deletion modules/docs/mdx/16.0-UPGRADE-GUIDE.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,58 @@ yarn remove @workday/canvas-kit-codemod

## Component Updates

[Content will be added]
> **Note:** All visual updates apply to both the Default Canvas theme and new Sana Canvas theme
> unless specified otherwise.

### Color Input

**PR:** [#3992](https://github.com/Workday/canvas-kit/pull/3992)

#### Visual Updates

- Shape is now **12px** (previously 8px).

### Color Picker

**PR:** [#3992](https://github.com/Workday/canvas-kit/pull/3992)

#### Visual Updates

- **Sana Canvas:** swatch shape is now **6px** (previously **4px**).

### Form Field

**PR:** [#3992](https://github.com/Workday/canvas-kit/pull/3992)

#### Visual Updates

- Shape for grouped inputs (Radio groups and Checkbox groups) is now **12px** (previously 8px). As
in v15, this shape is primarily visible for error and caution states.
- Block padding for grouped inputs is now **8px** (previously **10px** and **8px**). Inline padding
for grouped inputs is now **4px** (previously **12px**). Again, this padding is primarily visible
for error and caution states.
- Error and caution states no longer display a status background color; only the standard background
is shown.

### Text Area

**PR:** [#3992](https://github.com/Workday/canvas-kit/pull/3992)

#### Visual Updates

- Shape is now **12px** (previously 8px).
- Error and caution states no longer display a status background color; only the standard background
is shown.

### Text Input

**PR:** [#3992](https://github.com/Workday/canvas-kit/pull/3992)

#### Visual Updates

- Shape is now **12px** (previously 8px).
- Error and caution states no longer display a status background color; only the standard background
is shown.

## New Utilities

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const ColorPickerStates = {
},
},
render: () => (
<StaticStates>
<StaticStates data-theme="sana-canvas">
<ComponentStatesTable
rowProps={[
{label: 'Default', props: {}},
Expand Down
7 changes: 4 additions & 3 deletions modules/react/color-picker/lib/parts/ColorSwatch.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';

import {pickForegroundColor} from '@workday/canvas-kit-react/common';
import {cornerShapeStencil, pickForegroundColor} from '@workday/canvas-kit-react/common';
import {SystemIcon, systemIconStencil} from '@workday/canvas-kit-react/icon';
import {calc, createStencil, handleCsProp, px2rem} from '@workday/canvas-kit-styling';
import {checkSmallIcon} from '@workday/canvas-system-icons-web';
Expand All @@ -12,15 +12,16 @@ export interface ColorSwatchProps extends React.HTMLAttributes<HTMLDivElement> {
}

export const colorPickerColorSwatchStencil = createStencil({
extends: cornerShapeStencil,
vars: {
color: '',
iconColor: '',
},
base: ({color, iconColor}) => ({
[systemIconStencil.vars.color]: iconColor,
[cornerShapeStencil.vars.shape]: system.legacy.shape.sm,
width: system.legacy.size.xxs,
height: system.legacy.size.xxs,
borderRadius: system.legacy.shape.sm,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The upgrade guide says Color Picker’s Sana Canvas swatch shape is now 6px, but the implementation uses system.legacy.shape.sm, which resolves to 4px in the installed tokens I checked.

Can we double check this?

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.

there is 2 theme and 2 different values: standard is 4px, but if sana turn on it's 6px

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.

it will be updated with new tokens alpha

backgroundColor: color,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Medium: ColorSwatch does not preserve color meaning in Windows High Contrast / forced-colors mode. Since the swatch’s semantic value is its actual color, backgroundColor: color will likely be remapped by forced-colors, causing swatches to appear identical. Consider forcedColorAdjust: 'none' for the swatch color surface, plus a real border/outline fallback for white/selected states since box-shadow is forced to none.

display: 'flex',
alignItems: 'center',
Expand Down Expand Up @@ -50,7 +51,7 @@ export const ColorSwatch = ({color, showCheck = false, ...elemProps}: ColorSwatc
colorPickerColorSwatchStencil({
color,
iconColor: pickForegroundColor(color),
withShadow: showCheck || lowerCasedColor === '#ffffff',
withShadow: showCheck || lowerCasedColor === '#ffffff' ? 'true' : undefined,
})
)}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default {
};

export const ColorInputStates = () => (
<StaticStates>
<StaticStates data-theme="sana-canvas">
<ComponentStatesTable
rowProps={permutateProps(
{
Expand Down
9 changes: 4 additions & 5 deletions modules/react/form-field/lib/FormFieldGroupList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {createSubcomponent} from '@workday/canvas-kit-react/common';
import {cornerShapeStencil, createSubcomponent} from '@workday/canvas-kit-react/common';
import {FlexProps} from '@workday/canvas-kit-react/layout';
import {CSProps, calc, createStencil, handleCsProp, px2rem} from '@workday/canvas-kit-styling';
import {base, system} from '@workday/canvas-tokens-web';
Expand All @@ -8,24 +8,23 @@ import {useFormFieldModel} from './hooks';
export interface FormFieldGroupListProps extends CSProps, FlexProps {}

const formFieldGroupListStencil = createStencil({
extends: cornerShapeStencil,
base: {
[cornerShapeStencil.vars.shape]: system.legacy.shape.lg,
display: 'flex',
flexDirection: 'column',
borderRadius: system.legacy.shape.md,
gap: system.legacy.gap.sm,
padding: `${px2rem(10)} ${base.legacy.size150} ${system.legacy.padding.xs}`,
padding: `${system.legacy.padding.xs} ${system.legacy.padding.xxs}`,
margin: `0 ${calc.negate(base.legacy.size150)}`,
transition: '100ms box-shadow',
width: 'fit-content',
},
modifiers: {
error: {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Medium: Error/caution visual affordances rely heavily on boxShadow, which is removed in forced-colors mode. For TextInput, TextArea inherits this behavior; for grouped fields, the group ring is entirely shadow-based. Add @media (forced-colors: active) fallbacks using real border/outline and system colors so Windows High Contrast users can still perceive invalid/caution states.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@williamjstanton I'm consulting the MDN docs for system colors. Which color would you recommend I use for error and caution states?

For example, ActiveText is visually similar to our standard error color (red), but doesn't line up semantically (i.e., the form field error has nothing to do with the "text of active links").

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@williamjstanton Also, it wasn't quite clear from your original comment, but is it ok to leave TextInput and TextArea as-is given they both still have a border in the error and caution states?

@williamjstanton williamjstanton Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@williamjstanton I'm consulting the MDN docs for system colors. Which color would you recommend I use for error and caution states?

For example, ActiveText is visually similar to our standard error color (red), but doesn't line up semantically (i.e., the form field error has nothing to do with the "text of active links").

This is a really good question, and I don't know. There isn't any semantically correct option available at all. The recommendation is to use border differentiation like double but I don't think it is necessary in the case of FormFieldGroupList. I think we could try a simple transparent border or outline as a fallback?

.form-field.error {
  border: 2px solid red; /* Standard mode color */
}
@media (forced-colors: active) {
  .form-field.error {
    /* Use a thicker or distinct border style with standard system colors */
    border: 4px double ButtonBorder; 
  }

@jamesfan jamesfan Jun 26, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'm using outline to prevent layout shifts since FormFieldGroupList doesn't have a border to begin with. My plan was to maintain a similar thickness to the boxShadow for the outline:

error: {
  boxShadow: `inset 0 0 0 ${px2rem(2)} ${system.legacy.color.brand.border.critical}`,
  '@media (forced-colors: active)': {
    outline: `solid ${px2rem(2)} ActiveText`,
  },
},

I can double the thickness, however. Out of curiosity, what's the rationale behind differentiating the border if forced-colors is active?

Also, did you mean to use ButtonBorder (presents as black to me in macOS) in your example snippet?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also, did you mean to use ButtonBorder (presents as black to me in macOS) in your example snippet?

Really? Presents as black? I'd assumed it would present as white on a dark background. I'll definitely need to test on a real Windows machine.

Rationale: Since we can't use color to differentiate a border on an input that already uses a border in a valid state (e.g. TextInput), that's where it is useful to use more thickness or a double style to differentiate the error states from valid states.

I don't think that rationale applies in this situation with the group list. (Because the border / outline / boxShadow is absent in valid state.)

error: {
backgroundColor: system.legacy.color.brand.surface.critical.default,
boxShadow: `inset 0 0 0 ${px2rem(2)} ${system.legacy.color.brand.border.critical}`,
},
caution: {
backgroundColor: system.legacy.color.brand.surface.caution.default,
boxShadow: `inset 0 0 0 ${px2rem(1)} ${system.legacy.color.brand.border.caution}, inset 0 0 0 ${px2rem(3)} ${system.legacy.color.brand.focus.caution.inner}`,
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default {
};

export const FormFieldStates = () => (
<StaticStates>
<StaticStates data-theme="sana-canvas">
<ComponentStatesTable
rowProps={[
{label: 'Required', props: {isRequired: true}},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default {
};

export const TextAreaStates = () => (
<StaticStates>
<StaticStates data-theme="sana-canvas">
<ComponentStatesTable
rowProps={permutateProps(
{
Expand Down
18 changes: 13 additions & 5 deletions modules/react/text-input/lib/TextInput.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import {ErrorType, GrowthBehavior, createComponent} from '@workday/canvas-kit-react/common';
import {
ErrorType,
GrowthBehavior,
cornerShapeStencil,
createComponent,
} from '@workday/canvas-kit-react/common';
import {mergeStyles} from '@workday/canvas-kit-react/layout';
import {CSProps, createStencil, cssVar, px2rem} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
Expand All @@ -15,10 +20,12 @@ export interface TextInputProps extends GrowthBehavior, CSProps {
}

export const textInputStencil = createStencil({
extends: cornerShapeStencil,
vars: {
width: '',
},
base: ({width}) => ({
[cornerShapeStencil.vars.shape]: system.legacy.shape.lg,
fontFamily: system.fontFamily.default,
fontSize: system.legacy.fontSize.subtext.lg,
fontWeight: system.fontWeight.normal,
Expand All @@ -27,7 +34,6 @@ export const textInputStencil = createStencil({
display: 'block',
border: `${px2rem(1)} solid ${system.color.border.input.default}`,
backgroundColor: system.legacy.color.surface.default,
borderRadius: system.legacy.shape.md,
height: system.legacy.size.md,
transition: '0.2s box-shadow, 0.2s border-color',
padding: system.legacy.padding.xs, // Compensate for border
Expand Down Expand Up @@ -74,7 +80,6 @@ export const textInputStencil = createStencil({
borderColor: system.legacy.color.brand.border.critical,
// borderWidth: px2rem(2),
boxShadow: `inset 0 0 0 ${px2rem(2)} ${system.legacy.color.brand.border.critical}`,
backgroundColor: system.legacy.color.brand.surface.critical.default,
'&:is(:hover, .hover, :disabled, .disabled, :focus-visible:not([disabled]), .focus:not([disabled]))':
{
borderColor: system.legacy.color.brand.border.critical,
Expand All @@ -89,7 +94,6 @@ export const textInputStencil = createStencil({
caution: {
borderColor: system.legacy.color.brand.border.caution,
boxShadow: `inset 0 0 0 ${px2rem(2)} ${system.legacy.color.brand.focus.caution.inner}`,
backgroundColor: system.legacy.color.brand.surface.caution.default,
'&:is(:hover, .hover, :disabled, .disabled, :focus-visible:not([disabled]), .focus:not([disabled]))':
{
borderColor: system.legacy.color.brand.border.caution,
Expand Down Expand Up @@ -117,7 +121,11 @@ export const TextInput = createComponent('input')({
ref={ref}
{...mergeStyles(
elemProps,
textInputStencil({width: typeof width === 'number' ? px2rem(width) : width, grow, error})
textInputStencil({
width: typeof width === 'number' ? px2rem(width) : width,
grow: grow === true ? 'true' : grow === false ? 'false' : undefined,
error,
})
Comment on lines +124 to +128

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This fix addresses a TypeScript issue which appeared after introducing extends cornerShapeStencil:

Image

Explanation of the fix from Cursor:

Image

And why the error only happened after introducing extends cornerShapeStencil:

Image

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.

connected to #3896, I'll talk to Alan about that the next week ☺️

Comment on lines +124 to +128

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.

we need to fix that issue finally :D I'll talk to Alan about that when he is back

)}
/>
);
Expand Down
4 changes: 2 additions & 2 deletions modules/react/text-input/stories/visualTesting.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default {
};

export const TextInputStates = () => (
<StaticStates>
<StaticStates data-theme="sana-canvas">

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.

Suggested change
<StaticStates data-theme="sana-canvas">
<StaticStates>

this can be removed after branches synced

<ComponentStatesTable
rowProps={permutateProps(
{
Expand Down Expand Up @@ -88,7 +88,7 @@ TextInputThemedStates.parameters = {
};

export const InputGroupStates = () => (
<StaticStates>
<StaticStates data-theme="sana-canvas">
<ComponentStatesTable
rowProps={[
{
Expand Down
Loading