@workday/canvas-kit-docs 7.0.0-alpha.94-next.20 → 7.0.0-alpha.97-next.23
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/mdx/7.0-MIGRATION-GUIDE.mdx +682 -564
- package/dist/mdx/preview-react/_examples/examples/SelectWithFormik.tsx +1 -1
- package/dist/mdx/preview-react/menu/examples/ContextMenu.tsx +2 -2
- package/dist/mdx/preview-react/pill/Pill.mdx +241 -0
- package/dist/mdx/preview-react/pill/examples/Basic.tsx +18 -0
- package/dist/mdx/preview-react/pill/examples/WithAvatar.tsx +21 -0
- package/dist/mdx/preview-react/pill/examples/WithCount.tsx +9 -0
- package/dist/mdx/preview-react/pill/examples/WithList.tsx +31 -0
- package/dist/mdx/preview-react/pill/examples/WithReadOnly.tsx +15 -0
- package/dist/mdx/preview-react/pill/examples/WithRemovable.tsx +25 -0
- package/dist/mdx/preview-react/pill/examples/test-avatar.png +0 -0
- package/dist/mdx/react/_examples/examples/CookieBanner.tsx +1 -1
- package/package.json +3 -3
|
@@ -1,32 +1,34 @@
|
|
|
1
1
|
# Canvas Kit 7.0 Migration Guide
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This guide contains breaking changes in Canvas Kit v7. Please
|
|
4
4
|
[reach out](https://github.com/Workday/canvas-kit/issues/new?labels=bug&template=bug.md) if you have
|
|
5
|
-
any questions
|
|
5
|
+
any questions.
|
|
6
6
|
|
|
7
7
|
- [Codemod](#codemod)
|
|
8
|
-
- [
|
|
9
|
-
- [
|
|
10
|
-
- [
|
|
11
|
-
- [
|
|
12
|
-
- [
|
|
13
|
-
- [
|
|
14
|
-
- [
|
|
15
|
-
- [
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
19
|
-
- [
|
|
20
|
-
- [
|
|
21
|
-
- [
|
|
22
|
-
- [
|
|
23
|
-
- [
|
|
8
|
+
- [General Changes](#general-changes)
|
|
9
|
+
- [Dependency Upgrades](#dependency-upgrades)
|
|
10
|
+
- [Model Changes](#model-changes)
|
|
11
|
+
- [Tokens](#tokens)
|
|
12
|
+
- [Depth](#depth)
|
|
13
|
+
- [Components](#components)
|
|
14
|
+
- [Component Deprecations](#component-deprecations)
|
|
15
|
+
- [Component Promotions](#component-promotions)
|
|
16
|
+
- [Action Bar](#action-bar)
|
|
17
|
+
- [Banner](#banner)
|
|
18
|
+
- [Button](#button)
|
|
19
|
+
- [Icon](#icon)
|
|
20
|
+
- [Popper](#popper)
|
|
21
|
+
- [Popup](#popup)
|
|
22
|
+
- [Segmented Control](#segmented-control)
|
|
23
|
+
- [Side Panel](#side-panel)
|
|
24
|
+
- [Status Indicator](#status-indicator)
|
|
25
|
+
- [Tabs](#tabs)
|
|
24
26
|
|
|
25
27
|
## Codemod
|
|
26
28
|
|
|
27
29
|
Please use our [codemod package](https://github.com/Workday/canvas-kit/tree/master/modules/codemod)
|
|
28
|
-
to automatically update your code to work with
|
|
29
|
-
|
|
30
|
+
to automatically update your code to work with many of the breaking changes as you migrate from
|
|
31
|
+
Canvas Kit v6 to v7:
|
|
30
32
|
|
|
31
33
|
```sh
|
|
32
34
|
> npx @workday/canvas-kit-codemod v7 [path]
|
|
@@ -35,257 +37,584 @@ from Canvas Kit v6 to v7:
|
|
|
35
37
|
> Note: This codemod only works on `.js`, `.jsx`, `.ts`, and `.tsx` extensions. You may need to make
|
|
36
38
|
> some manual changes in other file types (`.json`, `.mdx`, `.md`, etc.).
|
|
37
39
|
|
|
38
|
-
> Note: You may need to run your linter after executing the codemod, as
|
|
40
|
+
> Note: You may need to run your linter after executing the codemod, as its resulting formatting
|
|
39
41
|
> (spacing, quotes, etc.) may not match your project's styling.
|
|
40
42
|
|
|
41
|
-
**Breaking changes
|
|
43
|
+
**Breaking changes handled by this codemod will be marked with a 🤖.**
|
|
42
44
|
|
|
43
45
|
**Please verify all changes made by the codemod. As a safety precaution, we recommend committing the
|
|
44
46
|
changes from the codemod as a single isolated commit (separate from other changes) so you can
|
|
45
47
|
rollback more easily if necessary.**
|
|
46
48
|
|
|
47
49
|
[Let us know](https://github.com/Workday/canvas-kit/issues/new?labels=bug&template=bug.md) if you
|
|
48
|
-
encounter any issues or use cases that we've missed.
|
|
49
|
-
help us maintain additional codemod transforms to make future migrations easier.
|
|
50
|
+
encounter any issues or use cases that we've missed.
|
|
50
51
|
|
|
51
|
-
##
|
|
52
|
+
## General Changes
|
|
52
53
|
|
|
53
|
-
|
|
54
|
+
### Dependency Upgrades
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
We've upgraded to Emotion 11 and React 17 in v7. This allows teams to upgrade to newer versions of
|
|
57
|
+
Emotion and React without needing to maintain older versions in order to use Canvas Kit.
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
upgrading your Typescript version. In our experience, Typescript 4.1 found a few more errors that
|
|
62
|
-
Typescript 3.8 did not, but the upgrade was manageable.
|
|
59
|
+
As part of this upgrade, we've removed use of the `/** @jsx jsx */` pragma and `css` prop within
|
|
60
|
+
Canvas Kit. See our [React 17 discussion](https://github.com/Workday/canvas-kit/discussions/1455)
|
|
61
|
+
and [corresponding PR](https://github.com/Workday/canvas-kit/pull/1409) for more information on why
|
|
62
|
+
we made this change. Consumers may continue to use the `css` prop.
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
To use v7, you'll need to upgrade the following dependencies:
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
- React 16.14 OR React 17.X for backwards compatibility on JSX transform if you're using Babel or
|
|
67
|
+
TypeScript to compile code
|
|
68
|
+
- Emotion 11
|
|
69
|
+
- TypeScript 4.1 or higher, if applicable
|
|
70
|
+
- Babel 7.9 or higher, if applicable
|
|
71
|
+
- An Enzyme adapter for React 17, if applicable
|
|
67
72
|
|
|
68
|
-
|
|
73
|
+
> We no longer support TypeScript 3.5-3.9. Previously, we used `downlevel-dts` to support TypeScript
|
|
74
|
+
> 3.5+ while using TypeScript 3.8 features, but `downlevel-dts` does not support features we use in
|
|
75
|
+
> TypeScript 4.1. TypeScript 4.1 was released in November 2020, and we feel it is time to move
|
|
76
|
+
> forward. Reach out if you experience issues upgrading your TypeScript version. In our experience,
|
|
77
|
+
> TypeScript 4.1 found a few more errors than TypeScript 3.8, but the upgrade was manageable.
|
|
69
78
|
|
|
70
|
-
|
|
79
|
+
Please note that you may also need to update any side effect dependencies or linting packages with
|
|
80
|
+
this update.
|
|
71
81
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
82
|
+
View our [React 17](https://github.com/Workday/canvas-kit/discussions/1455) and
|
|
83
|
+
[Emotion 11](https://github.com/Workday/canvas-kit/discussions/1453) discussions to learn more about
|
|
84
|
+
any gotchas or tips and tricks with these upgrades. And of course, feel free to contribute to the
|
|
85
|
+
discussion with any questions or learnings of your own!
|
|
75
86
|
|
|
76
|
-
|
|
77
|
-
warning.
|
|
87
|
+
---
|
|
78
88
|
|
|
79
|
-
|
|
89
|
+
### Model Changes
|
|
80
90
|
|
|
81
|
-
|
|
82
|
-
prescribed in our migration guide to update your application. Please reach out to our team directly
|
|
83
|
-
if you need additional help.
|
|
91
|
+
#### Guards and Callbacks
|
|
84
92
|
|
|
85
|
-
|
|
93
|
+
We've changed the signature of model event guards and callbacks. In v6, the parameters were in an
|
|
94
|
+
object. This was a less than ideal developer experience as IntelliSense isn't engaged immediately
|
|
95
|
+
and we don't plan on adding any additional parameters to guard and callback functions. We've removed
|
|
96
|
+
the object wrapper.
|
|
86
97
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
98
|
+
```tsx
|
|
99
|
+
// v6
|
|
100
|
+
const model = useTabsModel({
|
|
101
|
+
onSelect({data: {id}, prevState}) {
|
|
102
|
+
console.log(id, prevState);
|
|
103
|
+
},
|
|
104
|
+
});
|
|
90
105
|
|
|
91
|
-
|
|
106
|
+
// v7
|
|
107
|
+
const model = useTabsModel({
|
|
108
|
+
onSelect({id}, prevState) {
|
|
109
|
+
console.log(id, prevState);
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
```
|
|
92
113
|
|
|
93
|
-
|
|
94
|
-
this deprecated component now, you can reference
|
|
95
|
-
[this example](https://workday.github.io/canvas-kit/?path=/story/examples-pageheader-react--basic)
|
|
114
|
+
🤖 The codemod will handle this change for you automatically.
|
|
96
115
|
|
|
97
|
-
|
|
116
|
+
#### Model Implementation
|
|
98
117
|
|
|
99
|
-
|
|
100
|
-
deprecated component now, you can reference
|
|
101
|
-
[this example](https://workday.github.io/canvas-kit/?path=/story/examples-globalheader-react--basic)
|
|
118
|
+
If you don't extend models, you can skip this section.
|
|
102
119
|
|
|
103
|
-
|
|
120
|
+
In v6 we supported TypeScript 3.8 which limited the way types could be inferred and defined. v7
|
|
121
|
+
requires TypeScript 4.1 which introduced
|
|
122
|
+
[Template Literal Types](https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html).
|
|
123
|
+
This means guards and callbacks no longer need to be manually defined via an `eventMap`. Event maps
|
|
124
|
+
were a stopgap, manual, and prone to errors in defining them. Not all events have guards or
|
|
125
|
+
callbacks, and there's no way other than manual review to verify their existence. Template Literal
|
|
126
|
+
Types allow us to properly type guards and callbacks without event maps. The previous types forced
|
|
127
|
+
`data` to be an object. We've since dropped that restriction. You can still only pass a single
|
|
128
|
+
argument to events. If you need additional information, use an object.
|
|
104
129
|
|
|
105
|
-
|
|
130
|
+
This change also allowed us to remove a lot of boilerplate associated with models without
|
|
131
|
+
sacrificing type safety. This change doesn't affect most use cases, but will affect those who
|
|
132
|
+
extended a model. We created a new `createModelHook` utility function to help set up types.
|
|
106
133
|
|
|
107
|
-
|
|
134
|
+
##### v6
|
|
108
135
|
|
|
109
|
-
|
|
136
|
+
```ts
|
|
137
|
+
export type MyState = {
|
|
138
|
+
value: string;
|
|
139
|
+
};
|
|
110
140
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
- Fixed position has been set as default if there is not passed `position` prop.
|
|
141
|
+
export type MyEvents = {
|
|
142
|
+
updateValue(data: {value: string}): void; // enforced that `data` is an object even if we only need to pass a string
|
|
143
|
+
};
|
|
115
144
|
|
|
116
|
-
|
|
145
|
+
export type MyModel = Model<MyState, MyEvents>;
|
|
117
146
|
|
|
118
|
-
|
|
119
|
-
|
|
147
|
+
export const myEventMap = createEventMap<MyEvents>()({
|
|
148
|
+
guards: {
|
|
149
|
+
shouldUpdateValue: 'updateValue', // easy to forget or make a mistake on guard name
|
|
150
|
+
},
|
|
151
|
+
callbacks: {
|
|
152
|
+
onUpdateValue: 'updateValue',
|
|
153
|
+
},
|
|
154
|
+
});
|
|
120
155
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
156
|
+
export type MyBaseConfig = {
|
|
157
|
+
initialValue?: string;
|
|
158
|
+
};
|
|
124
159
|
|
|
125
|
-
|
|
126
|
-
|
|
160
|
+
export type MyConfig = MyBaseConfig & Partial<ToModelConfig<MyState, MyEvents, typeof myEventMap>>;
|
|
161
|
+
|
|
162
|
+
const useMyModel = (config: MyConfig = {}): MyModel => {
|
|
163
|
+
const [value, setValue] = React.useState(config.initialValue || '');
|
|
164
|
+
|
|
165
|
+
const state = {value};
|
|
166
|
+
|
|
167
|
+
// useEventMap is used to wrap the event object with guards and callbacks according to the event map
|
|
168
|
+
const events = useEventMap(myEventMap, state, config, {
|
|
169
|
+
updateValue(data) {
|
|
170
|
+
setValue(data.value);
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
return {state, events};
|
|
175
|
+
};
|
|
127
176
|
```
|
|
128
177
|
|
|
129
|
-
|
|
178
|
+
##### v7
|
|
130
179
|
|
|
131
|
-
|
|
132
|
-
|
|
180
|
+
```tsx
|
|
181
|
+
const useMyModel = createModelHook({
|
|
182
|
+
defaultConfig: {
|
|
183
|
+
initialValue: '',
|
|
184
|
+
},
|
|
185
|
+
})(config => {
|
|
186
|
+
const [value, setValue] = React.useState(config.initialValue); // default is already handled
|
|
133
187
|
|
|
134
|
-
|
|
188
|
+
const state = {value};
|
|
135
189
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
190
|
+
const events = {
|
|
191
|
+
updateValue(value: string) {
|
|
192
|
+
// doesn't need to be an object anymore
|
|
193
|
+
setValue(value);
|
|
194
|
+
},
|
|
195
|
+
};
|
|
139
196
|
|
|
140
|
-
|
|
197
|
+
return {state, events};
|
|
198
|
+
});
|
|
199
|
+
```
|
|
141
200
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
`<SecondaryButton variant='inverseFilled' icon={plusIcon} />`
|
|
201
|
+
Note the large reduction in TypeScript type boilerplate. In this example, the only place that
|
|
202
|
+
TypeScript syntax exists is in the `updateValue` function definition. This allows better collocating
|
|
203
|
+
of types and values. Also note that `useEventMap` is no longer needed. `createModelHook` will
|
|
204
|
+
automatically wrap the `events` returned to call guards and callbacks when appropriate. Today, this
|
|
205
|
+
is done by creating a new events object. Once we drop IE11 support, this will be done via a proxy
|
|
206
|
+
instead. `createModelHook` handles all type inference so you don't need to explicitly type
|
|
207
|
+
everything. `createModelHook` also attaches React Context directly to the hook along with
|
|
208
|
+
`defaultConfig` and `requiredConfig` for model extension.
|
|
151
209
|
|
|
152
|
-
|
|
210
|
+
If you extended a model, you'll notice all those types are no longer being exported. You'll have to
|
|
211
|
+
use this new utility function. Here's an example we found in the wild:
|
|
153
212
|
|
|
154
|
-
|
|
213
|
+
##### v6
|
|
155
214
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
215
|
+
```tsx
|
|
216
|
+
import {
|
|
217
|
+
BasePopupModelConfig,
|
|
218
|
+
createEventMap,
|
|
219
|
+
Model,
|
|
220
|
+
popupEventMap,
|
|
221
|
+
PopupEvents,
|
|
222
|
+
PopupModelConfig,
|
|
223
|
+
PopupState,
|
|
224
|
+
ToModelConfig,
|
|
225
|
+
useCloseOnEscape,
|
|
226
|
+
useEventMap,
|
|
227
|
+
useFocusTrap,
|
|
228
|
+
useInitialFocus,
|
|
229
|
+
usePopupModel,
|
|
230
|
+
useReturnFocus,
|
|
231
|
+
} from '@workday/canvas-kit-react';
|
|
160
232
|
|
|
161
|
-
|
|
233
|
+
type MyModalState = PopupState & {
|
|
234
|
+
showOverlay: boolean;
|
|
235
|
+
};
|
|
162
236
|
|
|
163
|
-
|
|
164
|
-
below is a description of how to manually migrate from unsupported V6 variants. | IconButton variant
|
|
165
|
-
| Button Type | | ------------------ | ------------------------------------ | | `circle` |
|
|
166
|
-
TertiaryButton | | `circleFilled` | SecondaryButton | | `inverse` | TertiButton with variant inverse
|
|
167
|
-
| | `inverseFilled` | SecondaryButton with variant inverse | | `plain` | Not Supporting | | `square`
|
|
168
|
-
| Not Supporting | | `squareFilled` | Not Supporting |
|
|
237
|
+
type MyModalEvents = PopupEvents;
|
|
169
238
|
|
|
170
|
-
|
|
239
|
+
const myModalEventMap = createEventMap<MyModalEvents>()({
|
|
240
|
+
guards: {
|
|
241
|
+
...popupEventMap.guards,
|
|
242
|
+
},
|
|
243
|
+
callbacks: {
|
|
244
|
+
...popupEventMap.callbacks,
|
|
245
|
+
},
|
|
246
|
+
});
|
|
171
247
|
|
|
172
|
-
|
|
173
|
-
|
|
248
|
+
type MyBaseModalConfig = BasePopupModelConfig & {
|
|
249
|
+
showOverlay?: boolean;
|
|
250
|
+
};
|
|
174
251
|
|
|
175
|
-
|
|
176
|
-
Secondary, and Tertiary button variants, the Toolbar Icon Button, or the Segmented Control component
|
|
252
|
+
type MyModalModel = Model<MyModalState, MyModalEvents>;
|
|
177
253
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
which also has the `toggled`prop.
|
|
254
|
+
type MyConfig = MyBaseConfig &
|
|
255
|
+
Partial<ToModelConfig<MyModalState, MyModalEvents, typeof myModalEventMap>>;
|
|
181
256
|
|
|
182
|
-
|
|
183
|
-
[
|
|
184
|
-
props, and size of the button. For an example of this being used, you can reference our
|
|
185
|
-
[PageButton component](https://github.com/Workday/canvas-kit/blob/master/modules/react/pagination/lib/Pagination/PageButton.tsx).
|
|
257
|
+
export const useMyModalModel = (config: MyConfig = {}): MyModalModel => {
|
|
258
|
+
const [showOverlay] = React.useState(config.showOverlay ?? true);
|
|
186
259
|
|
|
187
|
-
|
|
260
|
+
const model = usePopupModel({
|
|
261
|
+
...config,
|
|
262
|
+
// hook up to a redux store
|
|
263
|
+
onShow(...params) {
|
|
264
|
+
dispatch(setIsModalOpen(true));
|
|
265
|
+
config?.onShow?.(...params);
|
|
266
|
+
},
|
|
267
|
+
onHide(...params) {
|
|
268
|
+
dispatch(setIsModalOpen(false));
|
|
269
|
+
config?.onShow?.(...params);
|
|
270
|
+
},
|
|
271
|
+
});
|
|
188
272
|
|
|
189
|
-
|
|
273
|
+
useInitialFocus(model);
|
|
274
|
+
useReturnFocus(model);
|
|
275
|
+
useFocusTrap(model);
|
|
276
|
+
useCloseOnEscape(model);
|
|
190
277
|
|
|
191
|
-
|
|
278
|
+
const state = {
|
|
279
|
+
...model.state,
|
|
280
|
+
showOverlay,
|
|
281
|
+
};
|
|
192
282
|
|
|
193
|
-
|
|
283
|
+
const events = useEventMap(myEventMap, state, config, {
|
|
284
|
+
...model.events,
|
|
285
|
+
});
|
|
194
286
|
|
|
195
|
-
|
|
196
|
-
|
|
287
|
+
return {state, events};
|
|
288
|
+
};
|
|
197
289
|
```
|
|
198
290
|
|
|
199
|
-
v7
|
|
291
|
+
##### v7
|
|
200
292
|
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
|
|
293
|
+
```ts
|
|
294
|
+
import {
|
|
295
|
+
useCloseOnEscape,
|
|
296
|
+
useEventMap,
|
|
297
|
+
useFocusTrap,
|
|
298
|
+
useInitialFocus,
|
|
299
|
+
usePopupModel,
|
|
300
|
+
useReturnFocus,
|
|
301
|
+
} from '@workday/canvas-kit-react';
|
|
204
302
|
|
|
205
|
-
|
|
303
|
+
const useMyModalModel = createModelHook({
|
|
304
|
+
defaultConfig: {
|
|
305
|
+
...usePopupModel.defaultConfig,
|
|
306
|
+
showOverlay: true,
|
|
307
|
+
},
|
|
308
|
+
requiredConfig: usePopupModel.requiredConfig,
|
|
309
|
+
contextOverride: usePopupModel.Context, // needed to make sure this model uses the same context as the popup model, otherwise it will create a new one
|
|
310
|
+
})(config => {
|
|
311
|
+
// `mergeConfig` takes care of the manual merging we were doing earlier
|
|
312
|
+
const model = usePopupModel(
|
|
313
|
+
usePopupModel.mergeConfig(config, {
|
|
314
|
+
// hook up to a redux store
|
|
315
|
+
onShow() {
|
|
316
|
+
dispatch(setIsModalOpen(true));
|
|
317
|
+
},
|
|
318
|
+
onHide() {
|
|
319
|
+
dispatch(setIsModalOpen(false));
|
|
320
|
+
},
|
|
321
|
+
})
|
|
322
|
+
);
|
|
206
323
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
324
|
+
useInitialFocus(model);
|
|
325
|
+
useReturnFocus(model);
|
|
326
|
+
useFocusTrap(model);
|
|
327
|
+
useCloseOnEscape(model);
|
|
328
|
+
|
|
329
|
+
const state = {
|
|
330
|
+
...model.state,
|
|
331
|
+
showOverlay,
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
return {...model, state};
|
|
335
|
+
});
|
|
214
336
|
```
|
|
215
337
|
|
|
216
|
-
|
|
338
|
+
We've eliminated the cumbersome type boilerplate and type imports. The code is more focused on your
|
|
339
|
+
unique logic and less on boilerplate.
|
|
340
|
+
|
|
341
|
+
Given the complex nature of this code, this change is **not** handled by the codemod.
|
|
342
|
+
|
|
343
|
+
## Tokens
|
|
344
|
+
|
|
345
|
+
### Depth
|
|
346
|
+
|
|
347
|
+
**Changes:**
|
|
348
|
+
|
|
349
|
+
- Removed `inset` depth
|
|
350
|
+
- Added new depth values: `none` (to remove the default depth from a component), `5` and `6`
|
|
351
|
+
- Updated all depth values: depth now adds only `box-shadow` with two shadows and no border
|
|
352
|
+
|
|
353
|
+
We've also changed the default depth for the following components:
|
|
354
|
+
|
|
355
|
+
- Breadcrumbs (Dropdown Menu): Depth 2 → Depth 3
|
|
356
|
+
- Card: Depth 2 → Depth 1
|
|
357
|
+
- Color Picker (Palette): Depth 2 → Depth 5
|
|
358
|
+
- Combobox: Depth 1 → Depth 3
|
|
359
|
+
- Dialog: Depth 2 → Depth 5
|
|
360
|
+
- Menu: Depth 2 → Depth 3
|
|
361
|
+
- Modal: Depth 2 → Depth 6
|
|
362
|
+
- Popup: Depth 2 → Depth 5
|
|
363
|
+
- Side Panel (Preview, alternate variant): Depth 3 → Depth 5
|
|
364
|
+
- Toast: Depth 2 → Depth 5
|
|
365
|
+
|
|
366
|
+
## Components
|
|
367
|
+
|
|
368
|
+
### Component Deprecations
|
|
369
|
+
|
|
370
|
+
#### Deprecation Types
|
|
371
|
+
|
|
372
|
+
There are two types of deprecations: soft and hard.
|
|
373
|
+
|
|
374
|
+
##### Soft Deprecation
|
|
375
|
+
|
|
376
|
+
A soft-deprecated component is still available with its full functionality, but it will have been
|
|
377
|
+
renamed with a prefix to indicate its soft-deprecated status. It will also include a console warning
|
|
378
|
+
announcing its deprecation. This warning will only be triggered on the component's initial render.
|
|
379
|
+
|
|
380
|
+
Soft-deprecated types and utilities will also be renamed but generally will not trigger a console
|
|
381
|
+
warning.
|
|
382
|
+
|
|
383
|
+
##### Hard Deprecation
|
|
217
384
|
|
|
218
|
-
|
|
219
|
-
|
|
385
|
+
A hard-deprecated component or package is no longer available. You will need to follow the method
|
|
386
|
+
prescribed in our migration guide to update your application. Please
|
|
387
|
+
[reach out](https://github.com/Workday/canvas-kit/issues/new?labels=bug&template=bug.md) to our team
|
|
388
|
+
directly if you need additional help.
|
|
389
|
+
|
|
390
|
+
#### Cookie Banner
|
|
391
|
+
|
|
392
|
+
We are [hard-deprecating](#hard-deprecation) `CookieBanner`. Please reference this
|
|
393
|
+
[example](https://workday.github.io/canvas-kit/?path=/story/examples-cookiebanner-react--basic) to
|
|
394
|
+
migrate away from `CookieBanner`.
|
|
395
|
+
|
|
396
|
+
#### Page Header
|
|
397
|
+
|
|
398
|
+
We are [hard-deprecating](#hard-deprecation) `PageHeader`. Please reference this
|
|
399
|
+
[example](https://workday.github.io/canvas-kit/?path=/story/examples-pageheader-react--basic) to
|
|
400
|
+
migrate away from `PageHeader`.
|
|
401
|
+
|
|
402
|
+
#### Header / Global Header
|
|
403
|
+
|
|
404
|
+
We are [hard-deprecating](#hard-deprecation) `Header`. Please reference this
|
|
405
|
+
[example](https://workday.github.io/canvas-kit/?path=/story/examples-globalheader-react--basic) to
|
|
406
|
+
migrate away from `Header`.
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
### Component Promotions
|
|
411
|
+
|
|
412
|
+
We've [promoted](https://github.com/Workday/canvas-kit/issues/1395) the following components in v7:
|
|
413
|
+
|
|
414
|
+
- `Box` from `@workday/canvas-kit-labs/common` to `@workday/canvas-kit-react/layout`
|
|
415
|
+
- `Flex` from `@workday/canvas-kit-labs/layout` to `@workday/canvas-kit-react/layout`
|
|
416
|
+
- `Stack` from `@workday/canvas-kit-labs/layout` to `@workday/canvas-kit-react/layout`
|
|
220
417
|
|
|
221
418
|
```tsx
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
419
|
+
// v6
|
|
420
|
+
import {Box} from '@workday/canvas-kit-labs-react/common';
|
|
421
|
+
|
|
422
|
+
// v7
|
|
423
|
+
import {Box} from '@workday/canvas-kit-react/layout';
|
|
226
424
|
```
|
|
227
425
|
|
|
228
|
-
|
|
426
|
+
🤖 The codemod will update imports for these promoted components.
|
|
427
|
+
|
|
428
|
+
The APIs for these promoted components remain unchanged.
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
### Action Bar
|
|
229
433
|
|
|
230
|
-
|
|
231
|
-
|
|
434
|
+
We've updated `ActionBar` to use the
|
|
435
|
+
[createComponent](/getting-started/for-developers/resources/creating-compound-components/#disclosurecontent-component)
|
|
436
|
+
utility from our
|
|
437
|
+
[common](https://github.com/Workday/canvas-kit/blob/ff77c5bd83e41c3ab2b9c55e41a8b7c1fde33a1b/modules/react/common/lib/utils/components.ts#L167)
|
|
438
|
+
module; it now supports [ref forwarding](https://reactjs.org/docs/forwarding-refs.html) and using
|
|
439
|
+
the `as` prop to change the rendered element.
|
|
232
440
|
|
|
233
|
-
|
|
441
|
+
We've removed the `fixed` prop from `ActionBar`. It now uses the `position` prop (defaults to
|
|
442
|
+
`fixed`) to set the container position.
|
|
443
|
+
|
|
444
|
+
🤖 The codemod will remove uses of the `fixed` prop from `ActionBar`.
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
### Banner
|
|
449
|
+
|
|
450
|
+
Banner is now a [compound component](/getting-started/for-developers/resources/compound-components/)
|
|
451
|
+
composed of `Banner.Icon`, `Banner.Label`, and `Banner.ActionText`. This allows direct access to the
|
|
452
|
+
icon, label, and text elements.
|
|
234
453
|
|
|
235
454
|
```tsx
|
|
236
|
-
|
|
455
|
+
// v6
|
|
456
|
+
<Banner label="3 Warnings" actionText="Show Details" variant={Banner.Variant.Sticky} error={Banner.ErrorType.Error} />
|
|
457
|
+
|
|
458
|
+
// v7
|
|
459
|
+
<Banner isSticky={true} hasError={true}>
|
|
460
|
+
<Banner.Icon />
|
|
461
|
+
<Banner.Label>3 Warnings</Banner.Label>
|
|
462
|
+
<Banner.ActionText>Show Details</Banner.ActionText>
|
|
463
|
+
</Banner>
|
|
237
464
|
```
|
|
238
465
|
|
|
239
|
-
|
|
466
|
+
🤖 The codemod will rewrite your JSX to match the new API.
|
|
467
|
+
|
|
468
|
+
Like all compound components, `Banner` is written using the
|
|
469
|
+
[createComponent](/getting-started/for-developers/resources/creating-compound-components/#disclosurecontent-component)
|
|
470
|
+
utility from our
|
|
471
|
+
[common](https://github.com/Workday/canvas-kit/blob/ff77c5bd83e41c3ab2b9c55e41a8b7c1fde33a1b/modules/react/common/lib/utils/components.ts#L167)
|
|
472
|
+
module; it supports [ref forwarding](https://reactjs.org/docs/forwarding-refs.html) and using the
|
|
473
|
+
`as` prop to change the rendered element.
|
|
474
|
+
|
|
475
|
+
The `variant` prop (which previously accepted `Banner.Variant.Full` or `Banner.Variant.Sticky`) has
|
|
476
|
+
been converted to the boolean `isSticky` prop on the container `Banner` component.
|
|
477
|
+
|
|
478
|
+
Similarly, the `error` prop (which previously accepted `Banner.ErrorType.Alert` or
|
|
479
|
+
`Banner.ErrorType.Error`) has been converted to the boolean `hasError` prop on `Banner`. `Banner`
|
|
480
|
+
now uses the `useThemedPalette` hook which allows you to override its colors using the Canvas theme.
|
|
481
|
+
|
|
482
|
+
The icon is now customizable via the `icon` prop of `Banner.Icon`. Previously, the icon was limited
|
|
483
|
+
to `exclamationTriangleIcon` and `exclamationCircleIcon` for the alert and error states,
|
|
484
|
+
respectively.
|
|
485
|
+
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
### Button
|
|
489
|
+
|
|
490
|
+
#### Removal of Icon Button
|
|
491
|
+
|
|
492
|
+
To consolidate Button APIs, we've removed `IconButton` in favor of `SecondaryButton` and
|
|
493
|
+
`TertiaryButton`. The following table shows how `IconButton` variants in v6 map to their
|
|
494
|
+
corresponding buttons in v7.
|
|
495
|
+
|
|
496
|
+
| v6 `IconButton` variant | v7 button (and variant, if necessary) |
|
|
497
|
+
| -------------------------- | ---------------------------------------- |
|
|
498
|
+
| `circle` (default variant) | `TertiaryButton` |
|
|
499
|
+
| `circleFilled` | `SecondaryButton` |
|
|
500
|
+
| `inverse` | `TertiaryButton` with `inverse` variant |
|
|
501
|
+
| `inverseFilled` | `SecondaryButton` with `inverse` variant |
|
|
502
|
+
| `plain` | Unsupported |
|
|
503
|
+
| `square` | Unsupported |
|
|
504
|
+
| `squareFilled` | Unsupported |
|
|
505
|
+
|
|
506
|
+
> Note: See below for more information about how to manually migrate from
|
|
507
|
+
> [unsupported v6 variants](#unsupported-iconbutton-variants).
|
|
508
|
+
|
|
509
|
+
🤖 Use the codemod to migrate your `IconButton` components in v6 to their corresponding buttons in
|
|
510
|
+
v7:
|
|
240
511
|
|
|
241
512
|
```tsx
|
|
242
|
-
|
|
513
|
+
// v6
|
|
514
|
+
<IconButton icon={plusIcon} />
|
|
515
|
+
<IconButton variant="circleFilled" icon={plusIcon} />
|
|
516
|
+
<IconButton variant="inverse" icon={plusIcon} />
|
|
517
|
+
<IconButton variant="inverseFilled" icon={plusIcon} />
|
|
518
|
+
|
|
519
|
+
// v7
|
|
520
|
+
<TertiaryButton icon={plusIcon} />
|
|
521
|
+
<SecondaryButton icon={plusIcon} />
|
|
522
|
+
<TertiaryButton variant="inverse" icon={plusIcon} />
|
|
523
|
+
<SecondaryButton variant="inverse" icon={plusIcon} />
|
|
243
524
|
```
|
|
244
525
|
|
|
245
|
-
|
|
526
|
+
##### Unsupported IconButton Variants
|
|
527
|
+
|
|
528
|
+
In order to simplify our API, we no longer support the `plain`, `square`, and `squareFilled`
|
|
529
|
+
variants from `IconButton`.
|
|
530
|
+
|
|
531
|
+
`IconButton` components with `square`, `squareFilled` and `plain` variants should be updated to the
|
|
532
|
+
corresponding icon-only button versions (`PrimaryButton`, `SecondaryButton`, and `TertiaryButton`),
|
|
533
|
+
`ToolbarIconButton`, or `SegmentedControl`. You may use `ToolbarIconButton` if you would still like
|
|
534
|
+
to have a square icon that is toggleable.
|
|
535
|
+
|
|
536
|
+
These changes are **not** handled by the codemod.
|
|
537
|
+
|
|
538
|
+
> If none of these options support your use case, we've introduced a low-level
|
|
539
|
+
> [`BaseButton`](#basebutton) component which allows you to modify the button's colors, size, and
|
|
540
|
+
> other props. For an example of it being used, reference our
|
|
541
|
+
> [`PageButton`](https://github.com/Workday/canvas-kit/blob/master/modules/react/pagination/lib/Pagination/PageButton.tsx)
|
|
542
|
+
> component.
|
|
246
543
|
|
|
247
|
-
|
|
544
|
+
##### Removal of IconButtonProps
|
|
248
545
|
|
|
249
|
-
The `
|
|
546
|
+
The `IconButtonProps` interface no longer exists now that `IconButton` has been removed.
|
|
250
547
|
|
|
251
|
-
|
|
252
|
-
have a similar effect, below is an example of how to achieve this.
|
|
548
|
+
This change is **not** handled by the codemod.
|
|
253
549
|
|
|
254
|
-
|
|
550
|
+
##### Toggled
|
|
551
|
+
|
|
552
|
+
There is no equivalent to the `IconButton` `toggled` prop in `SecondaryButton` and `TertiaryButton`.
|
|
553
|
+
If you wish to render a button with a toggled state, consider using `ToolbarIconButton`.
|
|
554
|
+
|
|
555
|
+
This change is **not** handled by the codemod.
|
|
556
|
+
|
|
557
|
+
#### Icon Position
|
|
558
|
+
|
|
559
|
+
The `iconPosition` prop determines where an icon should be rendered relative to the button text.
|
|
560
|
+
We've updated the values from `left` and `right` to `start` and `end` respectively to better reflect
|
|
561
|
+
bidirectionality. The default value is `start`.
|
|
255
562
|
|
|
256
563
|
```tsx
|
|
257
|
-
|
|
564
|
+
// v6
|
|
565
|
+
iconPosition: 'left' | 'right';
|
|
566
|
+
|
|
567
|
+
// v7
|
|
568
|
+
iconPosition: 'start' | 'end';
|
|
258
569
|
```
|
|
259
570
|
|
|
260
|
-
|
|
571
|
+
🤖 The codemod will map `left` to `start` and `right` to `end` for all uses of `iconPosition`.
|
|
572
|
+
|
|
573
|
+
`iconPosition` will have no effect if you're rendering a button with only an icon and no text.
|
|
574
|
+
|
|
575
|
+
#### Removal of dataLabel
|
|
576
|
+
|
|
577
|
+
In order to simplify our API, we've removed the `dataLabel` prop from `PrimaryButton` and
|
|
578
|
+
`SecondaryButton`.
|
|
579
|
+
|
|
580
|
+
Given the varied use of `dataLabel`, this change is **not** handled by the codemod. Here's an
|
|
581
|
+
example of how to achieve a similar styling in v7:
|
|
261
582
|
|
|
262
583
|
```tsx
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
584
|
+
// v6
|
|
585
|
+
<PrimaryButton dataLabel="1:00">Time</PrimaryButton>;
|
|
586
|
+
|
|
587
|
+
// v7
|
|
588
|
+
import {space, type} from '@workday/canvas-kit-react/common';
|
|
589
|
+
|
|
590
|
+
const DataLabel = styled('span')({
|
|
591
|
+
position: 'relative', // Fixes an IE issue with text within button moving on click
|
|
592
|
+
overflow: 'hidden',
|
|
593
|
+
whiteSpace: 'nowrap',
|
|
594
|
+
fontWeight: type.properties.fontWeights.regular,
|
|
595
|
+
marginLeft: space.xxxs,
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
return (
|
|
599
|
+
<PrimaryButton>
|
|
600
|
+
Time
|
|
601
|
+
<DataLabel>1:00</DataLabel>
|
|
602
|
+
</PrimaryButton>
|
|
603
|
+
);
|
|
278
604
|
```
|
|
279
605
|
|
|
280
|
-
|
|
606
|
+
#### BaseButton
|
|
281
607
|
|
|
282
|
-
|
|
608
|
+
> **Disclaimer**: We **strongly** advise consumers **not** to use `BaseButton` and to instead rely
|
|
609
|
+
> on `PrimaryButton`, `SecondaryButton` and `TertiaryButton` whenever possible. `BaseButton` is
|
|
610
|
+
> strictly provided as a last resort if no other option is available for your use case.
|
|
611
|
+
|
|
612
|
+
As part of our Button restructuring, we've created a low level `BaseButton` component. This
|
|
283
613
|
component isn't intended to be used outside of Canvas Kit, but we do export it for very specific use
|
|
284
|
-
cases
|
|
285
|
-
|
|
286
|
-
properties.
|
|
614
|
+
cases. `BaseButton` is a styled `<button>` element which supports style properties such as `colors`,
|
|
615
|
+
`padding`, and `width` among many others.
|
|
287
616
|
|
|
288
|
-
|
|
617
|
+
Here's an example:
|
|
289
618
|
|
|
290
619
|
```tsx
|
|
291
620
|
import * as React from 'react';
|
|
@@ -332,134 +661,64 @@ export const BasicButton = ({children, ...elemProps}: BasicButtonProps) => {
|
|
|
332
661
|
<BaseButton.Label>{children}</BaseButton.Label>
|
|
333
662
|
<BaseButton.Icon icon={plusIcon}>
|
|
334
663
|
</StyledToggleButton>
|
|
335
|
-
);
|
|
336
|
-
};
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
**Note:** Under the hood, `BaseButton` uses our `Box` component which allows `BaseButton` to accept
|
|
340
|
-
style properties. Because of the flexibility of this component, consumers can use this to create
|
|
341
|
-
toggled buttons or a specific button that doesn't fall under the main use case you see in our design
|
|
342
|
-
system.
|
|
343
|
-
|
|
344
|
-
**Disclaimer** We strongly advise consumers not to use this component if possible and to rely on our
|
|
345
|
-
`PrimaryButton`, `SecondaryButton` and `TertiaryButton` when possible.
|
|
346
|
-
|
|
347
|
-
## Segmented Control
|
|
348
|
-
|
|
349
|
-
Segmented Control use to work when rendering `IconButton` as children. This has now moved to a
|
|
350
|
-
compound component and removed the use of `IconButton`.
|
|
351
|
-
|
|
352
|
-
### Breaking Change
|
|
353
|
-
|
|
354
|
-
`IconButton` is no longer a valid child of segmented control.
|
|
355
|
-
|
|
356
|
-
🤖 The codemod will handle all these changes automatically:
|
|
357
|
-
|
|
358
|
-
- `IconButton` becomes `SegmentedControl.Button`
|
|
359
|
-
|
|
360
|
-
v6
|
|
361
|
-
|
|
362
|
-
```tsx
|
|
363
|
-
<SegmentedControl value={value} onChange={handleToggle}>
|
|
364
|
-
<IconButton
|
|
365
|
-
icon={listViewIcon}
|
|
366
|
-
value="list-view"
|
|
367
|
-
aria-label="List View"
|
|
368
|
-
onClick={e => console.log('Existing IconButton onClick callback')}
|
|
369
|
-
/>
|
|
370
|
-
<IconButton icon={worksheetsIcon} value="table-view" aria-label="Table View" disabled={true} />
|
|
371
|
-
<IconButton icon={deviceTabletIcon} value="device-view" aria-label="Device View" />
|
|
372
|
-
<IconButton icon={percentageIcon} value="percent-view" aria-label="Percent View" />
|
|
373
|
-
</SegmentedControl>
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
v7
|
|
377
|
-
|
|
378
|
-
```tsx
|
|
379
|
-
<SegmentedControl value={value} onChange={handleToggle}>
|
|
380
|
-
<SegmentedControl.Button
|
|
381
|
-
icon={listViewIcon}
|
|
382
|
-
value="list-view"
|
|
383
|
-
aria-label="List View"
|
|
384
|
-
onClick={e => console.log('Existing IconButton onClick callback')}
|
|
385
|
-
/>
|
|
386
|
-
<SegmentedControl.Button
|
|
387
|
-
icon={worksheetsIcon}
|
|
388
|
-
value="table-view"
|
|
389
|
-
aria-label="Table View"
|
|
390
|
-
disabled={true}
|
|
391
|
-
/>
|
|
392
|
-
<SegmentedControl.Button icon={deviceTabletIcon} value="device-view" aria-label="Device View" />
|
|
393
|
-
<SegmentedControl.Button icon={percentageIcon} value="percent-view" aria-label="Percent View" />
|
|
394
|
-
</SegmentedControl>
|
|
664
|
+
);
|
|
665
|
+
};
|
|
395
666
|
```
|
|
396
667
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
tooltip built in. If you currently have a `Tooltip` component wrapping this element, you should
|
|
401
|
-
remove it and provide the appropiate text to the button based on its state.
|
|
402
|
-
|
|
403
|
-
Two props where added to the `SidePanel.ToggleButton`:
|
|
404
|
-
|
|
405
|
-
```tsx
|
|
406
|
-
/**
|
|
407
|
-
* The tooltip text to expand the side panel
|
|
408
|
-
* @default 'Expand'
|
|
409
|
-
*/
|
|
410
|
-
tooltipTextExpand?: string;
|
|
411
|
-
/**
|
|
412
|
-
* The tooltip text to collapse the side panel
|
|
413
|
-
* @default 'Collapse'
|
|
414
|
-
*/
|
|
415
|
-
tooltipTextCollapse?: string;
|
|
416
|
-
```
|
|
668
|
+
`BaseButton` uses our `Box` component under the hood, which allows it to accept a variety of style
|
|
669
|
+
properties. Because of the flexibility of this component, consumers can use it to create toggled
|
|
670
|
+
buttons or other buttons that aren't supported by our standard button components.
|
|
417
671
|
|
|
418
|
-
|
|
672
|
+
---
|
|
419
673
|
|
|
420
|
-
|
|
421
|
-
`Tabs.Menu.Item`. The attribute changed from `name` to `data-id`. We did this to not interfere with
|
|
422
|
-
the HTML `name` attribute.
|
|
674
|
+
### Icon
|
|
423
675
|
|
|
424
|
-
|
|
676
|
+
We've updated `AccentIcon`, `AppletIcon`, `Graphic`, `Icon`, `Svg`, `SystemIcon`, and
|
|
677
|
+
`SystemIconCircle` to use the
|
|
678
|
+
[createComponent](/getting-started/for-developers/resources/creating-compound-components/#disclosurecontent-component)
|
|
679
|
+
utility from our
|
|
680
|
+
[common](https://github.com/Workday/canvas-kit/blob/ff77c5bd83e41c3ab2b9c55e41a8b7c1fde33a1b/modules/react/common/lib/utils/components.ts#L167)
|
|
681
|
+
module; they now support [ref forwarding](https://reactjs.org/docs/forwarding-refs.html) and using
|
|
682
|
+
the `as` prop to change the rendered element.
|
|
425
683
|
|
|
426
|
-
|
|
684
|
+
These components previously supported an `iconRef` prop. In v7, you'll need to use `ref` instead of
|
|
685
|
+
`iconRef`:
|
|
427
686
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
687
|
+
```tsx
|
|
688
|
+
// v6
|
|
689
|
+
<SystemIcon iconRef={ref} />;
|
|
431
690
|
|
|
432
|
-
|
|
691
|
+
// v7
|
|
692
|
+
<SystemIcon ref={ref} />;
|
|
693
|
+
```
|
|
433
694
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
[createComponent](https://github.com/Workday/canvas-kit/blob/ff77c5bd83e41c3ab2b9c55e41a8b7c1fde33a1b/modules/react/common/lib/utils/components.ts#L167)
|
|
437
|
-
which allows us to `forwardRef`.
|
|
695
|
+
🤖 The codemod will update all Icon components that previously supported `iconRef` to use `ref`
|
|
696
|
+
instead.
|
|
438
697
|
|
|
439
|
-
|
|
698
|
+
---
|
|
440
699
|
|
|
441
|
-
|
|
442
|
-
element.
|
|
700
|
+
### Popper
|
|
443
701
|
|
|
444
|
-
|
|
702
|
+
We've removed the `containerElement` prop from `Popper` because it's no longer needed with the
|
|
703
|
+
Fullscreen API.
|
|
445
704
|
|
|
446
|
-
|
|
705
|
+
---
|
|
447
706
|
|
|
448
|
-
|
|
707
|
+
### Popup
|
|
449
708
|
|
|
450
|
-
|
|
451
|
-
This was done to support overflowing content (by default, the `Popup.Body` component). The idea is
|
|
452
|
-
the card is a vertical flexbox container and the `Popup.Heading`, `Popup.Body`, and any other
|
|
453
|
-
children are flex items. The `Popup.Body` now has an `overflow-y: auto` on it to naturally allow the
|
|
454
|
-
body content to overflow in a scroll container. This is a breaking change if your `Popup`, `Modal`,
|
|
455
|
-
or `Dialog` doesn't work with a flexbox with `flex-direction: column`. In most cases, this shouldn't
|
|
456
|
-
matter. If this change does cause your popup to display correctly, you may need to play around with
|
|
457
|
-
flex item containers.
|
|
709
|
+
#### Popup.Card
|
|
458
710
|
|
|
459
|
-
|
|
711
|
+
`Popup.Card` components (this includes `Modal.Card` and `Dialog.Card`) are now flexbox containers.
|
|
712
|
+
This was done to support overflowing content (by default, the `Popup.Body` component). The card is a
|
|
713
|
+
vertical flexbox container and `Popup.Heading`, `Popup.Body`, and any other children are flex items.
|
|
714
|
+
`Popup.Body` now has `overflow-y: auto` to naturally allow the body content to overflow in a scroll
|
|
715
|
+
container. This is a breaking change if your `Popup`, `Modal`, or `Dialog` doesn't work with a
|
|
716
|
+
flexbox with `flex-direction: column`. In most cases, this shouldn't matter. If this change does
|
|
717
|
+
cause your popup to display incorrectly, you may need to play around with flex item containers.
|
|
460
718
|
|
|
461
|
-
|
|
462
|
-
|
|
719
|
+
Here's an example of where your current implementation might break. A common `Modal` has a heading,
|
|
720
|
+
body, and footer (Cancel/Submit buttons). If the Cancel and Submit buttons are direct children of
|
|
721
|
+
the `Modal.Card` like the following...
|
|
463
722
|
|
|
464
723
|
```tsx
|
|
465
724
|
<Modal.Card>
|
|
@@ -470,11 +729,10 @@ buttons are direct children of the `Modal.Card` like the following:
|
|
|
470
729
|
</Modal.Card>
|
|
471
730
|
```
|
|
472
731
|
|
|
473
|
-
|
|
474
|
-
Before, the buttons would layout next to each other horizontally.
|
|
475
|
-
vertically. To fix this, you'll
|
|
476
|
-
|
|
477
|
-
change:
|
|
732
|
+
...the buttons will become vertical flex items instead of the default which is displaying
|
|
733
|
+
inline-block. Before v7, the buttons would layout next to each other horizontally. In v7, the
|
|
734
|
+
buttons will stack vertically. To fix this, you'll need to add another element as a flex item in the
|
|
735
|
+
`Modal.Card`. The following example uses `HStack` to achieve the desired horizontal layout:
|
|
478
736
|
|
|
479
737
|
```tsx
|
|
480
738
|
<Modal.Card>
|
|
@@ -487,41 +745,37 @@ change:
|
|
|
487
745
|
</Modal.Card>
|
|
488
746
|
```
|
|
489
747
|
|
|
490
|
-
If your code contains any hacks to make a `Modal` overflow,
|
|
748
|
+
If your code contains any hacks to make a `Modal` overflow, those hacks should now be removed.
|
|
491
749
|
[This example shows how body content overflows](https://workday.github.io/canvas-kit/?path=/docs/components-popups-modal-react--body-overflow)
|
|
492
|
-
(you may have to limit your browser height to see the overflow). Before you had to manually set
|
|
493
|
-
`max-height` of the `Modal.Body` element using calculations. These should be removed. The
|
|
750
|
+
(you may have to limit your browser height to see the overflow). Before v7, you had to manually set
|
|
751
|
+
the `max-height` of the `Modal.Body` element using calculations. These should now be removed. The
|
|
494
752
|
`Popup.Card` now has a max height and the `Popup.Body` height is automatically calculated.
|
|
495
753
|
|
|
496
|
-
|
|
754
|
+
#### Popup.Body
|
|
497
755
|
|
|
498
|
-
|
|
756
|
+
`Popup.Body` is now an overflow container. This means two things:
|
|
499
757
|
|
|
500
758
|
- `Popup.Body` will scroll if the contents are too big to fit in the page
|
|
501
759
|
- `Popup.Body` will hide focus rings that render outside the overflow container
|
|
502
760
|
|
|
503
|
-
Our examples contained
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
Before:
|
|
761
|
+
Our examples contained buttons inside the `Body` element with their focus rings cut off. We fixed
|
|
762
|
+
this by moving the buttons outside the `Body` element. This is most likely the desired structure
|
|
763
|
+
anyway since the buttons will no longer scroll with overflowed `Body` content.
|
|
508
764
|
|
|
509
765
|
```tsx
|
|
766
|
+
// v6
|
|
510
767
|
<Modal.Card>
|
|
511
768
|
<Modal.Body>
|
|
512
769
|
Body Contents
|
|
513
770
|
<HStack spacing="s">
|
|
514
|
-
{/*
|
|
771
|
+
{/* Will scroll with the body */}
|
|
515
772
|
<Modal.CloseButton as={PrimaryButton}>Delete</Modal.CloseButton>
|
|
516
773
|
<Modal.CloseButton>Cancel</Modal.CloseButton>
|
|
517
774
|
</HStack>
|
|
518
775
|
</Modal.Body>
|
|
519
776
|
</Modal.Card>
|
|
520
|
-
```
|
|
521
|
-
|
|
522
|
-
After:
|
|
523
777
|
|
|
524
|
-
|
|
778
|
+
// v7
|
|
525
779
|
<Modal.Card>
|
|
526
780
|
<Modal.Body>Body Contents</Modal.Body>
|
|
527
781
|
<HStack spacing="s">
|
|
@@ -531,301 +785,165 @@ After:
|
|
|
531
785
|
</Modal.Card>
|
|
532
786
|
```
|
|
533
787
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
We removed the `containerElement` prop from Popper component because it's no longer needed with
|
|
537
|
-
Fullscreen API.
|
|
538
|
-
|
|
539
|
-
## Component Promotions
|
|
540
|
-
|
|
541
|
-
After some [assessment](https://github.com/Workday/canvas-kit/issues/1395) we've decided to promote
|
|
542
|
-
the following components: `Flex`, `Stack`, `Box` and `Breadcumbs`
|
|
543
|
-
|
|
544
|
-
This promotion does not introduce any API changes, we've just changed moved the components to our
|
|
545
|
-
main `react` package.
|
|
788
|
+
#### Popup Model
|
|
546
789
|
|
|
547
|
-
|
|
790
|
+
In addition to the other [Model Changes](#model-changes), the `show` and `hide` events of all
|
|
791
|
+
disclosure-type models have been updated to remove the extra event wrapper. This change allows
|
|
792
|
+
developers to directly attach the `show` and `hide` events to React event handlers.
|
|
548
793
|
|
|
549
|
-
|
|
550
|
-
- `Flex` was promoted from `@workday/canvas-kit-labs/layout` to `@workday/canvas-kit-react/layout`
|
|
551
|
-
- `Stack` was promoted from `@workday/canvas-kit-labs/layout` to `@workday/canvas-kit-react/layout`
|
|
794
|
+
The following models were affected:
|
|
552
795
|
|
|
553
|
-
|
|
796
|
+
- `useDisclosureModel`
|
|
797
|
+
- `usePopupModel`
|
|
798
|
+
- `useModalModel`
|
|
799
|
+
- `useDisclosureModel`
|
|
554
800
|
|
|
555
|
-
|
|
801
|
+
```tsx
|
|
802
|
+
// v6
|
|
803
|
+
<button onClick={() => model.events.show()} /> // most use-cases look like this
|
|
804
|
+
<button onClick={event => model.events.show({event})} />
|
|
556
805
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
the object wrapper.
|
|
806
|
+
// v7
|
|
807
|
+
<button onClick={model.events.show} />
|
|
808
|
+
```
|
|
561
809
|
|
|
562
|
-
|
|
810
|
+
Removing the object wrapper around the `event` allows us to directly pass the `show` or `hide` event
|
|
811
|
+
to the `onClick` handler which is much more convenient. We couldn't find many uses of the `event` in
|
|
812
|
+
the wild, so the impact will be minimal. Most usage of `show` or `hide` events are called without
|
|
813
|
+
`event`, so this change will not impact most people. There is **no** codemod for this change,
|
|
814
|
+
because the usage is very difficult to detect since most people pass a callback that doesn't take
|
|
815
|
+
parameters.
|
|
563
816
|
|
|
564
|
-
|
|
817
|
+
Guards and callback signatures have also changed to remove the object wrapper around the `event`.
|
|
818
|
+
The following v6 example includes the [Model Changes](#model-changes) which this change compounds
|
|
819
|
+
upon.
|
|
565
820
|
|
|
566
821
|
```tsx
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
822
|
+
// v6
|
|
823
|
+
const model = usePopupModel({
|
|
824
|
+
shouldShow({data: {event}, state}) {
|
|
825
|
+
console.log(event, state);
|
|
570
826
|
},
|
|
571
|
-
})
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
After:
|
|
575
|
-
|
|
576
|
-
```tsx
|
|
577
|
-
const model = useTabsModel({
|
|
578
|
-
onSelect({id}, prevState) {
|
|
579
|
-
console.log(id, prevState);
|
|
827
|
+
onShow({data: {event}, prevState}) {
|
|
828
|
+
console.log(event, prevState);
|
|
580
829
|
},
|
|
581
830
|
});
|
|
582
|
-
```
|
|
583
|
-
|
|
584
|
-
### Model Implementation
|
|
585
|
-
|
|
586
|
-
If you don't extend models, you can skip this section.
|
|
587
|
-
|
|
588
|
-
In v6 we supported Typescript 3.8 which limited the way types could be inferred and defined. Canvas
|
|
589
|
-
Kit v7 now requires Typescript 4.1 which introduced
|
|
590
|
-
[Template Literal Types](https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html).
|
|
591
|
-
This means that the guards and callbacks no longer need to be manually defined via an `eventMap`.
|
|
592
|
-
Event maps were a stopgap, were manual, and prone to errors in defining them. Not all events had
|
|
593
|
-
guards or callbacks there's no check other than manual review to ensure the existence of an event
|
|
594
|
-
callback or guard. Template Literal Types allow us to properly type guards and callbacks without
|
|
595
|
-
event maps. The previous types forced `data` to be an object. We've since dropped that restriction.
|
|
596
|
-
You can still only pass a single argument to events. If you need additional information, use an
|
|
597
|
-
object.
|
|
598
|
-
|
|
599
|
-
This change also allowed us to remove a lot of boilerplate associated with models without
|
|
600
|
-
sacrificing type safety. This change doesn't effect most use cases, but will effect those whole
|
|
601
|
-
extended a model. We created a new utility function called `createModelHook` that helps set up
|
|
602
|
-
types.
|
|
603
|
-
|
|
604
|
-
Before:
|
|
605
|
-
|
|
606
|
-
```ts
|
|
607
|
-
export type MyState = {
|
|
608
|
-
value: string;
|
|
609
|
-
};
|
|
610
|
-
|
|
611
|
-
export type MyEvents = {
|
|
612
|
-
updateValue(data: {value: string}): void; // enforced that `data` is an object even if we only need to pass a string
|
|
613
|
-
};
|
|
614
|
-
|
|
615
|
-
export type MyModel = Model<MyState, MyEvents>;
|
|
616
831
|
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
832
|
+
// v7
|
|
833
|
+
const model = usePopupModel({
|
|
834
|
+
shouldShow(event, state) {
|
|
835
|
+
console.log(event, state);
|
|
620
836
|
},
|
|
621
|
-
|
|
622
|
-
|
|
837
|
+
onShow(event, prevState) {
|
|
838
|
+
console.log(event, prevState);
|
|
623
839
|
},
|
|
624
840
|
});
|
|
625
|
-
|
|
626
|
-
export type MyBaseConfig = {
|
|
627
|
-
initialValue?: string;
|
|
628
|
-
};
|
|
629
|
-
|
|
630
|
-
export type MyConfig = MyBaseConfig & Partial<ToModelConfig<MyState, MyEvents, typeof myEventMap>>;
|
|
631
|
-
|
|
632
|
-
const useMyModel = (config: MyConfig = {}): MyModel => {
|
|
633
|
-
const [value, setValue] = React.useState(config.initialValue || '');
|
|
634
|
-
|
|
635
|
-
const state = {value};
|
|
636
|
-
|
|
637
|
-
// useEventMap is used to wrap the event object with guards and callbacks according to the event map
|
|
638
|
-
const events = useEventMap(myEventMap, state, config, {
|
|
639
|
-
updateValue(data) {
|
|
640
|
-
setValue(data.value);
|
|
641
|
-
},
|
|
642
|
-
});
|
|
643
|
-
|
|
644
|
-
return {state, events};
|
|
645
|
-
};
|
|
646
841
|
```
|
|
647
842
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
const useMyModel = createModelHook({
|
|
652
|
-
defaultConfig: {
|
|
653
|
-
initialValue: '',
|
|
654
|
-
},
|
|
655
|
-
})(config => {
|
|
656
|
-
const [value, setValue] = React.useState(config.initialValue); // default is already handled
|
|
657
|
-
|
|
658
|
-
const state = {value};
|
|
843
|
+
🤖 The codemod will update all inline guards and callbacks defined like they are in this example. If
|
|
844
|
+
a guard or callback was defined outside the model config block, it will not be covered by the
|
|
845
|
+
codemod.
|
|
659
846
|
|
|
660
|
-
|
|
661
|
-
updateValue(value: string) {
|
|
662
|
-
// doesn't need to be an object anymore
|
|
663
|
-
setValue(value);
|
|
664
|
-
},
|
|
665
|
-
};
|
|
847
|
+
---
|
|
666
848
|
|
|
667
|
-
|
|
668
|
-
});
|
|
669
|
-
```
|
|
849
|
+
### Segmented Control
|
|
670
850
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
of types and values. Also notice that `useEventMap` doesn't need to be used anymore. The
|
|
674
|
-
`createModelHook` will automatically wrap the `events` returned to call guards and callbacks when
|
|
675
|
-
appropriate. Today this is done via creating a new events object. Once we drop IE11 support, this
|
|
676
|
-
can be done via a proxy instead. The `createModelHook` handles all type inference so we don't have
|
|
677
|
-
to explicitly type everything. Also `createModelHook` attaches React Context directly to the hook
|
|
678
|
-
along with `defaultConfig` and `requiredConfig` for model extension.
|
|
851
|
+
`SegmentedControl` is now a
|
|
852
|
+
[compound component](/getting-started/for-developers/resources/compound-components/).
|
|
679
853
|
|
|
680
|
-
|
|
681
|
-
|
|
854
|
+
Given the [removal of `IconButton`](#removal-of-icon-button) in v7, you'll now need to use
|
|
855
|
+
`SegmentedControl.Button` instead.
|
|
682
856
|
|
|
683
857
|
```tsx
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
useInitialFocus,
|
|
697
|
-
usePopupModel,
|
|
698
|
-
useReturnFocus,
|
|
699
|
-
} from '@workday/canvas-kit-react';
|
|
700
|
-
|
|
701
|
-
type MyModalState = PopupState & {
|
|
702
|
-
showOverlay: boolean;
|
|
703
|
-
};
|
|
704
|
-
|
|
705
|
-
type MyModalEvents = PopupEvents;
|
|
706
|
-
|
|
707
|
-
const myModalEventMap = createEventMap<MyModalEvents>()({
|
|
708
|
-
guards: {
|
|
709
|
-
...popupEventMap.guards,
|
|
710
|
-
},
|
|
711
|
-
callbacks: {
|
|
712
|
-
...popupEventMap.callbacks,
|
|
713
|
-
},
|
|
714
|
-
});
|
|
715
|
-
|
|
716
|
-
type MyBaseModalConfig = BasePopupModelConfig & {
|
|
717
|
-
showOverlay?: boolean;
|
|
718
|
-
};
|
|
719
|
-
|
|
720
|
-
type MyModalModel = Model<MyModalState, MyModalEvents>;
|
|
721
|
-
|
|
722
|
-
type MyConfig = MyBaseConfig &
|
|
723
|
-
Partial<ToModelConfig<MyModalState, MyModalEvents, typeof myModalEventMap>>;
|
|
858
|
+
// v6
|
|
859
|
+
<SegmentedControl value={value} onChange={handleToggle}>
|
|
860
|
+
<IconButton
|
|
861
|
+
icon={listViewIcon}
|
|
862
|
+
value="list-view"
|
|
863
|
+
aria-label="List View"
|
|
864
|
+
onClick={e => console.log('Existing IconButton onClick callback')}
|
|
865
|
+
/>
|
|
866
|
+
<IconButton icon={worksheetsIcon} value="table-view" aria-label="Table View" disabled={true} />
|
|
867
|
+
<IconButton icon={deviceTabletIcon} value="device-view" aria-label="Device View" />
|
|
868
|
+
<IconButton icon={percentageIcon} value="percent-view" aria-label="Percent View" />
|
|
869
|
+
</SegmentedControl>
|
|
724
870
|
|
|
725
|
-
|
|
726
|
-
|
|
871
|
+
// v7
|
|
872
|
+
<SegmentedControl value={value} onChange={handleToggle}>
|
|
873
|
+
<SegmentedControl.Button
|
|
874
|
+
icon={listViewIcon}
|
|
875
|
+
value="list-view"
|
|
876
|
+
aria-label="List View"
|
|
877
|
+
onClick={e => console.log('Existing IconButton onClick callback')}
|
|
878
|
+
/>
|
|
879
|
+
<SegmentedControl.Button
|
|
880
|
+
icon={worksheetsIcon}
|
|
881
|
+
value="table-view"
|
|
882
|
+
aria-label="Table View"
|
|
883
|
+
disabled={true}
|
|
884
|
+
/>
|
|
885
|
+
<SegmentedControl.Button icon={deviceTabletIcon} value="device-view" aria-label="Device View" />
|
|
886
|
+
<SegmentedControl.Button icon={percentageIcon} value="percent-view" aria-label="Percent View" />
|
|
887
|
+
</SegmentedControl>
|
|
888
|
+
```
|
|
727
889
|
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
// hook up to a redux store
|
|
731
|
-
onShow(...params) {
|
|
732
|
-
dispatch(setIsModalOpen(true));
|
|
733
|
-
config?.onShow?.(...params);
|
|
734
|
-
},
|
|
735
|
-
onHide(...params) {
|
|
736
|
-
dispatch(setIsModalOpen(false));
|
|
737
|
-
config?.onShow?.(...params);
|
|
738
|
-
},
|
|
739
|
-
});
|
|
890
|
+
🤖 The codemod will replace all `IconButton` children of `SegmentedControl` with
|
|
891
|
+
`SegmentedControl.Button`.
|
|
740
892
|
|
|
741
|
-
|
|
742
|
-
useReturnFocus(model);
|
|
743
|
-
useFocusTrap(model);
|
|
744
|
-
useCloseOnEscape(model);
|
|
893
|
+
---
|
|
745
894
|
|
|
746
|
-
|
|
747
|
-
...model.state,
|
|
748
|
-
showOverlay,
|
|
749
|
-
};
|
|
895
|
+
### Side Panel
|
|
750
896
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
897
|
+
The `SidePanel` in our Preview package now has a tooltip built in to its toggle button. If you
|
|
898
|
+
currently have a `Tooltip` component wrapping this component, you should remove it. Instead, you'll
|
|
899
|
+
need to provide the appropriate tooltip text to the button based on its state using the following
|
|
900
|
+
new props added to `SidePanel.ToggleButton`:
|
|
754
901
|
|
|
755
|
-
|
|
756
|
-
|
|
902
|
+
```tsx
|
|
903
|
+
/**
|
|
904
|
+
* The tooltip text to expand the side panel
|
|
905
|
+
* @default 'Expand'
|
|
906
|
+
*/
|
|
907
|
+
tooltipTextExpand?: string;
|
|
908
|
+
/**
|
|
909
|
+
* The tooltip text to collapse the side panel
|
|
910
|
+
* @default 'Collapse'
|
|
911
|
+
*/
|
|
912
|
+
tooltipTextCollapse?: string;
|
|
757
913
|
```
|
|
758
914
|
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
```ts
|
|
762
|
-
import {
|
|
763
|
-
useCloseOnEscape,
|
|
764
|
-
useEventMap,
|
|
765
|
-
useFocusTrap,
|
|
766
|
-
useInitialFocus,
|
|
767
|
-
usePopupModel,
|
|
768
|
-
useReturnFocus,
|
|
769
|
-
} from '@workday/canvas-kit-react';
|
|
915
|
+
---
|
|
770
916
|
|
|
771
|
-
|
|
772
|
-
defaultConfig: {
|
|
773
|
-
...usePopupModel.defaultConfig,
|
|
774
|
-
showOverlay: true,
|
|
775
|
-
},
|
|
776
|
-
requiredConfig: usePopupModel.requiredConfig,
|
|
777
|
-
contextOverride: usePopupModel.Context, // needed to make sure this model uses the same context as the popup model, otherwise it will create a new one
|
|
778
|
-
})(config => {
|
|
779
|
-
// `mergeConfig` takes care of the manual merging we were doing earlier
|
|
780
|
-
const model = usePopupModel(
|
|
781
|
-
usePopupModel.mergeConfig(config, {
|
|
782
|
-
// hook up to a redux store
|
|
783
|
-
onShow() {
|
|
784
|
-
dispatch(setIsModalOpen(true));
|
|
785
|
-
},
|
|
786
|
-
onHide() {
|
|
787
|
-
dispatch(setIsModalOpen(false));
|
|
788
|
-
},
|
|
789
|
-
})
|
|
790
|
-
);
|
|
917
|
+
### Status Indicator
|
|
791
918
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
useFocusTrap(model);
|
|
795
|
-
useCloseOnEscape(model);
|
|
919
|
+
Status Indicators currently truncate when they reach their max width of `150px`. After receiving
|
|
920
|
+
requests to increase this value, we've increased it by 33% to `200px`.
|
|
796
921
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
};
|
|
922
|
+
We've also added a `maxWidth` prop to further configure this value if necessary. While this
|
|
923
|
+
increases flexibility, please keep in mind that status text should be short, direct, and preferably
|
|
924
|
+
a single word.
|
|
801
925
|
|
|
802
|
-
|
|
803
|
-
}
|
|
926
|
+
```tsx
|
|
927
|
+
<StatusIndicator label="Slightly Longer Status" type={StatusIndicator.Type.Gray} maxWidth={250} />
|
|
804
928
|
```
|
|
805
929
|
|
|
806
|
-
|
|
807
|
-
focused on your unique logic and less on boilerplate. Unfortunately, this change doesn't have a
|
|
808
|
-
codemod. While possible, this code isn't very common and the codemod would be very complex.
|
|
930
|
+
---
|
|
809
931
|
|
|
810
|
-
|
|
932
|
+
### Tabs
|
|
811
933
|
|
|
812
|
-
|
|
934
|
+
To avoid interference with the HTML `name` attribute, we're now using `data-id` instead of `name`
|
|
935
|
+
for `Tabs.Item`, `Tabs.Panel`, and `Tabs.Menu.Item`.
|
|
813
936
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
-
|
|
817
|
-
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
937
|
+
```tsx
|
|
938
|
+
// v6
|
|
939
|
+
<Tabs.Item name="tabs-item">...</Tabs.Item>
|
|
940
|
+
<Tabs.Panel name="tabs-panel">...</Tabs.Panel>
|
|
941
|
+
<Tabs.Menu.Item name="tabs-menu-item">...</Tabs.Menu.Item>
|
|
942
|
+
|
|
943
|
+
// v7
|
|
944
|
+
<Tabs.Item data-id="tabs-item">...</TabsItem>
|
|
945
|
+
<Tabs.Panel data-id="tabs-panel">...</Tabs.Panel>
|
|
946
|
+
<Tabs.Menu.Item data-id="tabs-menu-item">...</Tabs.Menu.Item>
|
|
947
|
+
```
|
|
821
948
|
|
|
822
|
-
|
|
823
|
-
- Breadcrumbs Dropdown Menu: Depth 2 → Depth 3
|
|
824
|
-
- Menu: Depth 2 → Depth 3
|
|
825
|
-
- Combobox: Depth 1 → Depth 3
|
|
826
|
-
- Popup: Depth 2 → Depth 5
|
|
827
|
-
- Dialog: Depth 2 → Depth 5
|
|
828
|
-
- Color Picker Palette: Depth 2 → Depth 5
|
|
829
|
-
- Toast: Depth 2 → Depth 5
|
|
830
|
-
- Modal: Depth 2 → Depth 6
|
|
831
|
-
- Preview Side Panel (alternate variant): Depth 3 → Depth 6
|
|
949
|
+
🤖 The codemod will handle these changes for you automatically.
|