@redocly/theme 0.64.0-next.4 → 0.64.0-next.6

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 (42) hide show
  1. package/lib/components/Banner/Banner.d.ts +5 -0
  2. package/lib/components/Banner/Banner.js +22 -5
  3. package/lib/components/Catalog/CatalogTags.js +2 -5
  4. package/lib/components/Sidebar/Sidebar.js +2 -2
  5. package/lib/core/constants/search.js +4 -0
  6. package/lib/core/contexts/MarkdownLinkContext.d.ts +1 -1
  7. package/lib/core/hooks/index.d.ts +1 -0
  8. package/lib/core/hooks/index.js +1 -0
  9. package/lib/core/hooks/use-banner-telemetry.d.ts +7 -0
  10. package/lib/core/hooks/use-banner-telemetry.js +64 -0
  11. package/lib/core/hooks/use-telemetry-fallback.d.ts +3 -0
  12. package/lib/core/hooks/use-telemetry-fallback.js +3 -0
  13. package/lib/core/types/l10n.d.ts +1 -1
  14. package/lib/core/types/search.d.ts +4 -1
  15. package/lib/core/types/search.js +1 -0
  16. package/lib/icons/AnthropicIcon/AnthropicIcon.d.ts +9 -0
  17. package/lib/icons/AnthropicIcon/AnthropicIcon.js +20 -0
  18. package/lib/icons/BotIcon/BotIcon.d.ts +9 -0
  19. package/lib/icons/BotIcon/BotIcon.js +21 -0
  20. package/lib/icons/GeminiIcon/GeminiIcon.d.ts +9 -0
  21. package/lib/icons/GeminiIcon/GeminiIcon.js +95 -0
  22. package/lib/index.d.ts +3 -0
  23. package/lib/index.js +3 -0
  24. package/lib/layouts/PageLayout.js +1 -1
  25. package/lib/markdoc/components/MarkdownLink/MarkdownLink.js +2 -2
  26. package/package.json +3 -3
  27. package/src/components/Banner/Banner.tsx +44 -13
  28. package/src/components/Catalog/CatalogTags.tsx +1 -6
  29. package/src/components/Sidebar/Sidebar.tsx +2 -2
  30. package/src/core/constants/search.ts +4 -0
  31. package/src/core/contexts/MarkdownLinkContext.tsx +1 -1
  32. package/src/core/hooks/index.ts +1 -0
  33. package/src/core/hooks/use-banner-telemetry.ts +66 -0
  34. package/src/core/hooks/use-telemetry-fallback.ts +3 -0
  35. package/src/core/types/l10n.ts +0 -1
  36. package/src/core/types/search.ts +3 -1
  37. package/src/icons/AnthropicIcon/AnthropicIcon.tsx +25 -0
  38. package/src/icons/BotIcon/BotIcon.tsx +25 -0
  39. package/src/icons/GeminiIcon/GeminiIcon.tsx +265 -0
  40. package/src/index.ts +3 -0
  41. package/src/layouts/PageLayout.tsx +1 -1
  42. package/src/markdoc/components/MarkdownLink/MarkdownLink.tsx +2 -2
@@ -1,23 +1,35 @@
1
- import React, { useRef, useEffect, useState } from 'react';
1
+ import React, { useRef, useEffect, useState, useMemo } from 'react';
2
2
  import styled, { css } from 'styled-components';
3
3
 
4
4
  import type { ResolvedBannerConfig } from '@redocly/config';
5
5
  import type { JSX } from 'react';
6
6
 
7
- import { useThemeHooks } from '@redocly/theme/core/hooks';
7
+ import { useThemeHooks, useBannerTelemetry } from '@redocly/theme/core/hooks';
8
8
  import { getNavbarElement } from '@redocly/theme/core/utils';
9
+ import { MarkdownLinkContext } from '@redocly/theme/core/contexts';
9
10
  import { Markdown } from '@redocly/theme/components/Markdown/Markdown';
10
11
  import { CloseIcon } from '@redocly/theme/icons/CloseIcon/CloseIcon';
11
12
  import { Button } from '@redocly/theme/components/Button/Button';
12
13
 
13
14
  const ANIMATION_DURATION = 0.4;
14
15
 
15
- type BannerColor = 'info' | 'success' | 'warning' | 'error';
16
-
17
16
  type BannerProps = {
18
17
  className?: string;
19
18
  };
20
19
 
20
+ export type DisplayBanner = ResolvedBannerConfig & {
21
+ color: NonNullable<ResolvedBannerConfig['color']>;
22
+ dismissible: NonNullable<ResolvedBannerConfig['dismissible']>;
23
+ };
24
+
25
+ function toDisplayBanner(banner: ResolvedBannerConfig): DisplayBanner {
26
+ return {
27
+ ...banner,
28
+ color: banner.color ?? 'info',
29
+ dismissible: banner.dismissible ?? false,
30
+ };
31
+ }
32
+
21
33
  function setBannerHeight(height: number): void {
22
34
  document.documentElement.style.setProperty('--banner-height', `${height}px`);
23
35
  }
