@redocly/theme 0.56.0-next.9 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/lib/components/Button/Button.d.ts +1 -1
  2. package/lib/components/Button/Button.js +2 -1
  3. package/lib/components/Button/ButtonGroup.d.ts +12 -0
  4. package/lib/components/Button/ButtonGroup.js +38 -0
  5. package/lib/components/Button/variables.js +32 -5
  6. package/lib/components/Catalog/Catalog.d.ts +1 -1
  7. package/lib/components/Catalog/CatalogCardView/CatalogCard.js +2 -2
  8. package/lib/components/Catalog/CatalogSelector.d.ts +1 -1
  9. package/lib/components/Catalog/CatalogSelector.js +4 -3
  10. package/lib/components/Catalog/CatalogViewModeToggle.d.ts +1 -1
  11. package/lib/components/CodeBlock/CodeBlock.d.ts +16 -6
  12. package/lib/components/CodeBlock/CodeBlock.js +2 -2
  13. package/lib/components/CodeBlock/CodeBlockControls.d.ts +4 -3
  14. package/lib/components/CodeBlock/CodeBlockControls.js +8 -5
  15. package/lib/components/CodeBlock/CodeBlockDropdown.d.ts +3 -0
  16. package/lib/components/CodeBlock/CodeBlockDropdown.js +35 -0
  17. package/lib/components/CodeBlock/CodeBlockTabs.d.ts +2 -2
  18. package/lib/components/CodeBlock/CodeBlockTabs.js +18 -9
  19. package/lib/components/CodeBlock/variables.js +1 -1
  20. package/lib/components/Dropdown/Dropdown.js +1 -0
  21. package/lib/components/Dropdown/DropdownMenu.js +4 -0
  22. package/lib/components/Dropdown/variables.js +1 -0
  23. package/lib/components/Footer/FooterItem.js +4 -7
  24. package/lib/components/Footer/variables.js +2 -2
  25. package/lib/components/Markdown/Markdown.js +9 -9
  26. package/lib/components/Markdown/styles/headingAnchor.js +0 -1
  27. package/lib/components/Menu/MenuItem.js +5 -5
  28. package/lib/components/Menu/variables.js +1 -1
  29. package/lib/components/Navbar/NavbarItem.js +8 -39
  30. package/lib/components/Navbar/variables.js +2 -2
  31. package/lib/components/PageActions/PageActions.d.ts +6 -0
  32. package/lib/components/PageActions/PageActions.js +104 -0
  33. package/lib/components/PageActions/PageActionsMenuItem.d.ts +7 -0
  34. package/lib/components/PageActions/PageActionsMenuItem.js +58 -0
  35. package/lib/components/PageActions/variables.d.ts +1 -0
  36. package/lib/components/PageActions/variables.dark.d.ts +1 -0
  37. package/lib/components/PageActions/variables.dark.js +9 -0
  38. package/lib/components/PageActions/variables.js +37 -0
  39. package/lib/components/TableOfContent/TableOfContent.js +15 -12
  40. package/lib/components/Tags/CounterTag.d.ts +1 -1
  41. package/lib/components/Tags/HttpTag.d.ts +1 -1
  42. package/lib/core/constants/common.d.ts +4 -0
  43. package/lib/core/constants/common.js +5 -1
  44. package/lib/core/contexts/CodeSnippetContext.d.ts +7 -0
  45. package/lib/core/contexts/CodeSnippetContext.js +23 -0
  46. package/lib/core/contexts/index.d.ts +1 -0
  47. package/lib/core/contexts/index.js +1 -0
  48. package/lib/core/hooks/__mocks__/use-theme-hooks.d.ts +1 -0
  49. package/lib/core/hooks/__mocks__/use-theme-hooks.js +1 -0
  50. package/lib/core/hooks/code-walkthrough/use-renderable-files.d.ts +1 -2
  51. package/lib/core/hooks/code-walkthrough/use-renderable-files.js +2 -2
  52. package/lib/core/hooks/index.d.ts +1 -0
  53. package/lib/core/hooks/index.js +1 -0
  54. package/lib/core/hooks/use-active-heading.d.ts +7 -2
  55. package/lib/core/hooks/use-active-heading.js +160 -23
  56. package/lib/core/hooks/use-codeblock-tabs-controls.d.ts +2 -2
  57. package/lib/core/hooks/use-codeblock-tabs-controls.js +6 -6
  58. package/lib/core/hooks/use-local-state.d.ts +1 -0
  59. package/lib/core/hooks/use-local-state.js +32 -0
  60. package/lib/core/hooks/use-page-actions.d.ts +2 -0
  61. package/lib/core/hooks/use-page-actions.js +101 -0
  62. package/lib/core/hooks/use-theme-hooks.js +2 -0
  63. package/lib/core/styles/dark.js +2 -0
  64. package/lib/core/styles/global.js +2 -0
  65. package/lib/core/types/hooks.d.ts +2 -1
  66. package/lib/core/types/index.d.ts +1 -0
  67. package/lib/core/types/index.js +1 -0
  68. package/lib/core/types/l10n.d.ts +1 -1
  69. package/lib/core/types/page-actions.d.ts +15 -0
  70. package/lib/core/types/page-actions.js +3 -0
  71. package/lib/core/types/sidebar.d.ts +1 -0
  72. package/lib/core/utils/enhanced-smoothstep.d.ts +5 -0
  73. package/lib/core/utils/enhanced-smoothstep.js +15 -0
  74. package/lib/core/utils/get-file-icon.d.ts +3 -2
  75. package/lib/core/utils/get-file-icon.js +109 -29
  76. package/lib/core/utils/icon-resolver.d.ts +28 -0
  77. package/lib/core/utils/icon-resolver.js +52 -0
  78. package/lib/core/utils/index.d.ts +4 -1
  79. package/lib/core/utils/index.js +4 -1
  80. package/lib/core/utils/lang-to-name.d.ts +1 -0
  81. package/lib/core/utils/lang-to-name.js +37 -0
  82. package/lib/core/utils/{text-transform.js → string.js} +1 -1
  83. package/lib/ext/configure.d.ts +1 -1
  84. package/lib/icons/CDNIcon/CDNIcon.d.ts +14 -0
  85. package/lib/icons/CDNIcon/CDNIcon.js +48 -0
  86. package/lib/icons/ChatGptIcon/ChatGptIcon.d.ts +9 -0
  87. package/lib/icons/ChatGptIcon/ChatGptIcon.js +22 -0
  88. package/lib/icons/CheckmarkOutlineIcon/CheckmarkOutlineIcon.d.ts +9 -0
  89. package/lib/icons/CheckmarkOutlineIcon/CheckmarkOutlineIcon.js +23 -0
  90. package/lib/icons/ClaudeIcon/ClaudeIcon.d.ts +9 -0
  91. package/lib/icons/ClaudeIcon/ClaudeIcon.js +22 -0
  92. package/lib/icons/GenericIcon/GenericIcon.d.ts +11 -0
  93. package/lib/icons/GenericIcon/GenericIcon.js +61 -0
  94. package/lib/icons/MarkdownFullIcon/MarkdownFullIcon.d.ts +9 -0
  95. package/lib/icons/MarkdownFullIcon/MarkdownFullIcon.js +23 -0
  96. package/lib/icons/NoneIcon/NoneIcon.d.ts +9 -0
  97. package/lib/icons/NoneIcon/NoneIcon.js +17 -0
  98. package/lib/icons/types.d.ts +6 -0
  99. package/lib/index.d.ts +6 -0
  100. package/lib/index.js +6 -0
  101. package/lib/layouts/CodeWalkthroughLayout.js +2 -2
  102. package/lib/layouts/DocumentationLayout.js +14 -10
  103. package/lib/markdoc/components/Cards/CardIcon.js +7 -19
  104. package/lib/markdoc/components/CodeGroup/CodeGroup.d.ts +4 -0
  105. package/lib/markdoc/components/CodeGroup/CodeGroup.js +72 -0
  106. package/lib/markdoc/components/CodeWalkthrough/CodePanelHeader.js +7 -4
  107. package/lib/markdoc/components/Heading/Heading.d.ts +2 -1
  108. package/lib/markdoc/components/Heading/Heading.js +21 -3
  109. package/lib/markdoc/components/Icon/Icon.d.ts +3 -0
  110. package/lib/markdoc/components/Icon/Icon.js +29 -0
  111. package/lib/markdoc/components/Tabs/Tab.d.ts +2 -1
  112. package/lib/markdoc/components/Tabs/Tab.js +5 -2
  113. package/lib/markdoc/components/Tabs/Tabs.d.ts +1 -1
  114. package/lib/markdoc/components/Tabs/variables.js +2 -0
  115. package/lib/markdoc/components/default.d.ts +2 -0
  116. package/lib/markdoc/components/default.js +2 -0
  117. package/lib/markdoc/default.js +4 -0
  118. package/lib/markdoc/tags/card.js +1 -1
  119. package/lib/markdoc/tags/code-group.d.ts +2 -0
  120. package/lib/markdoc/tags/code-group.js +23 -0
  121. package/lib/markdoc/tags/code-snippet.js +1 -1
  122. package/lib/markdoc/tags/icon.d.ts +2 -0
  123. package/lib/markdoc/tags/icon.js +16 -0
  124. package/lib/markdoc/tags/tab.js +1 -0
  125. package/package.json +3 -3
  126. package/src/components/Button/Button.tsx +3 -2
  127. package/src/components/Button/ButtonGroup.tsx +53 -0
  128. package/src/components/Button/variables.ts +32 -5
  129. package/src/components/Catalog/Catalog.tsx +1 -1
  130. package/src/components/Catalog/CatalogCardView/CatalogCard.tsx +1 -1
  131. package/src/components/Catalog/CatalogSelector.tsx +3 -1
  132. package/src/components/Catalog/CatalogViewModeToggle.tsx +1 -1
  133. package/src/components/CodeBlock/CodeBlock.tsx +14 -5
  134. package/src/components/CodeBlock/CodeBlockControls.tsx +14 -6
  135. package/src/components/CodeBlock/CodeBlockDropdown.tsx +53 -0
  136. package/src/components/CodeBlock/CodeBlockTabs.tsx +29 -20
  137. package/src/components/CodeBlock/variables.ts +1 -1
  138. package/src/components/Dropdown/Dropdown.tsx +1 -0
  139. package/src/components/Dropdown/DropdownMenu.tsx +4 -0
  140. package/src/components/Dropdown/variables.ts +1 -0
  141. package/src/components/Footer/FooterItem.tsx +5 -12
  142. package/src/components/Footer/variables.ts +2 -2
  143. package/src/components/Markdown/Markdown.tsx +3 -3
  144. package/src/components/Markdown/styles/headingAnchor.ts +0 -1
  145. package/src/components/Menu/MenuItem.tsx +5 -5
  146. package/src/components/Menu/variables.ts +1 -1
  147. package/src/components/Navbar/NavbarItem.tsx +8 -17
  148. package/src/components/Navbar/variables.ts +2 -2
  149. package/src/components/PageActions/PageActions.tsx +110 -0
  150. package/src/components/PageActions/PageActionsMenuItem.tsx +73 -0
  151. package/src/components/PageActions/variables.dark.ts +6 -0
  152. package/src/components/PageActions/variables.ts +34 -0
  153. package/src/components/TableOfContent/TableOfContent.tsx +33 -36
  154. package/src/core/constants/common.ts +4 -0
  155. package/src/core/contexts/CodeSnippetContext.tsx +31 -0
  156. package/src/core/contexts/index.ts +1 -0
  157. package/src/core/hooks/__mocks__/use-theme-hooks.ts +1 -0
  158. package/src/core/hooks/code-walkthrough/use-renderable-files.ts +3 -4
  159. package/src/core/hooks/index.ts +1 -0
  160. package/src/core/hooks/use-active-heading.ts +199 -28
  161. package/src/core/hooks/use-codeblock-tabs-controls.ts +8 -8
  162. package/src/core/hooks/use-local-state.ts +30 -0
  163. package/src/core/hooks/use-page-actions.ts +115 -0
  164. package/src/core/hooks/use-theme-hooks.ts +2 -0
  165. package/src/core/styles/dark.ts +2 -1
  166. package/src/core/styles/global.ts +2 -0
  167. package/src/core/types/hooks.ts +2 -0
  168. package/src/core/types/index.ts +1 -0
  169. package/src/core/types/l10n.ts +12 -0
  170. package/src/core/types/page-actions.ts +18 -0
  171. package/src/core/types/sidebar.ts +1 -0
  172. package/src/core/utils/enhanced-smoothstep.ts +14 -0
  173. package/src/core/utils/get-file-icon.tsx +94 -0
  174. package/src/core/utils/icon-resolver.ts +57 -0
  175. package/src/core/utils/index.ts +4 -1
  176. package/src/core/utils/lang-to-name.ts +35 -0
  177. package/src/ext/configure.ts +1 -1
  178. package/src/icons/CDNIcon/CDNIcon.tsx +47 -0
  179. package/src/icons/ChatGptIcon/ChatGptIcon.tsx +23 -0
  180. package/src/icons/CheckmarkOutlineIcon/CheckmarkOutlineIcon.tsx +24 -0
  181. package/src/icons/ClaudeIcon/ClaudeIcon.tsx +23 -0
  182. package/src/icons/GenericIcon/GenericIcon.tsx +69 -0
  183. package/src/icons/MarkdownFullIcon/MarkdownFullIcon.tsx +24 -0
  184. package/src/icons/NoneIcon/NoneIcon.tsx +17 -0
  185. package/src/icons/types.ts +7 -0
  186. package/src/index.ts +6 -0
  187. package/src/layouts/CodeWalkthroughLayout.tsx +1 -1
  188. package/src/layouts/DocumentationLayout.tsx +23 -13
  189. package/src/markdoc/components/Cards/CardIcon.tsx +6 -21
  190. package/src/markdoc/components/CodeGroup/CodeGroup.tsx +78 -0
  191. package/src/markdoc/components/CodeWalkthrough/CodePanelHeader.tsx +7 -4
  192. package/src/markdoc/components/Heading/Heading.tsx +22 -3
  193. package/src/markdoc/components/Icon/Icon.tsx +16 -0
  194. package/src/markdoc/components/Tabs/Tab.tsx +6 -1
  195. package/src/markdoc/components/Tabs/Tabs.tsx +1 -1
  196. package/src/markdoc/components/Tabs/variables.ts +2 -0
  197. package/src/markdoc/components/default.ts +2 -0
  198. package/src/markdoc/default.ts +4 -0
  199. package/src/markdoc/tags/card.ts +1 -1
  200. package/src/markdoc/tags/code-group.ts +21 -0
  201. package/src/markdoc/tags/code-snippet.ts +1 -1
  202. package/src/markdoc/tags/icon.ts +14 -0
  203. package/src/markdoc/tags/tab.ts +1 -0
  204. package/src/core/utils/get-file-icon.ts +0 -42
  205. /package/lib/core/utils/{text-transform.d.ts → string.d.ts} +0 -0
  206. /package/src/core/utils/{text-transform.ts → string.ts} +0 -0
