@redocly/theme 0.47.0 → 0.48.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 (219) hide show
  1. package/lib/components/Buttons/CopyButton.d.ts +8 -3
  2. package/lib/components/Buttons/CopyButton.js +4 -3
  3. package/lib/components/Feedback/Mood.d.ts +2 -2
  4. package/lib/components/Feedback/Mood.js +6 -6
  5. package/lib/components/Feedback/Rating.d.ts +2 -2
  6. package/lib/components/Feedback/Rating.js +6 -6
  7. package/lib/components/Feedback/Scale.d.ts +2 -2
  8. package/lib/components/Feedback/Scale.js +6 -6
  9. package/lib/components/Feedback/Sentiment.d.ts +2 -2
  10. package/lib/components/Feedback/Sentiment.js +6 -6
  11. package/lib/components/Search/SearchDialog.js +8 -8
  12. package/lib/components/Search/SearchFilter.d.ts +3 -2
  13. package/lib/components/Search/SearchFilter.js +2 -2
  14. package/lib/components/Search/SearchFilterField.d.ts +3 -2
  15. package/lib/components/Search/SearchFilterField.js +2 -2
  16. package/lib/components/Search/SearchGroups.d.ts +5 -4
  17. package/lib/components/Search/SearchGroups.js +3 -3
  18. package/lib/components/StatusCode/StatusCode.js +11 -14
  19. package/lib/core/constants/code-walkthrough.d.ts +1 -0
  20. package/lib/core/constants/code-walkthrough.js +5 -0
  21. package/lib/core/constants/index.d.ts +1 -0
  22. package/lib/core/constants/index.js +1 -0
  23. package/lib/core/contexts/CodeWalkthrough/CodeWalkthroughControlsContext.d.ts +2 -0
  24. package/lib/core/contexts/CodeWalkthrough/CodeWalkthroughControlsContext.js +18 -0
  25. package/lib/core/contexts/CodeWalkthrough/CodeWalkthroughStepsContext.d.ts +2 -0
  26. package/lib/core/contexts/CodeWalkthrough/CodeWalkthroughStepsContext.js +11 -0
  27. package/lib/core/contexts/index.d.ts +2 -0
  28. package/lib/core/contexts/index.js +2 -0
  29. package/lib/core/hooks/__mocks__/search/use-search-filter.d.ts +1 -1
  30. package/lib/core/hooks/__mocks__/search/use-search-filter.js +1 -1
  31. package/lib/core/hooks/code-walkthrough/__mocks__/MockIntersectionObserver.d.ts +10 -0
  32. package/lib/core/hooks/code-walkthrough/__mocks__/MockIntersectionObserver.js +55 -0
  33. package/lib/core/hooks/code-walkthrough/use-code-panel.d.ts +6 -0
  34. package/lib/core/hooks/code-walkthrough/use-code-panel.js +93 -0
  35. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.d.ts +22 -0
  36. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.js +183 -0
  37. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.d.ts +16 -0
  38. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.js +117 -0
  39. package/lib/core/hooks/code-walkthrough/use-code-walkthrough.d.ts +14 -0
  40. package/lib/core/hooks/code-walkthrough/use-code-walkthrough.js +22 -0
  41. package/lib/core/hooks/index.d.ts +4 -0
  42. package/lib/core/hooks/index.js +4 -0
  43. package/lib/core/hooks/search/use-search-filter.d.ts +2 -2
  44. package/lib/core/hooks/search/use-search-filter.js +5 -5
  45. package/lib/core/styles/global.js +2 -0
  46. package/lib/core/templates/Markdown.d.ts +8 -2
  47. package/lib/core/templates/Markdown.js +5 -2
  48. package/lib/core/types/hooks.d.ts +3 -0
  49. package/lib/core/types/l10n.d.ts +1 -1
  50. package/lib/core/types/search.d.ts +1 -2
  51. package/lib/core/utils/download-code-walkthrough.d.ts +4 -0
  52. package/lib/core/utils/download-code-walkthrough.js +32 -0
  53. package/lib/core/utils/get-code-walkthrough-file-text.d.ts +4 -0
  54. package/lib/core/utils/get-code-walkthrough-file-text.js +22 -0
  55. package/lib/core/utils/get-file-icon.d.ts +2 -0
  56. package/lib/core/utils/get-file-icon.js +31 -0
  57. package/lib/core/utils/index.d.ts +5 -0
  58. package/lib/core/utils/index.js +5 -0
  59. package/lib/core/utils/js-utils.d.ts +30 -0
  60. package/lib/core/utils/js-utils.js +41 -0
  61. package/lib/core/utils/match-code-walkthrough-conditions.d.ts +4 -0
  62. package/lib/core/utils/match-code-walkthrough-conditions.js +23 -0
  63. package/lib/core/utils/replace-inputs-with-value.d.ts +3 -0
  64. package/lib/core/utils/replace-inputs-with-value.js +16 -0
  65. package/lib/icons/DocumentCssIcon/DocumentCssIcon.d.ts +9 -0
  66. package/lib/icons/DocumentCssIcon/DocumentCssIcon.js +23 -0
  67. package/lib/icons/DocumentCssIcon/index.d.ts +1 -0
  68. package/lib/icons/DocumentCssIcon/index.js +6 -0
  69. package/lib/icons/DocumentGraphqlIcon/DocumentGraphqlIcon.d.ts +9 -0
  70. package/lib/icons/DocumentGraphqlIcon/DocumentGraphqlIcon.js +31 -0
  71. package/lib/icons/DocumentGraphqlIcon/index.d.ts +1 -0
  72. package/lib/icons/DocumentGraphqlIcon/index.js +6 -0
  73. package/lib/icons/DocumentHtmlIcon/DocumentHtmlIcon.d.ts +9 -0
  74. package/lib/icons/DocumentHtmlIcon/DocumentHtmlIcon.js +23 -0
  75. package/lib/icons/DocumentHtmlIcon/index.d.ts +1 -0
  76. package/lib/icons/DocumentHtmlIcon/index.js +6 -0
  77. package/lib/icons/DocumentJsIcon/DocumentJsIcon.d.ts +9 -0
  78. package/lib/icons/DocumentJsIcon/DocumentJsIcon.js +23 -0
  79. package/lib/icons/DocumentJsIcon/index.d.ts +1 -0
  80. package/lib/icons/DocumentJsIcon/index.js +6 -0
  81. package/lib/icons/DocumentJsonIcon/DocumentJsonIcon.d.ts +9 -0
  82. package/lib/icons/DocumentJsonIcon/DocumentJsonIcon.js +23 -0
  83. package/lib/icons/DocumentJsonIcon/index.d.ts +1 -0
  84. package/lib/icons/DocumentJsonIcon/index.js +6 -0
  85. package/lib/icons/DocumentMarkdownIcon/DocumentMarkdownIcon.d.ts +9 -0
  86. package/lib/icons/DocumentMarkdownIcon/DocumentMarkdownIcon.js +23 -0
  87. package/lib/icons/DocumentMarkdownIcon/index.d.ts +1 -0
  88. package/lib/icons/DocumentMarkdownIcon/index.js +6 -0
  89. package/lib/icons/DocumentReactIcon/DocumentReactIcon.d.ts +9 -0
  90. package/lib/icons/DocumentReactIcon/DocumentReactIcon.js +23 -0
  91. package/lib/icons/DocumentReactIcon/index.d.ts +1 -0
  92. package/lib/icons/DocumentReactIcon/index.js +6 -0
  93. package/lib/icons/DocumentTsIcon/DocumentTsIcon.d.ts +9 -0
  94. package/lib/icons/DocumentTsIcon/DocumentTsIcon.js +23 -0
  95. package/lib/icons/DocumentTsIcon/index.d.ts +1 -0
  96. package/lib/icons/DocumentTsIcon/index.js +6 -0
  97. package/lib/icons/DocumentYamlIcon/DocumentYamlIcon.d.ts +9 -0
  98. package/lib/icons/DocumentYamlIcon/DocumentYamlIcon.js +23 -0
  99. package/lib/icons/DocumentYamlIcon/index.d.ts +1 -0
  100. package/lib/icons/DocumentYamlIcon/index.js +6 -0
  101. package/lib/index.d.ts +1 -0
  102. package/lib/index.js +1 -0
  103. package/lib/layouts/CodeWalkthroughLayout.d.ts +5 -0
  104. package/lib/layouts/CodeWalkthroughLayout.js +72 -0
  105. package/lib/markdoc/attributes/code-walkthrough-filesets.d.ts +5 -0
  106. package/lib/markdoc/attributes/code-walkthrough-filesets.js +16 -0
  107. package/lib/markdoc/attributes/code-walkthrough-filters.d.ts +5 -0
  108. package/lib/markdoc/attributes/code-walkthrough-filters.js +16 -0
  109. package/lib/markdoc/components/CodeWalkthrough/CodeContainer.d.ts +5 -0
  110. package/lib/markdoc/components/CodeWalkthrough/CodeContainer.js +81 -0
  111. package/lib/markdoc/components/CodeWalkthrough/CodeFilters.d.ts +12 -0
  112. package/lib/markdoc/components/CodeWalkthrough/CodeFilters.js +58 -0
  113. package/lib/markdoc/components/CodeWalkthrough/CodePanel.d.ts +8 -0
  114. package/lib/markdoc/components/CodeWalkthrough/CodePanel.js +64 -0
  115. package/lib/markdoc/components/CodeWalkthrough/CodePanelHeader.d.ts +8 -0
  116. package/lib/markdoc/components/CodeWalkthrough/CodePanelHeader.js +155 -0
  117. package/lib/markdoc/components/CodeWalkthrough/CodePanelPreview.d.ts +2 -0
  118. package/lib/markdoc/components/CodeWalkthrough/CodePanelPreview.js +73 -0
  119. package/lib/markdoc/components/CodeWalkthrough/CodePanelToolbar.d.ts +5 -0
  120. package/lib/markdoc/components/CodeWalkthrough/CodePanelToolbar.js +47 -0
  121. package/lib/markdoc/components/CodeWalkthrough/CodeStep.d.ts +12 -0
  122. package/lib/markdoc/components/CodeWalkthrough/CodeStep.js +128 -0
  123. package/lib/markdoc/components/CodeWalkthrough/CodeToggle.d.ts +9 -0
  124. package/lib/markdoc/components/CodeWalkthrough/CodeToggle.js +69 -0
  125. package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.d.ts +4 -0
  126. package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.js +121 -0
  127. package/lib/markdoc/components/CodeWalkthrough/Input.d.ts +8 -0
  128. package/lib/markdoc/components/CodeWalkthrough/Input.js +99 -0
  129. package/lib/markdoc/components/CodeWalkthrough/variables.d.ts +1 -0
  130. package/lib/markdoc/components/CodeWalkthrough/variables.js +19 -0
  131. package/lib/markdoc/components/default.d.ts +5 -0
  132. package/lib/markdoc/components/default.js +5 -0
  133. package/lib/markdoc/default.js +8 -0
  134. package/lib/markdoc/tags/code-step.d.ts +2 -0
  135. package/lib/markdoc/tags/code-step.js +28 -0
  136. package/lib/markdoc/tags/code-toggle.d.ts +2 -0
  137. package/lib/markdoc/tags/code-toggle.js +40 -0
  138. package/lib/markdoc/tags/code-walkthrough.d.ts +8 -0
  139. package/lib/markdoc/tags/code-walkthrough.js +242 -0
  140. package/lib/markdoc/tags/input.d.ts +2 -0
  141. package/lib/markdoc/tags/input.js +37 -0
  142. package/lib/plugin.d.ts +2 -1
  143. package/lib/plugin.js +2 -4
  144. package/package.json +10 -3
  145. package/src/components/Buttons/CopyButton.tsx +24 -6
  146. package/src/components/Feedback/Mood.tsx +9 -10
  147. package/src/components/Feedback/Rating.tsx +9 -10
  148. package/src/components/Feedback/Scale.tsx +9 -10
  149. package/src/components/Feedback/Sentiment.tsx +9 -10
  150. package/src/components/Search/SearchDialog.tsx +11 -6
  151. package/src/components/Search/SearchFilter.tsx +6 -3
  152. package/src/components/Search/SearchFilterField.tsx +4 -2
  153. package/src/components/Search/SearchGroups.tsx +13 -8
  154. package/src/components/StatusCode/StatusCode.ts +11 -10
  155. package/src/core/constants/code-walkthrough.ts +1 -0
  156. package/src/core/constants/index.ts +1 -0
  157. package/src/core/contexts/CodeWalkthrough/CodeWalkthroughControlsContext.tsx +21 -0
  158. package/src/core/contexts/CodeWalkthrough/CodeWalkthroughStepsContext.tsx +10 -0
  159. package/src/core/contexts/index.ts +2 -0
  160. package/src/core/hooks/__mocks__/search/use-search-filter.ts +1 -1
  161. package/src/core/hooks/code-walkthrough/__mocks__/MockIntersectionObserver.ts +22 -0
  162. package/src/core/hooks/code-walkthrough/use-code-panel.ts +164 -0
  163. package/src/core/hooks/code-walkthrough/use-code-walkthrough-controls.ts +302 -0
  164. package/src/core/hooks/code-walkthrough/use-code-walkthrough-steps.ts +165 -0
  165. package/src/core/hooks/code-walkthrough/use-code-walkthrough.ts +51 -0
  166. package/src/core/hooks/index.ts +4 -0
  167. package/src/core/hooks/search/use-search-filter.ts +9 -5
  168. package/src/core/styles/global.ts +2 -0
  169. package/src/core/templates/Markdown.tsx +16 -5
  170. package/src/core/types/hooks.ts +3 -0
  171. package/src/core/types/l10n.ts +5 -3
  172. package/src/core/types/search.ts +1 -2
  173. package/src/core/utils/download-code-walkthrough.ts +25 -0
  174. package/src/core/utils/get-code-walkthrough-file-text.ts +32 -0
  175. package/src/core/utils/get-file-icon.ts +35 -0
  176. package/src/core/utils/index.ts +5 -0
  177. package/src/core/utils/js-utils.ts +48 -0
  178. package/src/core/utils/match-code-walkthrough-conditions.ts +29 -0
  179. package/src/core/utils/replace-inputs-with-value.ts +11 -0
  180. package/src/icons/DocumentCssIcon/DocumentCssIcon.tsx +36 -0
  181. package/src/icons/DocumentCssIcon/index.ts +1 -0
  182. package/src/icons/DocumentGraphqlIcon/DocumentGraphqlIcon.tsx +64 -0
  183. package/src/icons/DocumentGraphqlIcon/index.ts +1 -0
  184. package/src/icons/DocumentHtmlIcon/DocumentHtmlIcon.tsx +36 -0
  185. package/src/icons/DocumentHtmlIcon/index.ts +1 -0
  186. package/src/icons/DocumentJsIcon/DocumentJsIcon.tsx +36 -0
  187. package/src/icons/DocumentJsIcon/index.ts +1 -0
  188. package/src/icons/DocumentJsonIcon/DocumentJsonIcon.tsx +36 -0
  189. package/src/icons/DocumentJsonIcon/index.ts +1 -0
  190. package/src/icons/DocumentMarkdownIcon/DocumentMarkdownIcon.tsx +36 -0
  191. package/src/icons/DocumentMarkdownIcon/index.ts +1 -0
  192. package/src/icons/DocumentReactIcon/DocumentReactIcon.tsx +36 -0
  193. package/src/icons/DocumentReactIcon/index.ts +1 -0
  194. package/src/icons/DocumentTsIcon/DocumentTsIcon.tsx +38 -0
  195. package/src/icons/DocumentTsIcon/index.ts +1 -0
  196. package/src/icons/DocumentYamlIcon/DocumentYamlIcon.tsx +36 -0
  197. package/src/icons/DocumentYamlIcon/index.ts +1 -0
  198. package/src/index.ts +1 -0
  199. package/src/layouts/CodeWalkthroughLayout.tsx +78 -0
  200. package/src/markdoc/attributes/code-walkthrough-filesets.ts +9 -0
  201. package/src/markdoc/attributes/code-walkthrough-filters.ts +9 -0
  202. package/src/markdoc/components/CodeWalkthrough/CodeContainer.tsx +76 -0
  203. package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +87 -0
  204. package/src/markdoc/components/CodeWalkthrough/CodePanel.tsx +68 -0
  205. package/src/markdoc/components/CodeWalkthrough/CodePanelHeader.tsx +192 -0
  206. package/src/markdoc/components/CodeWalkthrough/CodePanelPreview.tsx +53 -0
  207. package/src/markdoc/components/CodeWalkthrough/CodePanelToolbar.tsx +31 -0
  208. package/src/markdoc/components/CodeWalkthrough/CodeStep.tsx +149 -0
  209. package/src/markdoc/components/CodeWalkthrough/CodeToggle.tsx +63 -0
  210. package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +111 -0
  211. package/src/markdoc/components/CodeWalkthrough/Input.tsx +101 -0
  212. package/src/markdoc/components/CodeWalkthrough/variables.ts +16 -0
  213. package/src/markdoc/components/default.ts +5 -0
  214. package/src/markdoc/default.ts +8 -0
  215. package/src/markdoc/tags/code-step.ts +27 -0
  216. package/src/markdoc/tags/code-toggle.ts +37 -0
  217. package/src/markdoc/tags/code-walkthrough.ts +315 -0
  218. package/src/markdoc/tags/input.ts +35 -0
  219. package/src/plugin.js +2 -2
