@purpurds/card 6.12.4 → 7.0.0
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/LICENSE.txt +5 -12
- package/dist/card-badge.d.ts.map +1 -1
- package/dist/card-content-container.d.ts.map +1 -1
- package/dist/card-content.d.ts.map +1 -1
- package/dist/card-cta.d.ts +3 -3
- package/dist/card-cta.d.ts.map +1 -1
- package/dist/card-heading.d.ts +46 -5
- package/dist/card-heading.d.ts.map +1 -1
- package/dist/card-media-layout.d.ts +2 -2
- package/dist/card-media-layout.d.ts.map +1 -1
- package/dist/card-media.d.ts +3 -3
- package/dist/card-media.d.ts.map +1 -1
- package/dist/card-root.d.ts +3 -71
- package/dist/card-root.d.ts.map +1 -1
- package/dist/card-trigger-item.d.ts +5 -3
- package/dist/card-trigger-item.d.ts.map +1 -1
- package/dist/card.cjs.js +8 -8
- package/dist/card.cjs.js.map +1 -1
- package/dist/card.d.ts +5 -8
- package/dist/card.d.ts.map +1 -1
- package/dist/card.es.js +464 -575
- package/dist/card.es.js.map +1 -1
- package/dist/metadata.js +4 -3
- package/dist/styles.css +1 -1
- package/package.json +12 -12
- package/src/card-badge.tsx +1 -1
- package/src/card-content-container.tsx +1 -1
- package/src/card-content.tsx +1 -1
- package/src/card-cta.tsx +3 -3
- package/src/card-heading.test.tsx +47 -0
- package/src/card-heading.tsx +98 -19
- package/src/card-media-layout.tsx +2 -2
- package/src/card-media.tsx +3 -3
- package/src/card-overline.module.scss +0 -2
- package/src/card-overline.tsx +1 -1
- package/src/card-root.test.tsx +0 -46
- package/src/card-root.tsx +10 -66
- package/src/card-trigger-item.module.scss +19 -3
- package/src/card-trigger-item.test.tsx +1 -1
- package/src/card-trigger-item.tsx +19 -10
- package/src/card.stories.tsx +18 -10
- package/src/card.tsx +11 -22
package/src/card-heading.tsx
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
|
|
1
|
+
import React, {
|
|
2
|
+
type AnchorHTMLAttributes,
|
|
3
|
+
type ForwardRefExoticComponent,
|
|
4
|
+
type HTMLAttributes,
|
|
5
|
+
type ReactNode,
|
|
6
|
+
} from "react";
|
|
7
|
+
import { Heading, type HeadingTagType, type TitleVariantType } from "@purpurds/heading";
|
|
3
8
|
import c from "classnames/bind";
|
|
4
9
|
|
|
5
10
|
import styles from "./card-heading.module.scss";
|
|
11
|
+
import { CardTriggerItem } from "./card-trigger-item";
|
|
6
12
|
|
|
7
13
|
const cx = c.bind(styles);
|
|
8
14
|
|
|
9
|
-
export type
|
|
15
|
+
export type CardHeadingDefaultProps = {
|
|
10
16
|
/**
|
|
11
17
|
* Use this to set a testid on the feature list
|
|
12
18
|
*/
|
|
@@ -15,37 +21,110 @@ export type CardHeadingProps = {
|
|
|
15
21
|
/**
|
|
16
22
|
* Use when you want an icon to the left of the title
|
|
17
23
|
*/
|
|
18
|
-
icon?:
|
|
24
|
+
icon?: ReactNode;
|
|
19
25
|
/**
|
|
20
26
|
* Use for the CTA, it will positioned to the right
|
|
21
27
|
*/
|
|
22
28
|
children?: ReactNode;
|
|
23
29
|
titleTag?: HeadingTagType;
|
|
30
|
+
variant?: TitleVariantType;
|
|
24
31
|
enableHyphenation?: boolean;
|
|
25
32
|
};
|
|
26
33
|
|
|
34
|
+
export type CardHeadingNonInteractiveProps = {
|
|
35
|
+
disabled?: never;
|
|
36
|
+
href?: never;
|
|
37
|
+
/**
|
|
38
|
+
* If the href prop is not provided the clickable element will be a button and use this clickHandler when the user presses the card.
|
|
39
|
+
*/
|
|
40
|
+
onClick?: never;
|
|
41
|
+
linkElement?: never;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type CardHeadingLinkProps = {
|
|
45
|
+
/**
|
|
46
|
+
* Use this to disable the card. Can be used both with a link card and a button card. In the case of the button the clickHandler will not be called and if a anchor tag the href will be removed.
|
|
47
|
+
*/
|
|
48
|
+
disabled?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Makes the card become a link to the provided href.
|
|
51
|
+
*/
|
|
52
|
+
href: string;
|
|
53
|
+
/**
|
|
54
|
+
* If the href prop is not provided the clickable element will be a button and use this clickHandler when the user presses the card.
|
|
55
|
+
*/
|
|
56
|
+
onClick?: () => void;
|
|
57
|
+
linkElement?: ForwardRefExoticComponent<AnchorHTMLAttributes<HTMLAnchorElement>> | "a";
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export type CardHeadingButtonProps = {
|
|
61
|
+
/**
|
|
62
|
+
* Use this to disable the card. Can be used both with a link card and a button card. In the case of the button the clickHandler will not be called and if a anchor tag the href will be removed.
|
|
63
|
+
*/
|
|
64
|
+
disabled?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Makes the card become a link to the provided href.
|
|
67
|
+
*/
|
|
68
|
+
href?: never;
|
|
69
|
+
/**
|
|
70
|
+
* If the href prop is not provided the clickable element will be a button and use this clickHandler when the user presses the card.
|
|
71
|
+
*/
|
|
72
|
+
onClick: () => void;
|
|
73
|
+
linkElement?: never;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export type CardHeadingProps = HTMLAttributes<HTMLHeadingElement> & CardHeadingDefaultProps;
|
|
77
|
+
|
|
27
78
|
const rootClassName = "purpur-card-heading";
|
|
28
79
|
|
|
29
80
|
export const CardHeading = ({
|
|
30
81
|
["data-testid"]: dataTestId = "purpur-card-heading",
|
|
82
|
+
["aria-label"]: ariaLabel,
|
|
31
83
|
title,
|
|
32
84
|
icon,
|
|
33
85
|
children,
|
|
34
86
|
titleTag = "h2",
|
|
35
87
|
enableHyphenation,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
88
|
+
onClick = undefined,
|
|
89
|
+
href = undefined,
|
|
90
|
+
disabled = false,
|
|
91
|
+
linkElement = "a",
|
|
92
|
+
variant = "title-100",
|
|
93
|
+
...props
|
|
94
|
+
}: CardHeadingProps &
|
|
95
|
+
(CardHeadingLinkProps | CardHeadingButtonProps | CardHeadingNonInteractiveProps)) => {
|
|
96
|
+
const classes = cx(rootClassName, {
|
|
97
|
+
[`${rootClassName}--is-interactive`]: onClick || href,
|
|
98
|
+
[`${rootClassName}--disabled`]: disabled,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<div className={classes} data-testid={dataTestId}>
|
|
103
|
+
<div className={cx(`${rootClassName}__header`)}>
|
|
104
|
+
{icon && <div className={cx(`${rootClassName}__icon`)}>{icon}</div>}
|
|
105
|
+
<Heading
|
|
106
|
+
tag={titleTag}
|
|
107
|
+
className={cx(`${rootClassName}__heading`)}
|
|
108
|
+
variant={variant}
|
|
109
|
+
enableHyphenation={enableHyphenation}
|
|
110
|
+
{...props}
|
|
111
|
+
>
|
|
112
|
+
{onClick || href ? (
|
|
113
|
+
<CardTriggerItem
|
|
114
|
+
aria-label={ariaLabel}
|
|
115
|
+
disabled={disabled}
|
|
116
|
+
href={href}
|
|
117
|
+
onClick={onClick}
|
|
118
|
+
linkElement={linkElement}
|
|
119
|
+
>
|
|
120
|
+
{title}
|
|
121
|
+
</CardTriggerItem>
|
|
122
|
+
) : (
|
|
123
|
+
title
|
|
124
|
+
)}
|
|
125
|
+
</Heading>
|
|
126
|
+
</div>
|
|
127
|
+
{children}
|
|
48
128
|
</div>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
);
|
|
129
|
+
);
|
|
130
|
+
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import React, { ReactNode } from "react";
|
|
1
|
+
import React, { type HTMLAttributes, type ReactNode } from "react";
|
|
2
2
|
import c from "classnames/bind";
|
|
3
3
|
|
|
4
4
|
import styles from "./card-media-layout.module.scss";
|
|
5
5
|
|
|
6
6
|
const cx = c.bind(styles);
|
|
7
7
|
|
|
8
|
-
export type CardMediaLayoutProps =
|
|
8
|
+
export type CardMediaLayoutProps = HTMLAttributes<HTMLDivElement> & {
|
|
9
9
|
["data-testid"]?: string;
|
|
10
10
|
children?: ReactNode;
|
|
11
11
|
};
|
package/src/card-media.tsx
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { type HTMLAttributes, type ReactNode } from "react";
|
|
2
2
|
import c from "classnames/bind";
|
|
3
3
|
|
|
4
4
|
import styles from "./card-media.module.scss";
|
|
5
5
|
|
|
6
6
|
const cx = c.bind(styles);
|
|
7
7
|
|
|
8
|
-
export type CardMediaProps =
|
|
8
|
+
export type CardMediaProps = HTMLAttributes<HTMLDivElement> & {
|
|
9
9
|
["data-testid"]?: string;
|
|
10
|
-
children?:
|
|
10
|
+
children?: ReactNode;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
const rootClassName = "purpur-card-media";
|
package/src/card-overline.tsx
CHANGED
|
@@ -24,7 +24,7 @@ export const CardOverline = ({
|
|
|
24
24
|
overline,
|
|
25
25
|
}: CardOverlineProps) => {
|
|
26
26
|
return overline ? (
|
|
27
|
-
<Paragraph className={cx(rootClassName)} data-testid={dataTestId}>
|
|
27
|
+
<Paragraph variant="overline-100" className={cx(rootClassName)} data-testid={dataTestId}>
|
|
28
28
|
{overline}
|
|
29
29
|
</Paragraph>
|
|
30
30
|
) : null;
|
package/src/card-root.test.tsx
CHANGED
|
@@ -32,50 +32,4 @@ describe("CardRoot", () => {
|
|
|
32
32
|
);
|
|
33
33
|
expect(screen.getByTestId("card-root")).not.toHaveClass("purpur-card-root--full-height");
|
|
34
34
|
});
|
|
35
|
-
|
|
36
|
-
it("should render a trigger item if href and screenReaderText props are set", () => {
|
|
37
|
-
render(
|
|
38
|
-
<CardRoot
|
|
39
|
-
data-testid="card-root"
|
|
40
|
-
variant="primary"
|
|
41
|
-
className="purpur-card"
|
|
42
|
-
fullHeight={false}
|
|
43
|
-
href="/link-to-product"
|
|
44
|
-
screenReaderText="Product Name S3 - 799kr/mån"
|
|
45
|
-
>
|
|
46
|
-
Card content
|
|
47
|
-
</CardRoot>
|
|
48
|
-
);
|
|
49
|
-
expect(screen.getByTestId("purpur-card-trigger-item")).toBeInTheDocument();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("should render a trigger item if onClick and screenReaderText props are set", () => {
|
|
53
|
-
render(
|
|
54
|
-
<CardRoot
|
|
55
|
-
data-testid="card-root"
|
|
56
|
-
variant="primary"
|
|
57
|
-
className="purpur-card"
|
|
58
|
-
fullHeight={false}
|
|
59
|
-
onClick={() => null}
|
|
60
|
-
screenReaderText="Product Name S3 - 799kr/mån"
|
|
61
|
-
>
|
|
62
|
-
Card content
|
|
63
|
-
</CardRoot>
|
|
64
|
-
);
|
|
65
|
-
expect(screen.getByTestId("purpur-card-trigger-item")).toBeInTheDocument();
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it("should not render a trigger item if href and onClick props are not set", () => {
|
|
69
|
-
render(
|
|
70
|
-
<CardRoot
|
|
71
|
-
data-testid="card-root"
|
|
72
|
-
variant="primary"
|
|
73
|
-
className="purpur-card"
|
|
74
|
-
fullHeight={false}
|
|
75
|
-
>
|
|
76
|
-
Card content
|
|
77
|
-
</CardRoot>
|
|
78
|
-
);
|
|
79
|
-
expect(screen.queryByTestId("purpur-card-trigger-item")).not.toBeInTheDocument();
|
|
80
|
-
});
|
|
81
35
|
});
|
package/src/card-root.tsx
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import React, {
|
|
2
|
+
type DetailedHTMLProps,
|
|
3
|
+
type ForwardedRef,
|
|
4
|
+
forwardRef,
|
|
5
|
+
type HTMLAttributes,
|
|
6
|
+
type ReactNode,
|
|
7
|
+
} from "react";
|
|
3
8
|
import c from "classnames/bind";
|
|
4
9
|
|
|
5
10
|
import styles from "./card-root.module.scss";
|
|
6
|
-
import { CardTriggerItem } from "./card-trigger-item";
|
|
7
11
|
|
|
8
12
|
const cx = c.bind(styles);
|
|
9
13
|
|
|
10
|
-
type
|
|
14
|
+
export type CardRootProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {
|
|
11
15
|
/**
|
|
12
16
|
* Use this to set a testid on the card
|
|
13
17
|
*/
|
|
@@ -17,54 +21,6 @@ type CardRootDefaultProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
|
17
21
|
variant?: "primary" | "secondary";
|
|
18
22
|
};
|
|
19
23
|
|
|
20
|
-
export type CardRootNonInteractiveProps = {
|
|
21
|
-
disabled?: never;
|
|
22
|
-
href?: never;
|
|
23
|
-
onClick?: never;
|
|
24
|
-
screenReaderText?: never;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export type CardRootLinkProps = {
|
|
28
|
-
/**
|
|
29
|
-
* Use this to disable the card. Can be used both with a link card and a button card. In the case of the button the clickHandler will not be called and if a anchor tag the href will be removed.
|
|
30
|
-
*/
|
|
31
|
-
disabled?: boolean;
|
|
32
|
-
/**
|
|
33
|
-
* Makes the card become a link to the provided href.
|
|
34
|
-
*/
|
|
35
|
-
href: string;
|
|
36
|
-
/**
|
|
37
|
-
* If the href prop is not provided the clickable element will be a button and use this clickHandler when the user presses the card.
|
|
38
|
-
*/
|
|
39
|
-
onClick?: () => unknown;
|
|
40
|
-
/**
|
|
41
|
-
* This is the text that will be read for screen readers when the link/button in the card gets focus. Try to create a text with all the important information about the card here. This text will not be visible in the UI.
|
|
42
|
-
*/
|
|
43
|
-
screenReaderText: string;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export type CardRootButtonProps = {
|
|
47
|
-
/**
|
|
48
|
-
* Use this to disable the card. Can be used both with a link card and a button card. In the case of the button the clickHandler will not be called and if a anchor tag the href will be removed.
|
|
49
|
-
*/
|
|
50
|
-
disabled?: boolean;
|
|
51
|
-
/**
|
|
52
|
-
* Makes the card become a link to the provided href.
|
|
53
|
-
*/
|
|
54
|
-
href?: never;
|
|
55
|
-
/**
|
|
56
|
-
* If the href prop is not provided the clickable element will be a button and use this clickHandler when the user presses the card.
|
|
57
|
-
*/
|
|
58
|
-
onClick: () => unknown;
|
|
59
|
-
/**
|
|
60
|
-
* This is the text that will be read for screen readers when the link/button in the card gets focus. Try to create a text with all the important information about the card here. This text will not be visible in the UI.
|
|
61
|
-
*/
|
|
62
|
-
screenReaderText: string;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export type CardRootProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> &
|
|
66
|
-
CardRootDefaultProps;
|
|
67
|
-
|
|
68
24
|
const rootClassName = "purpur-card-root";
|
|
69
25
|
|
|
70
26
|
export const CardRoot = forwardRef(
|
|
@@ -73,14 +29,10 @@ export const CardRoot = forwardRef(
|
|
|
73
29
|
["data-testid"]: dataTestId = "purpur-card-root",
|
|
74
30
|
children,
|
|
75
31
|
className,
|
|
76
|
-
|
|
77
|
-
fullHeight,
|
|
78
|
-
href,
|
|
79
|
-
onClick,
|
|
80
|
-
screenReaderText,
|
|
32
|
+
fullHeight = true,
|
|
81
33
|
variant,
|
|
82
34
|
...props
|
|
83
|
-
}: CardRootProps
|
|
35
|
+
}: CardRootProps,
|
|
84
36
|
ref: ForwardedRef<HTMLDivElement>
|
|
85
37
|
) => {
|
|
86
38
|
const classes = cx([
|
|
@@ -95,14 +47,6 @@ export const CardRoot = forwardRef(
|
|
|
95
47
|
return (
|
|
96
48
|
<div className={classes} data-testid={dataTestId} ref={ref} {...props}>
|
|
97
49
|
{children}
|
|
98
|
-
{(onClick || href) && screenReaderText && (
|
|
99
|
-
<CardTriggerItem
|
|
100
|
-
disabled={disabled}
|
|
101
|
-
href={href}
|
|
102
|
-
onClick={onClick}
|
|
103
|
-
screenReaderText={screenReaderText}
|
|
104
|
-
/>
|
|
105
|
-
)}
|
|
106
50
|
</div>
|
|
107
51
|
);
|
|
108
52
|
}
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
.purpur-card-trigger-item {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
&--link {
|
|
3
|
+
color: inherit;
|
|
4
|
+
text-decoration: none;
|
|
5
|
+
}
|
|
5
6
|
|
|
6
7
|
&--button {
|
|
7
8
|
background-color: transparent;
|
|
8
9
|
border: none;
|
|
10
|
+
padding: 0;
|
|
11
|
+
font-size: inherit;
|
|
12
|
+
font-weight: inherit;
|
|
13
|
+
font-family: inherit;
|
|
14
|
+
color: inherit;
|
|
15
|
+
line-height: inherit;
|
|
9
16
|
cursor: pointer;
|
|
17
|
+
text-align: left;
|
|
18
|
+
text-rendering: geometricPrecision;
|
|
10
19
|
}
|
|
11
20
|
|
|
12
21
|
&--disabled {
|
|
@@ -16,4 +25,11 @@
|
|
|
16
25
|
&:focus-visible {
|
|
17
26
|
outline: none;
|
|
18
27
|
}
|
|
28
|
+
|
|
29
|
+
&::before {
|
|
30
|
+
content: "";
|
|
31
|
+
position: absolute;
|
|
32
|
+
inset: 0;
|
|
33
|
+
z-index: 1;
|
|
34
|
+
}
|
|
19
35
|
}
|
|
@@ -1,28 +1,35 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
type AnchorHTMLAttributes,
|
|
3
|
+
type ForwardRefExoticComponent,
|
|
4
|
+
type MouseEvent,
|
|
5
|
+
type ReactNode,
|
|
6
|
+
} from "react";
|
|
2
7
|
import c from "classnames/bind";
|
|
3
8
|
|
|
4
9
|
import styles from "./card-trigger-item.module.scss";
|
|
5
10
|
|
|
6
11
|
const cx = c.bind(styles);
|
|
7
12
|
|
|
8
|
-
import { VisuallyHidden } from "@purpurds/visually-hidden";
|
|
9
|
-
|
|
10
13
|
export type CardTriggerItemProps = {
|
|
11
14
|
["data-testid"]?: string;
|
|
15
|
+
["aria-label"]?: string;
|
|
12
16
|
disabled?: boolean;
|
|
13
17
|
href?: string;
|
|
14
18
|
onClick?: () => unknown;
|
|
15
|
-
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
linkElement?: ForwardRefExoticComponent<AnchorHTMLAttributes<HTMLAnchorElement>> | "a";
|
|
16
21
|
};
|
|
17
22
|
|
|
18
23
|
const rootClassName = "purpur-card-trigger-item";
|
|
19
24
|
|
|
20
25
|
export const CardTriggerItem = ({
|
|
21
26
|
["data-testid"]: dataTestId = "purpur-card-trigger-item",
|
|
27
|
+
["aria-label"]: ariaLabel,
|
|
22
28
|
disabled = false,
|
|
23
29
|
href,
|
|
24
30
|
onClick,
|
|
25
|
-
|
|
31
|
+
children,
|
|
32
|
+
linkElement: LinkElement = "a",
|
|
26
33
|
}: CardTriggerItemProps) => {
|
|
27
34
|
const handleClick = (e: MouseEvent<HTMLButtonElement | HTMLAnchorElement>): void => {
|
|
28
35
|
if (disabled) {
|
|
@@ -37,11 +44,12 @@ export const CardTriggerItem = ({
|
|
|
37
44
|
}`;
|
|
38
45
|
|
|
39
46
|
return href ? (
|
|
40
|
-
|
|
41
|
-
<a
|
|
47
|
+
<LinkElement
|
|
42
48
|
aria-disabled={disabled}
|
|
49
|
+
aria-label={ariaLabel}
|
|
43
50
|
className={`${cx([
|
|
44
51
|
rootClassName,
|
|
52
|
+
`${rootClassName}--link`,
|
|
45
53
|
{
|
|
46
54
|
[`${rootClassName}--disabled`]: disabled,
|
|
47
55
|
},
|
|
@@ -51,11 +59,12 @@ export const CardTriggerItem = ({
|
|
|
51
59
|
tabIndex={disabled ? 0 : undefined}
|
|
52
60
|
onClick={handleClick}
|
|
53
61
|
>
|
|
54
|
-
|
|
55
|
-
</
|
|
62
|
+
{children}
|
|
63
|
+
</LinkElement>
|
|
56
64
|
) : (
|
|
57
65
|
<button
|
|
58
66
|
aria-disabled={disabled}
|
|
67
|
+
aria-label={ariaLabel}
|
|
59
68
|
className={`${cx([
|
|
60
69
|
rootClassName,
|
|
61
70
|
`${rootClassName}--button`,
|
|
@@ -67,7 +76,7 @@ export const CardTriggerItem = ({
|
|
|
67
76
|
type="button"
|
|
68
77
|
onClick={handleClick}
|
|
69
78
|
>
|
|
70
|
-
|
|
79
|
+
{children}
|
|
71
80
|
</button>
|
|
72
81
|
);
|
|
73
82
|
};
|
package/src/card.stories.tsx
CHANGED
|
@@ -20,6 +20,8 @@ const meta = {
|
|
|
20
20
|
title: "Components/Card",
|
|
21
21
|
component: Card,
|
|
22
22
|
subcomponents: {
|
|
23
|
+
//@ts-ignore
|
|
24
|
+
"Card.Heading": Card.Heading,
|
|
23
25
|
//@ts-ignore
|
|
24
26
|
"Card.ContentContainer": Card.ContentContainer,
|
|
25
27
|
//@ts-ignore
|
|
@@ -33,23 +35,15 @@ const meta = {
|
|
|
33
35
|
//@ts-ignore
|
|
34
36
|
"Card.Overline": Card.Overline,
|
|
35
37
|
//@ts-ignore
|
|
36
|
-
"Card.Heading": Card.Heading,
|
|
37
|
-
//@ts-ignore
|
|
38
38
|
"Card.Media": Card.Media,
|
|
39
39
|
//@ts-ignore
|
|
40
40
|
"Card.MediaLayout": Card.MediaLayout,
|
|
41
41
|
},
|
|
42
42
|
args: {
|
|
43
|
-
href: "/?path=/docs/components-card--docs",
|
|
44
|
-
screenReaderText: "Browse to tips and tricks",
|
|
45
43
|
variant: "primary",
|
|
46
44
|
fullHeight: false,
|
|
47
|
-
disabled: false,
|
|
48
45
|
},
|
|
49
46
|
argTypes: {
|
|
50
|
-
onClick: {
|
|
51
|
-
table: { type: { summary: "() => unknown" } },
|
|
52
|
-
},
|
|
53
47
|
variant: {
|
|
54
48
|
options: ["primary", "secondary"],
|
|
55
49
|
control: {
|
|
@@ -57,6 +51,17 @@ const meta = {
|
|
|
57
51
|
},
|
|
58
52
|
},
|
|
59
53
|
},
|
|
54
|
+
parameters: {
|
|
55
|
+
docs: {
|
|
56
|
+
description: {
|
|
57
|
+
component: `
|
|
58
|
+
<br/>
|
|
59
|
+
<br/>
|
|
60
|
+
## Action using link or button
|
|
61
|
+
The Card component can be used to create a link or button. To do so, use the \`Card.Heading\` component with either \`href\` or \`onClick\` prop.`,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
60
65
|
} satisfies Meta<typeof Card>;
|
|
61
66
|
|
|
62
67
|
export default meta;
|
|
@@ -76,10 +81,13 @@ export const CardWithHeading: Story = {
|
|
|
76
81
|
{Array(4)
|
|
77
82
|
.fill(0)
|
|
78
83
|
.map((_, index) => (
|
|
79
|
-
|
|
80
84
|
<Card {...args} key={index}>
|
|
81
85
|
<Card.ContentContainer gapSize="sm">
|
|
82
|
-
<Card.Heading
|
|
86
|
+
<Card.Heading
|
|
87
|
+
title="Tips and tricks"
|
|
88
|
+
icon={<IconSimcard size="sm" />}
|
|
89
|
+
href="/?path=/docs/components-card--docs"
|
|
90
|
+
>
|
|
83
91
|
<Card.Cta linkStyling>
|
|
84
92
|
<IconArrowRight size="sm" />
|
|
85
93
|
</Card.Cta>
|
package/src/card.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { type FunctionComponent } from "react";
|
|
2
2
|
import c from "classnames/bind";
|
|
3
3
|
|
|
4
4
|
import styles from "./card.module.scss";
|
|
@@ -11,17 +11,18 @@ import { CardHeading } from "./card-heading";
|
|
|
11
11
|
import { CardMedia } from "./card-media";
|
|
12
12
|
import { CardMediaLayout } from "./card-media-layout";
|
|
13
13
|
import { CardOverline } from "./card-overline";
|
|
14
|
-
import type {
|
|
15
|
-
CardRootButtonProps,
|
|
16
|
-
CardRootLinkProps,
|
|
17
|
-
CardRootNonInteractiveProps,
|
|
18
|
-
CardRootProps,
|
|
19
|
-
} from "./card-root";
|
|
14
|
+
import type { CardRootProps } from "./card-root";
|
|
20
15
|
import { CardRoot } from "./card-root";
|
|
16
|
+
export type {
|
|
17
|
+
CardHeadingButtonProps,
|
|
18
|
+
CardHeadingDefaultProps,
|
|
19
|
+
CardHeadingLinkProps,
|
|
20
|
+
CardHeadingNonInteractiveProps,
|
|
21
|
+
} from "./card-heading";
|
|
21
22
|
|
|
22
23
|
const cx = c.bind(styles);
|
|
23
24
|
|
|
24
|
-
type CardCmp<P> =
|
|
25
|
+
type CardCmp<P> = FunctionComponent<P> & {
|
|
25
26
|
Badge: typeof CardBadge;
|
|
26
27
|
Content: typeof CardContent;
|
|
27
28
|
ContentContainer: typeof CardContentContainer;
|
|
@@ -34,23 +35,11 @@ type CardCmp<P> = React.FunctionComponent<P> & {
|
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
export type CardProps = CardRootProps;
|
|
37
|
-
export type CardButtonProps = CardRootButtonProps;
|
|
38
|
-
export type CardLinkProps = CardRootLinkProps;
|
|
39
|
-
export type CardNonInteractiveProps = CardRootNonInteractiveProps;
|
|
40
38
|
|
|
41
39
|
const rootClassName = "purpur-card";
|
|
42
40
|
|
|
43
|
-
export const Card: CardCmp<
|
|
44
|
-
|
|
45
|
-
> = ({ children, className, ...props }) => {
|
|
46
|
-
const classes = cx([
|
|
47
|
-
rootClassName,
|
|
48
|
-
className,
|
|
49
|
-
{
|
|
50
|
-
[`${rootClassName}--is-interactive`]: props.onClick || props.href,
|
|
51
|
-
[`${rootClassName}--disabled`]: props.disabled,
|
|
52
|
-
},
|
|
53
|
-
]);
|
|
41
|
+
export const Card: CardCmp<CardProps> = ({ children, className, ...props }) => {
|
|
42
|
+
const classes = cx([rootClassName, className]);
|
|
54
43
|
return (
|
|
55
44
|
<div
|
|
56
45
|
className={cx(`${rootClassName}__container`, {
|