@redocly/theme 0.61.1 → 0.62.0-custom.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 (188) hide show
  1. package/lib/components/AsyncApiDocs/hooks/AfterAsyncApiChannelDescription.d.ts +1 -0
  2. package/lib/components/AsyncApiDocs/hooks/AfterAsyncApiChannelDescription.js +12 -0
  3. package/lib/components/Badge/Badge.d.ts +2 -1
  4. package/lib/components/Badge/Badge.js +24 -2
  5. package/lib/components/Banner/Banner.js +19 -1
  6. package/lib/components/Banner/variables.js +1 -0
  7. package/lib/components/Breadcrumbs/Breadcrumb.js +1 -1
  8. package/lib/components/Breadcrumbs/BreadcrumbDropdown.js +9 -6
  9. package/lib/components/Breadcrumbs/Breadcrumbs.js +24 -15
  10. package/lib/components/Buttons/AIAssistantButton.js +7 -4
  11. package/lib/components/Catalog/CatalogEntities.js +10 -8
  12. package/lib/components/Catalog/CatalogEntity/CatalogEntity.js +2 -2
  13. package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.js +1 -1
  14. package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/TagsProperty.js +2 -2
  15. package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.js +13 -11
  16. package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +7 -5
  17. package/lib/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.js +9 -7
  18. package/lib/components/Catalog/CatalogTableView/CatalogTableViewRow.js +1 -1
  19. package/lib/components/Catalog/CatalogTagsWithTooltip.js +2 -2
  20. package/lib/components/CatalogClassic/CatalogClassicInfoBlock.js +1 -1
  21. package/lib/components/CodeBlock/CodeBlockControls.js +8 -6
  22. package/lib/components/Filter/FilterCheckboxes.js +1 -1
  23. package/lib/components/JsonViewer/JsonViewer.js +2 -2
  24. package/lib/components/JsonViewer/{Helpers.js → helpers.js} +2 -1
  25. package/lib/components/LanguagePicker/LanguagePicker.js +1 -1
  26. package/lib/components/Markdown/Markdown.js +2 -2
  27. package/lib/components/Menu/MenuItem.js +41 -15
  28. package/lib/components/Navbar/NavbarItem.js +1 -1
  29. package/lib/components/OpenApiDocs/hooks/AdditionalOverviewInfo.d.ts +1 -0
  30. package/lib/components/OpenApiDocs/hooks/AdditionalOverviewInfo.js +12 -0
  31. package/lib/components/OpenApiDocs/hooks/AfterOpenApiDescription.d.ts +1 -0
  32. package/lib/components/OpenApiDocs/hooks/AfterOpenApiDescription.js +6 -0
  33. package/lib/components/PageActions/PageActions.js +25 -8
  34. package/lib/components/Search/SearchAiDialog.d.ts +4 -2
  35. package/lib/components/Search/SearchAiDialog.js +23 -4
  36. package/lib/components/Search/SearchAiMessage.d.ts +4 -2
  37. package/lib/components/Search/SearchAiMessage.js +82 -23
  38. package/lib/components/Search/SearchDialog.js +50 -25
  39. package/lib/components/Select/variables.js +2 -2
  40. package/lib/components/SvgViewer/SvgViewer.d.ts +15 -0
  41. package/lib/components/SvgViewer/SvgViewer.js +312 -0
  42. package/lib/components/SvgViewer/variables.d.ts +1 -0
  43. package/lib/components/SvgViewer/variables.dark.d.ts +1 -0
  44. package/lib/components/SvgViewer/variables.dark.js +8 -0
  45. package/lib/components/SvgViewer/variables.js +17 -0
  46. package/lib/components/Tag/Tag.js +1 -1
  47. package/lib/components/Tag/variables.dark.js +6 -0
  48. package/lib/components/Tag/variables.js +6 -0
  49. package/lib/components/Tooltip/Tooltip.d.ts +2 -3
  50. package/lib/components/Tooltip/Tooltip.js +66 -113
  51. package/lib/components/Tooltip/variables.dark.js +4 -0
  52. package/lib/components/Tooltip/variables.js +3 -3
  53. package/lib/components/UserMenu/LoginButton.d.ts +8 -2
  54. package/lib/components/UserMenu/LoginButton.js +4 -3
  55. package/lib/core/constants/search.d.ts +5 -1
  56. package/lib/core/constants/search.js +24 -1
  57. package/lib/core/hooks/search/use-search-dialog.js +2 -2
  58. package/lib/core/hooks/use-color-switcher.js +3 -1
  59. package/lib/core/hooks/use-mcp-config.js +2 -1
  60. package/lib/core/hooks/use-modal-scroll-lock.js +24 -10
  61. package/lib/core/hooks/use-outside-click.d.ts +3 -1
  62. package/lib/core/hooks/use-outside-click.js +8 -4
  63. package/lib/core/hooks/use-page-actions.d.ts +1 -1
  64. package/lib/core/hooks/use-page-actions.js +44 -11
  65. package/lib/core/hooks/use-product-picker.js +1 -1
  66. package/lib/core/hooks/use-unique-svg-ids.d.ts +6 -0
  67. package/lib/core/hooks/use-unique-svg-ids.js +15 -0
  68. package/lib/core/openapi/index.d.ts +1 -0
  69. package/lib/core/openapi/index.js +3 -1
  70. package/lib/core/styles/dark.js +2 -0
  71. package/lib/core/styles/global.js +31 -15
  72. package/lib/core/types/catalog.d.ts +1 -1
  73. package/lib/core/types/hooks.d.ts +23 -2
  74. package/lib/core/types/l10n.d.ts +1 -1
  75. package/lib/core/types/search.d.ts +24 -0
  76. package/lib/core/types/search.js +9 -1
  77. package/lib/core/utils/content-segments.d.ts +2 -0
  78. package/lib/core/utils/content-segments.js +22 -0
  79. package/lib/core/utils/index.d.ts +1 -0
  80. package/lib/core/utils/index.js +1 -0
  81. package/lib/core/utils/transform-revisions-to-version-history.js +8 -51
  82. package/lib/ext/process-scorecard.d.ts +5 -0
  83. package/lib/ext/process-scorecard.js +11 -0
  84. package/lib/icons/FitToViewIcon/FitToViewIcon.d.ts +9 -0
  85. package/lib/icons/FitToViewIcon/FitToViewIcon.js +25 -0
  86. package/lib/index.d.ts +8 -0
  87. package/lib/index.js +8 -0
  88. package/lib/layouts/DocumentationLayout.js +4 -25
  89. package/lib/layouts/DocumentationLayoutBottom.d.ts +11 -0
  90. package/lib/layouts/DocumentationLayoutBottom.js +28 -0
  91. package/lib/layouts/DocumentationLayoutTop.d.ts +13 -0
  92. package/lib/layouts/DocumentationLayoutTop.js +33 -0
  93. package/lib/layouts/Forbidden.js +22 -18
  94. package/lib/markdoc/components/Cards/Card.js +1 -0
  95. package/lib/markdoc/components/CodeWalkthrough/CodeFilters.js +1 -1
  96. package/lib/markdoc/components/Heading/Heading.js +40 -2
  97. package/lib/markdoc/components/LoginButton/LoginButton.d.ts +9 -0
  98. package/lib/markdoc/components/LoginButton/LoginButton.js +48 -0
  99. package/lib/markdoc/components/Mermaid/Mermaid.js +70 -2
  100. package/lib/markdoc/components/default.d.ts +1 -0
  101. package/lib/markdoc/components/default.js +1 -0
  102. package/lib/markdoc/default.d.ts +6 -0
  103. package/lib/markdoc/default.js +2 -0
  104. package/lib/markdoc/tags/login-button.d.ts +2 -0
  105. package/lib/markdoc/tags/login-button.js +32 -0
  106. package/package.json +8 -8
  107. package/src/components/AsyncApiDocs/hooks/AfterAsyncApiChannelDescription.tsx +10 -0
  108. package/src/components/Badge/Badge.tsx +18 -2
  109. package/src/components/Banner/Banner.tsx +23 -1
  110. package/src/components/Banner/variables.ts +1 -0
  111. package/src/components/Breadcrumbs/Breadcrumb.tsx +3 -3
  112. package/src/components/Breadcrumbs/BreadcrumbDropdown.tsx +11 -8
  113. package/src/components/Breadcrumbs/Breadcrumbs.tsx +24 -15
  114. package/src/components/Buttons/AIAssistantButton.tsx +7 -4
  115. package/src/components/Catalog/CatalogEntities.tsx +10 -8
  116. package/src/components/Catalog/CatalogEntity/CatalogEntity.tsx +1 -1
  117. package/src/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.tsx +1 -2
  118. package/src/components/Catalog/CatalogEntity/CatalogEntityProperties/TagsProperty.tsx +1 -1
  119. package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.tsx +13 -11
  120. package/src/components/Catalog/CatalogEntity/CatalogEntitySchema.tsx +7 -5
  121. package/src/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.tsx +9 -7
  122. package/src/components/Catalog/CatalogTableView/CatalogTableViewRow.tsx +1 -2
  123. package/src/components/Catalog/CatalogTagsWithTooltip.tsx +9 -5
  124. package/src/components/CatalogClassic/CatalogClassicInfoBlock.tsx +3 -1
  125. package/src/components/CodeBlock/CodeBlockControls.tsx +16 -10
  126. package/src/components/Filter/FilterCheckboxes.tsx +1 -1
  127. package/src/components/JsonViewer/JsonViewer.tsx +1 -2
  128. package/src/components/JsonViewer/{Helpers.tsx → helpers.tsx} +1 -0
  129. package/src/components/LanguagePicker/LanguagePicker.tsx +1 -1
  130. package/src/components/Markdown/Markdown.tsx +2 -2
  131. package/src/components/Menu/MenuItem.tsx +61 -16
  132. package/src/components/Navbar/NavbarItem.tsx +3 -1
  133. package/src/components/OpenApiDocs/hooks/AdditionalOverviewInfo.tsx +10 -0
  134. package/src/components/OpenApiDocs/hooks/AfterOpenApiDescription.tsx +2 -0
  135. package/src/components/PageActions/PageActions.tsx +38 -15
  136. package/src/components/Search/SearchAiDialog.tsx +31 -2
  137. package/src/components/Search/SearchAiMessage.tsx +103 -17
  138. package/src/components/Search/SearchDialog.tsx +70 -37
  139. package/src/components/Select/variables.ts +2 -2
  140. package/src/components/SvgViewer/SvgViewer.tsx +405 -0
  141. package/src/components/SvgViewer/variables.dark.ts +5 -0
  142. package/src/components/SvgViewer/variables.ts +14 -0
  143. package/src/components/Tag/Tag.tsx +2 -1
  144. package/src/components/Tag/variables.dark.ts +6 -0
  145. package/src/components/Tag/variables.ts +6 -0
  146. package/src/components/Tooltip/Tooltip.tsx +77 -120
  147. package/src/components/Tooltip/variables.dark.ts +4 -0
  148. package/src/components/Tooltip/variables.ts +3 -3
  149. package/src/components/UserMenu/LoginButton.tsx +23 -8
  150. package/src/core/constants/search.ts +27 -1
  151. package/src/core/hooks/__mocks__/use-theme-hooks.ts +10 -1
  152. package/src/core/hooks/search/use-search-dialog.ts +2 -2
  153. package/src/core/hooks/use-color-switcher.ts +3 -1
  154. package/src/core/hooks/use-mcp-config.ts +2 -1
  155. package/src/core/hooks/use-modal-scroll-lock.ts +29 -10
  156. package/src/core/hooks/use-outside-click.ts +16 -5
  157. package/src/core/hooks/use-page-actions.ts +66 -25
  158. package/src/core/hooks/use-product-picker.ts +1 -1
  159. package/src/core/hooks/use-unique-svg-ids.ts +12 -0
  160. package/src/core/openapi/index.ts +1 -0
  161. package/src/core/styles/dark.ts +2 -0
  162. package/src/core/styles/global.ts +31 -15
  163. package/src/core/types/catalog.ts +1 -1
  164. package/src/core/types/hooks.ts +29 -1
  165. package/src/core/types/l10n.ts +12 -1
  166. package/src/core/types/search.ts +19 -0
  167. package/src/core/utils/content-segments.ts +27 -0
  168. package/src/core/utils/index.ts +1 -0
  169. package/src/core/utils/transform-revisions-to-version-history.ts +8 -80
  170. package/src/ext/process-scorecard.ts +14 -0
  171. package/src/icons/FitToViewIcon/FitToViewIcon.tsx +26 -0
  172. package/src/index.ts +8 -0
  173. package/src/layouts/DocumentationLayout.tsx +4 -30
  174. package/src/layouts/DocumentationLayoutBottom.tsx +42 -0
  175. package/src/layouts/DocumentationLayoutTop.tsx +52 -0
  176. package/src/layouts/Forbidden.tsx +36 -21
  177. package/src/markdoc/components/Cards/Card.tsx +1 -0
  178. package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +1 -1
  179. package/src/markdoc/components/Heading/Heading.tsx +52 -4
  180. package/src/markdoc/components/LoginButton/LoginButton.tsx +38 -0
  181. package/src/markdoc/components/Mermaid/Mermaid.tsx +57 -8
  182. package/src/markdoc/components/default.ts +1 -0
  183. package/src/markdoc/default.ts +2 -0
  184. package/src/markdoc/tags/login-button.ts +30 -0
  185. package/lib/components/Tooltip/TooltipWrapper.d.ts +0 -12
  186. package/lib/components/Tooltip/TooltipWrapper.js +0 -34
  187. package/src/components/Tooltip/TooltipWrapper.tsx +0 -70
  188. /package/lib/components/JsonViewer/{Helpers.d.ts → helpers.d.ts} +0 -0
