@redocly/theme 0.57.0-next.2 → 0.57.0-next.4

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 (96) hide show
  1. package/lib/components/Breadcrumbs/Breadcrumbs.js +4 -7
  2. package/lib/components/Buttons/EditPageButton.js +1 -1
  3. package/lib/components/Catalog/CatalogCardView/CatalogCard.js +1 -1
  4. package/lib/components/Catalog/CatalogEntity/CatalogEntity.js +1 -35
  5. package/lib/components/CatalogClassic/CatalogClassicActions.js +1 -1
  6. package/lib/components/CatalogClassic/CatalogClassicCard.js +1 -1
  7. package/lib/components/CatalogClassic/CatalogClassicInfoBlock.js +1 -1
  8. package/lib/components/CodeBlock/CodeBlockControls.js +7 -9
  9. package/lib/components/Feedback/Feedback.js +1 -1
  10. package/lib/components/Feedback/ReportDialog.js +1 -1
  11. package/lib/components/Filter/FilterCheckboxes.js +1 -1
  12. package/lib/components/Footer/FooterItem.js +1 -1
  13. package/lib/components/LanguagePicker/LanguagePicker.js +1 -4
  14. package/lib/components/Logo/Logo.js +1 -1
  15. package/lib/components/Menu/MenuItem.js +3 -6
  16. package/lib/components/Navbar/Navbar.js +2 -2
  17. package/lib/components/Navbar/NavbarItem.js +1 -1
  18. package/lib/components/Search/SearchDialog.js +9 -15
  19. package/lib/components/Search/SearchInput.js +1 -1
  20. package/lib/components/Search/SearchRecent.js +1 -1
  21. package/lib/components/SidebarActions/SidebarActions.js +3 -3
  22. package/lib/components/Switch/Switch.d.ts +4 -1
  23. package/lib/components/Switch/Switch.js +12 -3
  24. package/lib/components/TableOfContent/TableOfContent.js +1 -1
  25. package/lib/components/Tooltip/TooltipWrapper.d.ts +2 -2
  26. package/lib/components/Tooltip/TooltipWrapper.js +2 -4
  27. package/lib/components/UserMenu/LoginButton.js +1 -1
  28. package/lib/components/UserMenu/LogoutMenuItem.js +1 -1
  29. package/lib/core/hooks/__mocks__/use-theme-hooks.d.ts +1 -0
  30. package/lib/core/hooks/__mocks__/use-theme-hooks.js +1 -0
  31. package/lib/core/hooks/search/use-search-dialog.js +2 -2
  32. package/lib/core/hooks/use-color-switcher.js +1 -4
  33. package/lib/core/hooks/use-product-picker.js +1 -1
  34. package/lib/core/hooks/use-telemetry-fallback.d.ts +60 -0
  35. package/lib/core/hooks/use-telemetry-fallback.js +66 -0
  36. package/lib/core/hooks/use-theme-hooks.js +2 -1
  37. package/lib/core/types/hooks.d.ts +2 -4
  38. package/lib/core/types/index.d.ts +0 -1
  39. package/lib/core/types/index.js +0 -1
  40. package/lib/icons/PlayIcon/PlayIcon.d.ts +9 -0
  41. package/lib/icons/PlayIcon/PlayIcon.js +21 -0
  42. package/lib/icons/WorkflowHierarchyIcon/WorkflowHierarchyIcon.d.ts +9 -0
  43. package/lib/icons/WorkflowHierarchyIcon/WorkflowHierarchyIcon.js +23 -0
  44. package/lib/index.d.ts +2 -0
  45. package/lib/index.js +2 -0
  46. package/lib/layouts/ThreePanelLayout.js +1 -4
  47. package/lib/markdoc/components/CodeWalkthrough/CodeFilters.js +2 -2
  48. package/lib/markdoc/components/CodeWalkthrough/CodePanel.js +1 -0
  49. package/lib/markdoc/components/CodeWalkthrough/CodeToggle.js +1 -1
  50. package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.js +7 -8
  51. package/package.json +2 -2
  52. package/src/components/Breadcrumbs/Breadcrumbs.tsx +4 -7
  53. package/src/components/Buttons/EditPageButton.tsx +1 -1
  54. package/src/components/Catalog/CatalogCardView/CatalogCard.tsx +1 -1
  55. package/src/components/Catalog/CatalogEntity/CatalogEntity.tsx +4 -76
  56. package/src/components/CatalogClassic/CatalogClassicActions.tsx +1 -1
  57. package/src/components/CatalogClassic/CatalogClassicCard.tsx +1 -1
  58. package/src/components/CatalogClassic/CatalogClassicInfoBlock.tsx +1 -3
  59. package/src/components/CodeBlock/CodeBlockControls.tsx +19 -9
  60. package/src/components/Feedback/Feedback.tsx +1 -1
  61. package/src/components/Feedback/ReportDialog.tsx +1 -1
  62. package/src/components/Filter/FilterCheckboxes.tsx +1 -1
  63. package/src/components/Footer/FooterItem.tsx +1 -1
  64. package/src/components/LanguagePicker/LanguagePicker.tsx +1 -4
  65. package/src/components/Logo/Logo.tsx +1 -1
  66. package/src/components/Menu/MenuItem.tsx +3 -6
  67. package/src/components/Navbar/Navbar.tsx +2 -2
  68. package/src/components/Navbar/NavbarItem.tsx +1 -3
  69. package/src/components/Search/SearchDialog.tsx +9 -15
  70. package/src/components/Search/SearchInput.tsx +1 -1
  71. package/src/components/Search/SearchRecent.tsx +1 -1
  72. package/src/components/SidebarActions/SidebarActions.tsx +3 -3
  73. package/src/components/Switch/Switch.tsx +34 -3
  74. package/src/components/TableOfContent/TableOfContent.tsx +1 -1
  75. package/src/components/Tooltip/TooltipWrapper.tsx +4 -6
  76. package/src/components/UserMenu/LoginButton.tsx +1 -1
  77. package/src/components/UserMenu/LogoutMenuItem.tsx +1 -1
  78. package/src/core/hooks/__mocks__/use-theme-hooks.ts +1 -0
  79. package/src/core/hooks/search/use-search-dialog.ts +2 -2
  80. package/src/core/hooks/use-color-switcher.ts +1 -4
  81. package/src/core/hooks/use-product-picker.ts +1 -1
  82. package/src/core/hooks/use-telemetry-fallback.ts +61 -0
  83. package/src/core/hooks/use-theme-hooks.ts +2 -1
  84. package/src/core/types/hooks.ts +10 -4
  85. package/src/core/types/index.ts +0 -1
  86. package/src/icons/PlayIcon/PlayIcon.tsx +22 -0
  87. package/src/icons/WorkflowHierarchyIcon/WorkflowHierarchyIcon.tsx +32 -0
  88. package/src/index.ts +2 -0
  89. package/src/layouts/ThreePanelLayout.tsx +1 -4
  90. package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +2 -2
  91. package/src/markdoc/components/CodeWalkthrough/CodePanel.tsx +1 -0
  92. package/src/markdoc/components/CodeWalkthrough/CodeToggle.tsx +5 -1
  93. package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +7 -8
  94. package/lib/core/types/telemetry.d.ts +0 -17
  95. package/lib/core/types/telemetry.js +0 -3
  96. package/src/core/types/telemetry.ts +0 -28
