@redocly/theme 0.67.0-next.1 → 0.67.0-next.3
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/lib/components/Image/Image.d.ts +3 -0
- package/lib/components/Image/Image.js +101 -13
- package/lib/components/Image/variables.d.ts +1 -0
- package/lib/components/Image/variables.js +59 -0
- package/lib/core/styles/global.js +79 -77
- package/lib/ext/configure-helpers.d.ts +35 -0
- package/lib/ext/configure-helpers.js +3 -0
- package/lib/ext/configure.d.ts +3 -25
- package/lib/ext/configure.js +16 -0
- package/lib/ext/helpers/is-direct-configure-request-values.d.ts +15 -0
- package/lib/ext/helpers/is-direct-configure-request-values.js +42 -0
- package/lib/ext/use-configure-replay.d.ts +1 -1
- package/lib/markdoc/tags/img.js +36 -2
- package/package.json +2 -2
- package/src/components/Image/Image.tsx +171 -34
- package/src/components/Image/variables.ts +56 -0
- package/src/core/styles/global.ts +2 -0
- package/src/ext/configure-helpers.ts +45 -0
- package/src/ext/configure.ts +6 -26
- package/src/ext/helpers/is-direct-configure-request-values.ts +53 -0
- package/src/ext/use-configure-replay.ts +3 -3
- package/src/markdoc/tags/img.ts +36 -2
|
@@ -3,11 +3,14 @@ import type { JSX } from 'react';
|
|
|
3
3
|
export type ImageProps = {
|
|
4
4
|
src?: string;
|
|
5
5
|
srcSet?: string;
|
|
6
|
+
images?: string[];
|
|
6
7
|
alt?: string;
|
|
7
8
|
className?: string;
|
|
8
9
|
width?: string | number;
|
|
9
10
|
height?: string | number;
|
|
10
11
|
border?: string;
|
|
12
|
+
caption?: string;
|
|
13
|
+
framed?: boolean;
|
|
11
14
|
withLightbox?: boolean;
|
|
12
15
|
lightboxStyle?: React.CSSProperties | string;
|
|
13
16
|
style?: React.CSSProperties | string;
|
|
@@ -32,17 +32,16 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
36
|
exports.Image = Image;
|
|
40
37
|
const react_1 = __importStar(require("react"));
|
|
41
|
-
const styled_components_1 =
|
|
38
|
+
const styled_components_1 = __importStar(require("styled-components"));
|
|
42
39
|
const utils_1 = require("../../core/utils");
|
|
43
40
|
const hooks_1 = require("../../core/hooks");
|
|
41
|
+
const CloseIcon_1 = require("../../icons/CloseIcon/CloseIcon");
|
|
42
|
+
const Button_1 = require("../../components/Button/Button");
|
|
44
43
|
function Image(props) {
|
|
45
|
-
const { src, srcSet, alt, className, width, height, border, style, withLightbox, lightboxStyle } = props;
|
|
44
|
+
const { src, srcSet, images: galleryImages, alt, className, width, height, border, caption, framed, style, withLightbox, lightboxStyle, } = props;
|
|
46
45
|
const lightboxContainerRef = (0, react_1.useRef)(null);
|
|
47
46
|
const [lightboxImage, setLightboxImage] = (0, react_1.useState)(undefined);
|
|
48
47
|
const parsedSourceSetMap = (0, react_1.useMemo)(() => {
|
|
@@ -72,12 +71,73 @@ function Image(props) {
|
|
|
72
71
|
}, [lightboxImage]);
|
|
73
72
|
const combinedStyles = Object.assign(Object.assign(Object.assign({}, (withLightbox && { cursor: 'pointer' })), (border && { border })), (typeof style === 'string' ? (0, utils_1.parseStyleString)(style) : style));
|
|
74
73
|
const lightboxOverlayStyles = typeof lightboxStyle === 'string' ? (0, utils_1.parseStyleString)(lightboxStyle) : lightboxStyle;
|
|
74
|
+
const images = src ? (react_1.default.createElement("img", { src: src, alt: alt, className: className, width: width, height: height, style: combinedStyles, onClick: () => handleImageClick(src) })) : (Array.from(parsedSourceSetMap).map(([key, value]) => (react_1.default.createElement(ColorModeAwareImage, { key: key, $colorMode: key, src: value, alt: alt, className: className, width: width, height: height, $withLightbox: withLightbox, style: combinedStyles, onClick: () => handleImageClick(value) }))));
|
|
75
|
+
const hasGallery = Array.isArray(galleryImages) && galleryImages.length > 0;
|
|
76
|
+
const visibleGalleryImages = hasGallery ? galleryImages.slice(0, 3) : [];
|
|
77
|
+
const gallery = hasGallery ? (react_1.default.createElement(GalleryRow, null, visibleGalleryImages.map((galleryImageSrc, index) => (react_1.default.createElement("img", { key: `${galleryImageSrc}-${index}`, src: galleryImageSrc, alt: alt, style: withLightbox ? { cursor: 'pointer' } : undefined, onClick: () => handleImageClick(galleryImageSrc) }))))) : null;
|
|
78
|
+
const hasCaption = Boolean(caption);
|
|
79
|
+
const hasWrapper = Boolean(framed || hasCaption || hasGallery);
|
|
80
|
+
const wrapperContent = hasGallery ? gallery : images;
|
|
75
81
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
76
82
|
lightboxImage ? (react_1.default.createElement(LightboxContainer, { ref: lightboxContainerRef, onClick: handleCloseLightbox, onKeyDown: handleLightboxKeyDown, tabIndex: 0 },
|
|
77
83
|
react_1.default.createElement(Overlay, { style: lightboxOverlayStyles }),
|
|
78
|
-
react_1.default.createElement(
|
|
79
|
-
|
|
84
|
+
react_1.default.createElement(LightboxContent, null,
|
|
85
|
+
react_1.default.createElement(CloseButton, { variant: "secondary", "aria-label": "Close image", onClick: handleCloseLightbox },
|
|
86
|
+
react_1.default.createElement(CloseIcon_1.CloseIcon, null)),
|
|
87
|
+
react_1.default.createElement(Image, { src: lightboxImage, alt: alt })))) : null,
|
|
88
|
+
hasWrapper ? (react_1.default.createElement(ImageFrame, { "data-component-name": "Image/Image", $framed: framed, $gallery: hasGallery },
|
|
89
|
+
wrapperContent,
|
|
90
|
+
hasCaption ? react_1.default.createElement(ImageCaption, null, caption) : null)) : (images)));
|
|
80
91
|
}
|
|
92
|
+
const ImageFrame = styled_components_1.default.figure `
|
|
93
|
+
display: ${({ $gallery }) => ($gallery ? 'block' : 'inline-block')};
|
|
94
|
+
margin: 0;
|
|
95
|
+
${({ $gallery }) => ($gallery ? 'width: 100%;' : '')}
|
|
96
|
+
max-width: 100%;
|
|
97
|
+
|
|
98
|
+
${({ $framed }) => $framed &&
|
|
99
|
+
(0, styled_components_1.css) `
|
|
100
|
+
padding: var(--image-frame-padding);
|
|
101
|
+
border: var(--border-width) var(--border-style) var(--image-frame-border-color);
|
|
102
|
+
border-radius: var(--image-frame-border-radius);
|
|
103
|
+
background-color: var(--image-frame-bg-color);
|
|
104
|
+
`}
|
|
105
|
+
|
|
106
|
+
> img {
|
|
107
|
+
display: block;
|
|
108
|
+
max-width: 100%;
|
|
109
|
+
height: auto;
|
|
110
|
+
background: transparent center / cover no-repeat;
|
|
111
|
+
|
|
112
|
+
${({ $framed }) => $framed &&
|
|
113
|
+
(0, styled_components_1.css) `
|
|
114
|
+
border-radius: var(--image-frame-image-border-radius);
|
|
115
|
+
`}
|
|
116
|
+
}
|
|
117
|
+
`;
|
|
118
|
+
const GalleryRow = styled_components_1.default.div `
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: stretch;
|
|
121
|
+
overflow: hidden;
|
|
122
|
+
border-radius: var(--image-gallery-border-radius);
|
|
123
|
+
|
|
124
|
+
img {
|
|
125
|
+
flex: 1 1 0;
|
|
126
|
+
min-width: 0;
|
|
127
|
+
width: 100%;
|
|
128
|
+
object-fit: cover;
|
|
129
|
+
border-radius: 0;
|
|
130
|
+
background: var(--image-gallery-image-bg-color) 50% / cover no-repeat;
|
|
131
|
+
}
|
|
132
|
+
`;
|
|
133
|
+
const ImageCaption = styled_components_1.default.figcaption `
|
|
134
|
+
padding: var(--image-caption-padding);
|
|
135
|
+
color: var(--image-caption-text-color);
|
|
136
|
+
font-size: var(--image-caption-font-size);
|
|
137
|
+
line-height: var(--image-caption-line-height);
|
|
138
|
+
font-weight: var(--image-caption-font-weight);
|
|
139
|
+
text-align: center;
|
|
140
|
+
`;
|
|
81
141
|
const ColorModeAwareImage = styled_components_1.default.img `
|
|
82
142
|
html:not(.${(props) => props.$colorMode}) && {
|
|
83
143
|
display: none;
|
|
@@ -88,13 +148,38 @@ const ColorModeAwareImage = styled_components_1.default.img `
|
|
|
88
148
|
`}
|
|
89
149
|
`;
|
|
90
150
|
const Overlay = styled_components_1.default.div `
|
|
91
|
-
background-color: var(--bg-color
|
|
151
|
+
background-color: var(--image-lightbox-overlay-bg-color);
|
|
92
152
|
grid-column: 1 / 2;
|
|
93
153
|
grid-row: 1 / 2;
|
|
94
154
|
height: 100%;
|
|
95
155
|
width: 100%;
|
|
96
156
|
z-index: -1;
|
|
97
157
|
`;
|
|
158
|
+
const CloseButton = (0, styled_components_1.default)(Button_1.Button) `
|
|
159
|
+
position: absolute;
|
|
160
|
+
top: 0;
|
|
161
|
+
left: 100%;
|
|
162
|
+
margin-left: var(--image-lightbox-close-offset);
|
|
163
|
+
width: var(--image-lightbox-close-size);
|
|
164
|
+
height: var(--image-lightbox-close-size);
|
|
165
|
+
border-radius: var(--image-lightbox-close-border-radius);
|
|
166
|
+
z-index: 1;
|
|
167
|
+
|
|
168
|
+
svg {
|
|
169
|
+
width: var(--image-lightbox-close-icon-size);
|
|
170
|
+
height: var(--image-lightbox-close-icon-size);
|
|
171
|
+
}
|
|
172
|
+
`;
|
|
173
|
+
const LightboxContent = styled_components_1.default.div `
|
|
174
|
+
position: relative;
|
|
175
|
+
grid-column: 1 / 2;
|
|
176
|
+
grid-row: 1 / 2;
|
|
177
|
+
margin: auto;
|
|
178
|
+
width: fit-content;
|
|
179
|
+
height: fit-content;
|
|
180
|
+
max-width: var(--image-lightbox-content-max-width);
|
|
181
|
+
max-height: var(--image-lightbox-content-max-height);
|
|
182
|
+
`;
|
|
98
183
|
const LightboxContainer = styled_components_1.default.div `
|
|
99
184
|
display: grid;
|
|
100
185
|
height: 100vh;
|
|
@@ -110,11 +195,14 @@ const LightboxContainer = styled_components_1.default.div `
|
|
|
110
195
|
|
|
111
196
|
img {
|
|
112
197
|
cursor: pointer;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
198
|
+
display: block;
|
|
199
|
+
max-width: var(--image-lightbox-image-max-width);
|
|
200
|
+
max-height: var(--image-lightbox-image-max-height);
|
|
201
|
+
border-radius: var(--image-lightbox-image-border-radius);
|
|
202
|
+
background:
|
|
203
|
+
var(--image-lightbox-image-bg-placeholder) center / cover no-repeat,
|
|
204
|
+
var(--image-frame-bg-color);
|
|
205
|
+
box-shadow: var(--image-lightbox-image-shadow);
|
|
118
206
|
}
|
|
119
207
|
`;
|
|
120
208
|
//# sourceMappingURL=Image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const image: import("styled-components").RuleSet<object>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.image = void 0;
|
|
4
|
+
const styled_components_1 = require("styled-components");
|
|
5
|
+
exports.image = (0, styled_components_1.css) `
|
|
6
|
+
/* === Image === */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @tokens Image frame
|
|
10
|
+
*/
|
|
11
|
+
--image-frame-padding: var(--spacing-xs);
|
|
12
|
+
--image-frame-border-color: var(--border-color-secondary);
|
|
13
|
+
--image-frame-border-radius: var(--border-radius-xxl);
|
|
14
|
+
--image-frame-bg-color: var(--bg-color-raised);
|
|
15
|
+
--image-frame-image-border-radius: var(--border-radius-lg);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @tokens Image caption
|
|
19
|
+
*/
|
|
20
|
+
--image-caption-padding: var(--spacing-sm) var(--spacing-lg) var(--spacing-xxs) var(--spacing-lg);
|
|
21
|
+
--image-caption-text-color: var(--text-color-primary);
|
|
22
|
+
--image-caption-font-size: var(--font-size-base);
|
|
23
|
+
--image-caption-line-height: var(--line-height-base);
|
|
24
|
+
--image-caption-font-weight: var(--font-weight-regular);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @tokens Image gallery
|
|
28
|
+
*/
|
|
29
|
+
--image-gallery-border-radius: var(--border-radius-lg);
|
|
30
|
+
--image-gallery-image-bg-color: var(--bg-color-tonal);
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @tokens Image lightbox
|
|
34
|
+
*/
|
|
35
|
+
--image-lightbox-overlay-bg-color: var(--bg-color-modal-overlay);
|
|
36
|
+
--image-lightbox-content-max-width: 90%;
|
|
37
|
+
--image-lightbox-content-max-height: 90%;
|
|
38
|
+
|
|
39
|
+
--image-lightbox-image-max-width: min(
|
|
40
|
+
90vw,
|
|
41
|
+
calc(100vw - 2 * var(--image-lightbox-side-gutter))
|
|
42
|
+
);
|
|
43
|
+
--image-lightbox-image-max-height: 90vh;
|
|
44
|
+
--image-lightbox-image-border-radius: var(--border-radius-xl);
|
|
45
|
+
--image-lightbox-image-bg-placeholder: var(--bg-color-tonal);
|
|
46
|
+
--image-lightbox-image-shadow: var(--bg-raised-shadow);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @tokens Image lightbox close button
|
|
50
|
+
*/
|
|
51
|
+
--image-lightbox-close-size: 40px;
|
|
52
|
+
--image-lightbox-close-icon-size: 18px;
|
|
53
|
+
--image-lightbox-close-offset: var(--spacing-base);
|
|
54
|
+
--image-lightbox-close-border-radius: var(--border-radius-lg);
|
|
55
|
+
--image-lightbox-side-gutter: calc(
|
|
56
|
+
var(--image-lightbox-close-size) + var(--image-lightbox-close-offset) + var(--spacing-sm)
|
|
57
|
+
);
|
|
58
|
+
`;
|
|
59
|
+
//# sourceMappingURL=variables.js.map
|
|
@@ -10,43 +10,44 @@ const variables_5 = require("../../components/Breadcrumbs/variables");
|
|
|
10
10
|
const variables_6 = require("../../components/Tag/variables");
|
|
11
11
|
const variables_7 = require("../../components/TableOfContent/variables");
|
|
12
12
|
const variables_8 = require("../../components/Catalog/variables");
|
|
13
|
-
const variables_9 = require("../../components/
|
|
14
|
-
const variables_10 = require("../../components/
|
|
15
|
-
const variables_11 = require("../../components/
|
|
16
|
-
const variables_12 = require("../../components/
|
|
17
|
-
const variables_13 = require("../../components/
|
|
18
|
-
const variables_14 = require("../../components/
|
|
19
|
-
const variables_15 = require("../../components/
|
|
20
|
-
const variables_16 = require("../../
|
|
21
|
-
const variables_17 = require("../../
|
|
22
|
-
const variables_18 = require("../../components/
|
|
23
|
-
const variables_19 = require("../../components/
|
|
24
|
-
const variables_20 = require("../../components/
|
|
25
|
-
const variables_21 = require("../../components/
|
|
26
|
-
const variables_22 = require("../../components/
|
|
27
|
-
const variables_23 = require("../../components/
|
|
28
|
-
const variables_24 = require("../../components/
|
|
29
|
-
const variables_25 = require("../../components/
|
|
30
|
-
const variables_26 = require("../../components/
|
|
31
|
-
const variables_27 = require("../../components/
|
|
32
|
-
const variables_28 = require("../../
|
|
33
|
-
const variables_29 = require("../../markdoc/components/
|
|
34
|
-
const variables_30 = require("../../components/
|
|
35
|
-
const variables_31 = require("../../components/
|
|
36
|
-
const variables_32 = require("../../components/
|
|
37
|
-
const variables_33 = require("../../components/
|
|
38
|
-
const variables_34 = require("../../components/
|
|
39
|
-
const variables_35 = require("../../components/
|
|
40
|
-
const variables_36 = require("../../components/
|
|
41
|
-
const variables_37 = require("../../components/
|
|
42
|
-
const variables_38 = require("../../components/
|
|
43
|
-
const variables_39 = require("../../
|
|
44
|
-
const variables_40 = require("../../markdoc/components/
|
|
45
|
-
const variables_41 = require("../../components/
|
|
46
|
-
const variables_42 = require("../../components/
|
|
47
|
-
const variables_43 = require("../../components/
|
|
48
|
-
const variables_44 = require("../../components/
|
|
49
|
-
const variables_45 = require("../../components/
|
|
13
|
+
const variables_9 = require("../../components/Image/variables");
|
|
14
|
+
const variables_10 = require("../../components/Filter/variables");
|
|
15
|
+
const variables_11 = require("../../components/CatalogClassic/variables");
|
|
16
|
+
const variables_12 = require("../../components/Panel/variables");
|
|
17
|
+
const variables_13 = require("../../components/Accordion/variables");
|
|
18
|
+
const variables_14 = require("../../components/Select/variables");
|
|
19
|
+
const variables_15 = require("../../components/Dropdown/variables");
|
|
20
|
+
const variables_16 = require("../../components/Tooltip/variables");
|
|
21
|
+
const variables_17 = require("../../icons/CheckboxIcon/variables");
|
|
22
|
+
const variables_18 = require("../../components/Admonition/variables");
|
|
23
|
+
const variables_19 = require("../../components/Footer/variables");
|
|
24
|
+
const variables_20 = require("../../components/Button/variables");
|
|
25
|
+
const variables_21 = require("../../components/Buttons/variables");
|
|
26
|
+
const variables_22 = require("../../components/Navbar/variables");
|
|
27
|
+
const variables_23 = require("../../components/Search/variables");
|
|
28
|
+
const variables_24 = require("../../components/Menu/variables");
|
|
29
|
+
const variables_25 = require("../../components/CodeBlock/variables");
|
|
30
|
+
const variables_26 = require("../../components/Product/variables");
|
|
31
|
+
const variables_27 = require("../../components/Markdown/variables");
|
|
32
|
+
const variables_28 = require("../../components/Banner/variables");
|
|
33
|
+
const variables_29 = require("../../markdoc/components/Tabs/variables");
|
|
34
|
+
const variables_30 = require("../../markdoc/components/Diagram/variables");
|
|
35
|
+
const variables_31 = require("../../components/LastUpdated/variables");
|
|
36
|
+
const variables_32 = require("../../components/Logo/variables");
|
|
37
|
+
const variables_33 = require("../../components/StatusCode/variables");
|
|
38
|
+
const variables_34 = require("../../components/Segmented/variables");
|
|
39
|
+
const variables_35 = require("../../components/UserMenu/variables");
|
|
40
|
+
const variables_36 = require("../../components/Tags/variables");
|
|
41
|
+
const variables_37 = require("../../components/VersionPicker/variables");
|
|
42
|
+
const variables_38 = require("../../components/DatePicker/variables");
|
|
43
|
+
const variables_39 = require("../../components/Switch/variables");
|
|
44
|
+
const variables_40 = require("../../markdoc/components/Cards/variables");
|
|
45
|
+
const variables_41 = require("../../markdoc/components/CodeWalkthrough/variables");
|
|
46
|
+
const variables_42 = require("../../components/SkipContent/variables");
|
|
47
|
+
const variables_43 = require("../../components/PageActions/variables");
|
|
48
|
+
const variables_44 = require("../../components/SvgViewer/variables");
|
|
49
|
+
const variables_45 = require("../../components/Toast/variables");
|
|
50
|
+
const variables_46 = require("../../components/PageNavigation/variables");
|
|
50
51
|
const palette_1 = require("./palette");
|
|
51
52
|
const dark_1 = require("./dark");
|
|
52
53
|
const themeColors = (0, styled_components_1.css) `
|
|
@@ -1255,47 +1256,48 @@ const replay = (0, styled_components_1.css) `
|
|
|
1255
1256
|
`;
|
|
1256
1257
|
exports.styles = (0, styled_components_1.css) `
|
|
1257
1258
|
:root {
|
|
1258
|
-
${
|
|
1259
|
-
${
|
|
1259
|
+
${variables_13.accordion}
|
|
1260
|
+
${variables_18.admonition}
|
|
1260
1261
|
${apiReferenceDocs}
|
|
1261
|
-
${
|
|
1262
|
+
${variables_12.apiReferencePanels}
|
|
1262
1263
|
${badges}
|
|
1263
|
-
${
|
|
1264
|
+
${variables_28.banner}
|
|
1264
1265
|
${borders}
|
|
1265
1266
|
${variables_5.breadcrumbs}
|
|
1266
|
-
${
|
|
1267
|
-
${
|
|
1268
|
-
${
|
|
1269
|
-
${
|
|
1267
|
+
${variables_20.button}
|
|
1268
|
+
${variables_21.aiAssistantButton}
|
|
1269
|
+
${variables_21.connectMCPButton}
|
|
1270
|
+
${variables_40.cards}
|
|
1270
1271
|
${variables_8.catalog}
|
|
1271
|
-
${
|
|
1272
|
-
${
|
|
1273
|
-
${
|
|
1272
|
+
${variables_11.catalogClassic}
|
|
1273
|
+
${variables_25.code}
|
|
1274
|
+
${variables_41.codeWalkthrough}
|
|
1274
1275
|
${docsDropdown}
|
|
1275
|
-
${
|
|
1276
|
+
${variables_15.dropdown}
|
|
1276
1277
|
${error}
|
|
1277
|
-
${
|
|
1278
|
-
${
|
|
1278
|
+
${variables_10.filter}
|
|
1279
|
+
${variables_19.footer}
|
|
1279
1280
|
${headingsTypography}
|
|
1280
|
-
${
|
|
1281
|
+
${variables_36.httpTag}
|
|
1282
|
+
${variables_9.image}
|
|
1281
1283
|
${inputs}
|
|
1282
1284
|
${variables_1.languagePicker}
|
|
1283
|
-
${
|
|
1285
|
+
${variables_31.lastUpdated}
|
|
1284
1286
|
${links}
|
|
1285
1287
|
${loadProgressBar}
|
|
1286
|
-
${
|
|
1287
|
-
${
|
|
1288
|
-
${
|
|
1289
|
-
${
|
|
1290
|
-
${
|
|
1291
|
-
${
|
|
1288
|
+
${variables_32.logo}
|
|
1289
|
+
${variables_27.markdown}
|
|
1290
|
+
${variables_29.markdownTabs}
|
|
1291
|
+
${variables_30.diagram}
|
|
1292
|
+
${variables_24.menu}
|
|
1293
|
+
${variables_24.mobileMenu}
|
|
1292
1294
|
${modal}
|
|
1293
|
-
${
|
|
1295
|
+
${variables_22.navbar}
|
|
1294
1296
|
${pages}
|
|
1295
|
-
${
|
|
1296
|
-
${
|
|
1297
|
-
${
|
|
1298
|
-
${
|
|
1297
|
+
${variables_26.productPicker}
|
|
1298
|
+
${variables_12.responsePanelColors}
|
|
1299
|
+
${variables_23.search}
|
|
1300
|
+
${variables_14.select}
|
|
1299
1301
|
${variables_4.sidebar}
|
|
1300
1302
|
${sizeAndSpace}
|
|
1301
1303
|
${variables_6.tag}
|
|
@@ -1303,28 +1305,28 @@ exports.styles = (0, styled_components_1.css) `
|
|
|
1303
1305
|
${palette_1.activeBrandPaletteLight}
|
|
1304
1306
|
${tile}
|
|
1305
1307
|
${variables_7.toc}
|
|
1306
|
-
${
|
|
1308
|
+
${variables_16.tooltip}
|
|
1307
1309
|
${typography}
|
|
1308
|
-
${
|
|
1309
|
-
${
|
|
1310
|
+
${variables_35.userMenu}
|
|
1311
|
+
${variables_37.versionPicker}
|
|
1310
1312
|
${zIndexDepth}
|
|
1311
1313
|
${scorecardColors}
|
|
1312
|
-
${
|
|
1314
|
+
${variables_33.statusCode}
|
|
1313
1315
|
${tab}
|
|
1314
1316
|
${icon}
|
|
1315
1317
|
${tree}
|
|
1316
|
-
${
|
|
1317
|
-
${
|
|
1318
|
-
${
|
|
1318
|
+
${variables_34.segmented}
|
|
1319
|
+
${variables_39.switcher}
|
|
1320
|
+
${variables_17.checkbox}
|
|
1319
1321
|
${variables_3.feedback}
|
|
1320
1322
|
${variables_2.scorecard}
|
|
1321
|
-
${
|
|
1323
|
+
${variables_38.datePicker}
|
|
1322
1324
|
${replay}
|
|
1323
|
-
${
|
|
1324
|
-
${
|
|
1325
|
-
${
|
|
1326
|
-
${
|
|
1327
|
-
${
|
|
1325
|
+
${variables_42.skipContent}
|
|
1326
|
+
${variables_43.pageActions}
|
|
1327
|
+
${variables_44.svgViewer}
|
|
1328
|
+
${variables_45.toast}
|
|
1329
|
+
${variables_46.pageNavigation}
|
|
1328
1330
|
|
|
1329
1331
|
background-color: var(--bg-color);
|
|
1330
1332
|
color: var(--text-color-primary);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type SecurityDetails = {
|
|
2
|
+
password?: string;
|
|
3
|
+
username?: string;
|
|
4
|
+
token?: {
|
|
5
|
+
token_type?: string;
|
|
6
|
+
access_token: string;
|
|
7
|
+
};
|
|
8
|
+
client_id?: string;
|
|
9
|
+
client_secret?: string;
|
|
10
|
+
scopes?: string[];
|
|
11
|
+
};
|
|
12
|
+
export type ConfigureInputHintAction = {
|
|
13
|
+
label: string;
|
|
14
|
+
action: () => void;
|
|
15
|
+
};
|
|
16
|
+
export type ConfigureInputHint = {
|
|
17
|
+
title: string;
|
|
18
|
+
text: string;
|
|
19
|
+
actions?: ConfigureInputHintAction[];
|
|
20
|
+
};
|
|
21
|
+
export type ConfigureRequestValues = {
|
|
22
|
+
headers?: Record<string, string>;
|
|
23
|
+
body?: Record<string, any>;
|
|
24
|
+
query?: Record<string, string>;
|
|
25
|
+
path?: Record<string, string>;
|
|
26
|
+
cookie?: Record<string, string>;
|
|
27
|
+
security?: Record<string, SecurityDetails>;
|
|
28
|
+
envVariables?: Record<string, string>;
|
|
29
|
+
serverVariables?: Record<string, string>;
|
|
30
|
+
inputHints?: Record<string, ConfigureInputHint>;
|
|
31
|
+
};
|
|
32
|
+
export type ConfigureServerRequestValues = {
|
|
33
|
+
[serverUrl: string]: ConfigureRequestValues;
|
|
34
|
+
};
|
|
35
|
+
export type ConfigureReplayConfig = ConfigureRequestValues | ConfigureServerRequestValues | null | undefined;
|
package/lib/ext/configure.d.ts
CHANGED
|
@@ -1,28 +1,7 @@
|
|
|
1
1
|
import type { UserClaims, OpenAPIServer } from '../core/types';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
token?: {
|
|
6
|
-
token_type?: string;
|
|
7
|
-
access_token: string;
|
|
8
|
-
};
|
|
9
|
-
client_id?: string;
|
|
10
|
-
client_secret?: string;
|
|
11
|
-
scopes?: string[];
|
|
12
|
-
};
|
|
13
|
-
export type ConfigureRequestValues = {
|
|
14
|
-
headers?: Record<string, string>;
|
|
15
|
-
body?: Record<string, any>;
|
|
16
|
-
query?: Record<string, string>;
|
|
17
|
-
path?: Record<string, string>;
|
|
18
|
-
cookie?: Record<string, string>;
|
|
19
|
-
security?: Record<string, SecurityDetails>;
|
|
20
|
-
envVariables?: Record<string, string>;
|
|
21
|
-
serverVariables?: Record<string, string>;
|
|
22
|
-
};
|
|
23
|
-
export type ConfigureServerRequestValues = {
|
|
24
|
-
[serverUrl: string]: ConfigureRequestValues;
|
|
25
|
-
};
|
|
2
|
+
export * from '../ext/configure-helpers';
|
|
3
|
+
export * from '../ext/helpers/is-direct-configure-request-values';
|
|
4
|
+
import type { ConfigureRequestValues, ConfigureServerRequestValues } from '../ext/configure-helpers';
|
|
26
5
|
type Configure = {
|
|
27
6
|
requestValues?: ConfigureRequestValues | ConfigureServerRequestValues;
|
|
28
7
|
};
|
|
@@ -38,4 +17,3 @@ type ContextProps = {
|
|
|
38
17
|
servers: OpenAPIServer[];
|
|
39
18
|
};
|
|
40
19
|
export declare function configure(_context: ContextProps): Configure;
|
|
41
|
-
export {};
|
package/lib/ext/configure.js
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
17
|
exports.configure = configure;
|
|
18
|
+
__exportStar(require("../ext/configure-helpers"), exports);
|
|
19
|
+
__exportStar(require("../ext/helpers/is-direct-configure-request-values"), exports);
|
|
4
20
|
function configure(_context) {
|
|
5
21
|
// const exampleDefaultRequestValues: ConfigureRequestValues = {
|
|
6
22
|
// body: {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ConfigureRequestValues, ConfigureServerRequestValues } from '../../ext/configure-helpers';
|
|
2
|
+
/**
|
|
3
|
+
* Type guard that distinguishes a direct {@link ConfigureRequestValues} payload (request
|
|
4
|
+
* values that apply to every server) from a {@link ConfigureServerRequestValues} payload
|
|
5
|
+
* (request values keyed by server URL).
|
|
6
|
+
*
|
|
7
|
+
* A payload is treated as server-keyed when at least one top-level key is *not* a known
|
|
8
|
+
* request-value key (e.g. `headers`, `security`, `inputHints`) and its value looks like a
|
|
9
|
+
* nested {@link ConfigureRequestValues}. This keeps mixed shapes — e.g. server-keyed values
|
|
10
|
+
* alongside a top-level `inputHints` sibling — classified as server-keyed.
|
|
11
|
+
*
|
|
12
|
+
* @param value - The configure payload returned from `getReplayConfiguration`.
|
|
13
|
+
* @returns `true` when `value` is a direct {@link ConfigureRequestValues}, narrowing the type.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isDirectConfigureRequestValues(value: ConfigureRequestValues | ConfigureServerRequestValues): value is ConfigureRequestValues;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isDirectConfigureRequestValues = isDirectConfigureRequestValues;
|
|
4
|
+
const CONFIGURE_REQUEST_VALUE_KEYS = [
|
|
5
|
+
'headers',
|
|
6
|
+
'body',
|
|
7
|
+
'query',
|
|
8
|
+
'path',
|
|
9
|
+
'cookie',
|
|
10
|
+
'security',
|
|
11
|
+
'envVariables',
|
|
12
|
+
'serverVariables',
|
|
13
|
+
'inputHints',
|
|
14
|
+
];
|
|
15
|
+
const CONFIGURE_REQUEST_VALUE_KEY_SET = new Set(CONFIGURE_REQUEST_VALUE_KEYS);
|
|
16
|
+
function hasConfigureRequestValueKeys(value) {
|
|
17
|
+
return CONFIGURE_REQUEST_VALUE_KEYS.some((key) => key in value);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Type guard that distinguishes a direct {@link ConfigureRequestValues} payload (request
|
|
21
|
+
* values that apply to every server) from a {@link ConfigureServerRequestValues} payload
|
|
22
|
+
* (request values keyed by server URL).
|
|
23
|
+
*
|
|
24
|
+
* A payload is treated as server-keyed when at least one top-level key is *not* a known
|
|
25
|
+
* request-value key (e.g. `headers`, `security`, `inputHints`) and its value looks like a
|
|
26
|
+
* nested {@link ConfigureRequestValues}. This keeps mixed shapes — e.g. server-keyed values
|
|
27
|
+
* alongside a top-level `inputHints` sibling — classified as server-keyed.
|
|
28
|
+
*
|
|
29
|
+
* @param value - The configure payload returned from `getReplayConfiguration`.
|
|
30
|
+
* @returns `true` when `value` is a direct {@link ConfigureRequestValues}, narrowing the type.
|
|
31
|
+
*/
|
|
32
|
+
function isDirectConfigureRequestValues(value) {
|
|
33
|
+
const hasServerKeyedValues = Object.entries(value).some(([key, entry]) => !CONFIGURE_REQUEST_VALUE_KEY_SET.has(key) &&
|
|
34
|
+
entry != null &&
|
|
35
|
+
typeof entry === 'object' &&
|
|
36
|
+
hasConfigureRequestValueKeys(entry));
|
|
37
|
+
if (hasServerKeyedValues) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
return hasConfigureRequestValueKeys(value);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=is-direct-configure-request-values.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ConfigureRequestValues, type ConfigureServerRequestValues } from '../ext/configure';
|
|
2
2
|
import type { UserClaims, OpenAPIServer, OpenAPIInfo } from '../core/types';
|
|
3
3
|
type ContextProps = {
|
|
4
4
|
operation: {
|
package/lib/markdoc/tags/img.js
CHANGED
|
@@ -14,9 +14,20 @@ exports.img = {
|
|
|
14
14
|
type: String,
|
|
15
15
|
resolver: 'imageSrcSet',
|
|
16
16
|
},
|
|
17
|
+
images: {
|
|
18
|
+
type: Array,
|
|
19
|
+
resolver: 'imageGallery',
|
|
20
|
+
},
|
|
17
21
|
alt: {
|
|
18
22
|
type: String,
|
|
19
23
|
},
|
|
24
|
+
caption: {
|
|
25
|
+
type: String,
|
|
26
|
+
},
|
|
27
|
+
framed: {
|
|
28
|
+
type: Boolean,
|
|
29
|
+
default: false,
|
|
30
|
+
},
|
|
20
31
|
withLightbox: {
|
|
21
32
|
type: Boolean,
|
|
22
33
|
default: false,
|
|
@@ -45,8 +56,31 @@ exports.img = {
|
|
|
45
56
|
},
|
|
46
57
|
},
|
|
47
58
|
validate: (node) => {
|
|
48
|
-
|
|
49
|
-
|
|
59
|
+
const { src, srcSet, images } = node.attributes;
|
|
60
|
+
const hasGallery = Array.isArray(images) && images.length > 0;
|
|
61
|
+
if (!src && !srcSet && !hasGallery) {
|
|
62
|
+
return [{ id: '', message: 'src, srcSet, or images is required', level: 'error' }];
|
|
63
|
+
}
|
|
64
|
+
if (hasGallery && (src || srcSet)) {
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
id: 'invalid-img-source-combination',
|
|
68
|
+
message: 'images cannot be used together with src or srcSet',
|
|
69
|
+
level: 'error',
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
if (src && srcSet) {
|
|
74
|
+
return [
|
|
75
|
+
{
|
|
76
|
+
id: 'invalid-img-source-combination',
|
|
77
|
+
message: 'src cannot be used together with srcSet',
|
|
78
|
+
level: 'error',
|
|
79
|
+
},
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
if (Array.isArray(images) && images.length > 3) {
|
|
83
|
+
return [{ id: '', message: 'images supports a maximum of 3 items', level: 'error' }];
|
|
50
84
|
}
|
|
51
85
|
return [];
|
|
52
86
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/theme",
|
|
3
|
-
"version": "0.67.0-next.
|
|
3
|
+
"version": "0.67.0-next.3",
|
|
4
4
|
"description": "Shared UI components lib",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"theme",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"vitest": "4.1.8",
|
|
64
64
|
"vitest-when": "0.6.2",
|
|
65
65
|
"webpack": "5.105.2",
|
|
66
|
-
"@redocly/realm-asyncapi-sdk": "0.13.0-next.
|
|
66
|
+
"@redocly/realm-asyncapi-sdk": "0.13.0-next.2"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"@tanstack/react-query": "5.62.3",
|
|
@@ -1,27 +1,45 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
-
import styled from 'styled-components';
|
|
2
|
+
import styled, { css } from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import type { KeyboardEvent, JSX } from 'react';
|
|
5
5
|
|
|
6
6
|
import { parseSrcSet, parseStyleString } from '@redocly/theme/core/utils';
|
|
7
7
|
import { useModalScrollLock } from '@redocly/theme/core/hooks';
|
|
8
|
+
import { CloseIcon } from '@redocly/theme/icons/CloseIcon/CloseIcon';
|
|
9
|
+
import { Button } from '@redocly/theme/components/Button/Button';
|
|
8
10
|
|
|
9
11
|
export type ImageProps = {
|
|
10
12
|
src?: string;
|
|
11
13
|
srcSet?: string;
|
|
14
|
+
images?: string[];
|
|
12
15
|
alt?: string;
|
|
13
16
|
className?: string;
|
|
14
17
|
width?: string | number;
|
|
15
18
|
height?: string | number;
|
|
16
19
|
border?: string;
|
|
20
|
+
caption?: string;
|
|
21
|
+
framed?: boolean;
|
|
17
22
|
withLightbox?: boolean;
|
|
18
23
|
lightboxStyle?: React.CSSProperties | string;
|
|
19
24
|
style?: React.CSSProperties | string;
|
|
20
25
|
};
|
|
21
26
|
|
|
22
27
|
export function Image(props: ImageProps): JSX.Element {
|
|
23
|
-
const {
|
|
24
|
-
|
|
28
|
+
const {
|
|
29
|
+
src,
|
|
30
|
+
srcSet,
|
|
31
|
+
images: galleryImages,
|
|
32
|
+
alt,
|
|
33
|
+
className,
|
|
34
|
+
width,
|
|
35
|
+
height,
|
|
36
|
+
border,
|
|
37
|
+
caption,
|
|
38
|
+
framed,
|
|
39
|
+
style,
|
|
40
|
+
withLightbox,
|
|
41
|
+
lightboxStyle,
|
|
42
|
+
} = props;
|
|
25
43
|
|
|
26
44
|
const lightboxContainerRef = useRef<HTMLDivElement>(null);
|
|
27
45
|
const [lightboxImage, setLightboxImage] = useState<string | undefined>(undefined);
|
|
@@ -66,6 +84,54 @@ export function Image(props: ImageProps): JSX.Element {
|
|
|
66
84
|
const lightboxOverlayStyles: React.CSSProperties | undefined =
|
|
67
85
|
typeof lightboxStyle === 'string' ? parseStyleString(lightboxStyle) : lightboxStyle;
|
|
68
86
|
|
|
87
|
+
const images = src ? (
|
|
88
|
+
<img
|
|
89
|
+
src={src}
|
|
90
|
+
alt={alt}
|
|
91
|
+
className={className}
|
|
92
|
+
width={width}
|
|
93
|
+
height={height}
|
|
94
|
+
style={combinedStyles}
|
|
95
|
+
onClick={() => handleImageClick(src)}
|
|
96
|
+
/>
|
|
97
|
+
) : (
|
|
98
|
+
Array.from(parsedSourceSetMap).map(([key, value]) => (
|
|
99
|
+
<ColorModeAwareImage
|
|
100
|
+
key={key}
|
|
101
|
+
$colorMode={key}
|
|
102
|
+
src={value}
|
|
103
|
+
alt={alt}
|
|
104
|
+
className={className}
|
|
105
|
+
width={width}
|
|
106
|
+
height={height}
|
|
107
|
+
$withLightbox={withLightbox}
|
|
108
|
+
style={combinedStyles}
|
|
109
|
+
onClick={() => handleImageClick(value)}
|
|
110
|
+
/>
|
|
111
|
+
))
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
const hasGallery = Array.isArray(galleryImages) && galleryImages.length > 0;
|
|
115
|
+
const visibleGalleryImages = hasGallery ? galleryImages.slice(0, 3) : [];
|
|
116
|
+
|
|
117
|
+
const gallery = hasGallery ? (
|
|
118
|
+
<GalleryRow>
|
|
119
|
+
{visibleGalleryImages.map((galleryImageSrc, index) => (
|
|
120
|
+
<img
|
|
121
|
+
key={`${galleryImageSrc}-${index}`}
|
|
122
|
+
src={galleryImageSrc}
|
|
123
|
+
alt={alt}
|
|
124
|
+
style={withLightbox ? { cursor: 'pointer' } : undefined}
|
|
125
|
+
onClick={() => handleImageClick(galleryImageSrc)}
|
|
126
|
+
/>
|
|
127
|
+
))}
|
|
128
|
+
</GalleryRow>
|
|
129
|
+
) : null;
|
|
130
|
+
|
|
131
|
+
const hasCaption = Boolean(caption);
|
|
132
|
+
const hasWrapper = Boolean(framed || hasCaption || hasGallery);
|
|
133
|
+
const wrapperContent = hasGallery ? gallery : images;
|
|
134
|
+
|
|
69
135
|
return (
|
|
70
136
|
<>
|
|
71
137
|
{lightboxImage ? (
|
|
@@ -76,39 +142,80 @@ export function Image(props: ImageProps): JSX.Element {
|
|
|
76
142
|
tabIndex={0}
|
|
77
143
|
>
|
|
78
144
|
<Overlay style={lightboxOverlayStyles} />
|
|
79
|
-
<
|
|
145
|
+
<LightboxContent>
|
|
146
|
+
<CloseButton variant="secondary" aria-label="Close image" onClick={handleCloseLightbox}>
|
|
147
|
+
<CloseIcon />
|
|
148
|
+
</CloseButton>
|
|
149
|
+
<Image src={lightboxImage} alt={alt} />
|
|
150
|
+
</LightboxContent>
|
|
80
151
|
</LightboxContainer>
|
|
81
152
|
) : null}
|
|
82
|
-
{
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
width={width}
|
|
88
|
-
height={height}
|
|
89
|
-
style={combinedStyles}
|
|
90
|
-
onClick={() => handleImageClick(src)}
|
|
91
|
-
/>
|
|
153
|
+
{hasWrapper ? (
|
|
154
|
+
<ImageFrame data-component-name="Image/Image" $framed={framed} $gallery={hasGallery}>
|
|
155
|
+
{wrapperContent}
|
|
156
|
+
{hasCaption ? <ImageCaption>{caption}</ImageCaption> : null}
|
|
157
|
+
</ImageFrame>
|
|
92
158
|
) : (
|
|
93
|
-
|
|
94
|
-
<ColorModeAwareImage
|
|
95
|
-
key={key}
|
|
96
|
-
$colorMode={key}
|
|
97
|
-
src={value}
|
|
98
|
-
alt={alt}
|
|
99
|
-
className={className}
|
|
100
|
-
width={width}
|
|
101
|
-
height={height}
|
|
102
|
-
$withLightbox={withLightbox}
|
|
103
|
-
style={combinedStyles}
|
|
104
|
-
onClick={() => handleImageClick(value)}
|
|
105
|
-
/>
|
|
106
|
-
))
|
|
159
|
+
images
|
|
107
160
|
)}
|
|
108
161
|
</>
|
|
109
162
|
);
|
|
110
163
|
}
|
|
111
164
|
|
|
165
|
+
const ImageFrame = styled.figure<{ $framed?: boolean; $gallery?: boolean }>`
|
|
166
|
+
display: ${({ $gallery }) => ($gallery ? 'block' : 'inline-block')};
|
|
167
|
+
margin: 0;
|
|
168
|
+
${({ $gallery }) => ($gallery ? 'width: 100%;' : '')}
|
|
169
|
+
max-width: 100%;
|
|
170
|
+
|
|
171
|
+
${({ $framed }) =>
|
|
172
|
+
$framed &&
|
|
173
|
+
css`
|
|
174
|
+
padding: var(--image-frame-padding);
|
|
175
|
+
border: var(--border-width) var(--border-style) var(--image-frame-border-color);
|
|
176
|
+
border-radius: var(--image-frame-border-radius);
|
|
177
|
+
background-color: var(--image-frame-bg-color);
|
|
178
|
+
`}
|
|
179
|
+
|
|
180
|
+
> img {
|
|
181
|
+
display: block;
|
|
182
|
+
max-width: 100%;
|
|
183
|
+
height: auto;
|
|
184
|
+
background: transparent center / cover no-repeat;
|
|
185
|
+
|
|
186
|
+
${({ $framed }) =>
|
|
187
|
+
$framed &&
|
|
188
|
+
css`
|
|
189
|
+
border-radius: var(--image-frame-image-border-radius);
|
|
190
|
+
`}
|
|
191
|
+
}
|
|
192
|
+
`;
|
|
193
|
+
|
|
194
|
+
const GalleryRow = styled.div`
|
|
195
|
+
display: flex;
|
|
196
|
+
align-items: stretch;
|
|
197
|
+
overflow: hidden;
|
|
198
|
+
border-radius: var(--image-gallery-border-radius);
|
|
199
|
+
|
|
200
|
+
img {
|
|
201
|
+
flex: 1 1 0;
|
|
202
|
+
min-width: 0;
|
|
203
|
+
width: 100%;
|
|
204
|
+
object-fit: cover;
|
|
205
|
+
border-radius: 0;
|
|
206
|
+
background: var(--image-gallery-image-bg-color) 50% / cover no-repeat;
|
|
207
|
+
}
|
|
208
|
+
`;
|
|
209
|
+
|
|
210
|
+
const ImageCaption = styled.figcaption`
|
|
211
|
+
padding: var(--image-caption-padding);
|
|
212
|
+
color: var(--image-caption-text-color);
|
|
213
|
+
font-size: var(--image-caption-font-size);
|
|
214
|
+
line-height: var(--image-caption-line-height);
|
|
215
|
+
font-weight: var(--image-caption-font-weight);
|
|
216
|
+
text-align: center;
|
|
217
|
+
`;
|
|
218
|
+
|
|
112
219
|
const ColorModeAwareImage = styled.img<{ $colorMode: string; $withLightbox?: boolean }>`
|
|
113
220
|
html:not(.${(props) => props.$colorMode}) && {
|
|
114
221
|
display: none;
|
|
@@ -121,7 +228,7 @@ const ColorModeAwareImage = styled.img<{ $colorMode: string; $withLightbox?: boo
|
|
|
121
228
|
`;
|
|
122
229
|
|
|
123
230
|
const Overlay = styled.div`
|
|
124
|
-
background-color: var(--bg-color
|
|
231
|
+
background-color: var(--image-lightbox-overlay-bg-color);
|
|
125
232
|
grid-column: 1 / 2;
|
|
126
233
|
grid-row: 1 / 2;
|
|
127
234
|
height: 100%;
|
|
@@ -129,6 +236,33 @@ const Overlay = styled.div`
|
|
|
129
236
|
z-index: -1;
|
|
130
237
|
`;
|
|
131
238
|
|
|
239
|
+
const CloseButton = styled(Button)`
|
|
240
|
+
position: absolute;
|
|
241
|
+
top: 0;
|
|
242
|
+
left: 100%;
|
|
243
|
+
margin-left: var(--image-lightbox-close-offset);
|
|
244
|
+
width: var(--image-lightbox-close-size);
|
|
245
|
+
height: var(--image-lightbox-close-size);
|
|
246
|
+
border-radius: var(--image-lightbox-close-border-radius);
|
|
247
|
+
z-index: 1;
|
|
248
|
+
|
|
249
|
+
svg {
|
|
250
|
+
width: var(--image-lightbox-close-icon-size);
|
|
251
|
+
height: var(--image-lightbox-close-icon-size);
|
|
252
|
+
}
|
|
253
|
+
`;
|
|
254
|
+
|
|
255
|
+
const LightboxContent = styled.div`
|
|
256
|
+
position: relative;
|
|
257
|
+
grid-column: 1 / 2;
|
|
258
|
+
grid-row: 1 / 2;
|
|
259
|
+
margin: auto;
|
|
260
|
+
width: fit-content;
|
|
261
|
+
height: fit-content;
|
|
262
|
+
max-width: var(--image-lightbox-content-max-width);
|
|
263
|
+
max-height: var(--image-lightbox-content-max-height);
|
|
264
|
+
`;
|
|
265
|
+
|
|
132
266
|
const LightboxContainer = styled.div`
|
|
133
267
|
display: grid;
|
|
134
268
|
height: 100vh;
|
|
@@ -144,10 +278,13 @@ const LightboxContainer = styled.div`
|
|
|
144
278
|
|
|
145
279
|
img {
|
|
146
280
|
cursor: pointer;
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
281
|
+
display: block;
|
|
282
|
+
max-width: var(--image-lightbox-image-max-width);
|
|
283
|
+
max-height: var(--image-lightbox-image-max-height);
|
|
284
|
+
border-radius: var(--image-lightbox-image-border-radius);
|
|
285
|
+
background:
|
|
286
|
+
var(--image-lightbox-image-bg-placeholder) center / cover no-repeat,
|
|
287
|
+
var(--image-frame-bg-color);
|
|
288
|
+
box-shadow: var(--image-lightbox-image-shadow);
|
|
152
289
|
}
|
|
153
290
|
`;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { css } from 'styled-components';
|
|
2
|
+
|
|
3
|
+
export const image = css`
|
|
4
|
+
/* === Image === */
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @tokens Image frame
|
|
8
|
+
*/
|
|
9
|
+
--image-frame-padding: var(--spacing-xs);
|
|
10
|
+
--image-frame-border-color: var(--border-color-secondary);
|
|
11
|
+
--image-frame-border-radius: var(--border-radius-xxl);
|
|
12
|
+
--image-frame-bg-color: var(--bg-color-raised);
|
|
13
|
+
--image-frame-image-border-radius: var(--border-radius-lg);
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @tokens Image caption
|
|
17
|
+
*/
|
|
18
|
+
--image-caption-padding: var(--spacing-sm) var(--spacing-lg) var(--spacing-xxs) var(--spacing-lg);
|
|
19
|
+
--image-caption-text-color: var(--text-color-primary);
|
|
20
|
+
--image-caption-font-size: var(--font-size-base);
|
|
21
|
+
--image-caption-line-height: var(--line-height-base);
|
|
22
|
+
--image-caption-font-weight: var(--font-weight-regular);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @tokens Image gallery
|
|
26
|
+
*/
|
|
27
|
+
--image-gallery-border-radius: var(--border-radius-lg);
|
|
28
|
+
--image-gallery-image-bg-color: var(--bg-color-tonal);
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @tokens Image lightbox
|
|
32
|
+
*/
|
|
33
|
+
--image-lightbox-overlay-bg-color: var(--bg-color-modal-overlay);
|
|
34
|
+
--image-lightbox-content-max-width: 90%;
|
|
35
|
+
--image-lightbox-content-max-height: 90%;
|
|
36
|
+
|
|
37
|
+
--image-lightbox-image-max-width: min(
|
|
38
|
+
90vw,
|
|
39
|
+
calc(100vw - 2 * var(--image-lightbox-side-gutter))
|
|
40
|
+
);
|
|
41
|
+
--image-lightbox-image-max-height: 90vh;
|
|
42
|
+
--image-lightbox-image-border-radius: var(--border-radius-xl);
|
|
43
|
+
--image-lightbox-image-bg-placeholder: var(--bg-color-tonal);
|
|
44
|
+
--image-lightbox-image-shadow: var(--bg-raised-shadow);
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @tokens Image lightbox close button
|
|
48
|
+
*/
|
|
49
|
+
--image-lightbox-close-size: 40px;
|
|
50
|
+
--image-lightbox-close-icon-size: 18px;
|
|
51
|
+
--image-lightbox-close-offset: var(--spacing-base);
|
|
52
|
+
--image-lightbox-close-border-radius: var(--border-radius-lg);
|
|
53
|
+
--image-lightbox-side-gutter: calc(
|
|
54
|
+
var(--image-lightbox-close-size) + var(--image-lightbox-close-offset) + var(--spacing-sm)
|
|
55
|
+
);
|
|
56
|
+
`;
|
|
@@ -8,6 +8,7 @@ import { breadcrumbs } from '@redocly/theme/components/Breadcrumbs/variables';
|
|
|
8
8
|
import { tag } from '@redocly/theme/components/Tag/variables';
|
|
9
9
|
import { toc } from '@redocly/theme/components/TableOfContent/variables';
|
|
10
10
|
import { catalog } from '@redocly/theme/components/Catalog/variables';
|
|
11
|
+
import { image } from '@redocly/theme/components/Image/variables';
|
|
11
12
|
import { filter } from '@redocly/theme/components/Filter/variables';
|
|
12
13
|
import { catalogClassic } from '@redocly/theme/components/CatalogClassic/variables';
|
|
13
14
|
import { apiReferencePanels, responsePanelColors } from '@redocly/theme/components/Panel/variables';
|
|
@@ -1301,6 +1302,7 @@ export const styles = css<{ palette?: string }>`
|
|
|
1301
1302
|
${footer}
|
|
1302
1303
|
${headingsTypography}
|
|
1303
1304
|
${httpTag}
|
|
1305
|
+
${image}
|
|
1304
1306
|
${inputs}
|
|
1305
1307
|
${languagePicker}
|
|
1306
1308
|
${lastUpdated}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export type SecurityDetails = {
|
|
2
|
+
password?: string;
|
|
3
|
+
username?: string;
|
|
4
|
+
token?: {
|
|
5
|
+
token_type?: string;
|
|
6
|
+
access_token: string;
|
|
7
|
+
};
|
|
8
|
+
client_id?: string;
|
|
9
|
+
client_secret?: string;
|
|
10
|
+
scopes?: string[];
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type ConfigureInputHintAction = {
|
|
14
|
+
label: string;
|
|
15
|
+
action: () => void;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type ConfigureInputHint = {
|
|
19
|
+
title: string;
|
|
20
|
+
text: string;
|
|
21
|
+
actions?: ConfigureInputHintAction[];
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type ConfigureRequestValues = {
|
|
25
|
+
headers?: Record<string, string>;
|
|
26
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
27
|
+
body?: Record<string, any>;
|
|
28
|
+
query?: Record<string, string>;
|
|
29
|
+
path?: Record<string, string>;
|
|
30
|
+
cookie?: Record<string, string>;
|
|
31
|
+
security?: Record<string, SecurityDetails>;
|
|
32
|
+
envVariables?: Record<string, string>;
|
|
33
|
+
serverVariables?: Record<string, string>;
|
|
34
|
+
inputHints?: Record<string, ConfigureInputHint>;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type ConfigureServerRequestValues = {
|
|
38
|
+
[serverUrl: string]: ConfigureRequestValues;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type ConfigureReplayConfig =
|
|
42
|
+
| ConfigureRequestValues
|
|
43
|
+
| ConfigureServerRequestValues
|
|
44
|
+
| null
|
|
45
|
+
| undefined;
|
package/src/ext/configure.ts
CHANGED
|
@@ -1,32 +1,12 @@
|
|
|
1
1
|
import type { UserClaims, OpenAPIServer } from '@redocly/theme/core/types';
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
username?: string;
|
|
6
|
-
token?: {
|
|
7
|
-
token_type?: string;
|
|
8
|
-
access_token: string;
|
|
9
|
-
};
|
|
10
|
-
client_id?: string;
|
|
11
|
-
client_secret?: string;
|
|
12
|
-
scopes?: string[];
|
|
13
|
-
};
|
|
3
|
+
export * from '@redocly/theme/ext/configure-helpers';
|
|
4
|
+
export * from '@redocly/theme/ext/helpers/is-direct-configure-request-values';
|
|
14
5
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
query?: Record<string, string>;
|
|
20
|
-
path?: Record<string, string>;
|
|
21
|
-
cookie?: Record<string, string>;
|
|
22
|
-
security?: Record<string, SecurityDetails>;
|
|
23
|
-
envVariables?: Record<string, string>;
|
|
24
|
-
serverVariables?: Record<string, string>;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export type ConfigureServerRequestValues = {
|
|
28
|
-
[serverUrl: string]: ConfigureRequestValues;
|
|
29
|
-
};
|
|
6
|
+
import type {
|
|
7
|
+
ConfigureRequestValues,
|
|
8
|
+
ConfigureServerRequestValues,
|
|
9
|
+
} from '@redocly/theme/ext/configure-helpers';
|
|
30
10
|
|
|
31
11
|
type Configure = {
|
|
32
12
|
requestValues?: ConfigureRequestValues | ConfigureServerRequestValues;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ConfigureRequestValues,
|
|
3
|
+
ConfigureServerRequestValues,
|
|
4
|
+
} from '@redocly/theme/ext/configure-helpers';
|
|
5
|
+
|
|
6
|
+
const CONFIGURE_REQUEST_VALUE_KEYS = [
|
|
7
|
+
'headers',
|
|
8
|
+
'body',
|
|
9
|
+
'query',
|
|
10
|
+
'path',
|
|
11
|
+
'cookie',
|
|
12
|
+
'security',
|
|
13
|
+
'envVariables',
|
|
14
|
+
'serverVariables',
|
|
15
|
+
'inputHints',
|
|
16
|
+
] as const;
|
|
17
|
+
|
|
18
|
+
const CONFIGURE_REQUEST_VALUE_KEY_SET = new Set<string>(CONFIGURE_REQUEST_VALUE_KEYS);
|
|
19
|
+
|
|
20
|
+
function hasConfigureRequestValueKeys(value: object): boolean {
|
|
21
|
+
return CONFIGURE_REQUEST_VALUE_KEYS.some((key) => key in value);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Type guard that distinguishes a direct {@link ConfigureRequestValues} payload (request
|
|
26
|
+
* values that apply to every server) from a {@link ConfigureServerRequestValues} payload
|
|
27
|
+
* (request values keyed by server URL).
|
|
28
|
+
*
|
|
29
|
+
* A payload is treated as server-keyed when at least one top-level key is *not* a known
|
|
30
|
+
* request-value key (e.g. `headers`, `security`, `inputHints`) and its value looks like a
|
|
31
|
+
* nested {@link ConfigureRequestValues}. This keeps mixed shapes — e.g. server-keyed values
|
|
32
|
+
* alongside a top-level `inputHints` sibling — classified as server-keyed.
|
|
33
|
+
*
|
|
34
|
+
* @param value - The configure payload returned from `getReplayConfiguration`.
|
|
35
|
+
* @returns `true` when `value` is a direct {@link ConfigureRequestValues}, narrowing the type.
|
|
36
|
+
*/
|
|
37
|
+
export function isDirectConfigureRequestValues(
|
|
38
|
+
value: ConfigureRequestValues | ConfigureServerRequestValues,
|
|
39
|
+
): value is ConfigureRequestValues {
|
|
40
|
+
const hasServerKeyedValues = Object.entries(value).some(
|
|
41
|
+
([key, entry]) =>
|
|
42
|
+
!CONFIGURE_REQUEST_VALUE_KEY_SET.has(key) &&
|
|
43
|
+
entry != null &&
|
|
44
|
+
typeof entry === 'object' &&
|
|
45
|
+
hasConfigureRequestValueKeys(entry),
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
if (hasServerKeyedValues) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return hasConfigureRequestValueKeys(value);
|
|
53
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useEffect, useState, useCallback } from 'react';
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
ConfigureRequestValues,
|
|
5
|
-
ConfigureServerRequestValues,
|
|
3
|
+
import {
|
|
4
|
+
type ConfigureRequestValues,
|
|
5
|
+
type ConfigureServerRequestValues,
|
|
6
6
|
} from '@redocly/theme/ext/configure';
|
|
7
7
|
import type { UserClaims, OpenAPIServer, OpenAPIInfo } from '@redocly/theme/core/types';
|
|
8
8
|
|
package/src/markdoc/tags/img.ts
CHANGED
|
@@ -13,9 +13,20 @@ export const img: MarkdocSchemaWrapper = {
|
|
|
13
13
|
type: String,
|
|
14
14
|
resolver: 'imageSrcSet',
|
|
15
15
|
},
|
|
16
|
+
images: {
|
|
17
|
+
type: Array,
|
|
18
|
+
resolver: 'imageGallery',
|
|
19
|
+
},
|
|
16
20
|
alt: {
|
|
17
21
|
type: String,
|
|
18
22
|
},
|
|
23
|
+
caption: {
|
|
24
|
+
type: String,
|
|
25
|
+
},
|
|
26
|
+
framed: {
|
|
27
|
+
type: Boolean,
|
|
28
|
+
default: false,
|
|
29
|
+
},
|
|
19
30
|
withLightbox: {
|
|
20
31
|
type: Boolean,
|
|
21
32
|
default: false,
|
|
@@ -44,8 +55,31 @@ export const img: MarkdocSchemaWrapper = {
|
|
|
44
55
|
},
|
|
45
56
|
},
|
|
46
57
|
validate: (node) => {
|
|
47
|
-
|
|
48
|
-
|
|
58
|
+
const { src, srcSet, images } = node.attributes;
|
|
59
|
+
const hasGallery = Array.isArray(images) && images.length > 0;
|
|
60
|
+
if (!src && !srcSet && !hasGallery) {
|
|
61
|
+
return [{ id: '', message: 'src, srcSet, or images is required', level: 'error' }];
|
|
62
|
+
}
|
|
63
|
+
if (hasGallery && (src || srcSet)) {
|
|
64
|
+
return [
|
|
65
|
+
{
|
|
66
|
+
id: 'invalid-img-source-combination',
|
|
67
|
+
message: 'images cannot be used together with src or srcSet',
|
|
68
|
+
level: 'error',
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
if (src && srcSet) {
|
|
73
|
+
return [
|
|
74
|
+
{
|
|
75
|
+
id: 'invalid-img-source-combination',
|
|
76
|
+
message: 'src cannot be used together with srcSet',
|
|
77
|
+
level: 'error',
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
}
|
|
81
|
+
if (Array.isArray(images) && images.length > 3) {
|
|
82
|
+
return [{ id: '', message: 'images supports a maximum of 3 items', level: 'error' }];
|
|
49
83
|
}
|
|
50
84
|
return [];
|
|
51
85
|
},
|