@redocly/theme 0.67.0-next.3 → 0.67.0-next.5

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 (83) hide show
  1. package/lib/components/Breadcrumbs/BreadcrumbDropdown.d.ts +2 -1
  2. package/lib/components/Breadcrumbs/BreadcrumbDropdown.js +9 -10
  3. package/lib/components/Breadcrumbs/Breadcrumbs.js +5 -22
  4. package/lib/components/Buttons/AIAssistantButton.js +2 -6
  5. package/lib/components/Buttons/EditPageButton.js +2 -1
  6. package/lib/components/Catalog/CatalogCardView/CatalogCard.js +1 -1
  7. package/lib/components/CatalogClassic/CatalogClassicActions.js +3 -1
  8. package/lib/components/CatalogClassic/CatalogClassicCard.js +1 -1
  9. package/lib/components/CatalogClassic/CatalogClassicInfoBlock.js +2 -1
  10. package/lib/components/Dropdown/Dropdown.d.ts +2 -0
  11. package/lib/components/Dropdown/Dropdown.js +8 -2
  12. package/lib/components/Feedback/ReportDialog.js +4 -1
  13. package/lib/components/Filter/FilterCheckboxes.js +3 -1
  14. package/lib/components/Footer/FooterItem.js +1 -1
  15. package/lib/components/LanguagePicker/LanguagePicker.js +3 -1
  16. package/lib/components/Logo/Logo.js +2 -1
  17. package/lib/components/Menu/MenuContainer.js +1 -0
  18. package/lib/components/Menu/MenuItem.js +21 -7
  19. package/lib/components/Navbar/Navbar.js +6 -2
  20. package/lib/components/Navbar/NavbarItem.js +3 -1
  21. package/lib/components/Search/SearchAiMessage.js +23 -5
  22. package/lib/components/Search/SearchDialog.js +5 -33
  23. package/lib/components/Search/SearchInput.js +4 -1
  24. package/lib/components/Search/SearchRecent.js +3 -1
  25. package/lib/components/SidebarActions/SidebarActions.js +10 -3
  26. package/lib/components/TableOfContent/TableOfContent.js +1 -1
  27. package/lib/components/UserMenu/LoginButton.js +2 -1
  28. package/lib/components/UserMenu/LogoutMenuItem.js +2 -1
  29. package/lib/core/hooks/search/use-search-dialog.js +7 -2
  30. package/lib/core/hooks/use-banner-telemetry.js +2 -11
  31. package/lib/core/hooks/use-color-switcher.js +2 -1
  32. package/lib/core/hooks/use-page-actions.js +12 -21
  33. package/lib/core/hooks/use-product-picker.js +14 -4
  34. package/lib/core/hooks/use-telemetry-fallback.d.ts +45 -37
  35. package/lib/core/hooks/use-telemetry-fallback.js +47 -39
  36. package/lib/core/types/search.d.ts +2 -1
  37. package/lib/core/types/search.js +1 -0
  38. package/lib/core/utils/index.d.ts +2 -0
  39. package/lib/core/utils/index.js +2 -0
  40. package/lib/core/utils/telemetry/generate-before-after-context.d.ts +37 -0
  41. package/lib/core/utils/telemetry/generate-before-after-context.js +32 -0
  42. package/lib/core/utils/telemetry/generate-resource-urn.d.ts +7 -0
  43. package/lib/core/utils/telemetry/generate-resource-urn.js +13 -0
  44. package/lib/core/utils/telemetry/get-base-data-attributes.d.ts +14 -0
  45. package/lib/core/utils/telemetry/get-base-data-attributes.js +17 -0
  46. package/package.json +3 -3
  47. package/src/components/Breadcrumbs/BreadcrumbDropdown.tsx +18 -4
  48. package/src/components/Breadcrumbs/Breadcrumbs.tsx +5 -6
  49. package/src/components/Buttons/AIAssistantButton.tsx +2 -3
  50. package/src/components/Buttons/EditPageButton.tsx +4 -1
  51. package/src/components/Catalog/CatalogCardView/CatalogCard.tsx +2 -2
  52. package/src/components/CatalogClassic/CatalogClassicActions.tsx +4 -2
  53. package/src/components/CatalogClassic/CatalogClassicCard.tsx +9 -2
  54. package/src/components/CatalogClassic/CatalogClassicInfoBlock.tsx +2 -1
  55. package/src/components/Dropdown/Dropdown.tsx +8 -1
  56. package/src/components/Feedback/ReportDialog.tsx +4 -1
  57. package/src/components/Filter/FilterCheckboxes.tsx +4 -2
  58. package/src/components/Footer/FooterItem.tsx +4 -2
  59. package/src/components/LanguagePicker/LanguagePicker.tsx +9 -2
  60. package/src/components/Logo/Logo.tsx +7 -1
  61. package/src/components/Menu/MenuContainer.tsx +1 -0
  62. package/src/components/Menu/MenuItem.tsx +35 -4
  63. package/src/components/Navbar/Navbar.tsx +7 -3
  64. package/src/components/Navbar/NavbarItem.tsx +7 -1
  65. package/src/components/Search/SearchAiMessage.tsx +25 -5
  66. package/src/components/Search/SearchDialog.tsx +6 -13
  67. package/src/components/Search/SearchInput.tsx +4 -1
  68. package/src/components/Search/SearchRecent.tsx +4 -2
  69. package/src/components/SidebarActions/SidebarActions.tsx +10 -3
  70. package/src/components/TableOfContent/TableOfContent.tsx +7 -2
  71. package/src/components/UserMenu/LoginButton.tsx +4 -1
  72. package/src/components/UserMenu/LogoutMenuItem.tsx +2 -1
  73. package/src/core/hooks/search/use-search-dialog.ts +13 -2
  74. package/src/core/hooks/use-banner-telemetry.ts +5 -4
  75. package/src/core/hooks/use-color-switcher.ts +7 -1
  76. package/src/core/hooks/use-page-actions.ts +17 -28
  77. package/src/core/hooks/use-product-picker.ts +19 -5
  78. package/src/core/hooks/use-telemetry-fallback.ts +47 -39
  79. package/src/core/types/search.ts +1 -0
  80. package/src/core/utils/index.ts +2 -0
  81. package/src/core/utils/telemetry/generate-before-after-context.ts +59 -0
  82. package/src/core/utils/telemetry/generate-resource-urn.ts +9 -0
  83. package/src/core/utils/telemetry/get-base-data-attributes.ts +27 -0
