@workday/canvas-kit-docs 15.0.0-alpha.0056-next.0 → 15.0.0-alpha.0060-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/StorybookStatusIndicator.d.ts +1 -1
- package/dist/es6/lib/StorybookStatusIndicator.d.ts.map +1 -1
- package/dist/es6/lib/StorybookStatusIndicator.js +12 -14
- package/dist/es6/lib/docs.js +3406 -100
- package/dist/es6/lib/stackblitzFiles/packageJSONFile.js +5 -5
- package/dist/es6/lib/stackblitzFiles/packageJSONFile.ts +5 -5
- package/dist/mdx/14.0-UPGRADE-GUIDE.mdx +1 -1
- package/dist/mdx/labs-react/side-panel/SidePanel.mdx +256 -0
- package/dist/mdx/labs-react/side-panel/examples/AlwaysOpen.tsx +52 -0
- package/dist/mdx/labs-react/side-panel/examples/Basic.tsx +55 -0
- package/dist/mdx/labs-react/side-panel/examples/ExternalControl.tsx +75 -0
- package/dist/mdx/labs-react/side-panel/examples/HiddenName.tsx +41 -0
- package/dist/mdx/labs-react/side-panel/examples/OnStateTransition.tsx +49 -0
- package/dist/mdx/labs-react/side-panel/examples/RightOrigin.tsx +73 -0
- package/dist/mdx/labs-react/side-panel/examples/Variant.tsx +60 -0
- package/dist/mdx/labs-react/side-panel/examples/useDirection.ts +23 -0
- package/dist/mdx/preview-react/side-panel/SidePanel.mdx +15 -3
- package/dist/mdx/react/common/mdx/Theming.mdx +16 -31
- package/dist/mdx/react/common/mdx/examples/Theming.tsx +25 -7
- package/dist/mdx/style-props/stylePropsMigrationOverview.mdx +1 -1
- package/dist/mdx/tokens/TokenMigrationOverview.mdx +1 -1
- package/lib/StorybookStatusIndicator.tsx +17 -14
- package/package.json +6 -6
|
@@ -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": "14.1.
|
|
22
|
-
"@workday/canvas-kit-preview-react": "14.1.
|
|
23
|
-
"@workday/canvas-kit-react": "14.1.
|
|
24
|
-
"@workday/canvas-kit-react-fonts": "^14.1.
|
|
25
|
-
"@workday/canvas-kit-styling": "14.1.
|
|
21
|
+
"@workday/canvas-kit-labs-react": "14.1.28",
|
|
22
|
+
"@workday/canvas-kit-preview-react": "14.1.28",
|
|
23
|
+
"@workday/canvas-kit-react": "14.1.28",
|
|
24
|
+
"@workday/canvas-kit-react-fonts": "^14.1.28",
|
|
25
|
+
"@workday/canvas-kit-styling": "14.1.28",
|
|
26
26
|
"@workday/canvas-system-icons-web": "3.0.36",
|
|
27
27
|
"@workday/canvas-tokens-web": "3.1.2"
|
|
28
28
|
},
|
|
@@ -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": "14.1.
|
|
22
|
-
"@workday/canvas-kit-preview-react": "14.1.
|
|
23
|
-
"@workday/canvas-kit-react": "14.1.
|
|
24
|
-
"@workday/canvas-kit-react-fonts": "^14.1.
|
|
25
|
-
"@workday/canvas-kit-styling": "14.1.
|
|
21
|
+
"@workday/canvas-kit-labs-react": "14.1.28",
|
|
22
|
+
"@workday/canvas-kit-preview-react": "14.1.28",
|
|
23
|
+
"@workday/canvas-kit-react": "14.1.28",
|
|
24
|
+
"@workday/canvas-kit-react-fonts": "^14.1.28",
|
|
25
|
+
"@workday/canvas-kit-styling": "14.1.28",
|
|
26
26
|
"@workday/canvas-system-icons-web": "3.0.36",
|
|
27
27
|
"@workday/canvas-tokens-web": "3.1.2"
|
|
28
28
|
},
|
|
@@ -83,7 +83,7 @@ input for LLMs to automate and assist with your migration process.
|
|
|
83
83
|
migration
|
|
84
84
|
|
|
85
85
|
<DownloadLLMFile
|
|
86
|
-
rawFileLink="https://raw.githubusercontent.com/Workday/canvas-kit/master/modules/docs/llm
|
|
86
|
+
rawFileLink="https://raw.githubusercontent.com/Workday/canvas-kit/master/modules/docs/llm/llm-canvas-kit-upgrade-guide-v14.txt"
|
|
87
87
|
filename="llm-canvas-kit-upgrade-guide-v14.txt"
|
|
88
88
|
/>
|
|
89
89
|
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import {ExampleCodeBlock, SymbolDoc, Specifications, StorybookStatusIndicator} from '@workday/canvas-kit-docs';
|
|
2
|
+
import Basic from './examples/Basic';
|
|
3
|
+
import HiddenName from './examples/HiddenName';
|
|
4
|
+
import AlternatePanel from './examples/Variant';
|
|
5
|
+
import ExternalControl from './examples/ExternalControl';
|
|
6
|
+
import RightOrigin from './examples/RightOrigin';
|
|
7
|
+
import AlwaysOpen from './examples/AlwaysOpen';
|
|
8
|
+
import OnStateTransition from './examples/OnStateTransition';
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Canvas Kit Side Panel <StorybookStatusIndicator type="new" />
|
|
12
|
+
|
|
13
|
+
`SidePanel` is a collapsible container that anchors to the left or right side of the screen. It uses
|
|
14
|
+
the model pattern for state management and is fully accessible.
|
|
15
|
+
|
|
16
|
+
[> Workday Design Reference](https://design.workday.com/components/containers/side-panel)
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
yarn add @workday/canvas-kit-labs-react
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Migrating from Preview
|
|
25
|
+
|
|
26
|
+
If you're migrating from `@workday/canvas-kit-preview-react/side-panel`, here are the key API changes:
|
|
27
|
+
|
|
28
|
+
### Import Changes
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
// Before (preview-react)
|
|
32
|
+
import {SidePanel, useSidePanel} from '@workday/canvas-kit-preview-react/side-panel';
|
|
33
|
+
|
|
34
|
+
// After (labs-react)
|
|
35
|
+
import {SidePanel, useSidePanelModel} from '@workday/canvas-kit-labs-react/side-panel';
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Hook API Changes
|
|
39
|
+
|
|
40
|
+
| Preview (`useSidePanel`) | Labs (`useSidePanelModel`) |
|
|
41
|
+
|--------------------------|----------------------------|
|
|
42
|
+
| `initialExpanded: boolean` | `initialTransitionState: 'expanded' \| 'collapsed'` |
|
|
43
|
+
| `origin: 'left' \| 'right'` | `origin: 'start' \| 'end'` |
|
|
44
|
+
| Returns `expanded: boolean` | Returns `model.state.transitionState` |
|
|
45
|
+
| Returns `setExpanded(bool)` | Use `model.events.expand()` / `model.events.collapse()` |
|
|
46
|
+
| Returns `panelProps` to spread | Props applied automatically via `elemPropsHook` |
|
|
47
|
+
| Returns `labelProps` to spread | Use `id={model.state.labelId}` on label element |
|
|
48
|
+
| Returns `controlProps` to spread | Props applied automatically to `SidePanel.ToggleButton` |
|
|
49
|
+
|
|
50
|
+
### Component API Changes
|
|
51
|
+
|
|
52
|
+
| Preview | Labs |
|
|
53
|
+
|---------|------|
|
|
54
|
+
| `<SidePanel {...panelProps}>` | `<SidePanel model={model}>` or just `<SidePanel>` |
|
|
55
|
+
| `<SidePanel.ToggleButton {...controlProps} />` | `<SidePanel.ToggleButton />` |
|
|
56
|
+
| `<Heading {...labelProps}>` | `<Heading id={model.state.labelId}>` |
|
|
57
|
+
| `expanded` prop on SidePanel | Managed by model's `transitionState` |
|
|
58
|
+
| `touched` prop on SidePanel | Managed internally |
|
|
59
|
+
| `onExpandedChange` callback | Use `onStateTransition` and derive expanded state |
|
|
60
|
+
| `onStateTransition` on component | `onStateTransition` on model config |
|
|
61
|
+
|
|
62
|
+
### Code Migration Example
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
// Before (preview-react)
|
|
66
|
+
const {expanded, panelProps, labelProps, controlProps} = useSidePanel({
|
|
67
|
+
initialExpanded: false,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
<SidePanel {...panelProps} origin="right" onExpandedChange={(exp) => console.log(exp)}>
|
|
71
|
+
<SidePanel.ToggleButton {...controlProps} />
|
|
72
|
+
<Heading {...labelProps}>Panel Title</Heading>
|
|
73
|
+
{expanded && <Content />}
|
|
74
|
+
</SidePanel>
|
|
75
|
+
|
|
76
|
+
// After (labs-react)
|
|
77
|
+
const model = useSidePanelModel({
|
|
78
|
+
initialTransitionState: 'collapsed',
|
|
79
|
+
origin: 'end',
|
|
80
|
+
onStateTransition: (state) => {
|
|
81
|
+
const isExpanded = state === 'expanded' || state === 'expanding';
|
|
82
|
+
console.log(isExpanded);
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
<SidePanel model={model}>
|
|
87
|
+
<SidePanel.ToggleButton />
|
|
88
|
+
<Heading id={model.state.labelId}>Panel Title</Heading>
|
|
89
|
+
{model.state.transitionState === 'expanded' && <Content />}
|
|
90
|
+
</SidePanel>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Checking Expanded State
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
// Before (preview-react)
|
|
97
|
+
if (expanded) { /* ... */ }
|
|
98
|
+
|
|
99
|
+
// After (labs-react) - for exact state
|
|
100
|
+
if (model.state.transitionState === 'expanded') { /* ... */ }
|
|
101
|
+
|
|
102
|
+
// After (labs-react) - including animation states
|
|
103
|
+
const isExpanded = model.state.transitionState === 'expanded' ||
|
|
104
|
+
model.state.transitionState === 'expanding';
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Usage
|
|
108
|
+
|
|
109
|
+
### Basic Example
|
|
110
|
+
|
|
111
|
+
`SidePanel` is composed of three parts:
|
|
112
|
+
|
|
113
|
+
- The panel container (with an optional `model` prop)
|
|
114
|
+
- An accessible name (using `model.state.labelId` on a visible or hidden element)
|
|
115
|
+
- A toggle button (`SidePanel.ToggleButton`) to control the expand / collapse states
|
|
116
|
+
|
|
117
|
+
The component automatically handles:
|
|
118
|
+
- ARIA attributes (`aria-labelledby`, `aria-controls`, `aria-expanded`)
|
|
119
|
+
- Transition states (`expanding`, `expanded`, `collapsing`, `collapsed`)
|
|
120
|
+
- CSS transitions for smooth animations
|
|
121
|
+
|
|
122
|
+
Bidirectional support is built into `SidePanel`. As seen in the example below, CSS Flexbox flips the
|
|
123
|
+
page layout and the panel's contents. `SidePanel` also has logic to flip the position and direction
|
|
124
|
+
of the `ToggleButton` as well as the direction of the expand / collapse animation. If you're using
|
|
125
|
+
CSS Flexbox for layouts and using the provided components, you shouldn't have to provide any custom
|
|
126
|
+
logic or styling for bidirectional support.
|
|
127
|
+
|
|
128
|
+
<ExampleCodeBlock code={Basic} />
|
|
129
|
+
|
|
130
|
+
### Hidden Name
|
|
131
|
+
|
|
132
|
+
`SidePanel` must always have an accessible label for both the HTML `<section>` container and the
|
|
133
|
+
`ToggleButton`. The label element must have `id={model.state.labelId}` to properly connect it to
|
|
134
|
+
the panel and toggle button via `aria-labelledby`. The label can be visually hidden using
|
|
135
|
+
`AccessibleHide` which relies on CSS properties to hide text visually while keeping it available
|
|
136
|
+
for screen readers.
|
|
137
|
+
|
|
138
|
+
<ExampleCodeBlock code={HiddenName} />
|
|
139
|
+
|
|
140
|
+
### Alternate Variant
|
|
141
|
+
|
|
142
|
+
`SidePanel` has one variant, `alternate`, which you can supply as a top-level prop. Default depth of
|
|
143
|
+
`alternate` variant is 5, if `alternate` SidePanel has an overlay behavior the depth 6 should be
|
|
144
|
+
used (this case is covered in the Examples section).
|
|
145
|
+
|
|
146
|
+
<ExampleCodeBlock code={AlternatePanel} />
|
|
147
|
+
|
|
148
|
+
### External Control
|
|
149
|
+
|
|
150
|
+
Sometimes you'll want to control `SidePanel`'s expand / collapse behavior from outside the
|
|
151
|
+
component. You can use the model's events (`model.events.expand()` and `model.events.collapse()`)
|
|
152
|
+
to programmatically control the panel.
|
|
153
|
+
|
|
154
|
+
#### Notes about accessibility
|
|
155
|
+
|
|
156
|
+
When using external controls, be mindful of accessibility:
|
|
157
|
+
|
|
158
|
+
- Use `aria-pressed` on toggle buttons to indicate the current state
|
|
159
|
+
- The `SidePanel.ToggleButton` inside the panel automatically receives the correct ARIA attributes
|
|
160
|
+
- External buttons should have their own accessible labels (don't rely on `aria-labelledby` pointing
|
|
161
|
+
to the panel's label)
|
|
162
|
+
|
|
163
|
+
In the following example, we use the model's `transitionState` to determine the button's pressed
|
|
164
|
+
state and call `model.events.expand()` or `model.events.collapse()` on click.
|
|
165
|
+
|
|
166
|
+
<ExampleCodeBlock code={ExternalControl} />
|
|
167
|
+
|
|
168
|
+
### Right Origin
|
|
169
|
+
|
|
170
|
+
By default, `SidePanel` uses a `start` origin (left in LTR, right in RTL). This sets the
|
|
171
|
+
`ToggleButton`'s position and direction as well as the direction of the animation. You can set
|
|
172
|
+
the origin to `"end"` to flip these. The origin uses logical properties (`start`/`end`) for
|
|
173
|
+
proper bidirectional support.
|
|
174
|
+
|
|
175
|
+
<ExampleCodeBlock code={RightOrigin} />
|
|
176
|
+
|
|
177
|
+
### Always Open
|
|
178
|
+
|
|
179
|
+
If you do not need `SidePanel`'s expand / collapse behavior, you can simply omit the `ToggleButton`.
|
|
180
|
+
|
|
181
|
+
<ExampleCodeBlock code={AlwaysOpen} />
|
|
182
|
+
|
|
183
|
+
### Deriving Expanded State
|
|
184
|
+
|
|
185
|
+
If you need a simple boolean `expanded` state (similar to the preview-react `onExpandedChange`
|
|
186
|
+
callback), you can derive it from the `transitionState` using the `onStateTransition` callback
|
|
187
|
+
on the model.
|
|
188
|
+
|
|
189
|
+
### onStateTransition
|
|
190
|
+
|
|
191
|
+
The `onStateTransition` callback is called whenever the panel's transition state changes. This
|
|
192
|
+
includes all four states: `expanding`, `expanded`, `collapsing`, and `collapsed`. You can pass
|
|
193
|
+
this callback directly to the `SidePanel` component or to the `useSidePanelModel` hook.
|
|
194
|
+
|
|
195
|
+
The transition flow is:
|
|
196
|
+
1. **Collapsing**: `expanded` → `collapsing` → `collapsed`
|
|
197
|
+
2. **Expanding**: `collapsed` → `expanding` → `expanded`
|
|
198
|
+
|
|
199
|
+
This is useful for:
|
|
200
|
+
- Triggering side effects when the panel state changes
|
|
201
|
+
- Syncing the panel state with external state management
|
|
202
|
+
- Animating child components based on the transition state
|
|
203
|
+
|
|
204
|
+
<ExampleCodeBlock code={OnStateTransition} />
|
|
205
|
+
|
|
206
|
+
## Component API
|
|
207
|
+
|
|
208
|
+
<SymbolDoc name="SidePanel" fileName="/labs-react/" />
|
|
209
|
+
|
|
210
|
+
## Hooks
|
|
211
|
+
|
|
212
|
+
### useSidePanelModel
|
|
213
|
+
|
|
214
|
+
The `useSidePanelModel` hook creates a model for managing the SidePanel's state and events. You can
|
|
215
|
+
pass this model to the `SidePanel` component, or let the component create one internally.
|
|
216
|
+
|
|
217
|
+
```tsx
|
|
218
|
+
import {useSidePanelModel} from '@workday/canvas-kit-labs-react/side-panel';
|
|
219
|
+
|
|
220
|
+
// Create a model with custom configuration
|
|
221
|
+
const model = useSidePanelModel({
|
|
222
|
+
initialTransitionState: 'collapsed',
|
|
223
|
+
origin: 'end',
|
|
224
|
+
onStateTransition: (state) => console.log('State:', state),
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// Access state
|
|
228
|
+
model.state.transitionState; // 'expanded' | 'expanding' | 'collapsed' | 'collapsing'
|
|
229
|
+
model.state.panelId; // unique ID for the panel
|
|
230
|
+
model.state.labelId; // unique ID for the label
|
|
231
|
+
|
|
232
|
+
// Trigger events
|
|
233
|
+
model.events.expand(); // Set to expanded (no animation)
|
|
234
|
+
model.events.collapse(); // Set to collapsed (no animation)
|
|
235
|
+
model.events.handleAnimationStart(); // Start expand/collapse animation
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
<SymbolDoc name="useSidePanelModel" fileName="/labs-react/" />
|
|
239
|
+
|
|
240
|
+
### useSidePanelContainer
|
|
241
|
+
|
|
242
|
+
The `useSidePanelContainer` elemProps hook provides the necessary props for the SidePanel container
|
|
243
|
+
element, including `id`, `aria-labelledby`, and `onTransitionEnd`.
|
|
244
|
+
|
|
245
|
+
<SymbolDoc name="useSidePanelContainer" fileName="/labs-react/" />
|
|
246
|
+
|
|
247
|
+
### useSidePanelToggleButtonElemProps
|
|
248
|
+
|
|
249
|
+
The `useSidePanelToggleButtonElemProps` elemProps hook provides ARIA attributes for the toggle
|
|
250
|
+
button, including `aria-controls`, `aria-expanded`, and `aria-labelledby`.
|
|
251
|
+
|
|
252
|
+
<SymbolDoc name="useSidePanelToggleButtonElemProps" fileName="/labs-react/" />
|
|
253
|
+
|
|
254
|
+
## Specifications
|
|
255
|
+
|
|
256
|
+
<Specifications file="SidePanelLabs.spec.ts" name="Side Panel" />
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {AccentIcon} from '@workday/canvas-kit-react/icon';
|
|
2
|
+
import {rocketIcon} from '@workday/canvas-accent-icons-web';
|
|
3
|
+
import {SidePanel, useSidePanelModel} from '@workday/canvas-kit-labs-react/side-panel';
|
|
4
|
+
import {Flex} from '@workday/canvas-kit-react/layout';
|
|
5
|
+
import {Heading, Text} from '@workday/canvas-kit-react/text';
|
|
6
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
7
|
+
import {createStyles, px2rem} from '@workday/canvas-kit-styling';
|
|
8
|
+
|
|
9
|
+
const stylesOverride = {
|
|
10
|
+
accentIcon: createStyles({
|
|
11
|
+
marginRight: system.space.x4,
|
|
12
|
+
}),
|
|
13
|
+
pageContainer: createStyles({
|
|
14
|
+
gap: system.space.x4,
|
|
15
|
+
height: px2rem(320),
|
|
16
|
+
}),
|
|
17
|
+
panelContainer: createStyles({
|
|
18
|
+
alignItems: 'center',
|
|
19
|
+
padding: system.space.x4,
|
|
20
|
+
}),
|
|
21
|
+
panelHeading: createStyles({
|
|
22
|
+
color: system.color.fg.default,
|
|
23
|
+
}),
|
|
24
|
+
mainContent: createStyles({
|
|
25
|
+
alignItems: 'center',
|
|
26
|
+
justifyContent: 'center',
|
|
27
|
+
flexBasis: 'auto',
|
|
28
|
+
flex: 1,
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default () => {
|
|
33
|
+
const model = useSidePanelModel();
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Flex cs={stylesOverride.pageContainer}>
|
|
37
|
+
<SidePanel model={model}>
|
|
38
|
+
<Flex cs={stylesOverride.panelContainer}>
|
|
39
|
+
<AccentIcon icon={rocketIcon} cs={stylesOverride.accentIcon} />
|
|
40
|
+
<Heading size="small" cs={stylesOverride.panelHeading} id={model.state.labelId}>
|
|
41
|
+
Tasks Panel
|
|
42
|
+
</Heading>
|
|
43
|
+
</Flex>
|
|
44
|
+
</SidePanel>
|
|
45
|
+
<Flex as="main" cs={stylesOverride.mainContent}>
|
|
46
|
+
<Text as="p" typeLevel="body.large">
|
|
47
|
+
This is the main content section.
|
|
48
|
+
</Text>
|
|
49
|
+
</Flex>
|
|
50
|
+
</Flex>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {SecondaryButton} from '@workday/canvas-kit-react/button';
|
|
3
|
+
import {SidePanel, useSidePanelModel} from '@workday/canvas-kit-labs-react/side-panel';
|
|
4
|
+
import {Flex} from '@workday/canvas-kit-react/layout';
|
|
5
|
+
import {Heading, Text} from '@workday/canvas-kit-react/text';
|
|
6
|
+
import {AccentIcon} from '@workday/canvas-kit-react/icon';
|
|
7
|
+
import {rocketIcon} from '@workday/canvas-accent-icons-web';
|
|
8
|
+
import {createStyles, px2rem} from '@workday/canvas-kit-styling';
|
|
9
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
10
|
+
|
|
11
|
+
const stylesOverride = {
|
|
12
|
+
viewPortContainer: createStyles({
|
|
13
|
+
height: px2rem(320),
|
|
14
|
+
}),
|
|
15
|
+
panel: createStyles({
|
|
16
|
+
alignItems: 'center',
|
|
17
|
+
padding: system.space.x4,
|
|
18
|
+
}),
|
|
19
|
+
accentIcon: createStyles({
|
|
20
|
+
marginInlineEnd: system.space.x4,
|
|
21
|
+
}),
|
|
22
|
+
mainContent: createStyles({
|
|
23
|
+
alignItems: 'center',
|
|
24
|
+
justifyContent: 'center',
|
|
25
|
+
flexDirection: 'column',
|
|
26
|
+
flex: 1,
|
|
27
|
+
flexBasis: 'auto',
|
|
28
|
+
}),
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default () => {
|
|
32
|
+
const model = useSidePanelModel();
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<Flex cs={stylesOverride.viewPortContainer}>
|
|
36
|
+
<SidePanel model={model}>
|
|
37
|
+
<SidePanel.ToggleButton />
|
|
38
|
+
<Flex cs={stylesOverride.panel}>
|
|
39
|
+
{model.state.transitionState === 'expanded' && (
|
|
40
|
+
<Flex cs={stylesOverride.accentIcon}>
|
|
41
|
+
<AccentIcon icon={rocketIcon} />
|
|
42
|
+
</Flex>
|
|
43
|
+
)}
|
|
44
|
+
<Heading
|
|
45
|
+
size="small"
|
|
46
|
+
id={model.state.labelId}
|
|
47
|
+
hidden={model.state.transitionState === 'collapsed' ? true : undefined}
|
|
48
|
+
>
|
|
49
|
+
Tasks Panel
|
|
50
|
+
</Heading>
|
|
51
|
+
</Flex>
|
|
52
|
+
</SidePanel>
|
|
53
|
+
</Flex>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {SidePanel, useSidePanelModel} from '@workday/canvas-kit-labs-react/side-panel';
|
|
3
|
+
import {Flex} from '@workday/canvas-kit-react/layout';
|
|
4
|
+
import {Heading, Text} from '@workday/canvas-kit-react/text';
|
|
5
|
+
import {SecondaryButton} from '@workday/canvas-kit-react/button';
|
|
6
|
+
import {createStyles, px2rem} from '@workday/canvas-kit-styling';
|
|
7
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
8
|
+
|
|
9
|
+
const stylesOverride = {
|
|
10
|
+
viewport: createStyles({
|
|
11
|
+
height: px2rem(320),
|
|
12
|
+
}),
|
|
13
|
+
panel: createStyles({
|
|
14
|
+
alignItems: 'center',
|
|
15
|
+
padding: system.space.x4,
|
|
16
|
+
}),
|
|
17
|
+
panelHeading: createStyles({
|
|
18
|
+
color: system.color.fg.muted.stronger,
|
|
19
|
+
}),
|
|
20
|
+
main: createStyles({
|
|
21
|
+
alignItems: 'center',
|
|
22
|
+
justifyContent: 'center',
|
|
23
|
+
flexDirection: 'column',
|
|
24
|
+
flex: 1,
|
|
25
|
+
flexBasis: 'auto',
|
|
26
|
+
}),
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/*
|
|
30
|
+
* NOTE TO DEV:
|
|
31
|
+
* Spreading the `controlProps` onto an external control creates serious accessibility issues.
|
|
32
|
+
* - `aria-labelledby` id reference is invalid when the SidePanel is collapsed
|
|
33
|
+
* - `aria-labelledby` will change the name of "Toggle Side Panel" button to "Tasks Panel"
|
|
34
|
+
* - `aria-expanded` won't make sense to screen reader users when the expanded SidePanel content isn't following the control
|
|
35
|
+
* - `aria-controls` is unsupported by screen readers and will not allow users to navigate to the controlled content
|
|
36
|
+
*
|
|
37
|
+
* SOLUTION:
|
|
38
|
+
* - Pass the `controlProps` click handler function down to the external control component.
|
|
39
|
+
* - Add a toggle state to Button components with `aria-pressed` for screen readers,
|
|
40
|
+
* - OR use a similar toggle input like Checkbox or Switch.
|
|
41
|
+
*/
|
|
42
|
+
export default () => {
|
|
43
|
+
const model = useSidePanelModel({
|
|
44
|
+
initialTransitionState: 'collapsed',
|
|
45
|
+
labelId: 'tasks-panel-label',
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Flex cs={stylesOverride.viewport}>
|
|
50
|
+
<SidePanel model={model}>
|
|
51
|
+
<SidePanel.ToggleButton />
|
|
52
|
+
{model.state.transitionState === 'expanded' && (
|
|
53
|
+
<Flex cs={stylesOverride.panel}>
|
|
54
|
+
<Heading size="small" cs={stylesOverride.panelHeading} id={model.state.labelId}>
|
|
55
|
+
Tasks Panel
|
|
56
|
+
</Heading>
|
|
57
|
+
</Flex>
|
|
58
|
+
)}
|
|
59
|
+
</SidePanel>
|
|
60
|
+
<Flex as="main" cs={stylesOverride.main}>
|
|
61
|
+
<Text as="p" typeLevel="body.large">
|
|
62
|
+
Control the panel externally
|
|
63
|
+
</Text>
|
|
64
|
+
<SecondaryButton
|
|
65
|
+
onClick={
|
|
66
|
+
model.state.transitionState === 'expanded' ? model.events.collapse : model.events.expand
|
|
67
|
+
}
|
|
68
|
+
aria-pressed={model.state.transitionState === 'expanded'}
|
|
69
|
+
>
|
|
70
|
+
{model.state.transitionState === 'expanded' ? 'Hide Side Panel' : 'Show Side Panel'}
|
|
71
|
+
</SecondaryButton>
|
|
72
|
+
</Flex>
|
|
73
|
+
</Flex>
|
|
74
|
+
);
|
|
75
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {SidePanel, useSidePanelModel} from '@workday/canvas-kit-labs-react/side-panel';
|
|
3
|
+
import {Flex} from '@workday/canvas-kit-react/layout';
|
|
4
|
+
import {AccessibleHide} from '@workday/canvas-kit-react/common';
|
|
5
|
+
import {Text} from '@workday/canvas-kit-react/text';
|
|
6
|
+
import {createStyles, px2rem} from '@workday/canvas-kit-styling';
|
|
7
|
+
|
|
8
|
+
const stylesOverride = {
|
|
9
|
+
viewport: createStyles({
|
|
10
|
+
height: px2rem(320),
|
|
11
|
+
}),
|
|
12
|
+
main: createStyles({
|
|
13
|
+
alignItems: 'center',
|
|
14
|
+
justifyContent: 'center',
|
|
15
|
+
flexDirection: 'column',
|
|
16
|
+
flex: 1,
|
|
17
|
+
flexBasis: 'auto',
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default () => {
|
|
22
|
+
const model = useSidePanelModel({
|
|
23
|
+
onStateTransition: state => {
|
|
24
|
+
console.log(`state is: ${state}`);
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Flex cs={stylesOverride.viewport}>
|
|
30
|
+
<SidePanel model={model}>
|
|
31
|
+
<SidePanel.ToggleButton />
|
|
32
|
+
<AccessibleHide id={model.state.labelId}>Hidden Title</AccessibleHide>
|
|
33
|
+
</SidePanel>
|
|
34
|
+
<Flex as="main" cs={stylesOverride.main}>
|
|
35
|
+
<Text as="p" typeLevel="body.large">
|
|
36
|
+
Side Panel with a hidden title text.
|
|
37
|
+
</Text>
|
|
38
|
+
</Flex>
|
|
39
|
+
</Flex>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {Flex} from '@workday/canvas-kit-react/layout';
|
|
3
|
+
import {
|
|
4
|
+
SidePanel,
|
|
5
|
+
useSidePanelModel,
|
|
6
|
+
SidePanelTransitionStates,
|
|
7
|
+
} from '@workday/canvas-kit-labs-react/side-panel';
|
|
8
|
+
import {Text} from '@workday/canvas-kit-react/text';
|
|
9
|
+
import {AccessibleHide} from '@workday/canvas-kit-react/common';
|
|
10
|
+
import {createStyles, px2rem} from '@workday/canvas-kit-styling';
|
|
11
|
+
|
|
12
|
+
const stylesOverride = {
|
|
13
|
+
viewport: createStyles({
|
|
14
|
+
height: px2rem(320),
|
|
15
|
+
}),
|
|
16
|
+
main: createStyles({
|
|
17
|
+
alignItems: 'center',
|
|
18
|
+
justifyContent: 'center',
|
|
19
|
+
flexDirection: 'column',
|
|
20
|
+
flex: 1,
|
|
21
|
+
flexBasis: 'auto',
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default () => {
|
|
26
|
+
const [transitionState, setTransitionState] =
|
|
27
|
+
React.useState<SidePanelTransitionStates>('expanded');
|
|
28
|
+
|
|
29
|
+
const model = useSidePanelModel({
|
|
30
|
+
onStateTransition: state => {
|
|
31
|
+
setTransitionState(state);
|
|
32
|
+
console.log('Expanded changed to:', state);
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<Flex cs={stylesOverride.viewport}>
|
|
38
|
+
<SidePanel model={model}>
|
|
39
|
+
<SidePanel.ToggleButton />
|
|
40
|
+
<AccessibleHide id={model.state.labelId}>Hidden Title</AccessibleHide>
|
|
41
|
+
</SidePanel>
|
|
42
|
+
<Flex as="main" cs={stylesOverride.main}>
|
|
43
|
+
<Text as="p" typeLevel="body.large">
|
|
44
|
+
Side panel is {transitionState}.
|
|
45
|
+
</Text>
|
|
46
|
+
</Flex>
|
|
47
|
+
</Flex>
|
|
48
|
+
);
|
|
49
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {SecondaryButton} from '@workday/canvas-kit-react/button';
|
|
2
|
+
import {SidePanel, useSidePanelModel} from '@workday/canvas-kit-labs-react/side-panel';
|
|
3
|
+
import {Flex} from '@workday/canvas-kit-react/layout';
|
|
4
|
+
import {Heading, Text} from '@workday/canvas-kit-react/text';
|
|
5
|
+
import {CanvasProvider} from '@workday/canvas-kit-react/common';
|
|
6
|
+
import {createStyles, px2rem} from '@workday/canvas-kit-styling';
|
|
7
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
8
|
+
|
|
9
|
+
// local helper hook for setting content direction;
|
|
10
|
+
import {useDirection} from './useDirection';
|
|
11
|
+
|
|
12
|
+
const stylesOverride = {
|
|
13
|
+
viewport: createStyles({
|
|
14
|
+
height: px2rem(320),
|
|
15
|
+
}),
|
|
16
|
+
panelContainer: createStyles({
|
|
17
|
+
marginInlineStart: 'auto',
|
|
18
|
+
}),
|
|
19
|
+
panel: createStyles({
|
|
20
|
+
alignItems: 'center',
|
|
21
|
+
justifyContent: 'flex-end',
|
|
22
|
+
padding: system.space.x4,
|
|
23
|
+
}),
|
|
24
|
+
main: createStyles({
|
|
25
|
+
alignItems: 'center',
|
|
26
|
+
justifyContent: 'center',
|
|
27
|
+
flexDirection: 'column',
|
|
28
|
+
flex: 1,
|
|
29
|
+
flexBasis: 'auto',
|
|
30
|
+
}),
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const RightPanel = () => {
|
|
34
|
+
const model = useSidePanelModel({
|
|
35
|
+
origin: 'end',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<SidePanel model={model} className={stylesOverride.panelContainer}>
|
|
40
|
+
<SidePanel.ToggleButton />
|
|
41
|
+
<Flex cs={stylesOverride.panel}>
|
|
42
|
+
<Heading
|
|
43
|
+
size="small"
|
|
44
|
+
hidden={model.state.transitionState === 'collapsed' ? true : undefined}
|
|
45
|
+
id={model.state.labelId}
|
|
46
|
+
>
|
|
47
|
+
Tasks Panel
|
|
48
|
+
</Heading>
|
|
49
|
+
</Flex>
|
|
50
|
+
</SidePanel>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default () => {
|
|
55
|
+
const {direction, toggleDirection} = useDirection();
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<CanvasProvider dir={direction}>
|
|
59
|
+
<Flex cs={stylesOverride.viewport}>
|
|
60
|
+
<Flex as="main" cs={stylesOverride.main}>
|
|
61
|
+
<Text as="p" typeLevel="body.large">
|
|
62
|
+
Toggle the content direction
|
|
63
|
+
</Text>
|
|
64
|
+
<SecondaryButton onClick={toggleDirection}>
|
|
65
|
+
Set to {direction === 'ltr' ? 'Right-to-Left' : 'Left-to-Right'}
|
|
66
|
+
</SecondaryButton>
|
|
67
|
+
</Flex>
|
|
68
|
+
|
|
69
|
+
<RightPanel />
|
|
70
|
+
</Flex>
|
|
71
|
+
</CanvasProvider>
|
|
72
|
+
);
|
|
73
|
+
};
|