@workday/canvas-kit-docs 15.0.0-alpha.0056-next.0 → 15.0.0-alpha.0064-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.
@@ -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.27",
22
- "@workday/canvas-kit-preview-react": "14.1.27",
23
- "@workday/canvas-kit-react": "14.1.27",
24
- "@workday/canvas-kit-react-fonts": "^14.1.27",
25
- "@workday/canvas-kit-styling": "14.1.27",
21
+ "@workday/canvas-kit-labs-react": "14.2.0",
22
+ "@workday/canvas-kit-preview-react": "14.2.0",
23
+ "@workday/canvas-kit-react": "14.2.0",
24
+ "@workday/canvas-kit-react-fonts": "^14.2.0",
25
+ "@workday/canvas-kit-styling": "14.2.0",
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.27",
22
- "@workday/canvas-kit-preview-react": "14.1.27",
23
- "@workday/canvas-kit-react": "14.1.27",
24
- "@workday/canvas-kit-react-fonts": "^14.1.27",
25
- "@workday/canvas-kit-styling": "14.1.27",
21
+ "@workday/canvas-kit-labs-react": "14.2.0",
22
+ "@workday/canvas-kit-preview-react": "14.2.0",
23
+ "@workday/canvas-kit-react": "14.2.0",
24
+ "@workday/canvas-kit-react-fonts": "^14.2.0",
25
+ "@workday/canvas-kit-styling": "14.2.0",
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-txt/llm-canvas-kit-upgrade-guide-v14.txt"
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
+ };