workday/canvas-kit/sana-canvas-kit-builder
Claude Code and agent skill by workday/canvas-kit
- community
Checking that the SKILL.md file is still in the repository.
Build custom React components with Canvas Kit factories from @workday/canvas-kit-react/common. Use when creating createComponent, createContainer, createSubcomponent, createModelHook, or createElemPropsHook; designing compound component APIs; or adding shared state/behavior. For styling see /sana-canvas-kit-styling; for tokens see /sana-canvas-kit-tokens; for accessibility see /sana-canvas-kit-accessibility; for avoiding deprecated exports see /sana-canvas-kit-component-selection.
Install
npx vskill@latest install workday/canvas-kit/sana-canvas-kit-builderSKILL.md
Canvas Kit Component Builder
Build custom components in consumer apps using Canvas Kit's exported factories. This skill covers the factory pattern — not contributing a component into the canvas-kit repo itself (that workflow uses yarn create-component, Storybook, Cypress, and stricter repo requirements).
Styling → /sana-canvas-kit-styling. Tokens → /sana-canvas-kit-tokens. Accessibility → /sana-canvas-kit-accessibility. Deprecated exports when composing existing components → /sana-canvas-kit-component-selection. Version detection (which factory APIs are available) → /sana-canvas-kit-version. Deciding whether a Canvas component already covers the use case before building your own → /sana-canvas-kit-design-principles.
When to apply
- Building a new reusable component with or without shared state
- Designing a compound component API (
<MyThing.Target>,<MyThing.Content>) - Extracting behavior into reusable elemProps hooks
- Wrapping Canvas Kit primitives into a tighter app-specific API
Factory selection
| Situation | Use | |
|---|---|---|
| Styled element, no behavior, no shared state | createComponent | |
| Root that owns/provides a model | createContainer + createModelHook | |
| Child that consumes the model | createSubcomponent | |
| Reusable prop/behavior logic on an element | createElemPropsHook (+ composeHooks) | |
| State + events (config, guards, callbacks) | createModelHook |
No shared state? Use createComponent — don't add a model.
Shared state across subcomponents? createModelHook → createContainer (root) → createSubcomponent (children).
Minimal compound component
Model
createModelHook gives you should<Event> guards and on<Event> callbacks for free.
Container
createContainer adds children, model, ref, and as to the prop types automatically. Do not declare them on your Props interface. Subcomponent JSDoc belongs inside the `subComponents` object on the container.
Subcomponent with elemProps hook
Static subcomponent (no behavior)
Core rules
- Never call `createElemPropsHook` / `composeHooks` inside a render function — hoist to module
scope.
- Merge props correctly — primitives override; callbacks/
style/className/csmerge. Use
mergeProps for hand-rolled props; handleCsProp for cs in reusable styled components (/sana-canvas-kit-styling).
- Don't declare `children`, `model`, `ref`, or `as` on Props — factories add them.
- No default exports in library modules.
- No TS `enum` — use disjoint string unions (
size: 'small' | 'medium' | 'large'). - Prop names never repeat the component name (
type, notbuttonType). - Avoid direction/color-coupled names (
startIcon, notleftIcon— breaks under RTL). - JSDoc every prop — include
@defaulton booleans and enum props. - Import from public subpaths —
@workday/canvas-kit-react/<component>, never the package barrel
or /lib/.
- Define styles at module level —
createStyles/createStencil+cs, not style props
(/sana-canvas-kit-styling).
Model composition
Compose smaller models when behavior is reusable (e.g. useIDModel for id + aria-controls):
Lists and grids — use the collection system
If the custom component is a list, grid, or set of items with selection, roving focus, or arrow-key navigation, extend @workday/canvas-kit-react/collection instead of hand-rolling selection/useState for the item set:
- Models:
useListModel,useGridModel,useOverflowListModel - Item hooks:
useListItemRegister,useListItemSelect,useListItemRovingFocus(compose via
composeHooks; register last unless overriding a prop register sets)
- Selection managers:
singleSelectionManager,multiSelectionManager
Keep a plain createModelHook (like the disclosure example above) for non-collection state (visibility, ids, form flags). For contributing a collection-based component into the canvas-kit repo, see /sana-canvas-kit-contribute-component.
Accessibility
Wire a11y in createElemPropsHook (e.g. aria-expanded, aria-controls, id from useIDModel). Full patterns — naming, keyboard, popups, forms, live regions, MCP lookup → /sana-canvas-kit-accessibility.
Workflow
App-level wrappers
Compound APIs are verbose by design. Apps often wrap them into tighter interfaces:
This is encouraged when the app knows its context (translations, test ids, analytics).
Anti-patterns
- ❌
createModelHookfor a static styled div - ❌ Hand-rolled selection / roving tabindex for a list or grid — use collection
- ❌
createElemPropsHookinside render - ❌ Manual
React.ContextwhencreateContainer/createSubcomponenthandle it - ❌
forwardRef+ Context by hand — use the factories - ❌ Style props on
Flex/Box(padding="s") - ❌
enumfor prop types - ❌
leftIcon/blueVariantprop names - ❌ Default exports
- ❌ Importing from
@workday/canvas-kit-reactbarrel or/lib/
Decision guide
Additional resources
- Full walkthrough:
modules/docs/mdx/CREATING_COMPOUND_COMPONENTS.mdx - API patterns:
modules/docs/mdx/API_PATTERN_GUIDELINES.mdx - Accessibility:
modules/docs/mdx/accessibility/AccessibilityOverview.mdx
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/sana-canvas-kit-builder/SKILL.md
Popularity
- Repository stars
- 367
- Repository forks
- 270
- 7-day trend score
- 0
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/workday/canvas-kit/sana-canvas-kit-builder)