@redocly/theme 0.67.0-next.0 → 0.67.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/lib/components/Admonition/Admonition.js +9 -9
  2. package/lib/components/Badge/Badge.d.ts +1 -1
  3. package/lib/components/Badge/Badge.js +4 -4
  4. package/lib/components/Button/Button.d.ts +1 -1
  5. package/lib/components/Button/Button.js +16 -17
  6. package/lib/components/Buttons/AIAssistantButton.js +2 -0
  7. package/lib/components/Catalog/CatalogActionsRow.js +3 -1
  8. package/lib/components/Catalog/CatalogAvatar.d.ts +3 -1
  9. package/lib/components/Catalog/CatalogAvatar.js +3 -3
  10. package/lib/components/Catalog/CatalogCardView/CatalogCard.js +4 -4
  11. package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsNodeContent.js +7 -7
  12. package/lib/components/Catalog/CatalogEntity/CatalogEntityInfoBar.js +6 -6
  13. package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/CatalogEntityPropertyCard.js +2 -2
  14. package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityApiDescriptionRelations.js +4 -6
  15. package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityTeamRelations.js +3 -5
  16. package/lib/components/Catalog/CatalogEntityTypeIcon.js +15 -11
  17. package/lib/components/Catalog/CatalogEntityTypeTag.js +5 -5
  18. package/lib/components/Catalog/CatalogTableView/CatalogTableView.js +5 -3
  19. package/lib/components/CatalogClassic/CatalogClassic.d.ts +4 -2
  20. package/lib/components/CatalogClassic/CatalogClassic.js +3 -1
  21. package/lib/components/CodeBlock/CodeBlockContainer.js +16 -4
  22. package/lib/components/CodeBlock/CodeBlockControls.d.ts +2 -1
  23. package/lib/components/CodeBlock/CodeBlockControls.js +9 -7
  24. package/lib/components/CodeBlock/CodeBlockTabs.js +2 -2
  25. package/lib/components/Dropdown/Dropdown.js +6 -6
  26. package/lib/components/Dropdown/DropdownMenuItem.d.ts +1 -1
  27. package/lib/components/Feedback/Comment.js +3 -3
  28. package/lib/components/Feedback/Mood.js +3 -3
  29. package/lib/components/Filter/FilterContent.js +2 -2
  30. package/lib/components/Footer/Footer.js +2 -2
  31. package/lib/components/Footer/FooterColumn.js +2 -2
  32. package/lib/components/Footer/FooterItem.js +5 -5
  33. package/lib/components/Image/Image.js +2 -2
  34. package/lib/components/LastUpdated/LastUpdated.js +2 -2
  35. package/lib/components/Link/Link.d.ts +2 -19
  36. package/lib/components/Link/Link.js +2 -9
  37. package/lib/components/Loaders/Loading.js +2 -2
  38. package/lib/components/Loaders/SpinnerLoader.js +4 -4
  39. package/lib/components/Markdown/Markdown.d.ts +7 -10
  40. package/lib/components/Markdown/Markdown.js +6 -3
  41. package/lib/components/Marker/Marker.js +3 -3
  42. package/lib/components/Menu/MenuContainer.d.ts +2 -2
  43. package/lib/components/Menu/MenuContainer.js +9 -11
  44. package/lib/components/Menu/MenuItem.js +14 -14
  45. package/lib/components/Menu/MenuMobile.js +8 -8
  46. package/lib/components/Navbar/NavbarItem.js +7 -7
  47. package/lib/components/PageNavigation/NavigationButton.js +3 -3
  48. package/lib/components/Panel/PanelBody.d.ts +5 -5
  49. package/lib/components/Panel/PanelBody.js +6 -3
  50. package/lib/components/Panel/PanelHeader.d.ts +2 -5
  51. package/lib/components/Panel/PanelHeader.js +6 -2
  52. package/lib/components/Search/SearchAiMessage.js +10 -8
  53. package/lib/components/Search/SearchDialog.js +6 -0
  54. package/lib/components/Search/SearchSuggestedPages.js +2 -2
  55. package/lib/components/Select/Select.js +3 -1
  56. package/lib/components/Select/SelectInput.d.ts +1 -0
  57. package/lib/components/Select/SelectInput.js +8 -8
  58. package/lib/components/Sidebar/Sidebar.d.ts +4 -2
  59. package/lib/components/Sidebar/Sidebar.js +10 -8
  60. package/lib/components/SidebarActions/styled.d.ts +6 -6
  61. package/lib/components/SidebarActions/styled.js +12 -4
  62. package/lib/components/StatusCode/StatusCode.d.ts +6 -4
  63. package/lib/components/StatusCode/StatusCode.js +8 -2
  64. package/lib/components/Switch/Switch.js +13 -13
  65. package/lib/components/TableOfContent/TableOfContent.js +2 -2
  66. package/lib/components/Tag/Tag.js +11 -11
  67. package/lib/components/Tooltip/AnchorTooltip.js +26 -25
  68. package/lib/components/Tooltip/JsTooltip.js +5 -5
  69. package/lib/components/Typography/CompactTypography.d.ts +27 -11
  70. package/lib/components/Typography/CompactTypography.js +2 -2
  71. package/lib/components/Typography/Typography.d.ts +6 -2
  72. package/lib/components/Typography/Typography.js +18 -3
  73. package/lib/components/UserMenu/UserAvatar.js +5 -5
  74. package/lib/core/contexts/ThemeDataContext.d.ts +1 -1
  75. package/lib/core/hooks/feedback/use-report-dialog.d.ts +8 -5
  76. package/lib/core/styles/global.js +1 -0
  77. package/lib/core/templates/Markdown.js +5 -6
  78. package/lib/core/types/index.d.ts +1 -0
  79. package/lib/core/types/link.d.ts +19 -0
  80. package/lib/core/types/link.js +3 -0
  81. package/lib/core/utils/details.d.ts +1 -1
  82. package/lib/core/utils/details.js +3 -0
  83. package/lib/core/utils/dom.d.ts +0 -1
  84. package/lib/core/utils/dom.js +0 -9
  85. package/lib/core/utils/index.d.ts +0 -1
  86. package/lib/core/utils/index.js +0 -1
  87. package/lib/icons/AiStarsGradientIcon/AiStarsGradientIcon.d.ts +1 -1
  88. package/lib/icons/AiStarsGradientIcon/AiStarsGradientIcon.js +6 -1
  89. package/lib/icons/AiStarsIcon/AiStarsIcon.d.ts +1 -1
  90. package/lib/icons/AiStarsIcon/AiStarsIcon.js +6 -1
  91. package/lib/icons/MagicWandIcon/MagicWandIcon.d.ts +23 -0
  92. package/lib/icons/MagicWandIcon/MagicWandIcon.js +25 -0
  93. package/lib/icons/ReturnKeyIcon/ReturnKeyIcon.d.ts +25 -5
  94. package/lib/index.d.ts +1 -0
  95. package/lib/index.js +1 -0
  96. package/lib/layouts/DocumentationLayout.js +2 -2
  97. package/lib/layouts/ThreePanelLayout.d.ts +27 -7
  98. package/lib/layouts/ThreePanelLayout.js +11 -8
  99. package/lib/markdoc/components/CodeWalkthrough/CodeContainer.js +2 -2
  100. package/lib/markdoc/components/CodeWalkthrough/CodePanelHeader.js +2 -2
  101. package/lib/markdoc/components/CodeWalkthrough/CodePanelPreview.js +2 -2
  102. package/lib/markdoc/components/CodeWalkthrough/CodeStep.d.ts +4 -2
  103. package/lib/markdoc/components/CodeWalkthrough/CodeStep.js +6 -2
  104. package/lib/markdoc/components/Image/Image.js +3 -3
  105. package/lib/markdoc/components/Tabs/TabItemFragment.d.ts +9 -0
  106. package/lib/markdoc/components/Tabs/TabItemFragment.js +11 -0
  107. package/lib/markdoc/components/Tabs/TabList.d.ts +7 -4
  108. package/lib/markdoc/components/Tabs/TabList.js +6 -4
  109. package/lib/markdoc/components/Tabs/Tabs.d.ts +3 -9
  110. package/lib/markdoc/components/Tabs/Tabs.js +12 -5
  111. package/lib/markdoc/components/default.d.ts +1 -0
  112. package/lib/markdoc/components/default.js +1 -0
  113. package/lib/markdoc/tags/tab.js +1 -1
  114. package/lib/markdoc/tags/tabs.js +1 -1
  115. package/package.json +1 -2
  116. package/src/components/Admonition/Admonition.tsx +11 -11
  117. package/src/components/Badge/Badge.tsx +11 -6
  118. package/src/components/Button/Button.tsx +51 -21
  119. package/src/components/Buttons/AIAssistantButton.tsx +2 -0
  120. package/src/components/Catalog/CatalogActionsRow.tsx +3 -1
  121. package/src/components/Catalog/CatalogAvatar.tsx +6 -10
  122. package/src/components/Catalog/CatalogCardView/CatalogCard.tsx +6 -6
  123. package/src/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsNodeContent.tsx +14 -14
  124. package/src/components/Catalog/CatalogEntity/CatalogEntityInfoBar.tsx +11 -11
  125. package/src/components/Catalog/CatalogEntity/CatalogEntityProperties/CatalogEntityPropertyCard.tsx +4 -4
  126. package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityApiDescriptionRelations.tsx +8 -11
  127. package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityTeamRelations.tsx +10 -9
  128. package/src/components/Catalog/CatalogEntityTypeIcon.tsx +22 -16
  129. package/src/components/Catalog/CatalogEntityTypeTag.tsx +8 -8
  130. package/src/components/Catalog/CatalogTableView/CatalogTableView.tsx +8 -6
  131. package/src/components/CatalogClassic/CatalogClassic.tsx +3 -1
  132. package/src/components/CodeBlock/CodeBlockContainer.tsx +23 -7
  133. package/src/components/CodeBlock/CodeBlockControls.tsx +16 -10
  134. package/src/components/CodeBlock/CodeBlockTabs.tsx +4 -4
  135. package/src/components/Dropdown/Dropdown.tsx +9 -9
  136. package/src/components/Dropdown/DropdownMenuItem.tsx +1 -1
  137. package/src/components/Feedback/Comment.tsx +5 -5
  138. package/src/components/Feedback/Mood.tsx +5 -5
  139. package/src/components/Filter/FilterContent.tsx +4 -4
  140. package/src/components/Filter/FilterPopover.tsx +1 -1
  141. package/src/components/Footer/Footer.tsx +4 -4
  142. package/src/components/Footer/FooterColumn.tsx +3 -3
  143. package/src/components/Footer/FooterItem.tsx +9 -9
  144. package/src/components/Image/Image.tsx +3 -3
  145. package/src/components/LastUpdated/LastUpdated.tsx +4 -4
  146. package/src/components/Link/Link.tsx +6 -51
  147. package/src/components/Loaders/Loading.tsx +3 -3
  148. package/src/components/Loaders/SpinnerLoader.tsx +5 -5
  149. package/src/components/Markdown/Markdown.tsx +7 -7
  150. package/src/components/Marker/Marker.tsx +4 -4
  151. package/src/components/Menu/MenuContainer.tsx +32 -16
  152. package/src/components/Menu/MenuItem.tsx +34 -29
  153. package/src/components/Menu/MenuMobile.tsx +12 -12
  154. package/src/components/Navbar/NavbarItem.tsx +13 -13
  155. package/src/components/PageNavigation/NavigationButton.tsx +4 -4
  156. package/src/components/Panel/PanelBody.tsx +7 -4
  157. package/src/components/Panel/PanelHeader.tsx +9 -4
  158. package/src/components/Search/SearchAiMessage.tsx +17 -15
  159. package/src/components/Search/SearchDialog.tsx +6 -0
  160. package/src/components/Search/SearchSuggestedPages.tsx +20 -5
  161. package/src/components/Select/Select.tsx +3 -1
  162. package/src/components/Select/SelectInput.tsx +10 -9
  163. package/src/components/Sidebar/Sidebar.tsx +15 -13
  164. package/src/components/SidebarActions/styled.ts +12 -4
  165. package/src/components/StatusCode/StatusCode.tsx +12 -4
  166. package/src/components/Switch/Switch.tsx +21 -21
  167. package/src/components/TableOfContent/TableOfContent.tsx +3 -3
  168. package/src/components/Tag/Tag.tsx +34 -27
  169. package/src/components/Tooltip/AnchorTooltip.tsx +50 -42
  170. package/src/components/Tooltip/JsTooltip.tsx +14 -13
  171. package/src/components/Typography/CompactTypography.tsx +4 -4
  172. package/src/components/Typography/Typography.tsx +21 -5
  173. package/src/components/UserMenu/UserAvatar.tsx +7 -7
  174. package/src/core/contexts/ThemeDataContext.tsx +1 -1
  175. package/src/core/hooks/feedback/use-report-dialog.ts +1 -5
  176. package/src/core/styles/dark.ts +1 -1
  177. package/src/core/styles/global.ts +1 -0
  178. package/src/core/templates/Markdown.tsx +6 -7
  179. package/src/core/types/index.ts +1 -0
  180. package/src/core/types/link.ts +20 -0
  181. package/src/core/utils/details.ts +4 -0
  182. package/src/core/utils/dom.ts +0 -8
  183. package/src/core/utils/index.ts +0 -1
  184. package/src/icons/AiStarsGradientIcon/AiStarsGradientIcon.tsx +9 -3
  185. package/src/icons/AiStarsIcon/AiStarsIcon.tsx +9 -3
  186. package/src/icons/MagicWandIcon/MagicWandIcon.tsx +26 -0
  187. package/src/icons/ReturnKeyIcon/ReturnKeyIcon.tsx +1 -1
  188. package/src/index.ts +1 -0
  189. package/src/layouts/DocumentationLayout.tsx +3 -3
  190. package/src/layouts/ThreePanelLayout.tsx +27 -14
  191. package/src/markdoc/components/CodeWalkthrough/CodeContainer.tsx +4 -4
  192. package/src/markdoc/components/CodeWalkthrough/CodePanelHeader.tsx +4 -4
  193. package/src/markdoc/components/CodeWalkthrough/CodePanelPreview.tsx +3 -3
  194. package/src/markdoc/components/CodeWalkthrough/CodeStep.tsx +6 -2
  195. package/src/markdoc/components/Image/Image.tsx +4 -4
  196. package/src/markdoc/components/Tabs/TabItemFragment.tsx +15 -0
  197. package/src/markdoc/components/Tabs/TabList.tsx +9 -6
  198. package/src/markdoc/components/Tabs/Tabs.tsx +21 -15
  199. package/src/markdoc/components/default.ts +1 -0
  200. package/src/markdoc/tags/tab.ts +1 -1
  201. package/src/markdoc/tags/tabs.ts +1 -1
