@workday/canvas-kit-docs 12.0.0-alpha.846-next.0 → 12.0.0-alpha.855-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es6/lib/docs.js +1378 -464
- package/dist/mdx/12.0-UPGRADE-GUIDE.mdx +35 -12
- package/dist/mdx/react/_examples/AriaLiveRegions.mdx +10 -6
- package/dist/mdx/react/_examples/examples/{common → AriaLiveRegions}/FilterListWithLiveStatus.tsx +18 -10
- package/dist/mdx/react/_examples/examples/AriaLiveRegions/HiddenLiveRegion.tsx +46 -0
- package/dist/mdx/react/_examples/examples/AriaLiveRegions/TextInputWithLiveError.tsx +31 -0
- package/dist/mdx/react/_examples/examples/AriaLiveRegions/VisibleLiveRegion.tsx +61 -0
- package/dist/mdx/react/popup/Popup.mdx +13 -2
- package/dist/mdx/react/popup/examples/ExternalWindow.tsx +176 -0
- package/package.json +7 -7
- package/dist/mdx/react/_examples/examples/common/HiddenLiveRegion.tsx +0 -30
- package/dist/mdx/react/_examples/examples/common/TextInputWithLiveError.tsx +0 -25
- package/dist/mdx/react/_examples/examples/common/VisibleLiveRegion.tsx +0 -40
- /package/dist/mdx/react/_examples/examples/{common → AriaLiveRegions}/IconButtonsWithLiveBadges.tsx +0 -0
|
@@ -39,10 +39,11 @@ A note to the reader:
|
|
|
39
39
|
- [Codemod](#codemod)
|
|
40
40
|
- [Deprecations](#deprecations)
|
|
41
41
|
- [Removals](#removals)
|
|
42
|
+
- [InputIconContainer](#inputiconcontainer)
|
|
42
43
|
- [Select (Preview)](#select-preview)
|
|
43
44
|
- [Component Updates](#component-updates)
|
|
44
|
-
- [
|
|
45
|
-
- [
|
|
45
|
+
- [Styling API and CSS Tokens](#styling-api-and-css-tokens)
|
|
46
|
+
- [Text Area](#text-area)
|
|
46
47
|
- [Style Utility Updates](#style-utility-updates)
|
|
47
48
|
- [createStencil](#createstencil)
|
|
48
49
|
- [Troubleshooting](#troubleshooting)
|
|
@@ -56,8 +57,8 @@ A note to the reader:
|
|
|
56
57
|
In v12, all the components listed in this guide have started using our new
|
|
57
58
|
[Canvas Tokens Web](https://workday.github.io/canvas-tokens/?path=/docs/docs-getting-started--docs).
|
|
58
59
|
|
|
59
|
-
In v12 you must add `@workday/canvas-tokens-web` to ensure our components are properly styled and
|
|
60
|
-
variables are defined. For more information on installing and using, please reference our tokens
|
|
60
|
+
In v12 you must add `@workday/canvas-tokens-web` to ensure our components are properly styled and
|
|
61
|
+
the variables are defined. For more information on installing and using, please reference our tokens
|
|
61
62
|
[docs](https://workday.github.io/canvas-tokens/?path=/docs/docs-getting-started--docs).
|
|
62
63
|
|
|
63
64
|
## Deprecations
|
|
@@ -67,13 +68,24 @@ in a future major release. This signals consumers to migrate to a more stable al
|
|
|
67
68
|
deprecated code is removed.
|
|
68
69
|
|
|
69
70
|
## Removals
|
|
70
|
-
|
|
71
|
+
|
|
72
|
+
Removals are deletions from our codebase and you can no longer consume this component. We've either
|
|
73
|
+
promoted or replaced a component or utility.
|
|
71
74
|
|
|
72
75
|
### Select (Preview)
|
|
73
76
|
|
|
74
77
|
**PR:** [#2796](https://github.com/Workday/canvas-kit/pull/2796)
|
|
75
78
|
|
|
76
|
-
We've removed the `Select` component that was in Preview. Please use the compound
|
|
79
|
+
We've removed the `Select` component that was in Preview. Please use the compound
|
|
80
|
+
[Select component from Main](https://workday.github.io/canvas-kit/?path=/docs/components-inputs-select--basic).
|
|
81
|
+
|
|
82
|
+
### InputIconContainer
|
|
83
|
+
|
|
84
|
+
**PR:** [#2838](https://github.com/Workday/canvas-kit/pull/2838)
|
|
85
|
+
|
|
86
|
+
We've removed `InputIconContainer` from Main. Please use
|
|
87
|
+
[InputGroup](https://workday.github.io/canvas-kit/?path=/docs/components-inputs-text-input--icons)
|
|
88
|
+
from Main instead.
|
|
77
89
|
|
|
78
90
|
---
|
|
79
91
|
|
|
@@ -81,6 +93,9 @@ We've removed the `Select` component that was in Preview. Please use the compoun
|
|
|
81
93
|
|
|
82
94
|
### Styling API and CSS Tokens
|
|
83
95
|
|
|
96
|
+
**PRs:** [#2825](https://github.com/Workday/canvas-kit/pull/2825),
|
|
97
|
+
[#2795](https://github.com/Workday/canvas-kit/pull/2795)
|
|
98
|
+
|
|
84
99
|
Several components have been refactored to use our new
|
|
85
100
|
[Canvas Tokens](https://workday.github.io/canvas-tokens/?path=/docs/docs-getting-started--docs) and
|
|
86
101
|
[styling API](https://workday.github.io/canvas-kit/?path=/docs/styling-basics--create-modifiers#createstyles-api).
|
|
@@ -88,24 +103,32 @@ The React interface **has not changed**, but CSS variables are now used for dyna
|
|
|
88
103
|
|
|
89
104
|
The following components are affected:
|
|
90
105
|
|
|
91
|
-
- `Popup`
|
|
92
106
|
- `Dialog`
|
|
93
107
|
- `Modal`
|
|
108
|
+
- `Popup`
|
|
109
|
+
- `TextArea`
|
|
110
|
+
- `TextInput`
|
|
94
111
|
- `Toast`
|
|
95
112
|
|
|
96
113
|
> **Note:** These components also support our new `cs` prop for styling. Learn more about styling
|
|
97
114
|
> with `cs` in our
|
|
98
115
|
> [documentation](https://workday.github.io/canvas-kit/?path=/docs/styling-basics--cs-prop).
|
|
99
116
|
|
|
100
|
-
###
|
|
117
|
+
### Text Area
|
|
101
118
|
|
|
102
|
-
**PR:** [#
|
|
119
|
+
**PR:** [#2825](https://github.com/Workday/canvas-kit/pull/2825)
|
|
103
120
|
|
|
104
|
-
|
|
121
|
+
`TextAreaResizeDirection` is no longer a TypeScript enum, but a JavaScript object. This change does
|
|
122
|
+
not effect runtime at all, but may cause TypeScript errors if you use `TextAreaResizeDirection` as a
|
|
123
|
+
type.
|
|
105
124
|
|
|
106
|
-
|
|
125
|
+
```tsx
|
|
126
|
+
// v11
|
|
127
|
+
interface MyProps { resize?: TextAreaResizeDirection }
|
|
107
128
|
|
|
108
|
-
|
|
129
|
+
// 12 type ValueOf<T> = T[keyof T]; interface MyProps { resize?:
|
|
130
|
+
ValueOf<typeof TextAreaResizeDirection> }
|
|
131
|
+
```
|
|
109
132
|
|
|
110
133
|
## Troubleshooting
|
|
111
134
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import {AriaLiveRegion} from '@workday/canvas-kit-react/common';
|
|
2
|
-
import FilterListWithLiveStatus from './examples/
|
|
3
|
-
import VisibleLiveRegion from './examples/
|
|
4
|
-
import HiddenLiveRegion from './examples/
|
|
5
|
-
import TextInputWithLiveError from './examples/
|
|
6
|
-
import IconButtonsWithLiveBadges from './examples/common/IconButtonsWithLiveBadges';
|
|
2
|
+
import FilterListWithLiveStatus from './examples/AriaLiveRegions/FilterListWithLiveStatus';
|
|
3
|
+
import VisibleLiveRegion from './examples/AriaLiveRegions/VisibleLiveRegion';
|
|
4
|
+
import HiddenLiveRegion from './examples/AriaLiveRegions/HiddenLiveRegion';
|
|
5
|
+
import TextInputWithLiveError from './examples/AriaLiveRegions/TextInputWithLiveError';
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
# ARIA Live Regions
|
|
@@ -56,7 +55,7 @@ experience when moving the keyboard focus to a new element on screen isn't feasi
|
|
|
56
55
|
|
|
57
56
|
In this example, a live region is applied to a short UI text describing the number of items shown in
|
|
58
57
|
the list. As you type characters into the input, listen for the screen reader to automatically
|
|
59
|
-
describe how many items in the list
|
|
58
|
+
describe how many items in the list are shown.
|
|
60
59
|
|
|
61
60
|
<ExampleCodeBlock code={FilterListWithLiveStatus} />
|
|
62
61
|
|
|
@@ -72,4 +71,9 @@ of error conditions. As forms increase in complexity, live regions on each error
|
|
|
72
71
|
increasingly distracting and disruptive to the experience, especially if users are trying to first
|
|
73
72
|
understand the information that is required of them to complete the task.
|
|
74
73
|
|
|
74
|
+
**Note:** The `<AriaLiveRegion>` component is used inside of the `Hint` to ensure the live
|
|
75
|
+
region remains in the browser DOM at all times. The `Hint` is only rendered in the DOM when it
|
|
76
|
+
contains content, so it will not work reliably as a live region for screen readers using the
|
|
77
|
+
`as={AriaLiveRegion}` prop.
|
|
78
|
+
|
|
75
79
|
<ExampleCodeBlock code={TextInputWithLiveError} />
|
package/dist/mdx/react/_examples/examples/{common → AriaLiveRegions}/FilterListWithLiveStatus.tsx
RENAMED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React, {useState} from 'react';
|
|
2
|
-
|
|
3
|
-
import {BodyText, Heading} from '@workday/canvas-kit-react/text';
|
|
2
|
+
|
|
4
3
|
import {AriaLiveRegion} from '@workday/canvas-kit-react/common';
|
|
4
|
+
import {BodyText, Heading} from '@workday/canvas-kit-react/text';
|
|
5
5
|
import {Flex} from '@workday/canvas-kit-react/layout';
|
|
6
|
+
import {FormField} from '@workday/canvas-kit-preview-react/form-field';
|
|
7
|
+
import {TextInput} from '@workday/canvas-kit-react/text-input';
|
|
6
8
|
import {system, base} from '@workday/canvas-tokens-web';
|
|
7
|
-
import {createStyles, px2rem} from '@workday/canvas-kit-styling';
|
|
9
|
+
import {createStyles, cssVar, px2rem} from '@workday/canvas-kit-styling';
|
|
8
10
|
|
|
9
11
|
const fruits = [
|
|
10
12
|
'Apples',
|
|
@@ -23,13 +25,19 @@ const liveRegionStyle = createStyles({
|
|
|
23
25
|
padding: system.space.x2,
|
|
24
26
|
});
|
|
25
27
|
|
|
26
|
-
const listStyles = {
|
|
28
|
+
const listStyles = createStyles({
|
|
29
|
+
paddingLeft: system.space.zero,
|
|
30
|
+
});
|
|
27
31
|
|
|
28
32
|
const listItemStyles = createStyles({
|
|
29
33
|
listStyle: 'none',
|
|
30
34
|
paddingLeft: system.space.zero,
|
|
31
35
|
});
|
|
32
36
|
|
|
37
|
+
const flexStyles = createStyles({
|
|
38
|
+
gap: system.space.x4,
|
|
39
|
+
});
|
|
40
|
+
|
|
33
41
|
let filteredFruits = fruits;
|
|
34
42
|
|
|
35
43
|
export default () => {
|
|
@@ -41,7 +49,7 @@ export default () => {
|
|
|
41
49
|
|
|
42
50
|
return (
|
|
43
51
|
<>
|
|
44
|
-
<Flex
|
|
52
|
+
<Flex cs={flexStyles}>
|
|
45
53
|
<Heading size="small">Fruits</Heading>
|
|
46
54
|
<AriaLiveRegion>
|
|
47
55
|
<BodyText size="small" cs={liveRegionStyle}>
|
|
@@ -49,11 +57,11 @@ export default () => {
|
|
|
49
57
|
</BodyText>
|
|
50
58
|
</AriaLiveRegion>
|
|
51
59
|
</Flex>
|
|
52
|
-
<
|
|
53
|
-
<
|
|
54
|
-
<
|
|
55
|
-
</
|
|
56
|
-
<ul
|
|
60
|
+
<FormField>
|
|
61
|
+
<FormField.Label>Filter Items:</FormField.Label>
|
|
62
|
+
<FormField.Input as={TextInput} value={filter} onChange={handleFilter} />
|
|
63
|
+
</FormField>
|
|
64
|
+
<ul className={listStyles}>
|
|
57
65
|
{filteredFruits.map(i => (
|
|
58
66
|
<BodyText size="small" as="li" cs={listItemStyles} key={i}>
|
|
59
67
|
{i}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import {AccessibleHide, AriaLiveRegion} from '@workday/canvas-kit-react/common';
|
|
4
|
+
import {PrimaryButton} from '@workday/canvas-kit-react/button';
|
|
5
|
+
import {FormField} from '@workday/canvas-kit-preview-react/form-field';
|
|
6
|
+
import {Flex} from '@workday/canvas-kit-react/layout';
|
|
7
|
+
import {Text} from '@workday/canvas-kit-react/text';
|
|
8
|
+
import {TextInput} from '@workday/canvas-kit-react/text-input';
|
|
9
|
+
import {createStyles} from '@workday/canvas-kit-styling';
|
|
10
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
11
|
+
|
|
12
|
+
let liveRegionStr = '';
|
|
13
|
+
|
|
14
|
+
const flexStyles = createStyles({
|
|
15
|
+
gap: system.space.x4,
|
|
16
|
+
alignItems: 'center',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export default () => {
|
|
20
|
+
const [message, setMessage] = React.useState('');
|
|
21
|
+
|
|
22
|
+
function handleChange(e) {
|
|
23
|
+
setMessage(e.target.value);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function handleSendMessage(e) {
|
|
27
|
+
e.preventDefault();
|
|
28
|
+
liveRegionStr = message;
|
|
29
|
+
setMessage('');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<>
|
|
34
|
+
<Flex as="form" aria-label="Hidden Live Region" onSubmit={handleSendMessage} cs={flexStyles}>
|
|
35
|
+
<FormField>
|
|
36
|
+
<FormField.Label>Type your message:</FormField.Label>
|
|
37
|
+
<FormField.Input as={TextInput} onChange={handleChange} value={message} />
|
|
38
|
+
</FormField>
|
|
39
|
+
<PrimaryButton type="submit">Send Message</PrimaryButton>
|
|
40
|
+
</Flex>
|
|
41
|
+
<AriaLiveRegion>
|
|
42
|
+
<Text as={AccessibleHide}>{liveRegionStr}</Text>
|
|
43
|
+
</AriaLiveRegion>
|
|
44
|
+
</>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {AriaLiveRegion, changeFocus} from '@workday/canvas-kit-react/common';
|
|
3
|
+
import {FormField} from '@workday/canvas-kit-preview-react/form-field';
|
|
4
|
+
import {PrimaryButton} from '@workday/canvas-kit-react/button';
|
|
5
|
+
import {TextInput} from '@workday/canvas-kit-react/text-input';
|
|
6
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
7
|
+
import {createStyles} from '@workday/canvas-kit-styling';
|
|
8
|
+
|
|
9
|
+
const hintStyles = createStyles({
|
|
10
|
+
height: system.space.x6,
|
|
11
|
+
});
|
|
12
|
+
export default () => {
|
|
13
|
+
const errMsg = 'Error: First name is required.';
|
|
14
|
+
const [hasError, setHasError] = React.useState('no');
|
|
15
|
+
const inputRef = React.useRef(null);
|
|
16
|
+
const handleBlur = e => setHasError(e.target.value.trim().length === 0 ? 'error' : 'no');
|
|
17
|
+
const handleSubmit = () => hasError && changeFocus(inputRef.current);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<>
|
|
21
|
+
<FormField error={hasError === 'error' ? 'error' : undefined} isRequired={true}>
|
|
22
|
+
<FormField.Label>First Name:</FormField.Label>
|
|
23
|
+
<FormField.Input as={TextInput} onBlur={handleBlur} ref={inputRef} />
|
|
24
|
+
<FormField.Hint cs={hintStyles}>
|
|
25
|
+
<AriaLiveRegion>{hasError === 'error' && errMsg}</AriaLiveRegion>
|
|
26
|
+
</FormField.Hint>
|
|
27
|
+
</FormField>
|
|
28
|
+
<PrimaryButton onClick={handleSubmit}>Continue</PrimaryButton>
|
|
29
|
+
</>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import {AriaLiveRegion} from '@workday/canvas-kit-react/common';
|
|
4
|
+
import {PrimaryButton} from '@workday/canvas-kit-react/button';
|
|
5
|
+
import {FormField} from '@workday/canvas-kit-preview-react/form-field';
|
|
6
|
+
import {Flex} from '@workday/canvas-kit-react/layout';
|
|
7
|
+
import {Text} from '@workday/canvas-kit-react/text';
|
|
8
|
+
import {TextInput} from '@workday/canvas-kit-react/text-input';
|
|
9
|
+
import {system, base} from '@workday/canvas-tokens-web';
|
|
10
|
+
import {createStyles, px2rem, calc} from '@workday/canvas-kit-styling';
|
|
11
|
+
|
|
12
|
+
const liveRegionStyle = createStyles({
|
|
13
|
+
border: `${px2rem(1)} solid ${system.color.border.caution.default}`,
|
|
14
|
+
backgroundColor: system.color.bg.caution.default,
|
|
15
|
+
padding: system.space.x4,
|
|
16
|
+
display: 'block',
|
|
17
|
+
marginBlockStart: system.space.x4,
|
|
18
|
+
marginBlockEnd: system.space.x4,
|
|
19
|
+
width: calc.multiply(system.space.x16, 7),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const flexGapStyles = createStyles({
|
|
23
|
+
gap: system.space.x4,
|
|
24
|
+
alignItems: 'center',
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
let liveRegionStr = 'This is an ARIA Live Region!';
|
|
28
|
+
|
|
29
|
+
export default () => {
|
|
30
|
+
const [message, setMessage] = React.useState('');
|
|
31
|
+
|
|
32
|
+
function handleChange(e) {
|
|
33
|
+
setMessage(e.target.value);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function handleSendMessage(e) {
|
|
37
|
+
e.preventDefault();
|
|
38
|
+
liveRegionStr = message;
|
|
39
|
+
setMessage('');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<>
|
|
44
|
+
<AriaLiveRegion>
|
|
45
|
+
<Text cs={liveRegionStyle}>{liveRegionStr}</Text>
|
|
46
|
+
</AriaLiveRegion>
|
|
47
|
+
<Flex
|
|
48
|
+
as="form"
|
|
49
|
+
aria-label="Visible Live Region"
|
|
50
|
+
onSubmit={handleSendMessage}
|
|
51
|
+
cs={flexGapStyles}
|
|
52
|
+
>
|
|
53
|
+
<FormField>
|
|
54
|
+
<FormField.Label>Type your message:</FormField.Label>
|
|
55
|
+
<FormField.Input as={TextInput} onChange={handleChange} value={message} />
|
|
56
|
+
</FormField>
|
|
57
|
+
<PrimaryButton type="submit">Send Message</PrimaryButton>
|
|
58
|
+
</Flex>
|
|
59
|
+
</>
|
|
60
|
+
);
|
|
61
|
+
};
|
|
@@ -10,6 +10,7 @@ import FocusRedirect from './examples/FocusRedirect';
|
|
|
10
10
|
import FocusTrap from './examples/FocusTrap';
|
|
11
11
|
import RTL from './examples/RTL';
|
|
12
12
|
import CustomTarget from './examples/CustomTarget';
|
|
13
|
+
import ExternalWindow from './examples/ExternalWindow';
|
|
13
14
|
import FullScreen from './examples/FullScreen';
|
|
14
15
|
|
|
15
16
|
|
|
@@ -159,6 +160,16 @@ the popup's stack context when entering/exiting fullscreen.
|
|
|
159
160
|
|
|
160
161
|
<ExampleCodeBlock code={FullScreen} />
|
|
161
162
|
|
|
163
|
+
### Opening an External Window
|
|
164
|
+
|
|
165
|
+
A popup can open an external window. This isn't supported directly. The `Popup.Popper` subcomponent
|
|
166
|
+
is replaced with a custom subcomponent that connects to the Popup model and controls the lifecycle
|
|
167
|
+
of the extenal window. Be sure to connect the `unload` event of both the parent `window` and the
|
|
168
|
+
external child `window` to the lifecycle of the Popup model to prevent memory leaks or zombie
|
|
169
|
+
windows.
|
|
170
|
+
|
|
171
|
+
<ExampleCodeBlock code={ExternalWindow} />
|
|
172
|
+
|
|
162
173
|
### RTL
|
|
163
174
|
|
|
164
175
|
The Popup component automatically handles right-to-left rendering.
|
|
@@ -170,8 +181,8 @@ The Popup component automatically handles right-to-left rendering.
|
|
|
170
181
|
## Component API
|
|
171
182
|
|
|
172
183
|
<>
|
|
173
|
-
<SymbolDoc name="Popper" fileName="/react/" />
|
|
174
|
-
<SymbolDoc name="Popup" fileName="/react/" />
|
|
184
|
+
<SymbolDoc name="Popper" fileName="/react/" />
|
|
185
|
+
<SymbolDoc name="Popup" fileName="/react/" />
|
|
175
186
|
</>
|
|
176
187
|
|
|
177
188
|
## Hooks
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ReactDOM from 'react-dom';
|
|
3
|
+
|
|
4
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
5
|
+
import {createStyles} from '@workday/canvas-kit-styling';
|
|
6
|
+
import {infoIcon} from '@workday/canvas-system-icons-web';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
CanvasProvider,
|
|
10
|
+
ContentDirection,
|
|
11
|
+
createSubcomponent,
|
|
12
|
+
PartialEmotionCanvasTheme,
|
|
13
|
+
useMount,
|
|
14
|
+
useTheme,
|
|
15
|
+
} from '@workday/canvas-kit-react/common';
|
|
16
|
+
import {Tooltip} from '@workday/canvas-kit-react/tooltip';
|
|
17
|
+
import {Popup, usePopupModel} from '@workday/canvas-kit-react/popup';
|
|
18
|
+
import {SecondaryButton} from '@workday/canvas-kit-react/button';
|
|
19
|
+
import {Flex} from '@workday/canvas-kit-react/layout';
|
|
20
|
+
|
|
21
|
+
const mainContentStyles = createStyles({
|
|
22
|
+
padding: system.space.x4,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export interface ExternalWindowPortalProps {
|
|
26
|
+
/**
|
|
27
|
+
* Child components of WindowPortal
|
|
28
|
+
*/
|
|
29
|
+
children: React.ReactNode;
|
|
30
|
+
/**
|
|
31
|
+
* Callback to close the popup
|
|
32
|
+
*/
|
|
33
|
+
onWindowClose?: () => void;
|
|
34
|
+
/**
|
|
35
|
+
* Width of the popup window
|
|
36
|
+
*/
|
|
37
|
+
width?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Height of the popup window
|
|
40
|
+
*/
|
|
41
|
+
height?: number;
|
|
42
|
+
/**
|
|
43
|
+
* The name of the popup window. If another popup opens with the same name, that instance will
|
|
44
|
+
* be reused. Use caution with setting this value
|
|
45
|
+
*/
|
|
46
|
+
target?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function copyAssets(sourceDoc: Document, targetDoc: Document) {
|
|
50
|
+
for (const font of (sourceDoc as any).fonts.values()) {
|
|
51
|
+
(targetDoc as any).fonts.add(font);
|
|
52
|
+
|
|
53
|
+
font.load();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
await (targetDoc as any).fonts.ready;
|
|
57
|
+
|
|
58
|
+
// The current ES lib version doesn't include iterable interfaces, so we cast as an iterable
|
|
59
|
+
for (const styleSheet of sourceDoc.styleSheets as StyleSheetList & Iterable<CSSStyleSheet>) {
|
|
60
|
+
if (styleSheet.cssRules) {
|
|
61
|
+
// text based styles
|
|
62
|
+
const styleEl = targetDoc.createElement('style');
|
|
63
|
+
for (const cssRule of styleSheet.cssRules as CSSRuleList & Iterable<CSSRule>) {
|
|
64
|
+
styleEl.appendChild(targetDoc.createTextNode(cssRule.cssText));
|
|
65
|
+
}
|
|
66
|
+
targetDoc.head.appendChild(styleEl);
|
|
67
|
+
} else if (styleSheet.href) {
|
|
68
|
+
// link based styles
|
|
69
|
+
const linkEl = targetDoc.createElement('link');
|
|
70
|
+
|
|
71
|
+
linkEl.rel = 'stylesheet';
|
|
72
|
+
linkEl.href = styleSheet.href;
|
|
73
|
+
targetDoc.head.appendChild(linkEl);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const ExternalWindowPortal = ({
|
|
79
|
+
children,
|
|
80
|
+
width = 300,
|
|
81
|
+
height = 500,
|
|
82
|
+
target = '',
|
|
83
|
+
onWindowClose,
|
|
84
|
+
}: ExternalWindowPortalProps) => {
|
|
85
|
+
const [portalElement, setPortalElement] = React.useState<HTMLDivElement | null>(null);
|
|
86
|
+
|
|
87
|
+
useMount(() => {
|
|
88
|
+
const newWindow = window.open(
|
|
89
|
+
'', // url
|
|
90
|
+
target,
|
|
91
|
+
`width=${width},height=${height},left=100,top=100,popup=true`
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
if (newWindow) {
|
|
95
|
+
// copy fonts and styles
|
|
96
|
+
copyAssets(document, newWindow.document);
|
|
97
|
+
|
|
98
|
+
const element = newWindow.document.createElement('div');
|
|
99
|
+
newWindow.document.body.appendChild(element);
|
|
100
|
+
setPortalElement(element);
|
|
101
|
+
} else {
|
|
102
|
+
onWindowClose();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const closeWindow = event => {
|
|
106
|
+
onWindowClose();
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
window.addEventListener('unload', closeWindow);
|
|
110
|
+
newWindow?.addEventListener('unload', closeWindow);
|
|
111
|
+
|
|
112
|
+
return () => {
|
|
113
|
+
window.removeEventListener('unload', closeWindow);
|
|
114
|
+
newWindow?.removeEventListener('unload', closeWindow);
|
|
115
|
+
newWindow?.close();
|
|
116
|
+
};
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
if (!portalElement) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return ReactDOM.createPortal(<CanvasProvider>{children}</CanvasProvider>, portalElement);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const PopupExternalWindow = createSubcomponent()({
|
|
127
|
+
displayName: 'Popup.ExternalWindow',
|
|
128
|
+
modelHook: usePopupModel,
|
|
129
|
+
})<ExternalWindowPortalProps>(({children, ...elemProps}, Element, model) => {
|
|
130
|
+
if (model.state.visibility === 'visible') {
|
|
131
|
+
return (
|
|
132
|
+
<ExternalWindowPortal onWindowClose={model.events.hide} {...elemProps}>
|
|
133
|
+
{children}
|
|
134
|
+
</ExternalWindowPortal>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return null;
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
export default () => {
|
|
142
|
+
// useTheme is filling in the Canvas theme object if any keys are missing
|
|
143
|
+
const canvasTheme: PartialEmotionCanvasTheme = useTheme({
|
|
144
|
+
canvas: {
|
|
145
|
+
// Switch to `ContentDirection.RTL` to change direction
|
|
146
|
+
direction: ContentDirection.LTR,
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const model = usePopupModel();
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<CanvasProvider theme={canvasTheme}>
|
|
154
|
+
<>
|
|
155
|
+
<main className={mainContentStyles}>
|
|
156
|
+
<p>Popup that opens a new Operating System Window</p>
|
|
157
|
+
<Popup model={model}>
|
|
158
|
+
<Tooltip title="Open External Window Tooltip">
|
|
159
|
+
<Popup.Target>Open External Window</Popup.Target>
|
|
160
|
+
</Tooltip>
|
|
161
|
+
<PopupExternalWindow>
|
|
162
|
+
<p>External Window Contents! Mouse over the info icon to get a tooltip</p>
|
|
163
|
+
<Flex gap="s">
|
|
164
|
+
<Tooltip title="More information">
|
|
165
|
+
<SecondaryButton icon={infoIcon} />
|
|
166
|
+
</Tooltip>
|
|
167
|
+
<Popup.CloseButton>Close Window</Popup.CloseButton>
|
|
168
|
+
</Flex>
|
|
169
|
+
</PopupExternalWindow>
|
|
170
|
+
</Popup>
|
|
171
|
+
<p>Popup visibility: {model.state.visibility}</p>
|
|
172
|
+
</main>
|
|
173
|
+
</>
|
|
174
|
+
</CanvasProvider>
|
|
175
|
+
);
|
|
176
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workday/canvas-kit-docs",
|
|
3
|
-
"version": "12.0.0-alpha.
|
|
3
|
+
"version": "12.0.0-alpha.855-next.0",
|
|
4
4
|
"description": "Documentation components of Canvas Kit components",
|
|
5
5
|
"author": "Workday, Inc. (https://www.workday.com)",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -44,13 +44,13 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@emotion/styled": "^11.6.0",
|
|
46
46
|
"@storybook/csf": "0.0.1",
|
|
47
|
-
"@workday/canvas-kit-labs-react": "^12.0.0-alpha.
|
|
48
|
-
"@workday/canvas-kit-preview-react": "^12.0.0-alpha.
|
|
49
|
-
"@workday/canvas-kit-react": "^12.0.0-alpha.
|
|
50
|
-
"@workday/canvas-kit-styling": "^12.0.0-alpha.
|
|
47
|
+
"@workday/canvas-kit-labs-react": "^12.0.0-alpha.855-next.0",
|
|
48
|
+
"@workday/canvas-kit-preview-react": "^12.0.0-alpha.855-next.0",
|
|
49
|
+
"@workday/canvas-kit-react": "^12.0.0-alpha.855-next.0",
|
|
50
|
+
"@workday/canvas-kit-styling": "^12.0.0-alpha.855-next.0",
|
|
51
51
|
"@workday/canvas-system-icons-web": "^3.0.0",
|
|
52
52
|
"@workday/canvas-tokens-web": "^2.0.0",
|
|
53
|
-
"markdown-to-jsx": "^
|
|
53
|
+
"markdown-to-jsx": "^7.2.0",
|
|
54
54
|
"ts-node": "^10.9.1"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"mkdirp": "^1.0.3",
|
|
60
60
|
"typescript": "4.2"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "9bf5667e2a94b160d69cb88c2e053d29760a34a9"
|
|
63
63
|
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import React, {useState, useRef} from 'react';
|
|
2
|
-
import {AriaLiveRegion, AccessibleHide} from '@workday/canvas-kit-react/common';
|
|
3
|
-
import {PrimaryButton} from '@workday/canvas-kit-react/button';
|
|
4
|
-
import {TextInput} from '@workday/canvas-kit-preview-react/text-input';
|
|
5
|
-
import {Flex} from '@workday/canvas-kit-react/layout';
|
|
6
|
-
import {system} from '@workday/canvas-tokens-web';
|
|
7
|
-
|
|
8
|
-
export default () => {
|
|
9
|
-
const [message, setMessage] = useState('This is an ARIA Live Region!');
|
|
10
|
-
const inputRef = useRef();
|
|
11
|
-
function handleSendMessage() {
|
|
12
|
-
setMessage(inputRef.current.value);
|
|
13
|
-
inputRef.current.value = '';
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<>
|
|
18
|
-
<Flex gap={`var(${system.space.x4})`} alignItems="flex-end">
|
|
19
|
-
<TextInput orientation="vertical">
|
|
20
|
-
<TextInput.Label>Type your message:</TextInput.Label>
|
|
21
|
-
<TextInput.Field ref={inputRef} />
|
|
22
|
-
</TextInput>
|
|
23
|
-
<PrimaryButton onClick={handleSendMessage}>Send Message</PrimaryButton>
|
|
24
|
-
</Flex>
|
|
25
|
-
<AriaLiveRegion>
|
|
26
|
-
<AccessibleHide>{message}</AccessibleHide>
|
|
27
|
-
</AriaLiveRegion>
|
|
28
|
-
</>
|
|
29
|
-
);
|
|
30
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import React, {useState, useRef} from 'react';
|
|
2
|
-
import {TextInput} from '@workday/canvas-kit-preview-react/text-input';
|
|
3
|
-
import {AriaLiveRegion, changeFocus} from '@workday/canvas-kit-react/common';
|
|
4
|
-
import {PrimaryButton} from '@workday/canvas-kit-react/button';
|
|
5
|
-
|
|
6
|
-
export default () => {
|
|
7
|
-
const errMsg = 'Error: First name is required.';
|
|
8
|
-
const [hasError, setHasError] = useState(false);
|
|
9
|
-
const inputRef = useRef();
|
|
10
|
-
const handleBlur = e => setHasError(e.target.value.trim().length === 0);
|
|
11
|
-
const handleSubmit = () => hasError && changeFocus(inputRef.current);
|
|
12
|
-
|
|
13
|
-
return (
|
|
14
|
-
<>
|
|
15
|
-
<TextInput orientation="vertical" hasError={hasError} isRequired={true}>
|
|
16
|
-
<TextInput.Label>First Name:</TextInput.Label>
|
|
17
|
-
<TextInput.Field onBlur={handleBlur} ref={inputRef} />
|
|
18
|
-
<TextInput.Hint height={'16px'}>
|
|
19
|
-
<AriaLiveRegion>{hasError && errMsg}</AriaLiveRegion>
|
|
20
|
-
</TextInput.Hint>
|
|
21
|
-
</TextInput>
|
|
22
|
-
<PrimaryButton onClick={handleSubmit}>Continue</PrimaryButton>
|
|
23
|
-
</>
|
|
24
|
-
);
|
|
25
|
-
};
|