@@ -45,10 +45,10 @@ const HttpTag_1 = require("../../components/Tags/HttpTag");
45
45
  const constants_1 = require("../../core/constants");
46
46
  const utils_1 = require("../../core/utils");
47
47
  const ArrowRightIcon_1 = require("../../icons/ArrowRightIcon/ArrowRightIcon");
48
- const Badge_1 = require("../../components/Badge/Badge");
49
48
  const GenericIcon_1 = require("../../icons/GenericIcon/GenericIcon");
49
+ const Tag_1 = require("../../components/Tag/Tag");
50
50
  function MenuItem(props) {
51
- var _a;
51
+ var _a, _b;
52
52
  const { item, depth, className, onClick } = props;
53
53
  const { useTranslate, useTelemetry } = (0, hooks_1.useThemeHooks)();
54
54
  const { translate } = useTranslate();
@@ -65,10 +65,13 @@ function MenuItem(props) {
65
65
  const hasChevron = isNested && !isDrilldown;
66
66
  const hasHttpTag = !!item.httpVerb || type === constants_1.MenuItemType.Operation;
67
67
  const handleOnClick = () => {
68
- telemetry.sendSidebarItemClickedMessage({
69
- label: item.label,
70
- type: item.type === 'link' || item.type === 'group' ? item.type : undefined,
71
- });
68
+ telemetry.sendSidebarItemClickedMessage([
69
+ {
70
+ object: 'sidebar_item',
71
+ label: item.label,
72
+ type: item.type === 'link' || item.type === 'group' ? item.type : undefined,
73
+ },
74
+ ]);
72
75
  onClick === null || onClick === void 0 ? void 0 : onClick();
73
76
  if (isNested) {
74
77
  handleExpand();
@@ -89,9 +92,10 @@ function MenuItem(props) {
89
92
  hasChevron ? react_1.default.createElement(ChevronWrapper, null, chevron) : null,
90
93
  react_1.default.createElement(MenuItemIcon, { icon: item.icon, srcSet: item.srcSet }),
91
94
  react_1.default.createElement(MenuItemLabelTextWrapper, null,
92
- react_1.default.createElement(MenuItemLabel, null,
93
- react_1.default.createElement("span", null, translate(item.labelTranslationKey, item.label)), (_a = item.badges) === null || _a === void 0 ? void 0 :
94
- _a.map(({ name, color }) => (react_1.default.createElement(MenuItemBadge, { color: color, key: name }, name))),
95
+ react_1.default.createElement(MenuItemLabel, null, (_a = item.badges) === null || _a === void 0 ? void 0 :
96
+ _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))),
97
+ react_1.default.createElement("span", null, translate(item.labelTranslationKey, item.label)), (_b = item.badges) === null || _b === void 0 ? void 0 :
98
+ _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))),
95
99
  item.external ? react_1.default.createElement(LaunchIcon_1.LaunchIcon, { size: "var(--menu-item-external-icon-size)" }) : null),
96
100
  item.sublabel ? (react_1.default.createElement(MenuItemSubLabel, null, translate(item.subLabelTranslationKey, item.sublabel))) : null),
