@redocly/theme 0.41.0 → 0.42.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.
Files changed (39) hide show
  1. package/lib/components/Dropdown/DropdownMenuItem.js +3 -3
  2. package/lib/core/styles/dark.js +2 -1
  3. package/lib/core/styles/global.js +2 -0
  4. package/lib/markdoc/components/Cards/Card.d.ts +15 -0
  5. package/lib/markdoc/components/Cards/Card.js +166 -0
  6. package/lib/markdoc/components/Cards/CardIcon.d.ts +7 -0
  7. package/lib/markdoc/components/Cards/CardIcon.js +46 -0
  8. package/lib/markdoc/components/Cards/CardImage.d.ts +7 -0
  9. package/lib/markdoc/components/Cards/CardImage.js +21 -0
  10. package/lib/markdoc/components/Cards/Cards.d.ts +8 -0
  11. package/lib/markdoc/components/Cards/Cards.js +44 -0
  12. package/lib/markdoc/components/Cards/variables.d.ts +1 -0
  13. package/lib/markdoc/components/Cards/variables.dark.d.ts +1 -0
  14. package/lib/markdoc/components/Cards/variables.dark.js +27 -0
  15. package/lib/markdoc/components/Cards/variables.js +71 -0
  16. package/lib/markdoc/components/default.d.ts +4 -0
  17. package/lib/markdoc/components/default.js +4 -0
  18. package/lib/markdoc/default.d.ts +5 -1
  19. package/lib/markdoc/default.js +4 -0
  20. package/lib/markdoc/tags/card.d.ts +2 -0
  21. package/lib/markdoc/tags/card.js +56 -0
  22. package/lib/markdoc/tags/cards.d.ts +2 -0
  23. package/lib/markdoc/tags/cards.js +20 -0
  24. package/lib/markdoc/tags/types.d.ts +6 -2
  25. package/package.json +1 -1
  26. package/src/components/Dropdown/DropdownMenuItem.tsx +5 -5
  27. package/src/core/styles/dark.ts +2 -1
  28. package/src/core/styles/global.ts +2 -1
  29. package/src/markdoc/components/Cards/Card.tsx +232 -0
  30. package/src/markdoc/components/Cards/CardIcon.tsx +55 -0
  31. package/src/markdoc/components/Cards/CardImage.tsx +21 -0
  32. package/src/markdoc/components/Cards/Cards.tsx +35 -0
  33. package/src/markdoc/components/Cards/variables.dark.ts +24 -0
  34. package/src/markdoc/components/Cards/variables.ts +68 -0
  35. package/src/markdoc/components/default.ts +4 -0
  36. package/src/markdoc/default.ts +4 -0
  37. package/src/markdoc/tags/card.ts +55 -0
  38. package/src/markdoc/tags/cards.ts +18 -0
  39. package/src/markdoc/tags/types.ts +4 -2
@@ -53,12 +53,12 @@ function DropdownMenuItem(_a) {
53
53
  };
54
54
  className = className || '' + (active ? ' active' : '');