@@ -9,6 +9,7 @@ type BreadcrumbDropdownProps = {
9
9
  })[];
10
10
  onItemClick?: (item: BreadcrumbItem, index: number) => void;
11
11
  className?: string;
12
+ withChevron?: boolean;
12
13
  };
13
- export declare function BreadcrumbDropdown({ children, label, items, onItemClick, className }: BreadcrumbDropdownProps): JSX.Element | null;
14
+ export declare function BreadcrumbDropdown({ children, label, items, onItemClick, className, withChevron }: BreadcrumbDropdownProps): JSX.Element | null;
14
15
  export {};
@@ -47,19 +47,23 @@ const Tooltip_1 = require("../../components/Tooltip/Tooltip");
47
47
  const GenericIcon_1 = require("../../icons/GenericIcon/GenericIcon");
48
48
  const constants_1 = require("../../core/constants");
49
49
  const BreadcrumbIcon_1 = require("../../components/Breadcrumbs/BreadcrumbIcon");
50
- function BreadcrumbDropdown({ children, label, items, onItemClick, className, }) {
50
+ const utils_1 = require("../../core/utils");
51
+ function BreadcrumbDropdown({ children, label, items, onItemClick, className, withChevron, }) {
51
52
  const { useTelemetry, useTranslate } = (0, hooks_1.useThemeHooks)();
52
53
  const telemetry = useTelemetry();
53
54
  const { translate } = useTranslate();
55
+ const [isOpen, setIsOpen] = react_1.default.useState(false);
54
56
  if (!items || items.length === 0) {
55
57
  return null;
56
58
  }
57
59
  const isTruncated = label.length > constants_1.BREADCRUMB_MAX_LENGTH;
58
60
  const triggerContent = isTruncated ? (react_1.default.createElement(Tooltip_1.Tooltip, { tip: label, placement: "bottom" },
59
61
  react_1.default.createElement(TriggerContentWrapper, null, children))) : (children);
60
- const trigger = react_1.default.createElement(StyledDropdownTrigger, null, triggerContent);
62
+ const trigger = (react_1.default.createElement(StyledDropdownTrigger, null,
63
+ triggerContent,
64
+ withChevron && react_1.default.createElement(GenericIcon_1.GenericIcon, { icon: isOpen ? 'chevron-up' : 'chevron-down' })));
61
65
  return (react_1.default.createElement(BreadcrumbDropdownWrapper, { "data-component-name": "Breadcrumbs/BreadcrumbDropdown", className: className, "data-testid": "breadcrumb-dropdown" },
62
- react_1.default.createElement(Dropdown_1.Dropdown, { trigger: trigger, closeOnClick: true },
66
+ react_1.default.createElement(Dropdown_1.Dropdown, { trigger: trigger, closeOnClick: true, onOpen: () => setIsOpen(true), onClose: () => setIsOpen(false) },
63
67
  react_1.default.createElement(DropdownMenu_1.DropdownMenu, null, items.map((item, index) => {
64
68
  const isActive = Boolean(item === null || item === void 0 ? void 0 : item.isActive);
65
69
  const hasLink = Boolean(item.link);
@@ -67,12 +71,7 @@ function BreadcrumbDropdown({ children, label, items, onItemClick, className, })
67
71
  return (react_1.default.createElement(StyledDropdownMenuItem, { key: index, onAction: () => {
68
72
  onItemClick === null || onItemClick === void 0 ? void 0 : onItemClick(item, index);
69
73
  telemetry.sendBreadcrumbClickedMessage([
70
- {
71
- object: 'breadcrumb',
72
- link: item.link,
73
- position: index + 1,
74
- totalBreadcrumbs: items.length,
75
- },
74
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('breadcrumbId', 'breadcrumb')), { link: item.link, position: index + 1, totalBreadcrumbs: items.length }),
76
75
  ]);
77
76
  }, $hasLink: hasLink, to: item.link, dataAttributes: !hasLink ? { 'aria-disabled': 'true' } : {} },
78
77
  react_1.default.createElement(DropdownContent, { $isActive: isActive },
@@ -101,7 +100,7 @@ const StyledDropdownTrigger = styled_components_1.default.button `
101
100
  background-color: var(--breadcrumbs-background-color-hover);
102
101
  }
103
102
 
104
- &:focus {
103
+ &:focus-visible {
105
104
  box-shadow: var(--breadcrumbs-box-shadow-focus);
106
105
  outline: none;
107
106
  }
@@ -12,7 +12,6 @@ const BreadcrumbDropdown_1 = require("../../components/Breadcrumbs/BreadcrumbDro
12
12
  const BreadcrumbIcon_1 = require("../../components/Breadcrumbs/BreadcrumbIcon");
13
13
  const utils_1 = require("../../core/utils");
14
14
  const constants_1 = require("../../core/constants");
15
- const GenericIcon_1 = require("../../icons/GenericIcon/GenericIcon");
16
15
  function Breadcrumbs(props) {
17
16
  const { useBreadcrumbs, useTelemetry, useTranslate } = (0, hooks_1.useThemeHooks)();
18
17
  const { breadcrumbs: fileBreadcrumbs, currentItemSiblings } = useBreadcrumbs();
@@ -46,25 +45,14 @@ function Breadcrumbs(props) {
46
45
  ...currentItemSiblings,
47
46
  ];
48
47
  const translatedLabel = translate(breadcrumb.labelTranslationKey, breadcrumb.label);
49
- return (react_1.default.createElement(BreadcrumbDropdown_1.BreadcrumbDropdown, { label: translatedLabel, items: siblingsWithActive, onItemClick: (item, itemIdx) => telemetry.sendBreadcrumbClickedMessage([
50
- {
51
- object: 'breadcrumb',
52
- link: item.link,
53
- position: itemIdx + 1,
54
- totalBreadcrumbs: siblingsWithActive.length,
55
- },
48
+ return (react_1.default.createElement(BreadcrumbDropdown_1.BreadcrumbDropdown, { label: translatedLabel, items: siblingsWithActive, withChevron: true, onItemClick: (item, itemIdx) => telemetry.sendBreadcrumbClickedMessage([
49
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('breadcrumbId', 'breadcrumb')), { link: item.link, position: itemIdx + 1, totalBreadcrumbs: siblingsWithActive.length }),
56
50
  ]) },
57
51
  react_1.default.createElement(BreadcrumbIcon_1.BreadcrumbIcon, { icon: breadcrumb.icon }),
58
- (0, utils_1.trimText)(translatedLabel, constants_1.BREADCRUMB_MAX_LENGTH),
59
- react_1.default.createElement(GenericIcon_1.GenericIcon, { icon: "chevron-down" })));
52
+ (0, utils_1.trimText)(translatedLabel, constants_1.BREADCRUMB_MAX_LENGTH)));
60
53
  }
61
54
  return (react_1.default.createElement(Breadcrumb_1.Breadcrumb, { link: breadcrumb.link, label: translate(breadcrumb.labelTranslationKey, breadcrumb.label), isActive: isActive, icon: breadcrumb.icon, onClick: () => telemetry.sendBreadcrumbClickedMessage([
62
- {
63
- object: 'breadcrumb',
64
- link: breadcrumb.link,
65
- position: idx + 1,
66
- totalBreadcrumbs: breadcrumbs.length,
67
- },
55
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('breadcrumbId', 'breadcrumb')), { link: breadcrumb.link, position: idx + 1, totalBreadcrumbs: breadcrumbs.length }),
68
56
  ]) }));
69
57
  };
70
58
  return (react_1.default.createElement(BreadcrumbsWrapper, { "data-component-name": "Breadcrumbs/Breadcrumbs", className: props.className }, items.map(({ breadcrumb, idx, isLast, inDropdown }) => {
@@ -76,12 +64,7 @@ function Breadcrumbs(props) {
76
64
  renderBreadcrumb(breadcrumb, idx, isLast),
77
65
  react_1.default.createElement(BreadcrumbSeparator, null, "/"),
78
66
  react_1.default.createElement(BreadcrumbDropdown_1.BreadcrumbDropdown, { label: "...", items: collapsedBreadcrumbs, onItemClick: (item, itemIdx) => telemetry.sendBreadcrumbClickedMessage([
79
- {
80
- object: 'breadcrumb',
81
- link: item.link,
82
- position: itemIdx + 1,
83
- totalBreadcrumbs: breadcrumbs.length,
84
- },
67
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('breadcrumbId', 'breadcrumb')), { link: item.link, position: itemIdx + 1, totalBreadcrumbs: breadcrumbs.length }),
85
68
  ]) }, "..."),
86
69
  react_1.default.createElement(BreadcrumbSeparator, null, "/")));
87
70
  }
@@ -47,6 +47,7 @@ const ChatIcon_1 = require("../../icons/ChatIcon/ChatIcon");
47
47
  const AiStarsGradientIcon_1 = require("../../icons/AiStarsGradientIcon/AiStarsGradientIcon");
48
48
  const RedoclyIcon_1 = require("../../icons/RedoclyIcon/RedoclyIcon");
49
49
  const contexts_1 = require("../../core/contexts");
50
+ const utils_1 = require("../../core/utils");
50
51
  const defaultConfig = {
51
52
  hide: false,
52
53
  inputType: 'button',
@@ -88,12 +89,7 @@ function AIAssistantButton() {
88
89
  const handleOpen = () => {
89
90
  setIsOpen(true);
90
91
  telemetry.sendSearchAiOpenedMessage([
91
- {
92
- id: 'aiAssistantTriggerButton',
93
- object: 'search',
94
- uri: 'urn:redocly:realm:ui:search:aiAssistantTriggerButton',
95
- method: 'ai_trigger_button',
96
- },
92
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('aiAssistantTriggerButton', 'search')), { method: 'ai_trigger_button' }),
97
93
  ]);
98
94
  };
99
95
  const handleClose = () => {
@@ -9,12 +9,13 @@ const styled_components_1 = __importDefault(require("styled-components"));
9
9
  const hooks_1 = require("../../core/hooks");
10
10
  const EditIcon_1 = require("../../icons/EditIcon/EditIcon");
11
11
  const Button_1 = require("../../components/Button/Button");
12
+ const utils_1 = require("../../core/utils");
12
13
  function EditPageButton({ to }) {
13
14
  const { useTranslate, useTelemetry } = (0, hooks_1.useThemeHooks)();
14
15
  const { translate } = useTranslate();
15
16
  const telemetry = useTelemetry();
16
17
  return (react_1.default.createElement(EditPageButtonWrapper, { "data-component-name": "Buttons/EditPageButton" },
17
- react_1.default.createElement(Button_1.Button, { to: to, external: true, variant: "ghost", size: "small", icon: react_1.default.createElement(EditIcon_1.EditIcon, null), onClick: () => telemetry.sendEditPageLinkClickedMessage(), "data-translation-key": "markdown.editPage.text" }, translate('markdown.editPage.text', 'Edit'))));
18
+ react_1.default.createElement(Button_1.Button, { to: to, external: true, variant: "ghost", size: "small", icon: react_1.default.createElement(EditIcon_1.EditIcon, null), onClick: () => telemetry.sendPageEditClickedMessage([(0, utils_1.getBaseDataAttributes)('pageEdit', 'button')]), "data-translation-key": "markdown.editPage.text" }, translate('markdown.editPage.text', 'Edit'))));
18
19
  }
19
20
  const EditPageButtonWrapper = styled_components_1.default.div `
20
21
  margin-left: auto;
@@ -23,7 +23,7 @@ function CatalogCard({ entity, catalogConfig }) {
23
23
  const pathPrefix = (0, utils_1.getPathPrefix)();
24
24
  return (react_1.default.createElement(CatalogCardWrapper, { "data-component-name": "Catalog/CatalogCardView/CatalogCard", onClick: () => {
25
25
  window.location.assign(`${pathPrefix}/catalogs/${catalogConfig.slug}/entities/${entity.key}`);
26
- telemetry.sendCatalogItemClickedMessage();
26
+ telemetry.sendCatalogItemClickedMessage([(0, utils_1.getBaseDataAttributes)('catalogItem', 'card')]);
27
27
  } },
28
28
  react_1.default.createElement(CardContent, null,
29
29
  react_1.default.createElement(CardHeader, null,
@@ -61,7 +61,9 @@ function CatalogClassicActions(props) {
61
61
  return (React.createElement(CatalogActionsWrapper, { "data-component-name": "CatalogClassic/CatalogClassicActions" },
62
62
  React.createElement(Button_1.Button, { variant: "ghost", size: "small", icon: React.createElement(FilterIcon_1.FilterIcon, null), iconPosition: "left", onClick: () => {
63
63
  onOpenFilter();
64
- telemetry.sendCatalogActionsButtonClickedMessage();
64
+ telemetry.sendCatalogActionsClickedMessage([
65
+ (0, utils_1.getBaseDataAttributes)('catalogActions', 'button'),
66
+ ]);
65
67
  }, "data-translation-key": "catalog.filters.title" }, translate('catalog.filters.title', 'Filters')),
66
68
  activeFilters > 0 ? React.createElement(CounterTag_1.CounterTag, { borderless: true }, activeFilters) : null));
67
69
  }
@@ -64,7 +64,7 @@ function CatalogClassicCard({ item }) {
64
64
  const { useTelemetry } = (0, hooks_1.useThemeHooks)();
65
65
  const telemetry = useTelemetry();
66
66
  return (React.createElement(Link_1.Link, { key: item.docsLink || item.link, to: item.docsLink || item.link },
67
- React.createElement(StyledCard, { "data-component-name": "CatalogClassic/CatalogClassicCard", onClick: () => telemetry.sendCatalogItemClickedMessage() },
67
+ React.createElement(StyledCard, { "data-component-name": "CatalogClassic/CatalogClassicCard", onClick: () => telemetry.sendCatalogItemClickedMessage([(0, utils_1.getBaseDataAttributes)('catalogItem', 'card')]) },
68
68
  React.createElement(CardContent, null,
69
69
  React.createElement(CardTitleWrapper, null,
70
70
  React.createElement(CardTitle, null,
@@ -10,6 +10,7 @@ const hooks_1 = require("../../core/hooks");
10
10
  const utils_1 = require("../../core/utils");
11
11
  const Tag_1 = require("../../components/Tag/Tag");
12
12
  const Link_1 = require("../../components/Link/Link");
13
+ const utils_2 = require("../../core/utils");
13
14
  function CatalogClassicInfoBlock(props) {
14
15
  var _a, _b, _c, _d;
15
16
  const scorecardBadge = ((_a = props.metadata) === null || _a === void 0 ? void 0 : _a.scorecardLevel) ? (react_1.default.createElement(ScorecardBadge, { level: props.metadata.scorecardLevel, slug: (_b = props.metadata) === null || _b === void 0 ? void 0 : _b.scoreCardSlug, colorVariable: (0, utils_1.getScorecardColorVariable)(((_c = props.metadata) === null || _c === void 0 ? void 0 : _c.scorecardLevelIdx) || 0, Object.keys(((_d = props.metadata) === null || _d === void 0 ? void 0 : _d.scorecardLevels) || {}).length) })) : null;
@@ -21,7 +22,7 @@ function ScorecardBadge(props) {
21
22
  const { useTelemetry } = (0, hooks_1.useThemeHooks)();
22
23
  const telemetry = useTelemetry();
23
24
  return (react_1.default.createElement(Link_1.Link, { to: slug },
24
- react_1.default.createElement(Tag_1.Tag, { onClick: () => telemetry.sendScorecardLinkClickedMessage([{ object: 'link', action: 'click' }]), withStatusDot: true, statusDotColor: `var(${colorVariable})` }, level)));
25
+ react_1.default.createElement(Tag_1.Tag, { onClick: () => telemetry.sendScorecardLinkClickedMessage([(0, utils_2.getBaseDataAttributes)('scorecardLink', 'tag')]), withStatusDot: true, statusDotColor: `var(${colorVariable})` }, level)));
25
26
  }
26
27
  const CatalogInfoBlockWrapper = styled_components_1.default.div `
27
28
  position: relative;
@@ -12,6 +12,7 @@ export type DropdownProps = PropsWithChildren<{
12
12
  withArrow?: boolean;
13
13
  onClick?: (event: React.UIEvent) => void;
14
14
  onClose?: () => void;
15
+ onOpen?: () => void;
15
16
  }>;
16
17
  export declare const Dropdown: React.ForwardRefExoticComponent<{
17
18
  trigger: React.ReactNode;
@@ -25,6 +26,7 @@ export declare const Dropdown: React.ForwardRefExoticComponent<{
25
26
  withArrow?: boolean;
26
27
  onClick?: (event: React.UIEvent) => void;
27
28
  onClose?: () => void;
29
+ onOpen?: () => void;
28
30
  } & {
29
31
  children?: React.ReactNode | undefined;
30
32
  } & React.RefAttributes<HTMLDivElement>>;
@@ -42,11 +42,12 @@ const styled_components_1 = __importDefault(require("styled-components"));
42
42
  const hooks_1 = require("../../core/hooks");
43
43
  const ChevronDownIcon_1 = require("../../icons/ChevronDownIcon/ChevronDownIcon");
44
44
  const ChevronUpIcon_1 = require("../../icons/ChevronUpIcon/ChevronUpIcon");
45
- exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigger, triggerEvent = 'click', closeOnClick = true, withArrow, dataAttributes, placement, alignment, onClick, onClose, }, ref) => {
45
+ exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigger, triggerEvent = 'click', closeOnClick = true, withArrow, dataAttributes, placement, alignment, onClick, onClose, onOpen, }, ref) => {
46
46
  const dropdownRef = (0, react_1.useRef)(null);
47
47
  const [isOpen, setIsOpen] = (0, hooks_1.useControlledState)(false, active);
48
48
  const handleOpen = () => {
49
49
  setIsOpen(true);
50
+ onOpen === null || onOpen === void 0 ? void 0 : onOpen();
50
51
  };
51
52
  const handleClose = () => {
52
53
  setIsOpen(false);
@@ -58,7 +59,12 @@ exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigg
58
59
  const handleToggle = (event) => {
59
60
  event.stopPropagation();
60
61
  event.preventDefault();
61
- setIsOpen(!isOpen);
62
+ if (isOpen) {
63
+ handleClose();
64
+ }
65
+ else {
66
+ handleOpen();
67
+ }
62
68
  };
63
69
  const handleKeyDown = (event) => {
64
70
  if (event.key === 'Enter' || event.key === ' ') {
@@ -19,6 +19,7 @@ const react_router_dom_1 = require("react-router-dom");
19
19
  const hooks_1 = require("../../core/hooks");
20
20
  const Comment_1 = require("../../components/Feedback/Comment");
21
21
  const Portal_1 = require("../../components/Portal/Portal");
22
+ const utils_1 = require("../../core/utils");
22
23
  function ReportDialog({ location, settings, onSubmit, onCancel, submitFeedback, lang, }) {
23
24
  const { label } = settings;
24
25
  const { useTelemetry } = (0, hooks_1.useThemeHooks)();
@@ -34,7 +35,9 @@ function ReportDialog({ location, settings, onSubmit, onCancel, submitFeedback,
34
35
  path: pathname,
35
36
  lang,
36
37
  });
37
- telemetry.sendCodeSnippetReportedMessage();
38
+ telemetry.sendCodeSnippetReportedMessage([
39
+ (0, utils_1.getBaseDataAttributes)('codeSnippet', 'markdocTag'),
40
+ ]);
38
41
  onSubmit();
39
42
  }), isDialog: true, onCancel: onCancel }))));
40
43
  }
@@ -24,7 +24,9 @@ function FilterCheckboxes({ filter, filterValuesCasing, showCounter = true, }) {
24
24
  const id = 'filter--' + filter.property + '--' + value;
25
25
  return (react_1.default.createElement(FilterCheckboxOption, { key: id, role: "link", onClick: () => {
26
26
  filter.toggleOption(value);
27
- telemetry.sendFilterCheckboxToggledMessage([{ object: 'checkbox', id }]);
27
+ telemetry.sendFilterCheckboxToggledMessage([
28
+ (0, utils_1.getBaseDataAttributes)('filterId', 'checkbox'),
29
+ ]);
28
30
  } },
29
31
  react_1.default.createElement(CheckboxIcon_1.CheckboxIcon, { checked: filter.selectedOptions instanceof Set
30
32
  ? filter.selectedOptions.has(value) ||
@@ -20,7 +20,7 @@ function FooterItem({ item, iconsOnly, className }) {
20
20
  }
21
21
  const hasIcon = Boolean(item.icon || item.srcSet);
22
22
  const iconWithoutLabel = Boolean(item.label === item.link && hasIcon);
23
- return (react_1.default.createElement(FooterItemWrapper, { className: className, "data-component-name": "Footer/FooterItem", $iconsOnly: iconsOnly, $item: item }, item.type === 'separator' ? (react_1.default.createElement(FooterSeparator, { "data-translation-key": item.labelTranslationKey }, translate(item.labelTranslationKey, item.label))) : (react_1.default.createElement(FooterLink, { to: item.link, external: item.external, target: item.target, "data-testid": item.label, onClick: () => telemetry.sendFooterItemClickedMessage(), "data-translation-key": item.labelTranslationKey },
23
+ return (react_1.default.createElement(FooterItemWrapper, { className: className, "data-component-name": "Footer/FooterItem", $iconsOnly: iconsOnly, $item: item }, item.type === 'separator' ? (react_1.default.createElement(FooterSeparator, { "data-translation-key": item.labelTranslationKey }, translate(item.labelTranslationKey, item.label))) : (react_1.default.createElement(FooterLink, { to: item.link, external: item.external, target: item.target, "data-testid": item.label, onClick: () => telemetry.sendFooterItemClickedMessage([(0, utils_1.getBaseDataAttributes)('footerItem', 'footer')]), "data-translation-key": item.labelTranslationKey },
24
24
  hasIcon ? (react_1.default.createElement(FooterLinkIcon, { $iconsOnly: iconsOnly },
25
25
  react_1.default.createElement(GenericIcon_1.GenericIcon, { icon: item.icon, srcSet: item.srcSet }))) : null,
26
26
  !iconWithoutLabel ? translate(item.labelTranslationKey, item.label) : null,
@@ -27,7 +27,9 @@ function LanguagePicker(props) {
27
27
  languageInsensitive: true,
28
28
  onAction: () => {
29
29
  props.onChangeLanguage(locale.code);
30
- telemetry.sendLanguagePickerLocaleChangedMessage([{ object: 'locale', locale: locale.code }]);
30
+ telemetry.sendLanguagePickerChangedMessage([
31
+ ...(0, utils_1.generateBeforeAfterContext)('languagePicker', 'dropdown', { locale: currentLocale.code }, { locale: locale.code }),
32
+ ]);
31
33
  },
32
34
  active: locale.code === currentLocale.code,
33
35
  suffix: locale.code === currentLocale.code && react_1.default.createElement(CheckmarkIcon_1.CheckmarkIcon, null),
@@ -20,6 +20,7 @@ const styled_components_1 = __importDefault(require("styled-components"));
20
20
  const hooks_1 = require("../../core/hooks");
21
21
  const Link_1 = require("../../components/Link/Link");
22
22
  const Image_1 = require("../../components/Image/Image");
23
+ const utils_1 = require("../../core/utils");
23
24
  function Logo(_a) {
24
25
  var { config, className } = _a, otherProps = __rest(_a, ["config", "className"]);
25
26
  const { useTelemetry } = (0, hooks_1.useThemeHooks)();
@@ -28,7 +29,7 @@ function Logo(_a) {
28
29
  return null;
29
30
  }
30
31
  const image = (react_1.default.createElement(Image_1.Image, { className: className, src: config.image, srcSet: config.srcSet, alt: config.altText }));
31
- return (react_1.default.createElement(LogoWrapper, Object.assign({ "data-component-name": "Logo/Logo", className: className }, otherProps), config.link ? (react_1.default.createElement(Link_1.Link, { to: config.link, onClick: () => telemetry.sendLogoClickedMessage() }, image)) : (image)));
32
+ return (react_1.default.createElement(LogoWrapper, Object.assign({ "data-component-name": "Logo/Logo", className: className }, otherProps), config.link ? (react_1.default.createElement(Link_1.Link, { to: config.link, onClick: () => telemetry.sendLogoClickedMessage([(0, utils_1.getBaseDataAttributes)('logo', 'navbar')]) }, image)) : (image)));
32
33
  }
33
34
  const LogoWrapper = styled_components_1.default.div `
34
35
  max-width: var(--logo-max-width);
@@ -71,6 +71,7 @@ const MenuContainerComponent = styled_components_1.default.div.attrs({
71
71
  animation-timing-function: ease;
72
72
  position: relative;
73
73
  overflow-y: auto;
74
+ scrollbar-gutter: stable;
74
75
  flex-grow: ${({ $growContent }) => ($growContent ? 1 : 0)};
75
76
  padding-top: var(--menu-container-padding-top);
76
77
  display: ${({ $hidden }) => ($hidden ? 'none' : 'block')};
@@ -66,11 +66,7 @@ function MenuItem(props) {
66
66
  const hasHttpTag = !!item.httpVerb || type === constants_1.MenuItemType.Operation;
67
67
  const handleOnClick = () => {
68
68
  telemetry.sendSidebarItemClickedMessage([
69
- {
70
- object: 'sidebar_item',
71
- label: item.label,
72
- type: item.type === 'link' || item.type === 'group' ? item.type : undefined,
73
- },
69
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('sidebarItem', 'sidebar')), { label: item.label, type: item.type === 'link' || item.type === 'group' ? item.type : undefined }),
74
70
  ]);
75
71
  onClick === null || onClick === void 0 ? void 0 : onClick();
76
72
  if (isNested) {
@@ -95,7 +91,7 @@ function MenuItem(props) {
95
91
  react_1.default.createElement(MenuItemLabel, null,
96
92
  (_a = item.badges) === null || _a === void 0 ? void 0 :
97
93
  _a.filter(({ position }) => position === 'before').map(({ name, color, icon }) => (react_1.default.createElement(SidebarTag, { color: isDirectColorValue(color) ? undefined : color, $bgColor: isDirectColorValue(color) ? color : undefined, key: name, icon: icon && react_1.default.createElement(BadgeIcon, { icon: icon }) }, name))),
98
- react_1.default.createElement("span", null, translate(item.labelTranslationKey, item.label)),
94
+ react_1.default.createElement(MenuItemLabelText, { $active: item.active, $isSeparator: isSeparator, "data-text": translate(item.labelTranslationKey, item.label) }, translate(item.labelTranslationKey, item.label)),
99
95
  (_b = item.badges) === null || _b === void 0 ? void 0 :
100
96
  _b.filter(({ position }) => position !== 'before').map(({ name, color, icon }) => (react_1.default.createElement(SidebarTag, { color: isDirectColorValue(color) ? undefined : color, $bgColor: isDirectColorValue(color) ? color : undefined, key: name, icon: icon && react_1.default.createElement(BadgeIcon, { icon: icon }) }, name))),
101
97
  item.external ? react_1.default.createElement(LaunchIcon_1.LaunchIcon, { size: "var(--menu-item-external-icon-size)" }) : null),
@@ -214,7 +210,6 @@ const MenuItemLabelWrapper = styled_components_1.default.li `
214
210
  (0, styled_components_1.css) `
215
211
  color: ${$deprecated ? 'var(--menu-content-color-disabled)' : 'var(--menu-item-color-active)'};
216
212
  background-color: var(--menu-item-bg-color-active);
217
- font-weight: var(--menu-item-font-weight-active);
218
213
 
219
214
  ${ChevronDownIcon_1.ChevronDownIcon} path {
220
215
  fill: var(--menu-item-color-active);
@@ -281,6 +276,25 @@ const MenuItemLabel = styled_components_1.default.span `
281
276
  margin-right: var(--spacing-xxs);
282
277
  }
283
278
  `;
279
+ const MenuItemLabelText = styled_components_1.default.span `
280
+ display: inline-block;
281
+ max-width: 100%;
282
+ font-weight: var(--menu-item-font-weight);
283
+
284
+ &::before {
285
+ content: attr(data-text);
286
+ display: block;
287
+ height: 0;
288
+ overflow: hidden;
289
+ visibility: hidden;
290
+ font-weight: ${({ $isSeparator }) => $isSeparator ? 'var(--menu-item-font-weight)' : 'var(--menu-item-font-weight-active)'};
291
+ }
292
+
293
+ ${({ $active }) => $active &&
294
+ (0, styled_components_1.css) `
295
+ font-weight: var(--menu-item-font-weight-active);
296
+ `}
297
+ `;
284
298
  const SidebarTag = (0, styled_components_1.default)(Tag_1.Tag) `
285
299
  ${({ $bgColor }) => $bgColor && `background-color: ${$bgColor};`} /* for backward compatibility */
286
300
  margin-left: 0;
@@ -47,11 +47,15 @@ function Navbar({ className }) {
47
47
  react_1.default.createElement(MobileMenuButton, { variant: "text", "data-testid": "mobile-menu-button", onClick: isOpen
48
48
  ? () => {
49
49
  closeMobileMenu();
50
- telemetry.sendMobileMenuButtonCloseClickedMessage();
50
+ telemetry.sendMobileMenuClosedMessage([
51
+ (0, utils_1.getBaseDataAttributes)('mobileMenuClose', 'button'),
52
+ ]);
51
53
  }
52
54
  : () => {
53
55
  openMobileMenu();
54
- telemetry.sendMobileMenuButtonOpenClickedMessage();
56
+ telemetry.sendMobileMenuOpenedMessage([
57
+ (0, utils_1.getBaseDataAttributes)('mobileMenuOpen', 'button'),
58
+ ]);
55
59
  }, icon: isOpen ? react_1.default.createElement(CloseIcon_1.CloseIcon, null) : react_1.default.createElement(MenuIcon_1.MenuIcon, null), "aria-label": isOpen ? 'Close menu button' : 'Open menu button' }),
56
60
  hideUserMenu ? null : react_1.default.createElement(UserMenu_1.UserMenu, null))));
57
61
  }
@@ -27,7 +27,9 @@ function NavbarItem({ navItem, className }) {
27
27
  const normalizedPath = (item.link ? (0, utils_1.removeTrailingSlash)(item.link) : item.link) || '';
28
28
  const pathWithPathPrefix = (0, utils_1.withPathPrefix)((0, utils_1.getPathnameForLocale)(normalizedPath, defaultLocale, currentLocale, locales));
29
29
  const isActive = (0, utils_1.removeTrailingSlash)(pathname) === (0, utils_1.removeTrailingSlash)(pathWithPathPrefix);
30
- const itemContent = (react_1.default.createElement(NavbarMenuItem, { as: item.link ? Link_1.Link : undefined, $active: isActive, className: className, onClick: () => telemetry.sendNavbarMenuItemClickedMessage([{ object: 'menu_item', type: item.type }]), external: item.external, target: item.target, to: item.link },
30
+ const itemContent = (react_1.default.createElement(NavbarMenuItem, { as: item.link ? Link_1.Link : undefined, $active: isActive, className: className, onClick: () => telemetry.sendNavbarMenuItemClickedMessage([
31
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('navbarItem', 'navbar')), { type: item.type }),
32
+ ]), external: item.external, target: item.target, to: item.link },
31
33
  react_1.default.createElement(NavbarIcon, { icon: item.icon, srcSet: item.srcSet }),
32
34
  react_1.default.createElement(NavbarLabel, { "data-translation-key": item.labelTranslationKey }, translate(item.labelTranslationKey, item.label)),
33
35
  item.external ? react_1.default.createElement(ExternalLinkIcon, { size: "10px" }) : null));
@@ -41,6 +41,7 @@ const react_1 = __importStar(require("react"));
41
41
  const styled_components_1 = __importDefault(require("styled-components"));
42
42
  const types_1 = require("../../core/types");
43
43
  const constants_1 = require("../../core/constants");
44
+ const types_2 = require("../../core/types");
44
45
  const Link_1 = require("../../components/Link/Link");
45
46
  const Tag_1 = require("../../components/Tag/Tag");
46
47
  const constants_2 = require("../../core/constants");
@@ -56,11 +57,28 @@ function MarkdownSegment({ text }) {
56
57
  const markdown = useMarkdownText(text);
57
58
  return react_1.default.createElement(ResponseText, { as: "div", children: markdown, "data-testid": "response-text" });
58
59
  }
59
- function getToolCallDisplayText(toolName) {
60
+ // The codemode `execute` tool passes a human-readable `description` of what its code
61
+ // does; show that instead of a generic "Executing execute..." label.
62
+ function getExecuteDescription(args) {
63
+ if (args && typeof args === 'object' && 'description' in args) {
64
+ const { description } = args;
65
+ if (typeof description === 'string' && description.trim().length > 0) {
66
+ return description.trim();
67
+ }
68
+ }
69
+ return undefined;
70
+ }
71
+ function getToolCallDisplayText(toolCall) {
60
72
  var _a;
61
- return ((_a = constants_1.TOOL_CALL_DISPLAY_TEXT[toolName]) !== null && _a !== void 0 ? _a : {
62
- inProgressText: `Executing ${toolName}...`,
63
- completedText: `${toolName} executed`,
73
+ if (toolCall.name === types_2.ToolCallName.Execute) {
74
+ const description = getExecuteDescription(toolCall.args);
75
+ if (description) {
76
+ return { inProgressText: description, completedText: description };
77
+ }
78
+ }
79
+ return ((_a = constants_1.TOOL_CALL_DISPLAY_TEXT[toolCall.name]) !== null && _a !== void 0 ? _a : {
80
+ inProgressText: `Executing ${toolCall.name}...`,
81
+ completedText: `${toolCall.name} executed`,
64
82
  });
65
83
  }
66
84
  function SearchAiMessageComponent({ role, content, isThinking, resources, className, messageId, feedback, onFeedbackChange, toolCalls = [], contentSegments = [{ type: 'text', text: content }], }) {
@@ -111,7 +129,7 @@ function SearchAiMessageComponent({ role, content, isThinking, resources, classN
111
129
  contentSegments.map((segment, index) => {
112
130
  if (segment.type === 'tool') {
113
131
  const toolCallCompleted = Boolean(segment.toolCall.result);
114
- const { inProgressText, completedText } = getToolCallDisplayText(segment.toolCall.name);
132
+ const { inProgressText, completedText } = getToolCallDisplayText(segment.toolCall);
115
133
  const toolCallDisplayText = toolCallCompleted ? completedText : inProgressText;
116
134
  return (react_1.default.createElement(ToolCallsInfoWrapper, { key: `tool-${index}`, "data-testid": "tool-calls-info" },
117
135
  react_1.default.createElement(ToolCallInfoItem, null,
@@ -141,15 +141,7 @@ function SearchDialog({ onClose, className, initialMode = 'search', }) {
141
141
  return (react_1.default.createElement(SearchItem_1.SearchItem, { key: `${index}-${item.document.id}`, item: item, product: itemProduct, innerRef: innerRef, onClick: () => {
142
142
  addSearchHistoryItem(query);
143
143
  telemetry.sendSearchResultClickedMessage([
144
- {
145
- object: 'search',
146
- query: query,
147
- url: item.document.url,
148
- totalResults: results.length.toString(),
149
- index: index.toString(),
150
- searchEngine: mode,
151
- searchSessionId,
152
- },
144
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('searchResultItem', 'search', item.document.url)), { query: query, totalResults: results.length.toString(), index: index.toString(), searchEngine: mode, searchSessionId }),
153
145
  ]);
154
146
  onClose();
155
147
  } }));
@@ -200,12 +192,7 @@ function SearchDialog({ onClose, className, initialMode = 'search', }) {
200
192
  aiSearch.askQuestion(query);
201
193
  }
202
194
  telemetry.sendSearchAiOpenedMessage([
203
- {
204
- id: 'searchAiButton',
205
- object: 'search',
206
- uri: 'urn:redocly:realm:ui:search:searchAiButton',
207
- method: 'ai_search_button',
208
- },
195
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('searchAiButton', 'search')), { method: 'ai_search_button' }),
209
196
  ]);
210
197
  } }, translate('search.ai.button', 'Search with AI'))) : null,
211
198
  showSearchFilterButton && (react_1.default.createElement(SearchFilterToggleButton, { icon: react_1.default.createElement(SettingsIcon_1.SettingsIcon, null), onClick: onFilterToggle })))))) : (react_1.default.createElement(AiDialogHeaderWrapper, null,
@@ -235,12 +222,7 @@ function SearchDialog({ onClose, className, initialMode = 'search', }) {
235
222
  aiSearch.askQuestion(query);
236
223
  }
237
224
  telemetry.sendSearchAiOpenedMessage([
238
- {
239
- id: 'searchAiInput',
240
- object: 'search',
241
- uri: 'urn:redocly:realm:ui:search:searchAiInput',
242
- method: 'ai_search_input',
243
- },
225
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('searchAiInput', 'search')), { method: 'ai_search_input' }),
244
226
  ]);
245
227
  }, onKeyDown: (e) => {
246
228
  if (e.key === 'Enter') {
@@ -249,12 +231,7 @@ function SearchDialog({ onClose, className, initialMode = 'search', }) {
249
231
  aiSearch.askQuestion(query);
250
232
  }
251
233
  telemetry.sendSearchAiOpenedMessage([
252
- {
253
- id: 'searchAiInput',
254
- object: 'search',
255
- uri: 'urn:redocly:realm:ui:search:searchAiInput',
256
- method: 'ai_search_input',
257
- },
234
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('searchAiInput', 'search')), { method: 'ai_search_input' }),
258
235
  ]);
259
236
  }
260
237
  }, ref: aiQueryRef, tabIndex: 0, role: "option", "aria-selected": "true" },
@@ -293,12 +270,7 @@ function SearchDialog({ onClose, className, initialMode = 'search', }) {
293
270
  react_1.default.createElement("b", null, translate('search.noResults.title', 'No results'))))) : (react_1.default.createElement(react_1.default.Fragment, null,
294
271
  react_1.default.createElement(SearchRecent_1.SearchRecent, { onSelect: (query, index) => {
295
272
  telemetry.sendSearchRecentClickedMessage([
296
- {
297
- object: 'search',
298
- query,
299
- index: index.toString(),
300
- searchSessionId,
301
- },
273
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('searchRecentItem', 'search')), { query, index: index.toString(), searchSessionId }),
302
274
  ]);
303
275
  setQuery(query);
304
276
  focusSearchInput();
@@ -12,6 +12,7 @@ const Button_1 = require("../../components/Button/Button");
12
12
  const hooks_1 = require("../../core/hooks");
13
13
  const CloseFilledIcon_1 = require("../../icons/CloseFilledIcon/CloseFilledIcon");
14
14
  const ChevronLeftIcon_1 = require("../../icons/ChevronLeftIcon/ChevronLeftIcon");
15
+ const utils_1 = require("../../core/utils");
15
16
  function SearchInput({ placeholder, value, onChange, isLoading, showReturnButton, inputRef, onReturn, onSubmit, className, }) {
16
17
  const { useTelemetry } = (0, hooks_1.useThemeHooks)();
17
18
  const { addSearchHistoryItem } = (0, hooks_1.useRecentSearches)();
@@ -27,7 +28,9 @@ function SearchInput({ placeholder, value, onChange, isLoading, showReturnButton
27
28
  const handleOnReset = () => {
28
29
  onChange('');
29
30
  addSearchHistoryItem(value);
30
- telemetry.sendSearchInputResetButtonClickedMessage();
31
+ telemetry.sendSearchInputResetClickedMessage([
32
+ (0, utils_1.getBaseDataAttributes)('searchInputReset', 'search'),
33
+ ]);
31
34
  };
32
35
  return (react_1.default.createElement(SearchInputWrapper, { "data-component-name": "Search/SearchInput", className: className },
33
36
  showReturnButton ? (react_1.default.createElement(Button_1.Button, { icon: react_1.default.createElement(ChevronLeftIcon_1.ChevronLeftIcon, null), onClick: onReturn })) : value && isLoading ? (react_1.default.createElement(Spinner_1.Spinner, { size: "24px", color: "--search-input-icon-color" })) : (react_1.default.createElement(SearchIcon_1.SearchIcon, { size: "24px", color: "--search-input-icon-color" })),
@@ -54,7 +54,9 @@ function SearchRecent({ onSelect, className }) {
54
54
  const handleOnRemove = (e, item) => {
55
55
  e.stopPropagation();
56
56
  removeSearchHistoryItem(item);
57
- telemetry.sendSearchRecentRemoveButtonClickedMessage();
57
+ telemetry.sendSearchRecentRemoveClickedMessage([
58
+ (0, utils_1.getBaseDataAttributes)('searchRecentRemove', 'search'),
59
+ ]);
58
60
  };
59
61
  const handleKeyDown = (e, item, index) => {
60
62
  if (e.key === 'Enter') {
@@ -14,6 +14,7 @@ const SidePanelCloseIcon_1 = require("../../icons/SidePanelCloseIcon/SidePanelCl
14
14
  const SidePanelOpenIcon_1 = require("../../icons/SidePanelOpenIcon/SidePanelOpenIcon");
15
15
  const styled_1 = require("../../components/SidebarActions/styled");
16
16
  const Tooltip_1 = require("../../components/Tooltip/Tooltip");
17
+ const utils_1 = require("../../core/utils");
17
18
  const SidebarActions = ({ layout, hideCollapseSidebarButton = false, collapsedSidebar, isApiDocs, onChangeViewClick, onChangeCollapseSidebarClick, requestAccessButton, className, }) => {
18
19
  const { useTelemetry, useTranslate } = (0, hooks_1.useThemeHooks)();
19
20
  const { translate } = useTranslate();
@@ -24,16 +25,22 @@ const SidebarActions = ({ layout, hideCollapseSidebarButton = false, collapsedSi
24
25
  : translate('sidebar.actions.hide', 'Hide sidebar') }, react_1.default.createElement(Button_1.Button, { onClick: () => {
25
26
  onChangeCollapseSidebarClick();
26
27
  if (collapsedSidebar) {
27
- telemetry.sendSidebarItemExpandedMessage();
28
+ telemetry.sendSidebarExpandedMessage([
29
+ (0, utils_1.getBaseDataAttributes)('sidebarExpand', 'button'),
30
+ ]);
28
31
  }
29
32
  else {
30
- telemetry.sendSidebarItemCollapsedMessage();
33
+ telemetry.sendSidebarCollapsedMessage([
34
+ (0, utils_1.getBaseDataAttributes)('sidebarCollapse', 'button'),
35
+ ]);
31
36
  }
32
37
  }, size: "small", variant: "outlined", "aria-label": collapsedSidebar ? 'Show sidebar' : 'Hide sidebar', icon: collapsedSidebar ? react_1.default.createElement(SidePanelOpenIcon_1.SidePanelOpenIcon, null) : react_1.default.createElement(SidePanelCloseIcon_1.SidePanelCloseIcon, null) }))),
33
38
  isApiDocs && (react_1.default.createElement(styled_1.ControlsWrapChangeLayoutButtons, { isCollapsed: collapsedSidebar },
34
39
  react_1.default.createElement(ChangeViewButton_1.ChangeViewButton, { collapsedSidebar: collapsedSidebar, layout: layout, onClick: () => {
35
40
  onChangeViewClick();
36
- telemetry.sendChangeLayoutButtonClickedMessage();
41
+ telemetry.sendChangeLayoutClickedMessage([
42
+ (0, utils_1.getBaseDataAttributes)('changeLayout', 'button'),
43
+ ]);
37
44
  } }))),
38
45
  !collapsedSidebar && requestAccessButton));
39
46
  };