@@ -761,6 +761,7 @@ const apiReferenceDocs = css`
761
761
  --schema-property-details-width: 70%;
762
762
  --schema-property-details-spacing: var(--spacing-base); // @presenter Spacing
763
763
  --schema-fist-property-details-spacing: var(--spacing-sm); // @presenter Spacing
764
+ --schema-first-property-details-spacing: var(--schema-fist-property-details-spacing, var(--spacing-sm)); // @presenter Spacing
764
765
 
765
766
  /**
766
767
  * @tokens API Reference Schema Icons
@@ -11,7 +11,6 @@ import { TableOfContent } from '@redocly/theme/components/TableOfContent/TableOf
11
11
  import { Feedback } from '@redocly/theme/components/Feedback/Feedback';
12
12
  import { CodeWalkthroughLayout } from '@redocly/theme/layouts/CodeWalkthroughLayout';
13
13
 
14
- import { IS_BROWSER, onDocumentReady } from '../utils/dom';
15
14
  import { extendDetailsBehaviour } from '../utils/details';
16
15
  import { useThemeHooks } from '../hooks/use-theme-hooks';
17
16
  import { useThemeConfig } from '../hooks/use-theme-config';
@@ -66,19 +65,19 @@ export default function ({ pageProps, children }: React.PropsWithChildren<Markdo
66
65
  prevPage,
67
66
  };
68
67
 
69
- if (IS_BROWSER) {
70
- onDocumentReady(extendDetailsBehaviour);
71
- }
68
+ React.useEffect(() => {
69
+ return extendDetailsBehaviour();
70
+ }, [pathname]);
72
71
 
73
- const document = <Markdown ref={wrapperRefCb}>{children}</Markdown>;
72
+ const markdownDocument = <Markdown ref={wrapperRefCb}>{children}</Markdown>;
74
73
  const tagList = pageProps.metadata.markdoc.tagList;
75
74
  const withCodeWalkthrough = Boolean(
76
75
  Array.isArray(tagList) && tagList.includes('code-walkthrough'),
77
76
  );
78
77
 
79
78
  return withCodeWalkthrough ? (
80
- <CodeWalkthroughLayout>{document}</CodeWalkthroughLayout>
79
+ <CodeWalkthroughLayout>{markdownDocument}</CodeWalkthroughLayout>
81
80
  ) : (
82
- <DocumentationLayout {...documentationLayoutProps}>{document}</DocumentationLayout>
81
+ <DocumentationLayout {...documentationLayoutProps}>{markdownDocument}</DocumentationLayout>
83
82
  );
84
83
  }
@@ -21,3 +21,4 @@ export type * from './open-api-info';
21
21
  export type * from './segmented';
22
22
  export type * from './tooltip';
23
23
  export type * from './toast';
24
+ export type * from './link';
@@ -0,0 +1,20 @@
1
+ import type { RelativeRoutingType } from 'react-router-dom';
2
+
3
+ export type LinkProps = {
4
+ to: string;
5
+ target?: '_self' | '_blank';
6
+ external?: boolean;
7
+ className?: string;
8
+ style?: React.CSSProperties;
9
+ innerRef?: React.Ref<HTMLAnchorElement>;
10
+ languageInsensitive?: boolean;
11
+ onClick?: () => void;
12
+ reloadDocument?: boolean;
13
+ replace?: boolean;
14
+ state?: unknown;
15
+ preventScrollReset?: boolean;
16
+ relative?: RelativeRoutingType;
17
+ viewTransition?: boolean;
18
+ [key: string]: unknown;
19
+ rel?: string;
20
+ };
@@ -2,6 +2,10 @@ export function extendDetailsBehaviour() {
2
2
  enhanceDetails();
3
3
  openDetailsFromHash();
4
4
  window.addEventListener('hashchange', openDetailsFromHash);
5
+
6
+ return () => {
7
+ window.removeEventListener('hashchange', openDetailsFromHash);
8
+ };
5
9
  }
6
10
 
7
11
  function openDetailsAndScroll(detailsElement: Element) {
@@ -1,9 +1 @@
1
1
  export const IS_BROWSER = typeof window !== 'undefined' && 'HTMLElement' in window;
2
-
3
- export function onDocumentReady(fn: () => unknown) {
4
- if (document.readyState === 'loading') {
5
- document.addEventListener('DOMContentLoaded', fn as EventListener);
6
- } else {
7
- fn();
8
- }
9
- }
@@ -11,7 +11,6 @@ export * from './urls';
11
11
  export * from './js-utils';
12
12
  export * from './tags-parser';
13
13
  export * from './string';
14
- export * from './dom';
15
14
  export * from './markdoc';
16
15
  export * from './attribute-parser';
17
16
  export * from './type-guards';
@@ -59,9 +59,15 @@ const Icon = (props: AiStarsGradientIconProps) => {
59
59
  );
60
60
  };
61
61
 
62
- export const AiStarsGradientIcon = styled(Icon).attrs({
63
- 'data-component-name': 'icons/AiStarsGradientIcon/AiStarsGradientIcon',
64
- })`
62
+ const iconStyleProps = new Set(['background', 'borderRadius', 'padding', 'margin']);
63
+
64
+ export const AiStarsGradientIcon = styled(Icon)
65
+ .withConfig({
66
+ shouldForwardProp: (prop) => !iconStyleProps.has(prop),
67
+ })
68
+ .attrs({
69
+ 'data-component-name': 'icons/AiStarsGradientIcon/AiStarsGradientIcon',
70
+ })<AiStarsGradientIconProps>`
65
71
  height: ${({ size }) => size || '16px'};
66
72
  width: ${({ size }) => size || '16px'};
67
73
 
@@ -29,9 +29,15 @@ const Icon = (props: AiStarsIconProps) => {
29
29
  );
30
30
  };
31
31
 
32
- export const AiStarsIcon = styled(Icon).attrs({
33
- 'data-component-name': 'icons/AiStarsIcon/AiStarsIcon',
34
- })`
32
+ const iconStyleProps = new Set(['background', 'borderRadius', 'padding', 'margin']);
33
+
34
+ export const AiStarsIcon = styled(Icon)
35
+ .withConfig({
36
+ shouldForwardProp: (prop) => !iconStyleProps.has(prop),
37
+ })
38
+ .attrs({
39
+ 'data-component-name': 'icons/AiStarsIcon/AiStarsIcon',
40
+ })<AiStarsIconProps>`
35
41
  height: ${({ size }) => size || '16px'};
36
42
  width: ${({ size }) => size || '16px'};
37
43
 
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import type { IconProps } from '@redocly/theme/icons/types';
5
+
6
+ import { getCssColorVariable } from '@redocly/theme/core/utils';
7
+
8
+ const Icon = (props: IconProps) => (
9
+ <svg viewBox="0 0 12.25 12.2494" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
10
+ <path d="M11.9937 9.62499L4.37501 2.00632C4.20836 1.84719 3.98679 1.7584 3.75636 1.7584C3.52594 1.7584 3.30437 1.84719 3.13772 2.00632L2.00634 3.1377C1.84252 3.30191 1.75051 3.52439 1.75051 3.75634C1.75051 3.9883 1.84252 4.21078 2.00634 4.37499L9.62457 11.9937C9.7888 12.1575 10.0113 12.2494 10.2432 12.2494C10.4752 12.2494 10.6976 12.1575 10.8619 11.9937L11.9937 10.8621C12.0749 10.7808 12.1394 10.6844 12.1834 10.5782C12.2274 10.4721 12.25 10.3583 12.25 10.2434C12.25 10.1285 12.2274 10.0147 12.1834 9.90859C12.1394 9.80244 12.0749 9.70622 11.9937 9.62499ZM2.62501 3.75632L3.75634 2.62499L5.94384 4.81249L4.81221 5.94426L2.62471 3.75676L2.62501 3.75632ZM10.2432 11.375L5.43074 6.56293L6.56251 5.43116L11.375 10.2437L10.2432 11.375Z" />
11
+ <path d="M0.875027 5.24999L3.56734e-05 6.12498L0.875027 6.99997L1.75002 6.12498L0.875027 5.24999Z" />
12
+ <path d="M6.12503 8.20979e-06L5.25004 0.875L6.12503 1.74999L7.00002 0.875L6.12503 8.20979e-06Z" />
13
+ <path d="M0.874992 0L0 0.874992L0.874992 1.74998L1.74998 0.874992L0.874992 0Z" />
14
+ </svg>
15
+ );
16
+
17
+ export const MagicWandIcon = styled(Icon).attrs({
18
+ 'data-component-name': 'icons/MagicWandIcon/MagicWandIcon',
19
+ })`
20
+ path {
21
+ fill: ${({ color }) => getCssColorVariable(color)};
22
+ }
23
+
24
+ height: ${({ size }) => size || '14px'};
25
+ width: ${({ size }) => size || '14px'};
26
+ `;
@@ -2,7 +2,7 @@ import styled from 'styled-components';
2
2
 
3
3
  import { Typography } from '@redocly/theme/components/Typography/Typography';
4
4
 
5
- export const ReturnKeyIcon = styled(Typography).attrs({
5
+ export const ReturnKeyIcon = styled(Typography).attrs<{ 'data-component-name': string }>({
6
6
  'data-component-name': 'icons/ReturnKeyIcon/ReturnKeyIcon',
7
7
  })`
