@workday/canvas-kit-docs 14.0.0-alpha.1149-next.0 → 14.0.0-alpha.1153-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,136 @@
1
+ # Why Canvas Styling
2
+
3
+ This package contains everything needed to create CSS styling. This styling package contains a
4
+ runtime for development and a static parsing process for build time.
5
+
6
+ Here are the goals for this project:
7
+
8
+ - TypeScript autocomplete of CSS object properties
9
+ - Low runtime for development
10
+ - Static CSS compilation for faster user experience
11
+ - Static CSS extraction for CSS only packages
12
+ - Dynamic styles using CSS Variables
13
+
14
+ If you're using Canvas Kit and not directly using this package, there is nothing extra to do on your
15
+ end. The Canvas Kit packages are using the static compilation as part of the build process. If you
16
+ want to use this package for your own styles, you don't need to do anything special to use in
17
+ development. Included is a small runtime to get styling working. If you wish to statically compile
18
+ your CSS from your TypeScript files for faster page loading, visit the
19
+ [Getting Started](/docs/styling-getting-started--docs) page.
20
+
21
+ ## Why?
22
+
23
+ Canvas Kit no longer needs to support IE11 which allows us to use
24
+ [CSS Custom Properties a.k.a. CSS Variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties).
25
+ Dynamic style properties (properties that change during the lifecylce of the component) are the most
26
+ costly in terms of performance in Emotion and should be avoided. Also, any conditionals in your
27
+ Emotion style functions create unique hashes in the Emotion cache and makes that render frame pay an
28
+ expensive
29
+ [style recalculation](https://microsoftedge.github.io/DevTools/explainers/StyleTracing/explainer.html).
30
+
31
+ We can avoid most of the cost of Emotion's runtime by using
32
+ [@emotion/css](https://www.npmjs.com/package/@emotion/css) instead and hoist all style definitions
33
+ outside of a component's render function. All dynamic styling can be moved into "modifiers" (from
34
+ [BEM](https://getbem.com/introduction/#modifer:~:text=%2C%20header%20title-,Modifier,-A%20flag%20on)).
35
+
36
+ There's still a runtime to select which styles should apply to an element and what the CSS Variable
37
+ should be, but it is essentially only having to choose what CSS classes should apply to an element
38
+ and changing the `style` property to set the CSS Variables. This does not require new
39
+ [StyleSheet](https://developer.mozilla.org/en-US/docs/Web/API/StyleSheet) inserts which cause
40
+ expensive style recalculation. Think of the runtime as being the following:
41
+
42
+ ```jsx
43
+ <div
44
+ className={getClassNames(/* input from props */)}
45
+ style={getCSSVarValues(/* input from props */)}
46
+ />
47
+ ```
48
+
49
+ For further information, please read our GitHub discussion on
50
+ [the future of styling](https://github.com/Workday/canvas-kit/discussions/2265)
51
+
52
+ ## What is Canvas Kit Styling?
53
+
54
+ Canvas Kit Styling includes two things:
55
+
56
+ 1. A utility function wrapper around `@emotion/css`
57
+ 2. An optional static compiler to remove most of the runtime
58
+
59
+ ### Utility Functions
60
+
61
+ This packages provides three utility functions to make it easier to style element-based components.
62
+ The following is a brief description of each function. If you'd like to read a more in-depth
63
+ discussion of each, our [API docs](/docs/features-styling-api--create-styles).
64
+
65
+ The primary utility function is the `createStyles` function. It makes a call to the `css` function
66
+ from `@emotion/css`. Emotion still does most of the heavy lifting by handling the serialization,
67
+ hashing, caching, and style injection.
68
+
69
+ The other two utility functions, `createVars` and `createModifiers`, provide supplemental styling
70
+ functionality. `createVars` allows you to create temporary CSS variables within components to create
71
+ dynamic properties. And `createModifiers` creates a modifier function to create dynamic groups of
72
+ properties. If you're familiar with modifiers in [BEM](https://getbem.com/introduction/) (Block,
73
+ Element, Modifier) CSS, you're well on your way to understanding this function's intent.
74
+
75
+ ### Static Compiler
76
+
77
+ The static compiler run as a TypeScript transform during TypeScript's transpilation phase. It
78
+ requires the TypeScript type checker to determine the static value of any variables used. The
79
+ transformer calls `@emotion/serialize` to pre-compute the serialized styles and hash so that
80
+ `@emotion/css` can skip these steps. For example, there's the before/after of the code.
81
+
82
+ ```ts
83
+ // before
84
+ const myVars = createVars('textColor', 'backgroundColor');
85
+
86
+ const myStyles = createStyles({
87
+ fontSize: 12,
88
+ color: cssVar(myVars.textColor),
89
+ backgroundColor: cssVar(myVars.backgroundColor),
90
+ });
91
+
92
+ // after
93
+ const myVars = createVars('textColor', 'backgroundColor');
94
+
95
+ const myStyles = createStyles({
96
+ name: 'a8g234',
97
+ styles:
98
+ 'font-size: 12px; color: var(--css-my-vars-textColor); backgroundColor: var(--css-my-vars-backgroundColor);',
99
+ });
100
+ ```
101
+
102
+ Emotion has an internal shortcut that recognizes the `styles` property and
103
+ [short-circuits interpolation](https://github.com/emotion-js/emotion/blob/f3b268f7c52103979402da919c9c0dd3f9e0e189/packages/serialize/src/index.js#L319).
104
+
105
+ ## Performance
106
+
107
+ `createStyles` is more performant than `styled` components or the `css` prop because the styles must
108
+ be statically evaluated. The actual characters of a CSS property value cannot change at runtime.
109
+ This means we do not need to recalculate a hash every render or inject new `StyleSheet` entries into
110
+ the `StyleSheetList` in a render cycle. Injecting new `StyleSheets` causes slow
111
+ [Style Recalculation](https://web.dev/articles/reduce-the-scope-and-complexity-of-style-calculations).
112
+ What is not well known is browser engines maintain an internal selector cache to make style
113
+ recalculations as fast as possible. Adding a CSS class to a DOM element will invoke a style
114
+ recalculation, but if the the CSS selector is already in the `StyleSheetList`, the browser can
115
+ optimize how those styles are applied to the current element.
116
+
117
+ In the runtime Emotion's case, a novel style will result in a new style hash which results in a new
118
+ `StyleSheet` being injected into the `StyleSheetList`. To be safe, the browser's runtime engine will
119
+ throw away any style recalculation cache and start from scratch. This happens if you render a new
120
+ component on the page that hasn't been rendered yet, or if you make one of your style properties
121
+ dynamic between render cycles. Eventually the Emotion cache gets warm and style recalcuation costs
122
+ start to normalize and no longer invalidate the browser's selector cache.
123
+
124
+ On a page with over 1,000 elements and over 1,000
125
+ [CSSRules](https://developer.mozilla.org/en-US/docs/Web/API/CSSRule), (typical of a large web
126
+ application), the difference between a &lt; 1ms for warmed selector cache and &gt; 100ms for a fresh
127
+ selector cache. `createStyles` encourages a pattern similar to [BEM](https://getbem.com/) which
128
+ works well with the browser's selector cache by not injecting new `StyleSheet`s during a page's
129
+ normal operations. All styles are injected before any rendering takes place.
130
+
131
+ > **Note:** Since style props force Emotion's dynamic rendering, style props will fall back to
132
+ > Emotion's runtime performance characteristics and lose any benefits gained. Also if you use
133
+ > `styled` components or the `css` prop in a tree that uses `createStyles`, the styles created by
134
+ > the runtime APIs will still result in a selector cache invalidation. Even if you want to use
135
+ > `styled` or the `css` prop, consider using CSS Variables for dynamic CSS property values to reduce
136
+ > the performance overhead of Emotion.
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+
3
+ import {createStencil, cssVar, px2rem} from '@workday/canvas-kit-styling';
4
+ import {system} from '@workday/canvas-tokens-web';
5
+ import {Card} from '@workday/canvas-kit-react/card';
6
+
7
+ const myStencil = createStencil({
8
+ base: {
9
+ maxWidth: px2rem(400),
10
+ padding: system.space.zero,
11
+ overflow: 'hidden',
12
+ },
13
+ });
14
+
15
+ export default () => {
16
+ return (
17
+ <Card cs={myStencil()}>
18
+ <Card.Heading
19
+ cs={{
20
+ color: cssVar(system.color.text.inverse),
21
+ background: cssVar(system.color.bg.primary.default),
22
+ padding: cssVar(system.space.x3),
23
+ }}
24
+ >
25
+ The Future of Styling
26
+ </Card.Heading>
27
+ <Card.Body cs={{padding: cssVar(system.space.x3)}}>
28
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin egestas blandit consectetur.
29
+ Nam in congue mauris. Ut non metus a arcu rutrum accumsan. Duis luctus, diam vitae iaculis
30
+ semper, nibh nisl varius erat, vitae dapibus velit lacus blandit tellus. Aenean vestibulum
31
+ porta lectus non mollis. Quisque in lacus vitae sem vulputate rutrum. Sed dapibus aliquam
32
+ dui, eu aliquam purus egestas eu.
33
+ </Card.Body>
34
+ </Card>
35
+ );
36
+ };
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+
3
+ import {createStyles, createModifiers} from '@workday/canvas-kit-styling';
4
+
5
+ const myModifiers = createModifiers({
6
+ size: {
7
+ large: createStyles({
8
+ backgroundColor: 'lightgray',
9
+ width: 100,
10
+ height: 100,
11
+ }),
12
+ small: createStyles({
13
+ backgroundColor: 'lightgray',
14
+ width: 50,
15
+ height: 50,
16
+ }),
17
+ },
18
+ });
19
+
20
+ export default () => {
21
+ return (
22
+ <>
23
+ <div className={myModifiers({size: 'large'})}>Large</div>
24
+ <div className={myModifiers({size: 'small'})}>Small</div>
25
+ </>
26
+ );
27
+ };
@@ -0,0 +1,63 @@
1
+ import * as React from 'react';
2
+ import {createStencil} from '@workday/canvas-kit-styling';
3
+ import {Card} from '@workday/canvas-kit-react/card';
4
+ import {system} from '@workday/canvas-tokens-web';
5
+ import {Switch} from '@workday/canvas-kit-react/switch';
6
+ import {FormField} from '@workday/canvas-kit-react/form-field';
7
+
8
+ const themedCardStencil = createStencil({
9
+ vars: {
10
+ // Create CSS variables for the color of the header
11
+ headerColor: '',
12
+ },
13
+ parts: {
14
+ // Allows for styling a sub element of the component that may not be exposed through the API
15
+ header: 'themed-card-header',
16
+ body: 'themed-card-body',
17
+ },
18
+ base: ({headerPart, headerColor}) => ({
19
+ padding: system.space.x4,
20
+ boxShadow: system.depth[2],
21
+ backgroundColor: system.color.bg.default,
22
+ color: system.color.text.default,
23
+ // Targets the header part via [data-part="themed-card-header"]"]
24
+ [headerPart]: {
25
+ color: headerColor,
26
+ },
27
+ }),
28
+ modifiers: {
29
+ isDarkTheme: {
30
+ // If the prop `isDarkTheme` is true, style the component and it's parts
31
+ true: ({headerPart, bodyPart}) => ({
32
+ backgroundColor: system.color.bg.contrast.default,
33
+ color: system.color.text.inverse,
34
+ [`${headerPart}, ${bodyPart}`]: {
35
+ color: system.color.text.inverse,
36
+ },
37
+ }),
38
+ },
39
+ },
40
+ });
41
+
42
+ export default ({isDarkTheme, headerColor, elemProps}) => {
43
+ const [darkTheme, setIsDarkTheme] = React.useState(false);
44
+ const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
45
+ setIsDarkTheme(event.target.checked);
46
+ };
47
+ return (
48
+ <div>
49
+ <FormField>
50
+ <FormField.Label>Toggle Dark Theme</FormField.Label>
51
+ <FormField.Input as={Switch} onChange={handleChange} checked={darkTheme} />
52
+ </FormField>
53
+
54
+ <Card cs={themedCardStencil({isDarkTheme: darkTheme, headerColor})} {...elemProps}>
55
+ <Card.Heading {...themedCardStencil.parts.header}>Canvas Supreme</Card.Heading>
56
+ <Card.Body {...themedCardStencil.parts.body}>
57
+ Our house special supreme pizza includes pepperoni, sausage, bell peppers, mushrooms,
58
+ onions, and oregano.
59
+ </Card.Body>
60
+ </Card>
61
+ </div>
62
+ );
63
+ };
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+
3
+ import {createStyles} from '@workday/canvas-kit-styling';
4
+ import {system} from '@workday/canvas-tokens-web';
5
+
6
+ const styles = createStyles({
7
+ background: system.color.bg.primary.default,
8
+ color: system.color.text.inverse,
9
+ });
10
+
11
+ export default () => {
12
+ return <button className={styles}>Click Me</button>;
13
+ };
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+
3
+ import {createStyles, createVars, cssVar} from '@workday/canvas-kit-styling';
4
+
5
+ const myVars = createVars('background');
6
+
7
+ const styles = createStyles({
8
+ width: 100,
9
+ height: 100,
10
+ backgroundColor: cssVar(myVars.background),
11
+ });
12
+
13
+ export default () => {
14
+ return (
15
+ <>
16
+ <div className={styles} style={myVars({background: 'gray'})} />
17
+ <div className={styles} style={myVars({background: 'blue'})} />
18
+ </>
19
+ );
20
+ };
@@ -0,0 +1,69 @@
1
+ import React from 'react';
2
+
3
+ import {system} from '@workday/canvas-tokens-web';
4
+ import {plusIcon} from '@workday/canvas-system-icons-web';
5
+ import {createStencil, handleCsProp, px2rem} from '@workday/canvas-kit-styling';
6
+ import {createComponent} from '@workday/canvas-kit-react/common';
7
+ import {
8
+ BaseButton,
9
+ buttonStencil,
10
+ PrimaryButton,
11
+ PrimaryButtonProps,
12
+ } from '@workday/canvas-kit-react/button';
13
+ import {systemIconStencil} from '@workday/canvas-kit-react/icon';
14
+ import {Grid} from '@workday/canvas-kit-react/layout';
15
+
16
+ const myButtonStencil = createStencil({
17
+ extends: buttonStencil,
18
+ base: {
19
+ [buttonStencil.vars.background]: system.color.static.green.soft,
20
+ [buttonStencil.vars.label]: system.color.static.green.strong,
21
+ [systemIconStencil.vars.color]: system.color.static.green.strong,
22
+ [buttonStencil.vars.borderRadius]: system.shape.half,
23
+ border: `${px2rem(3)} solid transparent`,
24
+ width: 'fit-content',
25
+ '&:hover': {
26
+ [buttonStencil.vars.background]: system.color.static.green.default,
27
+ border: `${px2rem(3)} dotted ${system.color.static.green.strong}`,
28
+ [systemIconStencil.vars.color]: system.color.static.green.strong,
29
+ },
30
+ '&:active': {
31
+ [buttonStencil.vars.background]: system.color.static.green.strong,
32
+ [buttonStencil.vars.label]: system.color.fg.inverse,
33
+ [systemIconStencil.vars.color]: system.color.fg.inverse,
34
+ },
35
+ },
36
+ modifiers: {
37
+ size: {
38
+ small: {
39
+ padding: system.space.x4,
40
+ },
41
+ medium: {
42
+ padding: system.space.x6,
43
+ },
44
+ large: {
45
+ padding: system.space.x8,
46
+ },
47
+ },
48
+ },
49
+ });
50
+
51
+ const MyButton = createComponent('button')({
52
+ Component: ({children, size, ...elemProps}: PrimaryButtonProps, ref, Element) => (
53
+ <Element ref={ref} {...handleCsProp(elemProps, myButtonStencil({size}))}>
54
+ {children}
55
+ </Element>
56
+ ),
57
+ });
58
+
59
+ export default () => (
60
+ <Grid cs={{gap: px2rem(4), gridTemplateColumns: 'repeat(3, 1fr)', alignItems: 'center'}}>
61
+ <MyButton icon={plusIcon}>My Button</MyButton>
62
+ <MyButton size="medium" icon={plusIcon} iconPosition="end">
63
+ Medium My Button
64
+ </MyButton>
65
+ <MyButton size="large" icon={plusIcon}>
66
+ Large My Button
67
+ </MyButton>
68
+ </Grid>
69
+ );
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import {createStencil, handleCsProp} from '@workday/canvas-kit-styling';
3
+ import {systemIconStencil} from '@workday/canvas-kit-react/icon';
4
+ import {system} from '@workday/canvas-tokens-web';
5
+
6
+ const myIconStencil = createStencil({
7
+ extends: systemIconStencil,
8
+ base: {
9
+ [systemIconStencil.vars.color]: system.color.icon.primary.default,
10
+ [systemIconStencil.vars.accentColor]: system.color.icon.critical.default,
11
+ [systemIconStencil.vars.size]: system.space.x4,
12
+ },
13
+ });
14
+
15
+ export default elemProps => (
16
+ <span {...handleCsProp(elemProps, myIconStencil())}>
17
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 80 20">
18
+ <circle className="wd-icon-fill" cx="10" cy="10" r="10" />
19
+ <circle className="wd-icon-accent" cx="40" cy="10" r="10" />
20
+ <circle className="wd-icon-fill" cx="70" cy="10" r="10" />
21
+ </svg>
22
+ </span>
23
+ );
@@ -0,0 +1,111 @@
1
+ import React from 'react';
2
+ import styled from '@emotion/styled';
3
+
4
+ interface ButtonProps {
5
+ variant: 'primary' | 'secondary' | 'danger';
6
+ size: 'large' | 'medium' | 'small';
7
+ backgroundColor?: string;
8
+ children?: React.ReactNode;
9
+ }
10
+
11
+ const StyledButton = styled('button')<ButtonProps>(
12
+ {
13
+ // base styles
14
+ fontSize: '1rem',
15
+ display: 'flex',
16
+ borderRadius: '1rem',
17
+ },
18
+ // variant styles
19
+ ({variant, backgroundColor}) => {
20
+ switch (variant) {
21
+ case 'primary':
22
+ return {
23
+ background: backgroundColor || 'blue',
24
+ color: 'white',
25
+ };
26
+ case 'secondary':
27
+ return {
28
+ background: backgroundColor || 'gray',
29
+ };
30
+ case 'danger':
31
+ return {
32
+ background: backgroundColor || 'red',
33
+ };
34
+ default:
35
+ return {};
36
+ }
37
+ },
38
+ // size styles
39
+ ({size}) => {
40
+ switch (size) {
41
+ case 'large':
42
+ return {
43
+ fontSize: '1.4rem',
44
+ height: '2rem',
45
+ };
46
+ case 'medium':
47
+ return {
48
+ fontSize: '1rem',
49
+ height: '1.5rem',
50
+ };
51
+ case 'small':
52
+ return {
53
+ fontSize: '0.8rem',
54
+ height: '1.2rem',
55
+ };
56
+ default:
57
+ return {};
58
+ }
59
+ }
60
+ );
61
+
62
+ export default () => {
63
+ return (
64
+ <div style={{display: 'flex', flexDirection: 'column', gap: '1rem'}}>
65
+ <div style={{display: 'flex', gap: '1rem'}}>
66
+ <StyledButton variant="primary" size="large">
67
+ Primary Large
68
+ </StyledButton>
69
+ <StyledButton variant="primary" size="medium">
70
+ Primary Medium
71
+ </StyledButton>
72
+ <StyledButton variant="primary" size="small">
73
+ Primary Small
74
+ </StyledButton>
75
+ </div>
76
+ <div style={{display: 'flex', gap: '1rem'}}>
77
+ <StyledButton variant="secondary" size="large">
78
+ Secondary Large
79
+ </StyledButton>
80
+ <StyledButton variant="secondary" size="medium">
81
+ Secondary Medium
82
+ </StyledButton>
83
+ <StyledButton variant="secondary" size="small">
84
+ Secondary Small
85
+ </StyledButton>
86
+ </div>
87
+ <div style={{display: 'flex', gap: '1rem'}}>
88
+ <StyledButton variant="danger" size="large">
89
+ Danger Large
90
+ </StyledButton>
91
+ <StyledButton variant="danger" size="medium">
92
+ Danger Medium
93
+ </StyledButton>
94
+ <StyledButton variant="danger" size="small">
95
+ Danger Small
96
+ </StyledButton>
97
+ </div>
98
+ <div style={{display: 'flex', gap: '1rem'}}>
99
+ <StyledButton variant="danger" size="large" backgroundColor="orange">
100
+ Custom Large
101
+ </StyledButton>
102
+ <StyledButton variant="danger" size="medium" backgroundColor="orange">
103
+ Custom Medium
104
+ </StyledButton>
105
+ <StyledButton variant="danger" size="small" backgroundColor="orange">
106
+ Custom Small
107
+ </StyledButton>
108
+ </div>
109
+ </div>
110
+ );
111
+ };
@@ -0,0 +1,107 @@
1
+ import React from 'react';
2
+ import {createStyles} from '@workday/canvas-kit-styling';
3
+
4
+ interface ButtonProps {
5
+ variant: 'primary' | 'secondary' | 'danger';
6
+ size: 'large' | 'medium' | 'small';
7
+ backgroundColor?: string;
8
+ children?: React.ReactNode;
9
+ }
10
+
11
+ const baseStyles = createStyles({
12
+ fontSize: '1rem',
13
+ display: 'flex',
14
+ borderRadius: '1rem',
15
+ });
16
+
17
+ const modifierStyles = {
18
+ variant: {
19
+ primary: createStyles({
20
+ background: `var(--button-background-color, blue)`,
21
+ color: 'white',
22
+ }),
23
+ secondary: createStyles({
24
+ background: `var(--button-background-color, gray)`,
25
+ }),
26
+ danger: createStyles({
27
+ background: `var(--button-background-color, red)`,
28
+ }),
29
+ },
30
+ size: {
31
+ large: createStyles({
32
+ fontSize: '1.4rem',
33
+ height: '2rem',
34
+ }),
35
+ medium: createStyles({
36
+ fontSize: '1rem',
37
+ height: '1.5rem',
38
+ }),
39
+ small: createStyles({
40
+ fontSize: '0.8rem',
41
+ height: '1.2rem',
42
+ }),
43
+ },
44
+ };
45
+
46
+ const Button = ({variant, size, backgroundColor, children}: ButtonProps) => {
47
+ const className = [baseStyles, modifierStyles.variant[variant], modifierStyles.size[size]].join(
48
+ ' '
49
+ );
50
+ const style = {'--button-background-color': backgroundColor} as React.CSSProperties;
51
+ return (
52
+ <button className={className} style={style}>
53
+ {children}
54
+ </button>
55
+ );
56
+ };
57
+
58
+ export default () => {
59
+ return (
60
+ <div style={{display: 'flex', flexDirection: 'column', gap: '1rem'}}>
61
+ <div style={{display: 'flex', gap: '1rem'}}>
62
+ <Button variant="primary" size="large">
63
+ Primary Large
64
+ </Button>
65
+ <Button variant="primary" size="medium">
66
+ Primary Medium
67
+ </Button>
68
+ <Button variant="primary" size="small">
69
+ Primary Small
70
+ </Button>
71
+ </div>
72
+ <div style={{display: 'flex', gap: '1rem'}}>
73
+ <Button variant="secondary" size="large">
74
+ Secondary Large
75
+ </Button>
76
+ <Button variant="secondary" size="medium">
77
+ Secondary Medium
78
+ </Button>
79
+ <Button variant="secondary" size="small">
80
+ Secondary Small
81
+ </Button>
82
+ </div>
83
+ <div style={{display: 'flex', gap: '1rem'}}>
84
+ <Button variant="danger" size="large">
85
+ Danger Large
86
+ </Button>
87
+ <Button variant="danger" size="medium">
88
+ Danger Medium
89
+ </Button>
90
+ <Button variant="danger" size="small">
91
+ Danger Small
92
+ </Button>
93
+ </div>
94
+ <div style={{display: 'flex', gap: '1rem'}}>
95
+ <Button variant="danger" size="large" backgroundColor="orange">
96
+ Custom Large
97
+ </Button>
98
+ <Button variant="danger" size="medium" backgroundColor="orange">
99
+ Custom Medium
100
+ </Button>
101
+ <Button variant="danger" size="small" backgroundColor="orange">
102
+ Custom Small
103
+ </Button>
104
+ </div>
105
+ </div>
106
+ );
107
+ };
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+
3
+ import {system} from '@workday/canvas-tokens-web';
4
+ import {caretDownIcon} from '@workday/canvas-system-icons-web';
5
+ import {createStyles} from '@workday/canvas-kit-styling';
6
+ import {buttonStencil, PrimaryButton} from '@workday/canvas-kit-react/button';
7
+ import {systemIconStencil} from '@workday/canvas-kit-react/icon';
8
+
9
+ const varStyles = createStyles({
10
+ [buttonStencil.vars.background]: system.color.static.gray.soft,
11
+ [buttonStencil.vars.label]: system.color.static.blue.strong,
12
+ // Because PrimaryButton uses SystemIcon under the hood,
13
+ // we also can change system icon variable for color
14
+ [systemIconStencil.vars.color]: system.color.static.blue.strong,
15
+ '&:hover': {
16
+ [buttonStencil.vars.background]: system.color.static.amber.default,
17
+ [buttonStencil.vars.label]: system.color.static.white,
18
+ [systemIconStencil.vars.color]: system.color.static.white,
19
+ },
20
+ '&:focus-visible': {
21
+ [buttonStencil.vars.background]: system.color.static.green.default,
22
+ [buttonStencil.vars.boxShadowOuter]: system.color.static.green.strong,
23
+ [buttonStencil.vars.boxShadowInner]: system.color.static.white,
24
+ },
25
+ });
26
+
27
+ export default () => (
28
+ <PrimaryButton cs={varStyles} icon={caretDownIcon} iconPosition="end">
29
+ Overwrite styles by setting variables
30
+ </PrimaryButton>
31
+ );