@workday/canvas-kit-docs 17.0.0-alpha.0619-next.0 → 17.0.0-alpha.0623-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/specs.js +62 -0
- package/dist/es6/lib/stackblitzFiles/packageJSONFile.js +5 -5
- package/dist/es6/lib/stackblitzFiles/packageJSONFile.ts +5 -5
- package/dist/mdx/react/button/Toolbar.mdx +54 -0
- package/dist/mdx/react/button/examples/TextFormattingToolbar.tsx +172 -0
- package/package.json +6 -6
package/dist/es6/lib/specs.js
CHANGED
|
@@ -7077,6 +7077,68 @@ module.exports = {specifications: [
|
|
|
7077
7077
|
}
|
|
7078
7078
|
]
|
|
7079
7079
|
},
|
|
7080
|
+
{
|
|
7081
|
+
"type": "file",
|
|
7082
|
+
"name": "Toolbar",
|
|
7083
|
+
"children": [
|
|
7084
|
+
{
|
|
7085
|
+
"type": "describe",
|
|
7086
|
+
"name": "Toolbar",
|
|
7087
|
+
"children": [
|
|
7088
|
+
{
|
|
7089
|
+
"type": "describe",
|
|
7090
|
+
"name": "given the Text Formatting toolbar is rendered",
|
|
7091
|
+
"children": [
|
|
7092
|
+
{
|
|
7093
|
+
"type": "it",
|
|
7094
|
+
"name": "should not have any axe errors"
|
|
7095
|
+
},
|
|
7096
|
+
{
|
|
7097
|
+
"type": "describe",
|
|
7098
|
+
"name": "when focus is on the Text Style select",
|
|
7099
|
+
"children": [
|
|
7100
|
+
{
|
|
7101
|
+
"type": "it",
|
|
7102
|
+
"name": "should move focus through the toolbar with the arrow keys"
|
|
7103
|
+
},
|
|
7104
|
+
{
|
|
7105
|
+
"type": "describe",
|
|
7106
|
+
"name": "when the down arrow key is pressed",
|
|
7107
|
+
"children": [
|
|
7108
|
+
{
|
|
7109
|
+
"type": "it",
|
|
7110
|
+
"name": "should show the text style options"
|
|
7111
|
+
}
|
|
7112
|
+
]
|
|
7113
|
+
}
|
|
7114
|
+
]
|
|
7115
|
+
},
|
|
7116
|
+
{
|
|
7117
|
+
"type": "describe",
|
|
7118
|
+
"name": "when the Bold button is clicked",
|
|
7119
|
+
"children": [
|
|
7120
|
+
{
|
|
7121
|
+
"type": "it",
|
|
7122
|
+
"name": "should toggle the button on"
|
|
7123
|
+
}
|
|
7124
|
+
]
|
|
7125
|
+
},
|
|
7126
|
+
{
|
|
7127
|
+
"type": "describe",
|
|
7128
|
+
"name": "when the Link button is clicked",
|
|
7129
|
+
"children": [
|
|
7130
|
+
{
|
|
7131
|
+
"type": "it",
|
|
7132
|
+
"name": "should open the link dialog with its text fields"
|
|
7133
|
+
}
|
|
7134
|
+
]
|
|
7135
|
+
}
|
|
7136
|
+
]
|
|
7137
|
+
}
|
|
7138
|
+
]
|
|
7139
|
+
}
|
|
7140
|
+
]
|
|
7141
|
+
},
|
|
7080
7142
|
{
|
|
7081
7143
|
"type": "file",
|
|
7082
7144
|
"name": "Tooltip",
|
|
@@ -18,11 +18,11 @@ export const packageJSONFile = `{
|
|
|
18
18
|
"@emotion/react": "11.11.4",
|
|
19
19
|
"@types/react": "18.2.60",
|
|
20
20
|
"@types/react-dom": "18.2.19",
|
|
21
|
-
"@workday/canvas-kit-labs-react": "16.1.
|
|
22
|
-
"@workday/canvas-kit-preview-react": "16.1.
|
|
23
|
-
"@workday/canvas-kit-react": "16.1.
|
|
24
|
-
"@workday/canvas-kit-react-fonts": "^16.1.
|
|
25
|
-
"@workday/canvas-kit-styling": "16.1.
|
|
21
|
+
"@workday/canvas-kit-labs-react": "16.1.5",
|
|
22
|
+
"@workday/canvas-kit-preview-react": "16.1.5",
|
|
23
|
+
"@workday/canvas-kit-react": "16.1.5",
|
|
24
|
+
"@workday/canvas-kit-react-fonts": "^16.1.5",
|
|
25
|
+
"@workday/canvas-kit-styling": "16.1.5",
|
|
26
26
|
"@workday/canvas-system-icons-web": "^5.0.3",
|
|
27
27
|
"@workday/canvas-expressive-icons-web": "1.0.1",
|
|
28
28
|
"@workday/canvas-tokens-web": "4.4.0-beta.11"
|
|
@@ -19,11 +19,11 @@ export const packageJSONFile = `{
|
|
|
19
19
|
"@emotion/react": "11.11.4",
|
|
20
20
|
"@types/react": "18.2.60",
|
|
21
21
|
"@types/react-dom": "18.2.19",
|
|
22
|
-
"@workday/canvas-kit-labs-react": "16.1.
|
|
23
|
-
"@workday/canvas-kit-preview-react": "16.1.
|
|
24
|
-
"@workday/canvas-kit-react": "16.1.
|
|
25
|
-
"@workday/canvas-kit-react-fonts": "^16.1.
|
|
26
|
-
"@workday/canvas-kit-styling": "16.1.
|
|
22
|
+
"@workday/canvas-kit-labs-react": "16.1.5",
|
|
23
|
+
"@workday/canvas-kit-preview-react": "16.1.5",
|
|
24
|
+
"@workday/canvas-kit-react": "16.1.5",
|
|
25
|
+
"@workday/canvas-kit-react-fonts": "^16.1.5",
|
|
26
|
+
"@workday/canvas-kit-styling": "16.1.5",
|
|
27
27
|
"@workday/canvas-system-icons-web": "^5.0.3",
|
|
28
28
|
"@workday/canvas-expressive-icons-web": "1.0.1",
|
|
29
29
|
"@workday/canvas-tokens-web": "4.4.0-beta.11"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {ExampleCodeBlock, Specifications, SymbolDoc} from '@workday/canvas-kit-docs';
|
|
2
|
+
import TextFormattingToolbar from './examples/TextFormattingToolbar';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# Canvas Kit Toolbar
|
|
6
|
+
|
|
7
|
+
Canvas Kit does not ship a Toolbar component. Build one by composing
|
|
8
|
+
[`ToolbarIconButton`](?path=/docs/components-buttons--docs),
|
|
9
|
+
[Select](?path=/docs/components-inputs-select--docs),
|
|
10
|
+
[Tooltip](?path=/docs/components-popups-tooltip--docs), and
|
|
11
|
+
[Dialog](?path=/docs/components-popups-dialog--docs) inside a group that uses the
|
|
12
|
+
[collection system](?path=/docs/features-collections--docs) for keyboard navigation.
|
|
13
|
+
|
|
14
|
+
The example below follows the
|
|
15
|
+
[W3C Toolbar pattern](https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/): one tab stop for the
|
|
16
|
+
group, and arrow keys to move between controls.
|
|
17
|
+
|
|
18
|
+
## Basic Example
|
|
19
|
+
|
|
20
|
+
The Text Formatting toolbar is a horizontal group of five controls:
|
|
21
|
+
|
|
22
|
+
1. **Text Style** — a `Select` with Normal Text, Heading 1, Heading 2, and Heading 3. Normal Text
|
|
23
|
+
starts selected.
|
|
24
|
+
2. **Bold, Italic, and Underline** — `ToolbarIconButton` toggles. `toggled` sets `aria-pressed`. The
|
|
25
|
+
example adds a brand border while a toggle is on, on top of the button's pressed background.
|
|
26
|
+
3. **Insert Link** — a `ToolbarIconButton` used as `Dialog.Target`. The dialog is non-modal and
|
|
27
|
+
contains Link Text and URL fields. Focus moves to Link Text when it opens.
|
|
28
|
+
|
|
29
|
+
Each control is the single child of a `Tooltip`. The default tooltip type is `label`, so the `title`
|
|
30
|
+
becomes that control's accessible name. Do not also set `aria-label` on the control.
|
|
31
|
+
|
|
32
|
+
The group itself is named with `aria-label="Text Formatting"` on an element with `role="toolbar"`.
|
|
33
|
+
|
|
34
|
+
Keyboard movement comes from `useListModel` with `orientation="horizontal"` and
|
|
35
|
+
`navigation={navigationManager}`. `navigationManager` stops at the first and last control instead of
|
|
36
|
+
wrapping. Each control registers with `useListItemRovingFocus` and `useListItemRegister`, which
|
|
37
|
+
keeps a single tab stop and moves it with the arrow keys. Give every control a stable `data-id`.
|
|
38
|
+
|
|
39
|
+
The Text Style `Select` has its own arrow-key behavior. Left and Right move through the toolbar only
|
|
40
|
+
while its menu is closed. While the menu is open, Left and Right do nothing, and Home and End move
|
|
41
|
+
within the menu.
|
|
42
|
+
|
|
43
|
+
<ExampleCodeBlock code={TextFormattingToolbar} />
|
|
44
|
+
|
|
45
|
+
## Component API
|
|
46
|
+
|
|
47
|
+
`ToolbarIconButton` is the icon button used inside the example. The toolbar container, roving tab
|
|
48
|
+
stop, and link dialog are composed in the example. They are not separate exported components.
|
|
49
|
+
|
|
50
|
+
<SymbolDoc name="ToolbarIconButton" fileName="/react/" />
|
|
51
|
+
|
|
52
|
+
## Specifications
|
|
53
|
+
|
|
54
|
+
<Specifications file="./cypress/component/Toolbar.spec.tsx" name="Toolbar" />
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
PrimaryButton,
|
|
5
|
+
ToolbarIconButton,
|
|
6
|
+
ToolbarIconButtonProps,
|
|
7
|
+
} from '@workday/canvas-kit-react/button';
|
|
8
|
+
import {
|
|
9
|
+
navigationManager,
|
|
10
|
+
useListItemRegister,
|
|
11
|
+
useListItemRovingFocus,
|
|
12
|
+
useListModel,
|
|
13
|
+
} from '@workday/canvas-kit-react/collection';
|
|
14
|
+
import {
|
|
15
|
+
composeHooks,
|
|
16
|
+
createContainer,
|
|
17
|
+
createSubcomponent,
|
|
18
|
+
useUniqueId,
|
|
19
|
+
} from '@workday/canvas-kit-react/common';
|
|
20
|
+
import {Dialog, useDialogModel} from '@workday/canvas-kit-react/dialog';
|
|
21
|
+
import {FormField} from '@workday/canvas-kit-react/form-field';
|
|
22
|
+
import {Select, useSelectModel} from '@workday/canvas-kit-react/select';
|
|
23
|
+
import {TextInput} from '@workday/canvas-kit-react/text-input';
|
|
24
|
+
import {Tooltip} from '@workday/canvas-kit-react/tooltip';
|
|
25
|
+
import {CSProps, createStyles, handleCsProp} from '@workday/canvas-kit-styling';
|
|
26
|
+
import {boldIcon, italicsIcon, linkIcon, underlineIcon} from '@workday/canvas-system-icons-web';
|
|
27
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
28
|
+
|
|
29
|
+
const textStyles = [
|
|
30
|
+
{id: 'normal', text: 'Normal Text'},
|
|
31
|
+
{id: 'heading-1', text: 'Heading 1'},
|
|
32
|
+
{id: 'heading-2', text: 'Heading 2'},
|
|
33
|
+
{id: 'heading-3', text: 'Heading 3'},
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
const toolbarStyles = createStyles({
|
|
37
|
+
display: 'flex',
|
|
38
|
+
alignItems: 'center',
|
|
39
|
+
gap: system.gap.sm,
|
|
40
|
+
padding: system.padding.sm,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const toggledToolbarButtonStyles = createStyles({
|
|
44
|
+
"&[aria-pressed='true'], &[aria-pressed='true']:hover, &[aria-pressed='true']:active, &[aria-pressed='true']:focus-visible":
|
|
45
|
+
{
|
|
46
|
+
borderColor: system.color.brand.border.primary,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const useToolbarItem = composeHooks(useListItemRovingFocus, useListItemRegister);
|
|
51
|
+
|
|
52
|
+
const Toolbar = createContainer('div')({
|
|
53
|
+
displayName: 'TextFormattingToolbar',
|
|
54
|
+
modelHook: useListModel,
|
|
55
|
+
})<CSProps>((elemProps, Element) => {
|
|
56
|
+
return (
|
|
57
|
+
<Element
|
|
58
|
+
{...handleCsProp(elemProps, toolbarStyles)}
|
|
59
|
+
role="toolbar"
|
|
60
|
+
aria-label="Text Formatting"
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const ToolbarButton = createSubcomponent(ToolbarIconButton)({
|
|
66
|
+
displayName: 'TextFormattingToolbar.Button',
|
|
67
|
+
modelHook: useListModel,
|
|
68
|
+
elemPropsHook: useToolbarItem,
|
|
69
|
+
})<ToolbarIconButtonProps>((elemProps, Element) => {
|
|
70
|
+
return <Element {...elemProps} />;
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const TextStyleSelect = ({toolbarModel}: {toolbarModel: ReturnType<typeof useListModel>}) => {
|
|
74
|
+
const selectModel = useSelectModel({
|
|
75
|
+
items: textStyles,
|
|
76
|
+
initialSelectedIds: ['normal'],
|
|
77
|
+
});
|
|
78
|
+
const {onKeyDown: onToolbarKeyDown, ...toolbarItemProps} = useToolbarItem(toolbarModel, {
|
|
79
|
+
'data-id': 'text-style',
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<Select model={selectModel}>
|
|
84
|
+
<Tooltip title="Text Style">
|
|
85
|
+
<Select.Input
|
|
86
|
+
{...toolbarItemProps}
|
|
87
|
+
onKeyDown={event => {
|
|
88
|
+
if (selectModel.state.visibility === 'hidden') {
|
|
89
|
+
onToolbarKeyDown(event);
|
|
90
|
+
}
|
|
91
|
+
}}
|
|
92
|
+
/>
|
|
93
|
+
</Tooltip>
|
|
94
|
+
<Select.Popper>
|
|
95
|
+
<Select.Card>
|
|
96
|
+
<Select.List>{item => <Select.Item>{item.text}</Select.Item>}</Select.List>
|
|
97
|
+
</Select.Card>
|
|
98
|
+
</Select.Popper>
|
|
99
|
+
</Select>
|
|
100
|
+
);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export default () => {
|
|
104
|
+
const toolbarModel = useListModel({
|
|
105
|
+
orientation: 'horizontal',
|
|
106
|
+
navigation: navigationManager,
|
|
107
|
+
});
|
|
108
|
+
const linkButtonId = useUniqueId();
|
|
109
|
+
const linkTextRef = React.useRef<HTMLInputElement>(null);
|
|
110
|
+
const dialogModel = useDialogModel({initialFocusRef: linkTextRef});
|
|
111
|
+
const [formats, setFormats] = React.useState({
|
|
112
|
+
bold: false,
|
|
113
|
+
italic: false,
|
|
114
|
+
underline: false,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<Toolbar model={toolbarModel}>
|
|
119
|
+
<TextStyleSelect toolbarModel={toolbarModel} />
|
|
120
|
+
<Tooltip title="Bold">
|
|
121
|
+
<ToolbarButton
|
|
122
|
+
cs={toggledToolbarButtonStyles}
|
|
123
|
+
data-id="bold"
|
|
124
|
+
icon={boldIcon}
|
|
125
|
+
toggled={formats.bold}
|
|
126
|
+
onClick={() => setFormats(formats => ({...formats, bold: !formats.bold}))}
|
|
127
|
+
/>
|
|
128
|
+
</Tooltip>
|
|
129
|
+
<Tooltip title="Italic">
|
|
130
|
+
<ToolbarButton
|
|
131
|
+
cs={toggledToolbarButtonStyles}
|
|
132
|
+
data-id="italic"
|
|
133
|
+
icon={italicsIcon}
|
|
134
|
+
toggled={formats.italic}
|
|
135
|
+
onClick={() => setFormats(formats => ({...formats, italic: !formats.italic}))}
|
|
136
|
+
/>
|
|
137
|
+
</Tooltip>
|
|
138
|
+
<Tooltip title="Underline">
|
|
139
|
+
<ToolbarButton
|
|
140
|
+
cs={toggledToolbarButtonStyles}
|
|
141
|
+
data-id="underline"
|
|
142
|
+
icon={underlineIcon}
|
|
143
|
+
toggled={formats.underline}
|
|
144
|
+
onClick={() => setFormats(formats => ({...formats, underline: !formats.underline}))}
|
|
145
|
+
/>
|
|
146
|
+
</Tooltip>
|
|
147
|
+
<Dialog model={dialogModel}>
|
|
148
|
+
<Tooltip title="Insert Link">
|
|
149
|
+
<Dialog.Target as={ToolbarButton} id={linkButtonId} data-id="link" icon={linkIcon} />
|
|
150
|
+
</Tooltip>
|
|
151
|
+
<Dialog.Popper>
|
|
152
|
+
<Dialog.Card aria-labelledby={linkButtonId}>
|
|
153
|
+
<Dialog.Body>
|
|
154
|
+
<FormField>
|
|
155
|
+
<FormField.Label>Link Text</FormField.Label>
|
|
156
|
+
<FormField.Input as={TextInput} ref={linkTextRef} />
|
|
157
|
+
</FormField>
|
|
158
|
+
<FormField>
|
|
159
|
+
<FormField.Label>URL</FormField.Label>
|
|
160
|
+
<FormField.Input as={TextInput} type="url" />
|
|
161
|
+
</FormField>
|
|
162
|
+
</Dialog.Body>
|
|
163
|
+
<Dialog.ButtonGroup>
|
|
164
|
+
<Dialog.CloseButton>Cancel</Dialog.CloseButton>
|
|
165
|
+
<Dialog.CloseButton as={PrimaryButton}>Apply</Dialog.CloseButton>
|
|
166
|
+
</Dialog.ButtonGroup>
|
|
167
|
+
</Dialog.Card>
|
|
168
|
+
</Dialog.Popper>
|
|
169
|
+
</Dialog>
|
|
170
|
+
</Toolbar>
|
|
171
|
+
);
|
|
172
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workday/canvas-kit-docs",
|
|
3
|
-
"version": "17.0.0-alpha.
|
|
3
|
+
"version": "17.0.0-alpha.0623-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",
|
|
@@ -47,10 +47,10 @@
|
|
|
47
47
|
"@stackblitz/sdk": "^1.11.0",
|
|
48
48
|
"@storybook/csf": "0.0.1",
|
|
49
49
|
"@workday/canvas-expressive-icons-web": "1.0.2",
|
|
50
|
-
"@workday/canvas-kit-labs-react": "^17.0.0-alpha.
|
|
51
|
-
"@workday/canvas-kit-preview-react": "^17.0.0-alpha.
|
|
52
|
-
"@workday/canvas-kit-react": "^17.0.0-alpha.
|
|
53
|
-
"@workday/canvas-kit-styling": "^17.0.0-alpha.
|
|
50
|
+
"@workday/canvas-kit-labs-react": "^17.0.0-alpha.0623-next.0",
|
|
51
|
+
"@workday/canvas-kit-preview-react": "^17.0.0-alpha.0623-next.0",
|
|
52
|
+
"@workday/canvas-kit-react": "^17.0.0-alpha.0623-next.0",
|
|
53
|
+
"@workday/canvas-kit-styling": "^17.0.0-alpha.0623-next.0",
|
|
54
54
|
"@workday/canvas-system-icons-web": "^5.0.3",
|
|
55
55
|
"@workday/canvas-tokens-web": "^4.4.0",
|
|
56
56
|
"markdown-to-jsx": "^7.2.0",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"mkdirp": "^1.0.3",
|
|
64
64
|
"typescript": "5.0"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "b46b831711d2b28326c53f1c40977910bce706e5"
|
|
67
67
|
}
|