@workday/canvas-kit-docs 14.0.0-alpha.1149-next.0 → 14.0.0-alpha.1151-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.
- package/dist/es6/lib/stackblitzFiles/packageJSONFile.js +5 -5
- package/dist/es6/lib/stackblitzFiles/packageJSONFile.ts +5 -5
- package/dist/mdx/styling/mdx/CreateStyles.mdx +111 -0
- package/dist/mdx/styling/mdx/CustomizingStyles.mdx +179 -0
- package/dist/mdx/styling/mdx/FromEmotion.mdx +178 -0
- package/dist/mdx/styling/mdx/MergingStyles.mdx +164 -0
- package/dist/mdx/styling/mdx/Overview.mdx +254 -0
- package/dist/mdx/styling/mdx/Stencils.mdx +459 -0
- package/dist/mdx/styling/mdx/Utilities.mdx +246 -0
- package/dist/mdx/styling/mdx/WhyCanvasStyling.mdx +136 -0
- package/dist/mdx/styling/mdx/examples/CSProp.tsx +36 -0
- package/dist/mdx/styling/mdx/examples/CreateModifiers.tsx +27 -0
- package/dist/mdx/styling/mdx/examples/CreateStencil.tsx +63 -0
- package/dist/mdx/styling/mdx/examples/CreateStyles.tsx +13 -0
- package/dist/mdx/styling/mdx/examples/CreateVars.tsx +20 -0
- package/dist/mdx/styling/mdx/examples/CustomButton.tsx +69 -0
- package/dist/mdx/styling/mdx/examples/CustomIcon.tsx +23 -0
- package/dist/mdx/styling/mdx/examples/EmotionButton.tsx +111 -0
- package/dist/mdx/styling/mdx/examples/ManualStylesButton.tsx +107 -0
- package/dist/mdx/styling/mdx/examples/StyledButton.tsx +31 -0
- package/dist/mdx/styling/mdx/examples/StylingButton.tsx +107 -0
- package/dist/mdx/styling/mdx/examples/StylingOverrides.tsx +158 -0
- package/package.json +6 -6
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import {ExampleCodeBlock, SymbolDoc} from '@workday/canvas-kit-docs';
|
|
2
|
+
import CreateStyles from './examples/CreateStyles';
|
|
3
|
+
import CreateVars from './examples/CreateVars';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# Canvas Kit Styling Utilities
|
|
7
|
+
|
|
8
|
+
A collection of helpful functions for styling with `@workday/canvas-kit-styling`. While they're
|
|
9
|
+
fairly simple, they make styling much nicer.
|
|
10
|
+
|
|
11
|
+
## Pixels to Rem
|
|
12
|
+
|
|
13
|
+
This function converts a `px` value (number) to `rem` (string). This keeps you from having to do any
|
|
14
|
+
tricky mental division or write irrational numbers.
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import {px2rem} from '@workday/canvas-kit-styling';
|
|
18
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
19
|
+
|
|
20
|
+
const styles = {
|
|
21
|
+
// returns '0.0625rem'
|
|
22
|
+
margin: px2rem(1),
|
|
23
|
+
};
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Calc Functions
|
|
27
|
+
|
|
28
|
+
Calc functions are useful for doing basic math operations with CSS `calc()` and variables. They will
|
|
29
|
+
also wrap variables automatically in `var()`.
|
|
30
|
+
|
|
31
|
+
### Add
|
|
32
|
+
|
|
33
|
+
This function returns a CSS `calc()` addition string.
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import {calc} from '@workday/canvas-kit-styling';
|
|
37
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
38
|
+
|
|
39
|
+
const styles = {
|
|
40
|
+
// returns 'calc(var(--cnvs-sys-space-x1) + 0.125rem)'
|
|
41
|
+
padding: calc.add(system.space.x1, '0.125rem'),
|
|
42
|
+
};
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Subtract
|
|
46
|
+
|
|
47
|
+
This function returns a CSS `calc()` subtraction string.
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import {calc} from '@workday/canvas-kit-styling';
|
|
51
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
52
|
+
|
|
53
|
+
const styles = {
|
|
54
|
+
// returns 'calc(var(--cnvs-sys-space-x1) - 0.125rem)'
|
|
55
|
+
padding: calc.subtract(system.space.x1, '0.125rem'),
|
|
56
|
+
};
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Multiply
|
|
60
|
+
|
|
61
|
+
This function returns a CSS `calc()` multiplication string.
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import {calc} from '@workday/canvas-kit-styling';
|
|
65
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
66
|
+
|
|
67
|
+
const styles = {
|
|
68
|
+
// returns 'calc(var(--cnvs-sys-space-x1) * 3)'
|
|
69
|
+
padding: calc.multiply(system.space.x1, 3),
|
|
70
|
+
};
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Divide
|
|
74
|
+
|
|
75
|
+
This function returns a CSS `calc()` division string
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import {calc} from '@workday/canvas-kit-styling';
|
|
79
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
80
|
+
|
|
81
|
+
const styles = {
|
|
82
|
+
// returns 'calc(var(--cnvs-sys-space-x1) / 2)'
|
|
83
|
+
padding: calc.divide(system.space.x1, 2),
|
|
84
|
+
};
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Negate
|
|
88
|
+
|
|
89
|
+
This function negates a CSS variable to give you the opposite value. This keeps you from having to
|
|
90
|
+
wrap the variable in `calc()` and multiplying by `-1`.
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import {calc} from '@workday/canvas-kit-styling';
|
|
94
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
95
|
+
|
|
96
|
+
const styles = {
|
|
97
|
+
// returns 'calc(var(--cnvs-sys-space-x4) * -1)'
|
|
98
|
+
margin: calc.negate(system.space.x4),
|
|
99
|
+
};
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## keyframes
|
|
103
|
+
|
|
104
|
+
The `keyframes` function re-exports the [Emotion CSS keyframes](https://emotion.sh/docs/keyframes)
|
|
105
|
+
function, but is compatible with a custom Emotion instance and is understood by the Static style
|
|
106
|
+
transformer.
|
|
107
|
+
|
|
108
|
+
### Usage Example
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
112
|
+
import {createComponent} from '@workday/canvas-kit-react/common';
|
|
113
|
+
import {
|
|
114
|
+
handleCsProp,
|
|
115
|
+
keyframes,
|
|
116
|
+
createStencil,
|
|
117
|
+
calc,
|
|
118
|
+
px2rem,
|
|
119
|
+
CSProps,
|
|
120
|
+
} from '@workday/canvas-kit-styling';
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Keyframe for the dots loading animation.
|
|
124
|
+
*/
|
|
125
|
+
const keyframesLoading = keyframes({
|
|
126
|
+
'0%, 80%, 100%': {
|
|
127
|
+
transform: 'scale(0)',
|
|
128
|
+
},
|
|
129
|
+
'40%': {
|
|
130
|
+
transform: 'scale(1)',
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
export const loadingStencil = createStencil({
|
|
135
|
+
base: {
|
|
136
|
+
display: 'inline-flex',
|
|
137
|
+
gap: system.space.x2,
|
|
138
|
+
width: system.space.x4,
|
|
139
|
+
height: system.space.x4,
|
|
140
|
+
fontSize: system.space.zero,
|
|
141
|
+
borderRadius: system.shape.round,
|
|
142
|
+
backgroundColor: system.color.bg.muted.softer,
|
|
143
|
+
outline: `${px2rem(2)} solid transparent`,
|
|
144
|
+
transform: 'scale(0)',
|
|
145
|
+
animationName: keyframesLoading,
|
|
146
|
+
animationDuration: calc.multiply('150ms', 35),
|
|
147
|
+
animationIterationCount: 'infinite',
|
|
148
|
+
animationTimingFunction: 'ease-in-out',
|
|
149
|
+
animationFillMode: 'both',
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* A simple component that displays three horizontal dots, to be used when some data is loading.
|
|
155
|
+
*/
|
|
156
|
+
export const LoadingDot = createComponent('div')({
|
|
157
|
+
displayName: 'LoadingDots',
|
|
158
|
+
Component: ({...elemProps}: CSProps, ref, Element) => {
|
|
159
|
+
return <Element ref={ref} {...handleCsProp(elemProps, loadingStencil())}></Element>;
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## injectGlobal
|
|
165
|
+
|
|
166
|
+
The `injectGlobal` function re-exports the
|
|
167
|
+
[Emotion CSS injectGlobal](https://emotion.sh/docs/@emotion/css#global-styles) function, but is
|
|
168
|
+
compatible with a custom Emotion instance and is understood by the Static style transformer.
|
|
169
|
+
|
|
170
|
+
### Usage Example
|
|
171
|
+
|
|
172
|
+
```tsx
|
|
173
|
+
import {createRoot} from 'react-dom/client';
|
|
174
|
+
import {fonts} from '@workday/canvas-kit-react-fonts';
|
|
175
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
176
|
+
import {cssVar, injectGlobal} from '@workday/canvas-kit-styling';
|
|
177
|
+
import {App} from './App';
|
|
178
|
+
|
|
179
|
+
import '@workday/canvas-tokens-web/css/base/_variables.css';
|
|
180
|
+
import '@workday/canvas-tokens-web/css/brand/_variables.css';
|
|
181
|
+
import '@workday/canvas-tokens-web/css/system/_variables.css';
|
|
182
|
+
|
|
183
|
+
//@ts-ignore
|
|
184
|
+
injectGlobal({
|
|
185
|
+
...fonts,
|
|
186
|
+
'html, body': {
|
|
187
|
+
fontFamily: cssVar(system.fontFamily.default),
|
|
188
|
+
margin: 0,
|
|
189
|
+
minHeight: '100vh',
|
|
190
|
+
},
|
|
191
|
+
'#root, #root < div': {
|
|
192
|
+
minHeight: '100vh',
|
|
193
|
+
...system.type.body.small,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const container = document.getElementById('root')!;
|
|
198
|
+
const root = createRoot(container);
|
|
199
|
+
root.render(<App />);
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Custom Emotion Instance
|
|
203
|
+
|
|
204
|
+
Static style injection happens during the parsing stages of the files. This means when you `import`
|
|
205
|
+
a component that uses static styling, the styles are injected immediately. This happens way before
|
|
206
|
+
rendering, so using the Emotion [CacheProvider](https://emotion.sh/docs/cache-provider) does not
|
|
207
|
+
work. A custom instance must be created _before_ any style utilities are called - during the
|
|
208
|
+
bootstrapping phase of an application. We don't have a working example because it requires an
|
|
209
|
+
isolated application, but here's an example adding a `nonce` to an application:
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
// bootstrap-styles.ts
|
|
213
|
+
import {createInstance} from '@workday/canvas-kit-styling';
|
|
214
|
+
|
|
215
|
+
// assuming this file is being called via a `script` tag and that
|
|
216
|
+
// script tag has a `nonce` attribute set from the server
|
|
217
|
+
createInstance({nonce: document.currentScript.nonce});
|
|
218
|
+
|
|
219
|
+
// index.ts
|
|
220
|
+
import React from 'react';
|
|
221
|
+
import ReactDOM from 'react-dom';
|
|
222
|
+
|
|
223
|
+
// call the bootstrap in the import list. This has the side-effect
|
|
224
|
+
// of creating an instance
|
|
225
|
+
import './bootstrap-styles';
|
|
226
|
+
|
|
227
|
+
import App from './App';
|
|
228
|
+
|
|
229
|
+
const root = ReactDOM.createRoot(document.querySelector('#root'));
|
|
230
|
+
|
|
231
|
+
root.render(<App />);
|
|
232
|
+
|
|
233
|
+
// App.tsx
|
|
234
|
+
import React from 'react';
|
|
235
|
+
|
|
236
|
+
// The following will create and inject styles. We cannot adjust
|
|
237
|
+
// the Emotion instance after this import
|
|
238
|
+
import {PrimaryButton} from '@workday/canvas-kit-react/button';
|
|
239
|
+
|
|
240
|
+
// if we call `createInstance` here, we'll get a warning in
|
|
241
|
+
// development mode
|
|
242
|
+
|
|
243
|
+
export default () => {
|
|
244
|
+
return <PrimaryButton>Button</PrimaryButton>;
|
|
245
|
+
};
|
|
246
|
+
```
|
|
@@ -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 < 1ms for warmed selector cache and > 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
|
+
);
|