-
Notifications
You must be signed in to change notification settings - Fork 256
feat: Implement Sana Canvas Text Input, Text Area, Form Field, and Color Picker #3992
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: prerelease/major
Are you sure you want to change the base?
Changes from all commits
8ad3aff
b3f1b31
bf299e6
cfea945
459c285
f07ad88
fcac97f
bcdef56
37afba8
f7805dd
92518ad
ae9ae1e
6f6ed4b
07db652
9bde3e3
92b234c
646df83
d38721c
4188f45
09245e9
8be501d
4bce17f
7b5ab04
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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'; | ||
|
|
@@ -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, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it will be updated with new tokens alpha |
||
| backgroundColor: color, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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', | ||
|
|
@@ -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, | ||
| }) | ||
| )} | ||
| > | ||
|
|
||
| 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'; | ||
|
|
@@ -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: { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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").
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm using 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
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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 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}`, | ||
| }, | ||
| }, | ||
|
|
||
| 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'; | ||
|
|
@@ -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, | ||
|
|
@@ -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 | ||
|
|
@@ -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, | ||
|
|
@@ -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, | ||
|
|
@@ -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
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| )} | ||
| /> | ||
| ); | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -24,7 +24,7 @@ export default { | |||||
| }; | ||||||
|
|
||||||
| export const TextInputStates = () => ( | ||||||
| <StaticStates> | ||||||
| <StaticStates data-theme="sana-canvas"> | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
this can be removed after branches synced |
||||||
| <ComponentStatesTable | ||||||
| rowProps={permutateProps( | ||||||
| { | ||||||
|
|
@@ -88,7 +88,7 @@ TextInputThemedStates.parameters = { | |||||
| }; | ||||||
|
|
||||||
| export const InputGroupStates = () => ( | ||||||
| <StaticStates> | ||||||
| <StaticStates data-theme="sana-canvas"> | ||||||
| <ComponentStatesTable | ||||||
| rowProps={[ | ||||||
| { | ||||||
|
|
||||||



There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ty for adding that 😎