Skip to content

Commit 766a5f0

Browse files
authored
S2 chromatic table (#7098)
* S2 chromatic table * fix cardview chromatic stories
1 parent c353e15 commit 766a5f0

File tree

3 files changed

+431
-228
lines changed

3 files changed

+431
-228
lines changed

packages/@react-spectrum/s2/chromatic/Card.stories.tsx

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,41 +10,19 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import {ActionMenu, AssetCard, Avatar, Badge, Button, Card, CardPreview, CardProps, CollectionCardPreview, Content, Divider, Footer, Image, MenuItem, Meter, ProductCard, Skeleton, StatusLight, Text, UserCard} from '../src';
13+
import {ActionMenu, AssetCard, Avatar, Badge, Button, Card, CardPreview, CardProps, CollectionCardPreview, Content, Divider, Footer, Image, MenuItem, Meter, ProductCard, StatusLight, Text, UserCard} from '../src';
1414
import Folder from '../s2wf-icons/S2_Icon_Folder_20_N.svg';
1515
import FolderGradient from 'illustration:../spectrum-illustrations/gradient/S2_fill_folderClose_generic2_160.svg';
1616
import type {Meta} from '@storybook/react';
1717
import Project from '../s2wf-icons/S2_Icon_Project_20_N.svg';
1818
import Select from '../s2wf-icons/S2_Icon_Select_20_N.svg';
1919
import {style} from '../style/spectrum-theme' with {type: 'macro'};
2020

21-
const meta: Meta<CardProps & {isLoading?: boolean}> = {
21+
const meta: Meta<CardProps> = {
2222
component: Card,
2323
parameters: {
24-
layout: 'centered'
24+
chromaticProvider: {disableAnimations: true}
2525
},
26-
args: {
27-
isLoading: false
28-
},
29-
argTypes: {
30-
href: {table: {disable: true}},
31-
download: {table: {disable: true}},
32-
hrefLang: {table: {disable: true}},
33-
referrerPolicy: {table: {disable: true}},
34-
rel: {table: {disable: true}},
35-
routerOptions: {table: {disable: true}},
36-
ping: {table: {disable: true}},
37-
target: {table: {disable: true}},
38-
value: {table: {disable: true}},
39-
textValue: {table: {disable: true}},
40-
onAction: {table: {disable: true}},
41-
isDisabled: {table: {disable: true}}
42-
},
43-
decorators: (children, {args}) => (
44-
<Skeleton isLoading={args.isLoading || false}>
45-
{children(args)}
46-
</Skeleton>
47-
),
4826
title: 'S2 Chromatic/Card'
4927
};
5028

@@ -162,7 +140,7 @@ export const Product = (args: any) => (
162140
slot="preview"
163141
src={new URL('assets/preview.png', import.meta.url).toString()} />
164142
</CardPreview>
165-
<Image
143+
<Image
166144
slot="thumbnail"
167145
src={new URL('assets/placeholder.png', import.meta.url).toString()} />
168146
<Content>
@@ -260,14 +238,14 @@ export const Custom = (args: any) => (
260238
<div style={{display: 'flex', gap: 16, flexWrap: 'wrap', alignItems: 'end', justifyContent: 'center'}}>
261239
<Card {...args}>
262240
<CardPreview>
263-
<Image
241+
<Image
264242
alt=""
265243
src="https://images.unsplash.com/photo-1671225137978-aa9a19071b9a?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
266244
</CardPreview>
267245
<Content>
268246
<div className={style({display: 'flex', alignItems: 'center', justifyContent: 'space-between'})}>
269247
<div className={style({display: 'flex', alignItems: 'center', gap: 4})}>
270-
<Select />
248+
<Select />
271249
<Text slot="description">Click through rate</Text>
272250
</div>
273251
<div className={style({display: 'flex', flexDirection: 'column'})}>
@@ -279,7 +257,7 @@ export const Custom = (args: any) => (
279257
</Card>
280258
<Card {...args}>
281259
<CardPreview>
282-
<Image
260+
<Image
283261
alt=""
284262
src="https://images.unsplash.com/photo-1460306855393-0410f61241c7?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
285263
</CardPreview>

packages/@react-spectrum/s2/chromatic/CardView.stories.tsx

Lines changed: 1 addition & 199 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,10 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import {ActionMenu, Avatar, Card, CardPreview, CardView, CardViewProps, Collection, CollectionCardPreview, Content, Heading, IllustratedMessage, Image, MenuItem, SkeletonCollection, Text} from '../src';
13+
import {CardView, CardViewProps, Content, Heading, IllustratedMessage} from '../src';
1414
import EmptyIcon from 'illustration:../spectrum-illustrations/gradient/S2_fill_image_generic1_160.svg';
15-
import ErrorIcon from '../spectrum-illustrations/linear/AlertNotice';
16-
import Folder from '../s2wf-icons/S2_Icon_Folder_20_N.svg';
1715
import type {Meta} from '@storybook/react';
1816
import {style} from '../style/spectrum-theme' with {type: 'macro'};
19-
import {useAsyncList} from 'react-stately';
2017

2118
const meta: Meta<typeof CardView> = {
2219
component: CardView,
@@ -44,120 +41,6 @@ const cardViewStyles = style({
4441
}
4542
});
4643

47-
type Item = {
48-
id: number,
49-
user: {
50-
name: string,
51-
profile_image: { small: string }
52-
},
53-
urls: { regular: string },
54-
description: string,
55-
alt_description: string,
56-
width: number,
57-
height: number
58-
};
59-
60-
const avatarSize = {
61-
XS: 16,
62-
S: 20,
63-
M: 24,
64-
L: 28,
65-
XL: 32
66-
} as const;
67-
68-
function PhotoCard({item, layout}: {item: Item, layout: string}) {
69-
return (
70-
<Card id={item.id} textValue={item.description || item.alt_description}>
71-
{({size}) => (<>
72-
<CardPreview>
73-
<Image
74-
src={item.urls.regular}
75-
styles={style({
76-
width: 'full',
77-
pointerEvents: 'none'
78-
})}
79-
// TODO - should we have a safe `dynamicStyles` or something for this?
80-
UNSAFE_style={{
81-
aspectRatio: layout === 'waterfall' ? `${item.width} / ${item.height}` : '4/3',
82-
objectFit: layout === 'waterfall' ? 'contain' : 'cover'
83-
}}
84-
renderError={() => (
85-
<div className={style({display: 'flex', alignItems: 'center', justifyContent: 'center', size: 'full'})}>
86-
<ErrorIcon size="S" />
87-
</div>
88-
)} />
89-
</CardPreview>
90-
<Content>
91-
<Text slot="title">{item.description || item.alt_description}</Text>
92-
{size !== 'XS' && <ActionMenu>
93-
<MenuItem>Test</MenuItem>
94-
</ActionMenu>}
95-
<div className={style({display: 'flex', alignItems: 'center', gap: 8, gridArea: 'description'})}>
96-
<Avatar src={item.user.profile_image.small} size={avatarSize[size]} />
97-
<Text slot="description">{item.user.name}</Text>
98-
</div>
99-
</Content>
100-
</>)}
101-
</Card>
102-
);
103-
}
104-
105-
export const Example = (args: CardViewProps<any>, {viewMode}) => {
106-
let list = useAsyncList<Item, number | null>({
107-
async load({signal, cursor, items}) {
108-
let page = cursor || 1;
109-
let res = await fetch(
110-
`https://api.unsplash.com/topics/nature/photos?page=${page}&per_page=30&client_id=AJuU-FPh11hn7RuumUllp4ppT8kgiLS7LtOHp_sp4nc`,
111-
{signal}
112-
);
113-
let nextItems = await res.json();
114-
// Filter duplicates which might be returned by the API.
115-
let existingKeys = new Set(items.map(i => i.id));
116-
nextItems = nextItems.filter(i => !existingKeys.has(i.id) && (i.description || i.alt_description));
117-
return {items: nextItems, cursor: nextItems.length ? page + 1 : null};
118-
}
119-
});
120-
121-
let loadingState = args.loadingState === 'idle' ? list.loadingState : args.loadingState;
122-
let items = loadingState === 'loading' ? [] : list.items;
123-
124-
return (
125-
<CardView
126-
aria-label="Nature photos"
127-
{...args}
128-
loadingState={loadingState}
129-
onLoadMore={args.loadingState === 'idle' ? list.loadMore : undefined}
130-
styles={cardViewStyles({viewMode})}>
131-
<Collection items={items} dependencies={[args.layout]}>
132-
{item => <PhotoCard item={item} layout={args.layout || 'grid'} />}
133-
</Collection>
134-
{(loadingState === 'loading' || loadingState === 'loadingMore') && (
135-
<SkeletonCollection>
136-
{() => (
137-
<PhotoCard
138-
item={{
139-
id: Math.random(),
140-
user: {name: 'Devon Govett', profile_image: {small: ''}},
141-
urls: {regular: ''},
142-
description: 'This is a fake description. Kinda long so it wraps to a new line.',
143-
alt_description: '',
144-
width: 400,
145-
height: 200 + Math.max(0, Math.round(Math.random() * 400))
146-
}}
147-
layout={args.layout || 'grid'} />
148-
)}
149-
</SkeletonCollection>
150-
)}
151-
</CardView>
152-
);
153-
};
154-
155-
Example.args = {
156-
loadingState: 'idle',
157-
onAction: null,
158-
selectionMode: 'multiple'
159-
};
160-
16144
export const Empty = (args: CardViewProps<any>, {viewMode}) => {
16245
return (
16346
<CardView
@@ -175,84 +58,3 @@ export const Empty = (args: CardViewProps<any>, {viewMode}) => {
17558
</CardView>
17659
);
17760
};
178-
179-
interface Topic {
180-
id: string,
181-
title: string,
182-
total_photos: number,
183-
links: {html: string},
184-
preview_photos: {id: string, urls: {small: string}}[]
185-
}
186-
187-
function TopicCard({topic}: {topic: Topic}) {
188-
return (
189-
<Card href={topic.links.html} target="_blank" textValue={topic.title}>
190-
<CollectionCardPreview>
191-
{topic.preview_photos.slice(0, 4).map(photo => (
192-
<Image key={photo.id} alt="" src={photo.urls.small} />
193-
))}
194-
</CollectionCardPreview>
195-
<Content>
196-
<Text slot="title">{topic.title}</Text>
197-
<div className={style({display: 'flex', alignItems: 'center', gap: 8})}>
198-
<Folder />
199-
<Text slot="description">{topic.total_photos.toLocaleString()} photos</Text>
200-
</div>
201-
</Content>
202-
</Card>
203-
);
204-
}
205-
206-
export const CollectionCards = (args: CardViewProps<any>, {viewMode}) => {
207-
let list = useAsyncList<Topic, number | null>({
208-
async load({signal, cursor}) {
209-
let page = cursor || 1;
210-
let res = await fetch(
211-
`https://api.unsplash.com/topics?page=${page}&per_page=30&client_id=AJuU-FPh11hn7RuumUllp4ppT8kgiLS7LtOHp_sp4nc`,
212-
{signal}
213-
);
214-
let items = (await res.json()).filter((topic: Topic) => !!topic.preview_photos);
215-
return {items, cursor: items.length ? page + 1 : null};
216-
}
217-
});
218-
219-
let loadingState = args.loadingState === 'idle' ? list.loadingState : args.loadingState;
220-
let items = loadingState === 'loading' ? [] : list.items;
221-
222-
return (
223-
<CardView
224-
aria-label="Topics"
225-
{...args}
226-
loadingState={loadingState}
227-
onLoadMore={args.loadingState === 'idle' ? list.loadMore : undefined}
228-
styles={cardViewStyles({viewMode})}>
229-
<Collection items={items}>
230-
{topic => <TopicCard topic={topic} />}
231-
</Collection>
232-
{(loadingState === 'loading' || loadingState === 'loadingMore') && (
233-
<SkeletonCollection>
234-
{() => (
235-
<TopicCard
236-
topic={{
237-
id: Math.random().toString(36),
238-
title: 'Topic title',
239-
total_photos: 80,
240-
links: {html: ''},
241-
preview_photos: [
242-
{id: 'a', urls: {small: ''}},
243-
{id: 'b', urls: {small: ''}},
244-
{id: 'c', urls: {small: ''}},
245-
{id: 'd', urls: {small: ''}}
246-
]
247-
}} />
248-
)}
249-
</SkeletonCollection>
250-
)}
251-
</CardView>
252-
);
253-
};
254-
255-
CollectionCards.args = {
256-
loadingState: 'idle',
257-
onAction: null
258-
};

0 commit comments

Comments
 (0)