55
55
  if (to) {
56
- return (react_1.default.createElement(DropdownMenuItemWrapper, Object.assign({ as: Link_1.Link, "data-component-name": "Dropdown/DropdownMenuItem", className: className, separatorLine: separatorLine, to: to, style: style, role: role }, dataAttributes, otherProps),
56
+ return (react_1.default.createElement(DropdownMenuItemWrapper, Object.assign({ as: Link_1.Link, "data-component-name": "Dropdown/DropdownMenuItem", className: className, "$separatorLine": separatorLine, to: to, style: style, role: role }, dataAttributes, otherProps),
57
57
  prefix,
58
58
  children,
59
59
  suffix));
60
60
  }
61
- return (react_1.default.createElement(DropdownMenuItemWrapper, Object.assign({ "data-component-name": "Dropdown/DropdownMenuItem", className: className, role: role, style: style }, dataAttributes, { onClick: handleClick, onKeyDown: handleKeyDown, tabIndex: onAction ? 0 : -1, active: active, disabled: disabled, separator: separator, dangerous: dangerous, separatorLine: separatorLine }),
61
+ return (react_1.default.createElement(DropdownMenuItemWrapper, Object.assign({ "data-component-name": "Dropdown/DropdownMenuItem", className: className, role: role, style: style }, dataAttributes, { onClick: handleClick, onKeyDown: handleKeyDown, tabIndex: onAction ? 0 : -1, active: active, disabled: disabled, separator: separator, dangerous: dangerous, "$separatorLine": separatorLine }),
62
62
  prefix,
63
63
  children || content,
64
64
  suffix));
@@ -130,7 +130,7 @@ const DropdownMenuItemWrapper = styled_components_1.default.li `
130
130
  }
131
131
  `}
132
132
 
133
- ${({ separatorLine }) => separatorLine &&
133
+ ${({ $separatorLine }) => $separatorLine &&
134
134
  (0, styled_components_1.css) `
135
135
  border-bottom: 1px solid var(--dropdown-menu-item-separator-border-color);
136
136
  border-bottom-left-radius: 0;
@@ -11,6 +11,7 @@ const variables_dark_6 = require("../../icons/CheckboxIcon/variables.dark");
11
11
  const variables_dark_7 = require("../../components/Tag/variables.dark");
12
12
  const variables_dark_8 = require("../../components/StatusCode/variables.dark");
13
13
  const variables_dark_9 = require("../../components/Switch/variables.dark");
14
+ const variables_dark_10 = require("../../markdoc/components/Cards/variables.dark");
14
15
  const replayDarkMode = (0, styled_components_1.css) `
15
16
  /**
16
17
  * @tokens Replay Colors
@@ -301,7 +302,7 @@ exports.darkMode = (0, styled_components_1.css) `
301
302
  ${variables_dark_1.scorecardDarkMode}
302
303
  ${replayDarkMode}
303
304
  ${variables_dark_9.switcherDarkMode}
304
-
305
+ ${variables_dark_10.cardsDarkMode}
305
306
 
306
307
  /**
307
308
  * @tokens Dark Theme Scrollbar Config
@@ -37,6 +37,7 @@ const variables_31 = require("../../components/Tags/variables");
37
37
  const variables_32 = require("../../components/VersionPicker/variables");
38
38
  const variables_33 = require("../../components/DatePicker/variables");
39
39
  const variables_34 = require("../../components/Switch/variables");
40
+ const variables_35 = require("../../markdoc/components/Cards/variables");
40
41
  const themeColors = (0, styled_components_1.css) `
41
42
  /* === Palette === */
42
43
  /**
@@ -1135,6 +1136,7 @@ exports.styles = (0, styled_components_1.css) `
1135
1136
  ${borders}
1136
1137
  ${variables_5.breadcrumbs}
1137
1138
  ${variables_17.button}
1139
+ ${variables_35.cards}
1138
1140
  ${variables_8.catalog}
1139
1141
  ${variables_21.code}
1140
1142
  ${docsDropdown}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ export type CardProps = React.PropsWithChildren<{
3
+ title: string;
4
+ image?: string;
5
+ icon?: string;
6
+ iconRawContent?: string;
7
+ imagePosition?: 'start' | 'end';
8
+ lineClamp?: number;
9
+ layout?: 'horizontal' | 'vertical' | 'combined';
10
+ variant?: 'filled' | 'outlined' | 'elevated' | 'ghost';
11
+ iconVariant?: 'filled' | 'ghost';
12
+ align: 'start' | 'center' | 'end';
13
+ to?: string;
14
+ }>;
15
+ export declare function Card({ title, image, icon, iconRawContent, imagePosition, layout, variant, lineClamp, iconVariant, align, to, children, }: CardProps): React.JSX.Element;
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Card = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const ChevronRightIcon_1 = require("../../../icons/ChevronRightIcon/ChevronRightIcon");
10
+ const CardImage_1 = require("../../../markdoc/components/Cards/CardImage");
11
+ const CardIcon_1 = require("../../../markdoc/components/Cards/CardIcon");
12
+ function Card({ title, image, icon, iconRawContent, imagePosition = 'start', layout = 'vertical', variant = 'filled', lineClamp, iconVariant, align = 'start', to, children, }) {
13
+ const titleNoSpaces = title.replace(/\s+/g, '-').toLowerCase();
14
+ const cardTitleId = `card-title-${titleNoSpaces}`;
15
+ // Get align values
16
+ const justifyContent = align === 'center' ? 'center' : align === 'end' ? 'flex-end' : 'flex-start';
17
+ const alignItems = align === 'center' ? 'center' : align === 'end' ? 'flex-end' : 'flex-start';
18
+ const textAlign = align === 'center' ? 'center' : align === 'end' ? 'right' : 'left';
19
+ iconVariant = (iconVariant !== null && iconVariant !== void 0 ? iconVariant : variant === 'ghost') ? 'filled' : 'ghost';
20
+ return (react_1.default.createElement(CardWrapper, { as: to ? 'a' : 'div', href: to, "aria-labelledby": cardTitleId, variant: variant, layout: layout, isCardLink: !!to },
21
+ react_1.default.createElement(react_1.default.Fragment, null,
22
+ image ? react_1.default.createElement(CardImage_1.CardImage, { src: image, alt: title, position: imagePosition }) : null,
23
+ react_1.default.createElement(CardContentWrapper, { layout: layout, alignItems: alignItems, textAlign: textAlign, hasImage: image !== undefined },
24
+ icon && react_1.default.createElement(CardIcon_1.CardIcon, { variant: iconVariant, src: icon, rawContent: iconRawContent }),
25
+ react_1.default.createElement(ContentWrapper, null,
26
+ react_1.default.createElement(Title, { id: cardTitleId, isCardLink: !!to, justifyContent: justifyContent },
27
+ title,
28
+ !!to && react_1.default.createElement(CardLinkIcon, null)),
29
+ react_1.default.createElement(Body, { lineClamp: lineClamp }, children))))));
30
+ }
31
+ exports.Card = Card;
32
+ const CardContentWrapper = styled_components_1.default.div `
33
+ display: flex;
34
+ flex-direction: ${({ layout }) => (layout === 'horizontal' ? 'row' : 'column')};
35
+ gap: var(--card-icon-gap);
36
+ align-items: ${({ alignItems }) => alignItems};
37
+ text-align: ${({ textAlign }) => textAlign};
38
+ flex-grow: 1;
39
+ padding: var(--card-padding);
40
+ height: ${({ hasImage }) => (hasImage ? 'auto' : '100%')};
41
+ `;
42
+ const ContentWrapper = styled_components_1.default.div `
43
+ display: flex;
44
+ flex-direction: column;
45
+ flex-shrink: 1;
46
+ gap: var(--card-content-gap);
47
+ `;
48
+ const Title = styled_components_1.default.h3 `
49
+ margin: var(--card-title-margin);
50
+ font-weight: var(--card-title-font-weight);
51
+ color: var(--card-title-text-color);
52
+ display: flex;
53
+ align-items: center;
54
+ justify-content: ${({ justifyContent }) => justifyContent};
55
+ width: 100%;
56
+ `;
57
+ const CardLinkIcon = (0, styled_components_1.default)(ChevronRightIcon_1.ChevronRightIcon) `
58
+ width: var(--card-link-icon-width);
59
+ height: var(--card-link-icon-height);
60
+ margin-left: var(--spacing-xxs);
61
+ opacity: 0;
62
+ transition: opacity 0.3s, transform 0.3s;
63
+ `;
64
+ const Body = styled_components_1.default.div `
65
+ color: var(--card-text-color);
66
+ font-size: var(--card-body-font-size);
67
+ line-height: var(--card-body-line-height);
68
+
69
+ ${({ lineClamp }) => lineClamp &&
70
+ `
71
+ display: -webkit-box;
72
+ -webkit-line-clamp: ${lineClamp};
73
+ -webkit-box-orient: vertical;
74
+ overflow: hidden;
75
+ text-overflow: ellipsis;`}
76
+
77
+ > *:first-child {
78
+ margin-top: 0;
79
+ }
80
+
81
+ > *:last-child {
82
+ margin-bottom: 0;
83
+ }
84
+
85
+ /* Icon link styles */
86
+ & a {
87
+ display: inline-flex;
88
+ align-items: center;
89
+ line-height: 1;
90
+
91
+ & svg {
92
+ width: 1.2em;
93
+ height: 1.2em;
94
+ margin-right: 0.25em;
95
+ vertical-align: middle;
96
+
97
+ & g {
98
+ fill: var(--link-color-primary);
99
+ }
100
+ }
101
+ }
102
+
103
+ & a:visited > span > svg > g {
104
+ fill: var(--link-color-visited);
105
+ }
106
+ `;
107
+ const CardWrapper = styled_components_1.default.div.attrs(({ isCardLink, variant }) => ({
108
+ className: getCardWrapperClass(isCardLink, variant),
109
+ })) `
110
+ display: flex;
111
+ flex-direction: ${({ layout }) => (layout === 'horizontal' ? 'row' : 'column')};
112
+ width: 100%;
113
+ height: 100%;
114
+ border-radius: var(--card-border-radius);
115
+ overflow: hidden;
116
+ transition: box-shadow 0.3s ease;
117
+ position: relative;
118
+ --md-paragraph-margin: 0;
119
+ --link-decoration-hover: none;
120
+
121
+ background-color: var(--card-bg-color);
122
+ border-width: var(--card-border-width);
123
+ border-style: var(--card-border-style);
124
+ border-color: var(--card-border-color);
125
+ box-shadow: var(--card-box-shadow);
126
+
127
+ && > img {
128
+ ${({ layout }) => layout === 'horizontal' &&
129
+ `
130
+ max-width: 33%;
131
+ width: auto;
132
+ height: 100%;
133
+ object-fit: cover;
134
+ `}
135
+ }
136
+
137
+ &.card-link {
138
+ cursor: var(--card-link-cursor);
139
+
140
+ &:hover,
141
+ &:focus-within {
142
+ background-color: var(--card-bg-color-hover);
143
+ border-color: var(--card-border-color-hover);
144
+ box-shadow: var(--card-box-shadow-hover);
145
+
146
+ svg {
147
+ opacity: 1;
148
+ }
149
+ }
150
+ }
151
+
152
+ && ul {
153
+ list-style: none;
154
+ padding-left: 0;
155
+ margin: var(--spacing-xs) 0;
156
+ }
157
+ `;
158
+ const getCardWrapperClass = (isCardLink, variant) => {
159
+ let classes = [];
160
+ classes.push(`card-variant-${variant}`);
161
+ if (isCardLink) {
162
+ classes.push('card-link');
163
+ }
164
+ return classes.join(' ');
165
+ };
166
+ //# sourceMappingURL=Card.js.map
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export type CardIconProps = {
3
+ variant?: string;
4
+ src: string;
5
+ rawContent?: string;
6
+ };
7
+ export declare function CardIcon({ variant, src, rawContent }: CardIconProps): React.JSX.Element;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CardIcon = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const InlineSvg_1 = require("../../../markdoc/components/InlineSvg/InlineSvg");
10
+ function CardIcon({ variant, src, rawContent }) {
11
+ return (react_1.default.createElement(CardIconWrapper, { variant: variant }, rawContent ? react_1.default.createElement(CardSvg, { fileRawContent: rawContent }) : react_1.default.createElement(CardImg, { src: src })));
12
+ }
13
+ exports.CardIcon = CardIcon;
14
+ const CardImg = styled_components_1.default.img `
15
+ width: var(--card-icon-width);
16
+ height: var(--card-icon-height);
17
+ display: inline-block;
18
+ object-fit: cover;
19
+ `;
20
+ const CardSvg = (0, styled_components_1.default)(InlineSvg_1.InlineSvg) `
21
+ width: var(--card-icon-width);
22
+ height: var(--card-icon-height);
23
+ display: inline-block;
24
+
25
+ svg {
26
+ width: 100%;
27
+ height: 100%;
28
+ fill: var(--card-icon-color);
29
+ }
30
+ `;
31
+ const CardIconWrapper = styled_components_1.default.div `
32
+ display: flex;
33
+ align-items: center;
34
+ justify-content: center;
35
+ min-width: var(--card-icon-width);
36
+ min-height: var(--card-icon-height);
37
+ flex-shrink: 0;
38
+
39
+ padding: ${({ variant }) => (variant === 'ghost' ? '0' : `var(--card-icon-padding);`)};
40
+ border-radius: var(--card-icon-border-radius);
41
+ overflow: hidden;
42
+
43
+ background-color: ${({ variant }) => variant === 'ghost' ? 'transparent' : 'var(--card-icon-bg-color)'};
44
+ border: ${({ variant }) => variant === 'ghost' ? 'none' : `1px solid var(--card-icon-border-color)`};
45
+ `;
46
+ //# sourceMappingURL=CardIcon.js.map
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export type CardImageProps = {
3
+ src: string;
4
+ alt: string;
5
+ position?: 'start' | 'end';
6
+ };
7
+ export declare function CardImage({ src, alt, position }: CardImageProps): React.JSX.Element;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CardImage = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ function CardImage({ src, alt, position }) {
10
+ return react_1.default.createElement(Image, { src: src, alt: alt, position: position });
11
+ }
12
+ exports.CardImage = CardImage;
13
+ const Image = styled_components_1.default.img `
14
+ width: 100%;
15
+ height: 100px;
16
+ flex-shrink: 0;
17
+ object-fit: cover;
18
+
19
+ order: ${({ position }) => (position === 'end' ? 1 : 0)};
20
+ `;
21
+ //# sourceMappingURL=CardImage.js.map
@@ -0,0 +1,8 @@
1
+ import * as React from 'react';
2
+ export type CardsProps = React.PropsWithChildren<{
3
+ columns?: number;
4
+ cardMinWidth?: number;
5
+ className?: string;
6
+ ariaLabel?: string;
7
+ }>;
8
+ export declare function Cards({ cardMinWidth, columns, className, children, ariaLabel }: CardsProps): React.JSX.Element;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.Cards = void 0;
30
+ const React = __importStar(require("react"));
31
+ const styled_components_1 = __importDefault(require("styled-components"));
32
+ function Cards({ cardMinWidth = 240, columns, className, children, ariaLabel }) {
33
+ return (React.createElement(GridLayout, { cardMinWidth: cardMinWidth, columns: columns, className: className, "aria-label": ariaLabel }, children));
34
+ }
35
+ exports.Cards = Cards;
36
+ const GridLayout = styled_components_1.default.div `
37
+ display: grid;
38
+ grid-template-columns: ${({ cardMinWidth, columns }) => `repeat(${columns || 'auto-fit'}, minmax(${cardMinWidth}px, 1fr))`};
39
+ gap: var(--cards-gap);
40
+ width: 100%;
41
+ margin-top: var(--spacing-base);
42
+ margin-bottom: var(--spacing-base);
43
+ `;
44
+ //# sourceMappingURL=Cards.js.map
@@ -0,0 +1 @@
1
+ export declare const cards: import("styled-components").FlattenSimpleInterpolation;
@@ -0,0 +1 @@
1
+ export declare const cardsDarkMode: import("styled-components").FlattenSimpleInterpolation;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cardsDarkMode = void 0;
4
+ const styled_components_1 = require("styled-components");
5
+ exports.cardsDarkMode = (0, styled_components_1.css) `
6
+ --card-icon-border-color: var(--color-warm-grey-4);
7
+ --card-icon-bg-color: var(--color-warm-grey-3);
8
+
9
+ .card-variant-filled {
10
+ --card-bg-color: var(--color-warm-grey-3);
11
+ --card-bg-color-hover: var(--color-warm-grey-4);
12
+ --card-border-color: var(--color-warm-grey-4);
13
+ --card-border-color-hover: var(--color-warm-grey-3);
14
+ --card-icon-bg-color: var(--card-bg-color);
15
+ }
16
+
17
+ .card-variant-outlined {
18
+ --card-border-color: var(--color-warm-grey-4);
19
+ --card-border-color-hover: var(--color-warm-grey-5);
20
+ }
21
+
22
+ .card-variant-elevated {
23
+ --card-box-shadow: 0px 8px 24px -4px #00000014, 0px 6px 12px -6px #0000001F;
24
+ --card-box-shadow-hover: 0px 14px 64px -4px #0000001F, 0px 8px 22px -6px #0000001F;
25
+ }
26
+ `;
27
+ //# sourceMappingURL=variables.dark.js.map
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cards = void 0;
4
+ const styled_components_1 = require("styled-components");
5
+ exports.cards = (0, styled_components_1.css) `
6
+ --cards-gap: var(--spacing-sm);
7
+
8
+ /**
9
+ * @tokens Card default colors
10
+ */
11
+ --card-icon-bg-color: var(--color-warm-grey-1);
12
+ --card-icon-border-color: var(--border-color-secondary);
13
+ --card-text-color: var(--text-color-secondary);
14
+ --card-title-text-color: var(--h2-text-color);
15
+ --card-icon-color: var(--card-title-text-color);
16
+
17
+ /**
18
+ * @tokens Card default values
19
+ */
20
+ --card-border-radius: var(--border-radius-md);
21
+ --card-border-style: solid;
22
+ --card-link-cursor: pointer;
23
+ --card-link-icon-width: var(--h3-font-size);
24
+ --card-link-icon-height: var(--h3-font-size);
25
+ --card-border-width: 1px;
26
+ --card-icon-border-radius: var(--border-radius-md);
27
+ --card-icon-padding: var(--spacing-xs);
28
+ --card-icon-size: 24px;
29
+ --card-icon-height: var(--card-icon-size);
30
+ --card-icon-width: var(--card-icon-size);
31
+ --card-icon-gap: var(--spacing-base);
32
+ --card-title-margin: 0;
33
+ --card-title-font-weight: var(--font-weight-semibold);
34
+ --card-content-gap: 4px;
35
+ --card-padding: 16px 20px;
36
+ --card-body-font-size: var(--font-size-base);
37
+ --card-body-line-height: var(--line-height-base);
38
+
39
+ /**
40
+ * @tokens Card variants
41
+ */
42
+ .card-variant-filled {
43
+ --card-bg-color: var(--color-warm-grey-1);
44
+ --card-bg-color-hover: var(--color-warm-grey-2);
45
+ --card-border-color: var(--color-warm-grey-2);
46
+ --card-border-color-hover: var(--color-warm-grey-1);
47
+ --card-icon-bg-color: var(--color-white);
48
+ --card-icon-border-color: var(--card-border-color);
49
+ }
50
+
51
+ .card-variant-outlined {
52
+ --card-bg-color: transparent;
53
+ --card-border-color: var(--color-warm-grey-2);
54
+ --card-border-color-hover: var(--color-warm-grey-3);
55
+ }
56
+
57
+ .card-variant-elevated {
58
+ --card-bg-color: transparent;
59
+ --card-border-color: transparent;
60
+ --card-border-color-hover: transparent;
61
+ --card-box-shadow: 0px 8px 24px -4px #232A6114, 0px 6px 12px -6px #232A611F;
62
+ --card-box-shadow-hover: 0px 14px 64px -4px #232A611F, 0px 8px 22px -6px #232A611F;
63
+ }
64
+
65
+ .card-variant-ghost {
66
+ --card-bg-color: transparent;
67
+ --card-border-width: 0;
68
+ }
69
+
70
+ `;
71
+ //# sourceMappingURL=variables.js.map
@@ -7,3 +7,7 @@ export * from '../../markdoc/components/HtmlBlock/HtmlBlock';
7
7
  export * from '../../markdoc/components/Tabs/Tab';
8
8
  export * from '../../markdoc/components/Tabs/Tabs';
9
9
  export * from '../../markdoc/components/CodeBlock/CodeBlock';
10
+ export * from '../../markdoc/components/Cards/Cards';
11
+ export * from '../../markdoc/components/Cards/Card';
12
+ export * from '../../markdoc/components/Cards/CardIcon';
13
+ export * from '../../markdoc/components/Cards/CardImage';
@@ -23,4 +23,8 @@ __exportStar(require("../../markdoc/components/HtmlBlock/HtmlBlock"), exports);
23
23
  __exportStar(require("../../markdoc/components/Tabs/Tab"), exports);
24
24
  __exportStar(require("../../markdoc/components/Tabs/Tabs"), exports);
25
25
  __exportStar(require("../../markdoc/components/CodeBlock/CodeBlock"), exports);
26
+ __exportStar(require("../../markdoc/components/Cards/Cards"), exports);
27
+ __exportStar(require("../../markdoc/components/Cards/Card"), exports);
28
+ __exportStar(require("../../markdoc/components/Cards/CardIcon"), exports);
29
+ __exportStar(require("../../markdoc/components/Cards/CardImage"), exports);
26
30
  //# sourceMappingURL=default.js.map
@@ -5,5 +5,9 @@ export * from '../markdoc/attributes/relative-path';
5
5
  export * from '../markdoc/attributes/svg-content';
6
6
  export * as components from '../markdoc/components/default';
7
7
  export declare const tags: {
8
- [x: string]: import("@markdoc/markdoc").Schema;
8
+ [x: string]: import("@markdoc/markdoc").Schema & {
9
+ attributes?: Record<string, import("@markdoc/markdoc").SchemaAttribute & {
10
+ resolver?: string | undefined;
11
+ }> | undefined;
12
+ };
9
13
  };
@@ -45,6 +45,8 @@ const tabs_1 = require("../markdoc/tags/tabs");
45
45
  const debug_1 = require("../markdoc/tags/debug");
46
46
  const code_snippet_1 = require("../markdoc/tags/code-snippet");
47
47
  const inline_svg_1 = require("../markdoc/tags/inline-svg");
48
+ const cards_1 = require("../markdoc/tags/cards");
49
+ const card_1 = require("../markdoc/tags/card");
48
50
  exports.tags = {
49
51
  [admonition_1.admonition.tagName]: admonition_1.admonition.schema,
50
52
  [debug_1.debug.tagName]: debug_1.debug.schema,
@@ -55,5 +57,7 @@ exports.tags = {
55
57
  [tabs_1.tabs.tagName]: tabs_1.tabs.schema,
56
58
  [code_snippet_1.codeSnippet.tagName]: code_snippet_1.codeSnippet.schema,
57
59
  [inline_svg_1.inlineSvg.tagName]: inline_svg_1.inlineSvg.schema,
60
+ [cards_1.cards.tagName]: cards_1.cards.schema,
61
+ [card_1.card.tagName]: card_1.card.schema,
58
62
  };
59
63
  //# sourceMappingURL=default.js.map
@@ -0,0 +1,2 @@
1
+ import type { MarkdocSchemaWrapper } from '../../markdoc/tags/types';
2
+ export declare const card: MarkdocSchemaWrapper;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.card = void 0;
4
+ // import { SvgContent } from '../../markdoc/attributes/svg-content';
5
+ exports.card = {
6
+ schema: {
7
+ render: 'Card',
8
+ attributes: {
9
+ title: {
10
+ type: String,
11
+ required: true,
12
+ },
13
+ image: {
14
+ type: String,
15
+ resolver: 'link',
16
+ },
17
+ icon: { type: String, resolver: 'inlineSvgOrImageLink' },
18
+ lineClamp: {
19
+ type: Number,
20
+ },
21
+ iconRawContent: {
22
+ // internal use only
23
+ type: String,
24
+ render: true,
25
+ },
26
+ imagePosition: {
27
+ type: String,
28
+ matches: ['start', 'end'],
29
+ default: 'start',
30
+ },
31
+ layout: {
32
+ type: String,
33
+ matches: ['horizontal', 'combined', 'vertical'],
34
+ default: 'vertical',
35
+ },
36
+ align: {
37
+ type: String,
38
+ matches: ['start', 'center', 'end'],
39
+ default: 'start',
40
+ },
41
+ variant: {
42
+ type: String,
43
+ matches: ['filled', 'outlined', 'elevated', 'ghost'],
44
+ default: 'filled',
45
+ },
46
+ iconVariant: {
47
+ type: String,
48
+ matches: ['filled', 'ghost'],
49
+ },
50
+ to: { type: String },
51
+ },
52
+ children: ['paragraph', 'tag', 'list'],
53
+ },
54
+ tagName: 'card',
55
+ };
56
+ //# sourceMappingURL=card.js.map
@@ -0,0 +1,2 @@
1
+ import type { MarkdocSchemaWrapper } from '../../markdoc/tags/types';
2
+ export declare const cards: MarkdocSchemaWrapper;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cards = void 0;
4
+ exports.cards = {
5
+ schema: {
6
+ render: 'Cards',
7
+ attributes: {
8
+ columns: {
9
+ type: Number,
10
+ default: 3,
11
+ },
12
+ cardMinWidth: {
13
+ type: Number,
14
+ default: 240,
15
+ },
16
+ },
17
+ },
18
+ tagName: 'cards',
19
+ };
20
+ //# sourceMappingURL=cards.js.map
@@ -1,5 +1,9 @@
1
- import type { Schema } from '@markdoc/markdoc';
1
+ import type { Schema, SchemaAttribute } from '@markdoc/markdoc';
2
2
  export type MarkdocSchemaWrapper = {
3
- schema: Schema;
3
+ schema: Schema & {
4
+ attributes?: Record<string, SchemaAttribute & {
5
+ resolver?: string;
6
+ }>;
7
+ };
4
8
  tagName: string;
5
9
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/theme",
3
- "version": "0.41.0",
3
+ "version": "0.42.0",
4
4
  "description": "Shared UI components lib",
5
5
  "keywords": [
6
6
  "theme",
@@ -61,7 +61,7 @@ export function DropdownMenuItem({
61
61
  as={Link}
62
62
  data-component-name="Dropdown/DropdownMenuItem"
63
63
  className={className}
64
- separatorLine={separatorLine}
64
+ $separatorLine={separatorLine}
65
65
  to={to}
66
66
  style={style}
67
67
  role={role}
@@ -89,7 +89,7 @@ export function DropdownMenuItem({
89
89
  disabled={disabled}
90
90
  separator={separator}
91
91
  dangerous={dangerous}
92
- separatorLine={separatorLine}
92
+ $separatorLine={separatorLine}
93
93
  >
94
94
  {prefix}
95
95
  {children || content}
@@ -99,7 +99,7 @@ export function DropdownMenuItem({
99
99
  }
100
100
 
101
101
  const DropdownMenuItemWrapper = styled.li<{
102
- separatorLine?: boolean;
102
+ $separatorLine?: boolean;
103
103
  active?: boolean;
104
104
  disabled?: boolean;
105
105
  separator?: boolean;
@@ -173,8 +173,8 @@ const DropdownMenuItemWrapper = styled.li<{
173
173
  }
174
174
  `}
175
175
 
176
- ${({ separatorLine }) =>
177
- separatorLine &&
176
+ ${({ $separatorLine }) =>
177
+ $separatorLine &&
178
178
  css`
179
179
  border-bottom: 1px solid var(--dropdown-menu-item-separator-border-color);
180
180
  border-bottom-left-radius: 0;
@@ -9,6 +9,7 @@ import { checkboxDarkMode } from '@redocly/theme/icons/CheckboxIcon/variables.da
9
9
  import { tagDarkMode } from '@redocly/theme/components/Tag/variables.dark';
10
10
  import { statusCodeDarkMode } from '@redocly/theme/components/StatusCode/variables.dark';
11
11
  import { switcherDarkMode } from '@redocly/theme/components/Switch/variables.dark';
12
+ import { cardsDarkMode } from '@redocly/theme/markdoc/components/Cards/variables.dark';
12
13
 
13
14
  const replayDarkMode = css`
14
15
  /**
@@ -301,7 +302,7 @@ export const darkMode = css`
301
302
  ${scorecardDarkMode}
302
303
  ${replayDarkMode}
303
304
  ${switcherDarkMode}
304
-
305
+ ${cardsDarkMode}
305
306
 
306
307
  /**
307
308
  * @tokens Dark Theme Scrollbar Config
@@ -35,7 +35,7 @@ import { httpTag } from '@redocly/theme/components/Tags/variables';
35
35
  import { versionPicker } from '@redocly/theme/components/VersionPicker/variables';
36
36
  import { datePicker } from '@redocly/theme/components/DatePicker/variables'
37
37
  import { switcher } from '@redocly/theme/components/Switch/variables';
38
-
38
+ import { cards } from '@redocly/theme/markdoc/components/Cards/variables';
39
39
 
40
40
  const themeColors = css`
41
41
  /* === Palette === */
@@ -1158,6 +1158,7 @@ export const styles = css`
1158
1158
  ${borders}
1159
1159
  ${breadcrumbs}
1160
1160
  ${button}
1161
+ ${cards}
1161
1162
  ${catalog}
1162
1163
  ${code}
1163
1164
  ${docsDropdown}
@@ -0,0 +1,232 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import { ChevronRightIcon } from '@redocly/theme/icons/ChevronRightIcon/ChevronRightIcon';
5
+ import { CardImage } from '@redocly/theme/markdoc/components/Cards/CardImage';
6
+ import { CardIcon } from '@redocly/theme/markdoc/components/Cards/CardIcon';
7
+
8
+ export type CardProps = React.PropsWithChildren<{
9
+ title: string;
10
+ image?: string;
11
+ icon?: string;
12
+ iconRawContent?: string;
13
+ imagePosition?: 'start' | 'end';
14
+ lineClamp?: number;
15
+ layout?: 'horizontal' | 'vertical' | 'combined';
16
+ variant?: 'filled' | 'outlined' | 'elevated' | 'ghost';
17
+ iconVariant?: 'filled' | 'ghost';
18
+ align: 'start' | 'center' | 'end';
19
+ to?: string;
20
+ }>;
21
+
22
+ export function Card({
23
+ title,
24
+ image,
25
+ icon,
26
+ iconRawContent,
27
+ imagePosition = 'start',
28
+ layout = 'vertical',
29
+ variant = 'filled',
30
+ lineClamp,
31
+ iconVariant,
32
+ align = 'start',
33
+ to,
34
+ children,
35
+ }: CardProps) {
36
+ const titleNoSpaces = title.replace(/\s+/g, '-').toLowerCase();
37
+ const cardTitleId = `card-title-${titleNoSpaces}`;
38
+ // Get align values
39
+ const justifyContent =
40
+ align === 'center' ? 'center' : align === 'end' ? 'flex-end' : 'flex-start';
41
+ const alignItems = align === 'center' ? 'center' : align === 'end' ? 'flex-end' : 'flex-start';
42
+ const textAlign = align === 'center' ? 'center' : align === 'end' ? 'right' : 'left';
43
+ iconVariant = iconVariant ?? variant === 'ghost' ? 'filled' : 'ghost';
44
+
45
+ return (
46
+ <CardWrapper
47
+ as={to ? 'a' : 'div'}
48
+ href={to}
49
+ aria-labelledby={cardTitleId}
50
+ variant={variant}
51
+ layout={layout}
52
+ isCardLink={!!to}
53
+ >
54
+ <>
55
+ {image ? <CardImage src={image} alt={title} position={imagePosition} /> : null}
56
+ <CardContentWrapper
57
+ layout={layout}
58
+ alignItems={alignItems}
59
+ textAlign={textAlign}
60
+ hasImage={image !== undefined}
61
+ >
62
+ {icon && <CardIcon variant={iconVariant} src={icon} rawContent={iconRawContent} />}
63
+ <ContentWrapper>
64
+ <Title id={cardTitleId} isCardLink={!!to} justifyContent={justifyContent}>
65
+ {title}
66
+ {!!to && <CardLinkIcon />}
67
+ </Title>
68
+ <Body lineClamp={lineClamp}>{children}</Body>
69
+ </ContentWrapper>
70
+ </CardContentWrapper>
71
+ </>
72
+ </CardWrapper>
73
+ );
74
+ }
75
+
76
+ const CardContentWrapper = styled.div<{
77
+ layout?: string;
78
+ alignItems: string;
79
+ textAlign: string;
80
+ hasImage: boolean;
81
+ }>`
82
+ display: flex;
83
+ flex-direction: ${({ layout }) => (layout === 'horizontal' ? 'row' : 'column')};
84
+ gap: var(--card-icon-gap);
85
+ align-items: ${({ alignItems }) => alignItems};
86
+ text-align: ${({ textAlign }) => textAlign};
87
+ flex-grow: 1;
88
+ padding: var(--card-padding);
89
+ height: ${({ hasImage }) => (hasImage ? 'auto' : '100%')};
90
+ `;
91
+
92
+ const ContentWrapper = styled.div`
93
+ display: flex;
94
+ flex-direction: column;
95
+ flex-shrink: 1;
96
+ gap: var(--card-content-gap);
97
+ `;
98
+
99
+ const Title = styled.h3<{ isCardLink: boolean; justifyContent: string }>`
100
+ margin: var(--card-title-margin);
101
+ font-weight: var(--card-title-font-weight);
102
+ color: var(--card-title-text-color);
103
+ display: flex;
104
+ align-items: center;
105
+ justify-content: ${({ justifyContent }) => justifyContent};
106
+ width: 100%;
107
+ `;
108
+
109
+ const CardLinkIcon = styled(ChevronRightIcon)`
110
+ width: var(--card-link-icon-width);
111
+ height: var(--card-link-icon-height);
112
+ margin-left: var(--spacing-xxs);
113
+ opacity: 0;
114
+ transition: opacity 0.3s, transform 0.3s;
115
+ `;
116
+
117
+ const Body = styled.div<{ lineClamp?: number }>`
118
+ color: var(--card-text-color);
119
+ font-size: var(--card-body-font-size);
120
+ line-height: var(--card-body-line-height);
121
+
122
+ ${({ lineClamp }) =>
123
+ lineClamp &&
124
+ `
125
+ display: -webkit-box;
126
+ -webkit-line-clamp: ${lineClamp};
127
+ -webkit-box-orient: vertical;
128
+ overflow: hidden;
129
+ text-overflow: ellipsis;`}
130
+
131
+ > *:first-child {
132
+ margin-top: 0;
133
+ }
134
+
135
+ > *:last-child {
136
+ margin-bottom: 0;
137
+ }
138
+
139
+ /* Icon link styles */
140
+ & a {
141
+ display: inline-flex;
142
+ align-items: center;
143
+ line-height: 1;
144
+
145
+ & svg {
146
+ width: 1.2em;
147
+ height: 1.2em;
148
+ margin-right: 0.25em;
149
+ vertical-align: middle;
150
+
151
+ & g {
152
+ fill: var(--link-color-primary);
153
+ }
154
+ }
155
+ }
156
+
157
+ & a:visited > span > svg > g {
158
+ fill: var(--link-color-visited);
159
+ }
160
+ `;
161
+
162
+ const CardWrapper = styled.div.attrs<{
163
+ variant: string;
164
+ isCardLink: boolean;
165
+ }>(({ isCardLink, variant }) => ({
166
+ className: getCardWrapperClass(isCardLink, variant),
167
+ }))<{
168
+ variant: string;
169
+ isCardLink: boolean;
170
+ layout: string;
171
+ }>`
172
+ display: flex;
173
+ flex-direction: ${({ layout }) => (layout === 'horizontal' ? 'row' : 'column')};
174
+ width: 100%;
175
+ height: 100%;
176
+ border-radius: var(--card-border-radius);
177
+ overflow: hidden;
178
+ transition: box-shadow 0.3s ease;
179
+ position: relative;
180
+ --md-paragraph-margin: 0;
181
+ --link-decoration-hover: none;
182
+
183
+ background-color: var(--card-bg-color);
184
+ border-width: var(--card-border-width);
185
+ border-style: var(--card-border-style);
186
+ border-color: var(--card-border-color);
187
+ box-shadow: var(--card-box-shadow);
188
+
189
+ && > img {
190
+ ${({ layout }) =>
191
+ layout === 'horizontal' &&
192
+ `
193
+ max-width: 33%;
194
+ width: auto;
195
+ height: 100%;
196
+ object-fit: cover;
197
+ `}
198
+ }
199
+
200
+ &.card-link {
201
+ cursor: var(--card-link-cursor);
202
+
203
+ &:hover,
204
+ &:focus-within {
205
+ background-color: var(--card-bg-color-hover);
206
+ border-color: var(--card-border-color-hover);
207
+ box-shadow: var(--card-box-shadow-hover);
208
+
209
+ svg {
210
+ opacity: 1;
211
+ }
212
+ }
213
+ }
214
+
215
+ && ul {
216
+ list-style: none;
217
+ padding-left: 0;
218
+ margin: var(--spacing-xs) 0;
219
+ }
220
+ `;
221
+
222
+ const getCardWrapperClass = (isCardLink: boolean, variant?: string) => {
223
+ let classes = [];
224
+
225
+ classes.push(`card-variant-${variant}`);
226
+
227
+ if (isCardLink) {
228
+ classes.push('card-link');
229
+ }
230
+
231
+ return classes.join(' ');
232
+ };
@@ -0,0 +1,55 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import { InlineSvg } from '@redocly/theme/markdoc/components/InlineSvg/InlineSvg';
5
+
6
+ export type CardIconProps = {
7
+ variant?: string;
8
+ src: string;
9
+ rawContent?: string;
10
+ };
11
+
12
+ export function CardIcon({ variant, src, rawContent }: CardIconProps) {
13
+ return (
14
+ <CardIconWrapper variant={variant}>
15
+ {rawContent ? <CardSvg fileRawContent={rawContent} /> : <CardImg src={src} />}
16
+ </CardIconWrapper>
17
+ );
18
+ }
19
+
20
+ const CardImg = styled.img`
21
+ width: var(--card-icon-width);
22
+ height: var(--card-icon-height);
23
+ display: inline-block;
24
+ object-fit: cover;
25
+ `;
26
+
27
+ const CardSvg = styled(InlineSvg)`
28
+ width: var(--card-icon-width);
29
+ height: var(--card-icon-height);
30
+ display: inline-block;
31
+
32
+ svg {
33
+ width: 100%;
34
+ height: 100%;
35
+ fill: var(--card-icon-color);
36
+ }
37
+ `;
38
+
39
+ const CardIconWrapper = styled.div<Omit<CardIconProps, 'src'>>`
40
+ display: flex;
41
+ align-items: center;
42
+ justify-content: center;
43
+ min-width: var(--card-icon-width);
44
+ min-height: var(--card-icon-height);
45
+ flex-shrink: 0;
46
+
47
+ padding: ${({ variant }) => (variant === 'ghost' ? '0' : `var(--card-icon-padding);`)};
48
+ border-radius: var(--card-icon-border-radius);
49
+ overflow: hidden;
50
+
51
+ background-color: ${({ variant }) =>
52
+ variant === 'ghost' ? 'transparent' : 'var(--card-icon-bg-color)'};
53
+ border: ${({ variant }) =>
54
+ variant === 'ghost' ? 'none' : `1px solid var(--card-icon-border-color)`};
55
+ `;
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ export type CardImageProps = {
5
+ src: string;
6
+ alt: string;
7
+ position?: 'start' | 'end';
8
+ };
9
+
10
+ export function CardImage({ src, alt, position }: CardImageProps) {
11
+ return <Image src={src} alt={alt} position={position} />;
12
+ }
13
+
14
+ const Image = styled.img<{ position?: string }>`
15
+ width: 100%;
16
+ height: 100px;
17
+ flex-shrink: 0;
18
+ object-fit: cover;
19
+
20
+ order: ${({ position }) => (position === 'end' ? 1 : 0)};
21
+ `;
@@ -0,0 +1,35 @@
1
+ import * as React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ export type CardsProps = React.PropsWithChildren<{
5
+ columns?: number;
6
+ cardMinWidth?: number;
7
+ className?: string;
8
+ ariaLabel?: string;
9
+ }>;
10
+
11
+ export function Cards({ cardMinWidth = 240, columns, className, children, ariaLabel }: CardsProps) {
12
+ return (
13
+ <GridLayout
14
+ cardMinWidth={cardMinWidth}
15
+ columns={columns}
16
+ className={className}
17
+ aria-label={ariaLabel}
18
+ >
19
+ {children}
20
+ </GridLayout>
21
+ );
22
+ }
23
+
24
+ const GridLayout = styled.div<{
25
+ cardMinWidth: number;
26
+ columns?: number;
27
+ }>`
28
+ display: grid;
29
+ grid-template-columns: ${({ cardMinWidth, columns }) =>
30
+ `repeat(${columns || 'auto-fit'}, minmax(${cardMinWidth}px, 1fr))`};
31
+ gap: var(--cards-gap);
32
+ width: 100%;
33
+ margin-top: var(--spacing-base);
34
+ margin-bottom: var(--spacing-base);
35
+ `;
@@ -0,0 +1,24 @@
1
+ import { css } from 'styled-components';
2
+
3
+ export const cardsDarkMode = css`
4
+ --card-icon-border-color: var(--color-warm-grey-4);
5
+ --card-icon-bg-color: var(--color-warm-grey-3);
6
+
7
+ .card-variant-filled {
8
+ --card-bg-color: var(--color-warm-grey-3);
9
+ --card-bg-color-hover: var(--color-warm-grey-4);
10
+ --card-border-color: var(--color-warm-grey-4);
11
+ --card-border-color-hover: var(--color-warm-grey-3);
12
+ --card-icon-bg-color: var(--card-bg-color);
13
+ }
14
+
15
+ .card-variant-outlined {
16
+ --card-border-color: var(--color-warm-grey-4);
17
+ --card-border-color-hover: var(--color-warm-grey-5);
18
+ }
19
+
20
+ .card-variant-elevated {
21
+ --card-box-shadow: 0px 8px 24px -4px #00000014, 0px 6px 12px -6px #0000001F;
22
+ --card-box-shadow-hover: 0px 14px 64px -4px #0000001F, 0px 8px 22px -6px #0000001F;
23
+ }
24
+ `;
@@ -0,0 +1,68 @@
1
+ import { css } from 'styled-components';
2
+
3
+ export const cards = css`
4
+ --cards-gap: var(--spacing-sm);
5
+
6
+ /**
7
+ * @tokens Card default colors
8
+ */
9
+ --card-icon-bg-color: var(--color-warm-grey-1);
10
+ --card-icon-border-color: var(--border-color-secondary);
11
+ --card-text-color: var(--text-color-secondary);
12
+ --card-title-text-color: var(--h2-text-color);
13
+ --card-icon-color: var(--card-title-text-color);
14
+
15
+ /**
16
+ * @tokens Card default values
17
+ */
18
+ --card-border-radius: var(--border-radius-md);
19
+ --card-border-style: solid;
20
+ --card-link-cursor: pointer;
21
+ --card-link-icon-width: var(--h3-font-size);
22
+ --card-link-icon-height: var(--h3-font-size);
23
+ --card-border-width: 1px;
24
+ --card-icon-border-radius: var(--border-radius-md);
25
+ --card-icon-padding: var(--spacing-xs);
26
+ --card-icon-size: 24px;
27
+ --card-icon-height: var(--card-icon-size);
28
+ --card-icon-width: var(--card-icon-size);
29
+ --card-icon-gap: var(--spacing-base);
30
+ --card-title-margin: 0;
31
+ --card-title-font-weight: var(--font-weight-semibold);
32
+ --card-content-gap: 4px;
33
+ --card-padding: 16px 20px;
34
+ --card-body-font-size: var(--font-size-base);
35
+ --card-body-line-height: var(--line-height-base);
36
+
37
+ /**
38
+ * @tokens Card variants
39
+ */
40
+ .card-variant-filled {
41
+ --card-bg-color: var(--color-warm-grey-1);
42
+ --card-bg-color-hover: var(--color-warm-grey-2);
43
+ --card-border-color: var(--color-warm-grey-2);
44
+ --card-border-color-hover: var(--color-warm-grey-1);
45
+ --card-icon-bg-color: var(--color-white);
46
+ --card-icon-border-color: var(--card-border-color);
47
+ }
48
+
49
+ .card-variant-outlined {
50
+ --card-bg-color: transparent;
51
+ --card-border-color: var(--color-warm-grey-2);
52
+ --card-border-color-hover: var(--color-warm-grey-3);
53
+ }
54
+
55
+ .card-variant-elevated {
56
+ --card-bg-color: transparent;
57
+ --card-border-color: transparent;
58
+ --card-border-color-hover: transparent;
59
+ --card-box-shadow: 0px 8px 24px -4px #232A6114, 0px 6px 12px -6px #232A611F;
60
+ --card-box-shadow-hover: 0px 14px 64px -4px #232A611F, 0px 8px 22px -6px #232A611F;
61
+ }
62
+
63
+ .card-variant-ghost {
64
+ --card-bg-color: transparent;
65
+ --card-border-width: 0;
66
+ }
67
+
68
+ `
@@ -7,3 +7,7 @@ export * from '@redocly/theme/markdoc/components/HtmlBlock/HtmlBlock';
7
7
  export * from '@redocly/theme/markdoc/components/Tabs/Tab';
8
8
  export * from '@redocly/theme/markdoc/components/Tabs/Tabs';
9
9
  export * from '@redocly/theme/markdoc/components/CodeBlock/CodeBlock';
10
+ export * from '@redocly/theme/markdoc/components/Cards/Cards';
11
+ export * from '@redocly/theme/markdoc/components/Cards/Card';
12
+ export * from '@redocly/theme/markdoc/components/Cards/CardIcon';
13
+ export * from '@redocly/theme/markdoc/components/Cards/CardImage';
@@ -16,6 +16,8 @@ import { tabs } from '@redocly/theme/markdoc/tags/tabs';
16
16
  import { debug } from '@redocly/theme/markdoc/tags/debug';
17
17
  import { codeSnippet } from '@redocly/theme/markdoc/tags/code-snippet';
18
18
  import { inlineSvg } from '@redocly/theme/markdoc/tags/inline-svg';
19
+ import { cards } from '@redocly/theme/markdoc/tags/cards';
20
+ import { card } from '@redocly/theme/markdoc/tags/card';
19
21
 
20
22
  export const tags = {
21
23
  [admonition.tagName]: admonition.schema,
@@ -27,4 +29,6 @@ export const tags = {
27
29
  [tabs.tagName]: tabs.schema,
28
30
  [codeSnippet.tagName]: codeSnippet.schema,
29
31
  [inlineSvg.tagName]: inlineSvg.schema,
32
+ [cards.tagName]: cards.schema,
33
+ [card.tagName]: card.schema,
30
34
  };
@@ -0,0 +1,55 @@
1
+ import type { MarkdocSchemaWrapper } from '@redocly/theme/markdoc/tags/types';
2
+
3
+ // import { SvgContent } from '@redocly/theme/markdoc/attributes/svg-content';
4
+
5
+ export const card: MarkdocSchemaWrapper = {
6
+ schema: {
7
+ render: 'Card',
8
+ attributes: {
9
+ title: {
10
+ type: String,
11
+ required: true,
12
+ },
13
+ image: {
14
+ type: String,
15
+ resolver: 'link',
16
+ },
17
+ icon: { type: String, resolver: 'inlineSvgOrImageLink' },
18
+ lineClamp: {
19
+ type: Number,
20
+ },
21
+ iconRawContent: {
22
+ // internal use only
23
+ type: String,
24
+ render: true,
25
+ },
26
+ imagePosition: {
27
+ type: String,
28
+ matches: ['start', 'end'],
29
+ default: 'start',
30
+ },
31
+ layout: {
32
+ type: String,
33
+ matches: ['horizontal', 'combined', 'vertical'],
34
+ default: 'vertical',
35
+ },
36
+ align: {
37
+ type: String,
38
+ matches: ['start', 'center', 'end'],
39
+ default: 'start',
40
+ },
41
+ variant: {
42
+ type: String,
43
+ matches: ['filled', 'outlined', 'elevated', 'ghost'],
44
+ default: 'filled',
45
+ },
46
+ iconVariant: {
47
+ type: String,
48
+ matches: ['filled', 'ghost'],
49
+ },
50
+ to: { type: String },
51
+ },
52
+ children: ['paragraph', 'tag', 'list'],
53
+ },
54
+ tagName: 'card',
55
+ };
@@ -0,0 +1,18 @@
1
+ import type { MarkdocSchemaWrapper } from '@redocly/theme/markdoc/tags/types';
2
+
3
+ export const cards: MarkdocSchemaWrapper = {
4
+ schema: {
5
+ render: 'Cards',
6
+ attributes: {
7
+ columns: {
8
+ type: Number,
9
+ default: 3,
10
+ },
11
+ cardMinWidth: {
12
+ type: Number,
13
+ default: 240,
14
+ },
15
+ },
16
+ },
17
+ tagName: 'cards',
18
+ };
@@ -1,6 +1,8 @@
1
- import type { Schema } from '@markdoc/markdoc';
1
+ import type { Schema, SchemaAttribute } from '@markdoc/markdoc';
2
2
 
3
3
  export type MarkdocSchemaWrapper = {
4
- schema: Schema;
4
+ schema: Schema & {
5
+ attributes?: Record<string, SchemaAttribute & { resolver?: string }>;
6
+ };
5
7
  tagName: string;
6
8
  };