diff --git a/CHANGELOG.md b/CHANGELOG.md index 24c3dd1359..2a3449e6c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,40 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [v14.2.9](https://github.com/Workday/canvas-kit/releases/tag/v14.2.9) (2026-01-16) + +### Components + +- fix: Fix default icon colors for ToolbarIconButton and ToolbarDropdownButton ([#3691](https://github.com/Workday/canvas-kit/pull/3691)) ([@adamtbui](https://github.com/adamtbui), Adam Bui) + + +## [v14.2.8](https://github.com/Workday/canvas-kit/releases/tag/v14.2.8) (2026-01-15) + +### Components + +- fix: Add variant type to insights ([#3685](https://github.com/Workday/canvas-kit/pull/3685)) ([@mannycarrera4](https://github.com/mannycarrera4), manuel.carrera, Alan Smith) + + +## [v13.2.51](https://github.com/Workday/canvas-kit/releases/tag/v13.2.51) (2026-01-15) + +### Components + +- fix: Add variant type to insights ([#3685](https://github.com/Workday/canvas-kit/pull/3685)) ([@mannycarrera4](https://github.com/mannycarrera4), manuel.carrera, Alan Smith) +## [v14.2.7](https://github.com/Workday/canvas-kit/releases/tag/v14.2.7) (2026-01-15) + +### Documentation + +- chore: Add llm cursor rules mdc ([#3684](https://github.com/Workday/canvas-kit/pull/3684)) ([@youryss](https://github.com/youryss), Youry Stancatte) + Added `modules/docs/llm/canvas-kit.mdc` - a Cursor/Claude rules file containing Canvas Kit best practices. Teams can add this to their `.cursor/rules/` directory to have AI assistants follow Canvas Kit conventions automatically. + + +## [v14.2.6](https://github.com/Workday/canvas-kit/releases/tag/v14.2.6) (2026-01-13) + +### Components + +- fix: Use getBoundingClientRect for popup width measurement ([#3686](https://github.com/Workday/canvas-kit/pull/3686)) ([@Zav39](https://github.com/Zav39)) + + ## [v14.2.5](https://github.com/Workday/canvas-kit/releases/tag/v14.2.5) (2026-01-08) diff --git a/lerna.json b/lerna.json index 42b45de03a..0719e27e51 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "packages": [ "modules/**" ], - "version": "14.2.5", + "version": "14.2.9", "npmClient": "yarn", "command": { "version": { diff --git a/modules/codemod/package.json b/modules/codemod/package.json index c3cca9eb0b..e8d15d9fe9 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": "14.2.5", + "version": "14.2.9", "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 72e51520b7..9748a0ba4a 100644 --- a/modules/css/package.json +++ b/modules/css/package.json @@ -1,6 +1,6 @@ { "name": "@workday/canvas-kit-css", - "version": "14.2.5", + "version": "14.2.9", "description": "The parent module that contains all Workday Canvas Kit CSS components", "author": "Workday, Inc. (https://www.workday.com)", "license": "Apache-2.0", diff --git a/modules/docs/llm/canvas-kit.mdc b/modules/docs/llm/canvas-kit.mdc new file mode 100644 index 0000000000..a3ca5beaa7 --- /dev/null +++ b/modules/docs/llm/canvas-kit.mdc @@ -0,0 +1,580 @@ +--- +description: Best practices for Workday Canvas Kit - tokens, styling, components, and accessibility +globs: ['**/*.tsx', '**/*.ts', '**/*.jsx', '**/*.js', '**/*.css'] +alwaysApply: true +--- + +# Canvas Kit Best Practices + +This file contains best practices for working with Workday Canvas Kit. Use these guidelines when +building components, styling, and implementing accessibility features. + +## Token Usage Guidelines + +### Always Use Design Tokens + +- **Prefer system tokens** from `@workday/canvas-tokens-web` over raw CSS values +- Use semantic token names (e.g., `system.color.bg.primary.default`) instead of hardcoded colors + (e.g., `#333`) +- Token hierarchy: base tokens → brand tokens → system tokens +- System tokens provide better theming support than base tokens + +### Token Import Pattern + +```tsx +import {system, brand, base} from '@workday/canvas-tokens-web'; + +// Import CSS variables once at app root level +import '@workday/canvas-tokens-web/css/base/_variables.css'; +import '@workday/canvas-tokens-web/css/system/_variables.css'; +import '@workday/canvas-tokens-web/css/brand/_variables.css'; +``` + +### Token Usage Examples + +```tsx +// ✅ Good - Use system tokens +const styles = createStyles({ + color: system.color.text.default, + margin: system.space.x4, + backgroundColor: system.color.bg.primary.default, +}); + +// ❌ Avoid - Hardcoded values +const styles = createStyles({ + color: '#333', + margin: '16px', + backgroundColor: 'blue', +}); +``` + +## Styling Best Practices + +### Core Styling APIs + +Canvas Kit uses a custom CSS-in-JS solution for static CSS generation and token integration: + +- **`createStyles`** - Define reusable, static CSS objects +- **`createStencil`** - Define reusable, dynamic component styles with parts, vars, and modifiers +- **`cs` prop** - Apply multiple styles and handle merges consistently to Canvas Kit components + +### Define Styles Outside Render Functions + +**Critical:** Always declare styles at the module level. Creating styles inside render functions +causes performance issues. + +```tsx +// ✅ Good - Module level +const buttonStyles = createStyles({ + backgroundColor: system.color.bg.primary.default, + color: system.color.text.inverse, +}); + +export const MyButton = () => ; + +// ❌ Bad - Inside render function +export const MyButton = () => { + const buttonStyles = createStyles({backgroundColor: 'red'}); // Performance hit! + return ; +}; +``` + +### When to Use `createStyles` + +Use `createStyles` for simple, reusable style objects that do **not** depend on dynamic data or +props: + +- Defining base styles +- Applying static overrides +- Styling tokens-based components + +```tsx +import {createStyles} from '@workday/canvas-kit-styling'; +import {system} from '@workday/canvas-tokens-web'; +import {Text} from '@workday/canvas-kit-react/text'; + +const uppercaseTextStyles = createStyles({ + textTransform: 'uppercase', + margin: system.space.x4, +}); + +My uppercased text; +``` + +### When to Use `createStencil` + +Use `createStencil` when styles depend on **props**, **variants**, or **component parts**: + +- Size or color variants (`primary`, `secondary`) +- Compound state combinations (`size=small`, `iconPosition=end`) +- Multi-part components (e.g., `Button`, `Card`, `MenuItem`) + +```tsx +const buttonStencil = createStencil({ + vars: {color: '', backgroundColor: ''}, + base: ({color, backgroundColor}) => ({ + color: cssVar(color, system.color.text.default), + backgroundColor: cssVar(backgroundColor, system.color.bg.default), + }), + modifiers: { + variant: { + primary: {backgroundColor: system.color.bg.primary.default}, + secondary: {backgroundColor: system.color.bg.muted.default}, + }, + }, +}); +``` + +### Using the `cs` Prop + +The `cs` prop accepts styles created by `createStyles`, `createStencil`, or a class name. Canvas Kit +components already handle style merging internally via `handleCsProp`: + +```tsx +// ✅ Good - Pass styles to cs prop on Canvas Kit components + + +// ✅ Good - Multiple styles via array + +``` + +**Important:** When building custom components, use `handleCsProp` to properly merge `className`, +`style`, and `cs` props. Do not manually concatenate class names: + +```tsx +// ✅ Good - Use handleCsProp in custom components +const MyComponent = elemProps => { + return
; +}; + +// ❌ Avoid - Manual className concatenation loses style merging +
; +``` + +### CSS Logical Properties for RTL Support + +Use CSS logical properties instead of physical properties for RTL compatibility: + +```tsx +// ✅ Good - Logical properties (adapt to RTL automatically) +const styles = createStyles({ + marginInlineStart: system.space.x4, + paddingInlineEnd: system.space.x2, + borderInlineStart: `1px solid ${system.color.border.default}`, +}); + +// ❌ Avoid - Physical properties (don't adapt to RTL) +const styles = createStyles({ + marginLeft: system.space.x4, + paddingRight: system.space.x2, + borderLeft: `1px solid ${system.color.border.default}`, +}); +``` + +### Utility Functions + +- **`px2rem()`** - Convert pixel values to rem units +- **`cssVar()`** - Wrap tokens in CSS variable syntax with optional fallback +- **`calc`** - Math operations with CSS calc() and variables + +```tsx +import {px2rem, cssVar, calc} from '@workday/canvas-kit-styling'; + +const styles = createStyles({ + margin: px2rem(8), // Converts 8px to rem + padding: calc.add(system.space.x1, '0.125rem'), + color: cssVar(system.color.text.default, '#000'), // With fallback +}); +``` + +### Avoid Emotion Runtime APIs + +- Avoid `styled()` from `@emotion/styled` for new code +- Avoid inline style objects in `cs` prop (use `createStyles` or `createStencil` instead) +- Don't mix Emotion and static styling approaches + +## Component Patterns + +### Compound Components + +Prefer the compound component pattern for flexible, semantic component APIs: + +```tsx +// ✅ Good - Compound component pattern + + + First Tab + Second Tab + + First Tab Contents + Second Tab Contents + + +// ❌ Avoid - Configuration component (less flexible) + +``` + +### Controlled Components + +- Prefer controlled components wherever possible +- Manage minimal state within components +- Use standard event handlers: `value` and `onChange` for inputs, `checked` and `onChange` for + checkboxes + +```tsx +// ✅ Good - Controlled component +const [value, setValue] = useState(''); + setValue(e.target.value)} />; +``` + +### Prop Spreading Pattern + +Use Canvas Kit utility functions to handle ref forwarding and HTML attribute extraction: + +**For simple components**, use `createComponent`: + +```tsx +import {createComponent} from '@workday/canvas-kit-react/common'; + +interface ButtonProps { + variant: 'primary' | 'secondary'; + size: 'small' | 'medium' | 'large'; + children: React.ReactNode; +} + +export const Button = createComponent('button')({ + displayName: 'Button', + Component: ({variant, size, children, ...elemProps}: ButtonProps, ref, Element) => { + return ( + + {children} + + ); + }, +}); +``` + +`createComponent` automatically handles: + +- Ref forwarding +- HTML attribute extraction based on the element type +- The `as` prop for changing the rendered element +- Proper TypeScript typing + +**For compound components with models**, use `createContainer` and `createSubComponent`: + +```tsx +import {createContainer, createSubComponent} from '@workday/canvas-kit-react/common'; + +// Container component +export const Disclosure = createContainer()({ + displayName: 'Disclosure', + modelHook: useDisclosureModel, + subComponents: { + Target: DisclosureTarget, + Content: DisclosureContent, + }, +})(({children}) => { + return <>{children}; +}); + +// Sub-component +export const DisclosureTarget = createSubComponent('button')({ + modelHook: useDisclosureModel, +})((elemProps, Element, model) => { + return model.events.toggle()} {...elemProps} />; +}); +``` + +These utilities handle ref forwarding, HTML attribute extraction, and model context automatically. + +### CanvasProvider + +Wrap your application in `` for proper styling context and Emotion cache: + +```tsx +import {CanvasProvider} from '@workday/canvas-kit-react/common'; + + + +; +``` + +### Using `handleCsProp` + +When building custom components with stencils, use `handleCsProp` to merge props: + +```tsx +import {handleCsProp} from '@workday/canvas-kit-styling'; + +const MyComponent = elemProps => { + return
; +}; +``` + +## Common Patterns + +### Style Definition Location + +**Always define styles at module level**, never inside render functions or component bodies: + +```tsx +// ✅ Good +const cardStyles = createStyles({ + padding: system.space.x4, +}); + +export const Card = () =>
Content
; + +// ❌ Bad +export const Card = () => { + const cardStyles = createStyles({padding: system.space.x4}); + return
Content
; +}; +``` + +### Modifiers Over Conditionals + +Use modifiers for variants/states instead of conditional logic: + +```tsx +// ✅ Good - Use modifiers +const badgeStencil = createStencil({ + modifiers: { + status: { + success: {background: system.color.bg.success.default}, + error: {background: system.color.bg.negative.default}, + }, + }, +}); + +// ❌ Avoid - Conditional logic in styles +const badgeStyles = status => + createStyles({ + background: status === 'success' ? 'green' : 'red', // Breaks static compilation + }); +``` + +### CSS Variables for Dynamic Values + +Use CSS variables (via stencil vars) for dynamic values instead of inline styles: + +```tsx +// ✅ Good - CSS variables +const buttonStencil = createStencil({ + vars: {backgroundColor: ''}, + base: ({backgroundColor}) => ({ + backgroundColor: cssVar(backgroundColor, system.color.bg.default), + }), +}); + +// ❌ Avoid - Inline styles +