97
101
  isDrilldown ? react_1.default.createElement(ArrowRightIcon_1.ArrowRightIcon, { size: "12px" }) : null,
@@ -101,6 +105,12 @@ function MenuItem(props) {
101
105
  isNested ? (react_1.default.createElement(MenuItemNestedWrapper, { depth: depth, ref: nestedMenuRef, style: style }, isExpanded || !canUnmount ? props.children : null)) : null,
102
106
  item.separatorLine ? (react_1.default.createElement(MenuItemSeparatorLine, { depth: depth, linePosition: item.linePosition })) : null));
103
107
  }
108
+ /* for backward compatibility */
109
+ function isDirectColorValue(color) {
110
+ if (!color)
111
+ return false;
112
+ return color.startsWith('#') || color.startsWith('rgb') || color.startsWith('hsl');
113
+ }
104
114
  function generateClassName({ type, item, className, }) {
105
115
  const classNames = [className, `menu-item-type-${type}`];
106
116
  if (type === constants_1.MenuItemType.Separator) {
@@ -279,15 +289,31 @@ const MenuItemLabel = styled_components_1.default.span `
279
289
  margin-right: var(--spacing-xxs);
280
290
  }
281
291
  `;
282
- const MenuItemBadge = (0, styled_components_1.default)(Badge_1.Badge) `
292
+ const SidebarTag = (0, styled_components_1.default)(Tag_1.Tag) `
293
+ ${({ $bgColor }) => $bgColor && `background-color: ${$bgColor};`} /* for backward compatibility */
283
294
  margin-left: 0;
284
- background-color: ${({ color }) => color || 'var(--color-info-base)'};
285
295
  font-size: var(--font-size-sm);
286
296
  line-height: var(--line-height-sm);
287
297
  padding: 0 var(--spacing-xxs);
288
- max-width: 80px;
289
- text-overflow: ellipsis;
290
- white-space: nowrap;
291
- overflow: hidden;
298
+ max-width: 90px;
299
+
300
+ --tag-padding: 0 var(--spacing-xxs);
301
+ --tag-content-padding: 0;
302
+ --tag-font-size: var(--font-size-sm);
303
+ --tag-line-height: var(--line-height-sm);
304
+ vertical-align: middle;
305
+
306
+ ${Tag_1.ContentWrapper} {
307
+ text-overflow: ellipsis;
308
+ white-space: nowrap;
309
+ overflow: hidden;
310
+ display: block;
311
+ }
312
+ `;
313
+ const BadgeIcon = (0, styled_components_1.default)(GenericIcon_1.GenericIcon) `
314
+ --icon-width: var(--font-size-sm);
315
+ --icon-height: var(--font-size-sm);
316
+ margin-right: var(--spacing-xxs);
317
+ flex-shrink: 0;
292
318
  `;
293
319
  //# sourceMappingURL=MenuItem.js.map
@@ -27,7 +27,7 @@ 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({ 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([{ object: 'menu_item', type: item.type }]), external: item.external, target: item.target, to: item.link },
31
31
  react_1.default.createElement(NavbarIcon, { icon: item.icon, srcSet: item.srcSet }),
32
32
  react_1.default.createElement(NavbarLabel, { "data-translation-key": item.labelTranslationKey }, translate(item.labelTranslationKey, item.label)),
33
33
  item.external ? react_1.default.createElement(ExternalLinkIcon, { size: "10px" }) : null));
@@ -0,0 +1 @@
1
+ export declare const AdditionalOverviewInfo: any;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ // interface AdditionalOverviewInfoProps {
3
+ // info: any;
4
+ // }
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AdditionalOverviewInfo = void 0;
7
+ // export function AdditionalOverviewInfo(_props: AdditionalOverviewInfoProps) {
8
+ // return null;
9
+ // }
10
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
11
+ exports.AdditionalOverviewInfo = null;
12
+ //# sourceMappingURL=AdditionalOverviewInfo.js.map
@@ -0,0 +1 @@
1
+ export declare const AfterOpenApiDescription: any;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AfterOpenApiDescription = void 0;
4
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
5
+ exports.AfterOpenApiDescription = null;
6
+ //# sourceMappingURL=AfterOpenApiDescription.js.map
@@ -49,6 +49,7 @@ exports.PageActions = PageActions;
49
49
  const react_1 = __importStar(require("react"));
50
50
  const styled_components_1 = __importDefault(require("styled-components"));
51
51
  const PageActionsMenuItem_1 = require("../../components/PageActions/PageActionsMenuItem");
52
+ const DropdownMenuItem_1 = require("../../components/Dropdown/DropdownMenuItem");
52
53
  const Link_1 = require("../../components/Link/Link");
53
54
  const ButtonGroup_1 = require("../../components/Button/ButtonGroup");
54
55
  const Button_1 = require("../../components/Button/Button");
@@ -77,16 +78,18 @@ function PageActions(props) {
77
78
  setActionState('idle');
78
79
  }, ACTION_DONE_DISPLAY_DURATION);
79
80
  });
80
- const menuItems = actions.map((action) => ({
81
- content: 'link' in action ? (react_1.default.createElement(LinkMenuItem, { to: action.link, external: true },
82
- react_1.default.createElement(PageActionsMenuItem_1.PageActionsMenuItem, { pageAction: action }))) : (react_1.default.createElement(PageActionsMenuItem_1.PageActionsMenuItem, { pageAction: action })),
83
- onAction: 'onClick' in action ? () => handleActionClick(action) : undefined,
84
- }));
85
- return (react_1.default.createElement(PageActionsWrapper, null,
81
+ const menuItems = actions.map((action, index) => {
82
+ const key = `${action.title}-${index}`;
83
+ const hasLink = 'link' in action;
84
+ const content = hasLink ? (react_1.default.createElement(LinkMenuItem, { key: `${key}-link`, to: action.link, tabIndex: -1, external: true },
85
+ react_1.default.createElement(PageActionsMenuItem_1.PageActionsMenuItem, { pageAction: action }))) : (react_1.default.createElement(PageActionsMenuItem_1.PageActionsMenuItem, { pageAction: action }));
86
+ return (react_1.default.createElement(StyledDropdownMenuItem, { key: key, onAction: () => handleActionClick(action) }, content));
87
+ });
88
+ return (react_1.default.createElement(PageActionsWrapper, { "data-component-name": "PageActions/PageActions" },
86
89
  react_1.default.createElement(ButtonGroup_1.ButtonGroup, { variant: "outlined", size: "medium" },
87
90
  react_1.default.createElement(Button_1.Button, { icon: renderIcon(buttonAction, actionState), to: 'link' in buttonAction ? buttonAction.link : undefined, external: true, onClick: () => handleActionClick(buttonAction) }, buttonAction.buttonText),
88
- actions.length > 1 ? (react_1.default.createElement(Dropdown_1.Dropdown, { withArrow: true, trigger: react_1.default.createElement(Button_1.Button, null), placement: "bottom", alignment: "end" },
89
- react_1.default.createElement(StyledDropdownMenu, { items: menuItems }))) : null)));
91
+ actions.length > 1 ? (react_1.default.createElement(StyledDropdown, { withArrow: true, trigger: react_1.default.createElement(Button_1.Button, null), placement: "bottom", alignment: "end" },
92
+ react_1.default.createElement(StyledDropdownMenu, null, menuItems))) : null)));
90
93
  }
91
94
  function renderIcon(buttonAction, actionState) {
92
95
  switch (actionState) {
@@ -111,7 +114,21 @@ const LinkMenuItem = (0, styled_components_1.default)(Link_1.Link) `
111
114
  text-decoration: none;
112
115
  --link-decoration-hover: none;
113
116
  `;
117
+ const StyledDropdown = (0, styled_components_1.default)(Dropdown_1.Dropdown) `
118
+ z-index: calc(var(--z-index-raised) - 1);
119
+ `;
114
120
  const StyledDropdownMenu = (0, styled_components_1.default)(DropdownMenu_1.DropdownMenu) `
115
121
  --dropdown-menu-max-height: var(--page-actions-dropdown-max-height);
116
122
  `;
123
+ const StyledDropdownMenuItem = (0, styled_components_1.default)(DropdownMenuItem_1.DropdownMenuItem) `
124
+ &:has(a) {
125
+ padding: 0;
126
+ & > a {
127
+ display: inline-block;
128
+ width: 100%;
129
+ padding: var(--dropdown-menu-item-padding-vertical)
130
+ var(--dropdown-menu-item-padding-horizontal);
131
+ }
132
+ }
133
+ `;
117
134
  //# sourceMappingURL=PageActions.js.map
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { JSX } from 'react';
3
- import type { AiSearchConversationItem, SearchAiMessageResource } from '../../core/types';
3
+ import type { AiSearchConversationItem, SearchAiMessageResource, ToolCall, ContentSegment } from '../../core/types';
4
4
  import { AiSearchError } from '../../core/constants';
5
5
  export type SearchAiDialogProps = {
6
6
  response: string | undefined;
@@ -12,5 +12,7 @@ export type SearchAiDialogProps = {
12
12
  conversation: AiSearchConversationItem[];
13
13
  setConversation: React.Dispatch<React.SetStateAction<AiSearchConversationItem[]>>;
14
14
  onMessageSent: (message: string, history?: AiSearchConversationItem[], messageId?: string) => void;
15
+ toolCalls?: ToolCall[];
16
+ contentSegments?: ContentSegment[];
15
17
  };
16
- export declare function SearchAiDialog({ isGeneratingResponse, response, initialMessage, error, resources, onMessageSent, className, conversation, setConversation, }: SearchAiDialogProps): JSX.Element;
18
+ export declare function SearchAiDialog({ isGeneratingResponse, response, initialMessage, error, resources, onMessageSent, className, conversation, setConversation, toolCalls, contentSegments, }: SearchAiDialogProps): JSX.Element;
@@ -46,7 +46,7 @@ const constants_1 = require("../../core/constants");
46
46
  const SearchAiMessage_1 = require("../../components/Search/SearchAiMessage");
47
47
  const Admonition_1 = require("../../components/Admonition/Admonition");
48
48
  const AiStarsIcon_1 = require("../../icons/AiStarsIcon/AiStarsIcon");
49
- function SearchAiDialog({ isGeneratingResponse, response, initialMessage, error, resources, onMessageSent, className, conversation, setConversation, }) {
49
+ function SearchAiDialog({ isGeneratingResponse, response, initialMessage, error, resources, onMessageSent, className, conversation, setConversation, toolCalls = [], contentSegments, }) {
50
50
  const { useTranslate } = (0, hooks_1.useThemeHooks)();
51
51
  const { aiAssistant } = (0, hooks_1.useThemeConfig)();
52
52
  const { translate } = useTranslate();
@@ -99,12 +99,31 @@ function SearchAiDialog({ isGeneratingResponse, response, initialMessage, error,
99
99
  content,
100
100
  resources,
101
101
  messageId: lastMessage.messageId,
102
+ toolCalls,
103
+ contentSegments,
102
104
  },
103
105
  ];
104
106
  }
105
- return [...prev, { role: constants_1.AiSearchConversationRole.ASSISTANT, content, resources }];
107
+ return [
108
+ ...prev,
109
+ {
110
+ role: constants_1.AiSearchConversationRole.ASSISTANT,
111
+ content,
112
+ resources,
113
+ toolCalls,
114
+ contentSegments,
115
+ },
116
+ ];
106
117
  });
107
- }, [response, conversation.length, error, resources, setConversation]);
118
+ }, [
119
+ response,
120
+ conversation.length,
121
+ error,
122
+ resources,
123
+ toolCalls,
124
+ contentSegments,
125
+ setConversation,
126
+ ]);
108
127
  (0, react_1.useEffect)(() => {
109
128
  if (error) {
110
129
  setConversation((prev) => prev.slice(0, -1));
@@ -123,7 +142,7 @@ function SearchAiDialog({ isGeneratingResponse, response, initialMessage, error,
123
142
  react_1.default.createElement(ConversationWrapper, null,
124
143
  conversation.map((item, index) => (react_1.default.createElement(SearchAiMessage_1.SearchAiMessage, { key: `search-ai-message-${index}`, role: item.role, content: item.content, isThinking: item.role === constants_1.AiSearchConversationRole.ASSISTANT &&
125
144
  isGeneratingResponse &&
126
- index === conversation.length - 1, resources: item.resources, messageId: item.messageId, feedback: item.feedback, onFeedbackChange: handleFeedbackChange }))),
145
+ index === conversation.length - 1, resources: item.resources, messageId: item.messageId, feedback: item.feedback, onFeedbackChange: handleFeedbackChange, toolCalls: item.toolCalls || (index === conversation.length - 1 ? toolCalls : undefined), contentSegments: item.contentSegments }))),
127
146
  error && (react_1.default.createElement(Admonition_1.Admonition, { type: "danger", name: translate(constants_1.AI_SEARCH_ERROR_CONFIG[error].headerKey, constants_1.AI_SEARCH_ERROR_CONFIG[error].headerDefault) }, translate(constants_1.AI_SEARCH_ERROR_CONFIG[error].messageKey, constants_1.AI_SEARCH_ERROR_CONFIG[error].messageDefault))),
128
147
  !conversation.length && !error && (react_1.default.createElement(SuggestionsWrapper, null, suggestions === null || suggestions === void 0 ? void 0 : suggestions.map((suggestion) => (react_1.default.createElement(Button_1.Button, { key: suggestion, variant: "outlined", onClick: () => handleOnMessageSent(suggestion) }, suggestion))))),
129
148
  react_1.default.createElement("div", { ref: conversationEndRef })),
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { JSX } from 'react';
3
- import { FeedbackType, type SearchAiMessageResource } from '../../core/types';
3
+ import { FeedbackType, type SearchAiMessageResource, type ToolCall, type ContentSegment } from '../../core/types';
4
4
  import { AiSearchConversationRole } from '../../core/constants';
5
5
  export type SearchAiMessageProps = {
6
6
  role: AiSearchConversationRole;
@@ -11,7 +11,9 @@ export type SearchAiMessageProps = {
11
11
  messageId?: string;
12
12
  feedback?: FeedbackType;
13
13
  onFeedbackChange: (messageId: string, feedback: FeedbackType | undefined) => void;
14
+ toolCalls?: ToolCall[];
15
+ contentSegments?: ContentSegment[];
14
16
  };
15
- declare function SearchAiMessageComponent({ role, content, isThinking, resources, className, messageId, feedback, onFeedbackChange, }: SearchAiMessageProps): JSX.Element;
17
+ declare function SearchAiMessageComponent({ role, content, isThinking, resources, className, messageId, feedback, onFeedbackChange, toolCalls, contentSegments, }: SearchAiMessageProps): JSX.Element;
16
18
  export declare const SearchAiMessage: React.MemoExoticComponent<typeof SearchAiMessageComponent>;
17
19
  export {};
@@ -40,35 +40,44 @@ exports.SearchAiMessage = void 0;
40
40
  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
+ const constants_1 = require("../../core/constants");
43
44
  const Link_1 = require("../../components/Link/Link");
44
45
  const Tag_1 = require("../../components/Tag/Tag");
45
- const constants_1 = require("../../core/constants");
46
+ const constants_2 = require("../../core/constants");
46
47
  const hooks_1 = require("../../core/hooks");
47
48
  const Markdown_1 = require("../../components/Markdown/Markdown");
48
49
  const DocumentIcon_1 = require("../../icons/DocumentIcon/DocumentIcon");
49
50
  const AiStarsIcon_1 = require("../../icons/AiStarsIcon/AiStarsIcon");
50
51
  const CheckmarkOutlineIcon_1 = require("../../icons/CheckmarkOutlineIcon/CheckmarkOutlineIcon");
51
- const SearchAiActionButtons_1 = require("./SearchAiActionButtons");
52
- const SearchAiNegativeFeedbackForm_1 = require("./SearchAiNegativeFeedbackForm");
53
- function SearchAiMessageComponent({ role, content, isThinking, resources, className, messageId, feedback, onFeedbackChange, }) {
52
+ const SearchAiActionButtons_1 = require("../../components/Search/SearchAiActionButtons");
53
+ const SearchAiNegativeFeedbackForm_1 = require("../../components/Search/SearchAiNegativeFeedbackForm");
54
+ function MarkdownSegment({ text }) {
55
+ const { useMarkdownText } = (0, hooks_1.useThemeHooks)();
56
+ const markdown = useMarkdownText(text);
57
+ return react_1.default.createElement(ResponseText, { as: "div", children: markdown, "data-testid": "response-text" });
58
+ }
59
+ function SearchAiMessageComponent({ role, content, isThinking, resources, className, messageId, feedback, onFeedbackChange, toolCalls = [], contentSegments = [{ type: 'text', text: content }], }) {
54
60
  var _a;
55
- const { useMarkdownText, useTranslate, useTelemetry } = (0, hooks_1.useThemeHooks)();
56
- const markDownContent = useMarkdownText(content || '');
61
+ const { useTranslate, useTelemetry } = (0, hooks_1.useThemeHooks)();
57
62
  const { translate } = useTranslate();
58
63
  const telemetry = useTelemetry();
59
64
  const [feedbackSent, setFeedbackSent] = (0, react_1.useState)(false);
60
65
  const hasResources = !isThinking && resources && resources.length > 0;
61
66
  const resourcesCount = (_a = resources === null || resources === void 0 ? void 0 : resources.length) !== null && _a !== void 0 ? _a : 0;
62
67
  const showSuccessMessage = feedbackSent && feedback;
68
+ const isLoading = isThinking && content.length === 0 && toolCalls.length === 0;
63
69
  const sendFeedbackTelemetry = (feedbackValue, dislikeReason) => {
64
70
  if (!messageId)
65
71
  return;
66
72
  try {
67
- telemetry.sendSearchAIFeedbackMessage({
68
- feedback: feedbackValue,
69
- messageId,
70
- reason: dislikeReason,
71
- });
73
+ telemetry.sendSearchAIFeedbackMessage([
74
+ {
75
+ object: 'feedback',
76
+ feedback: feedbackValue,
77
+ messageId,
78
+ reason: dislikeReason,
79
+ },
80
+ ]);
72
81
  }
73
82
  catch (error) {
74
83
  console.error('Error sending feedback', error);
@@ -87,10 +96,25 @@ function SearchAiMessageComponent({ role, content, isThinking, resources, classN
87
96
  }
88
97
  };
89
98
  return (react_1.default.createElement(SearchAiMessageWrapper, { "data-component-name": "Search/SearchAiMessage", role: role, className: className, "data-testid": "search-ai-message" },
90
- role === constants_1.AiSearchConversationRole.ASSISTANT && (react_1.default.createElement(AiStarsIcon_1.AiStarsIcon, { size: "32px", background: "var(--search-ai-icon-bg-color)", borderRadius: "var(--border-radius-lg)", color: "var(--search-ai-icon-color)", margin: "0 var(--spacing-xs) 0 0" })),
91
- react_1.default.createElement(MessageContentWrapper, null, role === constants_1.AiSearchConversationRole.ASSISTANT ? (react_1.default.createElement(react_1.default.Fragment, null,
99
+ role === constants_2.AiSearchConversationRole.ASSISTANT && (react_1.default.createElement(AiStarsIcon_1.AiStarsIcon, { size: "32px", background: "var(--search-ai-icon-bg-color)", borderRadius: "var(--border-radius-lg)", color: "var(--search-ai-icon-color)", margin: "0 var(--spacing-xs) 0 0" })),
100
+ react_1.default.createElement(MessageContentWrapper, null, role === constants_2.AiSearchConversationRole.ASSISTANT ? (react_1.default.createElement(react_1.default.Fragment, null,
92
101
  react_1.default.createElement(MessageWrapper, { role: role },
93
- react_1.default.createElement(ResponseText, { as: "div", children: markDownContent, "data-testid": "response-text" }),
102
+ contentSegments.map((segment, index) => {
103
+ var _a, _b, _c, _d, _e, _f;
104
+ if (segment.type === 'tool') {
105
+ const toolCallCompleted = Boolean(segment.toolCall.result);
106
+ const toolCallCompletedText = (_b = (_a = constants_1.TOOL_CALL_DISPLAY_TEXT[segment.toolCall.name]) === null || _a === void 0 ? void 0 : _a.completedText) !== null && _b !== void 0 ? _b : `${translate('search.ai.toolResult.found', 'Found')} ${(_d = (_c = segment.toolCall.result) === null || _c === void 0 ? void 0 : _c.documentCount) !== null && _d !== void 0 ? _d : 0} ${translate('search.ai.toolResult.found.documents', 'documents')}`;
107
+ const toolCallInProgressText = (_f = (_e = constants_1.TOOL_CALL_DISPLAY_TEXT[segment.toolCall.name]) === null || _e === void 0 ? void 0 : _e.inProgressText) !== null && _f !== void 0 ? _f : translate('search.ai.toolCall.searching', 'Searching...');
108
+ const toolCallDisplayText = toolCallCompleted
109
+ ? toolCallCompletedText
110
+ : toolCallInProgressText;
111
+ return (react_1.default.createElement(ToolCallsInfoWrapper, { key: `tool-${index}`, "data-testid": "tool-calls-info" },
112
+ react_1.default.createElement(ToolCallInfoItem, null,
113
+ react_1.default.createElement(DocumentIcon_1.DocumentIcon, { size: "14px", color: "--search-ai-text-color" }),
114
+ react_1.default.createElement(ToolCallText, { "$isSearching": !toolCallCompleted }, toolCallDisplayText))));
115
+ }
116
+ return react_1.default.createElement(MarkdownSegment, { key: `text-${index}`, text: segment.text });
117
+ }),
94
118
  hasResources && (react_1.default.createElement(react_1.default.Fragment, null,
95
119
  react_1.default.createElement(ResourcesWrapper, { "data-testid": "resources-wrapper" },
96
120
  react_1.default.createElement(ResourcesTitle, { "data-translation-key": "search.ai.resourcesFound" },
@@ -99,9 +123,9 @@ function SearchAiMessageComponent({ role, content, isThinking, resources, classN
99
123
  resourcesCount,
100
124
  ' ',
101
125
  translate('search.ai.resourcesFound.resources', 'resources')),
102
- react_1.default.createElement(ResourceTagsWrapper, null, resources === null || resources === void 0 ? void 0 : resources.map((resource, idx) => (react_1.default.createElement(Link_1.Link, { key: `${resource.url}-${idx}`, to: resource.url, target: "_blank" },
126
+ react_1.default.createElement(ResourceTagsWrapper, null, resources === null || resources === void 0 ? void 0 : resources.map((resource, index) => (react_1.default.createElement(Link_1.Link, { key: `${resource.url}-${index}`, to: resource.url, target: "_blank" },
103
127
  react_1.default.createElement(ResourceTag, { borderless: true, icon: react_1.default.createElement(DocumentIcon_1.DocumentIcon, { color: "--search-ai-resource-tag-icon-color" }) }, resource.title)))))))),
104
- isThinking && content.length === 0 && (react_1.default.createElement(ThinkingDotsWrapper, { "data-testid": "thinking-dots-wrapper" },
128
+ isLoading && (react_1.default.createElement(ThinkingDotsWrapper, { "data-testid": "thinking-dots-wrapper" },
105
129
  react_1.default.createElement(ThinkingDot, null),
106
130
  react_1.default.createElement(ThinkingDot, null),
107
131
  react_1.default.createElement(ThinkingDot, null))),
@@ -126,20 +150,23 @@ function areResourcesEqual(prev, next) {
126
150
  });
127
151
  }
128
152
  exports.SearchAiMessage = (0, react_1.memo)(SearchAiMessageComponent, (prevProps, nextProps) => {
153
+ var _a, _b;
129
154
  return (prevProps.role === nextProps.role &&
130
155
  prevProps.content === nextProps.content &&
131
156
  prevProps.isThinking === nextProps.isThinking &&
132
157
  prevProps.messageId === nextProps.messageId &&
133
158
  prevProps.feedback === nextProps.feedback &&
134
159
  prevProps.onFeedbackChange === nextProps.onFeedbackChange &&
135
- areResourcesEqual(prevProps.resources, nextProps.resources));
160
+ areResourcesEqual(prevProps.resources, nextProps.resources) &&
161
+ ((_a = prevProps.toolCalls) === null || _a === void 0 ? void 0 : _a.length) === ((_b = nextProps.toolCalls) === null || _b === void 0 ? void 0 : _b.length) &&
162
+ prevProps.contentSegments === nextProps.contentSegments);
136
163
  });
137
164
  const SearchAiMessageWrapper = styled_components_1.default.div `
138
165
  display: flex;
139
166
  flex-direction: row;
140
167
  align-items: flex-start;
141
168
  width: 100%;
142
- justify-content: ${({ role }) => role === constants_1.AiSearchConversationRole.USER ? 'flex-end' : 'flex-start'};
169
+ justify-content: ${({ role }) => role === constants_2.AiSearchConversationRole.USER ? 'flex-end' : 'flex-start'};
143
170
  `;
144
171
  const MessageContentWrapper = styled_components_1.default.div `
145
172
  display: flex;
@@ -165,18 +192,19 @@ const ResponseText = (0, styled_components_1.default)(Markdown_1.Markdown) `
165
192
  }
166
193
  `;
167
194
  const MessageWrapper = styled_components_1.default.div `
168
- padding: ${({ role }) => role === constants_1.AiSearchConversationRole.USER ? 'var(--spacing-sm)' : 'var(--spacing-xs)'}
169
- var(--spacing-sm);
195
+ padding: ${({ role }) => role === constants_2.AiSearchConversationRole.USER
196
+ ? 'var(--spacing-sm)'
197
+ : 'var(--spacing-sm) var(--spacing-sm) var(--spacing-xs) var(--spacing-sm)'};
170
198
  border-radius: var(--border-radius-lg);
171
199
  width: fit-content;
172
200
  max-width: 100%;
173
201
  word-wrap: break-word;
174
202
  white-space: pre-wrap;
175
- background-color: ${({ role }) => role === constants_1.AiSearchConversationRole.USER
203
+ background-color: ${({ role }) => role === constants_2.AiSearchConversationRole.USER
176
204
  ? 'var(--search-ai-user-bg-color)'
177
205
  : 'var(--search-ai-assistant-bg-color)'};
178
- border: ${({ role }) => role === constants_1.AiSearchConversationRole.USER ? 'none' : 'var(--search-ai-assistant-border)'};
179
- color: ${({ role }) => role === constants_1.AiSearchConversationRole.USER
206
+ border: ${({ role }) => role === constants_2.AiSearchConversationRole.USER ? 'none' : 'var(--search-ai-assistant-border)'};
207
+ color: ${({ role }) => role === constants_2.AiSearchConversationRole.USER
180
208
  ? 'var(--search-ai-user-text-color)'
181
209
  : 'var(--search-ai-assistant-text-color)'};
182
210
  `;
@@ -270,4 +298,35 @@ const SuccessMessageText = styled_components_1.default.div `
270
298
  font-size: var(--font-size-base);
271
299
  color: var(--color-success-darker);
272
300
  `;
301
+ const ToolCallsInfoWrapper = styled_components_1.default.div `
302
+ display: flex;
303
+ flex-direction: column;
304
+ gap: var(--spacing-xxs);
305
+ margin: 0 0 var(--spacing-sm) 0;
306
+ font-size: var(--font-size-xs);
307
+ color: var(--search-ai-text-color);
308
+ opacity: 0.6;
309
+ `;
310
+ const ToolCallInfoItem = styled_components_1.default.div `
311
+ display: flex;
312
+ align-items: center;
313
+ gap: var(--spacing-xxs);
314
+ `;
315
+ const ToolCallText = styled_components_1.default.span `
316
+ font-weight: var(--font-weight-regular);
317
+
318
+ ${({ $isSearching }) => $isSearching &&
319
+ `
320
+ animation: pulse 1.5s ease-in-out infinite;
321
+
322
+ @keyframes pulse {
323
+ 0%, 100% {
324
+ opacity: 1;
325
+ }
326
+ 50% {
327
+ opacity: 0.4;
328
+ }
329
+ }
330
+ `}
331
+ `;
273
332
  //# sourceMappingURL=SearchAiMessage.js.map
@@ -74,6 +74,7 @@ function SearchDialog({ onClose, className, initialMode = 'search', }) {
74
74
  const { isFilterOpen, onFilterToggle, onFilterChange, onFilterReset, onFacetReset, onQuickFilterReset, } = (0, hooks_1.useSearchFilter)(filter, setFilter);
75
75
  const { addSearchHistoryItem } = (0, hooks_1.useRecentSearches)();
76
76
  const aiSearch = useAiSearch({ filter });
77
+ (0, hooks_1.useModalScrollLock)(true);
77
78
  const searchInputRef = (0, react_1.useRef)(null);
78
79
  const modalRef = (0, react_1.useRef)(null);
79
80
  const [isMobile, setIsMobile] = (0, react_1.useState)(false);
@@ -134,14 +135,17 @@ function SearchDialog({ onClose, className, initialMode = 'search', }) {
134
135
  }
135
136
  return (react_1.default.createElement(SearchItem_1.SearchItem, { key: `${index}-${item.document.id}`, item: item, product: itemProduct, innerRef: innerRef, onClick: () => {
136
137
  addSearchHistoryItem(query);
137
- telemetry.sendSearchResultClickedMessage({
138
- query,
139
- url: item.document.url,
140
- totalResults: results.length.toString(),
141
- index: index.toString(),
142
- searchEngine: mode,
143
- searchSessionId,
144
- });
138
+ telemetry.sendSearchResultClickedMessage([
139
+ {
140
+ object: 'search',
141
+ query: query,
142
+ url: item.document.url,
143
+ totalResults: results.length.toString(),
144
+ index: index.toString(),
145
+ searchEngine: mode,
146
+ searchSessionId,
147
+ },
148
+ ]);
145
149
  onClose();
146
150
  } }));
147
151
  }, [onClose, product, products, addSearchHistoryItem, query, telemetry, mode, searchSessionId]);
@@ -189,18 +193,23 @@ function SearchDialog({ onClose, className, initialMode = 'search', }) {
189
193
  if (query.trim()) {
190
194
  aiSearch.askQuestion(query);
191
195
  }
192
- telemetry.sendSearchAiOpenedMessage({
193
- method: 'ai_search_button',
194
- });
196
+ telemetry.sendSearchAiOpenedMessage([
197
+ {
198
+ object: 'search',
199
+ method: 'ai_search_button',
200
+ },
201
+ ]);
195
202
  } }, translate('search.ai.button', 'Search with AI'))) : null,
