@workday/canvas-kit-docs 6.0.0-alpha.0-next.31 → 6.0.0-alpha.0-next.37
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/LICENSE +1 -1
- package/dist/commonjs/lib/specs.js +351 -33
- package/dist/es6/lib/specs.js +351 -33
- package/dist/mdx/6.0-MIGRATION-GUIDE.mdx +76 -12
- package/dist/mdx/7.0-MIGRATION-GUIDE.mdx +33 -0
- package/dist/mdx/COMPOUND_COMPONENTS.mdx +31 -30
- package/dist/mdx/CONTRIBUTING.mdx +90 -63
- package/dist/mdx/preview-react/breadcrumbs/Breadcrumbs.mdx +1 -1
- package/dist/mdx/preview-react/form-field/FormField.mdx +27 -0
- package/dist/mdx/preview-react/form-field/examples/Custom.tsx +57 -0
- package/dist/mdx/preview-react/menu/examples/Icons.tsx +1 -1
- package/dist/mdx/preview-react/menu/examples/ManyItems.tsx +1 -1
- package/dist/mdx/preview-react/text-area/TextArea.mdx +122 -0
- package/dist/mdx/preview-react/text-area/examples/Alert.tsx +31 -0
- package/dist/mdx/preview-react/text-area/examples/Basic.tsx +17 -0
- package/dist/mdx/preview-react/text-area/examples/Disabled.tsx +17 -0
- package/dist/mdx/preview-react/text-area/examples/Error.tsx +40 -0
- package/dist/mdx/preview-react/text-area/examples/Grow.tsx +17 -0
- package/dist/mdx/preview-react/text-area/examples/HiddenLabel.tsx +20 -0
- package/dist/mdx/preview-react/text-area/examples/LabelPositionHorizontal.tsx +17 -0
- package/dist/mdx/preview-react/text-area/examples/LabelPositionVertical.tsx +17 -0
- package/dist/mdx/preview-react/text-area/examples/Placeholder.tsx +21 -0
- package/dist/mdx/preview-react/text-area/examples/RefForwarding.tsx +28 -0
- package/dist/mdx/preview-react/text-area/examples/Required.tsx +17 -0
- package/dist/mdx/preview-react/text-area/examples/ResizeConstraints.tsx +22 -0
- package/dist/mdx/{labs-react → preview-react}/text-input/TextInput.mdx +40 -18
- package/dist/mdx/preview-react/text-input/examples/Alert.tsx +40 -0
- package/dist/mdx/{labs-react/text-input/examples/HiddenLabel.tsx → preview-react/text-input/examples/Basic.tsx} +3 -3
- package/dist/mdx/preview-react/text-input/examples/Disabled.tsx +17 -0
- package/dist/mdx/{labs-react → preview-react}/text-input/examples/Error.tsx +6 -9
- package/dist/mdx/preview-react/text-input/examples/Grow.tsx +17 -0
- package/dist/mdx/preview-react/text-input/examples/HiddenLabel.tsx +20 -0
- package/dist/mdx/preview-react/text-input/examples/LabelPositionHorizontal.tsx +17 -0
- package/dist/mdx/preview-react/text-input/examples/LabelPositionVertical.tsx +17 -0
- package/dist/mdx/{labs-react → preview-react}/text-input/examples/LoginForm.tsx +10 -5
- package/dist/mdx/preview-react/text-input/examples/Password.tsx +17 -0
- package/dist/mdx/preview-react/text-input/examples/Placeholder.tsx +17 -0
- package/dist/mdx/{labs-react → preview-react}/text-input/examples/RefForwarding.tsx +7 -6
- package/dist/mdx/preview-react/text-input/examples/Required.tsx +17 -0
- package/dist/mdx/preview-react/text-input/examples/ThemedAlert.tsx +46 -0
- package/dist/mdx/{labs-react → preview-react}/text-input/examples/ThemedError.tsx +8 -11
- package/dist/mdx/react/_examples/GlobalHeader.mdx +9 -0
- package/dist/mdx/react/_examples/PageHeader.mdx +8 -0
- package/dist/mdx/react/_examples/examples/GlobalHeader.tsx +66 -0
- package/dist/mdx/react/_examples/examples/PageHeader.tsx +63 -0
- package/dist/mdx/react/action-bar/ActionBar.mdx +1 -1
- package/dist/mdx/react/banner/Banner.mdx +203 -19
- package/dist/mdx/react/banner/PropTables.splitprops.tsx +39 -0
- package/dist/mdx/react/banner/examples/ActionText.tsx +8 -1
- package/dist/mdx/react/banner/examples/Basic.tsx +8 -1
- package/dist/mdx/react/banner/examples/Error.tsx +8 -1
- package/dist/mdx/react/banner/examples/RefForwarding.tsx +25 -0
- package/dist/mdx/react/banner/examples/Sticky.tsx +15 -7
- package/dist/mdx/react/banner/examples/StickyAnimation.tsx +62 -0
- package/dist/mdx/react/banner/examples/StickyRTL.tsx +38 -0
- package/dist/mdx/react/banner/examples/ThemedAlert.tsx +28 -0
- package/dist/mdx/react/banner/examples/ThemedError.tsx +29 -0
- package/dist/mdx/react/button/button/Button.mdx +7 -7
- package/dist/mdx/react/button/icon-button/IconButton.mdx +1 -1
- package/dist/mdx/react/loading-animation/LoadingAnimation.mdx +5 -0
- package/dist/mdx/react/loading-animation/examples/RTL.tsx +16 -0
- package/dist/mdx/react/pagination/PropTables.splitprops.tsx +47 -0
- package/dist/mdx/react/pagination/examples/{StepControls.tsx → Basic.tsx} +1 -1
- package/dist/mdx/react/pagination/examples/GoToForm.tsx +1 -1
- package/dist/mdx/react/pagination/examples/HoistedModel.tsx +36 -22
- package/dist/mdx/react/pagination/examples/RTL.tsx +1 -1
- package/dist/mdx/react/pagination/pagination.mdx +225 -474
- package/dist/mdx/react/popup/Popup.mdx +34 -36
- package/dist/mdx/react/radio/examples/Alert.tsx +3 -3
- package/dist/mdx/react/radio/examples/Basic.tsx +3 -3
- package/dist/mdx/react/radio/examples/Disabled.tsx +3 -3
- package/dist/mdx/react/radio/examples/Error.tsx +3 -3
- package/dist/mdx/react/radio/examples/LabelPosition.tsx +3 -3
- package/dist/mdx/react/radio/examples/NoValue.tsx +3 -3
- package/dist/mdx/react/radio/examples/RefForwarding.tsx +3 -3
- package/dist/mdx/react/radio/examples/Required.tsx +3 -3
- package/dist/mdx/react/segmented-control/SegmentedControl.mdx +1 -1
- package/dist/mdx/react/tabs/Tabs.mdx +67 -36
- package/dist/mdx/react/tabs/examples/DisabledTab.tsx +1 -1
- package/dist/mdx/react/tabs/examples/DynamicTabs.tsx +41 -13
- package/dist/mdx/react/tabs/examples/HoistedModel.tsx +4 -4
- package/dist/mdx/react/tabs/examples/Icons.tsx +36 -0
- package/dist/mdx/react/tabs/examples/{NamedKeys.tsx → NamedTabs.tsx} +0 -0
- package/dist/mdx/react/tabs/examples/OverflowTabs.tsx +58 -0
- package/dist/mdx/react/tabs/examples/SinglePanel.tsx +1 -1
- package/dist/mdx/react/toast/toast.mdx +1 -17
- package/dist/mdx/react/tooltip/Tooltip.mdx +9 -1
- package/dist/mdx/react/tooltip/examples/DelayedTooltip.tsx +16 -0
- package/dist/mdx/react/tooltip/examples/Ellipsis.tsx +6 -0
- package/package.json +5 -4
- package/dist/mdx/CODE_OF_CONDUCT.md +0 -68
- package/dist/mdx/labs-react/text-input/examples/Alert.tsx +0 -46
- package/dist/mdx/labs-react/text-input/examples/Basic.tsx +0 -20
- package/dist/mdx/labs-react/text-input/examples/Disabled.tsx +0 -20
- package/dist/mdx/labs-react/text-input/examples/Grow.tsx +0 -20
- package/dist/mdx/labs-react/text-input/examples/LabelPosition.tsx +0 -20
- package/dist/mdx/labs-react/text-input/examples/Password.tsx +0 -20
- package/dist/mdx/labs-react/text-input/examples/Placeholder.tsx +0 -20
- package/dist/mdx/labs-react/text-input/examples/Required.tsx +0 -20
- package/dist/mdx/labs-react/text-input/examples/ThemedAlert.tsx +0 -51
- package/dist/mdx/react/pagination/examples/ShowAdditionalDetails.tsx +0 -52
|
@@ -15,6 +15,7 @@ any questions about the update.
|
|
|
15
15
|
- [Depth Tokens](#depth-tokens)
|
|
16
16
|
- [Theme Breakpoint Updates](#theme-breakpoint-updates)
|
|
17
17
|
- [Action Bar](#action-bar)
|
|
18
|
+
- [Tabs Component](#tabs-component)
|
|
18
19
|
- [Button Updates](#button-updates)
|
|
19
20
|
- [Primary Button](#primary-button)
|
|
20
21
|
- [Primary Disabled](#primary-disabled)
|
|
@@ -215,6 +216,9 @@ const CustomGlobalHeader = props => {
|
|
|
215
216
|
};
|
|
216
217
|
```
|
|
217
218
|
|
|
219
|
+
You may continue to use this component exactly as you did in v5, but note that we plan to hard-deprecate it in Canvas Kit v7.
|
|
220
|
+
If you would like to migrate away from this deprecated component now, you can reference [this example](https://workday.github.io/canvas-kit/?path=/story/examples-global-header-react--basic) instead.
|
|
221
|
+
|
|
218
222
|
### Page Header
|
|
219
223
|
|
|
220
224
|
We are [soft-deprecating](#soft-deprecation) `PageHeader`. It has been renamed to
|
|
@@ -266,6 +270,9 @@ export const CustomPageHeader = (props: CustomPageHeaderProps) => {
|
|
|
266
270
|
};
|
|
267
271
|
```
|
|
268
272
|
|
|
273
|
+
You may continue to use this component exactly as you did in v5, but note that we plan to hard-deprecate it in Canvas Kit v7.
|
|
274
|
+
If you would like to migrate away from this deprecated component now, you can reference [this example](https://workday.github.io/canvas-kit/?path=/story/examples-page-header-react--basic) instead.
|
|
275
|
+
|
|
269
276
|
## Component Migrations
|
|
270
277
|
|
|
271
278
|
### Search Bar
|
|
@@ -336,7 +343,7 @@ type CustomDepthValues = CanvasDepthValue;
|
|
|
336
343
|
interface OtherCustomDepthValues extends CanvasDepthValue {}
|
|
337
344
|
|
|
338
345
|
// v6
|
|
339
|
-
import {
|
|
346
|
+
import {CanvasDepthValues} from '@workday/canvas-kit-react/tokens';
|
|
340
347
|
|
|
341
348
|
type CustomDepthValues = CanvasDepthValues;
|
|
342
349
|
interface OtherCustomDepthValues extends CanvasDepthValues {}
|
|
@@ -362,10 +369,10 @@ Below is a reference table for the V5 and V6 breakpoint values.
|
|
|
362
369
|
|
|
363
370
|
Also for reference, these are our viewport ranges:
|
|
364
371
|
|
|
365
|
-
- `small` (320px - 767px) Used for mobile-sized screens
|
|
366
|
-
- `medium` (768px - 1023px) Used for tablet-sized screens
|
|
367
|
-
- `large` - (1024px - 1439px) Used for laptop and small desktop screens
|
|
368
|
-
- `extra-large` (
|
|
372
|
+
- `small` (`320px` - `767px`) Used for mobile-sized screens
|
|
373
|
+
- `medium` (`768px` - `1023px`) Used for tablet-sized screens
|
|
374
|
+
- `large` - (`1024px` - `1439px`) Used for laptop and small desktop screens
|
|
375
|
+
- `extra-large` (`≥1440px`) Used for very large screens
|
|
369
376
|
|
|
370
377
|
### Action Bar
|
|
371
378
|
|
|
@@ -373,13 +380,70 @@ Also for reference, these are our viewport ranges:
|
|
|
373
380
|
`max-width: 575px`. They now use `max-width: 767.5px` – the upper limit of the `small` range. This
|
|
374
381
|
will have two effects for this component:
|
|
375
382
|
|
|
376
|
-
- Container padding will decrease from `s` (16px) to `xxs` (8px) on all viewports
|
|
377
|
-
- This was previously happening only on viewports
|
|
378
|
-
- Button order will be reversed on all viewports
|
|
379
|
-
- This was previously happening only on viewports
|
|
383
|
+
- Container padding will decrease from `s` (`16px`) to `xxs` (`8px`) on all viewports less than `768px` wide
|
|
384
|
+
- This was previously happening only on viewports less than `576px` wide
|
|
385
|
+
- Button order will be reversed on all viewports less than `768px` wide
|
|
386
|
+
- This was previously happening only on viewports less than `576px` wide
|
|
380
387
|
|
|
381
388
|
These changes in behavior are intentional and expected.
|
|
382
389
|
|
|
390
|
+
## Tabs Component
|
|
391
|
+
|
|
392
|
+
The Tabs API changed to support a responsive layout
|
|
393
|
+
([#1325](https://github.com/Workday/canvas-kit/pull/1325)). The model API was updated to support
|
|
394
|
+
more generic behaviors to allow for other components to support responsive layouts using the same
|
|
395
|
+
models and behaviors. The most notable changes were concerning the state and events around tab
|
|
396
|
+
selection. The verb "select" was chosen to more accurately reflect selection for more component
|
|
397
|
+
types. Also selection of lists (which Tabs is based on) can support single or multiple selection.
|
|
398
|
+
Selection is now stored on state as an array of selected keys.
|
|
399
|
+
|
|
400
|
+
```tsx
|
|
401
|
+
// v5
|
|
402
|
+
const model = useTabsModel({
|
|
403
|
+
shouldActivate,
|
|
404
|
+
onActivate,
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
console.log('Selected tab', model.state.activeTab);
|
|
408
|
+
model.events.activate({tab: tabName});
|
|
409
|
+
|
|
410
|
+
// v6
|
|
411
|
+
const model = useTabsModel({
|
|
412
|
+
shouldSelect,
|
|
413
|
+
onSelect,
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
console.log('Selected tab', model.state.selectedKey[0]);
|
|
417
|
+
model.events.select({id: tabName});
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
The Tabs component can now handle responsive containers, but the support is not automatic. You must
|
|
421
|
+
use the dynamic API and provide an overflow menu subcomponent. The dynamic API doesn't know the
|
|
422
|
+
shape of your object, so render props must be used to instruct React how to render each item.
|
|
423
|
+
|
|
424
|
+
```tsx
|
|
425
|
+
// Use `useState` because React will give the same reference each render
|
|
426
|
+
const [items] = React.useState([
|
|
427
|
+
{id: 'first', text: 'First Tab', contents: 'First Tab Content'},
|
|
428
|
+
{id: 'second', text: 'Second Tab', contents: 'Second Tab Content'},
|
|
429
|
+
]);
|
|
430
|
+
|
|
431
|
+
return (
|
|
432
|
+
<Tabs items={items}>
|
|
433
|
+
<Tabs.List overflowButton={<Tabs.OverflowButton>More</Tabs.OverflowButton>}>
|
|
434
|
+
{item => <Tabs.Item name={item.id}>{item.text}</Tabs.Item>}
|
|
435
|
+
</Tabs.List>
|
|
436
|
+
<Tabs.Menu.Popper>
|
|
437
|
+
<Tabs.Menu.Card maxWidth={300} maxHeight={200}>
|
|
438
|
+
<Tabs.Menu.List>
|
|
439
|
+
{(item: MyTabItem) => <Tabs.Menu.Item name={item.id}>{item.text}</Tabs.Menu.Item>}
|
|
440
|
+
</Tabs.Menu.List>
|
|
441
|
+
</Tabs.Menu.Card>
|
|
442
|
+
</Tabs.Menu.Popper>
|
|
443
|
+
</Tabs>
|
|
444
|
+
);
|
|
445
|
+
```
|
|
446
|
+
|
|
383
447
|
## Button Updates
|
|
384
448
|
|
|
385
449
|
All button updates for V6 are limited to our Primary, Secondary, and Tertiary buttons. Most of the
|
|
@@ -413,7 +477,7 @@ All these changes are described in detail by button type in the sections below.
|
|
|
413
477
|
#### Primary Disabled State
|
|
414
478
|
|
|
415
479
|
Previously the button's disabled state had a `blueberry200` background, but it now uses the default
|
|
416
|
-
`blueberry400` and sets the entire button to 40% opacity. This creates more
|
|
480
|
+
`blueberry400` and sets the entire button to 40% opacity. This creates more consistency for the
|
|
417
481
|
disabled states across all our buttons.
|
|
418
482
|
|
|
419
483
|
#### Primary Large
|
|
@@ -431,7 +495,7 @@ height of the button will remain the same.
|
|
|
431
495
|
|
|
432
496
|
#### Primary Small
|
|
433
497
|
|
|
434
|
-
We now support icons for small `PrimaryButton`s. The icons are `20px` x `
|
|
498
|
+
We now support icons for small `PrimaryButton`s. The icons are `20px` x `20px`.
|
|
435
499
|
|
|
436
500
|
#### Primary Extra Small
|
|
437
501
|
|
|
@@ -455,7 +519,7 @@ overall height of the button will remain the same.
|
|
|
455
519
|
|
|
456
520
|
#### Secondary Small
|
|
457
521
|
|
|
458
|
-
We now support icons for small `SecondaryButton`s. The icons are `20px` x `
|
|
522
|
+
We now support icons for small `SecondaryButton`s. The icons are `20px` x `20px`.
|
|
459
523
|
|
|
460
524
|
#### Secondary Extra Small
|
|
461
525
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Canvas Kit 7.0 Migration Guide
|
|
2
|
+
|
|
3
|
+
Below are the breaking changes made in Canvas Kit v7. Please
|
|
4
|
+
[reach out](https://github.com/Workday/canvas-kit/issues/new?labels=bug&template=bug.md) if you have
|
|
5
|
+
any questions about the update.
|
|
6
|
+
|
|
7
|
+
- [Codemod](#codemod)
|
|
8
|
+
|
|
9
|
+
## Codemod
|
|
10
|
+
|
|
11
|
+
Please use our [codemod package](https://github.com/Workday/canvas-kit/tree/master/modules/codemod)
|
|
12
|
+
to automatically update your code to work with a majority of the breaking changes in the migration
|
|
13
|
+
from Canvas Kit v6 to v7:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
> npx @workday/canvas-kit-codemod v7 [path]
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
> Note: This codemod only works on `.js`, `.jsx`, `.ts`, and `.tsx` extensions. You may need to make
|
|
20
|
+
> some manual changes in other file types (`.json`, `.mdx`, `.md`, etc.).
|
|
21
|
+
|
|
22
|
+
> Note: You may need to run your linter after executing the codemod, as it's resulting formatting
|
|
23
|
+
> (spacing, quotes, etc.) may not match your project's styling.
|
|
24
|
+
|
|
25
|
+
**Breaking changes accounted for by this codemod will be marked with a 🤖.**
|
|
26
|
+
|
|
27
|
+
**Please verify all changes made by the codemod. As a safety precaution, we recommend committing the
|
|
28
|
+
changes from the codemod as a single isolated commit (separate from other changes) so you can
|
|
29
|
+
rollback more easily if necessary.**
|
|
30
|
+
|
|
31
|
+
[Let us know](https://github.com/Workday/canvas-kit/issues/new?labels=bug&template=bug.md) if you
|
|
32
|
+
encounter any issues or use cases that we've missed. The `@workday/canvas-kit-codemod` package will
|
|
33
|
+
help us maintain additional codemod transforms to make future migrations easier.
|
|
@@ -78,8 +78,8 @@ const Tabs = ({children, model, ...config}) => {
|
|
|
78
78
|
|
|
79
79
|
## Subcomponents
|
|
80
80
|
|
|
81
|
-
A subcomponent typically follows ARIA roles. For the `Tabs` example, these are the `tablist`,
|
|
82
|
-
|
|
81
|
+
A subcomponent typically follows ARIA roles. For the `Tabs` example, these are the `tablist`, `tab`,
|
|
82
|
+
and `tabpanel` roles. A subcomponent provides direct access to semantic or key elements of a
|
|
83
83
|
compound component. In the `IconButton` example, the icon is not semantic and might be hidden from
|
|
84
84
|
screen readers while the `IconButton.Text` content is instead used for a tooltip and as the
|
|
85
85
|
accessible name while being visibly hidden.
|
|
@@ -175,35 +175,35 @@ Components that directly wrap an element (most of them) will have the following
|
|
|
175
175
|
|
|
176
176
|
Compound components are also made up of [models](#models) that accept [guards](#guards) to
|
|
177
177
|
conditionally prevent state changes and [callbacks](#callbacks) to attach listeners. For example, in
|
|
178
|
-
our Tabs component clicking a Tab will
|
|
179
|
-
|
|
178
|
+
our Tabs component clicking a Tab will select that tab. The `Tabs` container component will accept a
|
|
179
|
+
`shouldSelect` and a `onSelect` for the event called `select`.
|
|
180
180
|
|
|
181
181
|
```tsx
|
|
182
182
|
const MyComponent = () => {
|
|
183
|
-
// `data` is all event data from the `
|
|
183
|
+
// `data` is all event data from the `select` event
|
|
184
184
|
|
|
185
185
|
// `state` is the current state of the `Tabs` component
|
|
186
|
-
const
|
|
187
|
-
// for some reason, we only want to allow
|
|
188
|
-
// Clicking on the first tab will
|
|
186
|
+
const shouldSelect = ({data, state}) => {
|
|
187
|
+
// for some reason, we only want to allow selection the 'first' tab
|
|
188
|
+
// Clicking on the first tab will select it, but clicking on the
|
|
189
189
|
// second tab will do nothing
|
|
190
190
|
return data.tab === 'first' ? true : false;
|
|
191
191
|
|
|
192
192
|
// returning true allows the event to trigger a state change and will
|
|
193
|
-
// also call the `
|
|
193
|
+
// also call the `onSelect` callback
|
|
194
194
|
};
|
|
195
195
|
|
|
196
196
|
// `prevState` is the previous state of the model. Callbacks are called _before_ state has resolved.
|
|
197
197
|
// This means the passed state hasn't updated yet. It also means it is safe to call `setState` without
|
|
198
198
|
// triggering extra renders. `setState` calls will add to React's batching system before a state changes
|
|
199
199
|
// are flushed and render functions are called.
|
|
200
|
-
const
|
|
201
|
-
// called any time the `
|
|
202
|
-
console.log('
|
|
200
|
+
const onSelect = ({data, prevState}) => {
|
|
201
|
+
// called any time the `select` event is triggered
|
|
202
|
+
console.log('onSelect', data, prevState);
|
|
203
203
|
};
|
|
204
204
|
|
|
205
205
|
return (
|
|
206
|
-
<Tabs
|
|
206
|
+
<Tabs shouldSelect={shouldSelect} onSelect={onSelect}>
|
|
207
207
|
<Tabs.List>
|
|
208
208
|
<Tabs.Item name="first">First</Tabs.Item>
|
|
209
209
|
<Tabs.Item name="second">Second</Tabs.Item>
|
|
@@ -324,20 +324,20 @@ const useEllipsisTooltipModel = (config = {}) => {
|
|
|
324
324
|
|
|
325
325
|
Models are meant to be composable. For example, a `TabsModel` uses a `CursorModel` (which itself
|
|
326
326
|
uses `ListModel`) and a `ListModel` for a list of panels. `TabsModel` also keeps track of which tab
|
|
327
|
-
is currently
|
|
327
|
+
is currently selected. This might look like the following:
|
|
328
328
|
|
|
329
329
|
```ts
|
|
330
330
|
const useTabsModel = (config = {}) => {
|
|
331
331
|
// id is used for ARIA attributes
|
|
332
332
|
const id = useUniqueId(config.id);
|
|
333
|
-
const [
|
|
333
|
+
const [selectedTab, setSelectedTab] = React.useState('');
|
|
334
334
|
const cursor = useCursorModel(config);
|
|
335
335
|
const panels = useListModel(config);
|
|
336
336
|
|
|
337
337
|
const state = {
|
|
338
338
|
...cursor.state, // extend the CursorModel state
|
|
339
339
|
id,
|
|
340
|
-
|
|
340
|
+
selectedTab,
|
|
341
341
|
panels: panels.state.items, // we only care about
|
|
342
342
|
};
|
|
343
343
|
|
|
@@ -346,12 +346,12 @@ const useTabsModel = (config = {}) => {
|
|
|
346
346
|
registerPanel: panels.events.registerItem,
|
|
347
347
|
unregisterPanel: panels.events.unregisterItem,
|
|
348
348
|
|
|
349
|
-
|
|
350
|
-
if (config.
|
|
349
|
+
select(data) {
|
|
350
|
+
if (config.shouldSelect?.({data, prevState: state}) === false) {
|
|
351
351
|
return;
|
|
352
352
|
}
|
|
353
|
-
|
|
354
|
-
config.
|
|
353
|
+
setSelectedTab(data.tab);
|
|
354
|
+
config.onSelect?.({data, prevState: state});
|
|
355
355
|
},
|
|
356
356
|
};
|
|
357
357
|
|
|
@@ -362,10 +362,11 @@ const useTabsModel = (config = {}) => {
|
|
|
362
362
|
Model composition allows for components to share functionality with other components. In the Tabs
|
|
363
363
|
example, `ListModel` is in charge of maintaining a list of tab elements. The `CursorModel` is in
|
|
364
364
|
charge of maintaining a current cursor position of the tab list. The `Tabs.List` component uses the
|
|
365
|
-
cursor to allow keyboard navigation of the tabs. The `TabsModel` also maintains the currently
|
|
366
|
-
tab to ensure the correct `TabPanel` is visible. The `TabsModel` is also using a
|
|
367
|
-
maintain a list of tab panels. The `TabsModel` is in charge of composing all this and
|
|
368
|
-
and events to the `Tabs` compound component - coordination state between
|
|
365
|
+
cursor to allow keyboard navigation of the tabs. The `TabsModel` also maintains the currently
|
|
366
|
+
selected tab to ensure the correct `TabPanel` is visible. The `TabsModel` is also using a
|
|
367
|
+
`ListModel` to maintain a list of tab panels. The `TabsModel` is in charge of composing all this and
|
|
368
|
+
providing data and events to the `Tabs` compound component - coordination state between
|
|
369
|
+
subcomponents.
|
|
369
370
|
|
|
370
371
|
Many other components like `Select`, `Breadcrumbs`, or dropdown menus can also use the `ListModel`
|
|
371
372
|
and/or the `CursorModel`. These models could be thought of as abstract models where they do not
|
|
@@ -463,11 +464,11 @@ const TabList = ({children, ...elemProps}) => {
|
|
|
463
464
|
|
|
464
465
|
A container component can either accept model configuration _or_ a model. Passing model
|
|
465
466
|
configuration allows for simpler model configuration of guards, callbacks, or any other model
|
|
466
|
-
configuration. The following example provides an `
|
|
467
|
-
|
|
467
|
+
configuration. The following example provides an `onSelect` callback that fetches some data from the
|
|
468
|
+
server:
|
|
468
469
|
|
|
469
470
|
```tsx
|
|
470
|
-
<Tabs
|
|
471
|
+
<Tabs onSelect={({data}) => fetch('/api/selectTab' + data.id)}>...</Tabs>
|
|
471
472
|
```
|
|
472
473
|
|
|
473
474
|
If you need direct access to a model's state or events, you can hoist the model into your component
|
|
@@ -479,15 +480,15 @@ look like this:
|
|
|
479
480
|
const MyTabs = () => {
|
|
480
481
|
const model = useTabsModel({
|
|
481
482
|
// we can still load data from the server
|
|
482
|
-
|
|
483
|
+
onSelect: ({data}) => fetch('/api/selectTab' + data.id),
|
|
483
484
|
});
|
|
484
485
|
|
|
485
486
|
return (
|
|
486
487
|
<>
|
|
487
488
|
<Tabs model={model}>...</Tabs>
|
|
488
|
-
// direct access to the model's state Currently selected tab: {model.state.
|
|
489
|
+
// direct access to the model's state Currently selected tab: {model.state.selectedTab}
|
|
489
490
|
// Now we can send events directly to the model
|
|
490
|
-
<button onClick={() => model.events.
|
|
491
|
+
<button onClick={() => model.events.select({tab: 'third'})}>Select third tab</button>
|
|
491
492
|
</>
|
|
492
493
|
);
|
|
493
494
|
};
|
|
@@ -5,42 +5,37 @@ part of the community. Before you contribute, please take a moment and look thro
|
|
|
5
5
|
sections:
|
|
6
6
|
|
|
7
7
|
- [Code of Conduct](#code-of-conduct)
|
|
8
|
-
- [
|
|
9
|
-
- [
|
|
10
|
-
- [How to Contribute](#how-to-contribute)
|
|
8
|
+
- [How to Contribute](#how-to-contribute)
|
|
9
|
+
- [Communicate on Issues](#communicate-on-issues)
|
|
11
10
|
- [Git Guidelines](#git-guidelines)
|
|
12
|
-
- [
|
|
11
|
+
- [Branches](#branches)
|
|
12
|
+
- [Commit Message Format](#commit-message-format)
|
|
13
|
+
- [Commit Descriptions](#commit-descriptions)
|
|
14
|
+
- [Pull Requests](#pull-requests)
|
|
15
|
+
- [Developer Experience](#developer-experience)
|
|
16
|
+
- [Yarn and Workspaces](#yarn-and-workspaces)
|
|
17
|
+
- [Storybook](#storybook)
|
|
18
|
+
- [Testing](#testing)
|
|
19
|
+
- [Automation on Commit](#automation-on-commit)
|
|
20
|
+
- [Releases](#releases)
|
|
21
|
+
- [Getting Started Developing](#getting-started-developing)
|
|
13
22
|
- [Creating a Module](#creating-a-module)
|
|
14
23
|
- [Exporting a Module](#exporting-a-module)
|
|
15
24
|
- [Building Modules](#building-modules)
|
|
16
25
|
- [Testing Modules](#testing-modules)
|
|
17
26
|
- [Code Style Guide](#code-style-guide)
|
|
18
|
-
- [Canvas Kit Labs & Preview](#canvas-kit-labs
|
|
27
|
+
- [Canvas Kit Labs & Preview](#canvas-kit-labs--preview)
|
|
19
28
|
- [Editors](#editors)
|
|
29
|
+
- [Contributor License Agreement](#contributor-license-agreement)
|
|
20
30
|
|
|
21
31
|
## Code of Conduct
|
|
22
32
|
|
|
23
33
|
At Workday, we are committed to a culture of integrity, innovation, and fun. That culture extends to
|
|
24
34
|
the community that we are building here through Canvas. By participating in it, you are expected to
|
|
25
|
-
uphold
|
|
26
|
-
and agree to our
|
|
35
|
+
uphold our [Code of Conduct](https://github.com/Workday/canvas-kit/blob/master/CODE_OF_CONDUCT.md)
|
|
36
|
+
and agree to our [Contributor License Agreement](#contributor-license-agreement).
|
|
27
37
|
|
|
28
|
-
##
|
|
29
|
-
|
|
30
|
-
Each Contributor (“You”) represents that such You are legally entitled to submit any Contributions
|
|
31
|
-
in accordance with these terms and by posting a Contribution, you represent that each of Your
|
|
32
|
-
Contribution is Your original creation.
|
|
33
|
-
|
|
34
|
-
You are not expected to provide support for Your Contributions, except to the extent You desire to
|
|
35
|
-
provide support. You may provide support for free, for a fee, or not at all. Unless required by
|
|
36
|
-
applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT
|
|
37
|
-
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any
|
|
38
|
-
warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR
|
|
39
|
-
PURPOSE.
|
|
40
|
-
|
|
41
|
-
## Contributing Guidelines
|
|
42
|
-
|
|
43
|
-
### How to Contribute
|
|
38
|
+
## How to Contribute
|
|
44
39
|
|
|
45
40
|
**Don't hesitate to contribute!** Canvas Kit thrives on open discussion and contribution by anyone
|
|
46
41
|
in the Workday community. Contribution doesn't have to be code-based. Anyone can suggest changes to
|
|
@@ -50,38 +45,25 @@ If you are contributing code, please take a look at the following sections to fa
|
|
|
50
45
|
with how the Canvas Kit repo is organized and run. This will help streamline the pull request
|
|
51
46
|
process. If you have any questions, please reach out!
|
|
52
47
|
|
|
53
|
-
If your contribution is visual or UI-based, please ensure you consult with a designer
|
|
54
|
-
contribution can be evaluated as an end-to-end process.
|
|
55
|
-
|
|
56
|
-
#### Automation on Commit
|
|
57
|
-
|
|
58
|
-
Upon commit, [lint-staged](https://github.com/okonet/lint-staged) will run your staged code through
|
|
59
|
-
[Prettier](https://prettier.io) and [eslint](https://eslint.org).
|
|
48
|
+
If your contribution is visual or UI-based, please ensure you consult with a designer or request a
|
|
49
|
+
maintainer's help so the contribution can be evaluated as an end-to-end process.
|
|
60
50
|
|
|
61
|
-
|
|
51
|
+
### Communicate on Issues
|
|
62
52
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
#### Testing
|
|
72
|
-
|
|
73
|
-
Canvas Kit uses [Jest](https://jestjs.io/) and
|
|
74
|
-
[React Testing Library](https://testing-library.com/docs/react-testing-library/intro) to unit test
|
|
75
|
-
our React components. For more information about our testing strategy and how we write unit tests,
|
|
76
|
-
visit our [Testing Readme](/getting-started/for-developers/resources/testing/)
|
|
77
|
-
|
|
78
|
-
Canvas Kit uses [Cypress](https://cypress.io) for UI tests. For info on why we chose Cypress, visit
|
|
79
|
-
[Why Cypress?](https://github.com/Workday/canvas-kit/tree/master/cypress/WHY_CYPRESS.md) For more
|
|
80
|
-
information about how to write Cypress tests, visit
|
|
81
|
-
[Writing Cypress Tests](https://github.com/Workday/canvas-kit/tree/master/cypress/README.md)
|
|
53
|
+
- Create or identify [an issue](https://github.com/Workday/canvas-kit/issues) to work on
|
|
54
|
+
- New contributors are recommended to start with a
|
|
55
|
+
[good first issue](https://github.com/Workday/canvas-kit/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
|
|
56
|
+
- Ask our team if the issue is relevant or has attention from other developers
|
|
57
|
+
- Communicate if you'd like to work on the issue
|
|
58
|
+
- Ask questions! You have our support, and you will always need more information than what is in the
|
|
59
|
+
issue.
|
|
82
60
|
|
|
83
61
|
### Git Guidelines
|
|
84
62
|
|
|
63
|
+
All development should happen on a personal fork (including maintainers). Fork the
|
|
64
|
+
[repo](https://github.com/Workday/canvas-kit) to your personal account, and create a feature branch
|
|
65
|
+
for each contribution.
|
|
66
|
+
|
|
85
67
|
#### Branches
|
|
86
68
|
|
|
87
69
|
- Create branches for each feature you develop
|
|
@@ -127,18 +109,50 @@ fix: Add missing static class variable to IconButton and Avatar
|
|
|
127
109
|
|
|
128
110
|
#### Pull Requests
|
|
129
111
|
|
|
130
|
-
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
PRs to the personal fork to collaborate with others on a feature.
|
|
112
|
+
- We support creating a Draft Pull Request as soon as you have figured out a working implementation,
|
|
113
|
+
for early feedback. It can later be marked Ready for Review.
|
|
114
|
+
- Open a pull request from a feature branch on your fork against the master branch on the main
|
|
115
|
+
repository
|
|
135
116
|
- When a pull request passes all checks and reviews, a core maintainer merges via Squash and Merge
|
|
136
|
-
with a link back to the PR
|
|
117
|
+
with a link back to the PR
|
|
137
118
|
- The branch will automatically be deleted on merge, but its commits and the branch reference are
|
|
138
|
-
still available via the PR
|
|
119
|
+
still available via the PR
|
|
120
|
+
- When multiple developers collaborate on a PR, project maintainers are able to push commits to fork
|
|
121
|
+
PRs, but other contributors will need to open their own PRs against the personal fork and the
|
|
122
|
+
appropriate feature branch.
|
|
139
123
|
- If you have questions about the above policies, please ask :)
|
|
140
124
|
|
|
141
|
-
|
|
125
|
+
## Developer Experience
|
|
126
|
+
|
|
127
|
+
### Storybook
|
|
128
|
+
|
|
129
|
+
Canvas Kit uses [Storybook](https://storybook.js.org/) for the component development environment.
|
|
130
|
+
|
|
131
|
+
### Yarn and Workspaces
|
|
132
|
+
|
|
133
|
+
Canvas Kit uses Yarn for package management and takes advantage of its support for
|
|
134
|
+
[Workspaces](https://yarnpkg.com/lang/en/docs/workspaces/) to connect all of its different modules
|
|
135
|
+
within a single repository. It is recommended but not required over `npm`, unless you are updating
|
|
136
|
+
dependencies, then it's required.
|
|
137
|
+
|
|
138
|
+
### Testing
|
|
139
|
+
|
|
140
|
+
Canvas Kit uses [Jest](https://jestjs.io/) and
|
|
141
|
+
[React Testing Library](https://testing-library.com/docs/react-testing-library/intro) to unit test
|
|
142
|
+
our React components. For more information about our testing strategy and how we write unit tests,
|
|
143
|
+
visit our [Testing Readme](/getting-started/for-developers/resources/testing/).
|
|
144
|
+
|
|
145
|
+
Canvas Kit uses [Cypress](https://cypress.io) for UI tests. For info on why we chose Cypress, visit
|
|
146
|
+
[Why Cypress?](https://github.com/Workday/canvas-kit/tree/master/cypress/WHY_CYPRESS.md) For more
|
|
147
|
+
information about how to write Cypress tests, visit
|
|
148
|
+
[Writing Cypress Tests](https://github.com/Workday/canvas-kit/tree/master/cypress/README.md).
|
|
149
|
+
|
|
150
|
+
### Automation on Commit
|
|
151
|
+
|
|
152
|
+
Upon commit, [lint-staged](https://github.com/okonet/lint-staged) will run your staged code through
|
|
153
|
+
[Prettier](https://prettier.io) and [eslint](https://eslint.org).
|
|
154
|
+
|
|
155
|
+
### Releases
|
|
142
156
|
|
|
143
157
|
- Releases are prepared by updating package versions with `lerna version`, and updating the
|
|
144
158
|
[changelog](./CHANGELOG.md)
|
|
@@ -148,9 +162,9 @@ fix: Add missing static class variable to IconButton and Avatar
|
|
|
148
162
|
- The GitHub release automatically tags master with the new version, and deploys the new version to
|
|
149
163
|
NPM.
|
|
150
164
|
|
|
151
|
-
## Getting Started
|
|
165
|
+
## Getting Started Developing
|
|
152
166
|
|
|
153
|
-
1. Clone the repository and run `yarn`
|
|
167
|
+
1. Clone the repository from your fork and run `yarn`
|
|
154
168
|
2. Run `yarn start` to start [Storybook](https://storybook.js.org/)
|
|
155
169
|
3. Visit [http://localhost:9001/](http://localhost:9001/)
|
|
156
170
|
|
|
@@ -220,8 +234,8 @@ Canvas Kit Preview is for beta components.
|
|
|
220
234
|
|
|
221
235
|
### Editors
|
|
222
236
|
|
|
223
|
-
|
|
224
|
-
formatting.
|
|
237
|
+
Visual Studio Code is our preferred IDE. Install the Prettier and ESLint plugins for quicker and
|
|
238
|
+
easier formatting.
|
|
225
239
|
|
|
226
240
|
#### Visual Studio Code
|
|
227
241
|
|
|
@@ -230,4 +244,17 @@ Install [prettier-vscode](https://github.com/prettier/prettier-vscode) and
|
|
|
230
244
|
|
|
231
245
|
Consider adding the following options:
|
|
232
246
|
|
|
233
|
-
- [Format on save](https://github.com/prettier/prettier-vscode#format-on-save)
|
|
247
|
+
- [Format on save](https://github.com/prettier/prettier-vscode#format-on-save)
|
|
248
|
+
|
|
249
|
+
## Contributor License Agreement
|
|
250
|
+
|
|
251
|
+
Each Contributor (“You”) represents that such You are legally entitled to submit any Contributions
|
|
252
|
+
in accordance with these terms and by posting a Contribution, you represent that each of Your
|
|
253
|
+
Contribution is Your original creation.
|
|
254
|
+
|
|
255
|
+
You are not expected to provide support for Your Contributions, except to the extent You desire to
|
|
256
|
+
provide support. You may provide support for free, for a fee, or not at all. Unless required by
|
|
257
|
+
applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT
|
|
258
|
+
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any
|
|
259
|
+
warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR
|
|
260
|
+
PURPOSE.
|
|
@@ -46,7 +46,7 @@ you'll need to add `buttonAriaLabel` to `Breadcrumbs.CollapsibleList`.
|
|
|
46
46
|
|
|
47
47
|
<ExampleCodeBlock code={CollapsibleList} />
|
|
48
48
|
|
|
49
|
-
### Right-to-Left
|
|
49
|
+
### Right-to-Left (RTL)
|
|
50
50
|
|
|
51
51
|
Breadcrumbs has bidirectional support out of the box. That means outside of setting the content
|
|
52
52
|
direction in your application's Canvas theme, you don't need to do anything else to make it work.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {Specifications} from '@workday/canvas-kit-docs';
|
|
2
|
+
|
|
3
|
+
import {FormField} from '@workday/canvas-kit-preview-react/form-field';
|
|
4
|
+
|
|
5
|
+
import Custom from './examples/Custom';
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# Canvas Kit Form Field
|
|
9
|
+
|
|
10
|
+
FormField allows users to wrap input components to make them accessible. You usually won't want to
|
|
11
|
+
use FormField directly but instead should use the specific component you need, e.g. `TextInput`.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
yarn add @workday/canvas-kit-preview-react
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Customizing With Behavior Hooks Example
|
|
22
|
+
|
|
23
|
+
If you need full customization you can use the form field behavior hooks to build your own solution.
|
|
24
|
+
It is also easy it work with custom components or third party libraries and get the CKR
|
|
25
|
+
accessibility guarantees by using the `as` prop.
|
|
26
|
+
|
|
27
|
+
<ExampleCodeBlock code={Custom} />
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
useFormFieldHint,
|
|
4
|
+
useFormFieldInput,
|
|
5
|
+
useFormFieldLabel,
|
|
6
|
+
useFormFieldModel,
|
|
7
|
+
useFormFieldOrientation,
|
|
8
|
+
FormFieldModelContext,
|
|
9
|
+
} from '@workday/canvas-kit-preview-react/form-field';
|
|
10
|
+
import {useModelContext} from '@workday/canvas-kit-react/common';
|
|
11
|
+
import {Stack} from '@workday/canvas-kit-labs-react/layout';
|
|
12
|
+
|
|
13
|
+
const Label = ({model, children}) => {
|
|
14
|
+
const localModel = useModelContext(FormFieldModelContext, model);
|
|
15
|
+
const props = useFormFieldLabel(localModel);
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<label {...props}>
|
|
19
|
+
{children}
|
|
20
|
+
{model.state.isRequired ? '*' : ''}
|
|
21
|
+
</label>
|
|
22
|
+
);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const Hint = ({model, children}) => {
|
|
26
|
+
const localModel = useModelContext(FormFieldModelContext, model);
|
|
27
|
+
const props = useFormFieldHint(localModel);
|
|
28
|
+
|
|
29
|
+
return <span {...props}>{children}</span>;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const Input = ({model, ...elementProps}) => {
|
|
33
|
+
const localModel = useModelContext(FormFieldModelContext, model);
|
|
34
|
+
const props = useFormFieldInput(localModel, elementProps);
|
|
35
|
+
|
|
36
|
+
return <input type="text" required={model.state.isRequired ? true : false} {...props} />;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default () => {
|
|
40
|
+
const [value, setValue] = React.useState('');
|
|
41
|
+
|
|
42
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
43
|
+
setValue(event.target.value);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const model = useFormFieldModel({isRequired: true});
|
|
47
|
+
|
|
48
|
+
const layoutProps = useFormFieldOrientation('vertical')
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<Stack {...layoutProps}>
|
|
52
|
+
<Label model={model}>My Custom Field</Label>
|
|
53
|
+
<Input model={model} value={value} onChange={handleChange} />
|
|
54
|
+
<Hint model={model}>You can be anything</Hint>
|
|
55
|
+
</Stack>
|
|
56
|
+
);
|
|
57
|
+
};
|
|
@@ -10,7 +10,7 @@ import {Menu, MenuItem} from '@workday/canvas-kit-preview-react/menu';
|
|
|
10
10
|
|
|
11
11
|
export default () => {
|
|
12
12
|
return (
|
|
13
|
-
<Menu
|
|
13
|
+
<Menu>
|
|
14
14
|
<MenuItem icon={uploadCloudIcon}>First Item</MenuItem>
|
|
15
15
|
<MenuItem icon={setupIcon}>Second Item (with a really really really long label)</MenuItem>
|
|
16
16
|
<MenuItem isDisabled icon={uploadCloudIcon} secondaryIcon={taskContactIcon}>
|
|
@@ -4,7 +4,7 @@ import {Menu, MenuItem} from '@workday/canvas-kit-preview-react/menu';
|
|
|
4
4
|
|
|
5
5
|
export default () => {
|
|
6
6
|
return (
|
|
7
|
-
<Menu
|
|
7
|
+
<Menu>
|
|
8
8
|
{'One Two Three Four Five Six Seven Eight Nine Ten Eleven Twelve Thirteen Fourteen Fifteen'
|
|
9
9
|
.split(' ')
|
|
10
10
|
.map(item => {
|