@sproutsocial/seeds-react-card 1.1.53 → 1.1.55
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.
- package/dist/card.css +152 -0
- package/dist/esm/index.js +298 -74
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +38 -6
- package/dist/index.d.ts +38 -6
- package/dist/index.js +293 -77
- package/dist/index.js.map +1 -1
- package/package.json +23 -12
- package/.eslintignore +0 -6
- package/.eslintrc.js +0 -4
- package/.turbo/turbo-build.log +0 -21
- package/CHANGELOG.md +0 -399
- package/jest.config.js +0 -9
- package/src/Card.feature +0 -122
- package/src/Card.stories.tsx +0 -389
- package/src/Card.tsx +0 -87
- package/src/CardTypes.ts +0 -133
- package/src/__tests__/Card.test.tsx +0 -313
- package/src/__tests__/CardTypes.typetest.tsx +0 -78
- package/src/index.ts +0 -6
- package/src/styles.tsx +0 -176
- package/src/subComponents.tsx +0 -110
- package/src/utils.ts +0 -61
- package/tsconfig.json +0 -15
- package/tsup.config.ts +0 -12
package/src/Card.stories.tsx
DELETED
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect } from "react";
|
|
2
|
-
import { Avatar } from "@sproutsocial/seeds-react-avatar";
|
|
3
|
-
import { Banner } from "@sproutsocial/seeds-react-banner";
|
|
4
|
-
import { Box } from "@sproutsocial/seeds-react-box";
|
|
5
|
-
import { Card } from "./";
|
|
6
|
-
import { Icon } from "@sproutsocial/seeds-react-icon";
|
|
7
|
-
import { Link } from "@sproutsocial/seeds-react-link";
|
|
8
|
-
import { PartnerLogo } from "@sproutsocial/seeds-react-partner-logo";
|
|
9
|
-
import type { EnumIllustrationNames } from "@sproutsocial/seeds-illustrations";
|
|
10
|
-
import { SpotIllustration } from "@sproutsocial/seeds-react-spot-illustration";
|
|
11
|
-
import { Text } from "@sproutsocial/seeds-react-text";
|
|
12
|
-
import styled from "styled-components";
|
|
13
|
-
import { CardHeader, CardContent, CardFooter, CardLink } from "./subComponents";
|
|
14
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
15
|
-
|
|
16
|
-
const meta: Meta<typeof Card> = {
|
|
17
|
-
title: "Components/Card",
|
|
18
|
-
component: Card,
|
|
19
|
-
argTypes: {
|
|
20
|
-
elevation: {
|
|
21
|
-
options: ["low", "medium", "high", undefined],
|
|
22
|
-
control: { type: "select" },
|
|
23
|
-
},
|
|
24
|
-
disabled: {
|
|
25
|
-
control: "boolean",
|
|
26
|
-
},
|
|
27
|
-
selected: {
|
|
28
|
-
control: "boolean",
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
args: {
|
|
32
|
-
elevation: undefined,
|
|
33
|
-
disabled: false,
|
|
34
|
-
selected: false,
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export default meta;
|
|
39
|
-
|
|
40
|
-
type Story = StoryObj<typeof Card>;
|
|
41
|
-
|
|
42
|
-
export const AsLink: Story = {
|
|
43
|
-
render: (args) => (
|
|
44
|
-
<Card width={1 / 4} {...args}>
|
|
45
|
-
<Box display="flex" justifyContent="center" alignItems="center" my={400}>
|
|
46
|
-
<SpotIllustration
|
|
47
|
-
height="200px"
|
|
48
|
-
name="calendar-reporting"
|
|
49
|
-
aria-hidden
|
|
50
|
-
/>
|
|
51
|
-
</Box>
|
|
52
|
-
<Text.SmallByline>Reporting</Text.SmallByline>
|
|
53
|
-
<CardLink external affordance>
|
|
54
|
-
Visit calendar report
|
|
55
|
-
</CardLink>
|
|
56
|
-
</Card>
|
|
57
|
-
),
|
|
58
|
-
args: {
|
|
59
|
-
role: "link",
|
|
60
|
-
href: "https://seeds.sproutsocial.com/",
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export const AsButton: Story = {
|
|
65
|
-
render: () => {
|
|
66
|
-
const [message, setMessage] = useState(false);
|
|
67
|
-
|
|
68
|
-
const _onClick = () => {
|
|
69
|
-
setMessage(true);
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
useEffect(() => {
|
|
73
|
-
const showMessage = setTimeout(() => {
|
|
74
|
-
setMessage(false);
|
|
75
|
-
}, 4000);
|
|
76
|
-
|
|
77
|
-
return function cleanup() {
|
|
78
|
-
clearTimeout(showMessage);
|
|
79
|
-
};
|
|
80
|
-
}, [message]);
|
|
81
|
-
|
|
82
|
-
return (
|
|
83
|
-
<>
|
|
84
|
-
{message ? (
|
|
85
|
-
<Box mb={400}>
|
|
86
|
-
<Banner text="Your click was successful." />
|
|
87
|
-
</Box>
|
|
88
|
-
) : (
|
|
89
|
-
<Box mb={400}>
|
|
90
|
-
<Banner
|
|
91
|
-
type="warning"
|
|
92
|
-
text={
|
|
93
|
-
<Box
|
|
94
|
-
width={1}
|
|
95
|
-
display="flex"
|
|
96
|
-
alignItems="center"
|
|
97
|
-
justifyContent="space-between"
|
|
98
|
-
>
|
|
99
|
-
<Text>
|
|
100
|
-
Avoid nesting interactive content inside a Card with
|
|
101
|
-
role='button'
|
|
102
|
-
</Text>
|
|
103
|
-
<Text>
|
|
104
|
-
<Link href="https://html.spec.whatwg.org/multipage/dom.html#interactive-content">
|
|
105
|
-
Learn more
|
|
106
|
-
<Icon
|
|
107
|
-
ml={200}
|
|
108
|
-
size="mini"
|
|
109
|
-
name="arrow-right-up-solid"
|
|
110
|
-
role={undefined}
|
|
111
|
-
svgProps={{
|
|
112
|
-
role: "img",
|
|
113
|
-
"aria-label": "opens in a new tab",
|
|
114
|
-
}}
|
|
115
|
-
/>
|
|
116
|
-
</Link>
|
|
117
|
-
</Text>
|
|
118
|
-
</Box>
|
|
119
|
-
}
|
|
120
|
-
/>
|
|
121
|
-
</Box>
|
|
122
|
-
)}
|
|
123
|
-
<Card role="button" onClick={_onClick} width={1 / 4}>
|
|
124
|
-
<Box mx="auto" mb={400}>
|
|
125
|
-
<PartnerLogo py={450} partnerName="facebook" size="jumbo" />
|
|
126
|
-
</Box>
|
|
127
|
-
<Text.SmallByline>Profile connect</Text.SmallByline>
|
|
128
|
-
<Text.Headline mb={300}>Facebook</Text.Headline>
|
|
129
|
-
<Text.BodyCopy>Click to connect your facebook account.</Text.BodyCopy>
|
|
130
|
-
</Card>
|
|
131
|
-
</>
|
|
132
|
-
);
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
export const AsPresentation: Story = {
|
|
137
|
-
render: (args) => (
|
|
138
|
-
<Card width={1 / 4} {...args}>
|
|
139
|
-
<Text.SmallByline>Analytics</Text.SmallByline>
|
|
140
|
-
<Text.Headline mb={300}>Google Analytics</Text.Headline>
|
|
141
|
-
<Box mx="auto" my={400}>
|
|
142
|
-
<PartnerLogo py={450} partnerName="google-analytics" size="jumbo" />
|
|
143
|
-
</Box>
|
|
144
|
-
<Text.BodyCopy mb={400}>
|
|
145
|
-
Learn more about how we track analytics.
|
|
146
|
-
</Text.BodyCopy>
|
|
147
|
-
<Link fontSize={300} href="https://google.com/" external>
|
|
148
|
-
Visit google
|
|
149
|
-
<Icon
|
|
150
|
-
mb={100}
|
|
151
|
-
ml={300}
|
|
152
|
-
size="mini"
|
|
153
|
-
name="arrow-right-outline"
|
|
154
|
-
role={undefined}
|
|
155
|
-
svgProps={{ role: "img", "aria-label": "opens in a new tab" }}
|
|
156
|
-
/>
|
|
157
|
-
</Link>
|
|
158
|
-
</Card>
|
|
159
|
-
),
|
|
160
|
-
args: {
|
|
161
|
-
role: "presentation",
|
|
162
|
-
},
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
export const AsButtonDisabled: Story = {
|
|
166
|
-
render: () => {
|
|
167
|
-
const [message, setMessage] = useState(false);
|
|
168
|
-
|
|
169
|
-
const _onClick = () => {
|
|
170
|
-
setMessage(true);
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
useEffect(() => {
|
|
174
|
-
const showMessage = setTimeout(() => {
|
|
175
|
-
setMessage(false);
|
|
176
|
-
}, 4000);
|
|
177
|
-
|
|
178
|
-
return function cleanup() {
|
|
179
|
-
clearTimeout(showMessage);
|
|
180
|
-
};
|
|
181
|
-
}, [message]);
|
|
182
|
-
|
|
183
|
-
return (
|
|
184
|
-
<>
|
|
185
|
-
{message ? (
|
|
186
|
-
<Box mb={400}>
|
|
187
|
-
<Banner text="Your click was successful." />
|
|
188
|
-
</Box>
|
|
189
|
-
) : (
|
|
190
|
-
<Box mb={400}>
|
|
191
|
-
<Banner
|
|
192
|
-
type="warning"
|
|
193
|
-
text={
|
|
194
|
-
<Box
|
|
195
|
-
width={1}
|
|
196
|
-
display="flex"
|
|
197
|
-
alignItems="center"
|
|
198
|
-
justifyContent="space-between"
|
|
199
|
-
>
|
|
200
|
-
<Text>
|
|
201
|
-
Avoid nesting interactive content inside a Card with
|
|
202
|
-
role='button'
|
|
203
|
-
</Text>
|
|
204
|
-
<Text>
|
|
205
|
-
<Link href="https://html.spec.whatwg.org/multipage/dom.html#interactive-content">
|
|
206
|
-
Learn more
|
|
207
|
-
<Icon
|
|
208
|
-
ml={200}
|
|
209
|
-
size="mini"
|
|
210
|
-
name="arrow-right-up-solid"
|
|
211
|
-
role={undefined}
|
|
212
|
-
svgProps={{
|
|
213
|
-
role: "img",
|
|
214
|
-
"aria-label": "opens in a new tab",
|
|
215
|
-
}}
|
|
216
|
-
/>
|
|
217
|
-
</Link>
|
|
218
|
-
</Text>
|
|
219
|
-
</Box>
|
|
220
|
-
}
|
|
221
|
-
/>
|
|
222
|
-
</Box>
|
|
223
|
-
)}
|
|
224
|
-
<Card role="button" disabled={true} onClick={_onClick} width={1 / 4}>
|
|
225
|
-
<Box mx="auto" mb={400}>
|
|
226
|
-
<SpotIllustration height="200px" name="coffee-cup" />
|
|
227
|
-
</Box>
|
|
228
|
-
<Text.SmallByline>SEEDS WEB</Text.SmallByline>
|
|
229
|
-
<Text.Headline mb={300}>Card component</Text.Headline>
|
|
230
|
-
<Text.BodyCopy>
|
|
231
|
-
The card component is a styled primitive container.
|
|
232
|
-
</Text.BodyCopy>
|
|
233
|
-
</Card>
|
|
234
|
-
</>
|
|
235
|
-
);
|
|
236
|
-
},
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
export const ConfigurableShadow: Story = {
|
|
240
|
-
render: (args) => (
|
|
241
|
-
<Card width={1 / 4} {...args}>
|
|
242
|
-
<Text.SmallByline>SEEDS WEB</Text.SmallByline>
|
|
243
|
-
<Text.Headline mb={300}>Card component</Text.Headline>
|
|
244
|
-
<Box mx="auto" my={400}>
|
|
245
|
-
<SpotIllustration height="200px" name="coffee-cup" />
|
|
246
|
-
</Box>
|
|
247
|
-
<Text.BodyCopy mb={400}>
|
|
248
|
-
The card component is a styled primitive container.
|
|
249
|
-
</Text.BodyCopy>
|
|
250
|
-
<Link fontSize={300} href="https://google.com/" external>
|
|
251
|
-
Use now
|
|
252
|
-
<Icon
|
|
253
|
-
mb={100}
|
|
254
|
-
ml={300}
|
|
255
|
-
size="mini"
|
|
256
|
-
name="arrow-right-up-solid"
|
|
257
|
-
role={undefined}
|
|
258
|
-
svgProps={{ role: "img", "aria-label": "opens in a new tab" }}
|
|
259
|
-
/>
|
|
260
|
-
</Link>
|
|
261
|
-
</Card>
|
|
262
|
-
),
|
|
263
|
-
args: {
|
|
264
|
-
role: "presentation",
|
|
265
|
-
elevation: "high",
|
|
266
|
-
},
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
export const SelectableComposition: Story = {
|
|
270
|
-
render: () => {
|
|
271
|
-
const [selected, setSelected] = useState(false);
|
|
272
|
-
const toggle = () => setSelected(!selected);
|
|
273
|
-
|
|
274
|
-
return (
|
|
275
|
-
<Card role="checkbox" selected={selected} onClick={toggle} width={1 / 3}>
|
|
276
|
-
<CardContent my={450} mx="auto">
|
|
277
|
-
<PartnerLogo partnerName="tiktok" size="jumbo" />
|
|
278
|
-
</CardContent>
|
|
279
|
-
<CardFooter flexDirection="column">
|
|
280
|
-
<Text.SmallSubHeadline>TikTok</Text.SmallSubHeadline>
|
|
281
|
-
<Text.SmallBodyCopy>
|
|
282
|
-
Select TikTok to start sharing content today.
|
|
283
|
-
</Text.SmallBodyCopy>
|
|
284
|
-
</CardFooter>
|
|
285
|
-
</Card>
|
|
286
|
-
);
|
|
287
|
-
},
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
export const CompositionUtilities: Story = {
|
|
291
|
-
render: () => (
|
|
292
|
-
<Card role="presentation">
|
|
293
|
-
<CardHeader>
|
|
294
|
-
<Avatar appearance="leaf" size="24px" name="Card Header" />
|
|
295
|
-
<Text.SubHeadline ml={300}>This is a card header</Text.SubHeadline>
|
|
296
|
-
</CardHeader>
|
|
297
|
-
<CardContent>
|
|
298
|
-
<Text.SmallBodyCopy as="p">
|
|
299
|
-
We can use the CardContent component to render cool content as seen
|
|
300
|
-
here:
|
|
301
|
-
</Text.SmallBodyCopy>
|
|
302
|
-
<Text.SmallBodyCopy as="p">
|
|
303
|
-
"Hi, Nard Dawg. I'm Lou Peachum!"
|
|
304
|
-
</Text.SmallBodyCopy>
|
|
305
|
-
</CardContent>
|
|
306
|
-
<CardFooter>
|
|
307
|
-
<Link external href="https://google.com">
|
|
308
|
-
Action in CardFooter
|
|
309
|
-
<Icon
|
|
310
|
-
ml={200}
|
|
311
|
-
size="mini"
|
|
312
|
-
name="arrow-right-up-solid"
|
|
313
|
-
role={undefined}
|
|
314
|
-
svgProps={{ role: "img", "aria-label": "opens in a new tab" }}
|
|
315
|
-
/>
|
|
316
|
-
</Link>
|
|
317
|
-
</CardFooter>
|
|
318
|
-
</Card>
|
|
319
|
-
),
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
export const Cards: Story = {
|
|
323
|
-
render: () => {
|
|
324
|
-
const cards: {
|
|
325
|
-
subhead: string;
|
|
326
|
-
reportName: string;
|
|
327
|
-
image: EnumIllustrationNames;
|
|
328
|
-
href: string;
|
|
329
|
-
}[] = [
|
|
330
|
-
{
|
|
331
|
-
subhead: "Reporting",
|
|
332
|
-
reportName: "Profile performance",
|
|
333
|
-
image: "reporting",
|
|
334
|
-
href: "https://app.sproutsocial.com/reports/group_report",
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
subhead: "Reporting",
|
|
338
|
-
reportName: "Post performance",
|
|
339
|
-
image: "reporting-folder",
|
|
340
|
-
href: "https://app.sproutsocial.com/reports/post_performance",
|
|
341
|
-
},
|
|
342
|
-
{
|
|
343
|
-
subhead: "Reporting",
|
|
344
|
-
reportName: "Tag performance",
|
|
345
|
-
image: "analytics-offering",
|
|
346
|
-
href: "https://app.sproutsocial.com/reports/tag_performance",
|
|
347
|
-
},
|
|
348
|
-
{
|
|
349
|
-
subhead: "Reporting",
|
|
350
|
-
reportName: "Paid performance",
|
|
351
|
-
image: "listening-tour",
|
|
352
|
-
href: "https://app.sproutsocial.com/reports/cross_network_campaign_performance",
|
|
353
|
-
},
|
|
354
|
-
];
|
|
355
|
-
|
|
356
|
-
const StyledList = styled.ul`
|
|
357
|
-
list-style: none;
|
|
358
|
-
display: flex;
|
|
359
|
-
flex-wrap: wrap;
|
|
360
|
-
`;
|
|
361
|
-
|
|
362
|
-
return (
|
|
363
|
-
<StyledList>
|
|
364
|
-
{cards.map((card) => (
|
|
365
|
-
<li key={card.href}>
|
|
366
|
-
<Card role="link" href={card.href} width="275px" mr={400} mb={400}>
|
|
367
|
-
<Box
|
|
368
|
-
display="flex"
|
|
369
|
-
justifyContent="center"
|
|
370
|
-
alignItems="center"
|
|
371
|
-
my={400}
|
|
372
|
-
>
|
|
373
|
-
<SpotIllustration
|
|
374
|
-
height="200px"
|
|
375
|
-
name={card.image}
|
|
376
|
-
aria-hidden
|
|
377
|
-
/>
|
|
378
|
-
</Box>
|
|
379
|
-
<Text.SmallByline>{card.subhead}</Text.SmallByline>
|
|
380
|
-
<CardLink external affordance>
|
|
381
|
-
Visit {card.reportName} report
|
|
382
|
-
</CardLink>
|
|
383
|
-
</Card>
|
|
384
|
-
</li>
|
|
385
|
-
))}
|
|
386
|
-
</StyledList>
|
|
387
|
-
);
|
|
388
|
-
},
|
|
389
|
-
};
|
package/src/Card.tsx
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import React, { useRef, useState } from "react";
|
|
2
|
-
import { StyledCard } from "./styles";
|
|
3
|
-
import type { TypeCardProps, TypeCardContext } from "./CardTypes";
|
|
4
|
-
import { SubComponentContext, onKeyDown } from "./utils";
|
|
5
|
-
import { SelectedIcon } from "./subComponents";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @link https://seeds.sproutsocial.com/components/card/
|
|
9
|
-
*
|
|
10
|
-
* Cards with role='presentation' are non-interactive for accessibility compliance.
|
|
11
|
-
* Use role='button' for interactive Cards.
|
|
12
|
-
*
|
|
13
|
-
* Avoid nesting interactive content inside a Card with role='button'.
|
|
14
|
-
*
|
|
15
|
-
* Interactive content: "a", "audio", "button", "embed", "iframe", "img", "input", "label", "select", "textarea", "video"
|
|
16
|
-
* @see https://html.spec.whatwg.org/multipage/dom.html#interactive-content
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* // Interactive Card
|
|
20
|
-
* <Card role="button" onClick={_onClick}>
|
|
21
|
-
* <Text>Click this card</Text>
|
|
22
|
-
* </Card>
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* // Presentation Card with interactive children
|
|
26
|
-
* <Card role="presentation">
|
|
27
|
-
* <Text>This card is not interactive</Text>
|
|
28
|
-
* <Link href="/details">But this link is</Link>
|
|
29
|
-
* </Card>
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
const Card = ({
|
|
33
|
-
children,
|
|
34
|
-
disabled = false,
|
|
35
|
-
elevation = "low",
|
|
36
|
-
href,
|
|
37
|
-
onClick,
|
|
38
|
-
role = "presentation",
|
|
39
|
-
selected,
|
|
40
|
-
...rest
|
|
41
|
-
}: TypeCardProps) => {
|
|
42
|
-
const [hasSubComponent, setHasSubComponent] = useState<boolean>(false);
|
|
43
|
-
const containerRef = useRef<HTMLDivElement>(null);
|
|
44
|
-
const linkRef = useRef<HTMLAnchorElement>(null);
|
|
45
|
-
const isRoleLink = role === "link";
|
|
46
|
-
const isRolePresentation = role === "presentation";
|
|
47
|
-
const checkedConditions = role === "checkbox" ? selected : undefined;
|
|
48
|
-
|
|
49
|
-
const cardContext: TypeCardContext = {
|
|
50
|
-
setHasSubComponent: setHasSubComponent,
|
|
51
|
-
href: href,
|
|
52
|
-
linkRef: linkRef,
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const handleClickConditions: React.MouseEventHandler = (e) =>
|
|
56
|
-
isRoleLink ? linkRef.current?.click() : onClick?.(e);
|
|
57
|
-
|
|
58
|
-
const handleKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (e) =>
|
|
59
|
-
onKeyDown({ e, href, onClick, ref: containerRef, role });
|
|
60
|
-
|
|
61
|
-
const shouldBeInteractive = !isRolePresentation && !disabled;
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<StyledCard
|
|
65
|
-
tabIndex={isRoleLink || isRolePresentation || disabled ? -1 : 0}
|
|
66
|
-
role={isRoleLink ? undefined : role}
|
|
67
|
-
onClick={shouldBeInteractive ? handleClickConditions : undefined}
|
|
68
|
-
onKeyDown={shouldBeInteractive ? handleKeyDown : undefined}
|
|
69
|
-
$elevation={elevation}
|
|
70
|
-
ref={containerRef}
|
|
71
|
-
$selected={selected}
|
|
72
|
-
aria-checked={checkedConditions}
|
|
73
|
-
$disabled={disabled}
|
|
74
|
-
aria-disabled={disabled && disabled}
|
|
75
|
-
$compositionalComponents={hasSubComponent}
|
|
76
|
-
$isRoleLink={isRoleLink}
|
|
77
|
-
{...rest}
|
|
78
|
-
>
|
|
79
|
-
<SelectedIcon $selected={selected} />
|
|
80
|
-
<SubComponentContext.Provider value={cardContext}>
|
|
81
|
-
{children}
|
|
82
|
-
</SubComponentContext.Provider>
|
|
83
|
-
</StyledCard>
|
|
84
|
-
);
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
export default Card;
|
package/src/CardTypes.ts
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import type { TypeIconProps } from "@sproutsocial/seeds-react-icon";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import type { TypeStyledComponentsCommonProps } from "@sproutsocial/seeds-react-system-props";
|
|
4
|
-
import type {
|
|
5
|
-
TypeBorderSystemProps,
|
|
6
|
-
TypeColorSystemProps,
|
|
7
|
-
TypeFlexboxSystemProps,
|
|
8
|
-
TypeGridSystemProps,
|
|
9
|
-
TypeLayoutSystemProps,
|
|
10
|
-
TypePositionSystemProps,
|
|
11
|
-
TypeSpaceSystemProps,
|
|
12
|
-
TypeTypographySystemProps,
|
|
13
|
-
} from "@sproutsocial/seeds-react-system-props";
|
|
14
|
-
|
|
15
|
-
export interface TypeSharedCardSystemProps
|
|
16
|
-
extends Omit<React.ComponentPropsWithoutRef<"div">, "color">,
|
|
17
|
-
TypeStyledComponentsCommonProps,
|
|
18
|
-
TypeBorderSystemProps,
|
|
19
|
-
TypeColorSystemProps,
|
|
20
|
-
TypeFlexboxSystemProps,
|
|
21
|
-
TypeGridSystemProps,
|
|
22
|
-
TypeLayoutSystemProps,
|
|
23
|
-
TypePositionSystemProps,
|
|
24
|
-
TypeSpaceSystemProps {}
|
|
25
|
-
|
|
26
|
-
// consumer facing props that affect the styles of the component. We need to define these first so the user doesn't see our transient naming conventions.
|
|
27
|
-
export interface TypeCardStyleProps {
|
|
28
|
-
elevation?: "low" | "medium" | "high";
|
|
29
|
-
disabled?: boolean;
|
|
30
|
-
compositionalComponents?: boolean;
|
|
31
|
-
selected?: boolean;
|
|
32
|
-
isRoleLink?: boolean;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Since we only want to manage the style props in one place(above), we'll use this generic to prepend the properties of TypeCardStyleProps with $.
|
|
36
|
-
export type TypeStyleTransientProps<T> = {
|
|
37
|
-
[K in Extract<keyof T, string> as `$${K}`]: T[K];
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export type TypeCardStyleTransientProps =
|
|
41
|
-
TypeStyleTransientProps<TypeCardStyleProps>;
|
|
42
|
-
|
|
43
|
-
export interface TypeStyledCard
|
|
44
|
-
extends TypeSharedCardSystemProps,
|
|
45
|
-
TypeCardStyleTransientProps {}
|
|
46
|
-
|
|
47
|
-
export interface TypeCardStyles
|
|
48
|
-
extends TypeSharedCardSystemProps,
|
|
49
|
-
Omit<TypeCardStyleProps, "compositionalComponents"> {}
|
|
50
|
-
|
|
51
|
-
type TypeOnClick = (event: React.MouseEvent | React.KeyboardEvent) => void;
|
|
52
|
-
|
|
53
|
-
type TypeGenericCard = {
|
|
54
|
-
/** role is used for to set accessibility properties,
|
|
55
|
-
* to determine styling and interaction behavior,
|
|
56
|
-
* and to determine which props should be allowed.*/
|
|
57
|
-
role: "link" | "button" | "checkbox" | "presentation";
|
|
58
|
-
/** When role is link, use href to determine the link destination.
|
|
59
|
-
* Required for role="link", disallowed for all other roles */
|
|
60
|
-
href?: string;
|
|
61
|
-
/** Required for role="button" and role="checkbox",
|
|
62
|
-
* discouraged for role="presentation", and disallowed for role="link" */
|
|
63
|
-
onClick?: TypeOnClick;
|
|
64
|
-
/** Indicates whether the card is selected.
|
|
65
|
-
* Required for role="checkbox", disallowed for all other roles */
|
|
66
|
-
selected?: boolean;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export type TypeLinkCardProps = {
|
|
70
|
-
role: "link";
|
|
71
|
-
href: string;
|
|
72
|
-
onClick?: never;
|
|
73
|
-
selected?: never;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
export type TypeButtonCardProps = {
|
|
77
|
-
role: "button";
|
|
78
|
-
href?: never;
|
|
79
|
-
onClick: TypeOnClick;
|
|
80
|
-
selected?: never;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
export type TypeCheckboxCardProps = {
|
|
84
|
-
role: "checkbox";
|
|
85
|
-
href?: never;
|
|
86
|
-
onClick: TypeOnClick;
|
|
87
|
-
selected: boolean;
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
export type TypePresentationCardProps = {
|
|
91
|
-
role: "presentation";
|
|
92
|
-
href?: never;
|
|
93
|
-
/**
|
|
94
|
-
* **Not supported for accessibility:**
|
|
95
|
-
* `role='presentation'` removes the element from the accessibility tree.
|
|
96
|
-
* Presentation Cards do not support `onClick` handlers or keyboard interactions.
|
|
97
|
-
* Use `role='button'` for interactive Cards instead.
|
|
98
|
-
*/
|
|
99
|
-
onClick?: never;
|
|
100
|
-
selected?: never;
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export type TypeCardConditions =
|
|
104
|
-
| TypeLinkCardProps
|
|
105
|
-
| TypeButtonCardProps
|
|
106
|
-
| TypeCheckboxCardProps
|
|
107
|
-
| TypePresentationCardProps;
|
|
108
|
-
|
|
109
|
-
export type TypeCardProps = React.PropsWithChildren<TypeCardStyles> &
|
|
110
|
-
TypeGenericCard &
|
|
111
|
-
TypeCardConditions;
|
|
112
|
-
|
|
113
|
-
export interface TypeCardArea extends TypeSharedCardSystemProps {
|
|
114
|
-
$divider?: "top" | "bottom";
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export interface TypeStyledSelectedIcon extends TypeIconProps {
|
|
118
|
-
$selected?: TypeCardStyleTransientProps["$selected"];
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export interface TypeCardContext {
|
|
122
|
-
setHasSubComponent?: React.Dispatch<React.SetStateAction<boolean>>;
|
|
123
|
-
href?: string;
|
|
124
|
-
linkRef: React.RefObject<HTMLAnchorElement> | null;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export interface TypeCardLink
|
|
128
|
-
extends Omit<React.ComponentPropsWithoutRef<"a">, "color">,
|
|
129
|
-
TypeColorSystemProps,
|
|
130
|
-
TypeTypographySystemProps {
|
|
131
|
-
affordance?: boolean;
|
|
132
|
-
external?: boolean;
|
|
133
|
-
}
|