@dnanpm/ui-components 0.7.0 → 0.9.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/components/Accordion/Accordion.css +6 -3
- package/dist/components/AccordionItem/AccordionItem.css +6 -3
- package/dist/components/Breadcrumb/Breadcrumb.css +15 -12
- package/dist/components/Breadcrumb/Breadcrumb.module.css.cjs +6 -6
- package/dist/components/Breadcrumb/Breadcrumb.module.css.js +6 -6
- package/dist/components/Button/Button.css +33 -32
- package/dist/components/Button/Button.module.css.cjs +11 -11
- package/dist/components/Button/Button.module.css.js +11 -11
- package/dist/components/ButtonCard/ButtonCard.cjs +105 -0
- package/dist/components/ButtonCard/ButtonCard.cjs.map +1 -0
- package/dist/components/ButtonCard/ButtonCard.css +166 -0
- package/dist/components/ButtonCard/ButtonCard.d.ts +3 -0
- package/dist/components/ButtonCard/ButtonCard.d.ts.map +1 -0
- package/dist/components/ButtonCard/ButtonCard.js +105 -0
- package/dist/components/ButtonCard/ButtonCard.js.map +1 -0
- package/dist/components/ButtonCard/ButtonCard.module.css.cjs +18 -0
- package/dist/components/ButtonCard/ButtonCard.module.css.cjs.map +1 -0
- package/dist/components/ButtonCard/ButtonCard.module.css.js +19 -0
- package/dist/components/ButtonCard/ButtonCard.module.css.js.map +1 -0
- package/dist/components/ButtonCard/ButtonCard.types.d.ts +103 -0
- package/dist/components/ButtonCard/ButtonCard.types.d.ts.map +1 -0
- package/dist/components/ButtonCard/index.d.ts +3 -0
- package/dist/components/ButtonCard/index.d.ts.map +1 -0
- package/dist/components/ContentCard/ContentCard.cjs +96 -0
- package/dist/components/ContentCard/ContentCard.cjs.map +1 -0
- package/dist/components/ContentCard/ContentCard.css +249 -0
- package/dist/components/ContentCard/ContentCard.d.ts +3 -0
- package/dist/components/ContentCard/ContentCard.d.ts.map +1 -0
- package/dist/components/ContentCard/ContentCard.js +96 -0
- package/dist/components/ContentCard/ContentCard.js.map +1 -0
- package/dist/components/ContentCard/ContentCard.module.css.cjs +24 -0
- package/dist/components/ContentCard/ContentCard.module.css.cjs.map +1 -0
- package/dist/components/ContentCard/ContentCard.module.css.js +25 -0
- package/dist/components/ContentCard/ContentCard.module.css.js.map +1 -0
- package/dist/components/ContentCard/ContentCard.types.d.ts +99 -0
- package/dist/components/ContentCard/ContentCard.types.d.ts.map +1 -0
- package/dist/components/ContentCard/index.d.ts +3 -0
- package/dist/components/ContentCard/index.d.ts.map +1 -0
- package/dist/components/Drawer/Drawer.cjs +101 -0
- package/dist/components/Drawer/Drawer.cjs.map +1 -0
- package/dist/components/Drawer/Drawer.css +218 -0
- package/dist/components/Drawer/Drawer.d.ts +3 -0
- package/dist/components/Drawer/Drawer.d.ts.map +1 -0
- package/dist/components/Drawer/Drawer.js +101 -0
- package/dist/components/Drawer/Drawer.js.map +1 -0
- package/dist/components/Drawer/Drawer.module.css.cjs +37 -0
- package/dist/components/Drawer/Drawer.module.css.cjs.map +1 -0
- package/dist/components/Drawer/Drawer.module.css.js +37 -0
- package/dist/components/Drawer/Drawer.module.css.js.map +1 -0
- package/dist/components/Drawer/Drawer.types.d.ts +63 -0
- package/dist/components/Drawer/Drawer.types.d.ts.map +1 -0
- package/dist/components/Drawer/index.d.ts +3 -0
- package/dist/components/Drawer/index.d.ts.map +1 -0
- package/dist/components/Footer/Footer.css +87 -77
- package/dist/components/Footer/Footer.module.css.cjs +39 -39
- package/dist/components/Footer/Footer.module.css.js +39 -39
- package/dist/components/FunctionButton/FunctionButton.cjs +34 -0
- package/dist/components/FunctionButton/FunctionButton.cjs.map +1 -0
- package/dist/components/FunctionButton/FunctionButton.css +124 -0
- package/dist/components/FunctionButton/FunctionButton.d.ts +3 -0
- package/dist/components/FunctionButton/FunctionButton.d.ts.map +1 -0
- package/dist/components/FunctionButton/FunctionButton.js +34 -0
- package/dist/components/FunctionButton/FunctionButton.js.map +1 -0
- package/dist/components/FunctionButton/FunctionButton.module.css.cjs +11 -0
- package/dist/components/FunctionButton/FunctionButton.module.css.cjs.map +1 -0
- package/dist/components/FunctionButton/FunctionButton.module.css.js +12 -0
- package/dist/components/FunctionButton/FunctionButton.module.css.js.map +1 -0
- package/dist/components/FunctionButton/FunctionButton.types.d.ts +21 -0
- package/dist/components/FunctionButton/FunctionButton.types.d.ts.map +1 -0
- package/dist/components/FunctionButton/index.d.ts +3 -0
- package/dist/components/FunctionButton/index.d.ts.map +1 -0
- package/dist/components/Hero/Hero.cjs +24 -26
- package/dist/components/Hero/Hero.cjs.map +1 -1
- package/dist/components/Hero/Hero.css +81 -74
- package/dist/components/Hero/Hero.js +24 -26
- package/dist/components/Hero/Hero.js.map +1 -1
- package/dist/components/Hero/Hero.module.css.cjs +20 -17
- package/dist/components/Hero/Hero.module.css.cjs.map +1 -1
- package/dist/components/Hero/Hero.module.css.js +20 -17
- package/dist/components/Hero/Hero.module.css.js.map +1 -1
- package/dist/components/IconButton/IconButton.css +32 -34
- package/dist/components/IconButton/IconButton.module.css.cjs +9 -9
- package/dist/components/IconButton/IconButton.module.css.js +9 -9
- package/dist/components/Label/Label.css +2 -3
- package/dist/components/MainNavigation/MainNavigation.cjs +415 -120
- package/dist/components/MainNavigation/MainNavigation.cjs.map +1 -1
- package/dist/components/MainNavigation/MainNavigation.css +265 -159
- package/dist/components/MainNavigation/MainNavigation.d.ts +1 -1
- package/dist/components/MainNavigation/MainNavigation.d.ts.map +1 -1
- package/dist/components/MainNavigation/MainNavigation.js +417 -122
- package/dist/components/MainNavigation/MainNavigation.js.map +1 -1
- package/dist/components/MainNavigation/MainNavigation.module.css.cjs +78 -68
- package/dist/components/MainNavigation/MainNavigation.module.css.cjs.map +1 -1
- package/dist/components/MainNavigation/MainNavigation.module.css.js +78 -68
- package/dist/components/MainNavigation/MainNavigation.module.css.js.map +1 -1
- package/dist/components/MainNavigation/MainNavigation.types.d.ts +64 -17
- package/dist/components/MainNavigation/MainNavigation.types.d.ts.map +1 -1
- package/dist/components/MainNavigation/MainNavigation.utils.cjs +20 -0
- package/dist/components/MainNavigation/MainNavigation.utils.cjs.map +1 -1
- package/dist/components/MainNavigation/MainNavigation.utils.d.ts +10 -1
- package/dist/components/MainNavigation/MainNavigation.utils.d.ts.map +1 -1
- package/dist/components/MainNavigation/MainNavigation.utils.js +20 -0
- package/dist/components/MainNavigation/MainNavigation.utils.js.map +1 -1
- package/dist/components/MainNavigation/index.d.ts +1 -1
- package/dist/components/MainNavigation/index.d.ts.map +1 -1
- package/dist/components/Modal/Modal.cjs +101 -0
- package/dist/components/Modal/Modal.cjs.map +1 -0
- package/dist/components/Modal/Modal.css +204 -0
- package/dist/components/Modal/Modal.d.ts +3 -0
- package/dist/components/Modal/Modal.d.ts.map +1 -0
- package/dist/components/Modal/Modal.js +101 -0
- package/dist/components/Modal/Modal.js.map +1 -0
- package/dist/components/Modal/Modal.module.css.cjs +39 -0
- package/dist/components/Modal/Modal.module.css.cjs.map +1 -0
- package/dist/components/Modal/Modal.module.css.js +39 -0
- package/dist/components/Modal/Modal.module.css.js.map +1 -0
- package/dist/components/Modal/Modal.types.d.ts +62 -0
- package/dist/components/Modal/Modal.types.d.ts.map +1 -0
- package/dist/components/Modal/index.d.ts +3 -0
- package/dist/components/Modal/index.d.ts.map +1 -0
- package/dist/components/Modal/useDialogDismissal.cjs +41 -0
- package/dist/components/Modal/useDialogDismissal.cjs.map +1 -0
- package/dist/components/Modal/useDialogDismissal.d.ts +17 -0
- package/dist/components/Modal/useDialogDismissal.d.ts.map +1 -0
- package/dist/components/Modal/useDialogDismissal.js +41 -0
- package/dist/components/Modal/useDialogDismissal.js.map +1 -0
- package/dist/components/Modal/useNativeDialog.cjs +126 -0
- package/dist/components/Modal/useNativeDialog.cjs.map +1 -0
- package/dist/components/Modal/useNativeDialog.d.ts +14 -0
- package/dist/components/Modal/useNativeDialog.d.ts.map +1 -0
- package/dist/components/Modal/useNativeDialog.js +126 -0
- package/dist/components/Modal/useNativeDialog.js.map +1 -0
- package/dist/components/Notification/Notification.css +6 -3
- package/dist/components/Pictograph/Pictograph.css +6 -3
- package/dist/components/Pictograph/PictographItem.css +6 -3
- package/dist/components/Quote/Quote.css +2 -3
- package/dist/components/Spinner/Spinner.css +6 -3
- package/dist/index.cjs +10 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/styles/utils/elevation.css +2 -3
- package/dist/styles/utils/elevation.module.css.cjs +3 -0
- package/dist/styles/utils/elevation.module.css.cjs.map +1 -1
- package/dist/styles/utils/elevation.module.css.js +4 -1
- package/dist/styles/utils/elevation.module.css.js.map +1 -1
- package/dist/styles/utils/focus.css +26 -24
- package/dist/styles/utils/focus.module.css.cjs +3 -6
- package/dist/styles/utils/focus.module.css.cjs.map +1 -1
- package/dist/styles/utils/focus.module.css.js +4 -7
- package/dist/styles/utils/focus.module.css.js.map +1 -1
- package/dist/styles/utils/overlay.css +2 -3
- package/dist/styles/utils/text-decoration.css +4 -4
- package/dist/styles/utils/text-decoration.module.css.cjs +2 -2
- package/dist/styles/utils/text-decoration.module.css.js +2 -2
- package/dist/styles.css +17 -7
- package/package.json +3 -3
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
@layer dds-base, dds-components;@layer dds-components { @layer fallback, components; }@layer dds-components.components{._button-card_14hpp_1 {
|
|
2
|
+
--_button-card-padding: var(--spacing-space-16);
|
|
3
|
+
--_button-card-gap: var(--spacing-space-16);
|
|
4
|
+
--_button-card-content-gap: var(--spacing-space-16);
|
|
5
|
+
--_button-card-text-gap: var(--spacing-space-4);
|
|
6
|
+
--_button-card-line-clamp: 2;
|
|
7
|
+
--_button-card-media-box: 56px;
|
|
8
|
+
--_button-card-media-icon: 40px;
|
|
9
|
+
--_button-card-indicator: 24px;
|
|
10
|
+
--_button-card-title-font: var(--typography-label-lg-bold);
|
|
11
|
+
--_button-card-subtitle-font: var(--typography-label-md);
|
|
12
|
+
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
gap: var(--_button-card-gap);
|
|
16
|
+
width: 100%;
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
margin: 0;
|
|
19
|
+
padding: var(--_button-card-padding);
|
|
20
|
+
font: inherit;
|
|
21
|
+
text-align: start;
|
|
22
|
+
text-decoration: none;
|
|
23
|
+
color: var(--color-semantic-foreground-default);
|
|
24
|
+
background-color: var(--color-semantic-surface-base);
|
|
25
|
+
border-color: var(--color-semantic-border-neutral-soft);
|
|
26
|
+
border-radius: var(--radius-semantic-md);
|
|
27
|
+
cursor: pointer;
|
|
28
|
+
appearance: none;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
._button-card_14hpp_1:where(:hover, :focus-visible) {
|
|
32
|
+
border-color: var(--color-semantic-border-neutral-mid);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* === Size variants (base holds the medium/default values) === */
|
|
36
|
+
|
|
37
|
+
._button-card--large_14hpp_37 {
|
|
38
|
+
--_button-card-title-font: var(--typography-heading-xs);
|
|
39
|
+
--_button-card-subtitle-font: var(--typography-label-lg);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
._button-card--small_14hpp_42 {
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
align-items: stretch;
|
|
45
|
+
--_button-card-padding: var(--spacing-space-8);
|
|
46
|
+
--_button-card-gap: var(--spacing-space-4);
|
|
47
|
+
--_button-card-content-gap: var(--spacing-space-8);
|
|
48
|
+
--_button-card-text-gap: 0;
|
|
49
|
+
--_button-card-line-clamp: 1;
|
|
50
|
+
--_button-card-media-box: 40px;
|
|
51
|
+
--_button-card-media-icon: 24px;
|
|
52
|
+
--_button-card-indicator: 16px;
|
|
53
|
+
--_button-card-title-font: var(--typography-label-md);
|
|
54
|
+
--_button-card-subtitle-font: var(--typography-label-sm);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* === Media === */
|
|
58
|
+
|
|
59
|
+
._button-card__media_14hpp_59 {
|
|
60
|
+
display: inline-flex;
|
|
61
|
+
flex-shrink: 0;
|
|
62
|
+
align-self: center;
|
|
63
|
+
align-items: center;
|
|
64
|
+
justify-content: center;
|
|
65
|
+
overflow: hidden;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
._button-card--small_14hpp_42 ._button-card__media_14hpp_59 {
|
|
69
|
+
align-self: flex-start;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
._button-card__media--icon_14hpp_72 {
|
|
73
|
+
width: var(--_button-card-media-box);
|
|
74
|
+
height: var(--_button-card-media-box);
|
|
75
|
+
background-color: var(--color-semantic-surface-neutral-mid);
|
|
76
|
+
border-radius: var(--radius-semantic-md);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
._button-card__media--icon_14hpp_72 svg {
|
|
80
|
+
display: block;
|
|
81
|
+
width: var(--_button-card-media-icon);
|
|
82
|
+
height: var(--_button-card-media-icon);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
._button-card__media--image_14hpp_85 {
|
|
86
|
+
position: relative;
|
|
87
|
+
width: var(--_button-card-media-box);
|
|
88
|
+
height: var(--_button-card-media-box);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
._button-card__media--image_14hpp_85 :where(img, picture, video, svg, canvas) {
|
|
92
|
+
display: block;
|
|
93
|
+
width: 100%;
|
|
94
|
+
height: 100%;
|
|
95
|
+
object-fit: cover;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* === Text === */
|
|
99
|
+
|
|
100
|
+
._button-card__content_14hpp_100 {
|
|
101
|
+
display: flex;
|
|
102
|
+
flex: 1 1 0;
|
|
103
|
+
min-width: 0;
|
|
104
|
+
align-items: center;
|
|
105
|
+
gap: var(--_button-card-content-gap);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
._button-card__text_14hpp_108 {
|
|
109
|
+
display: flex;
|
|
110
|
+
flex: 1 1 0;
|
|
111
|
+
min-width: 0;
|
|
112
|
+
flex-direction: column;
|
|
113
|
+
justify-content: center;
|
|
114
|
+
gap: var(--_button-card-text-gap);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
._button-card__title_14hpp_117,
|
|
118
|
+
._button-card__subtitle_14hpp_118 {
|
|
119
|
+
display: -webkit-box;
|
|
120
|
+
margin: 0;
|
|
121
|
+
overflow: hidden;
|
|
122
|
+
overflow-wrap: anywhere;
|
|
123
|
+
-webkit-box-orient: vertical;
|
|
124
|
+
-webkit-line-clamp: var(--_button-card-line-clamp);
|
|
125
|
+
line-clamp: var(--_button-card-line-clamp);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
._button-card__title_14hpp_117 {
|
|
129
|
+
color: var(--color-semantic-foreground-default);
|
|
130
|
+
font: var(--_button-card-title-font);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
._button-card__subtitle_14hpp_118 {
|
|
134
|
+
color: var(--color-semantic-foreground-muted);
|
|
135
|
+
font: var(--_button-card-subtitle-font);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* === Indicator === */
|
|
139
|
+
|
|
140
|
+
._button-card__indicator_14hpp_140 {
|
|
141
|
+
display: inline-flex;
|
|
142
|
+
flex-shrink: 0;
|
|
143
|
+
align-items: center;
|
|
144
|
+
justify-content: center;
|
|
145
|
+
color: var(--color-semantic-foreground-primary-strong);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
._button-card__indicator_14hpp_140 svg {
|
|
149
|
+
display: block;
|
|
150
|
+
width: var(--_button-card-indicator);
|
|
151
|
+
height: var(--_button-card-indicator);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* === Visually hidden === */
|
|
155
|
+
|
|
156
|
+
._button-card__sr-only_14hpp_156 {
|
|
157
|
+
position: absolute;
|
|
158
|
+
width: 1px;
|
|
159
|
+
height: 1px;
|
|
160
|
+
padding: 0;
|
|
161
|
+
margin: -1px;
|
|
162
|
+
overflow: hidden;
|
|
163
|
+
white-space: nowrap;
|
|
164
|
+
border: 0;
|
|
165
|
+
clip: rect(0, 0, 0, 0);
|
|
166
|
+
} }
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { ButtonCardProps } from './ButtonCard.types';
|
|
2
|
+
export declare const ButtonCard: ({ title, subtitle, size, icon, image, isExternal, externalLinkAriaLabel, className, ref, ...props }: ButtonCardProps) => import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
//# sourceMappingURL=ButtonCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ButtonCard.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonCard/ButtonCard.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAuB,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE/E,eAAO,MAAM,UAAU,GAAI,qGAWxB,eAAe,4CAgIjB,CAAC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Open, ChevronRight } from "@dnanpm/icons";
|
|
3
|
+
import focusStyles from "../../styles/utils/focus.module.css.js";
|
|
4
|
+
import elevationStyles from "../../styles/utils/elevation.module.css.js";
|
|
5
|
+
import styles from "./ButtonCard.module.css.js";
|
|
6
|
+
import { cn } from "../../utils/cn/cn.js";
|
|
7
|
+
const ButtonCard = ({
|
|
8
|
+
title,
|
|
9
|
+
subtitle,
|
|
10
|
+
size = "medium",
|
|
11
|
+
icon,
|
|
12
|
+
image,
|
|
13
|
+
isExternal = false,
|
|
14
|
+
externalLinkAriaLabel = "avautuu uuteen välilehteen",
|
|
15
|
+
className,
|
|
16
|
+
ref,
|
|
17
|
+
...props
|
|
18
|
+
}) => {
|
|
19
|
+
const isAnchor = "href" in props && props.href != null;
|
|
20
|
+
const classes = cn(
|
|
21
|
+
styles["button-card"],
|
|
22
|
+
styles[`button-card--${size}`],
|
|
23
|
+
focusStyles.focusable,
|
|
24
|
+
elevationStyles.elevationLow,
|
|
25
|
+
className
|
|
26
|
+
);
|
|
27
|
+
const IconComponent = icon;
|
|
28
|
+
const media = IconComponent != null ? /* @__PURE__ */ jsx(
|
|
29
|
+
"span",
|
|
30
|
+
{
|
|
31
|
+
className: cn(styles["button-card__media"], styles["button-card__media--icon"]),
|
|
32
|
+
"aria-hidden": "true",
|
|
33
|
+
children: /* @__PURE__ */ jsx(IconComponent, { "aria-hidden": "true" })
|
|
34
|
+
}
|
|
35
|
+
) : image ? /* @__PURE__ */ jsx("span", { className: cn(styles["button-card__media"], styles["button-card__media--image"]), children: image }) : null;
|
|
36
|
+
const explicitTarget = isAnchor ? props.target?.toLowerCase() : void 0;
|
|
37
|
+
const opensInNewTab = isExternal || explicitTarget === "_blank";
|
|
38
|
+
const Indicator = opensInNewTab ? Open : ChevronRight;
|
|
39
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
40
|
+
media,
|
|
41
|
+
/* @__PURE__ */ jsxs("span", { className: styles["button-card__content"], children: [
|
|
42
|
+
/* @__PURE__ */ jsxs("span", { className: styles["button-card__text"], children: [
|
|
43
|
+
/* @__PURE__ */ jsx("span", { className: styles["button-card__title"], children: title }),
|
|
44
|
+
subtitle != null && /* @__PURE__ */ jsx("span", { className: styles["button-card__subtitle"], children: subtitle })
|
|
45
|
+
] }),
|
|
46
|
+
/* @__PURE__ */ jsx("span", { className: styles["button-card__indicator"], "aria-hidden": "true", children: /* @__PURE__ */ jsx(Indicator, { "aria-hidden": "true" }) })
|
|
47
|
+
] }),
|
|
48
|
+
opensInNewTab && externalLinkAriaLabel && /* @__PURE__ */ jsx("span", { className: styles["button-card__sr-only"], children: ` (${externalLinkAriaLabel})` })
|
|
49
|
+
] });
|
|
50
|
+
if (isAnchor) {
|
|
51
|
+
const {
|
|
52
|
+
href,
|
|
53
|
+
renderLink,
|
|
54
|
+
target: targetProp,
|
|
55
|
+
rel,
|
|
56
|
+
disabled: _disabled,
|
|
57
|
+
...safeAnchorProps
|
|
58
|
+
} = props;
|
|
59
|
+
const target = isExternal ? "_blank" : targetProp;
|
|
60
|
+
const shouldHardenRel = target?.toLowerCase() === "_blank";
|
|
61
|
+
const relTokens = new Set(
|
|
62
|
+
(rel ?? "").split(/\s+/).filter(Boolean).map((token) => token.toLowerCase())
|
|
63
|
+
);
|
|
64
|
+
if (shouldHardenRel) {
|
|
65
|
+
relTokens.add("noopener");
|
|
66
|
+
relTokens.add("noreferrer");
|
|
67
|
+
}
|
|
68
|
+
const hardenedRel = relTokens.size > 0 ? Array.from(relTokens).join(" ") : void 0;
|
|
69
|
+
const linkProps = {
|
|
70
|
+
...safeAnchorProps,
|
|
71
|
+
ref,
|
|
72
|
+
href,
|
|
73
|
+
target,
|
|
74
|
+
rel: hardenedRel,
|
|
75
|
+
className: classes,
|
|
76
|
+
children: content
|
|
77
|
+
};
|
|
78
|
+
if (renderLink) {
|
|
79
|
+
return /* @__PURE__ */ jsx(Fragment, { children: renderLink(linkProps) });
|
|
80
|
+
}
|
|
81
|
+
return /* @__PURE__ */ jsx("a", { ...linkProps });
|
|
82
|
+
}
|
|
83
|
+
const {
|
|
84
|
+
type = "button",
|
|
85
|
+
href: _href,
|
|
86
|
+
target: _target,
|
|
87
|
+
rel: _rel,
|
|
88
|
+
renderLink: _renderLink,
|
|
89
|
+
...buttonProps
|
|
90
|
+
} = props;
|
|
91
|
+
return /* @__PURE__ */ jsx(
|
|
92
|
+
"button",
|
|
93
|
+
{
|
|
94
|
+
ref,
|
|
95
|
+
type,
|
|
96
|
+
className: classes,
|
|
97
|
+
...buttonProps,
|
|
98
|
+
children: content
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
};
|
|
102
|
+
export {
|
|
103
|
+
ButtonCard
|
|
104
|
+
};
|
|
105
|
+
//# sourceMappingURL=ButtonCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ButtonCard.js","sources":["../../../src/components/ButtonCard/ButtonCard.tsx"],"sourcesContent":["import type { ComponentPropsWithRef, ReactNode, Ref } from 'react';\nimport { ChevronRight, Open } from '@dnanpm/icons';\nimport { cn } from '../../utils/cn';\nimport focusStyles from '../../styles/utils/focus.module.css';\nimport elevationStyles from '../../styles/utils/elevation.module.css';\nimport styles from './ButtonCard.module.css';\nimport type { ButtonCardLinkProps, ButtonCardProps } from './ButtonCard.types';\n\nexport const ButtonCard = ({\n title,\n subtitle,\n size = 'medium',\n icon,\n image,\n isExternal = false,\n externalLinkAriaLabel = 'avautuu uuteen välilehteen',\n className,\n ref,\n ...props\n}: ButtonCardProps) => {\n const isAnchor = 'href' in props && (props as { href?: string }).href != null;\n\n const classes = cn(\n styles['button-card'],\n styles[`button-card--${size}`],\n focusStyles.focusable,\n elevationStyles.elevationLow,\n className,\n );\n\n const IconComponent = icon;\n\n const media =\n IconComponent != null ? (\n <span\n className={cn(styles['button-card__media'], styles['button-card__media--icon'])}\n aria-hidden=\"true\"\n >\n <IconComponent aria-hidden=\"true\" />\n </span>\n ) : image ? (\n <span className={cn(styles['button-card__media'], styles['button-card__media--image'])}>\n {image}\n </span>\n ) : null;\n\n const explicitTarget = isAnchor\n ? (props as { target?: string }).target?.toLowerCase()\n : undefined;\n // The link opens a new tab when isExternal is set or the target is _blank.\n const opensInNewTab = isExternal || explicitTarget === '_blank';\n const Indicator = opensInNewTab ? Open : ChevronRight;\n\n const content = (\n <>\n {media}\n <span className={styles['button-card__content']}>\n <span className={styles['button-card__text']}>\n <span className={styles['button-card__title']}>{title}</span>\n {subtitle != null && (\n <span className={styles['button-card__subtitle']}>{subtitle}</span>\n )}\n </span>\n <span className={styles['button-card__indicator']} aria-hidden=\"true\">\n <Indicator aria-hidden=\"true\" />\n </span>\n </span>\n {opensInNewTab && externalLinkAriaLabel && (\n <span className={styles['button-card__sr-only']}>\n {` (${externalLinkAriaLabel})`}\n </span>\n )}\n </>\n );\n\n if (isAnchor) {\n const {\n href,\n renderLink,\n target: targetProp,\n rel,\n disabled: _disabled,\n ...safeAnchorProps\n } = props as unknown as ComponentPropsWithRef<'a'> & {\n href: string;\n renderLink?: (props: ButtonCardLinkProps) => ReactNode;\n disabled?: boolean;\n };\n\n // isExternal is authoritative and forces a new tab; an explicit _blank is preserved.\n const target = isExternal ? '_blank' : targetProp;\n const shouldHardenRel = target?.toLowerCase() === '_blank';\n const relTokens = new Set(\n (rel ?? '')\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => token.toLowerCase()),\n );\n\n if (shouldHardenRel) {\n relTokens.add('noopener');\n relTokens.add('noreferrer');\n }\n\n const hardenedRel = relTokens.size > 0 ? Array.from(relTokens).join(' ') : undefined;\n\n const linkProps = {\n ...safeAnchorProps,\n ref: ref as Ref<HTMLAnchorElement>,\n href,\n target,\n rel: hardenedRel,\n className: classes,\n children: content,\n };\n\n if (renderLink) {\n return <>{renderLink(linkProps)}</>;\n }\n\n return <a {...linkProps} />;\n }\n\n const {\n type = 'button',\n href: _href,\n target: _target,\n rel: _rel,\n renderLink: _renderLink,\n ...buttonProps\n } = props as unknown as ComponentPropsWithRef<'button'> & {\n href?: string;\n target?: string;\n rel?: string;\n renderLink?: unknown;\n };\n\n return (\n <button\n ref={ref as Ref<HTMLButtonElement>}\n type={type}\n className={classes}\n {...buttonProps}\n >\n {content}\n </button>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require('./ButtonCard.css');
|
|
2
|
+
"use strict";
|
|
3
|
+
const styles = {
|
|
4
|
+
"button-card": "_button-card_14hpp_1",
|
|
5
|
+
"button-card--large": "_button-card--large_14hpp_37",
|
|
6
|
+
"button-card--small": "_button-card--small_14hpp_42",
|
|
7
|
+
"button-card__media": "_button-card__media_14hpp_59",
|
|
8
|
+
"button-card__media--icon": "_button-card__media--icon_14hpp_72",
|
|
9
|
+
"button-card__media--image": "_button-card__media--image_14hpp_85",
|
|
10
|
+
"button-card__content": "_button-card__content_14hpp_100",
|
|
11
|
+
"button-card__text": "_button-card__text_14hpp_108",
|
|
12
|
+
"button-card__title": "_button-card__title_14hpp_117",
|
|
13
|
+
"button-card__subtitle": "_button-card__subtitle_14hpp_118",
|
|
14
|
+
"button-card__indicator": "_button-card__indicator_14hpp_140",
|
|
15
|
+
"button-card__sr-only": "_button-card__sr-only_14hpp_156"
|
|
16
|
+
};
|
|
17
|
+
module.exports = styles;
|
|
18
|
+
//# sourceMappingURL=ButtonCard.module.css.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ButtonCard.module.css.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import './ButtonCard.css';
|
|
2
|
+
const styles = {
|
|
3
|
+
"button-card": "_button-card_14hpp_1",
|
|
4
|
+
"button-card--large": "_button-card--large_14hpp_37",
|
|
5
|
+
"button-card--small": "_button-card--small_14hpp_42",
|
|
6
|
+
"button-card__media": "_button-card__media_14hpp_59",
|
|
7
|
+
"button-card__media--icon": "_button-card__media--icon_14hpp_72",
|
|
8
|
+
"button-card__media--image": "_button-card__media--image_14hpp_85",
|
|
9
|
+
"button-card__content": "_button-card__content_14hpp_100",
|
|
10
|
+
"button-card__text": "_button-card__text_14hpp_108",
|
|
11
|
+
"button-card__title": "_button-card__title_14hpp_117",
|
|
12
|
+
"button-card__subtitle": "_button-card__subtitle_14hpp_118",
|
|
13
|
+
"button-card__indicator": "_button-card__indicator_14hpp_140",
|
|
14
|
+
"button-card__sr-only": "_button-card__sr-only_14hpp_156"
|
|
15
|
+
};
|
|
16
|
+
export {
|
|
17
|
+
styles as default
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=ButtonCard.module.css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ButtonCard.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { ComponentPropsWithRef, ComponentType, ReactNode, SVGProps } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Size variant of the Button card.
|
|
4
|
+
*
|
|
5
|
+
* - `large` — Large text title (Heading XS).
|
|
6
|
+
* - `medium` — Default title (Label LG Bold).
|
|
7
|
+
* - `small` — Compact vertical layout (Label MD title).
|
|
8
|
+
*/
|
|
9
|
+
export type ButtonCardSize = 'large' | 'medium' | 'small';
|
|
10
|
+
/** SVG icon component, for example `ChevronRight` from `@dnanpm/icons`. */
|
|
11
|
+
export type ButtonCardIcon = ComponentType<SVGProps<SVGSVGElement>>;
|
|
12
|
+
export interface ButtonCardLinkProps extends ComponentPropsWithRef<'a'> {
|
|
13
|
+
readonly href: string;
|
|
14
|
+
readonly children: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
interface ButtonCardBaseProps {
|
|
17
|
+
/**
|
|
18
|
+
* Primary title. Keep it short; the card clamps it as a layout fallback
|
|
19
|
+
* (two lines, or one line in the small size) and is not designed for long
|
|
20
|
+
* titles.
|
|
21
|
+
*/
|
|
22
|
+
readonly title: ReactNode;
|
|
23
|
+
/**
|
|
24
|
+
* Optional subtitle. Keep it short; the card clamps it as a layout fallback
|
|
25
|
+
* (two lines, or one line in the small size) and is not designed for long
|
|
26
|
+
* subtitles.
|
|
27
|
+
*/
|
|
28
|
+
readonly subtitle?: ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* Size variant controlling layout and typography.
|
|
31
|
+
* @default 'medium'
|
|
32
|
+
*/
|
|
33
|
+
readonly size?: ButtonCardSize;
|
|
34
|
+
/**
|
|
35
|
+
* Marks the action as opening in a new tab/window: shows the external-link
|
|
36
|
+
* indicator icon and appends the hidden `externalLinkAriaLabel` hint. In link
|
|
37
|
+
* mode (`href`) it is authoritative and forces `target="_blank"` with a
|
|
38
|
+
* hardened `rel`, overriding any explicit `target`; in button mode the
|
|
39
|
+
* consumer opens the new window (for example `window.open`).
|
|
40
|
+
* @default false
|
|
41
|
+
*/
|
|
42
|
+
readonly isExternal?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Visually hidden hint appended to the accessible name when `isExternal` is
|
|
45
|
+
* true. Defaults to Finnish per the design system aria-label policy.
|
|
46
|
+
* @default 'avautuu uuteen välilehteen'
|
|
47
|
+
*/
|
|
48
|
+
readonly externalLinkAriaLabel?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Media is optional and mutually exclusive: provide either `icon` or `image`,
|
|
52
|
+
* never both. Omitting both renders the card without a media area.
|
|
53
|
+
*/
|
|
54
|
+
type ButtonCardMediaProps = {
|
|
55
|
+
/** Decorative SVG icon rendered in a neutral media box. */
|
|
56
|
+
readonly icon?: ButtonCardIcon;
|
|
57
|
+
readonly image?: never;
|
|
58
|
+
} | {
|
|
59
|
+
readonly icon?: never;
|
|
60
|
+
/**
|
|
61
|
+
* Image slot rendered inside the DS-sized, clipped media box. The
|
|
62
|
+
* client owns the rendering, so an optimized image component (for
|
|
63
|
+
* example `next/image` or an app's own `OptimizedImage`) can be dropped
|
|
64
|
+
* in. The box is `position: relative`, so `next/image` `fill` works.
|
|
65
|
+
* Mark decorative images with an empty `alt`.
|
|
66
|
+
*/
|
|
67
|
+
readonly image?: ReactNode;
|
|
68
|
+
};
|
|
69
|
+
export type ButtonCardAsButton = ButtonCardBaseProps & ButtonCardMediaProps & Omit<ComponentPropsWithRef<'button'>, keyof ButtonCardBaseProps | 'children' | 'disabled'> & {
|
|
70
|
+
/** When omitted, the card renders as a `<button>`. */
|
|
71
|
+
readonly href?: never;
|
|
72
|
+
readonly target?: never;
|
|
73
|
+
readonly rel?: never;
|
|
74
|
+
readonly renderLink?: never;
|
|
75
|
+
/** ButtonCard has no disabled state by design; render it conditionally instead. */
|
|
76
|
+
readonly disabled?: never;
|
|
77
|
+
};
|
|
78
|
+
export type ButtonCardAsAnchor = ButtonCardBaseProps & ButtonCardMediaProps & Omit<ComponentPropsWithRef<'a'>, keyof ButtonCardBaseProps | 'children'> & {
|
|
79
|
+
/** When provided, the card renders as an `<a>`. */
|
|
80
|
+
readonly href: string;
|
|
81
|
+
readonly disabled?: never;
|
|
82
|
+
readonly type?: never;
|
|
83
|
+
readonly name?: never;
|
|
84
|
+
/**
|
|
85
|
+
* Custom render function for the link element. Use this to integrate with
|
|
86
|
+
* client-side routing libraries like Next.js or React Router.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* // Next.js
|
|
90
|
+
* import Link from 'next/link';
|
|
91
|
+
* <ButtonCard href="/page" title="Open" renderLink={(props) => <Link {...props} />} />
|
|
92
|
+
*/
|
|
93
|
+
readonly renderLink?: (props: ButtonCardLinkProps) => ReactNode;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Props for the Button card component.
|
|
97
|
+
*
|
|
98
|
+
* When `href` is provided the component renders as an `<a>` element;
|
|
99
|
+
* otherwise it renders as a `<button>`.
|
|
100
|
+
*/
|
|
101
|
+
export type ButtonCardProps = ButtonCardAsButton | ButtonCardAsAnchor;
|
|
102
|
+
export {};
|
|
103
|
+
//# sourceMappingURL=ButtonCard.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ButtonCard.types.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonCard/ButtonCard.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEvF;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1D,2EAA2E;AAC3E,MAAM,MAAM,cAAc,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;AAEpE,MAAM,WAAW,mBAAoB,SAAQ,qBAAqB,CAAC,GAAG,CAAC;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAChC;AAED,UAAU,mBAAmB;IACzB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC;IAC/B;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAC3C;AAED;;;GAGG;AACH,KAAK,oBAAoB,GACnB;IACI,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CAC1B,GACD;IACI,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;CAC9B,CAAC;AAER,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,GAChD,oBAAoB,GACpB,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,MAAM,mBAAmB,GAAG,UAAU,GAAG,UAAU,CAAC,GAAG;IACzF,sDAAsD;IACtD,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC;IAC5B,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;CAC7B,CAAC;AAEN,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,GAChD,oBAAoB,GACpB,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,EAAE,MAAM,mBAAmB,GAAG,UAAU,CAAC,GAAG;IACvE,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IACtB;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,SAAS,CAAC;CACnE,CAAC;AAEN;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,kBAAkB,GAAG,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonCard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EACR,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,cAAc,GACjB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const react = require("react");
|
|
5
|
+
const elevation_module = require("../../styles/utils/elevation.module.css.cjs");
|
|
6
|
+
const ContentCard_module = require("./ContentCard.module.css.cjs");
|
|
7
|
+
const cn = require("../../utils/cn/cn.cjs");
|
|
8
|
+
const logoBackgroundToken = {
|
|
9
|
+
white: "var(--color-semantic-surface-base)",
|
|
10
|
+
"sand-soft": "var(--color-semantic-surface-neutral-soft)",
|
|
11
|
+
"sand-mid": "var(--color-semantic-surface-neutral-mid)",
|
|
12
|
+
"sand-strong": "var(--color-semantic-surface-neutral-strong)",
|
|
13
|
+
"pink-soft": "var(--color-semantic-surface-primary-soft)",
|
|
14
|
+
"pink-mid": "var(--color-semantic-surface-primary-mid)",
|
|
15
|
+
"pink-strong": "var(--color-semantic-surface-primary-strong)",
|
|
16
|
+
"plum-soft": "var(--color-semantic-surface-secondary-soft)",
|
|
17
|
+
"plum-mid": "var(--color-semantic-surface-secondary-mid)",
|
|
18
|
+
"plum-strong": "var(--color-semantic-surface-secondary-strong)"
|
|
19
|
+
};
|
|
20
|
+
const isRenderable = (node) => node != null && typeof node !== "boolean";
|
|
21
|
+
const ContentCard = ({
|
|
22
|
+
media,
|
|
23
|
+
mediaKind = "image",
|
|
24
|
+
mediaBackground,
|
|
25
|
+
mediaWidth = "1/3",
|
|
26
|
+
mediaPosition = "start",
|
|
27
|
+
titlePrefix,
|
|
28
|
+
title,
|
|
29
|
+
headingLevel = "h3",
|
|
30
|
+
body,
|
|
31
|
+
actions,
|
|
32
|
+
appearance = "plain",
|
|
33
|
+
as = "article",
|
|
34
|
+
className,
|
|
35
|
+
ref,
|
|
36
|
+
...props
|
|
37
|
+
}) => {
|
|
38
|
+
const titleId = react.useId();
|
|
39
|
+
const HeadingLevel = headingLevel;
|
|
40
|
+
const Root = as;
|
|
41
|
+
const hasMedia = isRenderable(media);
|
|
42
|
+
const ariaLabel = props["aria-label"];
|
|
43
|
+
const ariaLabelledBy = props["aria-labelledby"] ?? (ariaLabel || as === "div" ? void 0 : titleId);
|
|
44
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
45
|
+
Root,
|
|
46
|
+
{
|
|
47
|
+
ref,
|
|
48
|
+
...props,
|
|
49
|
+
className: cn.cn(
|
|
50
|
+
ContentCard_module["content-card"],
|
|
51
|
+
hasMedia && mediaWidth === "1/2" && ContentCard_module["content-card--media-half"],
|
|
52
|
+
hasMedia && mediaPosition === "end" && ContentCard_module["content-card--media-end"],
|
|
53
|
+
appearance === "border" && ContentCard_module["content-card--border"],
|
|
54
|
+
appearance === "elevated" && ContentCard_module["content-card--elevated"],
|
|
55
|
+
appearance === "elevated" && elevation_module.default.elevationLow,
|
|
56
|
+
className
|
|
57
|
+
),
|
|
58
|
+
"aria-label": ariaLabel,
|
|
59
|
+
"aria-labelledby": ariaLabelledBy,
|
|
60
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ContentCard_module["content-card__layout"], children: [
|
|
61
|
+
hasMedia && /* @__PURE__ */ jsxRuntime.jsx(
|
|
62
|
+
"div",
|
|
63
|
+
{
|
|
64
|
+
className: cn.cn(
|
|
65
|
+
ContentCard_module["content-card__media"],
|
|
66
|
+
mediaKind === "logo" ? ContentCard_module["content-card__media--logo"] : ContentCard_module["content-card__media--image"]
|
|
67
|
+
),
|
|
68
|
+
style: mediaKind === "logo" && mediaBackground != null ? {
|
|
69
|
+
"--_cc-logo-bg": logoBackgroundToken[mediaBackground]
|
|
70
|
+
} : void 0,
|
|
71
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: ContentCard_module["content-card__media-inner"], children: media })
|
|
72
|
+
}
|
|
73
|
+
),
|
|
74
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ContentCard_module["content-card__content"], children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ContentCard_module["content-card__content-inner"], children: [
|
|
75
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ContentCard_module["content-card__body-region"], children: [
|
|
76
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ContentCard_module["content-card__header"], children: [
|
|
77
|
+
isRenderable(titlePrefix) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: ContentCard_module["content-card__prefix"], children: titlePrefix }),
|
|
78
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
79
|
+
HeadingLevel,
|
|
80
|
+
{
|
|
81
|
+
id: titleId,
|
|
82
|
+
className: ContentCard_module["content-card__title"],
|
|
83
|
+
children: title
|
|
84
|
+
}
|
|
85
|
+
)
|
|
86
|
+
] }),
|
|
87
|
+
isRenderable(body) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn.cn(ContentCard_module["content-card__body"], "dds-prose"), children: body })
|
|
88
|
+
] }),
|
|
89
|
+
isRenderable(actions) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: ContentCard_module["content-card__actions"], children: actions })
|
|
90
|
+
] }) })
|
|
91
|
+
] })
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
};
|
|
95
|
+
exports.ContentCard = ContentCard;
|
|
96
|
+
//# sourceMappingURL=ContentCard.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContentCard.cjs","sources":["../../../src/components/ContentCard/ContentCard.tsx"],"sourcesContent":["import { useId } from 'react';\nimport type { CSSProperties, ElementType, ReactNode } from 'react';\nimport { cn } from '../../utils/cn';\nimport elevationStyles from '../../styles/utils/elevation.module.css';\nimport styles from './ContentCard.module.css';\nimport type { ContentCardLogoBackground, ContentCardProps } from './ContentCard.types';\n\nconst logoBackgroundToken: Record<ContentCardLogoBackground, string> = {\n white: 'var(--color-semantic-surface-base)',\n 'sand-soft': 'var(--color-semantic-surface-neutral-soft)',\n 'sand-mid': 'var(--color-semantic-surface-neutral-mid)',\n 'sand-strong': 'var(--color-semantic-surface-neutral-strong)',\n 'pink-soft': 'var(--color-semantic-surface-primary-soft)',\n 'pink-mid': 'var(--color-semantic-surface-primary-mid)',\n 'pink-strong': 'var(--color-semantic-surface-primary-strong)',\n 'plum-soft': 'var(--color-semantic-surface-secondary-soft)',\n 'plum-mid': 'var(--color-semantic-surface-secondary-mid)',\n 'plum-strong': 'var(--color-semantic-surface-secondary-strong)',\n};\n\n// A boolean ReactNode (e.g. from `condition && <X />`) renders nothing, so treat it as absent.\nconst isRenderable = (node: ReactNode): boolean => node != null && typeof node !== 'boolean';\n\nexport const ContentCard = ({\n media,\n mediaKind = 'image',\n mediaBackground,\n mediaWidth = '1/3',\n mediaPosition = 'start',\n titlePrefix,\n title,\n headingLevel = 'h3',\n body,\n actions,\n appearance = 'plain',\n as = 'article',\n className,\n ref,\n ...props\n}: ContentCardProps) => {\n const titleId = useId();\n const HeadingLevel = headingLevel;\n // Cast to ElementType so the constrained union of tags renders without ref/props conflicts.\n const Root = as as ElementType;\n const hasMedia = isRenderable(media);\n const ariaLabel = props['aria-label'];\n // Keep an explicit aria-labelledby; only the generated title fallback is suppressed for a\n // bare div or when an aria-label is provided.\n const ariaLabelledBy =\n props['aria-labelledby'] ?? (ariaLabel || as === 'div' ? undefined : titleId);\n\n return (\n <Root\n ref={ref}\n {...props}\n className={cn(\n styles['content-card'],\n hasMedia && mediaWidth === '1/2' && styles['content-card--media-half'],\n hasMedia && mediaPosition === 'end' && styles['content-card--media-end'],\n appearance === 'border' && styles['content-card--border'],\n appearance === 'elevated' && styles['content-card--elevated'],\n appearance === 'elevated' && elevationStyles.elevationLow,\n className,\n )}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n <div className={styles['content-card__layout']}>\n {hasMedia && (\n <div\n className={cn(\n styles['content-card__media'],\n mediaKind === 'logo'\n ? styles['content-card__media--logo']\n : styles['content-card__media--image'],\n )}\n style={\n mediaKind === 'logo' && mediaBackground != null\n ? ({\n '--_cc-logo-bg': logoBackgroundToken[mediaBackground],\n } as CSSProperties)\n : undefined\n }\n >\n <div className={styles['content-card__media-inner']}>{media}</div>\n </div>\n )}\n\n <div className={styles['content-card__content']}>\n <div className={styles['content-card__content-inner']}>\n <div className={styles['content-card__body-region']}>\n <div className={styles['content-card__header']}>\n {isRenderable(titlePrefix) && (\n <div className={styles['content-card__prefix']}>\n {titlePrefix}\n </div>\n )}\n <HeadingLevel\n id={titleId}\n className={styles['content-card__title']}\n >\n {title}\n </HeadingLevel>\n </div>\n {isRenderable(body) && (\n <div className={cn(styles['content-card__body'], 'dds-prose')}>\n {body}\n </div>\n )}\n </div>\n {isRenderable(actions) && (\n <div className={styles['content-card__actions']}>{actions}</div>\n )}\n </div>\n </div>\n </div>\n </Root>\n );\n};\n"],"names":["useId","jsx","cn","styles","elevationStyles","jsxs"],"mappings":"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"}
|