196
203
  showSearchFilterButton && (react_1.default.createElement(SearchFilterToggleButton, { icon: react_1.default.createElement(SettingsIcon_1.SettingsIcon, null), onClick: onFilterToggle })))))) : (react_1.default.createElement(AiDialogHeaderWrapper, null,
197
- react_1.default.createElement(Button_1.Button, { variant: "secondary", onClick: () => {
204
+ initialMode === 'ai-dialog' ? (react_1.default.createElement(AiDialogHeaderTitle, null,
205
+ react_1.default.createElement(AiStarsGradientIcon_1.AiStarsGradientIcon, { color: "var(--search-ai-button-icon-color)", size: "1.25rem" }),
206
+ translate('search.ai.assistant', 'Assistant'))) : (react_1.default.createElement(Button_1.Button, { variant: "secondary", onClick: () => {
198
207
  setMode('search');
199
208
  aiSearch.clearConversation();
200
209
  focusSearchInput();
201
210
  }, tabIndex: 0, icon: react_1.default.createElement(ChevronLeftIcon_1.ChevronLeftIcon, null) }, isMobile
202
211
  ? translate('search.ai.back', 'Back')
203
- : translate('search.ai.backToSearch', 'Back to search')),
212
+ : translate('search.ai.backToSearch', 'Back to search'))),
204
213
  react_1.default.createElement(AiDialogHeaderActionsWrapper, null,
205
214
  react_1.default.createElement(Button_1.Button, { variant: "secondary", disabled: !aiSearch.conversation.length, onClick: () => {
206
215
  refreshSearchSessionId();
@@ -217,18 +226,24 @@ function SearchDialog({ onClose, className, initialMode = 'search', }) {
217
226
  if (query.trim()) {
218
227
  aiSearch.askQuestion(query);
219
228
  }
220
- telemetry.sendSearchAiOpenedMessage({
221
- method: 'ai_search_input',
222
- });
229
+ telemetry.sendSearchAiOpenedMessage([
230
+ {
231
+ object: 'search',
232
+ method: 'ai_search_input',
233
+ },
234
+ ]);
223
235
  }, onKeyDown: (e) => {
224
236
  if (e.key === 'Enter') {
225
237
  setMode('ai-dialog');
226
238
  if (query.trim()) {
227
239
  aiSearch.askQuestion(query);
228
240
  }
229
- telemetry.sendSearchAiOpenedMessage({
230
- method: 'ai_search_input',
231
- });
241
+ telemetry.sendSearchAiOpenedMessage([
242
+ {
243
+ object: 'search',
244
+ method: 'ai_search_input',
245
+ },
246
+ ]);
232
247
  }
233
248
  }, ref: aiQueryRef, tabIndex: 0, role: "option", "aria-selected": "true" },
234
249
  react_1.default.createElement(AiStarsIcon_1.AiStarsIcon, { style: { flexShrink: 0 }, color: "var(--search-ai-icon-color)", size: "36px", background: "var(--search-ai-icon-bg-color)", margin: "0 var(--spacing-md) 0 0", borderRadius: "var(--border-radius-lg)" }),
@@ -262,15 +277,18 @@ function SearchDialog({ onClose, className, initialMode = 'search', }) {
262
277
  translate('search.loading', 'Loading...'))) : (react_1.default.createElement(SearchMessage, { "data-translation-key": "search.noResults" },
263
278
  react_1.default.createElement("b", null, translate('search.noResults.title', 'No results'))))) : (react_1.default.createElement(react_1.default.Fragment, null,
264
279
  react_1.default.createElement(SearchRecent_1.SearchRecent, { onSelect: (query, index) => {
265
- telemetry.sendSearchRecentClickedMessage({
266
- query,
267
- index: index.toString(),
268
- searchSessionId,
269
- });
280
+ telemetry.sendSearchRecentClickedMessage([
281
+ {
282
+ object: 'search',
283
+ query,
284
+ index: index.toString(),
285
+ searchSessionId,
286
+ },
287
+ ]);
270
288
  setQuery(query);
271
289
  focusSearchInput();
272
290
  } }),
273
- react_1.default.createElement(SearchSuggestedPages_1.SearchSuggestedPages, null)))))) : (react_1.default.createElement(SearchAiDialog_1.SearchAiDialog, { initialMessage: query, response: aiSearch.response, isGeneratingResponse: aiSearch.isGeneratingResponse, error: aiSearch.error, resources: aiSearch.resources, conversation: aiSearch.conversation, setConversation: aiSearch.setConversation, onMessageSent: aiSearch.askQuestion }))),
291
+ react_1.default.createElement(SearchSuggestedPages_1.SearchSuggestedPages, null)))))) : (react_1.default.createElement(SearchAiDialog_1.SearchAiDialog, { initialMessage: query, response: aiSearch.response, isGeneratingResponse: aiSearch.isGeneratingResponse, error: aiSearch.error, resources: aiSearch.resources, conversation: aiSearch.conversation, setConversation: aiSearch.setConversation, onMessageSent: aiSearch.askQuestion, toolCalls: aiSearch.toolCalls, contentSegments: aiSearch.contentSegments }))),
274
292
  react_1.default.createElement(SearchDialogFooter, null, mode === 'ai-dialog' ? (react_1.default.createElement(AiDisclaimer, null, translate('search.ai.disclaimer', 'AI search might provide incomplete or incorrect results. Verify important information.'))) : (react_1.default.createElement(react_1.default.Fragment, null,
275
293
  react_1.default.createElement(SearchShortcuts, null,
276
294
  react_1.default.createElement(SearchShortcut_1.SearchShortcut, { "data-translation-key": "search.keys.navigate", combination: "Tab", text: translate('search.keys.navigate', 'to navigate') }),
@@ -345,6 +363,13 @@ const AiDialogHeaderActionsWrapper = styled_components_1.default.div `
345
363
  display: flex;
346
364
  gap: var(--spacing-xxs);
347
365
  `;
366
+ const AiDialogHeaderTitle = styled_components_1.default.span `
367
+ display: flex;
368
+ align-items: center;
369
+ gap: var(--spacing-xs);
370
+ font-weight: var(--font-weight-semibold);
371
+ font-size: var(--font-size-lg);
372
+ `;
348
373
  const SearchDialogBody = styled_components_1.default.div `
349
374
  display: flex;
350
375
  flex-direction: row-reverse;
@@ -12,7 +12,7 @@ exports.select = (0, styled_components_1.css) `
12
12
  --select-text-color: var(--text-color-secondary); // @presenter Color
13
13
  --select-border-radius: var(--border-radius); // @presenter BorderRadius
14
14
  --select-border: var(--border-width) var(--border-style) var(--border-color-primary); // @presenter Border
15
-
15
+
16
16
  --select-input-padding-vertical: 6px; // @presenter Spacing
17
17
  --select-input-padding-horizontal: 6px; // @presenter Spacing
18
18
  --select-input-padding: var(--select-input-padding-vertical) var(--select-input-padding-horizontal);
@@ -40,7 +40,7 @@ exports.select = (0, styled_components_1.css) `
40
40
  --select-list-item-border-radius: var(--border-radius); // @presenter BorderRadius
41
41
  --select-list-item-bg-color-active: transparent; // @presenter Color
42
42
  --select-list-item-bg-color-hover: var(--menu-item-bg-color-hover); // @presenter Color
43
- --select-list-item-font-weight-active: var(--font-weight-medium); // @presenter Color
43
+ --select-list-item-font-weight-active: var(--font-weight-medium); // @presenter Color
44
44
 
45
45
  --select-placeholder-color: var(--color-warm-grey-6); // @presenter Color
46
46
  // @tokens End