@@ -3,11 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useActiveHeading = useActiveHeading;
4
4
  const react_1 = require("react");
5
5
  const react_router_dom_1 = require("react-router-dom");
6
- function useActiveHeading(contentElement, displayedHeaders) {
7
- const [heading, setHeading] = (0, react_1.useState)(displayedHeaders.length > 1 ? displayedHeaders[0] : undefined);
6
+ const utils_1 = require("../utils");
7
+ function useActiveHeading(contentElement, displayedHeadings) {
8
+ const [heading, setHeading] = (0, react_1.useState)(undefined);
8
9
  const [headingElements, setHeadingElements] = (0, react_1.useState)([]);
9
10
  const headingElementsRef = (0, react_1.useRef)({});
11
+ const displayedHeadingsRef = (0, react_1.useRef)(displayedHeadings);
12
+ const lockObserver = (0, react_1.useRef)(false);
10
13
  const location = (0, react_router_dom_1.useLocation)();
14
+ (0, react_1.useEffect)(() => {
15
+ setHeading(undefined);
16
+ headingElementsRef.current = {};
17
+ }, [location.pathname]);
18
+ (0, react_1.useEffect)(() => {
19
+ displayedHeadingsRef.current = displayedHeadings;
20
+ }, [displayedHeadings]);
11
21
  const getVisibleHeadings = () => {
12
22
  const visibleHeadings = [];
13
23
  for (const key in headingElementsRef.current) {
@@ -18,28 +28,98 @@ function useActiveHeading(contentElement, displayedHeaders) {
18
28
  }
19
29
  return visibleHeadings;
20
30
  };
31
+ const isTopOfPage = () => window.scrollY <= 50;
32
+ // Returns viewport ratio for intersection observer based on screen height
33
+ const getViewportRatio = () => {
34
+ const vh = window.innerHeight;
35
+ if (vh >= 1400)
36
+ return 0.4;
37
+ if (vh >= 1000)
38
+ return 0.3;
39
+ return 0.25;
40
+ };
21
41
  const getIndexFromId = (0, react_1.useCallback)((id) => {
22
42
  return headingElements.findIndex((item) => item.id === id);
23
43
  }, [headingElements]);
24
44
  const findHeaders = (allContent) => {
25
45
  const allHeaders = allContent.querySelectorAll('.heading-anchor');
26
- return Array.from(allHeaders);
46
+ const headers = Array.from(allHeaders);
47
+ if (displayedHeadingsRef.current && displayedHeadingsRef.current.length > 0) {
48
+ const displayedIds = displayedHeadingsRef.current.map((h) => h === null || h === void 0 ? void 0 : h.id).filter(Boolean);
49
+ return headers.filter((header) => displayedIds.includes(header.id));
50
+ }
51
+ return headers;
27
52
  };
28
- const intersectionCallback = (0, react_1.useCallback)((headings) => {
53
+ const calculateVirtualPositions = (0, react_1.useCallback)((headers) => {
54
+ var _a;
55
+ if (!headers.length)
56
+ return {};
57
+ const navbarHeight = ((_a = document.querySelector('nav')) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().height) || 0;
58
+ const viewportHeight = window.innerHeight;
59
+ const triggerOffset = navbarHeight + viewportHeight * 0.25;
60
+ const lastHeader = headers[headers.length - 1];
61
+ const lastHeaderTop = lastHeader.offsetTop;
62
+ const maxScrollableHeight = document.body.scrollHeight - viewportHeight;
63
+ const requiredUplift = Math.max(0, lastHeaderTop - maxScrollableHeight + triggerOffset);
64
+ const virtualPositions = {};
65
+ for (let i = 0; i < headers.length; i++) {
66
+ const header = headers[i];
67
+ const headerTop = header.offsetTop;
68
+ const normalizedPosition = headers.length === 1 ? 0 : i / (headers.length - 1);
69
+ const adjustmentFactor = (0, utils_1.enhancedSmoothstep)(normalizedPosition, 0.4);
70
+ const uplift = requiredUplift * adjustmentFactor;
71
+ const virtualTop = headerTop - uplift;
72
+ virtualPositions[header.id] = virtualTop;
73
+ }
74
+ return virtualPositions;
75
+ }, []);
76
+ const getTriggerOffset = (0, react_1.useCallback)(() => {
29
77
  var _a;
30
- headingElementsRef.current = headings.reduce((map, headingElement) => {
31
- map[headingElement.target.id] = headingElement;
78
+ const navbarHeight = ((_a = document.querySelector('nav')) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().height) || 0;
79
+ return navbarHeight + window.innerHeight * getViewportRatio();
80
+ }, []);
81
+ const findActiveHeaderByVirtualPosition = (0, react_1.useCallback)((headers, scrollY, triggerOffset) => {
82
+ const virtualPositions = calculateVirtualPositions(headers);
83
+ let activeHeader = headers[0];
84
+ for (const header of headers) {
85
+ const virtualTop = virtualPositions[header.id] || header.offsetTop;
86
+ if (virtualTop <= scrollY + triggerOffset) {
87
+ activeHeader = header;
88
+ }
89
+ else {
90
+ break;
91
+ }
92
+ }
93
+ return activeHeader;
94
+ }, [calculateVirtualPositions]);
95
+ const intersectionCallback = (0, react_1.useCallback)((entries) => {
96
+ var _a, _b, _c;
97
+ if (lockObserver.current) {
98
+ return;
99
+ }
100
+ headingElementsRef.current = entries.reduce((map, entry) => {
101
+ map[entry.target.id] = entry;
32
102
  return map;
33
103
  }, headingElementsRef.current);
34
- const totalHeight = window.scrollY + window.innerHeight;
35
- // handle bottom of the page
36
- if (totalHeight >= document.body.scrollHeight) {
37
- const newHeading = ((_a = headingElements[(headingElements === null || headingElements === void 0 ? void 0 : headingElements.length) - 1]) === null || _a === void 0 ? void 0 : _a.id) || undefined;
104
+ if (isTopOfPage()) {
105
+ const newHeading = ((_a = headingElements[0]) === null || _a === void 0 ? void 0 : _a.id) || undefined;
38
106
  setHeading(newHeading);
39
107
  return;
40
108
  }
41
109
  const visibleHeadings = getVisibleHeadings();
42
110
  if (!visibleHeadings.length) {
111
+ const triggerOffset = getTriggerOffset();
112
+ if (isTopOfPage()) {
113
+ setHeading(((_b = headingElements[0]) === null || _b === void 0 ? void 0 : _b.id) || undefined);
114
+ return;
115
+ }
116
+ const totalHeight = window.scrollY + window.innerHeight;
117
+ if (totalHeight >= document.body.scrollHeight - 10) {
118
+ setHeading(((_c = headingElements[headingElements.length - 1]) === null || _c === void 0 ? void 0 : _c.id) || undefined);
119
+ return;
120
+ }
121
+ const activeHeader = findActiveHeaderByVirtualPosition(headingElements, window.scrollY, triggerOffset);
122
+ setHeading(activeHeader.id);
43
123
  return;
44
124
  }
45
125
  if (visibleHeadings.length === 1) {
@@ -49,31 +129,88 @@ function useActiveHeading(contentElement, displayedHeaders) {
49
129
  visibleHeadings.sort((a, b) => {
50
130
  return getIndexFromId(a.target.id) - getIndexFromId(b.target.id);
51
131
  });
132
+ const firstVisibleHeading = visibleHeadings[0];
133
+ if (getIndexFromId(firstVisibleHeading.target.id) === 0 && isTopOfPage()) {
134
+ setHeading(firstVisibleHeading.target.id);
135
+ return;
136
+ }
137
+ const totalHeight = scrollY + window.innerHeight;
138
+ if (totalHeight >= document.body.scrollHeight - 10) {
139
+ setHeading(visibleHeadings[visibleHeadings.length - 1].target.id);
140
+ return;
141
+ }
52
142
  setHeading(visibleHeadings[0].target.id);
53
- }, [getIndexFromId, headingElements]);
143
+ }, [getIndexFromId, headingElements, getTriggerOffset, findActiveHeaderByVirtualPosition]);
144
+ const handleHeadingClick = (0, react_1.useCallback)((headingId) => {
145
+ lockObserver.current = true;
146
+ setHeading(headingId);
147
+ const headingElement = headingElements.find((el) => el.id === headingId);
148
+ if (headingElement && headingElement.scrollIntoView) {
149
+ headingElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
150
+ }
151
+ setTimeout(() => {
152
+ headingElementsRef.current = {};
153
+ lockObserver.current = false;
154
+ }, 300);
155
+ }, [headingElements]);
54
156
  (0, react_1.useEffect)(() => {
157
+ var _a;
55
158
  if (!contentElement) {
56
159
  return;
57
160
  }
58
- setHeadingElements(findHeaders(contentElement));
59
- }, [contentElement, location]);
161
+ const headers = findHeaders(contentElement);
162
+ setHeadingElements(headers);
163
+ if (headers.length > 0 && !heading) {
164
+ if (isTopOfPage()) {
165
+ setHeading(headers[0].id);
166
+ }
167
+ else {
168
+ const totalHeight = scrollY + window.innerHeight;
169
+ if (totalHeight >= document.body.scrollHeight - 10) {
170
+ setHeading(((_a = headers[headers.length - 1]) === null || _a === void 0 ? void 0 : _a.id) || undefined);
171
+ }
172
+ else {
173
+ const triggerOffset = getTriggerOffset();
174
+ const activeHeader = findActiveHeaderByVirtualPosition(headers, scrollY, triggerOffset);
175
+ setHeading(activeHeader.id);
176
+ }
177
+ }
178
+ }
179
+ }, [
180
+ contentElement,
181
+ location,
182
+ heading,
183
+ calculateVirtualPositions,
184
+ getTriggerOffset,
185
+ findActiveHeaderByVirtualPosition,
186
+ ]);
60
187
  (0, react_1.useEffect)(() => {
61
188
  if (!(headingElements === null || headingElements === void 0 ? void 0 : headingElements.length)) {
62
189
  return;
63
190
  }
64
191
  headingElementsRef.current = {};
65
- // Bottom rootMargin -30% changes part of the view where IntersectionObserver starts to detect headers
192
+ const triggerOffset = getTriggerOffset();
66
193
  const observer = new IntersectionObserver(intersectionCallback, {
67
- rootMargin: '0px 0px -30% 0px',
68
- threshold: 1,
194
+ rootMargin: `-${triggerOffset}px 0px -${window.innerHeight * getViewportRatio()}px 0px`,
195
+ threshold: [0, 0.1, 0.3, 0.5, 0.7, 1],
69
196
  });
70
- headingElements === null || headingElements === void 0 ? void 0 : headingElements.forEach((element) => {
71
- if (displayedHeaders.includes(element.id)) {
72
- observer.observe(element);
73
- }
197
+ headingElements.forEach((element) => {
198
+ observer.observe(element);
74
199
  });
75
- return () => observer.disconnect();
76
- }, [headingElements, displayedHeaders, intersectionCallback]);
77
- return heading;
200
+ const handleScroll = () => {
201
+ var _a;
202
+ if (lockObserver.current)
203
+ return;
204
+ if (isTopOfPage()) {
205
+ setHeading(((_a = headingElements[0]) === null || _a === void 0 ? void 0 : _a.id) || undefined);
206
+ }
207
+ };
208
+ window.addEventListener('scroll', handleScroll, { passive: true });
209
+ return () => {
210
+ observer.disconnect();
211
+ window.removeEventListener('scroll', handleScroll);
212
+ };
213
+ }, [headingElements, intersectionCallback, getTriggerOffset]);
214
+ return { heading, handleHeadingClick };
78
215
  }
79
216
  //# sourceMappingURL=use-active-heading.js.map
@@ -1,6 +1,6 @@
1
- import type { FileTabs } from '../../components/CodeBlock/CodeBlock';
1
+ import type { CodeBlockTabItems } from '../../components/CodeBlock/CodeBlock';
2
2
  type CodeBlockTabsProps = {
3
- tabs: FileTabs;
3
+ tabs: CodeBlockTabItems;
4
4
  containerRef: React.RefObject<HTMLDivElement | null>;
5
5
  tabRefs: React.RefObject<HTMLButtonElement[]>;
6
6
  };
@@ -14,11 +14,11 @@ function useCodeBlockTabsControls({ tabs, containerRef, tabRefs }) {
14
14
  // eslint-disable-next-line react-hooks/exhaustive-deps
15
15
  [(_a = tabRefs === null || tabRefs === void 0 ? void 0 : tabRefs.current) === null || _a === void 0 ? void 0 : _a.length]);
16
16
  const { currentIndex, isFirstTab, isLastTab } = (0, react_1.useMemo)(() => {
17
- const currentIndex = tabs.files.findIndex((file) => file.name === tabs.activeTabName);
17
+ const currentIndex = tabs.items.findIndex((file) => file.name === tabs.value);
18
18
  return {
19
19
  currentIndex,
20
20
  isFirstTab: currentIndex === 0,
21
- isLastTab: currentIndex === tabs.files.length - 1,
21
+ isLastTab: currentIndex === tabs.items.length - 1,
22
22
  };
23
23
  }, [tabs]);
24
24
  (0, react_1.useEffect)(() => {
@@ -37,15 +37,15 @@ function useCodeBlockTabsControls({ tabs, containerRef, tabRefs }) {
37
37
  }, [containerRef.current]);
38
38
  const handlePrevTab = (0, react_1.useCallback)(() => {
39
39
  if (!isFirstTab) {
40
- const prevTab = tabs.files[currentIndex - 1].name;
41
- tabs.handleTabSwitch(prevTab);
40
+ const prevTab = tabs.items[currentIndex - 1].name;
41
+ tabs.onChange(prevTab);
42
42
  }
43
43
  // eslint-disable-next-line react-hooks/exhaustive-deps
44
44
  }, [currentIndex]);
45
45
  const handleNextTab = (0, react_1.useCallback)(() => {
46
46
  if (!isLastTab) {
47
- const nextTab = tabs.files[currentIndex + 1].name;
48
- tabs.handleTabSwitch(nextTab);
47
+ const nextTab = tabs.items[currentIndex + 1].name;
48
+ tabs.onChange(nextTab);
49
49
  }
50
50
  // eslint-disable-next-line react-hooks/exhaustive-deps
51
51
  }, [currentIndex]);
@@ -0,0 +1 @@
1
+ export declare function useLocalState<T>(key: string, initialValue: T): [T, (value: T) => void];
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useLocalState = useLocalState;
4
+ const react_1 = require("react");
5
+ function getInitialValue(key, initialValue) {
6
+ if (typeof window === 'undefined') {
7
+ return initialValue;
8
+ }
9
+ try {
10
+ const savedValue = localStorage.getItem(key);
11
+ if (savedValue) {
12
+ return JSON.parse(savedValue);
13
+ }
14
+ }
15
+ catch (error) {
16
+ console.error(`Error reading from localStorage for key "${key}":`, error);
17
+ }
18
+ return initialValue;
19
+ }
20
+ function useLocalState(key, initialValue) {
21
+ const [value, setValue] = (0, react_1.useState)(() => getInitialValue(key, initialValue));
22
+ (0, react_1.useEffect)(() => {
23
+ try {
24
+ localStorage.setItem(key, JSON.stringify(value));
25
+ }
26
+ catch (error) {
27
+ console.error(`Error writing to localStorage for key "${key}":`, error);
28
+ }
29
+ }, [key, value]);
30
+ return [value, setValue];
31
+ }
32
+ //# sourceMappingURL=use-local-state.js.map
@@ -0,0 +1,2 @@
1
+ import type { PageAction } from '../types';
2
+ export declare function usePageActions(pageSlug: string): PageAction[];
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.usePageActions = usePageActions;
13
+ const react_1 = require("react");
14
+ const CopyIcon_1 = require("../../icons/CopyIcon/CopyIcon");
15
+ const ChatGptIcon_1 = require("../../icons/ChatGptIcon/ChatGptIcon");
16
+ const ClaudeIcon_1 = require("../../icons/ClaudeIcon/ClaudeIcon");
17
+ const MarkdownFullIcon_1 = require("../../icons/MarkdownFullIcon/MarkdownFullIcon");
18
+ const use_theme_hooks_1 = require("./use-theme-hooks");
19
+ const use_theme_config_1 = require("./use-theme-config");
20
+ const clipboard_service_1 = require("../utils/clipboard-service");
21
+ const dom_1 = require("../utils/dom");
22
+ const DEFAULT_ENABLED_ACTIONS = ['copy', 'view', 'chatgpt', 'claude'];
23
+ function usePageActions(pageSlug) {
24
+ var _a, _b, _c;
25
+ const { useTranslate, usePageData, usePageProps } = (0, use_theme_hooks_1.useThemeHooks)();
26
+ const { translate } = useTranslate();
27
+ const { navigation } = (0, use_theme_config_1.useThemeConfig)();
28
+ // Can't use any actions if no markdown files are generated for LLMs
29
+ const isLlmsDisabled = ((_c = (_b = (_a = usePageProps()) === null || _a === void 0 ? void 0 : _a.seo) === null || _b === void 0 ? void 0 : _b.llmstxt) === null || _c === void 0 ? void 0 : _c.hide) === true;
30
+ const { isPublic } = usePageData() || {};
31
+ const actions = (0, react_1.useMemo)(() => {
32
+ var _a, _b;
33
+ if (((_a = navigation === null || navigation === void 0 ? void 0 : navigation.actions) === null || _a === void 0 ? void 0 : _a.hide) || isLlmsDisabled) {
34
+ return [];
35
+ }
36
+ const origin = dom_1.IS_BROWSER ? window.location.origin : globalThis['SSR_HOSTNAME'];
37
+ const normalizedSlug = pageSlug.startsWith('/') ? pageSlug : '/' + pageSlug;
38
+ const mdPageUrl = new URL(origin + normalizedSlug + (normalizedSlug === '/' ? 'index.html.md' : '.md')).toString();
39
+ function getExternalAiPromptLink(baseUrl) {
40
+ const externalAiPrompt = `Read ${mdPageUrl} and answer questions based on the content.`;
41
+ const url = new URL(baseUrl);
42
+ url.searchParams.set('q', externalAiPrompt);
43
+ return url.toString();
44
+ }
45
+ return (((_b = navigation === null || navigation === void 0 ? void 0 : navigation.actions) === null || _b === void 0 ? void 0 : _b.items) || DEFAULT_ENABLED_ACTIONS)
46
+ .map((action) => {
47
+ switch (action) {
48
+ case 'copy':
49
+ return {
50
+ buttonText: translate('page.actions.copyButtonText', 'Copy'),
51
+ title: translate('page.actions.copyTitle', 'Copy for LLM'),
52
+ description: translate('page.actions.copyDescription', 'Copy page as Markdown for LLMs'),
53
+ iconComponent: CopyIcon_1.CopyIcon,
54
+ onClick: () => __awaiter(this, void 0, void 0, function* () {
55
+ try {
56
+ const result = yield fetch(mdPageUrl);
57
+ const text = yield result.text();
58
+ clipboard_service_1.ClipboardService.copyCustom(text);
59
+ }
60
+ catch (error) {
61
+ console.error(error);
62
+ }
63
+ }),
64
+ };
65
+ case 'view':
66
+ return {
67
+ buttonText: translate('page.actions.viewAsMdButtonText', 'View as Markdown'),
68
+ title: translate('page.actions.viewAsMdTitle', 'View as Markdown'),
69
+ description: translate('page.actions.viewAsMdDescription', 'Open this page as Markdown'),
70
+ iconComponent: MarkdownFullIcon_1.MarkdownFullIcon,
71
+ link: mdPageUrl,
72
+ };
73
+ case 'chatgpt':
74
+ if (!isPublic) {
75
+ return null;
76
+ }
77
+ return {
78
+ buttonText: translate('page.actions.chatGptButtonText', 'Open in ChatGPT'),
79
+ title: translate('page.actions.chatGptTitle', 'Open in ChatGPT'),
80
+ description: translate('page.actions.chatGptDescription', 'Get insights from ChatGPT'),
81
+ iconComponent: ChatGptIcon_1.ChatGptIcon,
82
+ link: getExternalAiPromptLink('https://chat.openai.com'),
83
+ };
84
+ case 'claude':
85
+ if (!isPublic) {
86
+ return null;
87
+ }
88
+ return {
89
+ buttonText: translate('page.actions.claudeButtonText', 'Open in Claude'),
90
+ title: translate('page.actions.claudeTitle', 'Open in Claude'),
91
+ description: translate('page.actions.claudeDescription', 'Get insights from Claude'),
92
+ iconComponent: ClaudeIcon_1.ClaudeIcon,
93
+ link: getExternalAiPromptLink('https://claude.ai/new'),
94
+ };
95
+ }
96
+ })
97
+ .filter((action) => action !== null);
98
+ }, [navigation, translate, pageSlug, isPublic, isLlmsDisabled]);
99
+ return actions;
100
+ }
101
+ //# sourceMappingURL=use-page-actions.js.map
@@ -16,6 +16,8 @@ const fallbacks = {
16
16
  useBreadcrumbs: () => [],
17
17
  useCodeHighlight: () => ({ highlight: (rawContent) => rawContent }),
18
18
  useUserMenu: () => ({}),
19
+ usePageData: () => null,
20
+ usePageProps: () => ({}),
19
21
  };
20
22
  const useThemeHooks = () => {
21
23
  const context = (0, react_1.useContext)(ThemeDataContext_1.ThemeDataContext);
@@ -13,6 +13,7 @@ const variables_dark_8 = require("../../components/StatusCode/variables.dark");
13
13
  const variables_dark_9 = require("../../components/Switch/variables.dark");
14
14
  const variables_dark_10 = require("../../markdoc/components/Cards/variables.dark");
15
15
  const variables_dark_11 = require("../../components/Catalog/variables.dark");
16
+ const variables_dark_12 = require("../../components/PageActions/variables.dark");
16
17
  const replayDarkMode = (0, styled_components_1.css) `
17
18
  /**
18
19
  * @tokens Replay Colors
@@ -316,6 +317,7 @@ exports.darkMode = (0, styled_components_1.css) `
316
317
  ${variables_dark_9.switcherDarkMode}
317
318
  ${variables_dark_10.cardsDarkMode}
318
319
  ${variables_dark_11.catalogDarkMode}
320
+ ${variables_dark_12.pageActionsDarkMode}
319
321
 
320
322
  /**
321
323
  * @tokens Dark Theme Scrollbar Config
@@ -40,6 +40,7 @@ const variables_35 = require("../../components/Switch/variables");
40
40
  const variables_36 = require("../../markdoc/components/Cards/variables");
41
41
  const variables_37 = require("../../markdoc/components/CodeWalkthrough/variables");
42
42
  const variables_38 = require("../../components/SkipContent/variables");
43
+ const variables_39 = require("../../components/PageActions/variables");
43
44
  const dark_1 = require("./dark");
44
45
  const themeColors = (0, styled_components_1.css) `
45
46
  /* === Palette === */
@@ -1245,6 +1246,7 @@ exports.styles = (0, styled_components_1.css) `
1245
1246
  ${variables_34.datePicker}
1246
1247
  ${replay}
1247
1248
  ${variables_38.skipContent}
1249
+ ${variables_39.pageActions}
1248
1250
 
1249
1251
  background-color: var(--bg-color);
1250
1252
  color: var(--text-color-primary);
@@ -1,4 +1,4 @@
1
- import type { CatalogEntityConfig, PageProps, ResolvedNavItemWithLink, Version } from '@redocly/config';
1
+ import type { CatalogEntityConfig, PageData, PageProps, ResolvedNavItemWithLink, Version } from '@redocly/config';
2
2
  import type { ShikiTransformer } from '@shikijs/types';
3
3
  import type { Callback, TFunction as TFunc } from 'i18next';
4
4
  import type { To, Location, NavigateFunction } from 'react-router-dom';
@@ -121,6 +121,7 @@ export type ThemeHooks = {
121
121
  send<TEventType extends EventType>(event: SendEventParams<TEventType>): void;
122
122
  };
123
123
  useUserTeams: () => string[];
124
+ usePageData: () => PageData | null;
124
125
  usePageProps: <T extends Record<string, unknown>>() => PageProps & T;
125
126
  useCodeHighlight: () => {
126
127
  highlight: (code: string, language?: string | undefined, highlightOptions?: {
@@ -16,3 +16,4 @@ export * from './open-api-server';
16
16
  export * from './marker';
17
17
  export * from './code-walkthrough';
18
18
  export * from './telemetry';
19
+ export * from './page-actions';
@@ -32,4 +32,5 @@ __exportStar(require("./open-api-server"), exports);
32
32
  __exportStar(require("./marker"), exports);
33
33
  __exportStar(require("./code-walkthrough"), exports);
34
34
  __exportStar(require("./telemetry"), exports);
35
+ __exportStar(require("./page-actions"), exports);
35
36
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
1
  import type { TOptions } from 'i18next';
2
- export type TranslationKey = 'dev.newApp' | 'dev.newApp.text' | 'dev.sidebar.header' | 'dev.sidebar.footer.text' | 'dev.create.app.dialog.appName.placeholder' | 'dev.create.app.dialog.appName.error' | 'dev.create.app.dialog.selectAPIs' | 'dev.create.app.dialog.description' | 'dev.create.app.dialog.description.placeholder' | 'dev.create.app.dialog.create' | 'dev.create.app.dialog.cancel' | 'dev.main.tab.appKeys' | 'dev.main.tab.logs' | 'dev.app.description.title' | 'dev.edit.description.dialog.title' | 'dev.edit.description.dialog.save' | 'dev.edit.description.dialog.cancel' | 'dev.edit.apis.dialog.selectedAPIs' | 'dev.app.key.create' | 'dev.create.key.dialog.title' | 'dev.create.key.dialog.create' | 'dev.create.key.dialog.cancel' | 'dev.app.edit' | 'dev.app.delete' | 'dev.edit.app.dialog.title' | 'dev.edit.app.dialog.save' | 'dev.edit.app.dialog.cancel' | 'dev.delete.app.dialog.title' | 'dev.delete.app.dialog.confirmation' | 'dev.delete.app.dialog.delete' | 'dev.delete.app.dialog.cancel' | 'dev.app.key.roll' | 'dev.roll.key.dialog.title' | 'dev.roll.key.dialog.apiKey' | 'dev.roll.key.dialog.expires' | 'dev.roll.key.dialog.confirmation' | 'dev.roll.key.dialog.cancel' | 'dev.roll.key.dialog.roll' | 'dev.update.key.dialog.title' | 'dev.update.key.dialog.update' | 'dev.update.key.dialog.cancel' | 'dev.app.key.api.name' | 'dev.app.key.api.status' | 'dev.app.key.api.edit' | 'dev.edit.apis.dialog.title' | 'dev.edit.apis.dialog.apiKey' | 'dev.edit.apis.dialog.save' | 'dev.edit.apis.dialog.cancel' | 'dev.select.placeholder' | 'dev.app.overview.status.pending' | 'dev.app.overview.status.approved' | 'dev.app.overview.status.revoked' | 'dev.app.overview.status' | 'dev.app.overview.non-production' | 'dev.app.overview.production' | 'dev.app.overview.clientId' | 'dev.app.overview.apiKey' | 'dev.app.key.revoke' | 'dev.revoke.key.dialog.title' | 'dev.revoke.key.dialog.apiKey' | 'dev.revoke.key.dialog.expires' | 'dev.revoke.key.dialog.confirmation' | 'dev.revoke.key.dialog.revoke' | 'dev.revoke.key.dialog.cancel' | 'dev.app.overview.expires' | 'dev.app.overview.created' | 'dev.app.overview.visibilityToggle.hide' | 'dev.app.overview.visibilityToggle.show' | 'search.loading' | 'search.noResults.title' | 'search.keys.navigate' | 'search.keys.select' | 'search.keys.exit' | 'search.label' | 'search.cancel' | 'search.recent' | 'search.navbar.label' | 'search.suggested' | 'search.showMore' | 'search.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.welcomeText' | 'search.ai.newConversation' | 'search.ai.backToSearch' | 'search.ai.placeholder' | 'search.ai.generatingResponse' | 'search.ai.followUpQuestion' | 'search.ai.suggestionsTitle' | 'search.ai.thinkingText' | 'search.ai.resourcesFound' | 'search.ai.resourcesFound.basedOn' | 'search.ai.resourcesFound.resources' | 'search.ai.button' | 'search.ai.label' | 'search.ai.disclaimer' | 'search.ai.error.description' | 'search.ai.error.description.forbidden' | 'search.ai.error.description.unauthorized' | 'search.ai.error.header' | 'search.ai.error.header.forbidden' | 'search.ai.error.header.unauthorized' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.notFound.title' | 'page.notFound.description' | 'page.lastUpdated.timeago' | 'page.lastUpdated.on' | 'catalog.filters.placeholder' | 'catalog.filters.title' | 'catalog.filters.add' | 'catalog.filters.clearAll' | 'catalog.filters.select.addFilter' | 'catalog.filters.select.all' | 'catalog.filters.done' | 'catalog.catalogs.all.title' | 'catalog.catalogs.all.description' | 'catalog.catalogs.all.switcherLabel' | 'catalog.catalogs.service.title' | 'catalog.catalogs.service.description' | 'catalog.catalogs.service.switcherLabel' | 'catalog.catalogs.user.title' | 'catalog.catalogs.user.description' | 'catalog.catalogs.user.switcherLabel' | 'catalog.catalogs.team.title' | 'catalog.catalogs.team.description' | 'catalog.catalogs.team.switcherLabel' | 'catalog.catalogs.domain.title' | 'catalog.catalogs.domain.description' | 'catalog.catalogs.domain.switcherLabel' | 'catalog.catalogs.apiDescription.title' | 'catalog.catalogs.apiDescription.description' | 'catalog.catalogs.apiDescription.switcherLabel' | 'catalog.catalogs.dataSchema.title' | 'catalog.catalogs.dataSchema.description' | 'catalog.catalogs.dataSchema.switcherLabel' | 'catalog.catalogs.apiOperation.title' | 'catalog.catalogs.apiOperation.description' | 'catalog.catalogs.apiOperation.switcherLabel' | 'catalog.entity.metadata.title' | 'catalog.entity.schema.title' | 'catalog.entity.properties.apiDescription.title' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeLayout' | 'versionPicker.label' | 'versionPicker.unversioned' | 'codeSnippet.copy.buttonText' | 'codeSnippet.copy.tooltipText' | 'codeSnippet.copy.toasterText' | 'markdown.editPage.text' | 'feedback.settings.comment.submitText' | 'feedback.settings.comment.label' | 'feedback.settings.comment.send' | 'feedback.settings.comment.cancel' | 'feedback.settings.comment.satisfiedLabel' | 'feedback.settings.comment.neutralLabel' | 'feedback.settings.comment.dissatisfiedLabel' | 'feedback.settings.submitText' | 'feedback.settings.label' | 'feedback.settings.reasons.label' | 'feedback.submit' | 'feedback.cancel' | 'feedback.settings.comment.likeLabel' | 'feedback.settings.comment.dislikeLabel' | 'feedback.sentiment.thumbUp' | 'feedback.sentiment.thumbDown' | 'feedback.settings.leftScaleLabel' | 'feedback.settings.rightScaleLabel' | 'feedback.settings.optionalEmail.placeholder' | 'feedback.settings.optionalEmail.label' | 'codeSnippet.report.buttonText' | 'codeSnippet.report.tooltipText' | 'codeSnippet.report.label' | 'codeSnippet.expand.tooltipText' | 'codeSnippet.collapse.tooltipText' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'mobileMenu.version' | 'navbar.products' | 'page.nextButton' | 'page.previousButton' | 'openapi.download.description.title' | 'openapi.info.title' | 'openapi.info.contact.url' | 'openapi.info.contact.name' | 'openapi.info.license' | 'openapi.info.termsOfService' | 'openapi.info.metadata.title' | 'openapi.key' | 'openapi.value' | 'openapi.enum' | 'openapi.items' | 'openapi.default' | 'openapi.variable' | 'openapi.variables' | 'openapi.actions.show' | 'openapi.actions.hide' | 'openapi.actions.more' | 'openapi.languages.title' | 'openapi.servers.title' | 'openapi.operations' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | 'openapi.cookie' | 'openapi.header' | 'openapi.body' | 'openapi.responses' | 'openapi.response' | 'openapi.callbacks' | 'openapi.callbackRequest' | 'openapi.callbackResponse' | 'openapi.payload' | 'openapi.discriminator' | 'openapi.contentType' | 'openapi.tryIt' | 'openapi.loading' | 'openapi.example' | 'openapi.examples' | 'openapi.additionalProperties' | 'openapi.patternProperties' | 'openapi.required' | 'openapi.recursive' | 'openapi.complex' | 'openapi.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.viewSecurityDetails' | 'openapi.noResponseExample' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | 'openapi.hidePattern' | 'openapi.showPattern' | 'openapi.authorizationUrl' | 'openapi.tokenUrl' | 'openapi.refreshUrl' | 'openapi.showOptionalScopes' | 'openapi.hideOptionalScopes' | 'openapi.security' | 'openapi.httpAuthorizationScheme' | 'openapi.bearerFormat' | 'openapi.parameterName' | 'openapi.flowType' | 'openapi.connectUrl' | 'openapi.requiredScopes' | 'openapi.unsupportedLanguage' | 'openapi.failedToGenerateCodeSample' | 'asyncapi.download.description.title' | 'asyncapi.info.title' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | 'graphql.arguments.label' | 'graphql.arguments.show' | 'graphql.arguments.hide' | 'graphql.arguments.here' | 'graphql.returnTypes.label' | 'graphql.returnTypes.show' | 'graphql.returnTypes.hide' | 'graphql.possibleTypes' | 'graphql.defaultValue' | 'graphql.deprecationReason' | 'graphql.implementedInterfaces' | 'graphql.nonNull' | 'graphql.required' | 'graphql.deprecated' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'graphql.content.fragment' | 'codeWalkthrough.download' | 'codeWalkthrough.preview' | 'time.justNow' | 'time.past.second' | 'time.past.seconds' | 'time.past.minute' | 'time.past.minutes' | 'time.past.hour' | 'time.past.hours' | 'time.past.day' | 'time.past.days' | 'time.past.week' | 'time.past.weeks' | 'time.past.month' | 'time.past.months' | 'time.past.year' | 'time.past.years' | 'page.internalServerError.title' | 'page.internalServerError.description' | 'page.skipToContent.label';
2
+ export type TranslationKey = 'dev.newApp' | 'dev.newApp.text' | 'dev.sidebar.header' | 'dev.sidebar.footer.text' | 'dev.create.app.dialog.appName.placeholder' | 'dev.create.app.dialog.appName.error' | 'dev.create.app.dialog.selectAPIs' | 'dev.create.app.dialog.description' | 'dev.create.app.dialog.description.placeholder' | 'dev.create.app.dialog.create' | 'dev.create.app.dialog.cancel' | 'dev.main.tab.appKeys' | 'dev.main.tab.logs' | 'dev.app.description.title' | 'dev.edit.description.dialog.title' | 'dev.edit.description.dialog.save' | 'dev.edit.description.dialog.cancel' | 'dev.edit.apis.dialog.selectedAPIs' | 'dev.app.key.create' | 'dev.create.key.dialog.title' | 'dev.create.key.dialog.create' | 'dev.create.key.dialog.cancel' | 'dev.app.edit' | 'dev.app.delete' | 'dev.edit.app.dialog.title' | 'dev.edit.app.dialog.save' | 'dev.edit.app.dialog.cancel' | 'dev.delete.app.dialog.title' | 'dev.delete.app.dialog.confirmation' | 'dev.delete.app.dialog.delete' | 'dev.delete.app.dialog.cancel' | 'dev.app.key.roll' | 'dev.roll.key.dialog.title' | 'dev.roll.key.dialog.apiKey' | 'dev.roll.key.dialog.expires' | 'dev.roll.key.dialog.confirmation' | 'dev.roll.key.dialog.cancel' | 'dev.roll.key.dialog.roll' | 'dev.update.key.dialog.title' | 'dev.update.key.dialog.update' | 'dev.update.key.dialog.cancel' | 'dev.app.key.api.name' | 'dev.app.key.api.status' | 'dev.app.key.api.edit' | 'dev.edit.apis.dialog.title' | 'dev.edit.apis.dialog.apiKey' | 'dev.edit.apis.dialog.save' | 'dev.edit.apis.dialog.cancel' | 'dev.select.placeholder' | 'dev.app.overview.status.pending' | 'dev.app.overview.status.approved' | 'dev.app.overview.status.revoked' | 'dev.app.overview.status' | 'dev.app.overview.non-production' | 'dev.app.overview.production' | 'dev.app.overview.clientId' | 'dev.app.overview.apiKey' | 'dev.app.key.revoke' | 'dev.revoke.key.dialog.title' | 'dev.revoke.key.dialog.apiKey' | 'dev.revoke.key.dialog.expires' | 'dev.revoke.key.dialog.confirmation' | 'dev.revoke.key.dialog.revoke' | 'dev.revoke.key.dialog.cancel' | 'dev.app.overview.expires' | 'dev.app.overview.created' | 'dev.app.overview.visibilityToggle.hide' | 'dev.app.overview.visibilityToggle.show' | 'search.loading' | 'search.noResults.title' | 'search.keys.navigate' | 'search.keys.select' | 'search.keys.exit' | 'search.label' | 'search.cancel' | 'search.recent' | 'search.navbar.label' | 'search.suggested' | 'search.showMore' | 'search.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.welcomeText' | 'search.ai.newConversation' | 'search.ai.backToSearch' | 'search.ai.placeholder' | 'search.ai.generatingResponse' | 'search.ai.followUpQuestion' | 'search.ai.suggestionsTitle' | 'search.ai.thinkingText' | 'search.ai.resourcesFound' | 'search.ai.resourcesFound.basedOn' | 'search.ai.resourcesFound.resources' | 'search.ai.button' | 'search.ai.label' | 'search.ai.disclaimer' | 'search.ai.error.description' | 'search.ai.error.description.forbidden' | 'search.ai.error.description.unauthorized' | 'search.ai.error.header' | 'search.ai.error.header.forbidden' | 'search.ai.error.header.unauthorized' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.notFound.title' | 'page.notFound.description' | 'page.lastUpdated.timeago' | 'page.lastUpdated.on' | 'catalog.filters.placeholder' | 'catalog.filters.title' | 'catalog.filters.add' | 'catalog.filters.clearAll' | 'catalog.filters.select.addFilter' | 'catalog.filters.select.all' | 'catalog.filters.done' | 'catalog.catalogs.all.title' | 'catalog.catalogs.all.description' | 'catalog.catalogs.all.switcherLabel' | 'catalog.catalogs.service.title' | 'catalog.catalogs.service.description' | 'catalog.catalogs.service.switcherLabel' | 'catalog.catalogs.user.title' | 'catalog.catalogs.user.description' | 'catalog.catalogs.user.switcherLabel' | 'catalog.catalogs.team.title' | 'catalog.catalogs.team.description' | 'catalog.catalogs.team.switcherLabel' | 'catalog.catalogs.domain.title' | 'catalog.catalogs.domain.description' | 'catalog.catalogs.domain.switcherLabel' | 'catalog.catalogs.apiDescription.title' | 'catalog.catalogs.apiDescription.description' | 'catalog.catalogs.apiDescription.switcherLabel' | 'catalog.catalogs.dataSchema.title' | 'catalog.catalogs.dataSchema.description' | 'catalog.catalogs.dataSchema.switcherLabel' | 'catalog.catalogs.apiOperation.title' | 'catalog.catalogs.apiOperation.description' | 'catalog.catalogs.apiOperation.switcherLabel' | 'catalog.entity.metadata.title' | 'catalog.entity.schema.title' | 'catalog.entity.properties.apiDescription.title' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeLayout' | 'versionPicker.label' | 'versionPicker.unversioned' | 'codeSnippet.copy.buttonText' | 'codeSnippet.copy.tooltipText' | 'codeSnippet.copy.toasterText' | 'markdown.editPage.text' | 'feedback.settings.comment.submitText' | 'feedback.settings.comment.label' | 'feedback.settings.comment.send' | 'feedback.settings.comment.cancel' | 'feedback.settings.comment.satisfiedLabel' | 'feedback.settings.comment.neutralLabel' | 'feedback.settings.comment.dissatisfiedLabel' | 'feedback.settings.submitText' | 'feedback.settings.label' | 'feedback.settings.reasons.label' | 'feedback.submit' | 'feedback.cancel' | 'feedback.settings.comment.likeLabel' | 'feedback.settings.comment.dislikeLabel' | 'feedback.sentiment.thumbUp' | 'feedback.sentiment.thumbDown' | 'feedback.settings.leftScaleLabel' | 'feedback.settings.rightScaleLabel' | 'feedback.settings.optionalEmail.placeholder' | 'feedback.settings.optionalEmail.label' | 'codeSnippet.report.buttonText' | 'codeSnippet.report.tooltipText' | 'codeSnippet.report.label' | 'codeSnippet.expand.tooltipText' | 'codeSnippet.collapse.tooltipText' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'mobileMenu.version' | 'navbar.products' | 'page.nextButton' | 'page.previousButton' | 'page.actions.copyButtonText' | 'page.actions.copyTitle' | 'page.actions.copyDescription' | 'page.actions.viewAsMdTitle' | 'page.actions.viewAsMdButtonText' | 'page.actions.viewAsMdDescription' | 'page.actions.chatGptTitle' | 'page.actions.chatGptButtonText' | 'page.actions.chatGptDescription' | 'page.actions.claudeTitle' | 'page.actions.claudeButtonText' | 'page.actions.claudeDescription' | 'openapi.download.description.title' | 'openapi.info.title' | 'openapi.info.contact.url' | 'openapi.info.contact.name' | 'openapi.info.license' | 'openapi.info.termsOfService' | 'openapi.info.metadata.title' | 'openapi.key' | 'openapi.value' | 'openapi.enum' | 'openapi.items' | 'openapi.default' | 'openapi.variable' | 'openapi.variables' | 'openapi.actions.show' | 'openapi.actions.hide' | 'openapi.actions.more' | 'openapi.languages.title' | 'openapi.servers.title' | 'openapi.operations' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | 'openapi.cookie' | 'openapi.header' | 'openapi.body' | 'openapi.responses' | 'openapi.response' | 'openapi.callbacks' | 'openapi.callbackRequest' | 'openapi.callbackResponse' | 'openapi.payload' | 'openapi.discriminator' | 'openapi.contentType' | 'openapi.tryIt' | 'openapi.loading' | 'openapi.example' | 'openapi.examples' | 'openapi.additionalProperties' | 'openapi.patternProperties' | 'openapi.required' | 'openapi.recursive' | 'openapi.complex' | 'openapi.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.viewSecurityDetails' | 'openapi.noResponseExample' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | 'openapi.hidePattern' | 'openapi.showPattern' | 'openapi.authorizationUrl' | 'openapi.tokenUrl' | 'openapi.refreshUrl' | 'openapi.showOptionalScopes' | 'openapi.hideOptionalScopes' | 'openapi.security' | 'openapi.httpAuthorizationScheme' | 'openapi.bearerFormat' | 'openapi.parameterName' | 'openapi.flowType' | 'openapi.connectUrl' | 'openapi.requiredScopes' | 'openapi.unsupportedLanguage' | 'openapi.failedToGenerateCodeSample' | 'asyncapi.download.description.title' | 'asyncapi.info.title' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | 'graphql.arguments.label' | 'graphql.arguments.show' | 'graphql.arguments.hide' | 'graphql.arguments.here' | 'graphql.returnTypes.label' | 'graphql.returnTypes.show' | 'graphql.returnTypes.hide' | 'graphql.possibleTypes' | 'graphql.defaultValue' | 'graphql.deprecationReason' | 'graphql.implementedInterfaces' | 'graphql.nonNull' | 'graphql.required' | 'graphql.deprecated' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'graphql.content.fragment' | 'codeWalkthrough.download' | 'codeWalkthrough.preview' | 'time.justNow' | 'time.past.second' | 'time.past.seconds' | 'time.past.minute' | 'time.past.minutes' | 'time.past.hour' | 'time.past.hours' | 'time.past.day' | 'time.past.days' | 'time.past.week' | 'time.past.weeks' | 'time.past.month' | 'time.past.months' | 'time.past.year' | 'time.past.years' | 'page.internalServerError.title' | 'page.internalServerError.description' | 'page.skipToContent.label';
3
3
  export type Locale = {
4
4
  code: string;
5
5
  name: string;
@@ -0,0 +1,15 @@
1
+ import type { ComponentType } from 'react';
2
+ type BaseAction = {
3
+ title: string;
4
+ description: string;
5
+ iconComponent: ComponentType;
6
+ buttonText: string;
7
+ };
8
+ type LinkPageAction = BaseAction & {
9
+ link: string;
10
+ };
11
+ type ClickPageAction = BaseAction & {
12
+ onClick: () => Promise<void> | void;
13
+ };
14
+ export type PageAction = LinkPageAction | ClickPageAction;
15
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=page-actions.js.map
@@ -7,6 +7,7 @@ export type SidebarNavItem = {
7
7
  sublabel?: string;
8
8
  subLabelTranslationKey?: string;
9
9
  icon?: string;
10
+ srcSet?: string;
10
11
  link?: string;
11
12
  type?: string;
12
13
  httpVerb?: string;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Enhanced smoothstep function for smooth interpolation with configurable threshold.
3
+ * Used in active heading detection to create virtual positions for better scroll behavior.
4
+ */
5
+ export declare function enhancedSmoothstep(input: number, threshold?: number): number;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enhancedSmoothstep = enhancedSmoothstep;
4
+ /**
5
+ * Enhanced smoothstep function for smooth interpolation with configurable threshold.
6
+ * Used in active heading detection to create virtual positions for better scroll behavior.
7
+ */
8
+ function enhancedSmoothstep(input, threshold = 0.4) {
9
+ if (input <= threshold) {
10
+ return 0;
11
+ }
12
+ const normalizedValue = Math.min(Math.max((input - threshold) / (1 - threshold), 0), 1);
13
+ return (3 * normalizedValue * normalizedValue - 2 * normalizedValue * normalizedValue * normalizedValue);
14
+ }
15
+ //# sourceMappingURL=enhanced-smoothstep.js.map
@@ -1,2 +1,3 @@
1
- import type { IconProps } from '../../icons/types';
2
- export declare function getFileIconByExt(ext: string): import("react").FunctionComponent<IconProps>;
1
+ import * as React from 'react';
2
+ export declare function getFileIconByExt(ext: string): React.JSX.Element;
3
+ export declare function getFileIconByLanguage(language: string): React.JSX.Element;