@redocly/theme 0.46.4 → 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}) && {
@@ -17,14 +17,16 @@ function ProductPicker() {
17
17
  const { currentProduct, products, setProduct } = (0, hooks_1.useProductPicker)();
18
18
  const { useTranslate } = (0, hooks_1.useThemeHooks)();
19
19
  const { translate } = useTranslate();
20
- const productComponents = products.map((product) => ({
21
- content: react_1.default.createElement(Product_1.Product, { product: product }),
22
- suffix: currentProduct === product && react_1.default.createElement(CheckmarkIcon_1.CheckmarkIcon, null),
23
- onAction: () => {
24
- setProduct(product);
25
- },
26
- active: product === currentProduct,
27
- }));
20
+ const productComponents = products.map((product) => {
21
+ return {
22
+ content: react_1.default.createElement(Product_1.Product, { product: product }),
23
+ suffix: product.slug === (currentProduct === null || currentProduct === void 0 ? void 0 : currentProduct.slug) && react_1.default.createElement(CheckmarkIcon_1.CheckmarkIcon, null),
24
+ onAction: () => {
25
+ setProduct(product);
26
+ },
27
+ active: product.slug === (currentProduct === null || currentProduct === void 0 ? void 0 : currentProduct.slug),
28
+ };
29
+ });
28
30
  return products.length ? (react_1.default.createElement(ProductDropdown, { withArrow: true, trigger: react_1.default.createElement(Button_1.Button, { variant: "ghost" }, currentProduct ? (react_1.default.createElement(Product_1.Product, { product: currentProduct })) : (react_1.default.createElement("span", { "data-translation-key": "navbar.products" }, translate('navbar.products', 'Products')))), triggerEvent: "hover" },
29
31
  react_1.default.createElement(DropdownMenu_1.DropdownMenu, { items: productComponents }))) : null;
30
32
  }
@@ -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 `
@@ -68,9 +68,11 @@ function SearchDialog({ onClose, className }) {
68
68
  }
69
69
  };
70
70
  const mapItem = (item, index) => {
71
+ var _a;
71
72
  let itemProduct;
72
73
  if (!product && item.document.product) {
73
- const resolvedProduct = products.find((product) => { var _a; return product.slug.match(`/${(_a = item.document.product) === null || _a === void 0 ? void 0 : _a.folder}/`); });
74
+ const folder = (_a = item.document.product) === null || _a === void 0 ? void 0 : _a.folder;
75
+ const resolvedProduct = products.find((product) => product.slug.match(`/${folder.startsWith('./') ? folder.slice(2) : folder}/`));
74
76
  itemProduct = resolvedProduct
75
77
  ? { name: resolvedProduct.name, icon: resolvedProduct.icon }
76
78
  : undefined;
@@ -105,17 +107,19 @@ function SearchDialog({ onClose, className }) {
105
107
  react_1.default.createElement(CloseIcon_1.CloseIcon, { onClick: () => setProduct(undefined), color: "--icon-color-additional" })))),
106
108
  react_1.default.createElement(SearchInput_1.SearchInput, { value: query, onChange: setQuery, placeholder: mode === 'search'
107
109
  ? translate('search.label', 'Search docs...')
108
- : 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'
109
111
  ? () => {
110
112
  setQuery('');
111
113
  aiSearch.askQuestion(query);
112
114
  }
113
115
  : undefined, "data-translation-key": mode === 'search' ? 'search.label' : 'search.ai.label' }),
114
116
  showHeaderButtons && (react_1.default.createElement(SearchHeaderButtons, null,
115
- 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: () => {
116
118
  setMode('ai-dialog');
117
- setQuery('');
118
- aiSearch.askQuestion(query);
119
+ if (query.trim()) {
120
+ setQuery('');
121
+ aiSearch.askQuestion(query);
122
+ }
119
123
  } }, translate('search.aiButton', 'Search with AI'))) : null,
120
124
  showSearchFilterButton && (react_1.default.createElement(SearchFilterToggleButton, { icon: react_1.default.createElement(SettingsIcon_1.SettingsIcon, null), onClick: onFilterToggle }))))),
121
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.4",
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.2"
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
  )}
@@ -14,14 +14,16 @@ export function ProductPicker(): JSX.Element | null {
14
14
  const { useTranslate } = useThemeHooks();
15
15
  const { translate } = useTranslate();
16
16
 
17
- const productComponents = products.map((product) => ({
18
- content: <Product product={product} />,
19
- suffix: currentProduct === product && <CheckmarkIcon />,
20
- onAction: () => {
21
- setProduct(product);
22
- },
23
- active: product === currentProduct,
24
- }));
17
+ const productComponents = products.map((product) => {
18
+ return {
19
+ content: <Product product={product} />,
20
+ suffix: product.slug === currentProduct?.slug && <CheckmarkIcon />,
21
+ onAction: () => {
22
+ setProduct(product);
23
+ },
24
+ active: product.slug === currentProduct?.slug,
25
+ };
26
+ });
25
27
 
26
28
  return products.length ? (
27
29
  <ProductDropdown
@@ -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" />}
@@ -71,8 +71,9 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
71
71
  const mapItem = (item: SearchItemData, index: number) => {
72
72
  let itemProduct;
73
73
  if (!product && item.document.product) {
74
+ const folder = item.document.product?.folder;
74
75
  const resolvedProduct = products.find((product) =>
75
- product.slug.match(`/${item.document.product?.folder}/`),
76
+ product.slug.match(`/${folder.startsWith('./') ? folder.slice(2) : folder}/`),
76
77
  );
77
78
  itemProduct = resolvedProduct
78
79
  ? { name: resolvedProduct.name, icon: resolvedProduct.icon }
@@ -123,7 +124,7 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
123
124
  placeholder={
124
125
  mode === 'search'
125
126
  ? translate('search.label', 'Search docs...')
126
- : translate('search.ai.label', 'Ask a follow up question')
127
+ : translate('search.ai.label', 'Ask AI assistant')
127
128
  }
128
129
  isLoading={isSearchLoading}
129
130
  showReturnButton={mode === 'ai-dialog'}
@@ -142,12 +143,13 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
142
143
  <SearchHeaderButtons>
143
144
  {showAiSearchButton ? (
144
145
  <SearchAiButton
145
- disabled={!query.trim()}
146
146
  icon={<AiStarsIcon />}
147
147
  onClick={() => {
148
148
  setMode('ai-dialog');
149
- setQuery('');
150
- aiSearch.askQuestion(query);
149
+ if (query.trim()) {
150
+ setQuery('');
151
+ aiSearch.askQuestion(query);
152
+ }
151
153
  }}
152
154
  >
153
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
+ };