8
8
  margin-left: auto;
package/src/index.ts CHANGED
@@ -267,6 +267,7 @@ export * from '@redocly/theme/icons/TableBuiltIcon/TableBuiltIcon';
267
267
  export * from '@redocly/theme/icons/ValueVariableIcon/ValueVariableIcon';
268
268
  export * from '@redocly/theme/icons/InformationIcon/InformationIcon';
269
269
  export * from '@redocly/theme/icons/ChevronSortIcon/ChevronSortIcon';
270
+ export * from '@redocly/theme/icons/MagicWandIcon/MagicWandIcon';
270
271
  export * from '@redocly/theme/icons/DocumentIcon/DocumentIcon';
271
272
  export * from '@redocly/theme/icons/JsonIcon/JsonIcon';
272
273
  export * from '@redocly/theme/icons/SubtractIcon/SubtractIcon';
@@ -38,7 +38,7 @@ export function DocumentationLayout({
38
38
  return (
39
39
  <CodeSnippetProvider>
40
40
  <LayoutWrapper data-component-name="Layout/DocumentationLayout" className={className}>
41
- <ContentWrapper withToc={!config?.toc?.hide}>
41
+ <ContentWrapper $withToc={!config?.toc?.hide}>
42
42
  <DocumentationLayoutTop config={config} editPage={editPage} lastModified={lastModified} />
43
43
  {children}
44
44
  <DocumentationLayoutBottom feedback={feedback} nextPage={nextPage} prevPage={prevPage} />
@@ -57,7 +57,7 @@ const LayoutWrapper = styled.div.attrs(({ className }) => ({
57
57
  width: 100%;
58
58
  `;
59
59
 
60
- const ContentWrapper = styled.section<{ withToc: boolean }>`
60
+ const ContentWrapper = styled.section<{ $withToc: boolean }>`
61
61
  --md-content-font-size: var(--font-size-lg);
62
62
  --md-content-line-height: var(--line-height-lg);
63
63
  --md-table-font-size: var(--md-content-font-size);
@@ -78,6 +78,6 @@ const ContentWrapper = styled.section<{ withToc: boolean }>`
78
78
  }
79
79
 
80
80
  @media screen and (min-width: ${breakpoints.medium}) {
81
- width: ${({ withToc }) => (withToc ? `calc(90% - var(--toc-width))` : '90%')};
81
+ width: ${({ $withToc }) => ($withToc ? `calc(90% - var(--toc-width))` : '90%')};
82
82
  }
83
83
  `;
@@ -1,28 +1,41 @@
1
- import React from 'react';
1
+ import React, { type JSX, type PropsWithChildren } from 'react';
2
2
  import styled, { css } from 'styled-components';
3
3
  import { LayoutVariant } from '@redocly/config';
4
4
 
5
- import type { JSX } from 'react';
6
-
7
5
  import { breakpoints } from '@redocly/theme/core/utils';
8
6
 
9
- interface LayoutConfig {
10
- children: React.ReactNode;
7
+ export type ThreePanelLayoutProps = PropsWithChildren<{
11
8
  layout?: LayoutVariant;
12
9
  collapsedSidebar?: boolean;
13
10
  id?: string;
14
11
  className?: string;
15
- }
12
+ }>;
16
13
 
17
- export function ThreePanelLayout({ children, ...props }: LayoutConfig): JSX.Element {
14
+ export function ThreePanelLayout({
15
+ layout,
16
+ collapsedSidebar,
17
+ children,
18
+ ...props
19
+ }: ThreePanelLayoutProps): JSX.Element {
18
20
  return (
19
- <Wrapper data-component-name="Layout/ThreePanelLayout" {...props}>
21
+ <Wrapper
22
+ data-component-name="Layout/ThreePanelLayout"
23
+ {...props}
24
+ $layout={layout}
25
+ $collapsedSidebar={collapsedSidebar}
26
+ >
20
27
  {children}
21
28
  </Wrapper>
22
29
  );
23
30
  }
24
31
 
25
- const Wrapper = styled.div<{ collapsedSidebar?: boolean; layout?: LayoutVariant }>`
32
+ export const Wrapper = styled.div.attrs<{
33
+ 'data-component-name': string;
34
+ $layout: LayoutVariant;
35
+ $collapsedSidebar: boolean;
36
+ }>({
37
+ 'data-component-name': 'Layout/ThreePanelLayout',
38
+ })<ThreePanelLayoutProps>`
26
39
  position: relative;
27
40
  display: flex;
28
41
  flex-direction: column;
@@ -30,20 +43,20 @@ const Wrapper = styled.div<{ collapsedSidebar?: boolean; layout?: LayoutVariant
30
43
  margin: 0 auto;
31
44
  width: 100%;
32
45
 
33
- ${({ layout = LayoutVariant.THREE_PANEL }) => {
46
+ ${({ $layout = LayoutVariant.THREE_PANEL }) => {
34
47
  return css`
35
- max-width: ${layout === LayoutVariant.THREE_PANEL ? '100%' : ''};
48
+ max-width: ${$layout === LayoutVariant.THREE_PANEL ? '100%' : ''};
36
49
 
37
50
  @media screen and (min-width: ${breakpoints.small}) {
38
- max-width: var(--layout-${layout}-small-max-width);
51
+ max-width: var(--layout-${$layout}-small-max-width);
39
52
  }
40
53
 
41
54
  @media screen and (min-width: ${breakpoints.medium}) {
42
- max-width: var(--layout-${layout}-medium-max-width);
55
+ max-width: var(--layout-${$layout}-medium-max-width);
43
56
  }
44
57
 
45
58
  @media screen and (min-width: ${breakpoints.large}) {
46
- max-width: var(--layout-${layout}-large-max-width);
59
+ max-width: var(--layout-${$layout}-large-max-width);
47
60
  }
48
61
 
49
62
  @media print {
@@ -59,7 +59,7 @@ export function CodeContainer({
59
59
  <CodeContainerWrapper
60
60
  data-component-name="Markdoc/CodeWalkthrough/CodeContainer"
61
61
  ref={compRef}
62
- hideCodeColors={!isHovered}
62
+ $hideCodeColors={!isHovered}
63
63
  onMouseEnter={() => setIsHovered(true)}
64
64
  onMouseLeave={() => setIsHovered(false)}
65
65
  >
@@ -69,7 +69,7 @@ export function CodeContainer({
69
69
  );
70
70
  }
71
71
 
72
- const CodeContainerWrapper = styled.div<{ hideCodeColors?: boolean }>`
72
+ const CodeContainerWrapper = styled.div<{ $hideCodeColors: boolean }>`
73
73
  position: relative;
74
74
 
75
75
  display: flex;
@@ -89,8 +89,8 @@ const CodeContainerWrapper = styled.div<{ hideCodeColors?: boolean }>`
89
89
  span.line::before {
90
90
  color: var(--code-panel-line-numbering-color);
91
91
  }
92
- ${({ hideCodeColors }) =>
93
- hideCodeColors &&
92
+ ${({ $hideCodeColors }) =>
93
+ $hideCodeColors &&
94
94
  css`
95
95
  .line.greyed-out {
96
96
  color: var(--text-color-helper) !important;
@@ -85,7 +85,7 @@ export function CodePanelHeader({
85
85
  tabRefs.current[i] = el as HTMLButtonElement;
86
86
  }}
87
87
  data-name={path}
88
- active={path === activeTabName}
88
+ $active={path === activeTabName}
89
89
  key={i}
90
90
  onClick={() => handleTabSwitch(path)}
91
91
  >
@@ -173,7 +173,7 @@ const ActionBar = styled.div`
173
173
  display: flex;
174
174
  `;
175
175
 
176
- const Tab = styled.button<{ active: boolean }>`
176
+ const Tab = styled.button<{ $active: boolean }>`
177
177
  --icon-width: 16px;
178
178
  --icon-height: 16px;
179
179
 
@@ -188,8 +188,8 @@ const Tab = styled.button<{ active: boolean }>`
188
188
  color: var(--text-color-secondary);
189
189
  white-space: nowrap;
190
190
  scroll-margin-right: var(--spacing-base);
191
- ${({ active }) =>
192
- active
191
+ ${({ $active }) =>
192
+ $active
193
193
  ? css`
194
194
  color: var(--text-color-primary);
195
195
  background-color: var(--tab-bg-color-filled);
@@ -18,7 +18,7 @@ export function CodePanelPreview({ children }: PropsWithChildren): JSX.Element {
18
18
  {translate('codeWalkthrough.preview', 'Preview')}
19
19
  {isOpen ? <ChevronUpIcon /> : <ChevronDownIcon />}
20
20
  </PreviewDropdown>
21
- <PreviewContentWrapper isOpen={isOpen}>{children}</PreviewContentWrapper>
21
+ <PreviewContentWrapper $isOpen={isOpen}>{children}</PreviewContentWrapper>
22
22
  </CodePanelPreviewWrapper>
23
23
  );
24
24
  }
@@ -41,8 +41,8 @@ const PreviewDropdown = styled.div`
41
41
  cursor: pointer;
42
42
  `;
43
43
 
44
- const PreviewContentWrapper = styled.div<{ isOpen: boolean }>`
45
- display: ${({ isOpen }) => (isOpen ? 'grid' : 'none')};
44
+ const PreviewContentWrapper = styled.div<{ $isOpen: boolean }>`
45
+ display: ${({ $isOpen }) => ($isOpen ? 'grid' : 'none')};
46
46
  place-items: center;
47
47
 
48
48
  margin: auto 0;
@@ -147,7 +147,9 @@ export function CodeStep({
147
147
  );
148
148
  }
149
149
 
150
- const StepContent = styled.div<{ isActive: boolean }>`
150
+ const StepContent = styled.div.withConfig({
151
+ shouldForwardProp: (prop) => prop !== 'isActive',
152
+ })<{ isActive: boolean }>`
151
153
  margin: var(--spacing-xs) 0px var(--spacing-xs) calc(var(--spacing-unit) * 3.5);
152
154
  padding: var(--spacing-md) var(--spacing-lg);
153
155
  background: ${({ isActive }) => (isActive ? 'var(--layer-color)' : 'none')};
@@ -163,7 +165,9 @@ const StepHeading = styled.p`
163
165
  font-weight: var(--font-weight-semibold);
164
166
  `;
165
167
 
166
- export const StepWrapper = styled.div<{ isActive: boolean; scrollMarginTop: number }>`
168
+ export const StepWrapper = styled.div.withConfig({
169
+ shouldForwardProp: (prop) => !['isActive', 'scrollMarginTop'].includes(prop),
170
+ })<{ isActive: boolean; scrollMarginTop: number; className?: string }>`
167
171
  position: relative;
168
172
  scroll-margin-top: ${({ scrollMarginTop }) => scrollMarginTop}px;
169
173
 
@@ -9,7 +9,7 @@ type MarkdocImageProps = React.PropsWithChildren<ImageProps> & {
9
9
  export function Image(props: MarkdocImageProps) {
10
10
  const { align, ...rest } = props;
11
11
  return align ? (
12
- <ImageWrapper align={align}>
12
+ <ImageWrapper $align={align}>
13
13
  <ImageComponent {...rest} />
14
14
  </ImageWrapper>
15
15
  ) : (
@@ -17,13 +17,13 @@ export function Image(props: MarkdocImageProps) {
17
17
  );
18
18
  }
19
19
 
20
- const ImageWrapper = styled.div<{ align?: MarkdocImageProps['align'] }>`
21
- text-align: ${(props) => props.align || 'initial'};
20
+ const ImageWrapper = styled.div<{ $align?: MarkdocImageProps['align'] }>`
21
+ text-align: ${(props) => props.$align || 'initial'};
22
22
 
23
23
  img {
24
24
  display: block;
25
25
  ${(props) => {
26
- switch (props.align) {
26
+ switch (props.$align) {
27
27
  case 'left':
28
28
  return 'margin-right: auto; margin-left: 0;';
29
29
  case 'right':
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+
3
+ import type { JSX, PropsWithChildren } from 'react';
4
+
5
+ // Below props are used by the TabList component to render tab labels
6
+ export type TabItemProps = PropsWithChildren<{
7
+ label: string;
8
+ disable?: boolean;
9
+ onClick?: () => void;
10
+ icon?: React.ReactNode | string;
11
+ }>;
12
+
13
+ export function TabItemFragment({ children }: TabItemProps): JSX.Element {
14
+ return <div>{children}</div>;
15
+ }
@@ -2,9 +2,10 @@ import React, { useState, useRef, useEffect, useCallback } from 'react';
2
2
  import styled, { css } from 'styled-components';
3
3
 
4
4
  import type { JSX } from 'react';
5
+ import type { TabItemProps } from '@redocly/theme/markdoc/components/Tabs/TabItemFragment';
5
6
 
6
7
  import { Tab } from '@redocly/theme/markdoc/components/Tabs/Tab';
7
- import { TabItemProps, TabsSize } from '@redocly/theme/markdoc/components/Tabs/Tabs';
8
+ import { TabsSize } from '@redocly/theme/markdoc/components/Tabs/Tabs';
8
9
  import { Dropdown } from '@redocly/theme/components/Dropdown/Dropdown';
9
10
  import { DropdownMenu } from '@redocly/theme/components/Dropdown/DropdownMenu';
10
11
  import { DropdownMenuItem } from '@redocly/theme/components/Dropdown/DropdownMenuItem';
@@ -198,7 +199,7 @@ export function TabList({
198
199
 
199
200
  return (
200
201
  <TabListContainer role="tablist" ref={containerRef}>
201
- <HighlightBar size={size} style={highlightStyle}>
202
+ <HighlightBar $size={size} style={highlightStyle}>
202
203
  <div />
203
204
  </HighlightBar>
204
205
 
@@ -359,7 +360,9 @@ export const TabListContainer = styled.ul`
359
360
  }
360
361
  `;
361
362
 
362
- export const TabItem = styled.li<{ active?: boolean; size: TabsSize; tabIndex?: number }>`
363
+ export const TabItem = styled.li.withConfig({
364
+ shouldForwardProp: (prop) => !['active', 'size'].includes(prop),
365
+ })<{ tabIndex?: number; className?: string; active?: boolean; size: TabsSize }>`
363
366
  display: inline-flex;
364
367
  list-style: none;
365
368
  cursor: pointer;
@@ -449,12 +452,12 @@ const FixedPositionDropdown = styled(Dropdown)`
449
452
  }
450
453
  `;
451
454
 
452
- const HighlightBar = styled.div<{ size: TabsSize }>`
455
+ const HighlightBar = styled.div<{ $size: TabsSize }>`
453
456
  position: absolute;
454
457
  top: 0;
455
458
  bottom: 0;
456
459
  border: solid var(--md-tabs-active-tab-border-color);
457
- border-width: var(--md-tabs-${({ size }) => size}-active-tab-border-width);
460
+ border-width: var(--md-tabs-${({ $size }) => $size}-active-tab-border-width);
458
461
  transition:
459
462
  left 300ms ease-in-out,
460
463
  width 300ms ease-in-out;
@@ -465,7 +468,7 @@ const HighlightBar = styled.div<{ size: TabsSize }>`
465
468
  width: 100%;
466
469
  height: 100%;
467
470
  background-color: var(--md-tabs-active-tab-bg-color);
468
- border-radius: var(--md-tabs-${({ size }) => size}-active-tab-border-radius);
471
+ border-radius: var(--md-tabs-${({ $size }) => $size}-active-tab-border-radius);
469
472
  }
470
473
  `;
471
474
 
@@ -1,26 +1,24 @@
1
- import React, { useEffect, useRef, useState } from 'react';
1
+ import React, { isValidElement, useEffect, useRef, useState } from 'react';
2
2
  import { useInRouterContext } from 'react-router-dom';
3
3
  import styled from 'styled-components';
4
4
 
5
- import type { JSX } from 'react';
5
+ import type { JSX, ReactElement, ReactNode } from 'react';
6
6
 
7
7
  import { useActiveTab } from '@redocly/theme/core/hooks';
8
+ import {
9
+ TabItemFragment,
10
+ type TabItemProps,
11
+ } from '@redocly/theme/markdoc/components/Tabs/TabItemFragment';
8
12
  import { TabList } from '@redocly/theme/markdoc/components/Tabs/TabList';
9
13
  import { getTabId } from '@redocly/theme/core/utils';
10
14
 
15
+ export type { TabItemProps } from '@redocly/theme/markdoc/components/Tabs/TabItemFragment';
16
+
11
17
  export enum TabsSize {
12
18
  SMALL = 'small',
13
19
  MEDIUM = 'medium',
14
20
  }
15
21
 
16
- export type TabItemProps = {
17
- label: string;
18
- disable?: boolean;
19
- onClick?: () => void;
20
- children: React.ReactNode;
21
- icon?: React.ReactNode | string;
22
- };
23
-
24
22
  type TabsProps = {
25
23
  id?: string;
26
24
  children: React.ReactElement<TabItemProps>[];
@@ -55,14 +53,17 @@ export function Tabs({
55
53
  size,
56
54
  initialTab: propInitialTab,
57
55
  activeTab: controlledActiveTab,
58
- }: TabsProps): JSX.Element {
59
- const childrenArray = React.Children.toArray(children) as React.ReactElement<TabItemProps>[];
56
+ }: TabsProps): JSX.Element | null {
57
+ const inRouter = useInRouterContext();
58
+ const childrenArray = React.Children.toArray(children).filter(isTabItemFragment);
60
59
  const containerRef = useRef<HTMLUListElement | null>(null);
61
60
 
62
- const initialTab = propInitialTab ?? childrenArray[0]?.props.label ?? '';
63
- const labelsHash = childrenArray.map((c) => c.props.label).join('|');
61
+ if (childrenArray.length === 0) {
62
+ return null;
63
+ }
64
64
 
65
- const inRouter = useInRouterContext();
65
+ const initialTab = propInitialTab ?? childrenArray[0].props.label;
66
+ const labelsHash = childrenArray.map((c) => c.props.label).join('|');
66
67
 
67
68
  return (
68
69
  <TabsView
@@ -127,6 +128,11 @@ function TabsView({
127
128
  );
128
129
  }
129
130
 
131
+ function isTabItemFragment(node: ReactNode): node is ReactElement<TabItemProps> {
132
+ if (!isValidElement(node)) return false;
133
+ return node.type === TabItemFragment;
134
+ }
135
+
130
136
  /**
131
137
  * Validates that the active tab exists in children and resets to initial tab if not found.
132
138
  * Ensures tab state remains consistent when tab structure changes.
@@ -4,6 +4,7 @@ export * from '@redocly/theme/markdoc/components/MarkdocExample/MarkdocExample';
4
4
  export * from '@redocly/theme/markdoc/components/Heading/Heading';
5
5
  export * from '@redocly/theme/markdoc/components/Diagram/Diagram';
6
6
  export * from '@redocly/theme/markdoc/components/HtmlBlock/HtmlBlock';
7
+ export * from '@redocly/theme/markdoc/components/Tabs/TabItemFragment';
7
8
  export * from '@redocly/theme/markdoc/components/Tabs/Tab';
8
9
  export * from '@redocly/theme/markdoc/components/Tabs/TabList';
9
10
  export * from '@redocly/theme/markdoc/components/Tabs/Tabs';
@@ -7,7 +7,7 @@ export const tab: MarkdocSchemaWrapper = {
7
7
  disable: { type: Boolean, default: false },
8
8
  icon: { type: String, resolver: 'relativeOrCdnIcon' },
9
9
  },
10
- render: 'div',
10
+ render: 'TabItemFragment',
11
11
  },
12
12
  tagName: 'tab',
13
13
  };
@@ -14,7 +14,7 @@ export const tabs: MarkdocSchemaWrapper = {
14
14
  if (isTag(child) && child?.name === 'CodeBlock') {
15
15
  const key = child.attributes['data-language'] || 'default';
16
16
  const label = child.attributes['data-label'] || key;
17
- return new markdoc.Tag('div', { label, key }, [child]);
17
+ return new markdoc.Tag('TabItemFragment', { label, key }, [child]);
18
18
  }
19
19
  return child;
20
20
  });