@workday/canvas-kit-docs 16.0.14 → 16.0.16

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.
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
 
3
3
  import {Checkbox} from '@workday/canvas-kit-react/checkbox';
4
- import {FormField} from '@workday/canvas-kit-react/form-field';
5
4
 
6
5
  export default () => {
7
6
  const [checked, setChecked] = React.useState(false);
@@ -11,17 +10,6 @@ export default () => {
11
10
  };
12
11
 
13
12
  return (
14
- <FormField>
15
- <FormField.Label>Confirm</FormField.Label>
16
- <FormField.Field>
17
- <FormField.Input
18
- as={Checkbox}
19
- checked={checked}
20
- disabled={true}
21
- label="I agree to the terms"
22
- onChange={handleChange}
23
- />
24
- </FormField.Field>
25
- </FormField>
13
+ <Checkbox checked={checked} disabled label="I agree to the terms" onChange={handleChange} />
26
14
  );
27
15
  };
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
 
3
3
  import {Checkbox} from '@workday/canvas-kit-react/checkbox';
4
- import {FormField} from '@workday/canvas-kit-react/form-field';
4
+ import {FormFieldGroup} from '@workday/canvas-kit-react/form-field';
5
5
 
6
6
  export default () => {
7
7
  const [checked, setChecked] = React.useState(false);
@@ -11,17 +11,18 @@ export default () => {
11
11
  };
12
12
 
13
13
  return (
14
- <FormField error="error">
15
- <FormField.Label>Confirm</FormField.Label>
16
- <FormField.Field>
17
- <FormField.Input
14
+ <FormFieldGroup error="error">
15
+ <FormFieldGroup.Label>Confirm</FormFieldGroup.Label>
16
+ <FormFieldGroup.Field>
17
+ <FormFieldGroup.Input
18
18
  as={Checkbox}
19
19
  checked={checked}
20
+ error={Checkbox.ErrorType.Error}
20
21
  label="I agree to the terms"
21
22
  onChange={handleChange}
22
23
  />
23
- <FormField.Hint>You must agree to the terms before proceeding</FormField.Hint>
24
- </FormField.Field>
25
- </FormField>
24
+ <FormFieldGroup.Hint>You must agree to the terms before proceeding</FormFieldGroup.Hint>
25
+ </FormFieldGroup.Field>
26
+ </FormFieldGroup>
26
27
  );
27
28
  };
@@ -1,13 +1,24 @@
1
1
  import React from 'react';
2
2
 
3
3
  import {Checkbox} from '@workday/canvas-kit-react/checkbox';
4
- import {Box} from '@workday/canvas-kit-react/layout';
5
4
  import {createStyles} from '@workday/canvas-kit-styling';
6
5
  import {system} from '@workday/canvas-tokens-web';
7
6
 