@@ -66,7 +66,8 @@ export function CodeBlockControls({
66
66
  dropdown,
67
67
  }: CodeBlockControlsProps): JSX.Element | null {
68
68
  const { codeSnippet } = useThemeConfig();
69
- const { useTelemetry } = useThemeHooks();
69
+ const { useTelemetry, useTranslate } = useThemeHooks();
70
+ const { translate } = useTranslate();
70
71
  const telemetry = useTelemetry();
71
72
  const controlsType = (codeSnippet?.elementFormat as ControlItemType) || 'icon';
72
73
  const { copy, expand, collapse, select, deselect, report } = controls || {
@@ -87,7 +88,10 @@ export function CodeBlockControls({
87
88
  <ControlsWrapper>
88
89
  {dropdown && <CodeBlockDropdown {...dropdown} />}
89
90
  {report && !report?.props?.hide ? (
90
- <TooltipWrapper tooltipTranslationKey="codeSnippet.report.tooltipText" placement="top">
91
+ <TooltipWrapper
92
+ tip={translate('codeSnippet.report.tooltipText', 'Report a problem')}
93
+ placement="top"
94
+ >
91
95
  <ControlButton
92
96
  variant="text"
93
97
  size="small"
@@ -101,7 +105,10 @@ export function CodeBlockControls({
101
105
  ) : null}
102
106
 
103
107
  {expand && !codeSnippet?.expand?.hide ? (
104
- <TooltipWrapper tooltipTranslationKey="codeSnippet.expand.tooltipText" placement="top">
108
+ <TooltipWrapper
109
+ tip={translate('codeSnippet.expand.tooltipText', 'Expand all')}
110
+ placement="top"
111
+ >
105
112
  <ControlButton
106
113
  variant="text"
107
114
  size="small"
@@ -115,7 +122,10 @@ export function CodeBlockControls({
115
122
  ) : null}
116
123
 
117
124
  {collapse && !codeSnippet?.collapse?.hide ? (
118
- <TooltipWrapper tooltipTranslationKey="codeSnippet.collapse.tooltipText" placement="top">
125
+ <TooltipWrapper
126
+ tip={translate('codeSnippet.collapse.tooltipText', 'Collapse all')}
127
+ placement="top"
128
+ >
119
129
  <ControlButton
120
130
  variant="text"
121
131
  size="small"
@@ -153,7 +163,10 @@ export function CodeBlockControls({
153
163
  ) : null}
154
164
 
155
165
  {copy && !codeSnippet?.copy?.hide ? (
156
- <TooltipWrapper tooltipTranslationKey="codeSnippet.copy.tooltipText" placement="top">
166
+ <TooltipWrapper
167
+ tip={translate('codeSnippet.copy.tooltipText', 'Copy to clipboard')}
168
+ placement="top"
169
+ >
157
170
  <StyledCopyButton
158
171
  data={copy.data}
159
172
  data-source={copy.dataSource}
@@ -167,10 +180,7 @@ export function CodeBlockControls({
167
180
  if (copy?.onClick) {
168
181
  copy?.onClick?.();
169
182
  } else {
170
- telemetry.send({
171
- type: 'openapi_docs.copy_code_snippet.clicked',
172
- payload: { snippetType: 'copy' },
173
- });
183
+ telemetry.sendCopyCodeSnippetClickedMessage({ snippetType: 'copy' });
174
184
  }
175
185
  }}
176
186
  />
@@ -58,7 +58,7 @@ export function Feedback(props: FeedbackProps & { path?: string }) {
58
58
  settings={settings}
59
59
  onSubmit={(values) => {
60
60
  submitFeedback({ type, values, path });
61
- telemetry.send({ type: 'feedback.sent', payload: { feedbackType: type } });
61
+ telemetry.sendFeedbackMessage({ feedbackType: type });
62
62
  }}
63
63
  />
64
64
  </FeedbackWrapper>
@@ -47,7 +47,7 @@ export function ReportDialog({
47
47
  path: pathname,
48
48
  lang,
49
49
  });
50
- telemetry.send({ type: 'code_snippet.reported' });
50
+ telemetry.sendCodeSnippetReportedMessage(undefined);
51
51
  onSubmit();
52
52
  }}
53
53
  isDialog={true}
@@ -36,7 +36,7 @@ export function FilterCheckboxes({
36
36
  role="link"
37
37
  onClick={() => {
38
38
  filter.toggleOption(value);
39
- telemetry.send({ type: 'filter_checkbox.toggled', payload: { id } });
39
+ telemetry.sendFilterCheckboxToggledMessage({ id });
40
40
  }}
41
41
  >
42
42
  <CheckboxIcon
@@ -44,7 +44,7 @@ export function FooterItem({ item, iconsOnly, className }: FooterItemProps): JSX
44
44
  external={item.external}
45
45
  target={item.target}
46
46
  data-testid={item.label}
47
- onClick={() => telemetry.send({ type: 'footer_item.clicked' })}
47
+ onClick={() => telemetry.sendFooterItemClickedMessage(undefined)}
48
48
  data-translation-key={item.labelTranslationKey}
49
49
  >
50
50
  {hasIcon ? (
@@ -40,10 +40,7 @@ export function LanguagePicker(props: LanguagePickerProps): JSX.Element | null {
40
40
  onAction: () => {
41
41
  setLocale(locale.code);
42
42
  props.onChangeLanguage(locale.code);
43
- telemetry.send({
44
- type: 'language_picker_locale.changed',
45
- payload: { locale: locale.code },
46
- });
43
+ telemetry.sendLanguagePickerLocaleChangedMessage({ locale: locale.code });
47
44
  },
48
45
  active: locale.code === currentLocale.code,
49
46
  suffix: locale.code === currentLocale.code && <CheckmarkIcon />,
@@ -27,7 +27,7 @@ export function Logo({ config, className, ...otherProps }: LogoProps): JSX.Eleme
27
27
  return (
28
28
  <LogoWrapper data-component-name="Logo/Logo" className={className} {...otherProps}>
29
29
  {config.link ? (
30
- <Link to={config.link} onClick={() => telemetry.send({ type: 'logo.clicked' })}>
30
+ <Link to={config.link} onClick={() => telemetry.sendLogoClickedMessage(undefined)}>
31
31
  {image}
32
32
  </Link>
33
33
  ) : (
@@ -37,12 +37,9 @@ export function MenuItem(props: React.PropsWithChildren<MenuItemProps>): JSX.Ele
37
37
  const hasHttpTag = !!item.httpVerb || type === MenuItemType.Operation;
38
38
 
39
39
  const handleOnClick = () => {
40
- telemetry.send({
41
- type: 'sidebar.item_clicked',
42
- payload: {
43
- label: item.label,
44
- type: item.type === 'link' || item.type === 'group' ? item.type : undefined,
45
- },
40
+ telemetry.sendSidebarItemClickedMessage({
41
+ label: item.label,
42
+ type: item.type === 'link' || item.type === 'group' ? item.type : undefined,
46
43
  });
47
44
  onClick?.();
48
45
  if (isNested) {
@@ -58,11 +58,11 @@ export function Navbar({ className }: NavbarProps): JSX.Element | null {
58
58
  isOpen
59
59
  ? () => {
60
60
  closeMobileMenu();
61
- telemetry.send({ type: 'mobile_menu_button_close.clicked' });
61
+ telemetry.sendMobileMenuButtonCloseClickedMessage(undefined);
62
62
  }
63
63
  : () => {
64
64
  openMobileMenu();
65
- telemetry.send({ type: 'mobile_menu_button_open.clicked' });
65
+ telemetry.sendMobileMenuButtonOpenClickedMessage(undefined);
66
66
  }
67
67
  }
68
68
  icon={isOpen ? <CloseIcon /> : <MenuIcon />}
@@ -46,9 +46,7 @@ export function NavbarItem({ navItem, className }: NavbarItemProps): JSX.Element
46
46
  as={item.link ? Link : undefined}
47
47
  active={isActive}
48
48
  className={className}
49
- onClick={() =>
50
- telemetry.send({ type: 'navbar.menu_item_clicked', payload: { type: item.type } })
51
- }
49
+ onClick={() => telemetry.sendNavbarMenuItemClickedMessage({ type: item.type })}
52
50
  external={item.external}
53
51
  target={item.target}
54
52
  to={item.link}
@@ -139,15 +139,12 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
139
139
  innerRef={innerRef}
140
140
  onClick={() => {
141
141
  addSearchHistoryItem(query);
142
- telemetry.send({
143
- type: 'search.result.clicked',
144
- payload: {
145
- query,
146
- url: item.document.url,
147
- totalResults: results.length.toString(),
148
- index: index.toString(),
149
- searchEngine: mode,
150
- },
142
+ telemetry.sendSearchResultClickedMessage({
143
+ query,
144
+ url: item.document.url,
145
+ totalResults: results.length.toString(),
146
+ index: index.toString(),
147
+ searchEngine: mode,
151
148
  });
152
149
  onClose();
153
150
  }}
@@ -381,12 +378,9 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
381
378
  <>
382
379
  <SearchRecent
383
380
  onSelect={(query, index) => {
384
- telemetry.send({
385
- type: 'search.recent.clicked',
386
- payload: {
387
- query,
388
- index: index.toString(),
389
- },
381
+ telemetry.sendSearchRecentClickedMessage({
382
+ query,
383
+ index: index.toString(),
390
384
  });
391
385
  setQuery(query);
392
386
  focusSearchInput();
@@ -51,7 +51,7 @@ export function SearchInput({
51
51
  const handleOnReset = () => {
52
52
  onChange('');
53
53
  addSearchHistoryItem(value);
54
- telemetry.send({ type: 'search_input_reset_button.clicked' });
54
+ telemetry.sendSearchInputResetButtonClickedMessage(undefined);
55
55
  };
56
56
 
57
57
  return (
@@ -25,7 +25,7 @@ export function SearchRecent({ onSelect, className }: SearchRecentProps): JSX.El
25
25
  const handleOnRemove = (e: React.MouseEvent<SVGSVGElement, MouseEvent>, item: string) => {
26
26
  e.stopPropagation();
27
27
  removeSearchHistoryItem(item);
28
- telemetry.send({ type: 'search_recent_remove_button.clicked' });
28
+ telemetry.sendSearchRecentRemoveButtonClickedMessage(undefined);
29
29
  };
30
30
 
31
31
  const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>, item: string, index: number) => {
@@ -48,9 +48,9 @@ export const SidebarActions = ({
48
48
  onClick={() => {
49
49
  onChangeCollapseSidebarClick();
50
50
  if (collapsedSidebar) {
51
- telemetry.send({ type: 'sidebar.item_expanded' });
51
+ telemetry.sendSidebarItemExpandedMessage(undefined);
52
52
  } else {
53
- telemetry.send({ type: 'sidebar.item_collapsed' });
53
+ telemetry.sendSidebarItemCollapsedMessage(undefined);
54
54
  }
55
55
  }}
56
56
  title={
@@ -70,7 +70,7 @@ export const SidebarActions = ({
70
70
  layout={layout}
71
71
  onClick={() => {
72
72
  onChangeViewClick();
73
- telemetry.send({ type: 'change_layout_button.clicked' });
73
+ telemetry.sendChangeLayoutButtonClickedMessage(undefined);
74
74
  }}
75
75
  />
76
76
  </ControlsWrapChangeLayoutButtons>
@@ -6,17 +6,48 @@ import type { JSX } from 'react';
6
6
  export type SwitchProps = {
7
7
  value: boolean;
8
8
  onChange: (value: boolean) => void;
9
+ onFocus?: () => void;
9
10
  disabled?: boolean;
11
+ stopPropagation?: boolean;
12
+ className?: string;
10
13
  };
11
14
 
12
- export function Switch({ value = false, disabled = false, onChange }: SwitchProps): JSX.Element {
13
- const handleClick = () => {
15
+ export function Switch({
16
+ value = false,
17
+ disabled = false,
18
+ onChange,
19
+ onFocus,
20
+ stopPropagation = false,
21
+ className,
22
+ }: SwitchProps): JSX.Element {
23
+ const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
14
24
  if (disabled) return;
25
+ if (stopPropagation) {
26
+ event.stopPropagation();
27
+ }
15
28
  onChange(!value);
16
29
  };
17
30
 
31
+ const handleFocus = (event: React.FocusEvent<HTMLDivElement>): void => {
32
+ if (stopPropagation) {
33
+ event.stopPropagation();
34
+ }
35
+
36
+ onFocus?.();
37
+ };
38
+
18
39
  return (
19
- <SwitchWrapper onClick={handleClick} role="switch" selected={value} disabled={disabled}>
40
+ <SwitchWrapper
41
+ tabIndex={disabled ? -1 : 0}
42
+ onFocus={handleFocus}
43
+ onClick={handleClick}
44
+ role="switch"
45
+ aria-checked={value}
46
+ aria-disabled={disabled}
47
+ selected={value}
48
+ disabled={disabled}
49
+ className={className}
50
+ >
20
51
  <Knob selected={value} disabled={disabled} />
21
52
  </SwitchWrapper>
22
53
  );
@@ -62,7 +62,7 @@ export function TableOfContent(props: TableOfContentProps): JSX.Element | null {
62
62
  data-testid={`toc-${heading.value}`}
63
63
  onClick={(e) => {
64
64
  e.preventDefault();
65
- telemetry.send({ type: 'toc_item.clicked' });
65
+ telemetry.sendTocItemClickedMessage(undefined);
66
66
  handleHeadingClick(heading.id);
67
67
  }}
68
68
  />
@@ -4,12 +4,12 @@ import React from 'react';
4
4
  import type { JSX, ReactElement } from 'react';
5
5
  import type { TooltipProps } from '@redocly/theme/components/Tooltip/Tooltip';
6
6
 
7
- import { useThemeHooks, useControl } from '@redocly/theme/core/hooks';
7
+ import { useControl } from '@redocly/theme/core/hooks';
8
8
  import { Tooltip } from '@redocly/theme/components/Tooltip/Tooltip';
9
9
 
10
10
  export type TooltipWrapperProps = {
11
11
  children: ReactElement;
12
- tooltipTranslationKey: string;
12
+ tip: string;
13
13
  placement?: TooltipProps['placement'];
14
14
  width?: string;
15
15
  className?: string;
@@ -19,16 +19,14 @@ export type TooltipWrapperProps = {
19
19
 
20
20
  export function TooltipWrapper({
21
21
  children,
22
- tooltipTranslationKey,
22
+ tip,
23
23
  placement = 'top',
24
24
  width = 'max-content',
25
25
  className = '',
26
26
  showOnHover = true,
27
27
  disabled = false,
28
28
  }: TooltipWrapperProps): JSX.Element {
29
- const { useTranslate } = useThemeHooks();
30
29
  const tooltip = useControl();
31
- const { translate } = useTranslate();
32
30
 
33
31
  const handleMouseEnter = (): void => {
34
32
  if (showOnHover && !disabled) {
@@ -51,7 +49,7 @@ export function TooltipWrapper({
51
49
  return (
52
50
  <Tooltip
53
51
  className={className}
54
- tip={translate(tooltipTranslationKey)}
52
+ tip={tip}
55
53
  isOpen={tooltip.isOpened}
56
54
  placement={placement}
57
55
  width={width}
@@ -20,7 +20,7 @@ export function LoginButton({ href, className }: LoginButtonProps): JSX.Element
20
20
  <Button
21
21
  data-translation-key="userMenu.login"
22
22
  to={href}
23
- onClick={() => telemetry.send({ type: 'login_button.clicked' })}
23
+ onClick={() => telemetry.sendLoginButtonClickedMessage(undefined)}
24
24
  data-testid="login-btn"
25
25
  extraClass={className}
26
26
  variant="primary"
@@ -18,7 +18,7 @@ export function LogoutMenuItem({ iconOnly, className }: LogoutMenuItemProps): JS
18
18
  const { translate } = useTranslate();
19
19
 
20
20
  const handleClick = () => {
21
- telemetry.send({ type: 'logout_menu_item.clicked' });
21
+ telemetry.sendLogoutMenuItemClickedMessage(undefined);
22
22
  handleLogout();
23
23
  };
24
24
 
@@ -12,6 +12,7 @@ export const useThemeHooks = vi.fn(() => ({
12
12
  })),
13
13
  useTelemetry: vi.fn(() => ({
14
14
  send: vi.fn(),
15
+ sendCodeSnippetReportedMessage: vi.fn(),
15
16
  })),
16
17
  useBreadcrumbs: vi.fn().mockReturnValue([]),
17
18
  usePageSharedData: vi.fn().mockReturnValue({}),
@@ -18,7 +18,7 @@ export function useSearchDialog() {
18
18
  if (hotKeys) {
19
19
  hotkeys(hotKeys, (ev) => {
20
20
  setIsOpen(true);
21
- telemetry.send({ type: 'search.opened', payload: { method: 'shortcut' } });
21
+ telemetry.sendSearchOpenedMessage({ method: 'shortcut' });
22
22
  ev.preventDefault();
23
23
  });
24
24
 
@@ -28,7 +28,7 @@ export function useSearchDialog() {
28
28
  }, [hotKeys]);
29
29
 
30
30
  const onOpen = useCallback(function () {
31
- telemetry.send({ type: 'search.opened', payload: { method: 'click' } });
31
+ telemetry.sendSearchOpenedMessage({ method: 'click' });
32
32
  setIsOpen(true);
33
33
  // eslint-disable-next-line react-hooks/exhaustive-deps
34
34
  }, []);
@@ -34,10 +34,7 @@ export const useColorSwitcher = () => {
34
34
  window.requestAnimationFrame(() => {
35
35
  document.documentElement.classList.remove('notransition');
36
36
  });
37
- telemetry.send({
38
- type: 'color_mode.switched',
39
- payload: { from: activeColorMode, to: newMode },
40
- });
37
+ telemetry.sendColorModeSwitchedMessage({ from: activeColorMode, to: newMode });
41
38
 
42
39
  setActiveColorMode(newMode);
43
40
  };
@@ -11,7 +11,7 @@ export function useProductPicker() {
11
11
  const loadAndNavigate = useLoadAndNavigate();
12
12
  function setProduct(product: typeof currentProduct) {
13
13
  if (!product) return;
14
- telemetry.send({ type: 'product.picked', payload: { product: product.slug } });
14
+ telemetry.sendProductPickedMessage({ product: product.slug });
15
15
  loadAndNavigate({ navigate, to: product.link });
16
16
  }
17
17
  return {
@@ -0,0 +1,61 @@
1
+ // TODO we need to create some common way to do this.
2
+ export const useTelemetryFallback = () => ({
3
+ send: () => {},
4
+ sendPageViewedMessage: () => {},
5
+ sendErrorMessage: () => {},
6
+ sendClientErrorMessage: () => {},
7
+ sendBreadcrumbClickedMessage: () => {},
8
+ sendColorModeSwitchedMessage: () => {},
9
+ sendSidebarItemClickedMessage: () => {},
10
+ sendSidebarItemExpandedMessage: () => {},
11
+ sendSidebarItemCollapsedMessage: () => {},
12
+ sendChangeLayoutButtonClickedMessage: () => {},
13
+ sendEditPageLinkClickedMessage: () => {},
14
+ sendCodeSnippetReportedMessage: () => {},
15
+ sendNavbarMenuItemClickedMessage: () => {},
16
+ sendLoginButtonClickedMessage: () => {},
17
+ sendLoginProviderButtonClickedMessage: () => {},
18
+ sendLogoutMenuItemClickedMessage: () => {},
19
+ sendLogoClickedMessage: () => {},
20
+ sendTocItemClickedMessage: () => {},
21
+ sendCatalogFilterChangedMessage: () => {},
22
+ sendCatalogItemClickedMessage: () => {},
23
+ sendScorecardLinkClickedMessage: () => {},
24
+ sendBackToCatalogButtonClickedMessage: () => {},
25
+ sendSidebarDrilldownBackButtonClickedMessage: () => {},
26
+ sendFooterItemClickedMessage: () => {},
27
+ sendCatalogActionsButtonClickedMessage: () => {},
28
+ sendMobileMenuButtonCloseClickedMessage: () => {},
29
+ sendMobileMenuButtonOpenClickedMessage: () => {},
30
+ sendSearchInputResetButtonClickedMessage: () => {},
31
+ sendSearchRecentRemoveButtonClickedMessage: () => {},
32
+ sendSearchRecentClickedMessage: () => {},
33
+ sendRequestApiAccessButtonClickedMessage: () => {},
34
+ sendVersionPickerSelectionChangeMessage: () => {},
35
+ sendProductPickedMessage: () => {},
36
+ sendFilterCheckboxToggledMessage: () => {},
37
+ sendLanguagePickerLocaleChangedMessage: () => {},
38
+ sendSearchOpenedMessage: () => {},
39
+ sendSearchQueryMessage: () => {},
40
+ sendSearchAIQueryMessage: () => {},
41
+ sendFeedbackMessage: () => {},
42
+ sendSearchResultClickedMessage: () => {},
43
+ sendRedirectMessage: () => {},
44
+ sendOpenapiDocsMessage: () => {},
45
+ sendCopyCodeSnippetClickedMessage: () => {},
46
+ sendOpenapiDocsViewedMessage: () => {},
47
+ sendOpenapiDocsPerformanceMetricsMessage: () => {},
48
+ sendOpenapiDocsDownloadDefinitionClickedMessage: () => {},
49
+ sendOpenapiDocsSelectLanguageClickedMessage: () => {},
50
+ sendOpenapiDocsExpandCollapseAllClickedMessage: () => {},
51
+ sendOpenapiDocsSwitchServersClickedMessage: () => {},
52
+ sendOpenapiDocsExamplesSwitcherClickedMessage: () => {},
53
+ sendOpenapiDocsTryItOpenedMessage: () => {},
54
+ sendAsyncapiDocsViewedMessage: () => {},
55
+ sendAsyncapiDocsPerformanceMetricsMessage: () => {},
56
+ sendAsyncapiDocsSwitchMessageClickedMessage: () => {},
57
+ sendAsyncapiDocsSwitchExampleClickedMessage: () => {},
58
+ sendAsyncapiDocsMessageClickedMessage: () => {},
59
+ sendAsyncapiDocsServerModalOpenedMessage: () => {},
60
+ sendAsyncapiDocsDownloadDefinitionClickedMessage: () => {},
61
+ });
@@ -3,6 +3,7 @@ import { useContext } from 'react';
3
3
  import type { ThemeHooks } from '../types/hooks';
4
4
 
5
5
  import { ThemeDataContext } from '../contexts/ThemeDataContext';
6
+ import { useTelemetryFallback } from './use-telemetry-fallback';
6
7
 
7
8
  const fallbacks = {
8
9
  useTranslate: () => ({
@@ -10,7 +11,7 @@ const fallbacks = {
10
11
  (typeof options === 'string' ? options : options?.defaultValue) || value || '',
11
12
  }),
12
13
  useSubmitFeedback: () => ({ submitFeedback: () => {} }),
13
- useTelemetry: () => ({ send: () => {} }),
14
+ useTelemetry: useTelemetryFallback,
14
15
  /**
15
16
  * @deprecated use `useTelemetry` instead
16
17
  **/
@@ -1,3 +1,4 @@
1
+ import type { AsyncApiRealmUI } from '@redocly/realm-asyncapi-sdk';
1
2
  import type {
2
3
  CatalogEntityConfig,
3
4
  PageData,
@@ -26,7 +27,6 @@ import type {
26
27
  SearchFacetQuery,
27
28
  AiSearchConversationItem,
28
29
  } from './search';
29
- import type { EventType, SendEventParams } from './telemetry';
30
30
  import type { SubmitFeedbackParams } from './feedback';
31
31
  import type { TFunction } from './l10n';
32
32
  import type { BreadcrumbItem } from './breadcrumb';
@@ -148,9 +148,15 @@ export type ThemeHooks = {
148
148
  initialData?: BffCatalogRelatedEntityList,
149
149
  ) => CatalogApiResults<BffCatalogRelatedEntity, BffCatalogRelatedEntityList>;
150
150
  useCatalogClassic: (config: CatalogConfig) => FilteredCatalog;
151
- useTelemetry: () => {
152
- send<TEventType extends EventType>(event: SendEventParams<TEventType>): void;
153
- };
151
+ useTelemetry: () => Omit<
152
+ AsyncApiRealmUI.Telemetry,
153
+ | 'init'
154
+ | 'updateCloudEventData'
155
+ | 'forceFlush'
156
+ | 'startSpan'
157
+ | 'constructCloudEvent'
158
+ | 'sendToOtelService'
159
+ >;
154
160
  useUserTeams: () => string[];
155
161
  usePageData: () => PageData | null;
156
162
  usePageProps: <T extends Record<string, unknown>>() => PageProps & T;
@@ -15,5 +15,4 @@ export * from './common';
15
15
  export * from './open-api-server';
16
16
  export * from './marker';
17
17
  export * from './code-walkthrough';
18
- export * from './telemetry';
19
18
  export * from './page-actions';
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import type { IconProps } from '@redocly/theme/icons/types';
5
+
6
+ import { getCssColorVariable } from '@redocly/theme/core/utils';
7
+
8
+ const Icon = (props: IconProps) => (
9
+ <svg viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
10
+ <path d="M3.0625 12.25C2.94647 12.25 2.83519 12.2039 2.75314 12.1219C2.67109 12.0398 2.625 11.9286 2.625 11.8125V2.18753C2.62499 2.1115 2.6448 2.03678 2.68247 1.97074C2.72014 1.9047 2.77437 1.84961 2.83981 1.81092C2.90526 1.77222 2.97965 1.75124 3.05567 1.75005C3.13169 1.74887 3.20671 1.76751 3.27333 1.80415L12.0233 6.61665C12.092 6.6544 12.1492 6.70989 12.1891 6.77733C12.229 6.84476 12.25 6.92167 12.25 7.00001C12.25 7.07835 12.229 7.15526 12.1891 7.22269C12.1492 7.29013 12.092 7.34562 12.0233 7.38337L3.27333 12.1959C3.20874 12.2314 3.13622 12.25 3.0625 12.25ZM3.5 2.9273V11.0726L10.9046 7.00003L3.5 2.9273Z" />
11
+ </svg>
12
+ );
13
+
14
+ export const PlayIcon = styled(Icon).attrs(() => ({
15
+ 'data-component-name': 'icons/PlayIcon/PlayIcon',
16
+ }))<IconProps>`
17
+ path {
18
+ fill: ${({ color }) => getCssColorVariable(color)};
19
+ }
20
+ height: ${({ size }) => size || '16px'};
21
+ width: ${({ size }) => size || '16px'};
22
+ `;
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import type { IconProps } from '@redocly/theme/icons/types';
5
+
6
+ import { getCssColorVariable } from '@redocly/theme/core/utils';
7
+
8
+ const Icon = (props: IconProps) => (
9
+ <svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" {...props}>
10
+ <path
11
+ fillRule="evenodd"
12
+ clipRule="evenodd"
13
+ d="M4.5 6.5H13.5C13.7651 6.4997 14.0193 6.39424 14.2068 6.20677C14.3942 6.0193 14.4997 5.76512 14.5 5.5V2.5C14.4997 2.23488 14.3942 1.9807 14.2068 1.79323C14.0193 1.60576 13.7651 1.5003 13.5 1.5H2.5C2.23488 1.5003 1.9807 1.60576 1.79323 1.79323C1.60576 1.9807 1.5003 2.23488 1.5 2.5V5.5C1.5003 5.76512 1.60576 6.0193 1.79323 6.20677C1.9807 6.39424 2.23488 6.4997 2.5 6.5H3.5H4.5ZM13.5 2.5H2.5V5.5H13.5V2.5Z"
14
+ />
15
+ <path
16
+ fillRule="evenodd"
17
+ clipRule="evenodd"
18
+ d="M13.5 9.5H8.5C8.23488 9.5003 7.9807 9.60576 7.79323 9.79323C7.60576 9.9807 7.5003 10.2349 7.5 10.5V11.5H4.5V9.29295V8.5V6.5H3.5V9.29295V11.5C3.5003 11.7651 3.60576 12.0193 3.79323 12.2068C3.9807 12.3942 4.23488 12.4997 4.5 12.5H7.5V13.5C7.5003 13.7651 7.60576 14.0193 7.79323 14.2068C7.9807 14.3942 8.23488 14.4997 8.5 14.5H13.5C13.7651 14.4997 14.0193 14.3942 14.2068 14.2068C14.3942 14.0193 14.4997 13.7651 14.5 13.5V10.5C14.4997 10.2349 14.3942 9.9807 14.2068 9.79323C14.0193 9.60576 13.7651 9.5003 13.5 9.5ZM8.5 10.5V13.5H13.5V10.5H8.5Z"
19
+ />
20
+ </svg>
21
+ );
22
+
23
+ export const WorkflowHierarchyIcon = styled(Icon).attrs(() => ({
24
+ 'data-component-name': 'icons/WorkflowHierarchyIcon/WorkflowHierarchyIcon',
25
+ }))<IconProps>`
26
+ path {
27
+ fill: ${({ color }) => getCssColorVariable(color)};
28
+ }
29
+
30
+ height: ${({ size }) => size || '16px'};
31
+ width: ${({ size }) => size || '16px'};
32
+ `;
package/src/index.ts CHANGED
@@ -264,6 +264,7 @@ export * from '@redocly/theme/icons/CharacterIcon/CharacterIcon';
264
264
  export * from '@redocly/theme/icons/FileIcon/FileIcon';
265
265
  export * from '@redocly/theme/icons/ExportIcon/ExportIcon';
266
266
  export * from '@redocly/theme/icons/CertificateIcon/CertificateIcon';
267
+ export * from '@redocly/theme/icons/PlayIcon/PlayIcon';
267
268
  export * from '@redocly/theme/icons/PlaylistIcon/PlaylistIcon';
268
269
  export * from '@redocly/theme/icons/WorkflowAutomationIcon/WorkflowAutomationIcon';
269
270
  export * from '@redocly/theme/icons/TaskViewIcon/TaskViewIcon';
@@ -280,6 +281,7 @@ export * from '@redocly/theme/icons/RabbitMQIcon/RabbitMQIcon';
280
281
  export * from '@redocly/theme/icons/CurveAutoColonIcon/CurveAutoColonIcon';
281
282
  export * from '@redocly/theme/icons/AiStarsIcon/AiStarsIcon';
282
283
  export * from '@redocly/theme/icons/AiStarsGradientIcon/AiStarsGradientIcon';
284
+ export * from '@redocly/theme/icons/WorkflowHierarchyIcon/WorkflowHierarchyIcon';
283
285
  export * from '@redocly/theme/icons/GenericIcon/GenericIcon';
284
286
  /* Layouts */
285
287
  export * from '@redocly/theme/layouts/RootLayout';
@@ -30,14 +30,11 @@ const Wrapper = styled.div<{ collapsedSidebar?: boolean; layout?: LayoutVariant
30
30
  margin: 0 auto;
31
31
  width: 100%;
32
32
 
33
- ${({ layout = LayoutVariant.THREE_PANEL, collapsedSidebar }) => {
33
+ ${({ layout = LayoutVariant.THREE_PANEL }) => {
34
34
  return css`
35
35
  max-width: ${layout === LayoutVariant.THREE_PANEL ? '100%' : ''};
36
36
 
37
37
  @media screen and (min-width: ${breakpoints.small}) {
38
- width: ${collapsedSidebar
39
- ? `var(--layout-${layout}-small-max-width)`
40
- : 'calc(100% - var(--sidebar-width))'};
41
38
  max-width: var(--layout-${layout}-small-max-width);
42
39
  }
43
40