Skip to content

Commit c59ea1b

Browse files
authored
docs(grid): enhance README with detailed usage, options, and accessibility information (#5810)
1 parent 4cffef3 commit c59ea1b

File tree

1 file changed

+160
-9
lines changed

1 file changed

+160
-9
lines changed

tools/grid/README.md

Lines changed: 160 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,183 @@
1-
## Description
1+
## Overview
22

3-
An `<sp-grid>` element displays a virtualized grid of elements built from its `items`, a normalized array of javascript objects, applied to a supplied `renderItem`, a `TemplateResult` returning method. `sp-grid` is a class extension of [`lit-virtualizer`](https://www.npmjs.com/package/@lit-labs/virtualizer/v/0.7.0-pre.2) and as such surfaces all of its underlying methods and events.
4-
5-
Elements displayed in the grid can be focused via the [roving tabindex](https://www.w3.org/TR/wai-aria-practices-1.2/#kbd_roving_tabindex) that allows the grid to be entered via the `Tab` key and then subsequent elements to be focused via the arrow keys. To inform the `<sp-grid>` element what part of the DOM created by the `renderItem` method can be focused, supply a value to `focusableSelector`. Focus will always enter the element list at index 0 of ALL available elements, not just those currently realized to the page.
6-
7-
Elements rendered via `renderItem` can have their width and height customized by supplying a value for `itemSize` that accepts an object: `{ width: number, height: number }`. You can customize the space between these elements via the `gap` property that accepts a value of `0` or `${number}px`.
3+
An `<sp-grid>` element displays a virtualized grid of elements built from its `items`, a normalized array of JavaScript objects, applied to a supplied `renderItem`, a `TemplateResult` returning method. The `<sp-grid>` is a class extension of [`lit-virtualizer`](https://www.npmjs.com/package/@lit-labs/virtualizer/v/0.7.0-pre.2) and as such surfaces all of its underlying methods and events.
84

95
### Usage
106

117
[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/grid?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/grid)
128
[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/grid?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/grid)
139

14-
```
10+
```bash
1511
yarn add @spectrum-web-components/grid
1612
```
1713

1814
Import the side effectful registration of `<sp-grid>` via:
1915

20-
```
16+
```javascript
2117
import '@spectrum-web-components/grid/sp-grid.js';
2218
```
2319

2420
When looking to leverage the `Grid` base class as a type and/or for extension purposes, do so via:
2521

26-
```
22+
```javascript
2723
import { Grid } from '@spectrum-web-components/grid';
2824
```
2925

26+
### Anatomy
27+
28+
The grid consists of several key parts:
29+
30+
- A virtualized container that efficiently renders only visible items
31+
- Individual grid items rendered via the `renderItem` method
32+
- A roving tabindex system for keyboard navigation
33+
- Configurable layout properties for item sizing and spacing
34+
35+
```html
36+
<sp-grid id="basic-grid"></sp-grid>
37+
<script type="module">
38+
const grid = document.querySelector('#basic-grid');
39+
grid.items = [{ name: 'Item 1' }, { name: 'Item 2' }, { name: 'Item 3' }];
40+
grid.renderItem = (item) => {
41+
const div = document.createElement('div');
42+
div.textContent = item.name;
43+
return div;
44+
};
45+
</script>
46+
```
47+
48+
### Options
49+
50+
#### Properties
51+
52+
The grid supports several properties for configuration:
53+
54+
##### Items
55+
56+
The `items` property accepts a normalized array of JavaScript objects that will be rendered in the grid:
57+
58+
```javascript
59+
const grid = document.querySelector('sp-grid');
60+
grid.items = [
61+
{ name: 'Card 1', date: '10/15/18' },
62+
{ name: 'Card 2', date: '10/16/18' },
63+
{ name: 'Card 3', date: '10/17/18' },
64+
];
65+
```
66+
67+
##### Render Item
68+
69+
The `renderItem` property is a function that receives an item, index, and selected state, and returns a DOM element to be rendered:
70+
71+
```javascript
72+
grid.renderItem = (item, index, selected) => {
73+
const card = document.createElement('sp-card');
74+
card.heading = item.name;
75+
card.selected = selected;
76+
return card;
77+
};
78+
```
79+
80+
##### Item Size
81+
82+
Control the dimensions of each grid item using the `itemSize` property, which accepts an object with `width` and `height` properties:
83+
84+
```javascript
85+
grid.itemSize = {
86+
width: 200,
87+
height: 300,
88+
};
89+
```
90+
91+
##### Gap
92+
93+
Customize the space between grid items via the `gap` property, which accepts a value of `0` or `${number}px`:
94+
95+
```javascript
96+
grid.gap = '10px';
97+
```
98+
99+
##### Focusable Selector
100+
101+
Specify which element within the rendered item can receive focus by providing a CSS selector to the `focusableSelector` property:
102+
103+
```javascript
104+
grid.focusableSelector = 'sp-card';
105+
```
106+
107+
This informs the `<sp-grid>` element what part of the DOM created by the `renderItem` method can be focused via keyboard navigation.
108+
109+
### Behaviors
110+
111+
#### Virtualization
112+
113+
The `<sp-grid>` uses virtualization to efficiently render large lists of items. Only the items visible in the viewport (plus a small buffer) are rendered to the DOM, which significantly improves performance for large datasets. As you scroll, the grid dynamically updates which items are rendered.
114+
115+
#### Focus Management
116+
117+
Elements displayed in the grid can be focused via the [roving tabindex](https://www.w3.org/TR/wai-aria-practices-1.2/#kbd_roving_tabindex) pattern. This allows the grid to be entered via the <kbd>Tab</kbd> key and then subsequent elements to be focused via the arrow keys.
118+
119+
Focus will always enter the element list at index 0 of all available elements, not just those currently realized to the page.
120+
121+
#### Selection Management
122+
123+
The grid supports selection of items. You can maintain a `selectedItems` array and update it based on user interactions:
124+
125+
```javascript
126+
grid.selectedItems = [];
127+
128+
grid.renderItem = (item, index, selected) => {
129+
const card = document.createElement('sp-card');
130+
card.selected = grid.selectedItems.includes(card.value);
131+
card.addEventListener('change', () => {
132+
if (grid.selectedItems.includes(card.value)) {
133+
grid.selectedItems = grid.selectedItems.filter(
134+
(item) => item !== card.value
135+
);
136+
} else {
137+
grid.selectedItems.push(card.value);
138+
}
139+
});
140+
return card;
141+
};
142+
```
143+
144+
### Accessibility
145+
146+
The `<sp-grid>` is designed with accessibility in mind and follows ARIA best practices for grid patterns.
147+
148+
#### Keyboard Navigation
149+
150+
The grid supports keyboard navigation through the roving tabindex pattern:
151+
152+
- <kbd>Tab</kbd>: Enter the grid (focus moves to first item)
153+
- <kbd>Arrow Keys</kbd>: Navigate between grid items
154+
- Focus always starts at index 0 of all available elements
155+
156+
#### ARIA Attributes
157+
158+
When implementing a grid, ensure you provide appropriate ARIA attributes for screen reader support:
159+
160+
```javascript
161+
grid.role = 'grid';
162+
grid.ariaLabel = 'Select images';
163+
grid.ariaMultiSelectable = 'true';
164+
grid.ariaRowCount = `${grid.items.length}`;
165+
grid.ariaColCount = 1;
166+
```
167+
168+
Additionally, each rendered item should have appropriate ARIA attributes:
169+
170+
```javascript
171+
card.role = 'row';
172+
card.label = `Card Heading ${index}`;
173+
card.ariaSelected = grid.selectedItems.includes(card.value);
174+
card.ariaRowIndex = `${index + 1}`;
175+
```
176+
177+
#### Focusable Elements
178+
179+
Use the `focusableSelector` property to specify which elements within each grid item should receive focus. This ensures that keyboard users can navigate to interactive elements within the grid.
180+
30181
## Example
31182

32183
To interact with a fully accessible grid example, reference our [Grid Storybook](https://opensource.adobe.com/spectrum-web-components/storybook/index.html?path=/story/grid/) documentation.

0 commit comments

Comments
 (0)