8
- const styleOverrides = createStyles({
7
+ const listStyles = createStyles({
8
+ listStyle: 'none',
9
+ margin: 0,
10
+ padding: 0,
11
+ });
12
+
13
+ const nestedListStyles = createStyles({
14
+ listStyle: 'none',
15
+ margin: 0,
9
16
  marginInlineStart: system.gap.xl,
10
17
  marginBlockStart: system.gap.sm,
18
+ padding: 0,
19
+ display: 'flex',
20
+ flexDirection: 'column',
21
+ gap: system.gap.sm,
11
22
  });
12
23
 
13
24
  export default () => {
@@ -59,23 +70,26 @@ export default () => {
59
70
  };
60
71
 
61
72
  return (
62
- <>
63
- <Checkbox
64
- checked={pizzaChecked}
65
- indeterminate={pizzaIndeterminate}
66
- label="Supreme Pizza Toppings"
67
- onChange={handlePizzaChange}
68
- />
69
- <Box cs={styleOverrides}>
70
- {toppings.map((topping, index) => (
71
- <Checkbox
72
- checked={topping.checked}
73
- key={topping.name}
74
- label={topping.name}
75
- onChange={event => handleToppingChange(event, index)}
76
- />
77
- ))}
78
- </Box>
79
- </>
73
+ <ul className={listStyles}>
74
+ <li>
75
+ <Checkbox
76
+ checked={pizzaChecked}
77
+ indeterminate={pizzaIndeterminate}
78
+ label="Supreme Pizza Toppings"
79
+ onChange={handlePizzaChange}
80
+ />
81
+ <ul className={nestedListStyles}>
82
+ {toppings.map((topping, index) => (
83
+ <li key={topping.name}>
84
+ <Checkbox
85
+ checked={topping.checked}
86
+ label={topping.name}
87
+ onChange={event => handleToppingChange(event, index)}
88
+ />
89
+ </li>
90
+ ))}
91
+ </ul>
92
+ </li>
93
+ </ul>
80
94
  );
81
95
  };
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
 
3
3
  import {Checkbox} from '@workday/canvas-kit-react/checkbox';
4
- import {FormField} from '@workday/canvas-kit-react/form-field';
4
+ import {FormFieldGroup} from '@workday/canvas-kit-react/form-field';
5
5
 
6
6
  export default () => {
7
7
  const [checked, setChecked] = React.useState(false);
@@ -11,16 +11,16 @@ export default () => {
11
11
  };
12
12
 
13
13
  return (
14
- <FormField orientation="horizontalStart">
15
- <FormField.Label>Confirm</FormField.Label>
16
- <FormField.Field>
17
- <FormField.Input
14
+ <FormFieldGroup orientation="horizontalStart">
15
+ <FormFieldGroup.Label>Confirm</FormFieldGroup.Label>
16
+ <FormFieldGroup.Field>
17
+ <FormFieldGroup.Input
18
18
  as={Checkbox}
19
19
  checked={checked}
20
20
  label="I agree to the terms"
21
21
  onChange={handleChange}
22
22
  />
23
- </FormField.Field>
24
- </FormField>
23
+ </FormFieldGroup.Field>
24
+ </FormFieldGroup>
25
25
  );
26
26
  };
@@ -2,45 +2,33 @@ import React from 'react';
2
2
 
3
3
  import {PrimaryButton} from '@workday/canvas-kit-react/button';
4
4
  import {Checkbox} from '@workday/canvas-kit-react/checkbox';
5
- import {FormField} from '@workday/canvas-kit-react/form-field';
6
- import {Box} from '@workday/canvas-kit-react/layout';
7
- import {createStyles, px2rem} from '@workday/canvas-kit-styling';
5
+ import {changeFocus} from '@workday/canvas-kit-react/common';
6
+ import {Flex} from '@workday/canvas-kit-react/layout';
7
+ import {createStyles} from '@workday/canvas-kit-styling';
8
8
  import {system} from '@workday/canvas-tokens-web';
9
9
 
10
- const boxStyles = createStyles({
11
- display: 'flex',
10
+ const containerStyles = createStyles({
11
+ gap: system.gap.md,
12
+ alignItems: 'flex-start',
12
13
  flexDirection: 'column',
13
14
  });
14
15
 
15
16
  export default () => {
16
17
  const [checked, setChecked] = React.useState(false);
17
- const ref = React.useRef(null);
18
+ const ref = React.useRef<HTMLInputElement>(null);
18
19
 
19
20
  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
20
21
  setChecked(event.target.checked);
21
22
  };
22
23
 
23
24
  const handleClick = () => {
24
- ref.current.click();
25
+ changeFocus(ref.current);
25
26
  };
26
27
 
27
28
  return (
28
- <>
29
- <Box cs={boxStyles}>
30
- <FormField>
31
- <FormField.Label>Confirm</FormField.Label>
32
- <FormField.Field>
33
- <FormField.Input
34
- as={Checkbox}
35
- checked={checked}
36
- label="I agree to the terms"
37
- onChange={handleChange}
38
- ref={ref}
39
- />
40
- </FormField.Field>
41
- </FormField>
42
- </Box>
43
- <PrimaryButton onClick={handleClick}>Check Agreement to Terms</PrimaryButton>
44
- </>
29
+ <Flex cs={containerStyles}>
30
+ <Checkbox checked={checked} label="I agree to the terms" onChange={handleChange} ref={ref} />
31
+ <PrimaryButton onClick={handleClick}>Focus Checkbox</PrimaryButton>
32
+ </Flex>
45
33
  );
46
34
  };
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
 
3
3
  import {Checkbox} from '@workday/canvas-kit-react/checkbox';
4
- import {FormField} from '@workday/canvas-kit-react/form-field';
4
+ import {FormFieldGroup} from '@workday/canvas-kit-react/form-field';
5
5
 
6
6
  export default () => {
7
7
  const [checked, setChecked] = React.useState(false);
@@ -11,16 +11,16 @@ export default () => {
11
11
  };
12
12
 
13
13
  return (
14
- <FormField isRequired={true}>
15
- <FormField.Label>Confirm</FormField.Label>
16
- <FormField.Field>
17
- <FormField.Input
14
+ <FormFieldGroup isRequired={true}>
15
+ <FormFieldGroup.Label>Confirm</FormFieldGroup.Label>
16
+ <FormFieldGroup.Field>
17
+ <FormFieldGroup.Input
18
18
  as={Checkbox}
19
19
  checked={checked}
20
20
  label="I agree to the terms"
21
21
  onChange={handleChange}
22
22
  />
23
- </FormField.Field>
24
- </FormField>
23
+ </FormFieldGroup.Field>
24
+ </FormFieldGroup>
25
25
  );
26
26
  };
@@ -1,9 +1,10 @@
1
1
  import {ExampleCodeBlock, SymbolDoc} from '@workday/canvas-kit-docs';
2
+ import BaseHtmlTable from './examples/BaseHtmlTable';
2
3
  import Basic from './examples/Basic';
3
4
  import BasicWithHeading from './examples/BasicWithHeading';
4
5
  import FixedColumn from './examples/FixedColumn';
5
6
  import RightToLeft from './examples/RightToLeft';
6
- import BaseHtmlTable from './examples/BaseHtmlTable';
7
+
7
8
 
8
9
  # Canvas Kit Table
9
10
 
@@ -77,12 +78,16 @@ use the `BaseTable` component.
77
78
 
78
79
  ### Advanced
79
80
 
80
- You can also find several advanced Table examples in our Storybook Examples section.
81
+ You can also find several advanced Table examples in our
82
+ [Guides > Accessibility > Table Patterns](?path=/docs/guides-accessibility-table-patterns--docs)
83
+ section.
81
84
 
82
- - [Expandable Rows](https://workday.github.io/canvas-kit/?path=/docs/guides-accessibility-examples-advanced-tables--docs#expandable-rows)
83
- - [Selectable Rows ](https://workday.github.io/canvas-kit/?path=/docs/guides-accessibility-examples-advanced-tables--docs#selectable-rows)
84
- - [Filterable Column Headers](https://workday.github.io/canvas-kit/?path=/docs/guides-accessibility-examples-advanced-tables--docs#filterable-column-headers)
85
- - [Sortable Column Headers](https://workday.github.io/canvas-kit/?path=/docs/guides-accessibility-examples-advanced-tables--docs#sortable-column-headers)
85
+ - [Expandable Rows](?path=/docs/guides-accessibility-table-patterns-expandable-rows--docs)
86
+ - [Nested Rows](?path=/docs/guides-accessibility-table-patterns-nested-rows--docs)
87
+ - [Selectable Rows](?path=/docs/guides-accessibility-table-patterns-selectable-rows--docs)
88
+ - [Filterable Column Headers](?path=/docs/guides-accessibility-table-patterns-filterable-column-headers--docs)
89
+ - [Sortable Column Headers](?path=/docs/guides-accessibility-table-patterns-sortable-column-headers--docs)
90
+ - [With Form Fields](?path=/docs/guides-accessibility-table-patterns-with-form-fields--docs)
86
91
 
87
92
  ### Custom Styles
88
93
 
@@ -90,6 +95,176 @@ Table and its subcomponents support custom styling via the `cs` prop. For more i
90
95
  our
91
96
  ["How To Customize Styles"](https://workday.github.io/canvas-kit/?path=/docs/styling-guides-customizing-styles--docs).
92
97
 
98
+ ## Accessibility
99
+
100
+ `Table` is a styled compound wrapper around native HTML table elements (`<table>`, `<caption>`,
101
+ `<thead>`, `<tbody>`, `<tfoot>`, `<tr>`, `<th>`, `<td>`). Assistive technology can announce column
102
+ and row headers as users move through cells **only when** the markup is a real data table with
103
+ correct headers and an accessible name. `Table` does **not** include a model, roving tabindex, or
104
+ built-in sort, filter, selection, or expand behavior.
105
+
106
+ Use `Table` for tabular data with a relationship between rows and columns—not for page layout.
107
+ Prefer **`Table`** (CSS Grid) unless the design needs a standard HTML table layout without Grid;
108
+ then use **`BaseTable`**. The same accessibility requirements apply to both. For interactive table
109
+ patterns, follow
110
+ [Guides > Accessibility > Table Patterns](?path=/docs/guides-accessibility-table-patterns--docs)
111
+ instead of inventing ARIA. See also
112
+ [Table Pattern | APG | WAI | W3C](https://www.w3.org/WAI/ARIA/apg/patterns/table/).
113
+
114
+ ### Minimum accessible structure
115
+
116
+ The following matches the [Example with Caption](#example-with-caption) (`Basic` story): native
117
+ table markup with **`Table.Caption`** as the accessible name and **`scope="col"`** on column
118
+ headers. The [Basic Example](#basic-example) uses a visible **`Heading`** and **`aria-labelledby`**
119
+ instead of a caption; that is an equally valid naming pattern (see **Accessibility Requirements**).
120
+
121
+ ```tsx
122
+ import {Table} from '@workday/canvas-kit-react/table';
123
+
124
+ <Table>
125
+ <Table.Caption>Coffee Drinks and Sizes</Table.Caption>
126
+ <Table.Head>
127
+ <Table.Row>
128
+ <Table.Header scope="col">Drink</Table.Header>
129
+ <Table.Header scope="col">Size</Table.Header>
130
+ </Table.Row>
131
+ </Table.Head>
132
+ <Table.Body>
133
+ <Table.Row>
134
+ <Table.Cell>Espresso</Table.Cell>
135
+ <Table.Cell>1 oz</Table.Cell>
136
+ </Table.Row>
137
+ <Table.Row>
138
+ <Table.Cell>Macchiato</Table.Cell>
139
+ <Table.Cell>2 oz Espresso</Table.Cell>
140
+ </Table.Row>
141
+ </Table.Body>
142
+ </Table>;
143
+ ```
144
+
145
+ Put **`Table.Caption`** first when you use it (HTML requires `<caption>` as the first child of
146
+ `<table>`). Pair every column header with **`scope="col"`**. Do not render empty **`Table.Row`**
147
+ elements.
148
+
149
+ ### Built-in Behaviors
150
+
151
+ Canvas Kit applies these automatically when you compose `Table` (or `BaseTable`) with its
152
+ subcomponents. **Do not duplicate them** in consuming code.
153
+
154
+ **Native table semantics** (_applied by `createComponent` element mapping_):
155
+
156
+ - `Table`: `<table>`
157
+ - `Table.Caption`: `<caption>`
158
+ - `Table.Head`: `<thead>`
159
+ - `Table.Body`: `<tbody>`
160
+ - `Table.Footer`: `<tfoot>`
161
+ - `Table.Row`: `<tr>` (`Table.Row` also sets CSS Grid column tracks from the count of valid child
162
+ cells; this is layout only)
163
+ - `Table.Header`: `<th>`
164
+ - `Table.Cell`: `<td>`
165
+
166
+ **Keyboard** (_standard `Table` behavior_):
167
+
168
+ `Table` uses native `<table>` keyboard behavior. Do not add custom key handlers or grid-widget keys
169
+ on a data table.
170
+
171
+ When **`Table`** overflows (the root stencil uses `overflow: auto`), add **`tabIndex={0}`** so
172
+ keyboard users can focus and scroll it, as in the [Fixed Column](#fixed-column) example. Omit
173
+ **`tabIndex`** when the table does not scroll.
174
+
175
+ **Screen reader expectations** (_when built-in behaviors are used as intended_):
176
+
177
+ - The table is announced as a table, with its accessible name from **`Table.Caption`** or
178
+ **`aria-labelledby`** / **`aria-label`** on **`Table`**
179
+ - Moving across a row announces the **column** header (`scope="col"`)
180
+ - Moving down a column announces the **row** header when body cells use **`Table.Header`** with
181
+ **`scope="row"`**
182
+ - Interactive controls inside cells are announced with their own name and role when focused
183
+
184
+ ### Accessibility Requirements
185
+
186
+ Required in application code for an accessible `Table`. There is **no** `useTableModel`. Canvas Kit
187
+ does **not** set `scope`, an accessible name, `tabIndex`, or `id` / `headers` cell associations —
188
+ supply those in application code when the table below requires them. Rows marked _(conditional)_
189
+ apply only when the situation matches—otherwise omit.
190
+
191
+ **If no design spec is provided:** generate a simple data table with **`Table.Caption`**,
192
+ **`Table.Head`** / **`Table.Body`**, **`scope="col"`** on column headers, and **`Table.Cell`** for
193
+ body data. Omit **`Table.Footer`**, row headers, **`tabIndex`**, `id` / `headers` associations,
194
+ **`aria-sort`**, **`aria-expanded`**, **`aria-level`**, selection checkboxes, and filter/sort popups
195
+ unless the spec calls for those patterns.
196
+
197
+ **Heading instead of caption** _(conditional)_:
198
+
199
+ When the design uses a visible heading (or other text) instead of **`Table.Caption`**, give that
200
+ heading a unique `id` and set **`aria-labelledby`** on **`Table`**. Do not also render
201
+ **`Table.Caption`** unless the design needs both a caption and extra labelling. See
202
+ [Basic Example](#basic-example).
203
+
204
+ ```tsx
205
+ <Heading as="h3" id={headingId}>
206
+ Pizza Toppings
207
+ </Heading>
208
+ <Table aria-labelledby={headingId}>{/* … */}</Table>
209
+ ```
210
+
211
+ **Interactive and advanced patterns** _(conditional)_:
212
+
213
+ Do not invent table ARIA. Copy the matching Canvas Kit guide when the spec includes that behavior:
214
+
215
+ - [Expandable Rows](?path=/docs/guides-accessibility-table-patterns-expandable-rows--docs)
216
+ - [Nested Rows](?path=/docs/guides-accessibility-table-patterns-nested-rows--docs)
217
+ - [Selectable Rows](?path=/docs/guides-accessibility-table-patterns-selectable-rows--docs)
218
+ - [Filterable Column Headers](?path=/docs/guides-accessibility-table-patterns-filterable-column-headers--docs)
219
+ - [Sortable Column Headers](?path=/docs/guides-accessibility-table-patterns-sortable-column-headers--docs)
220
+ - [With Form Fields](?path=/docs/guides-accessibility-table-patterns-with-form-fields--docs)
221
+
222
+ | Requirement | How to satisfy |
223
+ | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
224
+ | Data table, not layout | Compose **`Table`** (or **`BaseTable`**) with **`Head`**, **`Body`**, **`Row`**, **`Header`**, and **`Cell`**. Do not use a table to position non-tabular UI. |
225
+ | Accessible name | **`Table.Caption`** with a descriptive title, **or** **`aria-labelledby`** on **`Table`** pointing at a visible heading `id` (see **Heading instead of caption**). Canvas Kit does not set **`aria-labelledby`**. |
226
+ | Column headers | Set **`scope="col"`** on every **`Table.Header`** in **`Table.Head`**. **`Table.Header`** renders `<th>` but does not set `scope`. Do not use **`Table.Cell`** (`<td>`) for column headers. |
227
+ | Row headers _(conditional)_ | When the first (or identifying) column names each row, set **`scope="row"`** on **`Table.Header`** in the body, as in [Fixed Column](#fixed-column). Do not rely on `<th>` alone. |
228
+ | Keyboard access to overflow _(conditional)_ | If the table scrolls, set **`tabIndex={0}`** on **`Table`**. Omit it when content does not overflow. |
229
+ | Footer _(conditional)_ | **`Table.Footer`** only when the design includes summary or footer rows. |
230
+ | Form controls in cells _(conditional)_ | Label every control (prefer **`FormField`**). See [With Form Fields](?path=/docs/guides-accessibility-table-patterns-with-form-fields--docs) and [Form Field](?path=/docs/components-inputs-form-field--docs). |
231
+ | Sort, filter, select, expand, or nest _(conditional)_ | Follow the matching [Table Patterns](?path=/docs/guides-accessibility-table-patterns--docs) guide. **Ask the developer** which pattern the spec requires before generating `aria-sort`, `aria-expanded`, `aria-level`, `aria-owns`, live regions, or selection checkboxes. |
232
+
233
+ **Summary for code generation:**
234
+
235
+ - **REQUIRED:** semantic `Table` composition, accessible name (caption or `aria-labelledby`),
236
+ `scope="col"` on column headers
237
+ - **CONDITIONAL:** heading + `aria-labelledby`, `scope="row"`, `tabIndex={0}` for overflow,
238
+ `Table.Footer`, form-field labelling in cells, advanced table patterns from the guides
239
+
240
+ ### Anti-Patterns
241
+
242
+ Do **not** generate code that does the following (see **Accessibility Requirements** above for what
243
+ to supply instead):
244
+
245
+ - Manually set `role="table"`, `role="row"`, `role="columnheader"`, `role="rowheader"`, or
246
+ `role="cell"` on **`Table`** subcomponents — they already render native table elements
247
+ - Omit **`scope`** on **`Table.Header`**, or use **`Table.Cell`** for column or row headers
248
+ - Generate `id` / `headers` associations on cells for a simple data table — use **`scope`** instead
249
+ (see **Accessibility Requirements**)
250
+ - Leave the table unnamed (no **`Table.Caption`**, **`aria-labelledby`**, or **`aria-label`**), or
251
+ set **`aria-labelledby`** when **`Table.Caption`** already names the table
252
+ - Use a table for page layout
253
+ - Add **`tabIndex={0}`** on a table that does not scroll, or omit it on a horizontally/vertically
254
+ scrollable table
255
+ - Set **`aria-sort`**, **`aria-expanded`**, **`aria-level`**, **`aria-owns`**, or selection
256
+ checkboxes by default — those belong to specific
257
+ [Table Patterns](?path=/docs/guides-accessibility-table-patterns--docs) and need a matching design
258
+ spec
259
+ - Nest a `<table>` inside a cell to fake hierarchy, or add extra **`Table.Body`** elements to fake a
260
+ tree — see [Nested Rows](?path=/docs/guides-accessibility-table-patterns-nested-rows--docs)
261
+ - Put a "Select All" checkbox in a column header **`Table.Header`** without following
262
+ [Selectable Rows](?path=/docs/guides-accessibility-table-patterns-selectable-rows--docs)
263
+ - Place unlabeled inputs in cells, or rely on the column header alone without checking
264
+ [With Form Fields](?path=/docs/guides-accessibility-table-patterns-with-form-fields--docs)
265
+ - Generate **`role="grid"`** / grid-widget keyboard behavior on **`Table`** — CSS Grid on
266
+ **`Table.Row`** is visual layout, not an ARIA grid
267
+
93
268
  ## Component API
94
269
 
95
270
  <SymbolDoc name="Table" fileName="/react/" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workday/canvas-kit-docs",
3
- "version": "16.0.14",
3
+ "version": "16.0.16",
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": "^16.0.14",
51
- "@workday/canvas-kit-preview-react": "^16.0.14",
52
- "@workday/canvas-kit-react": "^16.0.14",
53
- "@workday/canvas-kit-styling": "^16.0.14",
50
+ "@workday/canvas-kit-labs-react": "^16.0.16",
51
+ "@workday/canvas-kit-preview-react": "^16.0.16",
52
+ "@workday/canvas-kit-react": "^16.0.16",
53
+ "@workday/canvas-kit-styling": "^16.0.16",
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": "dd1a615f55e73a45836ac2ef7056dc1fb95ba1cd"
66
+ "gitHead": "ecd8756a79137742567e511e64bb7f1fa14f659c"
67
67
  }
@@ -1,21 +0,0 @@
1
- import {ExampleCodeBlock} from '@workday/canvas-kit-docs';
2
-
3
- import InlinePortalPopup from './examples/Popups/InlinePortalPopup';
4
-
5
-
6
- ## Inline portal with `PopupStack`
7
-
8
- This example builds on the patterns described in
9
- [Guides > Accessibility > Inline Popups](?path=/docs/guides-accessibility-inline-popups--docs). It
10
- does **not** use a focus trap. For modal dialogs with overlay and focus trap, use the
11
- [**Modal**](?path=/docs/components-popups-modal--docs) component instead.
12
-
13
- Keep using a portal (default stacking and positioning) but mount the portal **into a sentinel
14
- element** placed right after the trigger. Call `PopupStack.pushStackContext(sentinelElement)` while
15
- the popup is open so new stack items append to that sentinel instead of `body`. **Tradeoff:** You
16
- still get **ancestor overflow** clipping—the portaled content is a descendant of the sentinel, not
17
- `document.body`. You must also handle **`PopupStack` context** (push/pop on open/close), which is
18
- more moving parts than `portal={false}` alone. Use **`useInitialFocus`** so opening the popup is
19
- announced when focus enters the dialog.
20
-
21
- <ExampleCodeBlock code={InlinePortalPopup} />
@@ -1,126 +0,0 @@
1
- import {ExampleCodeBlock} from '@workday/canvas-kit-docs';
2
-
3
- import SelectableRows from './examples/Table/WithSelectableRows';
4
- import ExpandableRows from './examples/Table/WithExpandableRows';
5
- import SortableColumnHeaders from './examples/Table/WithSortableColumnHeaders';
6
- import FilterableColumnHeaders from './examples/Table/WithColumnHeaderFilters';
7
-
8
-
9
- ## Advanced Table Examples
10
-
11
- Tables should only be used to organize data that has a clear relationship between rows and columns,
12
- like a calendar or a schedule. Never use a table just for page layout.
13
-
14
- When you use the proper HTML table markup, a screen reader can help a user navigate the table. It
15
- will automatically read the column and row headers as they move through the data, so they always
16
- know what information they're looking at.
17
-
18
- - All tables should have a clear header and a descriptive title.
19
- - Keep your tables simple. If a table is too complex, it might be better to break it up into several
20
- smaller tables or use a different format.
21
-
22
- Out of the box, `Table` is a lightweight compound component with a high degree of flexibility, but
23
- not much functionality outside of providing a basic table layout. This flexibility lets developers
24
- implement common features, such as selecting rows and sorting columns, on top of `Table` to meet
25
- their specific application needs.
26
-
27
- The Workday Accessibility Team has researched and developed the following examples below to
28
- demonstrate how to build these accessible table patterns. We've listed the specific considerations
29
- and decisions we've made for each of the examples.
30
-
31
- ### Expandable Rows
32
-
33
- Expandable Rows combines the likes of an accordion with tabular data tables. Column 1 renders icon
34
- buttons with 2 states, a collapsed and expanded state. A new row that spans the entire width of the
35
- table is added to the table just after the expanded row.
36
-
37
- - The `aria-expanded` property is added to the chevron button to communicate this state to screen
38
- reader users.
39
- - A Canvas accessible `Tooltip` component is used to assign names to each icon button based on the
40
- most useful value in the row. In this example, we combined the car make (in column 1) and model
41
- (in column 2) together. This allows everyone to view the name of the icon buttons by hovering the
42
- mouse or focusing with the keyboard.
43
- - The expanded row uses `colspan` to span the entire width of the table and support screen readers.
44
- This space provides flexibility to show headings, lists, and other structured content for the
45
- table row above.
46
- - There is no explicit relationship between a row of cells and the spanned content below it. The
47
- spanned content is assumed to belong to the row of cells above it, based on established accordion
48
- patterns and logical reading order of content rendered to the screen.
49
- - Outlining hierarchy with additional nested rows in the table is not supported for screen readers
50
- in this example.
51
-
52
- <ExampleCodeBlock code={ExpandableRows} />
53
-
54
- ### Selectable Rows
55
-
56
- Using a `Checkbox` labeled "Select All" inside of a column header can be a confusing experience for
57
- screen reader users. Screen readers will automatically announce the "Select All" label in the column
58
- header each time users are reading any of the Check boxes in the first column. For instance, the
59
- `Checkbox` in row 4 is definitely not going to select all of the rows. Here is what we did about it:
60
-
61
- - We intentionally rendered row 1, column 1 as a standard `<td>` element so screen readers won't
62
- automatically announce the "Select All" label while reading cells in column 1.
63
- - Our research found that VoiceOver (MacOS v12.7, Safari v17.1) persistently announce "Select All"
64
- despite using the `<td>` element because of the optional `<thead>` element in the table. We
65
- omitted the optional `<thead>` and `<tbody>` elements from this example for that reason.
66
- - We used Canvas' accessible `Tooltip` component to assign names to each Checkbox based on the most
67
- useful value in the row, the topping name. This allows everyone to view the name of the checkboxes
68
- by hovering the mouse or focusing with the keyboard.
69
- - We rendered the cells in column 2 as the row headers for the table, enabling screen readers to
70
- automatically announce the topping name even while reading down the Amounts in column 3. When we
71
- rendered column 1 as row headers, then reading down column 2 (Topping Name) sounded redundant
72
- because the `Checkbox` names in column 1 are identical to the Topping Name in column 2.
73
-
74
- <ExampleCodeBlock code={SelectableRows} />
75
-
76
- ### Filterable Column Headers
77
-
78
- In this example, we demonstrate using the `Popup` component in each column header allowing users to
79
- search and filter the data on the table. The `Popup` component relies on React Portals to render the
80
- popup elements at the bottom of the browser's DOM presenting 2 key challenges for accessibility:
81
-
82
- 1. Keyboard focus order of the elements in the popup,
83
- 2. Screen readers' reading order of the content rendered in the browser.
84
-
85
- Here's what we did about it:
86
-
87
- - Canvas Kit includes a `usePopupModel` hook, with quite a few additional hooks developers can add
88
- to their models. In particular, the `useFocusRedirect` hook manages keyboard focus between the
89
- `<Popup.Target>` button and the popup content.
90
- - The `useInitialFocus` hook allows developers to specify which element receives keyboard focus when
91
- the popup appears. In this example, we auto-focused the search input field.
92
- - To address the reading order of content, we set the `aria-owns` property onto the parent
93
- `<Table.Header>` component (`<th>` DOM element) with 2 unique `id` values. The first `id` refers
94
- to the `<Popup.Target>` button and the second refers to the `<Popup.Card>` container element. This
95
- manually reassigns the column header's `<Popup.Target>` button and the `Popup` contents as
96
- siblings in the browser's accessibility tree hierarchy. Screen readers **should** read the column
97
- header buttons and the popup content in sequential order even though they are not siblings in the
98
- DOM.
99
- - The `type='description'` variant of the Canvas `Tooltip` is used to communicate the filtered state
100
- of the column header, and assigned to the accessible description of the column header
101
- `<TertiaryButton>` component.
102
- - The Canvas `AriaLiveRegion` component is used to render the "X of Y items" status inside the table
103
- caption. This enables screen readers to automatically describe the filter state changes of the
104
- table content to users in real time. We recommend validating whether this use of a live region is
105
- well supported for your screen reader and browser combinations first.
106
-
107
- <ExampleCodeBlock code={FilterableColumnHeaders} />
108
-
109
- ### Sortable Column Headers
110
-
111
- The challenge in this example is to provide all of the necessary information about the interactive
112
- column headers, the sort state of the column, and instructions about how the table will be sorted
113
- without giving too much information to users while reading the data cells below.
114
-
115
- - The `aria-sort` property has been added to each of the `<Table.Header>` components (`<th>` DOM
116
- element) and updated to `ascending` or `descending` to reflect the current sort state. We
117
- recommend validating whether this property is well supported for your screen reader and browser
118
- combinations first.
119
- - A `<TertiaryButton>` describing the column name is used inside of the `<Table.Header>` component.
120
- - The `description` variant of the Canvas `Tooltip` component is applied to the button in the column
121
- header and applied to the accessible description of the button with the `aria-description`
122
- property. This is used to describe how the column will be sorted when pressed and screen readers
123
- will only read this description while focusing on the column headers, not while reading the data
124
- cells below.
125
-
126
- <ExampleCodeBlock code={SortableColumnHeaders} />