@@ -25,15 +37,18 @@ function setBannerHeight(height: number): void {
25
37
  export function Banner({ className }: BannerProps): JSX.Element | null {
26
38
  const { useBanner, useMarkdocRenderer } = useThemeHooks();
27
39
  const { banner, dismissBanner } = useBanner();
28
- const [displayBanner, setDisplayBanner] = useState<ResolvedBannerConfig | undefined>(undefined);
40
+ const [displayBanner, setDisplayBanner] = useState<DisplayBanner | undefined>(undefined);
29
41
  const [isVisible, setIsVisible] = useState(false);
30
42
 
43
+ const { sendBannerViewedMessage, sendBannerDismissedMessage, sendBannerLinkClickedMessage } =
44
+ useBannerTelemetry(displayBanner);
45
+
31
46
  const markdownContent = useMarkdocRenderer(displayBanner?.ast);
32
47
  const bannerRef = useRef<HTMLDivElement>(null);
33
48
 
34
49
  useEffect(() => {
35
50
  if (banner) {
36
- setDisplayBanner(banner);
51
+ setDisplayBanner(toDisplayBanner(banner));
37
52
  requestAnimationFrame(() => {
38
53
  requestAnimationFrame(() => {
39
54
  setIsVisible(true);
@@ -98,29 +113,45 @@ export function Banner({ className }: BannerProps): JSX.Element | null {
98
113
  };
99
114
  }, [displayBanner, isVisible]);
100
115
 
116
+ useEffect(() => {
117
+ if (isVisible) {
118
+ sendBannerViewedMessage();
119
+ }
120
+ }, [isVisible, sendBannerViewedMessage]);
121
+
122
+ const markdownLinkContextValue = useMemo(
123
+ () => ({
124
+ onMarkdownLinkClick: sendBannerLinkClickedMessage,
125
+ }),
126
+ [sendBannerLinkClickedMessage],
127
+ );
128
+
101
129
  if (!displayBanner) {
102
130
  return null;
103
131
  }
104
132
 
105
- const bannerColor = displayBanner.color || 'info';
106
-
107
133
  return (
108
134
  <BannerWrapper
109
135
  ref={bannerRef}
110
136
  data-component-name="Banner/Banner"
111
137
  className={className}
112
- $color={bannerColor}
138
+ $color={displayBanner.color}
113
139
  $isVisible={isVisible}
114
140
  >
115
141
  <BannerContent>
116
- <Markdown compact>{markdownContent}</Markdown>
142
+ <MarkdownLinkContext.Provider value={markdownLinkContextValue}>
143
+ <Markdown compact>{markdownContent}</Markdown>
144
+ </MarkdownLinkContext.Provider>
117
145
  </BannerContent>
118
146
  {displayBanner.dismissible && (
119
147
  <DismissButton
120
148
  variant="ghost"
121
149
  size="var(--banner-button-size)"
122
- icon={<CloseIcon color={`var(--banner-${bannerColor}-icon-color)`} size="16px" />}
123
- onClick={() => dismissBanner(displayBanner.hash)}
150
+ icon={<CloseIcon color={`var(--banner-${displayBanner.color}-icon-color)`} size="16px" />}
151
+ onClick={() => {
152
+ dismissBanner(displayBanner.hash);
153
+ sendBannerDismissedMessage();
154
+ }}
124
155
  aria-label="Dismiss banner"
125
156
  />
126
157
  )}
@@ -162,7 +193,7 @@ const BannerContent = styled.div`
162
193
  }
163
194
  `;
164
195
 
165
- const BannerWrapper = styled.div<{ $color?: BannerColor; $isVisible?: boolean }>`
196
+ const BannerWrapper = styled.div<{ $color?: DisplayBanner['color']; $isVisible?: boolean }>`
166
197
  display: flex;
167
198
  align-items: center;
168
199
  justify-content: space-between;
@@ -48,7 +48,6 @@ export function CatalogTags({
48
48
  if (shouldUseVariantWithTooltip) {
49
49
  const displayedItems = items.slice(0, itemsToShow);
50
50
  const remainingCount = items.length - itemsToShow;
51
- const moreLabel = translate('catalog.tags.more', 'more');
52
51
 
53
52
  return (
54
53
  <Tooltip tip={items.join(', ')} placement="bottom" className="catalog">
@@ -71,11 +70,7 @@ export function CatalogTags({
71
70
  </Tag>
72
71
  ))}
73
72
 
74
- {remainingCount > 0 && (
75
- <MoreTagsButton>
76
- + {remainingCount} <span data-translation-key="catalog.tags.more">{moreLabel}</span>
77
- </MoreTagsButton>
78
- )}
73
+ {remainingCount > 0 && <MoreTagsButton>+ {remainingCount}</MoreTagsButton>}
79
74
  </CatalogTagsWrapper>
80
75
  </Tooltip>
81
76
  );
@@ -88,8 +88,8 @@ const SidebarContent = styled.aside<{ opened?: boolean; collapsed?: boolean }>`
88
88
  flex-direction: column;
89
89
  width: 100%;
90
90
  -webkit-font-smoothing: antialiased;
91
- top: var(--navbar-height);
92
- height: calc(100vh - var(--navbar-height));
91
+ top: calc(var(--navbar-height) + var(--banner-height));
92
+ height: calc(100vh - var(--navbar-height) - var(--banner-height));
93
93
  overflow-x: hidden;
94
94
  ${({ opened }) => `
95
95
  display: ${opened ? 'flex' : 'none'}
@@ -61,6 +61,10 @@ export const TOOL_CALL_DISPLAY_TEXT: Partial<
61
61
  inProgressText: 'Browsing endpoints for API...',
62
62
  completedText: 'Browsed endpoints for API',
63
63
  },
64
+ [ToolCallName.GetEndpointInfo]: {
65
+ inProgressText: 'Reading endpoint details...',
66
+ completedText: 'Read endpoint details',
67
+ },
64
68
  [ToolCallName.GetSecuritySchemes]: {
65
69
  inProgressText: 'Browsing security schemes for API...',
66
70
  completedText: 'Browsed security schemes for API',
@@ -1,6 +1,6 @@
1
1
  import { createContext } from 'react';
2
2
 
3
- export type MarkdownLinkClickHandler = () => void;
3
+ export type MarkdownLinkClickHandler = (href: string) => void;
4
4
 
5
5
  export type MarkdownLinkContextValue = {
6
6
  onMarkdownLinkClick?: MarkdownLinkClickHandler;
@@ -53,3 +53,4 @@ export * from './use-store';
53
53
  export * from './use-is-truncated';
54
54
  export * from './use-toast';
55
55
  export * from './use-toast-logic';
56
+ export * from './use-banner-telemetry';
@@ -0,0 +1,66 @@
1
+ import { useMemo } from 'react';
2
+
3
+ import type { DisplayBanner } from '@redocly/theme/components/Banner/Banner';
4
+
5
+ import { useThemeHooks } from './use-theme-hooks';
6
+
7
+ const noop = (): void => {};
8
+ const noopLink = (_href: string): void => {};
9
+
10
+ export type BannerTelemetryActions = {
11
+ sendBannerViewedMessage: () => void;
12
+ sendBannerDismissedMessage: () => void;
13
+ sendBannerLinkClickedMessage: (href: string) => void;
14
+ };
15
+
16
+ function getCurrentPageUri(): string {
17
+ return window.location.href;
18
+ }
19
+
20
+ export function useBannerTelemetry(
21
+ displayBanner: DisplayBanner | undefined,
22
+ ): BannerTelemetryActions {
23
+ const { useTelemetry } = useThemeHooks();
24
+ const telemetry = useTelemetry();
25
+
26
+ return useMemo(() => {
27
+ if (!displayBanner) {
28
+ return {
29
+ sendBannerViewedMessage: noop,
30
+ sendBannerDismissedMessage: noop,
31
+ sendBannerLinkClickedMessage: noopLink,
32
+ };
33
+ }
34
+
35
+ const bannerUri = 'urn:redocly:realm:ui:banner:banner-id';
36
+ const payload = {
37
+ id: 'banner-id' as const,
38
+ object: 'banner' as const,
39
+ uri: bannerUri,
40
+ trackingId: displayBanner.trackingId,
41
+ hash: displayBanner.hash,
42
+ color: displayBanner.color,
43
+ target: displayBanner.target,
44
+ dismissible: displayBanner.dismissible,
45
+ };
46
+
47
+ return {
48
+ sendBannerViewedMessage: () => {
49
+ const pageUri = getCurrentPageUri();
50
+ const page = { id: pageUri, object: 'page' as const, uri: pageUri };
51
+ telemetry.sendBannerViewedMessage([payload, page]);
52
+ },
53
+ sendBannerDismissedMessage: () => {
54
+ const pageUri = getCurrentPageUri();
55
+ const page = { id: pageUri, object: 'page' as const, uri: pageUri };
56
+ const { dismissible: _, ...dismissedPayload } = payload;
57
+ telemetry.sendBannerDismissedMessage([dismissedPayload, page]);
58
+ },
59
+ sendBannerLinkClickedMessage: (href: string) => {
60
+ const pageUri = getCurrentPageUri();
61
+ const page = { id: pageUri, object: 'page' as const, uri: pageUri };
62
+ telemetry.sendBannerLinkClickedMessage([{ ...payload, href }, page]);
63
+ },
64
+ };
65
+ }, [displayBanner, telemetry]);
66
+ }
@@ -70,4 +70,7 @@ export const useTelemetryFallback = () => ({
70
70
  sendGraphqlDocsReferencedInLinkClickedMessage: () => {},
71
71
  sendGraphqlDocsRequiredScopesModalOpenedMessage: () => {},
72
72
  sendGraphqlDocsDownloadDefinitionClickedMessage: () => {},
73
+ sendBannerViewedMessage: () => {},
74
+ sendBannerLinkClickedMessage: () => {},
75
+ sendBannerDismissedMessage: () => {},
73
76
  });
@@ -161,7 +161,6 @@ export type TranslationKey =
161
161
  | 'catalog.entity.properties.apiDescription.title'
162
162
  | 'catalog.backToAllLabel'
163
163
  | 'catalog.notConnected'
164
- | 'catalog.tags.more'
165
164
  | 'catalog.tags.label'
166
165
  | 'catalog.sort'
167
166
  | 'catalog.catalogs.label'
@@ -106,10 +106,11 @@ export type SearchAiMessageResource = {
106
106
  };
107
107
 
108
108
  export type ToolCall = {
109
+ id: string;
109
110
  name: string;
110
111
  args: unknown;
111
112
  position: number;
112
- result?: { documentCount: number };
113
+ result?: { toolCallId: string; documentCount?: number };
113
114
  };
114
115
 
115
116
  export type ContentSegment = { type: 'text'; text: string } | { type: 'tool'; toolCall: ToolCall };
@@ -128,6 +129,7 @@ export enum ToolCallName {
128
129
  SearchDocumentation = 'search_documentation',
129
130
  ListApis = 'list-apis',
130
131
  GetEndpoints = 'get-endpoints',
132
+ GetEndpointInfo = 'get-endpoint-info',
131
133
  GetSecuritySchemes = 'get-security-schemes',
132
134
  GetFullApiDescription = 'get-full-api-description',
133
135
  }
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import type { IconProps } from '@redocly/theme/icons/types';
5
+
6
+ import { getCssColorVariable } from '@redocly/theme/core/utils';
7
+
8
+ const Icon = (props: IconProps) => (
9
+ <svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
10
+ <g transform="translate(2.15065 3.876255)">
11
+ <path
12
+ d="M8.43781 0.000244141H6.64874L9.90967 8.24774H11.6987L8.43781 0.000244141ZM3.26092 0.000244141L-7.62939e-06 8.24774H1.82713L2.49962 6.52211H5.91281L6.57261 8.24774H8.39975L5.13881 0.000244141H3.26092ZM3.08329 4.9868L4.19987 2.09384L5.31645 4.9868H3.08329Z"
13
+ fill="currentColor"
14
+ />
15
+ </g>
16
+ </svg>
17
+ );
18
+
19
+ export const AnthropicIcon = styled(Icon).attrs(() => ({
20
+ 'data-component-name': 'icons/AnthropicIcon/AnthropicIcon',
21
+ }))<IconProps>`
22
+ color: ${({ color }) => getCssColorVariable(color)};
23
+ height: ${({ size }) => size || '16px'};
24
+ width: ${({ size }) => size || '16px'};
25
+ `;
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import type { IconProps } from '@redocly/theme/icons/types';
5
+
6
+ import { getCssColorVariable } from '@redocly/theme/core/utils';
7
+
8
+ const Icon = (props: IconProps) => (
9
+ <svg viewBox="0 0 10.5 12.25" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
10
+ <path d="M7 3.5H6.125V4.375H7V3.5Z" fill="currentColor" />
11
+ <path d="M4.375 3.5H3.5V4.375H4.375V3.5Z" fill="currentColor" />
12
+ <path
13
+ d="M9.625 7.875H7.4375V7H7.875C8.10698 6.99973 8.32939 6.90746 8.49342 6.74342C8.65746 6.57939 8.74973 6.35698 8.75 6.125V4.375H9.625V3.5H8.75V2.625C8.74973 2.39302 8.65746 2.17061 8.49342 2.00658C8.32939 1.84254 8.10698 1.75027 7.875 1.75H7V0H6.125V1.75H4.375V0H3.5V1.75H2.625C2.39302 1.75027 2.17061 1.84254 2.00658 2.00658C1.84254 2.17061 1.75027 2.39302 1.75 2.625V3.5H0.875V4.375H1.75V6.125C1.75027 6.35698 1.84254 6.57939 2.00658 6.74342C2.17061 6.90746 2.39302 6.99973 2.625 7H3.0625V7.875H0.875C0.643017 7.87527 0.420612 7.96754 0.256576 8.13158C0.092539 8.29561 0.000266321 8.51802 0 8.75V12.25H0.875V8.75H9.625V12.25H10.5V8.75C10.4997 8.51802 10.4075 8.29561 10.2434 8.13158C10.0794 7.96754 9.85698 7.87527 9.625 7.875ZM2.625 2.625H7.875V6.125H2.625V2.625ZM3.9375 7H6.5625V7.875H3.9375V7Z"
14
+ fill="currentColor"
15
+ />
16
+ </svg>
17
+ );
18
+
19
+ export const BotIcon = styled(Icon).attrs(() => ({
20
+ 'data-component-name': 'icons/BotIcon/BotIcon',
21
+ }))<IconProps>`
22
+ color: ${({ color }) => getCssColorVariable(color)};
23
+ height: ${({ size }) => size || '16px'};
24
+ width: ${({ size }) => size || '16px'};
25
+ `;
@@ -0,0 +1,265 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import type { IconProps } from '@redocly/theme/icons/types';
5
+
6
+ const Icon = (props: IconProps) => (
7
+ <svg viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
8
+ <g clipPath="url(#clip0_5333_7017)">
9
+ <mask
10
+ id="mask0_5333_7017"
11
+ style={{ maskType: 'alpha' }}
12
+ maskUnits="userSpaceOnUse"
13
+ x="0"
14
+ y="0"
15
+ width="14"
16
+ height="14"
17
+ >
18
+ <path
19
+ d="M6.98858 0.876221C7.11667 0.876221 7.22837 0.96381 7.25964 1.08813C7.3552 1.46837 7.48112 1.84033 7.63618 2.20043C8.04154 3.14225 8.59778 3.96654 9.30396 4.67271C10.0105 5.37908 10.8346 5.93532 11.7763 6.34069C12.1364 6.4957 12.5085 6.62162 12.8887 6.71723C13.0131 6.7485 13.1005 6.86001 13.1005 6.9881C13.1005 7.11618 13.0131 7.22788 12.8885 7.25915C12.5083 7.35471 12.1363 7.48063 11.7763 7.63569C10.8344 8.04106 10.0103 8.5973 9.30396 9.30348C8.59778 10.01 8.04154 10.8341 7.63618 11.7758C7.48109 12.1359 7.35511 12.508 7.25945 12.8882C7.24431 12.9487 7.20945 13.0023 7.16038 13.0406C7.11132 13.079 7.05086 13.0999 6.98858 13.1C6.8605 13.1 6.74898 13.0126 6.71772 12.8881C6.62209 12.5078 6.49611 12.1359 6.34099 11.7758C5.93581 10.8339 5.37976 10.0098 4.6732 9.30348C3.96684 8.5973 3.14274 8.04106 2.20091 7.63569C1.8408 7.48062 1.46885 7.35464 1.08862 7.25896C1.02821 7.24387 0.974561 7.20905 0.936177 7.16002C0.897792 7.11099 0.876864 7.05055 0.876709 6.98828C0.876709 6.8602 0.964299 6.74868 1.08862 6.71742C1.46887 6.6218 1.84082 6.49582 2.20091 6.34069C3.14274 5.93551 3.96702 5.37927 4.6732 4.6729C5.37957 3.96672 5.93581 3.14244 6.34117 2.20061C6.49619 1.8405 6.62211 1.46854 6.71772 1.08832C6.73278 1.02784 6.76762 0.97413 6.81669 0.935705C6.86576 0.89728 6.92626 0.876345 6.98858 0.876221Z"
20
+ fill="black"
21
+ />
22
+ <path
23
+ d="M6.98858 0.876221C7.11667 0.876221 7.22837 0.96381 7.25964 1.08813C7.3552 1.46837 7.48112 1.84033 7.63618 2.20043C8.04154 3.14225 8.59778 3.96654 9.30396 4.67271C10.0105 5.37908 10.8346 5.93532 11.7763 6.34069C12.1364 6.4957 12.5085 6.62162 12.8887 6.71723C13.0131 6.7485 13.1005 6.86001 13.1005 6.9881C13.1005 7.11618 13.0131 7.22788 12.8885 7.25915C12.5083 7.35471 12.1363 7.48063 11.7763 7.63569C10.8344 8.04106 10.0103 8.5973 9.30396 9.30348C8.59778 10.01 8.04154 10.8341 7.63618 11.7758C7.48109 12.1359 7.35511 12.508 7.25945 12.8882C7.24431 12.9487 7.20945 13.0023 7.16038 13.0406C7.11132 13.079 7.05086 13.0999 6.98858 13.1C6.8605 13.1 6.74898 13.0126 6.71772 12.8881C6.62209 12.5078 6.49611 12.1359 6.34099 11.7758C5.93581 10.8339 5.37976 10.0098 4.6732 9.30348C3.96684 8.5973 3.14274 8.04106 2.20091 7.63569C1.8408 7.48062 1.46885 7.35464 1.08862 7.25896C1.02821 7.24387 0.974561 7.20905 0.936177 7.16002C0.897792 7.11099 0.876864 7.05055 0.876709 6.98828C0.876709 6.8602 0.964299 6.74868 1.08862 6.71742C1.46887 6.6218 1.84082 6.49582 2.20091 6.34069C3.14274 5.93551 3.96702 5.37927 4.6732 4.6729C5.37957 3.96672 5.93581 3.14244 6.34117 2.20061C6.49619 1.8405 6.62211 1.46854 6.71772 1.08832C6.73278 1.02784 6.76762 0.97413 6.81669 0.935705C6.86576 0.89728 6.92626 0.876345 6.98858 0.876221Z"
24
+ fill="url(#paint0_linear_5333_7017)"
25
+ />
26
+ </mask>
27
+ <g mask="url(#mask0_5333_7017)">
28
+ <g filter="url(#filter0_f_5333_7017)">
29
+ <path
30
+ d="M-0.227015 10.4326C1.18534 10.9342 2.80867 9.99369 3.39882 8.33193C3.98897 6.67037 3.32234 4.91669 1.90998 4.41507C0.497625 3.91346 -1.1257 4.85396 -1.71604 6.51553C-2.306 8.17729 -1.63937 9.93096 -0.227015 10.4326Z"
31
+ fill="#FFE432"
32
+ />
33
+ </g>
34
+ <g filter="url(#filter1_f_5333_7017)">
35
+ <path
36
+ d="M6.04409 4.95442C7.98425 4.95442 9.55728 3.34672 9.55728 1.3638C9.55728 -0.619301 7.98443 -2.22681 6.04409 -2.22681C4.10374 -2.22681 2.53052 -0.619113 2.53052 1.3638C2.53052 3.34672 4.10355 4.95442 6.04409 4.95442Z"
37
+ fill="#FC413D"
38
+ />
39
+ </g>
40
+ <g filter="url(#filter2_f_5333_7017)">
41
+ <path
42
+ d="M4.67843 16.4367C6.70392 16.3378 8.24192 14.1304 8.11364 11.5065C7.98556 8.88254 6.23941 6.83558 4.21393 6.93466C2.18844 7.03374 0.650439 9.241 0.778715 11.8649C0.906992 14.4888 2.65295 16.5358 4.67843 16.4367Z"
43
+ fill="#00B95C"
44
+ />
45
+ </g>
46
+ <g filter="url(#filter3_f_5333_7017)">
47
+ <path
48
+ d="M4.67843 16.4367C6.70392 16.3378 8.24192 14.1304 8.11364 11.5065C7.98556 8.88254 6.23941 6.83558 4.21393 6.93466C2.18844 7.03374 0.650439 9.241 0.778715 11.8649C0.906992 14.4888 2.65295 16.5358 4.67843 16.4367Z"
49
+ fill="#00B95C"
50
+ />
51
+ </g>
52
+ <g filter="url(#filter4_f_5333_7017)">
53
+ <path
54
+ d="M6.70714 14.8494C8.40506 13.8162 8.85958 11.4634 7.72223 9.59402C6.58489 7.7245 4.28627 7.04658 2.58816 8.07957C0.890051 9.11294 0.435527 11.4658 1.57287 13.3353C2.7106 15.2047 5.00903 15.8826 6.70714 14.8494Z"
55
+ fill="#00B95C"
56
+ />
57
+ </g>
58
+ <g filter="url(#filter5_f_5333_7017)">
59
+ <path
60
+ d="M13.5707 8.97502C15.4792 8.97502 17.0265 7.48505 17.0265 5.64736C17.0265 3.80949 15.4792 2.31952 13.5707 2.31952C11.6622 2.31952 10.115 3.80949 10.115 5.64736C10.115 7.48524 11.6622 8.97502 13.5707 8.97502Z"
61
+ fill="#3186FF"
62
+ />
63
+ </g>
64
+ <g filter="url(#filter6_f_5333_7017)">
65
+ <path
66
+ d="M-1.5844 8.58873C0.17304 9.92499 2.74027 9.50587 4.1498 7.65218C5.55933 5.79867 5.27754 3.2126 3.5201 1.87634C1.76265 0.539895 -0.804385 0.959007 -2.21411 2.81271C-3.62364 4.66622 -3.34166 7.25247 -1.5844 8.58873Z"
67
+ fill="#FBBC04"
68
+ />
69
+ </g>
70
+ <g filter="url(#filter7_f_5333_7017)">
71
+ <path
72
+ d="M7.42033 10.5639C9.51777 12.006 12.2982 11.6044 13.6303 9.66653C14.9626 7.72883 14.3422 4.98906 12.2445 3.54694C10.1469 2.10444 7.36664 2.50641 6.03434 4.44393C4.70222 6.38183 5.32251 9.12159 7.42014 10.5639H7.42033Z"
73
+ fill="#3186FF"
74
+ />
75
+ </g>
76
+ <g filter="url(#filter8_f_5333_7017)">
77
+ <path
78
+ d="M11.2336 0.436156C11.7673 1.16174 11.0814 2.57221 9.70202 3.58694C8.32243 4.60166 6.77163 4.83598 6.23799 4.11059C5.70435 3.38482 6.39 1.97416 7.76939 0.959622C9.14898 -0.0550994 10.7 -0.289425 11.2334 0.435968L11.2336 0.436156Z"
79
+ fill="#749BFF"
80
+ />
81
+ </g>
82
+ <g filter="url(#filter9_f_5333_7017)">
83
+ <path
84
+ d="M6.85291 3.9097C8.98633 1.93074 9.7185 -0.748558 8.48848 -2.07465C7.25846 -3.40074 4.53169 -2.87181 2.39827 -0.892846C0.264845 1.08612 -0.467518 3.76542 0.762693 5.09151C1.99272 6.41759 4.71949 5.88867 6.85291 3.9097Z"
85
+ fill="#FC413D"
86
+ />
87
+ </g>
88
+ <g filter="url(#filter10_f_5333_7017)">
89
+ <path
90
+ d="M2.47959 11.0173C3.74766 11.9248 5.20334 12.0627 5.73114 11.3254C6.25894 10.588 5.65881 9.25455 4.39074 8.34701C3.12285 7.43947 1.66698 7.30159 1.13937 8.03885C0.611574 8.77629 1.21152 10.1097 2.47959 11.0173Z"
91
+ fill="#FFEE48"
92
+ />
93
+ </g>
94
+ </g>
95
+ </g>
96
+ <defs>
97
+ <filter
98
+ id="filter0_f_5333_7017"
99
+ x="-2.85766"
100
+ y="3.3534"
101
+ width="7.39819"
102
+ height="8.14086"
103
+ filterUnits="userSpaceOnUse"
104
+ colorInterpolationFilters="sRGB"
105
+ >
106
+ <feFlood floodOpacity="0" result="BackgroundImageFix" />
107
+ <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
108
+ <feGaussianBlur stdDeviation="0.463378" result="effect1_foregroundBlur_5333_7017" />
109
+ </filter>
110
+ <filter
111
+ id="filter1_f_5333_7017"
112
+ x="-1.94918"
113
+ y="-6.7065"
114
+ width="15.9862"
115
+ height="16.1406"
116
+ filterUnits="userSpaceOnUse"
117
+ colorInterpolationFilters="sRGB"
118
+ >
119
+ <feFlood floodOpacity="0" result="BackgroundImageFix" />
120
+ <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
121
+ <feGaussianBlur stdDeviation="2.23985" result="effect1_foregroundBlur_5333_7017" />
122
+ </filter>
123
+ <filter
124
+ id="filter2_f_5333_7017"
125
+ x="-3.03712"
126
+ y="3.12285"
127
+ width="14.9666"
128
+ height="17.1257"
129
+ filterUnits="userSpaceOnUse"
130
+ colorInterpolationFilters="sRGB"
131
+ >
132
+ <feFlood floodOpacity="0" result="BackgroundImageFix" />
133
+ <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
134
+ <feGaussianBlur stdDeviation="1.90418" result="effect1_foregroundBlur_5333_7017" />
135
+ </filter>
136
+ <filter
137
+ id="filter3_f_5333_7017"
138
+ x="-3.03712"
139
+ y="3.12285"
140
+ width="14.9666"
141
+ height="17.1257"
142
+ filterUnits="userSpaceOnUse"
143
+ colorInterpolationFilters="sRGB"
144
+ >
145
+ <feFlood floodOpacity="0" result="BackgroundImageFix" />
146
+ <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
147
+ <feGaussianBlur stdDeviation="1.90418" result="effect1_foregroundBlur_5333_7017" />
148
+ </filter>
149
+ <filter
150
+ id="filter4_f_5333_7017"
151
+ x="-2.86183"
152
+ y="3.78807"
153
+ width="15.0188"
154
+ height="15.3529"
155
+ filterUnits="userSpaceOnUse"
156
+ colorInterpolationFilters="sRGB"
157
+ >
158
+ <feFlood floodOpacity="0" result="BackgroundImageFix" />
159
+ <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
160
+ <feGaussianBlur stdDeviation="1.90418" result="effect1_foregroundBlur_5333_7017" />
161
+ </filter>
162
+ <filter
163
+ id="filter5_f_5333_7017"
164
+ x="6.49612"
165
+ y="-1.29935"
166
+ width="14.1491"
167
+ height="13.8932"
168
+ filterUnits="userSpaceOnUse"
169
+ colorInterpolationFilters="sRGB"
170
+ >
171
+ <feFlood floodOpacity="0" result="BackgroundImageFix" />
172
+ <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
173
+ <feGaussianBlur stdDeviation="1.80943" result="effect1_foregroundBlur_5333_7017" />
174
+ </filter>
175
+ <filter
176
+ id="filter6_f_5333_7017"
177
+ x="-6.39114"
178
+ y="-2.1852"
179
+ width="14.7181"
180
+ height="14.8353"
181
+ filterUnits="userSpaceOnUse"
182
+ colorInterpolationFilters="sRGB"
183
+ >
184
+ <feFlood floodOpacity="0" result="BackgroundImageFix" />
185
+ <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
186
+ <feGaussianBlur stdDeviation="1.6399" result="effect1_foregroundBlur_5333_7017" />
187
+ </filter>
188
+ <filter
189
+ id="filter7_f_5333_7017"
190
+ x="2.40345"
191
+ y="-0.247677"
192
+ width="14.8579"
193
+ height="14.606"
194
+ filterUnits="userSpaceOnUse"
195
+ colorInterpolationFilters="sRGB"
196
+ >
197
+ <feFlood floodOpacity="0" result="BackgroundImageFix" />
198
+ <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
199
+ <feGaussianBlur stdDeviation="1.46454" result="effect1_foregroundBlur_5333_7017" />
200
+ </filter>
201
+ <filter
202
+ id="filter8_f_5333_7017"
203
+ x="3.43598"
204
+ y="-2.60638"
205
+ width="10.5997"
206
+ height="9.75933"
207
+ filterUnits="userSpaceOnUse"
208
+ colorInterpolationFilters="sRGB"
209
+ >
210
+ <feFlood floodOpacity="0" result="BackgroundImageFix" />
211
+ <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
212
+ <feGaussianBlur stdDeviation="1.31045" result="effect1_foregroundBlur_5333_7017" />
213
+ </filter>
214
+ <filter
215
+ id="filter9_f_5333_7017"
216
+ x="-2.04789"
217
+ y="-5.01896"
218
+ width="13.3468"
219
+ height="13.0548"
220
+ filterUnits="userSpaceOnUse"
221
+ colorInterpolationFilters="sRGB"
222
+ >
223
+ <feFlood floodOpacity="0" result="BackgroundImageFix" />
224
+ <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
225
+ <feGaussianBlur stdDeviation="1.10683" result="effect1_foregroundBlur_5333_7017" />
226
+ </filter>
227
+ <filter
228
+ id="filter10_f_5333_7017"
229
+ x="-1.7922"
230
+ y="4.82486"
231
+ width="10.455"
232
+ height="9.71453"
233
+ filterUnits="userSpaceOnUse"
234
+ colorInterpolationFilters="sRGB"
235
+ >
236
+ <feFlood floodOpacity="0" result="BackgroundImageFix" />
237
+ <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
238
+ <feGaussianBlur stdDeviation="1.36998" result="effect1_foregroundBlur_5333_7017" />
239
+ </filter>
240
+ <linearGradient
241
+ id="paint0_linear_5333_7017"
242
+ x1="4.35148"
243
+ y1="9.05502"
244
+ x2="10.7005"
245
+ y2="3.70245"
246
+ gradientUnits="userSpaceOnUse"
247
+ >
248
+ <stop stopColor="#4893FC" />
249
+ <stop offset="0.27" stopColor="#4893FC" />
250
+ <stop offset="0.777" stopColor="#969DFF" />
251
+ <stop offset="1" stopColor="#BD99FE" />
252
+ </linearGradient>
253
+ <clipPath id="clip0_5333_7017">
254
+ <rect width="14" height="14" fill="white" />
255
+ </clipPath>
256
+ </defs>
257
+ </svg>
258
+ );
259
+
260
+ export const GeminiIcon = styled(Icon).attrs(() => ({
261
+ 'data-component-name': 'icons/GeminiIcon/GeminiIcon',
262
+ }))<IconProps>`
263
+ height: ${({ size }) => size || '16px'};
264
+ width: ${({ size }) => size || '16px'};
265
+ `;
package/src/index.ts CHANGED
@@ -293,6 +293,9 @@ export * from '@redocly/theme/icons/RabbitMQIcon/RabbitMQIcon';
293
293
  export * from '@redocly/theme/icons/CurveAutoColonIcon/CurveAutoColonIcon';
294
294
  export * from '@redocly/theme/icons/AiStarsIcon/AiStarsIcon';
295
295
  export * from '@redocly/theme/icons/AiStarsGradientIcon/AiStarsGradientIcon';
296
+ export * from '@redocly/theme/icons/BotIcon/BotIcon';
297
+ export * from '@redocly/theme/icons/AnthropicIcon/AnthropicIcon';
298
+ export * from '@redocly/theme/icons/GeminiIcon/GeminiIcon';
296
299
  export * from '@redocly/theme/icons/RedoclyIcon/RedoclyIcon';
297
300
  export * from '@redocly/theme/icons/WorkflowHierarchyIcon/WorkflowHierarchyIcon';
298
301
  export * from '@redocly/theme/icons/GenericIcon/GenericIcon';
@@ -27,7 +27,7 @@ export function PageLayout({
27
27
  const Container = styled.div`
28
28
  display: flex;
29
29
  flex-direction: row;
30
- min-height: calc(100vh - var(--navbar-height));
30
+ min-height: calc(100vh - var(--navbar-height) - var(--banner-height));
31
31
 
32
32
  @media screen and (min-width: ${breakpoints.max}) {
33
33
  max-width: var(--container-max-width);
@@ -12,8 +12,8 @@ type MarkdownLinkProps = Omit<ComponentProps<typeof Link>, 'to' | 'onClick'> & {
12
12
  export function MarkdownLink({ href, ...props }: MarkdownLinkProps): ReactElement {
13
13
  const markdownLinkContext = useContext(MarkdownLinkContext);
14
14
  const onClick = useCallback(() => {
15
- markdownLinkContext?.onMarkdownLinkClick?.();
16
- }, [markdownLinkContext]);
15
+ markdownLinkContext?.onMarkdownLinkClick?.(href);
16
+ }, [markdownLinkContext, href]);
17
17
 
18
18
  const linkProps = { ...props, languageInsensitive: true, onClick };
19
19