@workday/canvas-kit-docs 5.3.0-next.3 → 5.3.0-next.32

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.
Files changed (105) hide show
  1. package/LICENSE +1 -1
  2. package/dist/commonjs/lib/specs.js +429 -33
  3. package/dist/es6/lib/specs.js +429 -33
  4. package/dist/mdx/5.0-MIGRATION-GUIDE.mdx +81 -7
  5. package/dist/mdx/6.0-MIGRATION-GUIDE.mdx +560 -0
  6. package/dist/mdx/COMPOUND_COMPONENTS.mdx +31 -30
  7. package/dist/mdx/CONTRIBUTING.mdx +90 -63
  8. package/dist/mdx/TESTING.mdx +29 -5
  9. package/dist/mdx/labs-react/search-form/SearchForm.mdx +64 -0
  10. package/dist/mdx/labs-react/search-form/examples/Basic.tsx +61 -0
  11. package/dist/mdx/labs-react/search-form/examples/CustomTheme.tsx +72 -0
  12. package/dist/mdx/labs-react/search-form/examples/Grow.tsx +62 -0
  13. package/dist/mdx/labs-react/search-form/examples/PropTables.splitProps.tsx +4 -0
  14. package/dist/mdx/labs-react/search-form/examples/RTL.tsx +70 -0
  15. package/dist/mdx/labs-react/search-form/examples/Theming.tsx +64 -0
  16. package/dist/mdx/preview-react/breadcrumbs/Breadcrumbs.mdx +1 -1
  17. package/dist/mdx/preview-react/form-field/FormField.mdx +27 -0
  18. package/dist/mdx/preview-react/form-field/examples/Custom.tsx +57 -0
  19. package/dist/mdx/preview-react/menu/Menu.mdx +17 -9
  20. package/dist/mdx/preview-react/menu/examples/Basic.tsx +65 -10
  21. package/dist/mdx/preview-react/menu/examples/ContextMenu.tsx +47 -29
  22. package/dist/mdx/preview-react/menu/examples/CustomMenuItem.tsx +2 -2
  23. package/dist/mdx/preview-react/menu/examples/Icons.tsx +1 -1
  24. package/dist/mdx/preview-react/menu/examples/ManyItems.tsx +2 -2
  25. package/dist/mdx/preview-react/text-area/TextArea.mdx +122 -0
  26. package/dist/mdx/preview-react/text-area/examples/Alert.tsx +31 -0
  27. package/dist/mdx/preview-react/text-area/examples/Basic.tsx +17 -0
  28. package/dist/mdx/preview-react/text-area/examples/Disabled.tsx +17 -0
  29. package/dist/mdx/preview-react/text-area/examples/Error.tsx +40 -0
  30. package/dist/mdx/preview-react/text-area/examples/Grow.tsx +17 -0
  31. package/dist/mdx/preview-react/text-area/examples/HiddenLabel.tsx +20 -0
  32. package/dist/mdx/preview-react/text-area/examples/LabelPositionHorizontal.tsx +17 -0
  33. package/dist/mdx/preview-react/text-area/examples/LabelPositionVertical.tsx +17 -0
  34. package/dist/mdx/preview-react/text-area/examples/Placeholder.tsx +21 -0
  35. package/dist/mdx/preview-react/text-area/examples/RefForwarding.tsx +28 -0
  36. package/dist/mdx/preview-react/text-area/examples/Required.tsx +17 -0
  37. package/dist/mdx/preview-react/text-area/examples/ResizeConstraints.tsx +22 -0
  38. package/dist/mdx/preview-react/text-input/TextInput.mdx +145 -0
  39. package/dist/mdx/preview-react/text-input/examples/Alert.tsx +40 -0
  40. package/dist/mdx/preview-react/text-input/examples/Basic.tsx +17 -0
  41. package/dist/mdx/preview-react/text-input/examples/Disabled.tsx +17 -0
  42. package/dist/mdx/preview-react/text-input/examples/Error.tsx +40 -0
  43. package/dist/mdx/preview-react/text-input/examples/Grow.tsx +17 -0
  44. package/dist/mdx/preview-react/text-input/examples/HiddenLabel.tsx +20 -0
  45. package/dist/mdx/preview-react/text-input/examples/LabelPositionHorizontal.tsx +17 -0
  46. package/dist/mdx/preview-react/text-input/examples/LabelPositionVertical.tsx +17 -0
  47. package/dist/mdx/preview-react/text-input/examples/LoginForm.tsx +105 -0
  48. package/dist/mdx/preview-react/text-input/examples/Password.tsx +17 -0
  49. package/dist/mdx/preview-react/text-input/examples/Placeholder.tsx +17 -0
  50. package/dist/mdx/preview-react/text-input/examples/RefForwarding.tsx +28 -0
  51. package/dist/mdx/preview-react/text-input/examples/Required.tsx +17 -0
  52. package/dist/mdx/preview-react/text-input/examples/ThemedAlert.tsx +46 -0
  53. package/dist/mdx/preview-react/text-input/examples/ThemedError.tsx +37 -0
  54. package/dist/mdx/react/_examples/CookieBanner.mdx +8 -0
  55. package/dist/mdx/react/_examples/GlobalHeader.mdx +9 -0
  56. package/dist/mdx/react/_examples/PageHeader.mdx +8 -0
  57. package/dist/mdx/react/_examples/examples/CookieBanner.tsx +97 -0
  58. package/dist/mdx/react/_examples/examples/GlobalHeader.tsx +66 -0
  59. package/dist/mdx/react/_examples/examples/PageHeader.tsx +63 -0
  60. package/dist/mdx/react/action-bar/ActionBar.mdx +1 -1
  61. package/dist/mdx/react/button/button/Button.mdx +34 -9
  62. package/dist/mdx/react/button/button/examples/Primary.tsx +11 -1
  63. package/dist/mdx/react/button/button/examples/PrimaryInverse.tsx +14 -0
  64. package/dist/mdx/react/button/button/examples/Secondary.tsx +10 -1
  65. package/dist/mdx/react/button/button/examples/SecondaryInverse.tsx +14 -0
  66. package/dist/mdx/react/button/button/examples/Tertiary.tsx +10 -1
  67. package/dist/mdx/react/button/button/examples/TertiaryInverse.tsx +14 -0
  68. package/dist/mdx/react/button/icon-button/IconButton.mdx +1 -1
  69. package/dist/mdx/react/loading-animation/LoadingAnimation.mdx +5 -0
  70. package/dist/mdx/react/loading-animation/examples/RTL.tsx +16 -0
  71. package/dist/mdx/react/pagination/PropTables.splitprops.tsx +47 -0
  72. package/dist/mdx/react/pagination/examples/{StepControls.tsx → Basic.tsx} +1 -1
  73. package/dist/mdx/react/pagination/examples/GoToForm.tsx +1 -1
  74. package/dist/mdx/react/pagination/examples/HoistedModel.tsx +36 -22
  75. package/dist/mdx/react/pagination/examples/RTL.tsx +1 -1
  76. package/dist/mdx/react/pagination/pagination.mdx +225 -474
  77. package/dist/mdx/react/popup/Popup.mdx +96 -36
  78. package/dist/mdx/react/popup/examples/FullScreen.tsx +115 -0
  79. package/dist/mdx/react/radio/examples/Alert.tsx +3 -3
  80. package/dist/mdx/react/radio/examples/Basic.tsx +3 -3
  81. package/dist/mdx/react/radio/examples/Disabled.tsx +3 -3
  82. package/dist/mdx/react/radio/examples/Error.tsx +3 -3
  83. package/dist/mdx/react/radio/examples/LabelPosition.tsx +3 -3
  84. package/dist/mdx/react/radio/examples/NoValue.tsx +3 -3
  85. package/dist/mdx/react/radio/examples/RefForwarding.tsx +3 -3
  86. package/dist/mdx/react/radio/examples/Required.tsx +3 -3
  87. package/dist/mdx/react/segmented-control/SegmentedControl.mdx +1 -1
  88. package/dist/mdx/react/tabs/Tabs.mdx +67 -36
  89. package/dist/mdx/react/tabs/examples/DisabledTab.tsx +1 -1
  90. package/dist/mdx/react/tabs/examples/DynamicTabs.tsx +82 -38
  91. package/dist/mdx/react/tabs/examples/HoistedModel.tsx +4 -4
  92. package/dist/mdx/react/tabs/examples/Icons.tsx +36 -0
  93. package/dist/mdx/react/tabs/examples/{NamedKeys.tsx → NamedTabs.tsx} +0 -0
  94. package/dist/mdx/react/tabs/examples/OverflowTabs.tsx +58 -0
  95. package/dist/mdx/react/tabs/examples/SinglePanel.tsx +1 -1
  96. package/dist/mdx/react/text-area/TextArea.mdx +1 -1
  97. package/dist/mdx/react/toast/toast.mdx +1 -17
  98. package/dist/mdx/react/tooltip/Tooltip.mdx +9 -1
  99. package/dist/mdx/react/tooltip/examples/DelayedTooltip.tsx +16 -0
  100. package/dist/mdx/react/tooltip/examples/Ellipsis.tsx +6 -0
  101. package/package.json +5 -4
  102. package/dist/mdx/CODE_OF_CONDUCT.md +0 -68
  103. package/dist/mdx/preview-react/menu/examples/ContextMenuTarget.tsx +0 -33
  104. package/dist/mdx/preview-react/menu/examples/ControlButton.tsx +0 -84
  105. package/dist/mdx/react/pagination/examples/ShowAdditionalDetails.tsx +0 -52
