@redocly/theme 0.46.5 → 0.47.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.
@@ -1,7 +1,12 @@
1
+ import React from 'react';
1
2
  export type ImageProps = {
2
3
  src?: string;
3
4
  srcSet?: string;
4
5
  alt?: string;
5
6
  className?: string;
7
+ width?: string | number;
8
+ height?: string | number;
9
+ border?: string;
10
+ style?: React.CSSProperties | string;
6
11
  };
7
12
  export declare function Image(props: ImageProps): JSX.Element;
@@ -8,11 +8,12 @@ const react_1 = __importDefault(require("react"));
8
8
  const styled_components_1 = __importDefault(require("styled-components"));
9
9
  const utils_1 = require("../../core/utils");
10
10
  function Image(props) {
11
- const { src, srcSet, alt, className } = props;
11
+ const { src, srcSet, alt, className, width, height, border, style } = props;
12
12
  const parsedSourceSetMap = react_1.default.useMemo(() => {
13
13
  return srcSet ? (0, utils_1.parseSrcSet)(srcSet) : new Map();
14
14
  }, [srcSet]);
15
- return (react_1.default.createElement(react_1.default.Fragment, null, src ? (react_1.default.createElement("img", { src: src, alt: alt, className: className })) : (Array.from(parsedSourceSetMap).map(([key, value]) => (react_1.default.createElement(ColorModeAwareImage, { key: key, colorMode: key, src: value, alt: alt, className: className }))))));
15
+ const combinedStyle = Object.assign(Object.assign({}, (border && { border })), (typeof style === 'string' ? { cssText: style } : style));
16
+ return (react_1.default.createElement(react_1.default.Fragment, null, src ? (react_1.default.createElement("img", { src: src, alt: alt, className: className, width: width, height: height, style: combinedStyle })) : (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, style: combinedStyle }))))));
16
17
  }
17
18
  const ColorModeAwareImage = styled_components_1.default.img `
18
19
  html:not(.${(props) => props.colorMode}) && {
@@ -30,7 +30,7 @@ function SearchAiResponse(props) {
30
30
  resources.length,
31
31
  " ",
32
32
  translate('search.ai.resourcesFound', 'resources found')),
33
- react_1.default.createElement(ResourceTags, null, resources.map((resource, idx) => (react_1.default.createElement(Link_1.Link, { key: idx, to: resource.url },
33
+ react_1.default.createElement(ResourceTags, null, resources.map((resource, idx) => (react_1.default.createElement(Link_1.Link, { key: idx, to: resource.url, target: "_blank" },
34
34
  react_1.default.createElement(ResourceTag, { borderless: true, icon: react_1.default.createElement(DocumentIcon_1.DocumentIcon, { color: "--search-ai-resource-tag-icon-color" }) }, resource.title))))))) : null)));
35
35
  }
36
36
  const ResponseWrapper = styled_components_1.default.div `
@@ -107,17 +107,19 @@ function SearchDialog({ onClose, className }) {
107
107
  react_1.default.createElement(CloseIcon_1.CloseIcon, { onClick: () => setProduct(undefined), color: "--icon-color-additional" })))),
108
108
  react_1.default.createElement(SearchInput_1.SearchInput, { value: query, onChange: setQuery, placeholder: mode === 'search'
109
109
  ? translate('search.label', 'Search docs...')
110
- : translate('search.ai.label', 'Ask a follow up question'), isLoading: isSearchLoading, showReturnButton: mode === 'ai-dialog', onReturn: () => setMode('search'), onSubmit: mode === 'ai-dialog'
110
+ : translate('search.ai.label', 'Ask AI assistant'), isLoading: isSearchLoading, showReturnButton: mode === 'ai-dialog', onReturn: () => setMode('search'), onSubmit: mode === 'ai-dialog'
111
111
  ? () => {
112
112
  setQuery('');
113
113
  aiSearch.askQuestion(query);
114
114
  }
115
115
  : undefined, "data-translation-key": mode === 'search' ? 'search.label' : 'search.ai.label' }),
