@workday/canvas-kit-docs 6.1.5 → 6.3.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commonjs/lib/specs.js +1 -1
- package/dist/es6/lib/specs.js +1 -1
- package/dist/mdx/TESTING.mdx +29 -5
- package/dist/mdx/preview-react/menu/examples/ContextMenu.tsx +2 -0
- package/dist/mdx/react/popup/Popup.mdx +62 -0
- package/dist/mdx/react/popup/examples/FullScreen.tsx +115 -0
- package/package.json +3 -3
package/dist/es6/lib/specs.js
CHANGED
package/dist/mdx/TESTING.mdx
CHANGED
|
@@ -29,7 +29,7 @@ do. A "test" simply has to pass. A specification requires meaning.
|
|
|
29
29
|
test('SomeComponent should render correctly', async () => {
|
|
30
30
|
const {getByTestId} = render(<SomeComponent data-testid="test" text="foo" />);
|
|
31
31
|
|
|
32
|
-
const component =
|
|
32
|
+
const component = getByTestId('test');
|
|
33
33
|
|
|
34
34
|
expect(component.textContent).toEqual('foo');
|
|
35
35
|
expect(component.getAttribute('aria-label')).toEqual('foo');
|
|
@@ -53,14 +53,14 @@ describe('SomeComponent', () => {
|
|
|
53
53
|
it('should render the "text" prop as the text', async () => {
|
|
54
54
|
const {getByTestId} = render(<SomeComponent data-testid="test" text="foo" />);
|
|
55
55
|
|
|
56
|
-
const component =
|
|
56
|
+
const component = getByTestId('test');
|
|
57
57
|
expect(component).toHaveTextContent('foo');
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
it('should render the "text" prop as an aria-label for accessibility', async () => {
|
|
61
61
|
const {getByTestId} = render(<SomeComponent data-testid="test" text="foo" />);
|
|
62
62
|
|
|
63
|
-
const component =
|
|
63
|
+
const component = getByTestId('test');
|
|
64
64
|
expect(component).toHaveAttribute('aria-label', 'foo');
|
|
65
65
|
});
|
|
66
66
|
});
|
|
@@ -124,8 +124,8 @@ const {getByTestId} = render(
|
|
|
124
124
|
</SomeComponent>
|
|
125
125
|
);
|
|
126
126
|
|
|
127
|
-
const component =
|
|
128
|
-
const child =
|
|
127
|
+
const component = getByTestId('container');
|
|
128
|
+
const child = getByTestId('test');
|
|
129
129
|
|
|
130
130
|
expect(component).toContainElement(child);
|
|
131
131
|
```
|
|
@@ -136,6 +136,30 @@ specification is met). Also this example will have a more useful failure message
|
|
|
136
136
|
`.toContainElement` has the context that it is expecting an element in another element vs a match of
|
|
137
137
|
a string.
|
|
138
138
|
|
|
139
|
+
### Snapshot tests
|
|
140
|
+
|
|
141
|
+
Canvas Kit does not contain DOM-based snapshot tests and uses [Visual Tests](#visual-tests) instead.
|
|
142
|
+
DOM snapshots failures are often difficult to parse. Humans tend to be better at noticing and
|
|
143
|
+
discerning visual changes than changes to a DOM structure.
|
|
144
|
+
|
|
145
|
+
If your project uses snapshot tests and Canvas Kit, chances are you'll run into issues with changing
|
|
146
|
+
ids and other ARIA attributes. Canvas Kit generates unique ids that are different every time the
|
|
147
|
+
page loads. This can be a problem with snapshot tests. To fix this, you'll need to add special code
|
|
148
|
+
to your test bootstrap file. For example:
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
import {setUniqueSeed, resetUniqueIdCount} from '@workday/canvas-kit-react/common';
|
|
152
|
+
|
|
153
|
+
beforeEach(() => {
|
|
154
|
+
setUniqueSeed('a'); // set a static seed
|
|
155
|
+
resetUniqueIdCount(); // reset the id counter before every test
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
This will ensure snapshot tests have stable ids for each snapshot. It is still possible to get ids
|
|
160
|
+
changing if you add an additional component that uses id generation - subsequent ids will be
|
|
161
|
+
different, but this will prevent snapshot tests that don't have any changes from showing diffs.
|
|
162
|
+
|
|
139
163
|
## Functional tests
|
|
140
164
|
|
|
141
165
|
Canvas Kit uses [Cypress][https://cypress.io] for browser-based behavior testing (additional info:
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
usePopupModel,
|
|
9
9
|
useAlwaysCloseOnOutsideClick,
|
|
10
10
|
useCloseOnEscape,
|
|
11
|
+
useTransferOnFullscreenExit,
|
|
11
12
|
} from '@workday/canvas-kit-react/popup';
|
|
12
13
|
|
|
13
14
|
const ContextMenuTarget = createComponent('div')({
|
|
@@ -40,6 +41,7 @@ export default () => {
|
|
|
40
41
|
|
|
41
42
|
useAlwaysCloseOnOutsideClick(model);
|
|
42
43
|
useCloseOnEscape(model);
|
|
44
|
+
useTransferOnFullscreenExit(model);
|
|
43
45
|
|
|
44
46
|
return (
|
|
45
47
|
<Popup model={model}>
|
|
@@ -9,6 +9,7 @@ import FocusRedirect from './examples/FocusRedirect';
|
|
|
9
9
|
import FocusTrap from './examples/FocusTrap';
|
|
10
10
|
import RTL from './examples/RTL';
|
|
11
11
|
import CustomTarget from './examples/CustomTarget';
|
|
12
|
+
import FullScreen from './examples/FullScreen';
|
|
12
13
|
import {
|
|
13
14
|
PopupModelConfigComponent,
|
|
14
15
|
PopupStateComponent,
|
|
@@ -143,6 +144,25 @@ requires a `label` prop.
|
|
|
143
144
|
|
|
144
145
|
<ExampleCodeBlock code={CustomTarget} />
|
|
145
146
|
|
|
147
|
+
### Full Screen API
|
|
148
|
+
|
|
149
|
+
By default, popups are created as children of the `document.body` element, but the `PopupStack`
|
|
150
|
+
supports the [Fullscreen API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API). When
|
|
151
|
+
fullscreen is entered, the `PopupStack` will automatically create a new stacking context for all
|
|
152
|
+
future popups. Any existing popups will disappear, but not be removed. They disappear because the
|
|
153
|
+
fullscreen API is only showing content within the fullscreen element. There are instances where a
|
|
154
|
+
popup may not close when fullscreen is exited:
|
|
155
|
+
|
|
156
|
+
- The escape key is used to exit fullscreen
|
|
157
|
+
- There is a button to exit fullscreen, but the popup doesn't use `useCloseOnOutsideClick`
|
|
158
|
+
|
|
159
|
+
If fullscreen is exited, popups within the fullscreen stacking context are not removed or
|
|
160
|
+
transferred automatically. If you do not handle this case, the popup may not render correctly. This
|
|
161
|
+
example shows a popup that closes when fullscreen is entered/exited and another popup that transfers
|
|
162
|
+
the popup's stack context when entering/exiting fullscreen.
|
|
163
|
+
|
|
164
|
+
<ExampleCodeBlock code={FullScreen} />
|
|
165
|
+
|
|
146
166
|
### RTL
|
|
147
167
|
|
|
148
168
|
The Popup component automatically handles right-to-left rendering.
|
|
@@ -396,6 +416,15 @@ stack. This is useful for Tooltips or hierarchical menus. Adds a
|
|
|
396
416
|
This should be used with popup elements that should close no matter their position in the stack
|
|
397
417
|
(i.e. Tooltips).
|
|
398
418
|
|
|
419
|
+
### useCloseOnFullscreenExit
|
|
420
|
+
|
|
421
|
+
```ts
|
|
422
|
+
useCloseOnFullscreenExit(model: PopupModel): {}
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
Closes the popup when fullscreen is exited. Entering/exiting fullscreen changes the context of the
|
|
426
|
+
entire screen. This should be added to popup types that are very context sensitive like Tooltips.
|
|
427
|
+
|
|
399
428
|
### useDisableBodyScroll
|
|
400
429
|
|
|
401
430
|
```ts
|
|
@@ -442,6 +471,10 @@ This should be used on popup elements that need to hide content (i.e. Modals).
|
|
|
442
471
|
|
|
443
472
|
### useInitialFocus
|
|
444
473
|
|
|
474
|
+
```ts
|
|
475
|
+
useInitialFocus(model: PopupModel): {}
|
|
476
|
+
```
|
|
477
|
+
|
|
445
478
|
Moves focus within the popup when the popup becomes visible. This is useful for keyboard and screen
|
|
446
479
|
reader users alike. This should be used with [useFocusRedirect](#usefocusredirect) or
|
|
447
480
|
[useFocusTrap](#usefocustrap) for a complete focus management solution.
|
|
@@ -451,12 +484,41 @@ menus, etc.
|
|
|
451
484
|
|
|
452
485
|
### useReturnFocus
|
|
453
486
|
|
|
487
|
+
```ts
|
|
488
|
+
useReturnFocus(model: PopupModel): {}
|
|
489
|
+
```
|
|
490
|
+
|
|
454
491
|
Returns focus to the target element when the popup is hidden. This works well with
|
|
455
492
|
[useInitialFocus](#useinitialfocus). This should be used with [useFocusRedirect](#usefocusredirect)
|
|
456
493
|
or [useFocusTrap](#usefocustrap) for a complete focus management solution.
|
|
457
494
|
|
|
458
495
|
This should ble used on popup elements that use [useInitialFocus](#useinitialfocus).
|
|
459
496
|
|
|
497
|
+
### useTransferOnFullscreenEnter
|
|
498
|
+
|
|
499
|
+
```ts
|
|
500
|
+
useTransferOnFullscreenEnter(model: PopupModel): {}
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
Makes the popup transfer to the fullscreen element when fullscreen is entered. Without this, the
|
|
504
|
+
popup would seem to disappear because the popup container element is not a child of the fullscreen
|
|
505
|
+
element.
|
|
506
|
+
|
|
507
|
+
Don't use this in conjunction with a hook that will close the popup when entering fullscreen. Doing
|
|
508
|
+
so would open the popup when the intention was to close it.
|
|
509
|
+
|
|
510
|
+
### useTransferOnFullscreenExit
|
|
511
|
+
|
|
512
|
+
```ts
|
|
513
|
+
useTransferOnFullscreenExit(model: PopupModel): {}
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
Makes the popup transfer to fullscreen when fullscreen is exited. Without this hook, the popup would
|
|
517
|
+
not operate correctly with other popups on the screen.
|
|
518
|
+
|
|
519
|
+
Don't use this in conjunction with a hook that will close the popup when exiting fullscreen. Doing
|
|
520
|
+
so would open the popup when the intention was to close it.
|
|
521
|
+
|
|
460
522
|
### usePopupPopper
|
|
461
523
|
|
|
462
524
|
```ts
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import {SecondaryButton} from '@workday/canvas-kit-react/button';
|
|
4
|
+
import {
|
|
5
|
+
Popup,
|
|
6
|
+
useCloseOnEscape,
|
|
7
|
+
useCloseOnOutsideClick,
|
|
8
|
+
useFocusTrap,
|
|
9
|
+
useInitialFocus,
|
|
10
|
+
useReturnFocus,
|
|
11
|
+
usePopupModel,
|
|
12
|
+
useCloseOnFullscreenExit,
|
|
13
|
+
useTransferOnFullscreenExit,
|
|
14
|
+
useTransferOnFullscreenEnter,
|
|
15
|
+
} from '@workday/canvas-kit-react/popup';
|
|
16
|
+
import {HStack, Flex} from '@workday/canvas-kit-labs-react/layout';
|
|
17
|
+
import {useIsFullscreen} from '@workday/canvas-kit-react/common';
|
|
18
|
+
import screenfull from 'screenfull';
|
|
19
|
+
|
|
20
|
+
const SelfClosePopup = () => {
|
|
21
|
+
const model = usePopupModel();
|
|
22
|
+
|
|
23
|
+
useCloseOnOutsideClick(model);
|
|
24
|
+
useCloseOnEscape(model);
|
|
25
|
+
useInitialFocus(model);
|
|
26
|
+
useReturnFocus(model);
|
|
27
|
+
useFocusTrap(model);
|
|
28
|
+
useCloseOnFullscreenExit(model);
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Popup model={model}>
|
|
32
|
+
<Popup.Target>Open Self-close Popup</Popup.Target>
|
|
33
|
+
<Popup.Popper>
|
|
34
|
+
<Popup.Card width={400} padding="s">
|
|
35
|
+
<Popup.CloseIcon aria-label="Close" />
|
|
36
|
+
<Popup.Heading>Self-close Popup</Popup.Heading>
|
|
37
|
+
<Popup.Body>
|
|
38
|
+
<p>
|
|
39
|
+
When in fullscreen, the escape key will be highjacked by the browser to exit
|
|
40
|
+
fullscreen and <code>useCloseOnEscape</code> hook will not receive the escape key. To
|
|
41
|
+
close when fullscreen is exited, use the <code>useCloseOnFullscreenExit</code> hook.
|
|
42
|
+
</p>
|
|
43
|
+
</Popup.Body>
|
|
44
|
+
<Popup.CloseButton>Close</Popup.CloseButton>
|
|
45
|
+
</Popup.Card>
|
|
46
|
+
</Popup.Popper>
|
|
47
|
+
</Popup>
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const TransferClosePopup = () => {
|
|
52
|
+
const model = usePopupModel();
|
|
53
|
+
|
|
54
|
+
useCloseOnEscape(model);
|
|
55
|
+
useInitialFocus(model);
|
|
56
|
+
useReturnFocus(model);
|
|
57
|
+
useFocusTrap(model);
|
|
58
|
+
useTransferOnFullscreenEnter(model);
|
|
59
|
+
useTransferOnFullscreenExit(model);
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<Popup model={model}>
|
|
63
|
+
<Popup.Target>Open Transfer Popup</Popup.Target>
|
|
64
|
+
<Popup.Popper>
|
|
65
|
+
<Popup.Card width={400} padding="s">
|
|
66
|
+
<Popup.CloseIcon aria-label="Close" />
|
|
67
|
+
<Popup.Heading>Transfer Popup</Popup.Heading>
|
|
68
|
+
<Popup.Body>
|
|
69
|
+
<p>
|
|
70
|
+
When in fullscreen, the escape key will be highjacked by the browser to exit
|
|
71
|
+
fullscreen and <code>useCloseOnEscape</code> hook will not receive the escape key. To
|
|
72
|
+
close when fullscreen is exited, use the <code>useTransferOnFullscreenExit</code>{' '}
|
|
73
|
+
hook.
|
|
74
|
+
</p>
|
|
75
|
+
</Popup.Body>
|
|
76
|
+
<Popup.CloseButton>Close</Popup.CloseButton>
|
|
77
|
+
</Popup.Card>
|
|
78
|
+
</Popup.Popper>
|
|
79
|
+
</Popup>
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export default () => {
|
|
84
|
+
// you could make this a hook depending on which fullscreen library your application uses
|
|
85
|
+
const fullscreenElementRef = React.useRef<HTMLDivElement>();
|
|
86
|
+
const isFullscreen = useIsFullscreen();
|
|
87
|
+
|
|
88
|
+
const enterFullScreen = () => {
|
|
89
|
+
screenfull.request(fullscreenElementRef.current);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const exitFullscreen = () => {
|
|
93
|
+
screenfull.exit();
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<>
|
|
98
|
+
<SecondaryButton onClick={enterFullScreen}>Open Fullscreen</SecondaryButton>
|
|
99
|
+
<Flex
|
|
100
|
+
ref={fullscreenElementRef}
|
|
101
|
+
alignItems="center"
|
|
102
|
+
justifyContent="center"
|
|
103
|
+
background="white"
|
|
104
|
+
>
|
|
105
|
+
<HStack spacing="s">
|
|
106
|
+
<SelfClosePopup />
|
|
107
|
+
<TransferClosePopup />
|
|
108
|
+
{isFullscreen ? (
|
|
109
|
+
<SecondaryButton onClick={exitFullscreen}>Exit fullscreen</SecondaryButton>
|
|
110
|
+
) : null}
|
|
111
|
+
</HStack>
|
|
112
|
+
</Flex>
|
|
113
|
+
</>
|
|
114
|
+
);
|
|
115
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workday/canvas-kit-docs",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.3.0-next.0+6e10a940",
|
|
4
4
|
"description": "Documentation components of Canvas Kit components",
|
|
5
5
|
"author": "Workday, Inc. (https://www.workday.com)",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
],
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@storybook/csf": "0.0.1",
|
|
53
|
-
"@workday/canvas-kit-react": "^6.
|
|
53
|
+
"@workday/canvas-kit-react": "^6.3.0-next.0+6e10a940"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"fs-extra": "^10.0.0",
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"mkdirp": "^1.0.3",
|
|
59
59
|
"typescript": "^3.8.3"
|
|
60
60
|
},
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "6e10a940283828fb6e34b23598a917a478bbabd6"
|
|
62
62
|
}
|