@@ -2,9 +2,11 @@ import {Tabs} from '@workday/canvas-kit-react/tabs';
2
2
  import {Specifications} from '@workday/canvas-kit-docs';
3
3
 
4
4
  import Basic from './examples/Basic';
5
- import NamedKeys from './examples/NamedKeys';
5
+ import NamedTabs from './examples/NamedTabs';
6
6
  import RightToLeft from './examples/RightToLeft';
7
+ import OverflowTabs from './examples/OverflowTabs';
7
8
  import DisabledTab from './examples/DisabledTab';
9
+ import Icons from './examples/Icons';
8
10
  import SinglePanel from './examples/SinglePanel';
9
11
  import AlternativeTabStop from './examples/AlternativeTabStop';
10
12
  import HoistedModel from './examples/HoistedModel';
@@ -19,8 +21,8 @@ import {
19
21
  # Canvas Kit Tabs
20
22
 
21
23
  `Tabs` is a [compound component](/getting-started/for-developers/resources/compound-components/)
22
- which can be composed in a variety of different ways. It follows the
23
- [W3 Tabs specification](https://www.w3.org/TR/wai-aria-practices/#tabpanel).
24
+ that allows users to navigate between related views of content while remaining in context of the
25
+ page.
24
26
 
25
27
  [> Workday Design Reference](https://design.workday.com/components/navigation/tabs)
26
28
 
@@ -34,34 +36,54 @@ yarn add @workday/canvas-kit-react
34
36
 
35
37
  ### Basic Example
36
38
 
37
- `Tabs` includes a container `Tabs` component and the following subcomponents: `Tabs.List`,
38
- `Tabs.Item` and `Tabs.Panel`.
39
+ `Tabs` includes a container `Tabs` component and the following subcomponents which can be composed
40
+ in a variety of ways: `Tabs.List`, `Tabs.Item` and `Tabs.Panel`. It follows the
41
+ [W3 Tabs specification](https://www.w3.org/TR/wai-aria-practices/#tabpanel).
42
+
43
+ In this example, we set up a basic `Tabs` component with five tabs. This example uses a static API
44
+ that does not support overflow.
39
45
 
40
46
  <ExampleCodeBlock code={Basic} />
41
47
 
48
+ ### Overflow Tabs
49
+
50
+ Tabs is a responsive component based on the width of its container. If the rendered tabs exceed the
51
+ width of the `Tabs.List`, an overflow menu will be rendered. This only works against the dynamic API
52
+ where you give the `TabsModel` an array of items to be rendered. The dynamic API handles the React
53
+ `key` for you based on the item's identifier. The dynamic API requires either an `id` on each item
54
+ object or a `getId` function that returns an identifier based on the item. The below example uses an
55
+ `id` property on each item.
56
+
57
+ The dynamic API takes in any object, but since nothing is known about your object, a
58
+ [render prop](https://reactjs.org/docs/render-props.html) is necessary to instruct a list how it
59
+ should render.
60
+
61
+ <ExampleCodeBlock code={OverflowTabs} />
62
+
42
63
  ### Hoisted Model
43
64
 
44
65
  By default, `Tabs` will create and use its own [model](#model) internally. Alternatively, you may
45
66
  configure your own model with `useTabsModel` and pass it to `Tabs` via the `model` prop. This
46
- pattern is referred to as hoisting the model and provides direct access to its `state` and `events`
47
- outside of the `Tabs` component.
67
+ pattern is referred to as
68
+ [hoisting the model](/getting-started/for-developers/resources/compound-components/#configuring-a-model)
69
+ and provides direct access to its `state` and `events` outside of the `Tabs` component.
48
70
 
49
71
  In this example, we set up external observation of the model state and create an external button to
50
72
  trigger an event to change the active tab.
51
73
 
52
74
  <ExampleCodeBlock code={HoistedModel} />
53
75
 
54
- ### Named Keys
76
+ ### Named Tabs
55
77
 
56
78
  `Tabs.Item` and `Tabs.Panel` both take an optional `name` attribute that is used for the
57
- `onActivate` callback. This example is identical to the Basic Example, but with named keys for the
79
+ `onActivate` callback. This example is identical to the Basic Example, but with named tabs for the
58
80
  `Tabs.Item` and `Tabs.Panel` subcomponents.
59
81
 
60
- <ExampleCodeBlock code={NamedKeys} />
82
+ <ExampleCodeBlock code={NamedTabs} />
61
83
 
62
- ### Right-to-Left
84
+ ### Right-to-Left (RTL)
63
85
 
64
- `Tabs` supports right-to-left through the theme of the `CanvasProvider`.
86
+ `Tabs` supports right-to-left languages when specified in the `CanvasProvider` `theme`.
65
87
 
66
88
  <ExampleCodeBlock code={RightToLeft} />
67
89
 
@@ -71,6 +93,14 @@ Set the `disabled` prop of a `Tabs.Item` to `true` to disable it.
71
93
 
72
94
  <ExampleCodeBlock code={DisabledTab} />
73
95
 
96
+ ### Tab Icons
97
+
98
+ Tabs can have icons. You must set `hasIcon` on the `Tabs.Item` and use the `Icon` and `Text`
99
+ subcomponent. The `hasIcon` changes the `Tabs.Item` to change where overflow detection is from the
100
+ `Tabs.Item` element to the `Tabs.Item.Text` element.
101
+
102
+ <ExampleCodeBlock code={Icons} />
103
+
74
104
  ### Alternative Tab Stop
75
105
 
76
106
  By default, tab panels are focusable for accessibility. If the contents of a tab panel have a
@@ -93,9 +123,9 @@ from the `contents` object.
93
123
  ### Dynamic Tabs
94
124
 
95
125
  The `Tabs.Item` component takes in an optional `index` property if you want to specify the position
96
- of a tab. If not defined, by default it will append tabs to the end. For example, if your tabs are
97
- stored as an array in the state that can be added to along with a fixed tab that should remain at
98
- the end.
126
+ of a tab. If not defined, by default it will append tabs to the end. In this example, our tabs are
127
+ stored as an array in the state, and we have a fixed tab at the end that can add new tabs to that
128
+ array.
99
129
 
100
130
  <ExampleCodeBlock code={DynamicTabs} />
101
131
 
@@ -106,22 +136,24 @@ the end.
106
136
  #### Usage
107
137
 
108
138
  `Tabs` is a container component that is responsible for creating a `TabsModel` and sharing it with
109
- its children using React context. It does not represent a real element.
139
+ its subcomponents using React context. It does not represent a real element.
110
140
 
111
141
  ```tsx
112
- // Configuration
113
- <Tabs onActivate={({data}) => console.log('Activated tab', data.tab)}>{/* Subcomponents */}</Tabs>;
142
+ <Tabs onActivate={({data}) => console.log('Activated tab', data.tab)}>
143
+ {/* Child components */}
144
+ </Tabs>
145
+ ```
114
146
 
115
- // OR
147
+ Alternatively, you may pass in a model using the hoisted model pattern.
116
148
 
117
- // Hoisted model
149
+ ```tsx
118
150
  const model = useTabsModel({
119
151
  onActivate({data}) {
120
152
  console.log('Activated Tab', data.tab);
121
153
  },
122
154
  });
123
155
 
124
- <Tabs model={model}>{/* Subcomponents */}</Tabs>;
156
+ <Tabs model={model}>{/* Child components */}</Tabs>;
125
157
  ```
126
158
 
127
159
  #### Props
@@ -135,8 +167,7 @@ Note that if you pass in a `model` configured with `useTabsModel`, configuration
135
167
 
136
168
  #### Usage
137
169
 
138
- `Tabs.List` is a `div` element with a `role=tablist`. It is a container for `Tabs.Item`
139
- subcomponents.
170
+ `Tabs.List` is a `<div role="tablist">` element. It is a container for `Tabs.Item` subcomponents.
140
171
 
141
172
  ```tsx
142
173
  <Tabs.List>{/* Tabs.Items */}</Tabs.List>
@@ -144,7 +175,7 @@ subcomponents.
144
175
 
145
176
  #### Props
146
177
 
147
- Undocumented props are spread to the underlying `div` element.
178
+ Undocumented props are spread to the underlying `<div>` element.
148
179
 
149
180
  <ArgsTable of={Tabs.List} />
150
181
 
@@ -152,9 +183,9 @@ Undocumented props are spread to the underlying `div` element.
152
183
 
153
184
  #### Usage
154
185
 
155
- `Tabs.Item` is a `button` element with a `role=tab`. Each `Tabs.Item` is associated with a
156
- `Tabs.Panel` either by a `name` attribute or by the position in the list. If a `name` is provided,
157
- it must match the name passed to the corresponding `Tabs.Panel` component.
186
+ `Tabs.Item` is a `<button role="tab">` element. Each `Tabs.Item` is associated with a `Tabs.Panel`
187
+ either by a `name` attribute or by the position in the list. If a `name` is provided, it must match
188
+ the name passed to the corresponding `Tabs.Panel` component.
158
189
 
159
190
  ```tsx
160
191
  <Tabs.Item name="first">First Tab</Tabs.Item>
@@ -170,10 +201,9 @@ Undocumented props are spread to the underlying `button` element.
170
201
 
171
202
  #### Usage
172
203
 
173
- `Tabs.Panel` is a `div` element with a `role=tabpanel`. It is focusable by default. Each
174
- `Tabs.Panel` is controlled by a `Tabs.Item` either by a `name` attribute or by the position in the
175
- list. If a `name` is provided, it must match the name passed to the corresponding `Tabs.Item`
176
- component.
204
+ `Tabs.Panel` is a `<div role="tabpanel">` element. It is focusable by default. Each `Tabs.Panel` is
205
+ controlled by a `Tabs.Item` either by a `name` attribute or by the position in the list. If a `name`
206
+ is provided, it must match the name passed to the corresponding `Tabs.Item` component.
177
207
 
178
208
  ```tsx
179
209
  <Tabs.Panel name="first">{/* Contents of the tab panel */}</Tabs.Panel>
@@ -181,7 +211,7 @@ component.
181
211
 
182
212
  #### Props
183
213
 
184
- Undocumented props are spread to the underlying `div` element.
214
+ Undocumented props are spread to the underlying `<div>` element.
185
215
 
186
216
  <ArgsTable of={Tabs.Panel} />
187
217
 
@@ -192,9 +222,10 @@ If `Tabs` was stripped of all its markup, attributes, and styling, what would re
192
222
  object composed of two parts: `state` which describes the current snapshot in time of the component
193
223
  and `events` which describes events that can be sent to the model.
194
224
 
195
- By default, `Tabs` will create and use its own model internally. Alternatively, if you need direct
196
- access to the model's `state` and `events`, you may configure your own model with `useTabsModel` and
197
- pass it to `Tabs` via a pattern called
225
+ By default, `Tabs` will create a model and share it internally with its subcomponents using React
226
+ context. Alternatively, if you need direct access to the model's `state` and `events` outside of the
227
+ `Tabs` component, you may configure your own model with `useTabsModel` and pass it to `Tabs` via a
228
+ pattern called
198
229
  [hoisting the model](/getting-started/for-developers/resources/compound-components/#configuring-a-model).
199
230
 
200
231
  ```tsx
@@ -204,7 +235,7 @@ const model = useTabsModel({
204
235
  },
205
236
  });
206
237
 
207
- <Tabs model={model}>{/* Subcomponents */}</Tabs>;
238
+ <Tabs model={model}>{/* Child components */}</Tabs>;
208
239
  ```
209
240
 
210
241
  ### Config
@@ -8,7 +8,7 @@ export default () => {
8
8
  <Tabs>
9
9
  <Tabs.List>
10
10
  <Tabs.Item>First Tab</Tabs.Item>
11
- <Tabs.Item disabled>Disabled Tab</Tabs.Item>
11
+ <Tabs.Item aria-disabled>Disabled Tab</Tabs.Item>
12
12
  <Tabs.Item>Third Tab</Tabs.Item>
13
13
  </Tabs.List>
14
14
  <div style={{marginTop: space.m}}>
@@ -1,60 +1,104 @@
1
1
  import React from 'react';
2
2
  import {space} from '@workday/canvas-kit-react/tokens';
3
3
 
4
- import {Tabs, useTabsModel} from '@workday/canvas-kit-react/tabs';
4
+ import {Tabs, useTabsModel, TabsModel} from '@workday/canvas-kit-react/tabs';
5
+ import {SelectionModel} from '../../lib/selection';
6
+
7
+ type Tab = {
8
+ tab: string;
9
+ id: string;
10
+ };
5
11
 
6
12
  export default () => {
7
- const [tabs, setTabs] = React.useState([
8
- {tab: 'Tab 1', name: 'tab-1'},
9
- {tab: 'Tab 2', name: 'tab-2'},
10
- {tab: 'Tab 3', name: 'tab-3'},
13
+ const [tabs, setTabs] = React.useState<Tab[]>([
14
+ {tab: 'Tab 1', id: 'tab-1'},
15
+ {tab: 'Tab 2', id: 'tab-2'},
16
+ {tab: 'Tab 3', id: 'tab-3'},
17
+ {tab: 'Add Tab', id: 'add'},
11
18
  ]);
12
- const addedRef = React.useRef(tabs.length);
19
+ const addedRef = React.useRef(tabs.length - 1);
13
20
  const model = useTabsModel({
14
- shouldActivate: ({data}) => data.tab !== 'last',
21
+ items: tabs,
22
+ shouldSelect: ({data}) => data.id !== 'add',
15
23
  });
16
24
 
17
- const onKeyDown = (e: React.KeyboardEvent<HTMLElement>, name: string) => {
18
- if (e.key === 'Backspace') {
19
- setTabs(tabs.filter(item => item.name !== name));
25
+ // A ref of the model for the render functions to work around the caching done to lists
26
+ const modelRef = React.useRef(model);
27
+ modelRef.current = model;
28
+
29
+ /**
30
+ * Helper function that should be called when an item is programmatically removed. The following
31
+ * side effects depend on state of the model:
32
+ * * **Item is focused**: Focus will be moved to next item in the list
33
+ * * **Item is selected**: Selection will be moved to the next item in the list
34
+ * @param id The id of the item that will be removed
35
+ */
36
+ const removeItem = <T extends unknown>(id: string, model: SelectionModel<T>) => {
37
+ const index = model.state.items.findIndex(item => model.getId(item) === model.state.cursorId);
38
+ console.log('index', index, id, model.state.cursorId, model.state.items);
39
+ const nextIndex = index === model.state.items.length - 1 ? index - 1 : index + 1;
40
+ const nextId = model.getId(model.state.items[nextIndex]);
41
+ if (model.state.selectedIds[0] === id) {
42
+ // We're removing the currently selected item. Select next item
43
+ model.events.select({id: nextId});
44
+ }
45
+ if (model.state.cursorId === id) {
46
+ // We're removing the currently focused item. Focus next item
47
+ model.events.goTo({id: nextId});
48
+
49
+ // wait for stabilization of state
50
+ requestAnimationFrame(() => {
51
+ document.querySelector<HTMLElement>(`#${model.state.id}-${nextId}`)?.focus();
52
+ });
53
+ }
54
+ };
55
+
56
+ const onKeyDown = (id: string) => (e: React.KeyboardEvent<HTMLElement>) => {
57
+ if (e.key === 'Delete' && id !== 'add') {
58
+ setTabs(tabs.filter(item => item.id !== id));
59
+ const model = modelRef.current;
60
+ removeItem(id, model);
61
+ }
62
+ };
63
+
64
+ const onClick = (id: string) => (e: React.MouseEvent) => {
65
+ if (id === 'add') {
66
+ addedRef.current += 1;
67
+ setTabs(tabs => {
68
+ const newTabs = tabs.slice(0, tabs.length - 1);
69
+ const addTab = tabs.slice(-1);
70
+ return newTabs.concat(
71
+ {tab: `Tab ${addedRef.current}`, id: `tab-${addedRef.current}`},
72
+ addTab
73
+ );
74
+ });
75
+ model.events.goTo({id: 'add'});
20
76
  }
21
77
  };
22
78
 
23
79
  return (
24
80
  <Tabs model={model}>
25
- <Tabs.List>
26
- {tabs.map((item, index) => (
27
- <Tabs.Item
28
- key={item.name}
29
- name={item.name}
30
- index={index}
31
- onKeyDown={e => onKeyDown(e, item.name)}
32
- >
81
+ <Tabs.List overflowButton={<Tabs.OverflowButton>More</Tabs.OverflowButton>}>
82
+ {(item: Tab) => (
83
+ <Tabs.Item name={item.id} onKeyDown={onKeyDown(item.id)} onClick={onClick(item.id)}>
33
84
  {item.tab}
34
85
  </Tabs.Item>
35
- ))}
36
- <Tabs.Item
37
- key={'last'}
38
- index={tabs.length}
39
- name={'last'}
40
- onClick={() => {
41
- addedRef.current += 1;
42
- setTabs(tabs =>
43
- tabs.concat({tab: `Tab ${addedRef.current}`, name: `tab-${addedRef.current}`})
44
- );
45
- model.events.goTo({id: 'last'});
46
- }}
47
- >
48
- Add Tab
49
- </Tabs.Item>
86
+ )}
50
87
  </Tabs.List>
51
- <div style={{marginTop: space.m}}>
52
- {tabs.map((item, index) => (
53
- <Tabs.Panel key={item.name} name={item.name}>
88
+ <Tabs.Menu.Popper>
89
+ <Tabs.Menu.Card maxWidth={300} maxHeight={200}>
90
+ <Tabs.Menu.List>
91
+ {(item: Tab) => <Tabs.Menu.Item name={item.id}>{item.tab}</Tabs.Menu.Item>}
92
+ </Tabs.Menu.List>
93
+ </Tabs.Menu.Card>
94
+ </Tabs.Menu.Popper>
95
+ <Tabs.Panels>
96
+ {(item: Tab) => (
97
+ <Tabs.Panel marginTop="m" name={item.id}>
54
98
  Contents of {item.tab}
55
99
  </Tabs.Panel>
56
- ))}
57
- </div>
100
+ )}
101
+ </Tabs.Panels>
58
102
  </Tabs>
59
103
  );
60
104
  };
@@ -6,8 +6,8 @@ import {Tabs, useTabsModel} from '@workday/canvas-kit-react/tabs';
6
6
 
7
7
  export default () => {
8
8
  const model = useTabsModel({
9
- onActivate({data, prevState}) {
10
- console.log('Activated Tab', data, prevState);
9
+ onSelect({data, prevState}) {
10
+ console.log('Selected Tab', data, prevState);
11
11
  },
12
12
  });
13
13
 
@@ -27,10 +27,10 @@ export default () => {
27
27
  </Tabs>
28
28
  <SecondaryButton
29
29
  onClick={() => {
30
- model.events.activate({tab: 'third'});
30
+ model.events.select({id: 'third'});
31
31
  }}
32
32
  >
33
- Activate third tab
33
+ Select Third Tab
34
34
  </SecondaryButton>
35
35
  </>
36
36
  );
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+
3
+ import {space} from '@workday/canvas-kit-react/tokens';
4
+ import {starIcon, searchIcon, selectIcon, shareIcon} from '@workday/canvas-system-icons-web';
5
+ import {Tabs} from '@workday/canvas-kit-react/tabs';
6
+
7
+ export default () => {
8
+ return (
9
+ <Tabs>
10
+ <Tabs.List>
11
+ <Tabs.Item hasIcon>
12
+ <Tabs.Item.Icon icon={starIcon} />
13
+ <Tabs.Item.Text>First Tab</Tabs.Item.Text>
14
+ </Tabs.Item>
15
+ <Tabs.Item hasIcon>
16
+ <Tabs.Item.Icon icon={searchIcon} />
17
+ <Tabs.Item.Text>Second Tab</Tabs.Item.Text>
18
+ </Tabs.Item>
19
+ <Tabs.Item hasIcon>
20
+ <Tabs.Item.Icon icon={selectIcon} />
21
+ <Tabs.Item.Text>Third Tab</Tabs.Item.Text>
22
+ </Tabs.Item>
23
+ <Tabs.Item hasIcon>
24
+ <Tabs.Item.Icon icon={shareIcon} />
25
+ <Tabs.Item.Text>Fourth Tab</Tabs.Item.Text>
26
+ </Tabs.Item>
27
+ </Tabs.List>
28
+ <div style={{marginTop: space.m}}>
29
+ <Tabs.Panel>Contents of First Tab</Tabs.Panel>
30
+ <Tabs.Panel>Contents of Second Tab</Tabs.Panel>
31
+ <Tabs.Panel>Contents of Third Tab</Tabs.Panel>
32
+ <Tabs.Panel>Contents of Fourth Tab</Tabs.Panel>
33
+ </div>
34
+ </Tabs>
35
+ );
36
+ };
@@ -0,0 +1,58 @@
1
+ import React from 'react';
2
+
3
+ import {Tabs, useTabsModel} from '@workday/canvas-kit-react/tabs';
4
+ import {HStack} from '@workday/canvas-kit-labs-react';
5
+ import {SecondaryButton} from '../../../button';
6
+
7
+ type MyTabItem = {
8
+ id: string;
9
+ text: React.ReactNode;
10
+ contents: string;
11
+ };
12
+
13
+ export default () => {
14
+ const [items] = React.useState<MyTabItem[]>([
15
+ {id: 'first', text: 'First Tab', contents: 'Contents of First Tab'},
16
+ {id: 'second', text: 'Second Tab', contents: 'Contents of Second Tab'},
17
+ {id: 'third', text: 'Third Tab', contents: 'Contents of Third Tab'},
18
+ {id: 'fourth', text: 'Fourth Tab', contents: 'Contents of Fourth Tab'},
19
+ {id: 'fifth', text: 'Fifth Tab', contents: 'Contents of Fifth Tab'},
20
+ {id: 'sixth', text: 'Sixth Tab', contents: 'Contents of Sixth Tab'},
21
+ {id: 'seventh', text: 'Seventh Tab', contents: 'Contents of Seventh Tab'},
22
+ ]);
23
+ const model = useTabsModel({
24
+ items,
25
+ });
26
+ const [containerWidth, setContainerWidth] = React.useState('100%');
27
+ return (
28
+ <div style={{width: containerWidth}}>
29
+ <Tabs model={model}>
30
+ <Tabs.List overflowButton={<Tabs.OverflowButton>More</Tabs.OverflowButton>}>
31
+ {(item: MyTabItem) => <Tabs.Item name={item.id}>{item.text}</Tabs.Item>}
32
+ </Tabs.List>
33
+ <Tabs.Menu.Popper>
34
+ <Tabs.Menu.Card maxWidth={300} maxHeight={200}>
35
+ <Tabs.Menu.List>
36
+ {(item: MyTabItem) => <Tabs.Menu.Item name={item.id}>{item.text}</Tabs.Menu.Item>}
37
+ </Tabs.Menu.List>
38
+ </Tabs.Menu.Card>
39
+ </Tabs.Menu.Popper>
40
+ <Tabs.Panels>
41
+ {(item: MyTabItem) => (
42
+ <Tabs.Panel marginTop="m" name={item.id}>
43
+ {item.contents}
44
+ </Tabs.Panel>
45
+ )}
46
+ </Tabs.Panels>
47
+ </Tabs>
48
+ <hr />
49
+ <h4>Change tab container size</h4>
50
+ <HStack spacing="xs">
51
+ <SecondaryButton onClick={() => setContainerWidth('100%')}>100%</SecondaryButton>
52
+ <SecondaryButton onClick={() => setContainerWidth('500px')}>500px</SecondaryButton>
53
+ <SecondaryButton onClick={() => setContainerWidth('235px')}>235px</SecondaryButton>
54
+ <SecondaryButton onClick={() => setContainerWidth('150px')}>150px</SecondaryButton>
55
+ </HStack>
56
+ </div>
57
+ );
58
+ };
@@ -34,7 +34,7 @@ export default () => {
34
34
  </Tabs.Item>
35
35
  </Tabs.List>
36
36
  <Tabs.Panel style={{marginTop: space.m}} hidden={undefined} id="mytab-panel">
37
- {contents[model.state.activeTab]}
37
+ {contents[model.state.selectedIds[0]]}
38
38
  </Tabs.Panel>
39
39
  </Tabs>
40
40
  );
@@ -23,7 +23,7 @@ Text Areas allow users to enter and edit multiple lines of text.
23
23
  ## Installation
24
24
 
25
25
  ```sh
26
- yarn add @workday/canvas-kit-react
26
+ yarn add @workday/canvas-kit-labs-react
27
27
  ```
28
28
 
29
29
  ## Usage
@@ -29,52 +29,36 @@ Below are examples we expect will work for most use cases. Note that all example
29
29
  they are an important signifier to communicate meaning. For this reason, Toast notifications should
30
30
  always include an icon.
31
31
 
32
- ---
33
-
34
32
  #### Complete Example with Popper
35
33
 
36
34
  We use Popper to position Toast. Here's an example of how to use them together.
37
35
 
38
36
  <ExampleCodeBlock code={WithPopper} />
39
37
 
40
- ---
41
-
42
38
  #### Success
43
39
 
44
40
  <ExampleCodeBlock code={Success} />
45
41
 
46
- ---
47
-
48
42
  #### Error
49
43
 
50
44
  <ExampleCodeBlock code={Error} />
51
45
 
52
- ---
53
-
54
46
  #### WithCloseButton
55
47
 
56
48
  <ExampleCodeBlock code={WithCloseButton} />
57
49
 
58
- ---
59
-
60
50
  #### With an Action Link
61
51
 
62
52
  <ExampleCodeBlock code={WithActionLink} />
63
53
 
64
- ---
65
-
66
54
  #### With an Action Link and CloseIcon
67
55
 
68
56
  <ExampleCodeBlock code={WithActionLinkAndCloseIcon} />
69
57
 
70
- ---
71
-
72
58
  #### With RTL
73
59
 
74
60
  <ExampleCodeBlock code={RTL} />
75
61
 
76
- ---
77
-
78
- ## Component Props
62
+ ## Props
79
63
 
80
64
  <ArgsTable of={Toast} />
@@ -3,6 +3,7 @@ import {Specifications} from '@workday/canvas-kit-docs';
3
3
 
4
4
  import Default from './examples/Default';
5
5
  import CustomContent from './examples/CustomContent';
6
+ import DelayedTooltip from './examples/DelayedTooltip';
6
7
  import DescribeType from './examples/DescribeType';
7
8
  import Muted from './examples/Muted';
8
9
  import Placements from './examples/Placements';
@@ -87,6 +88,13 @@ a dialog instead.
87
88
 
88
89
  <ExampleCodeBlock code={CustomContent} />
89
90
 
91
+ ### Delayed Tooltip
92
+
93
+ The default delay for showing and hiding a tooltip are 300ms and 100ms, respectively. You can
94
+ control the length of the delay by providing custom `showDelay` and `hideDelay` in ms.
95
+
96
+ <ExampleCodeBlock code={DelayedTooltip} />
97
+
90
98
  ### Placements
91
99
 
92
100
  The tooltip allows for a `placement` configuration. The tooltip uses
@@ -168,7 +176,7 @@ example uses those parts directly while being functionally equivalent to the ori
168
176
 
169
177
  <ExampleCodeBlock code={UseTooltip} />
170
178
 
171
- ## Properties
179
+ ## Props
172
180
 
173
181
  <ArgsTable of={Tooltip} />
174
182
 
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+
3
+ import {SecondaryButton} from '@workday/canvas-kit-react/button';
4
+ import {Tooltip} from '@workday/canvas-kit-react/tooltip';
5
+
6
+ export default () => {
7
+ return (
8
+ <React.Fragment>
9
+ <Tooltip type="describe" title="Tooltip Text" showDelay={2000} hideDelay={1000}>
10
+ <SecondaryButton>
11
+ Tooltip appears after 2 seconds and disappears after 1 second
12
+ </SecondaryButton>
13
+ </Tooltip>
14
+ </React.Fragment>
15
+ );
16
+ };
@@ -3,6 +3,7 @@ import React from 'react';
3
3
  import {SecondaryButton} from '@workday/canvas-kit-react/button';
4
4
  import {OverflowTooltip} from '@workday/canvas-kit-react/tooltip';
5
5
  import {space} from '@workday/canvas-kit-react/tokens';
6
+ import {resetIcon} from '@workday/canvas-system-icons-web';
6
7
 
7
8
  const CustomContent = ({...elemProps}) => (
8
9
  <button
@@ -30,6 +31,11 @@ export default () => {
30
31
  Super Mega Ultra Long Content With Max Width On The Button
31
32
  </SecondaryButton>
32
33
  </OverflowTooltip>
34
+ <OverflowTooltip>
35
+ <SecondaryButton icon={resetIcon} style={{maxWidth: 200}}>
36
+ Super Mega Ultra Long Content With Max Width On The Button with Icon
37
+ </SecondaryButton>
38
+ </OverflowTooltip>
33
39
  <OverflowTooltip>
34
40
  <button
35
41
  style={{