116
116
  showHeaderButtons && (react_1.default.createElement(SearchHeaderButtons, null,
117
- showAiSearchButton ? (react_1.default.createElement(SearchAiButton, { disabled: !query.trim(), icon: react_1.default.createElement(AiStarsIcon_1.AiStarsIcon, null), onClick: () => {
117
+ showAiSearchButton ? (react_1.default.createElement(SearchAiButton, { icon: react_1.default.createElement(AiStarsIcon_1.AiStarsIcon, null), onClick: () => {
118
118
  setMode('ai-dialog');
119
- setQuery('');
120
- aiSearch.askQuestion(query);
119
+ if (query.trim()) {
120
+ setQuery('');
121
+ aiSearch.askQuestion(query);
122
+ }
121
123
  } }, translate('search.aiButton', 'Search with AI'))) : null,
122
124
  showSearchFilterButton && (react_1.default.createElement(SearchFilterToggleButton, { icon: react_1.default.createElement(SettingsIcon_1.SettingsIcon, null), onClick: onFilterToggle }))))),
123
125
  react_1.default.createElement(SearchDialogBody, null, mode === 'search' ? (react_1.default.createElement(react_1.default.Fragment, null,
@@ -214,6 +214,7 @@ const themeColors = (0, styled_components_1.css) `
214
214
 
215
215
  --color-black: #000000;
216
216
  --color-white: #ffffff;
217
+ --color-static-white: #ffffff;
217
218
 
218
219
  --color-primary-bg: var(--color-blueberry-1);
219
220
  --color-primary-bg-hover: var(--color-blueberry-2);
@@ -331,7 +332,7 @@ const typography = (0, styled_components_1.css) `
331
332
  --text-color-description: var(--color-warm-grey-7); // Caption, Description, Icon
332
333
  --text-color-helper: var(--color-warm-grey-6);
333
334
  --text-color-disabled: var(--color-warm-grey-5);
334
- --text-color-on-color: var(--color-warm-grey-1);
335
+ --text-color-on-color: var(--color-static-white);
335
336
  --text-color-inverse: var(--color-white);
336
337
 
337
338
  /**
@@ -677,7 +678,7 @@ const apiReferenceDocs = (0, styled_components_1.css) `
677
678
  * @presenter Color
678
679
  */
679
680
 
680
- --schema-recursive-text-color: var(--text-color-on-color); // @presenter Color
681
+ --schema-recursive-text-color: var(--color-warm-grey-1); // @presenter Color
681
682
  --schema-recursive-bg-color: var(--color-persian-green-6); // @presenter Color
682
683
  --schema-recursive-border-color: var(--schema-recursive-bg-color); // @presenter Color
683
684
 
@@ -781,7 +782,7 @@ const badges = (0, styled_components_1.css) `
781
782
  * @tokens Deprecated Badge
782
783
  */
783
784
 
784
- --badge-deprecated-text-color: var(--text-color-on-color); // @presenter Color
785
+ --badge-deprecated-text-color: var(--color-warm-grey-1); // @presenter Color
785
786
  --badge-deprecated-bg-color: var(--color-warning-base); // @presenter Color
786
787
  --badge-deprecated-border-radius: var(--border-radius); // @presenter BorderRadius
787
788
 
@@ -949,18 +950,30 @@ const pages = (0, styled_components_1.css) `
949
950
 
950
951
  // @tokens End
951
952
  `;
953
+ // //
954
+ // --color-raspberry-1: #612241;
955
+ // --color-raspberry-2: #77214c;
956
+ // --color-raspberry-3: #901d56;
957
+ // --color-raspberry-4: #b3185e;
958
+ // --color-raspberry-5: #d6236a;
959
+ // --color-raspberry-6: #f9316d;
960
+ // --color-raspberry-7: #fb6382;
961
+ // --color-raspberry-8: #fd838f;
962
+ // --color-raspberry-9: #feacad;
963
+ // --color-raspberry-10: #fed9d5;
964
+ // --color-raspberry-11: #fef0ef;
952
965
  const error = (0, styled_components_1.css) `
953
966
  --error-bubble-padding: var(--spacing-sm);
954
967
  --error-bubble-gap: var(--spacing-xxs);
955
968
  --error-bubble-font-family: var(--font-family-base);
956
969
  --error-bubble-font-size: var(--font-size-base);
957
970
  --error-bubble-z-index: var(--z-index-popover);
958
- --error-bubble-bg-color: var(--color-raspberry-1);
959
- --error-bubble-bg-color-hover: var(--color-raspberry-2);
960
- --error-bubble-bg-color-pressed: var(--color-raspberry-3);
961
- --error-bubble-content-color: var(--color-raspberry-6);
962
- --error-bubble-content-color-hover: var(--color-raspberry-6);
963
- --error-bubble-content-color-pressed: var(--color-raspberry-6);
971
+ --error-bubble-bg-color: #612241;
972
+ --error-bubble-bg-color-hover: #77214c;
973
+ --error-bubble-bg-color-pressed: #901d56;
974
+ --error-bubble-content-color: #f9316d;
975
+ --error-bubble-content-color-hover: #f9316d;
976
+ --error-bubble-content-color-pressed: #f9316d;
964
977
 
965
978
 
966
979
  --detailed-error-overlay-bg-color: #4f4f4f;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { type ImageProps } from '../../../components/Image/Image';
3
+ type MarkdocImageProps = React.PropsWithChildren<ImageProps> & {
4
+ align?: 'left' | 'right' | 'center' | 'justify' | 'initial' | 'inherit';
5
+ };
6
+ export declare function Image(props: MarkdocImageProps): React.JSX.Element;
7
+ export {};
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.Image = Image;
18
+ const react_1 = __importDefault(require("react"));
19
+ const styled_components_1 = __importDefault(require("styled-components"));
20
+ const Image_1 = require("../../../components/Image/Image");
21
+ function Image(props) {
22
+ const { align } = props, rest = __rest(props, ["align"]);
23
+ return align ? (react_1.default.createElement(ImageWrapper, { align: align },
24
+ react_1.default.createElement(Image_1.Image, Object.assign({}, rest)))) : (react_1.default.createElement(Image_1.Image, Object.assign({}, rest)));
25
+ }
26
+ const ImageWrapper = styled_components_1.default.div `
27
+ text-align: ${(props) => props.align || 'initial'};
28
+
29
+ img {
30
+ display: block;
31
+ ${(props) => {
32
+ switch (props.align) {
33
+ case 'left':
34
+ return 'margin-right: auto; margin-left: 0;';
35
+ case 'right':
36
+ return 'margin-left: auto; margin-right: 0;';
37
+ case 'center':
38
+ return 'margin-left: auto; margin-right: auto;';
39
+ default:
40
+ return '';
41
+ }
42
+ }}
43
+ }
44
+ `;
45
+ //# sourceMappingURL=Image.js.map
@@ -11,3 +11,4 @@ export * from '../../markdoc/components/Cards/Cards';
11
11
  export * from '../../markdoc/components/Cards/Card';
12
12
  export * from '../../markdoc/components/Cards/CardIcon';
13
13
  export * from '../../markdoc/components/Cards/CardImage';
14
+ export * from '../../markdoc/components/Image/Image';
@@ -27,4 +27,5 @@ __exportStar(require("../../markdoc/components/Cards/Cards"), exports);
27
27
  __exportStar(require("../../markdoc/components/Cards/Card"), exports);
28
28
  __exportStar(require("../../markdoc/components/Cards/CardIcon"), exports);
29
29
  __exportStar(require("../../markdoc/components/Cards/CardImage"), exports);
30
+ __exportStar(require("../../markdoc/components/Image/Image"), exports);
30
31
  //# sourceMappingURL=default.js.map
@@ -47,6 +47,7 @@ const code_snippet_1 = require("../markdoc/tags/code-snippet");
47
47
  const inline_svg_1 = require("../markdoc/tags/inline-svg");
48
48
  const cards_1 = require("../markdoc/tags/cards");
49
49
  const card_1 = require("../markdoc/tags/card");
50
+ const img_1 = require("../markdoc/tags/img");
50
51
  exports.tags = {
51
52
  [admonition_1.admonition.tagName]: admonition_1.admonition.schema,
52
53
  [debug_1.debug.tagName]: debug_1.debug.schema,
@@ -59,5 +60,6 @@ exports.tags = {
59
60
  [inline_svg_1.inlineSvg.tagName]: inline_svg_1.inlineSvg.schema,
60
61
  [cards_1.cards.tagName]: cards_1.cards.schema,
61
62
  [card_1.card.tagName]: card_1.card.schema,
63
+ [img_1.img.tagName]: img_1.img.schema,
62
64
  };
63
65
  //# sourceMappingURL=default.js.map
@@ -0,0 +1,2 @@
1
+ import type { MarkdocSchemaWrapper } from '../../markdoc/tags/types';
2
+ export declare const img: MarkdocSchemaWrapper;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.img = void 0;
4
+ exports.img = {
5
+ schema: {
6
+ render: 'Image',
7
+ attributes: {
8
+ src: {
9
+ type: String,
10
+ resolver: 'imageSrc',
11
+ },
12
+ srcSet: {
13
+ type: String,
14
+ resolver: 'imageSrcSet',
15
+ },
16
+ alt: {
17
+ type: String,
18
+ },
19
+ className: {
20
+ type: String,
21
+ },
22
+ width: {
23
+ type: [String, Number],
24
+ },
25
+ height: {
26
+ type: [String, Number],
27
+ },
28
+ align: {
29
+ type: String,
30
+ matches: ['left', 'right', 'center', 'justify', 'initial', 'inherit'],
31
+ },
32
+ border: {
33
+ type: String,
34
+ },
35
+ style: {
36
+ type: [Object, String],
37
+ },
38
+ },
39
+ validate: (node) => {
40
+ if (!node.attributes.src && !node.attributes.srcSet) {
41
+ return [{ id: '', message: 'src or srcSet is required', level: 'error' }];
42
+ }
43
+ return [];
44
+ },
45
+ },
46
+ tagName: 'img',
47
+ };
48
+ //# sourceMappingURL=img.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/theme",
3
- "version": "0.46.5",
3
+ "version": "0.47.0",
4
4
  "description": "Shared UI components lib",
5
5
  "keywords": [
6
6
  "theme",
@@ -79,7 +79,7 @@
79
79
  "timeago.js": "4.0.2",
80
80
  "i18next": "22.4.15",
81
81
  "nprogress": "0.2.0",
82
- "@redocly/config": "0.19.3"
82
+ "@redocly/config": "0.19.4"
83
83
  },
84
84
  "scripts": {
85
85
  "watch": "tsc -p tsconfig.build.json && (concurrently \"tsc -w -p tsconfig.build.json\" \"tsc-alias -w -p tsconfig.build.json\")",
@@ -8,19 +8,35 @@ export type ImageProps = {
8
8
  srcSet?: string;
9
9
  alt?: string;
10
10
  className?: string;
11
+ width?: string | number;
12
+ height?: string | number;
13
+ border?: string;
14
+ style?: React.CSSProperties | string;
11
15
  };
12
16
 
13
17
  export function Image(props: ImageProps): JSX.Element {
14
- const { src, srcSet, alt, className } = props;
18
+ const { src, srcSet, alt, className, width, height, border, style } = props;
15
19
 
16
20
  const parsedSourceSetMap = React.useMemo(() => {
17
21
  return srcSet ? parseSrcSet(srcSet) : new Map();
18
22
  }, [srcSet]);
19
23
 
24
+ const combinedStyle: React.CSSProperties = {
25
+ ...(border && { border }),
26
+ ...(typeof style === 'string' ? { cssText: style } : style),
27
+ };
28
+
20
29
  return (
21
30
  <>
22
31
  {src ? (
23
- <img src={src} alt={alt} className={className} />
32
+ <img
33
+ src={src}
34
+ alt={alt}
35
+ className={className}
36
+ width={width}
37
+ height={height}
38
+ style={combinedStyle}
39
+ />
24
40
  ) : (
25
41
  Array.from(parsedSourceSetMap).map(([key, value]) => (
26
42
  <ColorModeAwareImage
@@ -29,6 +45,9 @@ export function Image(props: ImageProps): JSX.Element {
29
45
  src={value}
30
46
  alt={alt}
31
47
  className={className}
48
+ width={width}
49
+ height={height}
50
+ style={combinedStyle}
32
51
  />
33
52
  ))
34
53
  )}
@@ -52,7 +52,7 @@ export function SearchAiResponse(props: SearchAiResponseProps): JSX.Element {
52
52
  </ResourcesTitle>
53
53
  <ResourceTags>
54
54
  {resources.map((resource, idx) => (
55
- <Link key={idx} to={resource.url}>
55
+ <Link key={idx} to={resource.url} target="_blank">
56
56
  <ResourceTag
57
57
  borderless
58
58
  icon={<DocumentIcon color="--search-ai-resource-tag-icon-color" />}
@@ -124,7 +124,7 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
124
124
  placeholder={
125
125
  mode === 'search'
126
126
  ? translate('search.label', 'Search docs...')
127
- : translate('search.ai.label', 'Ask a follow up question')
127
+ : translate('search.ai.label', 'Ask AI assistant')
128
128
  }
129
129
  isLoading={isSearchLoading}
130
130
  showReturnButton={mode === 'ai-dialog'}
@@ -143,12 +143,13 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
143
143
  <SearchHeaderButtons>
144
144
  {showAiSearchButton ? (
145
145
  <SearchAiButton
146
- disabled={!query.trim()}
147
146
  icon={<AiStarsIcon />}
148
147
  onClick={() => {
149
148
  setMode('ai-dialog');
150
- setQuery('');
151
- aiSearch.askQuestion(query);
149
+ if (query.trim()) {
150
+ setQuery('');
151
+ aiSearch.askQuestion(query);
152
+ }
152
153
  }}
153
154
  >
154
155
  {translate('search.aiButton', 'Search with AI')}
@@ -213,6 +213,7 @@ const themeColors = css`
213
213
 
214
214
  --color-black: #000000;
215
215
  --color-white: #ffffff;
216
+ --color-static-white: #ffffff;
216
217
 
217
218
  --color-primary-bg: var(--color-blueberry-1);
218
219
  --color-primary-bg-hover: var(--color-blueberry-2);
@@ -331,7 +332,7 @@ const typography = css`
331
332
  --text-color-description: var(--color-warm-grey-7); // Caption, Description, Icon
332
333
  --text-color-helper: var(--color-warm-grey-6);
333
334
  --text-color-disabled: var(--color-warm-grey-5);
334
- --text-color-on-color: var(--color-warm-grey-1);
335
+ --text-color-on-color: var(--color-static-white);
335
336
  --text-color-inverse: var(--color-white);
336
337
 
337
338
  /**
@@ -683,7 +684,7 @@ const apiReferenceDocs = css`
683
684
  * @presenter Color
684
685
  */
685
686
 
686
- --schema-recursive-text-color: var(--text-color-on-color); // @presenter Color
687
+ --schema-recursive-text-color: var(--color-warm-grey-1); // @presenter Color
687
688
  --schema-recursive-bg-color: var(--color-persian-green-6); // @presenter Color
688
689
  --schema-recursive-border-color: var(--schema-recursive-bg-color); // @presenter Color
689
690
 
@@ -788,7 +789,7 @@ const badges = css`
788
789
  * @tokens Deprecated Badge
789
790
  */
790
791
 
791
- --badge-deprecated-text-color: var(--text-color-on-color); // @presenter Color
792
+ --badge-deprecated-text-color: var(--color-warm-grey-1); // @presenter Color
792
793
  --badge-deprecated-bg-color: var(--color-warning-base); // @presenter Color
793
794
  --badge-deprecated-border-radius: var(--border-radius); // @presenter BorderRadius
794
795
 
@@ -961,19 +962,30 @@ const pages = css`
961
962
 
962
963
  // @tokens End
963
964
  `;
964
-
965
+ // //
966
+ // --color-raspberry-1: #612241;
967
+ // --color-raspberry-2: #77214c;
968
+ // --color-raspberry-3: #901d56;
969
+ // --color-raspberry-4: #b3185e;
970
+ // --color-raspberry-5: #d6236a;
971
+ // --color-raspberry-6: #f9316d;
972
+ // --color-raspberry-7: #fb6382;
973
+ // --color-raspberry-8: #fd838f;
974
+ // --color-raspberry-9: #feacad;
975
+ // --color-raspberry-10: #fed9d5;
976
+ // --color-raspberry-11: #fef0ef;
965
977
  const error = css`
966
978
  --error-bubble-padding: var(--spacing-sm);
967
979
  --error-bubble-gap: var(--spacing-xxs);
968
980
  --error-bubble-font-family: var(--font-family-base);
969
981
  --error-bubble-font-size: var(--font-size-base);
970
982
  --error-bubble-z-index: var(--z-index-popover);
971
- --error-bubble-bg-color: var(--color-raspberry-1);
972
- --error-bubble-bg-color-hover: var(--color-raspberry-2);
973
- --error-bubble-bg-color-pressed: var(--color-raspberry-3);
974
- --error-bubble-content-color: var(--color-raspberry-6);
975
- --error-bubble-content-color-hover: var(--color-raspberry-6);
976
- --error-bubble-content-color-pressed: var(--color-raspberry-6);
983
+ --error-bubble-bg-color: #612241;
984
+ --error-bubble-bg-color-hover: #77214c;
985
+ --error-bubble-bg-color-pressed: #901d56;
986
+ --error-bubble-content-color: #f9316d;
987
+ --error-bubble-content-color-hover: #f9316d;
988
+ --error-bubble-content-color-pressed: #f9316d;
977
989
 
978
990
 
979
991
  --detailed-error-overlay-bg-color: #4f4f4f;
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import { Image as ImageComponent, type ImageProps } from '@redocly/theme/components/Image/Image';
5
+
6
+ type MarkdocImageProps = React.PropsWithChildren<ImageProps> & {
7
+ align?: 'left' | 'right' | 'center' | 'justify' | 'initial' | 'inherit';
8
+ };
9
+ export function Image(props: MarkdocImageProps) {
10
+ const { align, ...rest } = props;
11
+ return align ? (
12
+ <ImageWrapper align={align}>
13
+ <ImageComponent {...rest} />
14
+ </ImageWrapper>
15
+ ) : (
16
+ <ImageComponent {...rest} />
17
+ );
18
+ }
19
+
20
+ const ImageWrapper = styled.div<{ align?: MarkdocImageProps['align'] }>`
21
+ text-align: ${(props) => props.align || 'initial'};
22
+
23
+ img {
24
+ display: block;
25
+ ${(props) => {
26
+ switch (props.align) {
27
+ case 'left':
28
+ return 'margin-right: auto; margin-left: 0;';
29
+ case 'right':
30
+ return 'margin-left: auto; margin-right: 0;';
31
+ case 'center':
32
+ return 'margin-left: auto; margin-right: auto;';
33
+ default:
34
+ return '';
35
+ }
36
+ }}
37
+ }
38
+ `;
@@ -11,3 +11,4 @@ export * from '@redocly/theme/markdoc/components/Cards/Cards';
11
11
  export * from '@redocly/theme/markdoc/components/Cards/Card';
12
12
  export * from '@redocly/theme/markdoc/components/Cards/CardIcon';
13
13
  export * from '@redocly/theme/markdoc/components/Cards/CardImage';
14
+ export * from '@redocly/theme/markdoc/components/Image/Image';
@@ -18,6 +18,7 @@ import { codeSnippet } from '@redocly/theme/markdoc/tags/code-snippet';
18
18
  import { inlineSvg } from '@redocly/theme/markdoc/tags/inline-svg';
19
19
  import { cards } from '@redocly/theme/markdoc/tags/cards';
20
20
  import { card } from '@redocly/theme/markdoc/tags/card';
21
+ import { img } from '@redocly/theme/markdoc/tags/img';
21
22
 
22
23
  export const tags = {
23
24
  [admonition.tagName]: admonition.schema,
@@ -31,4 +32,5 @@ export const tags = {
31
32
  [inlineSvg.tagName]: inlineSvg.schema,
32
33
  [cards.tagName]: cards.schema,
33
34
  [card.tagName]: card.schema,
35
+ [img.tagName]: img.schema,
34
36
  };
@@ -0,0 +1,46 @@
1
+ import type { MarkdocSchemaWrapper } from '@redocly/theme/markdoc/tags/types';
2
+
3
+ export const img: MarkdocSchemaWrapper = {
4
+ schema: {
5
+ render: 'Image',
6
+ attributes: {
7
+ src: {
8
+ type: String,
9
+ resolver: 'imageSrc',
10
+ },
11
+ srcSet: {
12
+ type: String,
13
+ resolver: 'imageSrcSet',
14
+ },
15
+ alt: {
16
+ type: String,
17
+ },
18
+ className: {
19
+ type: String,
20
+ },
21
+ width: {
22
+ type: [String, Number],
23
+ },
24
+ height: {
25
+ type: [String, Number],
26
+ },
27
+ align: {
28
+ type: String,
29
+ matches: ['left', 'right', 'center', 'justify', 'initial', 'inherit'],
30
+ },
31
+ border: {
32
+ type: String,
33
+ },
34
+ style: {
35
+ type: [Object, String],
36
+ },
37
+ },
38
+ validate: (node) => {
39
+ if (!node.attributes.src && !node.attributes.srcSet) {
40
+ return [{ id: '', message: 'src or srcSet is required', level: 'error' }];
41
+ }
42
+ return [];
43
+ },
44
+ },
45
+ tagName: 'img',
46
+ };