Skip to content

Commit ec36061

Browse files
Add support for illustration as thumbnail in ListView (#3249)
* add support for illustration as listview thumbnail * update chromatic stories * updated chromatic to use same as storybook * remove dup css * don't share Folder between storybook and chromatic Co-authored-by: Robert Snow <[email protected]>
1 parent 26b8da0 commit ec36061

File tree

5 files changed

+58
-12
lines changed

5 files changed

+58
-12
lines changed

packages/@react-spectrum/list/chromatic/ListView.chromatic.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import {ActionMenu} from '@react-spectrum/menu';
1515
import Add from '@spectrum-icons/workflow/Add';
1616
import {Content, View} from '@react-spectrum/view';
1717
import Delete from '@spectrum-icons/workflow/Delete';
18-
import Folder from '@spectrum-icons/workflow/Folder';
1918
import {generatePowerset} from '@react-spectrum/story-utils';
2019
import {Grid, repeat} from '@react-spectrum/layout';
2120
import {Heading, Text} from '@react-spectrum/text';
@@ -25,6 +24,7 @@ import Info from '@spectrum-icons/workflow/Info';
2524
import {Item, ListView} from '../';
2625
import {Meta, Story} from '@storybook/react';
2726
import React from 'react';
27+
import {useSlotProps, useStyleProps} from '@react-spectrum/utils';
2828

2929
let states = [
3030
{isQuiet: true},
@@ -89,6 +89,26 @@ const renderActions = (
8989
</>
9090
);
9191

92+
function IllustrationContainer(props) {
93+
props = useSlotProps(props, 'illustration');
94+
let {styleProps} = useStyleProps(props);
95+
return (
96+
<div {...styleProps}>
97+
{props.children}
98+
</div>
99+
);
100+
}
101+
102+
function Folder() {
103+
return (
104+
<IllustrationContainer>
105+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 95.23 67" height="110">
106+
<path fill="var(--spectrum-global-color-gray-600)" d="M94.47,27a4.45,4.45,0,0,0-3.72-2H20.34a5.45,5.45,0,0,0-5.05,3.37L3.12,57.68V3.88A.89.89,0,0,1,4,3H23.21a2.51,2.51,0,0,1,1.69.66l9.7,8.94a1.56,1.56,0,0,0,1,.4h40a1.5,1.5,0,0,1,1.5,1.5v6a1.5,1.5,0,0,0,3,0v-6a4.51,4.51,0,0,0-4.5-4.5H36.21L26.93,1.46A5.48,5.48,0,0,0,23.21,0H4A3.88,3.88,0,0,0,.12,3.88v61h0A1.51,1.51,0,0,0,1.5,67H79a1.49,1.49,0,0,0,1.38-.92L94.89,31.19A4.45,4.45,0,0,0,94.47,27ZM92.12,30,78,64H3.75L18.06,29.52A2.46,2.46,0,0,1,20.34,28H90.75a1.48,1.48,0,0,1,1.37,2Z" />
107+
</svg>
108+
</IllustrationContainer>
109+
);
110+
}
111+
92112
const Template = (): Story => ({combos, ...args}) => (
93113
<Grid columns={repeat(3, '1fr')} autoFlow="row" gap="size-300">
94114
{combos.map(c => {

packages/@react-spectrum/list/src/DragPreview.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export function DragPreview(props: DragPreviewProps) {
3939
content: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-content']},
4040
text: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-content']},
4141
description: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-description']},
42-
icon: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-icon'], size: 'M'},
42+
illustration: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-illustration']},
4343
image: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-image']},
4444
actionButton: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-actions'], isQuiet: true},
4545
actionGroup: {

packages/@react-spectrum/list/src/ListViewItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ export function ListViewItem<T>(props: ListViewItemProps<T>) {
250250
slots={{
251251
text: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-content']},
252252
description: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-description'], ...descriptionProps},
253-
icon: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-icon'], size: 'M'},
253+
illustration: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-illustration']},
254254
image: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-image']},
255255
actionButton: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-actions'], isQuiet: true},
256256
actionGroup: {

packages/@react-spectrum/list/src/styles.css

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -326,22 +326,19 @@
326326
}
327327
}
328328

329-
.react-spectrum-ListViewItem-icon,
329+
.react-spectrum-ListViewItem-illustration,
330330
.react-spectrum-ListViewItem-image {
331331
grid-area: image;
332-
align-items: center;
333332
justify-items: center;
334333
padding-inline-end: var(--spectrum-global-dimension-size-100);
335-
}
336-
337-
.react-spectrum-ListViewItem-image {
338334
display: flex;
339335
border-radius: var(--spectrum-global-dimension-size-25);
340336
width: var(--spectrum-global-dimension-size-400);
341337
height: var(--spectrum-global-dimension-size-400);
342338
align-items: center;
343339
justify-content: center;
344-
> img {
340+
341+
> img, svg {
345342
width: unset;
346343
height: unset;
347344
max-height: 100%;

packages/@react-spectrum/list/stories/ListView.stories.tsx

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {Droppable} from '@react-aria/dnd/stories/dnd.stories';
1313
import Edit from '@spectrum-icons/workflow/Edit';
1414
import FileTxt from '@spectrum-icons/workflow/FileTxt';
1515
import {Flex} from '@react-spectrum/layout';
16-
import Folder from '@spectrum-icons/workflow/Folder';
1716
import {Heading, Text} from '@react-spectrum/text';
1817
import {IllustratedMessage} from '@react-spectrum/illustratedmessage';
1918
import {Image} from '@react-spectrum/image';
@@ -25,6 +24,7 @@ import React, {useEffect, useState} from 'react';
2524
import {storiesOf} from '@storybook/react';
2625
import {useAsyncList, useListData} from '@react-stately/data';
2726
import {useDragHooks, useDropHooks} from '@react-spectrum/dnd';
27+
import {useSlotProps, useStyleProps} from '@react-spectrum/utils';
2828

2929
const parameters = {
3030
args: {
@@ -94,16 +94,38 @@ const items: any = [
9494

9595
// taken from https://random.dog/
9696
const itemsWithThumbs = [
97+
{key: '0', title: 'folder of good bois', illustration: <Folder />},
9798
{key: '1', title: 'swimmer', url: 'https://random.dog/b2fe2172-cf11-43f4-9c7f-29bd19601712.jpg'},
9899
{key: '2', title: 'chocolate', url: 'https://random.dog/2032518a-eec8-4102-9d48-3dca5a26eb23.png'},
99100
{key: '3', title: 'good boi', url: 'https://random.dog/191091b2-7d69-47af-9f52-6605063f1a47.jpg'},
100101
{key: '4', title: 'polar bear', url: 'https://random.dog/c22c077e-a009-486f-834c-a19edcc36a17.jpg'},
101102
{key: '5', title: 'cold boi', url: 'https://random.dog/093a41da-e2c0-4535-a366-9ef3f2013f73.jpg'},
102103
{key: '6', title: 'pilot', url: 'https://random.dog/09f8ecf4-c22b-49f4-af24-29fb5c8dbb2d.jpg'},
103104
{key: '7', title: 'nerd', url: 'https://random.dog/1a0535a6-ca89-4059-9b3a-04a554c0587b.jpg'},
104-
{key: '8', title: 'audiophile', url: 'https://random.dog/32367-2062-4347.jpg'}
105+
{key: '8', title: 'audiophile', url: 'https://random.dog/32367-2062-4347.jpg'},
106+
{key: '9', title: 'folder of great bois', illustration: <Folder />}
105107
];
106108

109+
function IllustrationContainer(props) {
110+
props = useSlotProps(props, 'illustration');
111+
let {styleProps} = useStyleProps(props);
112+
return (
113+
<div {...styleProps}>
114+
{props.children}
115+
</div>
116+
);
117+
}
118+
119+
function Folder() {
120+
return (
121+
<IllustrationContainer>
122+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 95.23 67" height="110">
123+
<path fill="var(--spectrum-global-color-gray-600)" d="M94.47,27a4.45,4.45,0,0,0-3.72-2H20.34a5.45,5.45,0,0,0-5.05,3.37L3.12,57.68V3.88A.89.89,0,0,1,4,3H23.21a2.51,2.51,0,0,1,1.69.66l9.7,8.94a1.56,1.56,0,0,0,1,.4h40a1.5,1.5,0,0,1,1.5,1.5v6a1.5,1.5,0,0,0,3,0v-6a4.51,4.51,0,0,0-4.5-4.5H36.21L26.93,1.46A5.48,5.48,0,0,0,23.21,0H4A3.88,3.88,0,0,0,.12,3.88v61h0A1.51,1.51,0,0,0,1.5,67H79a1.49,1.49,0,0,0,1.38-.92L94.89,31.19A4.45,4.45,0,0,0,94.47,27ZM92.12,30,78,64H3.75L18.06,29.52A2.46,2.46,0,0,1,20.34,28H90.75a1.48,1.48,0,0,1,1.37,2Z" />
124+
</svg>
125+
</IllustrationContainer>
126+
);
127+
}
128+
107129
function renderEmptyState() {
108130
return (
109131
<IllustratedMessage>
@@ -220,7 +242,14 @@ storiesOf('ListView', module)
220242
.add('with emphasized ActionBar', args => <ActionBarExample isEmphasized {...args} />)
221243
.add('thumbnails', args => (
222244
<ListView width="250px" items={itemsWithThumbs} aria-label="ListView with thumbnails" {...args}>
223-
{(item: any) => <Item textValue={item.title}><Image src={item.url} alt="" /><Text>{item.title}</Text><Text slot="description">JPG</Text></Item>}
245+
{(item: any) => (
246+
<Item textValue={item.title}>
247+
{item.url && <Image src={item.url} alt="" />}
248+
{item.illustration}
249+
<Text>{item.title}</Text>
250+
{item.url && <Text slot="description">JPG</Text>}
251+
</Item>
252+
)}
224253
</ListView>
225254
))
226255
.add('long text', args => (

0 commit comments

Comments
 (0)