@@ -1,7 +1,7 @@
1
1
  import React, { memo } from 'react';
2
2
 
3
3
  import type { TooltipProps } from '@redocly/theme/components/Tooltip/Tooltip';
4
- import type { ControlItemType } from '@redocly/theme/components/CodeBlock/CodeBlockControls';
4
+ import type { ButtonProps } from '@redocly/theme/components/Button/Button';
5
5
 
6
6
  import { ClipboardService } from '@redocly/theme/core/utils';
7
7
  import { useThemeHooks, useControl } from '@redocly/theme/core/hooks';
@@ -11,7 +11,7 @@ import { Tooltip } from '@redocly/theme/components/Tooltip/Tooltip';
11
11
 
12
12
  export type CopyButtonProps = {
13
13
  data: unknown;
14
- type?: ControlItemType;
14
+ type?: 'icon' | 'text' | 'compound';
15
15
  toasterPlacement?: TooltipProps['placement'];
16
16
  toasterText?: string;
17
17
  toasterDuration?: number;
@@ -19,7 +19,14 @@ export type CopyButtonProps = {
19
19
  onCopyClick?: (e: React.MouseEvent<HTMLElement>) => void;
20
20
  dataTestId?: string;
21
21
  className?: string;
22
- variant?: string;
22
+
23
+ // Generic button props
24
+ variant?: ButtonProps['variant'];
25
+ size?: ButtonProps['size'];
26
+ disabled?: ButtonProps['disabled'];
27
+ fullWidth?: ButtonProps['fullWidth'];
28
+ tone?: ButtonProps['tone'];
29
+ extraClass?: ButtonProps['extraClass'];
23
30
  };
24
31
 
25
32
  function CopyButtonComponent({
@@ -33,6 +40,11 @@ function CopyButtonComponent({
33
40
  dataTestId = 'copy-button',
34
41
  className,
35
42
  variant = 'text',
43
+ size = 'small',
44
+ disabled,
45
+ fullWidth,
46
+ tone,
47
+ extraClass,
36
48
  }: CopyButtonProps): JSX.Element {
37
49
  const { useTranslate } = useThemeHooks();
38
50
  const tooltip = useControl();
@@ -59,16 +71,22 @@ function CopyButtonComponent({
59
71
  tip={translate('codeSnippet.copy.buttonText', toasterText || 'Copied!')}
60
72
  isOpen={tooltip.isOpened}
61
73
  placement={toasterPlacement}
74
+ width="fit-content"
62
75
  >
63
76
  <Button
64
77
  data-component-name="Buttons/CopyButton"
65
78
  onClick={(e) => copy(e, toasterDuration)}
66
79
  data-testid={dataTestId}
67
- icon={type === 'icon' ? <CopyIcon /> : undefined}
68
- size="small"
80
+ icon={type === 'icon' || type === 'compound' ? <CopyIcon /> : undefined}
81
+ size={size}
69
82
  variant={variant}
83
+ disabled={disabled}
84
+ fullWidth={fullWidth}
85
+ tone={tone}
86
+ extraClass={extraClass}
70
87
  >
71
- {type !== 'icon' && translate('codeSnippet.copy.toasterText', buttonText || 'Copy')}
88
+ {(type === 'text' || type === 'compound') &&
89
+ translate('codeSnippet.copy.toasterText', buttonText || 'Copy')}
72
90
  </Button>
73
91
  </Tooltip>
74
92
  );
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { useEffect } from 'react';
3
3
  import styled from 'styled-components';
4
4
 
5
- import type { AnonymousUserEmailSettings, ReasonsSettingsSchema } from '@redocly/config';
5
+ import type { OptionalEmailSettings, ReasonsSettingsSchema } from '@redocly/config';
6
6
  import type { ReasonsProps } from '@redocly/theme/components/Feedback/Reasons';
7
7
 
8
8
  import { Reasons } from '@redocly/theme/components/Feedback/Reasons';
@@ -41,7 +41,7 @@ export type MoodProps = {
41
41
  neutral?: ReasonsSettingsSchema;
42
42
  dissatisfied?: ReasonsSettingsSchema;
43
43
  };
44
- anonymousUserEmail?: AnonymousUserEmailSettings;
44
+ optionalEmail?: OptionalEmailSettings;
45
45
  };
46
46
  className?: string;
47
47
  };
@@ -52,7 +52,7 @@ export function Mood({ settings, onSubmit, className }: MoodProps): JSX.Element
52
52
  submitText,
53
53
  comment: commentSettings,
54
54
  reasons: reasonsSettings,
55
- anonymousUserEmail: anonymousUserEmailSettings,
55
+ optionalEmail: optionalEmailSettings,
56
56
  } = settings || {};
57
57
  const [score, setScore] = React.useState('');
58
58
  const [isSubmitted, setIsSubmitted] = React.useState(false);
@@ -131,8 +131,7 @@ export function Mood({ settings, onSubmit, className }: MoodProps): JSX.Element
131
131
  const displayReasons = checkIfShouldDisplayReasons(score);
132
132
  const displayComment = !!(score && !commentSettings?.hide);
133
133
  const displaySubmitBnt = !!(score && (displayReasons || displayComment));
134
- const displayFeedbackEmail =
135
- !!score && anonymousUserEmailSettings?.enabled && !userData.isAuthenticated;
134
+ const displayFeedbackEmail = !!score && !optionalEmailSettings?.hide && !userData.isAuthenticated;
136
135
 
137
136
  const onSubmitMoodForm = () => {
138
137
  onSubmit({
@@ -241,18 +240,18 @@ export function Mood({ settings, onSubmit, className }: MoodProps): JSX.Element
241
240
 
242
241
  {displayFeedbackEmail && (
243
242
  <StyledFormOptionalFields>
244
- <Label data-translation-key="feedback.settings.anonymousUserEmail.label">
245
- {anonymousUserEmailSettings?.label ||
243
+ <Label data-translation-key="feedback.settings.optionalEmail.label">
244
+ {optionalEmailSettings?.label ||
246
245
  translate(
247
- 'feedback.settings.anonymousUserEmail.label',
246
+ 'feedback.settings.optionalEmail.label',
248
247
  'Your email (optional, for follow-up)',
249
248
  )}
250
249
  </Label>
251
250
  <EmailInput
252
251
  onChange={onEmailChange}
253
252
  placeholder={
254
- anonymousUserEmailSettings?.placeholder ||
255
- translate('feedback.settings.anonymousUserEmail.placeholder', 'username@mail.com')
253
+ optionalEmailSettings?.placeholder ||
254
+ translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com')
256
255
  }
257
256
  type="email"
258
257
  required={!!email}
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { useEffect } from 'react';
3
3
  import styled from 'styled-components';
4
4
 
5
- import type { AnonymousUserEmailSettings } from '@redocly/config';
5
+ import type { OptionalEmailSettings } from '@redocly/config';
6
6
  import type { ReasonsProps } from '@redocly/theme/components/Feedback/Reasons';
7
7
 
8
8
  import { Reasons } from '@redocly/theme/components/Feedback/Reasons';
@@ -35,7 +35,7 @@ export type RatingProps = {
35
35
  component?: string;
36
36
  items: string[];
37
37
  };
38
- anonymousUserEmail?: AnonymousUserEmailSettings;
38
+ optionalEmail?: OptionalEmailSettings;
39
39
  };
40
40
  className?: string;
41
41
  };
@@ -46,7 +46,7 @@ export function Rating({ settings, onSubmit, className }: RatingProps): JSX.Elem
46
46
  submitText,
47
47
  comment: commentSettings,
48
48
  reasons: reasonsSettings,
49
- anonymousUserEmail: anonymousUserEmailSettings,
49
+ optionalEmail: optionalEmailSettings,
50
50
  } = settings || {};
51
51
  const [isSubmitted, setIsSubmitted] = React.useState(false);
52
52
  const [score, setScore] = React.useState(0);
@@ -83,8 +83,7 @@ export function Rating({ settings, onSubmit, className }: RatingProps): JSX.Elem
83
83
  const displayReasons = !!(score && reasonsSettings && !reasonsSettings.hide);
84
84
  const displayComment = !!(score && !commentSettings?.hide);
85
85
  const displaySubmitBnt = !!(score && (displayReasons || displayComment));
86
- const displayFeedbackEmail =
87
- !!score && anonymousUserEmailSettings?.enabled && !userData.isAuthenticated;
86
+ const displayFeedbackEmail = !!score && !optionalEmailSettings?.hide && !userData.isAuthenticated;
88
87
 
89
88
  useEffect(() => {
90
89
  if (score && !displayComment && !displayReasons && !displayFeedbackEmail) {
@@ -154,18 +153,18 @@ export function Rating({ settings, onSubmit, className }: RatingProps): JSX.Elem
154
153
 
155
154
  {displayFeedbackEmail && (
156
155
  <StyledFormOptionalFields>
157
- <Label data-translation-key="feedback.settings.anonymousUserEmail.label">
158
- {anonymousUserEmailSettings?.label ||
156
+ <Label data-translation-key="feedback.settings.optionalEmail.label">
157
+ {optionalEmailSettings?.label ||
159
158
  translate(
160
- 'feedback.settings.anonymousUserEmail.label',
159
+ 'feedback.settings.optionalEmail.label',
161
160
  'Your email (optional, for follow-up)',
162
161
  )}
163
162
  </Label>
164
163
  <EmailInput
165
164
  onChange={onEmailChange}
166
165
  placeholder={
167
- anonymousUserEmailSettings?.placeholder ||
168
- translate('feedback.settings.anonymousUserEmail.placeholder', 'username@mail.com')
166
+ optionalEmailSettings?.placeholder ||
167
+ translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com')
169
168
  }
170
169
  type="email"
171
170
  required={!!email}
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { useEffect } from 'react';
3
3
  import styled from 'styled-components';
4
4
 
5
- import type { AnonymousUserEmailSettings } from '@redocly/config';
5
+ import type { OptionalEmailSettings } from '@redocly/config';
6
6
  import type { ReasonsProps } from '@redocly/theme/components/Feedback/Reasons';
7
7
 
8
8
  import { breakpoints } from '@redocly/theme/core/utils';
@@ -37,7 +37,7 @@ export type ScaleProps = {
37
37
  component?: string;
38
38
  items: string[];
39
39
  };
40
- anonymousUserEmail?: AnonymousUserEmailSettings;
40
+ optionalEmail?: OptionalEmailSettings;
41
41
  };
42
42
  className?: string;
43
43
  };
@@ -50,7 +50,7 @@ export function Scale({ settings, onSubmit, className }: ScaleProps): JSX.Elemen
50
50
  rightScaleLabel,
51
51
  comment: commentSettings,
52
52
  reasons: reasonsSettings,
53
- anonymousUserEmail: anonymousUserEmailSettings,
53
+ optionalEmail: optionalEmailSettings,
54
54
  } = settings || {};
55
55
  const [score, setScore] = React.useState(0);
56
56
  const [isSubmitted, setIsSubmitted] = React.useState(false);
@@ -85,8 +85,7 @@ export function Scale({ settings, onSubmit, className }: ScaleProps): JSX.Elemen
85
85
  const displayReasons = !!score && reasonsSettings && !reasonsSettings.hide;
86
86
  const displayComment = !!(score && !commentSettings?.hide);
87
87
  const displaySubmitBnt = !!score && (displayReasons || displayComment);
88
- const displayFeedbackEmail =
89
- !!score && anonymousUserEmailSettings?.enabled && !userData.isAuthenticated;
88
+ const displayFeedbackEmail = !!score && !optionalEmailSettings?.hide && !userData.isAuthenticated;
90
89
 
91
90
  const handleCancel = () => {
92
91
  setScore(0);
@@ -179,18 +178,18 @@ export function Scale({ settings, onSubmit, className }: ScaleProps): JSX.Elemen
179
178
 
180
179
  {displayFeedbackEmail && (
181
180
  <StyledFormOptionalFields>
182
- <Label data-translation-key="feedback.settings.anonymousUserEmail.label">
183
- {anonymousUserEmailSettings?.label ||
181
+ <Label data-translation-key="feedback.settings.optionalEmail.label">
182
+ {optionalEmailSettings?.label ||
184
183
  translate(
185
- 'feedback.settings.anonymousUserEmail.label',
184
+ 'feedback.settings.optionalEmail.label',
186
185
  'Your email (optional, for follow-up)',
187
186
  )}
188
187
  </Label>
189
188
  <EmailInput
190
189
  onChange={onEmailChange}
191
190
  placeholder={
192
- anonymousUserEmailSettings?.placeholder ||
193
- translate('feedback.settings.anonymousUserEmail.placeholder', 'username@mail.com')
191
+ optionalEmailSettings?.placeholder ||
192
+ translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com')
194
193
  }
195
194
  type="email"
196
195
  required={!!email}
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { useEffect } from 'react';
3
3
  import styled from 'styled-components';
4
4
 
5
- import type { ReasonsSettingsSchema, AnonymousUserEmailSettings } from '@redocly/config';
5
+ import type { OptionalEmailSettings, ReasonsSettingsSchema } from '@redocly/config';
6
6
  import type { ReasonsProps } from '@redocly/theme/components/Feedback/Reasons';
7
7
 
8
8
  import { Reasons } from '@redocly/theme/components/Feedback/Reasons';
@@ -32,7 +32,7 @@ export type SentimentProps = {
32
32
  like?: ReasonsSettingsSchema;
33
33
  dislike?: ReasonsSettingsSchema;
34
34
  };
35
- anonymousUserEmail?: AnonymousUserEmailSettings;
35
+ optionalEmail?: OptionalEmailSettings;
36
36
  };
37
37
  className?: string;
38
38
  };
@@ -43,7 +43,7 @@ export function Sentiment({ settings, onSubmit, className }: SentimentProps): JS
43
43
  submitText,
44
44
  comment: commentSettings,
45
45
  reasons: reasonsSettings,
46
- anonymousUserEmail: anonymousUserEmailSettings,
46
+ optionalEmail: optionalEmailSettings,
47
47
  } = settings || {};
48
48
  const [isSubmitted, setIsSubmitted] = React.useState(false);
49
49
  const [score, setScore] = React.useState(0);
@@ -87,8 +87,7 @@ export function Sentiment({ settings, onSubmit, className }: SentimentProps): JS
87
87
  const displayReasons = checkIfShouldDisplayReasons(score);
88
88
  const displayComment = !!(score && !commentSettings?.hide);
89
89
  const displaySubmitBnt = !!(score && (displayReasons || displayComment));
90
- const displayFeedbackEmail =
91
- !!score && anonymousUserEmailSettings?.enabled && !userData.isAuthenticated;
90
+ const displayFeedbackEmail = !!score && !optionalEmailSettings?.hide && !userData.isAuthenticated;
92
91
 
93
92
  const commentLabel =
94
93
  score === 1
@@ -214,18 +213,18 @@ export function Sentiment({ settings, onSubmit, className }: SentimentProps): JS
214
213
 
215
214
  {displayFeedbackEmail && (
216
215
  <StyledFormOptionalFields>
217
- <Label data-translation-key="feedback.settings.anonymousUserEmail.label">
218
- {anonymousUserEmailSettings?.label ||
216
+ <Label data-translation-key="feedback.settings.optionalEmail.label">
217
+ {optionalEmailSettings?.label ||
219
218
  translate(
220
- 'feedback.settings.anonymousUserEmail.label',
219
+ 'feedback.settings.optionalEmail.label',
221
220
  'Your email (optional, for follow-up)',
222
221
  )}
223
222
  </Label>
224
223
  <EmailInput
225
224
  onChange={onEmailChange}
226
225
  placeholder={
227
- anonymousUserEmailSettings?.placeholder ||
228
- translate('feedback.settings.anonymousUserEmail.placeholder', 'username@mail.com')
226
+ optionalEmailSettings?.placeholder ||
227
+ translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com')
229
228
  }
230
229
  type="email"
231
230
  required={!!email}
@@ -44,6 +44,7 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
44
44
  setLoadMore,
45
45
  advancedSearch,
46
46
  askAi,
47
+ groupField,
47
48
  } = useSearch(product?.name, autoSearchDisabled);
48
49
  const {
49
50
  isFilterOpen,
@@ -51,7 +52,7 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
51
52
  onFilterChange,
52
53
  onFilterReset,
53
54
  onFacetReset,
54
- onTopFacetsReset,
55
+ onQuickFilterReset,
55
56
  } = useSearchFilter(filter, setFilter);
56
57
  const aiSearch = useAiSearch({ filter });
57
58
 
@@ -83,10 +84,10 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
83
84
  };
84
85
 
85
86
  const showLoadMore = (groupKey: string, currentCount: number = 0) => {
86
- const topFacet = facets.find((facet) => facet.isTop);
87
+ const groupFacet = facets.find((facet) => facet.field === groupField);
87
88
  let needLoadMore = false;
88
- if (topFacet) {
89
- const groupValue = topFacet.values.find((value) => {
89
+ if (groupFacet) {
90
+ const groupValue = groupFacet.values.find((value) => {
90
91
  if (typeof value === 'object') {
91
92
  return value.value === groupKey;
92
93
  } else return false;
@@ -170,14 +171,17 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
170
171
  facets={facets}
171
172
  searchFilter={filter}
172
173
  onFilterChange={onFilterChange}
173
- onTopFacetsReset={onTopFacetsReset}
174
+ onQuickFilterReset={onQuickFilterReset}
175
+ groupField={groupField}
174
176
  />
175
177
  {showResults ? (
176
178
  items && Object.keys(items).some((key) => items[key]?.length) ? (
177
179
  Object.keys(items).map((key) =>
178
180
  items[key]?.length ? (
179
181
  <Fragment key={key}>
180
- <SearchGroupTitle>{key}</SearchGroupTitle>
182
+ <SearchGroupTitle data-testid="search-group-title">
183
+ {key}
184
+ </SearchGroupTitle>
181
185
  {items[key]?.map(mapItem)}
182
186
  {showLoadMore(key, items[key]?.length || 0) && (
183
187
  <SearchGroupFooter
@@ -215,6 +219,7 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
215
219
  facets={facets}
216
220
  filter={filter}
217
221
  query={query}
222
+ quickFilterFields={[groupField]}
218
223
  onFilterChange={onFilterChange}
219
224
  onFilterReset={onFilterReset}
220
225
  onFacetReset={onFacetReset}
@@ -13,7 +13,8 @@ export type SearchFilterProps = {
13
13
  facets: SearchFacet[];
14
14
  filter: SearchFilterItem[];
15
15
  query: string;
16
- onFilterChange: (field: string, value: string | string[], isTop?: boolean) => void;
16
+ quickFilterFields: string[];
17
+ onFilterChange: (field: string, value: string | string[], isQuickFilter?: boolean) => void;
17
18
  onFilterReset: () => void;
18
19
  onFacetReset: (field: string) => void;
19
20
  };
@@ -23,6 +24,7 @@ export function SearchFilter({
23
24
  facets,
24
25
  filter,
25
26
  query,
27
+ quickFilterFields,
26
28
  onFilterChange,
27
29
  onFilterReset,
28
30
  onFacetReset,
@@ -50,10 +52,11 @@ export function SearchFilter({
50
52
  <SearchFilterField
51
53
  key={`${facet.field}-${index}`}
52
54
  facet={facet}
53
- onFilterChange={onFilterChange}
54
- onFacetReset={onFacetReset}
55
55
  filter={filter}
56
56
  query={query}
57
+ quickFilterFields={quickFilterFields}
58
+ onFilterChange={onFilterChange}
59
+ onFacetReset={onFacetReset}
57
60
  />
58
61
  ))}
59
62
  </SearchFilterFields>
@@ -14,7 +14,8 @@ type SearchFilterFieldProps = {
14
14
  facet: SearchFacet;
15
15
  filter: SearchFilterItem[];
16
16
  query: string;
17
- onFilterChange: (field: string, value: string | string[], isTop?: boolean) => void;
17
+ quickFilterFields: string[];
18
+ onFilterChange: (field: string, value: string | string[], isQuickFilter?: boolean) => void;
18
19
  onFacetReset: (filed: string) => void;
19
20
  };
20
21
 
@@ -23,6 +24,7 @@ export function SearchFilterField({
23
24
  facet,
24
25
  filter,
25
26
  query,
27
+ quickFilterFields,
26
28
  onFilterChange,
27
29
  onFacetReset,
28
30
  }: SearchFilterFieldProps): JSX.Element {
@@ -31,7 +33,7 @@ export function SearchFilterField({
31
33
  const selectedValues = filter.find((item) => item.field === facet.field)?.values || [];
32
34
 
33
35
  const onChange = (value: string | string[]) => {
34
- onFilterChange(facet.field, value, facet.isTop);
36
+ onFilterChange(facet.field, value, facet.field in quickFilterFields);
35
37
  };
36
38
 
37
39
  const onReset = () => {
@@ -1,24 +1,29 @@
1
1
  import * as React from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
- import type { SearchFacet, SearchFacetCount, SearchFilterItem } from '@redocly/theme';
5
-
4
+ import {
5
+ type SearchFacet,
6
+ type SearchFacetCount,
7
+ type SearchFilterItem,
8
+ } from '@redocly/theme/core/types';
6
9
  import { Tag } from '@redocly/theme/components/Tag/Tag';
7
10
 
8
11
  type SearchGroupsProps = {
9
12
  facets: SearchFacet[];
10
13
  searchFilter: SearchFilterItem[];
11
- onFilterChange: (field: string, value: string[], isTop?: boolean) => void;
12
- onTopFacetsReset: () => void;
14
+ groupField: string;
15
+ onFilterChange: (field: string, value: string[], isQuickFilter?: boolean) => void;
16
+ onQuickFilterReset: () => void;
13
17
  };
14
18
 
15
19
  export function SearchGroups({
16
20
  facets,
17
21
  searchFilter,
22
+ groupField,
18
23
  onFilterChange,
19
- onTopFacetsReset,
24
+ onQuickFilterReset,
20
25
  }: SearchGroupsProps): JSX.Element {
21
- const groupFacets = facets.filter((facet) => facet.isTop);
26
+ const groupFacets = facets.filter((facet) => facet.field === groupField);
22
27
 
23
28
  const handleGroupTagClick = (
24
29
  value: string,
@@ -36,8 +41,8 @@ export function SearchGroups({
36
41
  <SearchGroupsWrapper>
37
42
  <GroupTag
38
43
  borderless
39
- active={!searchFilter.some((item) => item.isTop)}
40
- onClick={() => searchFilter.some((item) => item.isTop) && onTopFacetsReset()}
44
+ active={!searchFilter.some((item) => item.isQuickFilter)}
45
+ onClick={() => searchFilter.some((item) => item.isQuickFilter) && onQuickFilterReset()}
41
46
  >
42
47
  All
43
48
  </GroupTag>
@@ -17,16 +17,17 @@ export const StatusCode = styled.button.attrs({ 'data-component-name': 'StatusCo
17
17
  width: var(--status-code-width);
18
18
  border: var(--status-code-border);
19
19
  background-color: ${({ status }) => {
20
- if (Math.floor(Number(status) / 100) === 2) {
21
- return 'var(--status-code-200-bg-color)';
22
- } else if (Math.floor(Number(status) / 100) === 4) {
23
- return 'var(--status-code-400-bg-color)';
24
- } else if (Math.floor(Number(status) / 100) === 5) {
25
- return 'var(--status-code-500-bg-color)';
26
- } else if (Math.floor(Number(status) / 100) === 3) {
27
- return 'var(--status-code-300-bg-color)';
28
- } else {
29
- return 'var(--status-code-100-bg-color)';
20
+ switch (true) {
21
+ case status.startsWith('2'):
22
+ return 'var(--status-code-200-bg-color)';
23
+ case status.startsWith('3'):
24
+ return 'var(--status-code-300-bg-color)';
25
+ case status.startsWith('4'):
26
+ return 'var(--status-code-400-bg-color)';
27
+ case status.startsWith('5'):
28
+ return 'var(--status-code-500-bg-color)';
29
+ default:
30
+ return 'var(--status-code-100-bg-color)';
30
31
  }
31
32
  }}
32
33
  `;
@@ -0,0 +1 @@
1
+ export const ACTIVE_STEP_QUERY_PARAM = '__step';
@@ -1,2 +1,3 @@
1
1
  export * from '@redocly/theme/core/constants/common';
2
2
  export * from '@redocly/theme/core/constants/environments';
3
+ export * from '@redocly/theme/core/constants/code-walkthrough';
@@ -0,0 +1,21 @@
1
+ import { createContext } from 'react';
2
+
3
+ import type { WalkthroughControlsState } from '@redocly/theme/core/hooks';
4
+
5
+ export const CodeWalkthroughControlsStateContext = createContext<WalkthroughControlsState>({
6
+ activeFilters: [],
7
+
8
+ getToggleState: () => null,
9
+ changeToggleState: () => {},
10
+
11
+ getInputState: () => null,
12
+ changeInputState: () => {},
13
+
14
+ getFilterState: () => null,
15
+ changeFilterState: () => {},
16
+
17
+ getFileText: () => '',
18
+ areConditionsMet: () => false,
19
+ handleDownloadCode: () => Promise.resolve(),
20
+ populateInputsWithValue: (node) => node,
21
+ });
@@ -0,0 +1,10 @@
1
+ import { createContext } from 'react';
2
+
3
+ import type { WalkthroughStepsState } from '@redocly/theme/core/hooks';
4
+
5
+ export const CodeWalkthroughStepsContext = createContext<WalkthroughStepsState>({
6
+ activeStep: null,
7
+ setActiveStep: () => {},
8
+ register: () => {},
9
+ unregister: () => {},
10
+ });
@@ -1 +1,3 @@
1
1
  export * from '@redocly/theme/core/contexts/ThemeDataContext';
2
+ export * from '@redocly/theme/core/contexts/CodeWalkthrough/CodeWalkthroughControlsContext';
3
+ export * from '@redocly/theme/core/contexts/CodeWalkthrough/CodeWalkthroughStepsContext';
@@ -5,6 +5,6 @@ export const useSearchFilter = jest.fn(() => {
5
5
  onFilterChange: () => {},
6
6
  onFilterToggle: () => {},
7
7
  onFilterReset: () => {},
8
- onTopFacetsReset: () => {},
8
+ onQuickFilterReset: () => {},
9
9
  };
10
10
  });
@@ -0,0 +1,22 @@
1
+ export class MockIntersectionObserver {
2
+ public readonly root: Element | Document | null;
3
+ public readonly rootMargin: string;
4
+ public readonly thresholds: ReadonlyArray<number>;
5
+ observe: (target: HTMLElement) => void;
6
+ unobserve: (target: HTMLElement) => void;
7
+ disconnect: () => void;
8
+
9
+ // @ts-ignore
10
+ constructor(callback: IntersectionObserverCallback, options?: IntersectionObserverInit) {
11
+ this.root = null;
12
+ this.rootMargin = '0px';
13
+ this.thresholds = [1];
14
+ this.observe = jest.fn;
15
+ this.unobserve = jest.fn;
16
+ this.disconnect = jest.fn;
17
+ }
18
+
19
+ takeRecords(): any[] {
20
+ return [];
21
+ }
22
+ }