Skip to content

Commit 291d095

Browse files
authored
docs: add GridListSection to the docs (#9447)
* docs: add gridlist section to docs * add gridlist section to tailwind starter * fix space * fix css * fix gridlistheader prop table * update css * make heading larger
1 parent ea7c913 commit 291d095

File tree

5 files changed

+198
-4
lines changed

5 files changed

+198
-4
lines changed

packages/dev/s2-docs/pages/react-aria/GridList.mdx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import vanillaDocs from 'docs:vanilla-starter/GridList';
77
import '../../tailwind/tailwind.css';
88
import Anatomy from 'react-aria-components/docs/GridListAnatomy.svg';
99
import {InlineAlert, Heading, Content} from '@react-spectrum/s2'
10+
import {VersionBadge} from '../../src/VersionBadge';
1011

1112
export const tags = ['list view'];
1213
export const relatedPages = [
@@ -532,6 +533,57 @@ import {GridList} from 'vanilla-starter/GridList';
532533
</GridList>
533534
```
534535

536+
### Sections <VersionBadge version="alpha" />
537+
538+
Use the `<GridListSection>` component to group options. A `<GridListHeader>` element may also be included to label the section. Sections without a header must have an `aria-label`.
539+
540+
```tsx render
541+
"use client";
542+
import {GridList, GridListItem} from 'vanilla-starter/GridList';
543+
import {GridListHeader, GridListSection, Text} from 'react-aria-components';
544+
545+
<GridList
546+
layout="grid"
547+
aria-label="Photos">
548+
<GridListSection>
549+
<GridListHeader>Fruit</GridListHeader>
550+
<GridListItem textValue="Apple">
551+
<img src="https://images.unsplash.com/photo-1630563451961-ac2ff27616ab?q=80&w=687&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={400} />
552+
<Text>Apple</Text>
553+
<Text slot="description">PNG • 9/2/2021</Text>
554+
</GridListItem>
555+
<GridListItem textValue="Peach">
556+
<img src="https://images.unsplash.com/photo-1642372849486-f88b963cb734?q=80&w=2858&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
557+
<Text>Peach</Text>
558+
<Text slot="description">JPEG • 1/16/2022</Text>
559+
</GridListItem>
560+
<GridListItem textValue="Blueberry">
561+
<img src="https://images.unsplash.com/photo-1606757389667-45c2024f9fa4?q=80&w=1740&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
562+
<Text>Blueberry</Text>
563+
<Text slot="description">JPEG • 11/30/2020</Text>
564+
</GridListItem>
565+
</GridListSection>
566+
<GridListSection>
567+
<GridListHeader>Vegetables</GridListHeader>
568+
<GridListItem textValue="Broccoli">
569+
<img src="https://images.unsplash.com/photo-1685504445355-0e7bdf90d415?q=80&w=928&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
570+
<Text>Broccoli</Text>
571+
<Text slot="description">PNG • 5/30/2023</Text>
572+
</GridListItem>
573+
<GridListItem textValue="Brussels Sprouts">
574+
<img src="https://images.unsplash.com/photo-1685504507286-dc290728c01a?q=80&w=1740&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
575+
<Text>Brussels Sprouts</Text>
576+
<Text slot="description">PNG • 7/3/2021</Text>
577+
</GridListItem>
578+
<GridListItem textValue="Peas">
579+
<img src="https://images.unsplash.com/photo-1587411768345-867e228218c8?q=80&w=1160&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
580+
<Text>Peas</Text>
581+
<Text slot="description">PNG • 4/20/2020</Text>
582+
</GridListItem>
583+
</GridListSection>
584+
</GridList>
585+
```
586+
535587
## Selection and actions
536588

537589
Use the `selectionMode` prop to enable single or multiple selection. The selected items can be controlled via the `selectedKeys` prop, matching the `id` prop of the items. The `onAction` event handles item actions. Items can be disabled with the `isDisabled` prop. See the [selection guide](selection?component=GridList) for more details.
@@ -931,6 +983,14 @@ function Example() {
931983

932984
<PropTable component={docs.exports.GridList} links={docs.links} showDescription />
933985

986+
### GridListSection
987+
988+
<PropTable component={docs.exports.GridListSection} links={docs.links} showDescription />
989+
990+
### GridListHeader
991+
992+
`<GridListHeader>` labels the section within a GridList. It accepts all HTML attributes.
993+
934994
### GridListItem
935995

936996
<PropTable component={docs.exports.GridListItem} links={docs.links} showDescription />

starters/docs/src/GridList.css

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
@import "./theme.css";
22

33
.react-aria-GridList {
4-
display: grid;
54
justify-content: center;
65
gap: var(--spacing-4);
76
padding: var(--spacing-2);
@@ -17,23 +16,42 @@
1716
box-sizing: border-box;
1817
--grid-item-size: 200px;
1918

20-
&[data-layout=grid] {
19+
&[data-layout=grid]:not(:has(.react-aria-GridListSection)) {
20+
display: grid;
2121
grid-template-columns: repeat(auto-fit, minmax(100px, var(--grid-item-size)));
2222
grid-auto-rows: min-content;
2323
}
2424

25+
&[data-layout=grid] > .react-aria-GridListSection {
26+
grid-template-columns: repeat(auto-fit, minmax(100px, var(--grid-item-size)));
27+
grid-auto-rows: min-content;
28+
}
29+
30+
.react-aria-GridListSection:not(:first-child) {
31+
margin-top: var(--spacing-4);
32+
}
33+
34+
&[data-layout=stack] > .react-aria-GridListSection {
35+
grid-template-columns: auto;
36+
align-items: center;
37+
}
38+
2539
&[data-size=small] {
2640
--grid-item-size: 150px;
2741
}
2842

2943
@media (width < 500px) {
3044
&[data-layout=grid] {
3145
--grid-item-size: 150px;
46+
}
47+
48+
&[data-layout=grid]:not(:has(.react-aria-GridListSection)) {
3249
grid-template-columns: 1fr 1fr;
3350
}
3451
}
3552

3653
&[data-layout=stack] {
54+
display: grid;
3755
grid-template-columns: auto;
3856
align-items: center;
3957
}
@@ -228,3 +246,34 @@
228246
height: 24px;
229247
width: 100%;
230248
}
249+
250+
.react-aria-GridListSection {
251+
display: grid;
252+
justify-content: center;
253+
gap: var(--spacing-4);
254+
color: var(--text-color);
255+
width: 100%;
256+
257+
> .react-aria-GridListHeader {
258+
grid-column: 1 / -1;
259+
}
260+
}
261+
262+
.react-aria-GridListHeader {
263+
position: sticky;
264+
z-index: 2;
265+
top: -8px;
266+
font-size: var(--font-size-lg);
267+
font-weight: 500;
268+
background: var(--gray-100);
269+
border-block: 0.5px solid var(--gray-400);
270+
cursor: default;
271+
user-select: none;
272+
box-shadow: inset 0px 1px 0px white, inset 0px -4px 8px var(--gray-200);
273+
border-radius: var(--radius);
274+
padding: var(--spacing-1) var(--spacing-4);
275+
276+
@media (prefers-color-scheme: dark) {
277+
box-shadow: inset 0px 4px 8px var(--gray-200);
278+
}
279+
}

starters/docs/stories/GridList.stories.tsx

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {GridList, GridListItem} from '../src/GridList';
2-
import {Text} from 'react-aria-components';
2+
import {Text, GridListSection, GridListHeader} from 'react-aria-components';
33

44
import type {Meta, StoryFn} from '@storybook/react';
55

@@ -77,3 +77,54 @@ Example.args = {
7777
selectionMode: 'multiple',
7878
layout: 'grid'
7979
};
80+
81+
82+
export const Sections: Story = (args) => (
83+
<GridList
84+
{...args}
85+
style={{width: 800, maxWidth: 'calc(100vw - 80px)'}}
86+
aria-label="Photos">
87+
<GridListSection>
88+
<GridListHeader>Fruit</GridListHeader>
89+
<GridListItem textValue="Apple">
90+
<img src="https://images.unsplash.com/photo-1630563451961-ac2ff27616ab?q=80&w=687&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={400} />
91+
<Text>Apple</Text>
92+
<Text slot="description">PNG • 9/2/2021</Text>
93+
</GridListItem>
94+
<GridListItem textValue="Peach">
95+
<img src="https://images.unsplash.com/photo-1642372849486-f88b963cb734?q=80&w=2858&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
96+
<Text>Peach</Text>
97+
<Text slot="description">JPEG • 1/16/2022</Text>
98+
</GridListItem>
99+
<GridListItem textValue="Blueberry">
100+
<img src="https://images.unsplash.com/photo-1606757389667-45c2024f9fa4?q=80&w=1740&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
101+
<Text>Blueberry</Text>
102+
<Text slot="description">JPEG • 11/30/2020</Text>
103+
</GridListItem>
104+
</GridListSection>
105+
<GridListSection>
106+
<GridListHeader>Vegetables</GridListHeader>
107+
<GridListItem textValue="Broccoli">
108+
<img src="https://images.unsplash.com/photo-1685504445355-0e7bdf90d415?q=80&w=928&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
109+
<Text>Broccoli</Text>
110+
<Text slot="description">PNG • 5/30/2023</Text>
111+
</GridListItem>
112+
<GridListItem textValue="Brussels Sprouts">
113+
<img src="https://images.unsplash.com/photo-1685504507286-dc290728c01a?q=80&w=1740&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
114+
<Text>Brussels Sprouts</Text>
115+
<Text slot="description">PNG • 7/3/2021</Text>
116+
</GridListItem>
117+
<GridListItem textValue="Peas">
118+
<img src="https://images.unsplash.com/photo-1587411768345-867e228218c8?q=80&w=1160&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
119+
<Text>Peas</Text>
120+
<Text slot="description">PNG • 4/20/2020</Text>
121+
</GridListItem>
122+
</GridListSection>
123+
</GridList>
124+
);
125+
126+
Sections.args = {
127+
onAction: undefined,
128+
selectionMode: 'multiple',
129+
layout: 'grid'
130+
};

starters/tailwind/src/GridList.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from 'react';
33
import {
44
GridList as AriaGridList,
55
GridListItem as AriaGridListItem,
6+
GridListHeader as AriaGridListHeader,
67
Button,
78
composeRenderProps,
89
GridListItemProps,
@@ -11,6 +12,8 @@ import {
1112
import { tv } from 'tailwind-variants';
1213
import { Checkbox } from './Checkbox';
1314
import { composeTailwindRenderProps, focusRing } from './utils';
15+
import {HTMLAttributes} from 'react';
16+
import { twMerge } from 'tailwind-merge';
1417

1518
export function GridList<T extends object>(
1619
{ children, ...props }: GridListProps<T>
@@ -53,3 +56,9 @@ export function GridListItem({ children, ...props }: GridListItemProps) {
5356
</AriaGridListItem>
5457
);
5558
}
59+
60+
export function GridListHeader({children, ...props}: HTMLAttributes<HTMLElement>) {
61+
return (
62+
<AriaGridListHeader {...props} className={twMerge("text-sm font-semibold text-neutral-500 dark:text-neutral-300 px-4 py-1 -mt-px z-10 bg-neutral-100/60 dark:bg-neutral-700/60 backdrop-blur-md supports-[-moz-appearance:none]:bg-neutral-100 border-y border-y-neutral-200 dark:border-y-neutral-700", props.className)}>{children}</AriaGridListHeader>
63+
)
64+
}

starters/tailwind/stories/GridList.stories.tsx

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Meta } from '@storybook/react';
2-
import { GridList, GridListItem } from '../src/GridList';
2+
import { GridList, GridListHeader, GridListItem} from '../src/GridList';
3+
import { GridListSection } from 'react-aria-components';
34
import React from 'react';
45

56
const meta: Meta<typeof GridList> = {
@@ -31,3 +32,27 @@ DisabledItems.args = {
3132
...Example.args,
3233
disabledKeys: ['mint']
3334
};
35+
36+
export const Sections = (args: any) => (
37+
<GridList aria-label="Food" {...args}>
38+
<GridListSection>
39+
<GridListHeader>Fruits</GridListHeader>
40+
<GridListItem id="Apple">Apple</GridListItem>
41+
<GridListItem id="Grape">Grape</GridListItem>
42+
<GridListItem id="Peach">Peach</GridListItem>
43+
<GridListItem id="Melon">Melon</GridListItem>
44+
</GridListSection>
45+
<GridListSection>
46+
<GridListHeader>Vegetables</GridListHeader>
47+
<GridListItem id="brocoli">Broccoli</GridListItem>
48+
<GridListItem id="peas">Peas</GridListItem>
49+
<GridListItem id="brussels-sprouts">Brussels Sprouts</GridListItem>
50+
<GridListItem id="zucchini">Zucchini</GridListItem>
51+
</GridListSection>
52+
</GridList>
53+
);
54+
55+
Sections.args = {
56+
onAction: null,
57+
selectionMode: 'multiple'
58+
};

0 commit comments

Comments
 (0)