@redocly/theme 0.67.0-next.4 → 0.67.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.
- package/lib/components/Breadcrumbs/BreadcrumbDropdown.js +2 -6
- package/lib/components/Breadcrumbs/Breadcrumbs.js +3 -18
- package/lib/components/Buttons/AIAssistantButton.js +2 -6
- package/lib/components/Buttons/EditPageButton.js +2 -1
- package/lib/components/Catalog/CatalogCardView/CatalogCard.js +1 -1
- package/lib/components/CatalogClassic/CatalogClassicActions.js +3 -1
- package/lib/components/CatalogClassic/CatalogClassicCard.js +1 -1
- package/lib/components/CatalogClassic/CatalogClassicInfoBlock.js +2 -1
- package/lib/components/Feedback/ReportDialog.js +4 -1
- package/lib/components/Filter/FilterCheckboxes.js +3 -1
- package/lib/components/Footer/FooterItem.js +1 -1
- package/lib/components/LanguagePicker/LanguagePicker.js +3 -1
- package/lib/components/Logo/Logo.js +2 -1
- package/lib/components/Menu/MenuContainer.js +1 -0
- package/lib/components/Menu/MenuItem.js +21 -7
- package/lib/components/Navbar/Navbar.js +6 -2
- package/lib/components/Navbar/NavbarItem.js +3 -1
- package/lib/components/Search/SearchDialog.js +5 -33
- package/lib/components/Search/SearchInput.js +4 -1
- package/lib/components/Search/SearchRecent.js +3 -1
- package/lib/components/SidebarActions/SidebarActions.js +10 -3
- package/lib/components/TableOfContent/TableOfContent.js +1 -1
- package/lib/components/UserMenu/LoginButton.js +2 -1
- package/lib/components/UserMenu/LogoutMenuItem.js +2 -1
- package/lib/core/constants/search.js +4 -0
- package/lib/core/hooks/search/use-search-dialog.js +7 -2
- package/lib/core/hooks/use-banner-telemetry.js +2 -11
- package/lib/core/hooks/use-color-switcher.js +2 -1
- package/lib/core/hooks/use-page-actions.js +29 -36
- package/lib/core/hooks/use-product-picker.js +14 -4
- package/lib/core/hooks/use-telemetry-fallback.d.ts +45 -37
- package/lib/core/hooks/use-telemetry-fallback.js +47 -39
- package/lib/core/styles/global.js +33 -0
- package/lib/core/types/l10n.d.ts +1 -1
- package/lib/core/types/search.d.ts +2 -1
- package/lib/core/types/search.js +1 -0
- package/lib/core/utils/index.d.ts +2 -0
- package/lib/core/utils/index.js +2 -0
- package/lib/core/utils/telemetry/generate-before-after-context.d.ts +37 -0
- package/lib/core/utils/telemetry/generate-before-after-context.js +32 -0
- package/lib/core/utils/telemetry/generate-resource-urn.d.ts +7 -0
- package/lib/core/utils/telemetry/generate-resource-urn.js +13 -0
- package/lib/core/utils/telemetry/get-base-data-attributes.d.ts +14 -0
- package/lib/core/utils/telemetry/get-base-data-attributes.js +17 -0
- package/lib/layouts/McpNotAllowed.d.ts +2 -0
- package/lib/layouts/McpNotAllowed.js +67 -0
- package/package.json +3 -3
- package/src/components/Breadcrumbs/BreadcrumbDropdown.tsx +2 -1
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +4 -4
- package/src/components/Buttons/AIAssistantButton.tsx +2 -3
- package/src/components/Buttons/EditPageButton.tsx +4 -1
- package/src/components/Catalog/CatalogCardView/CatalogCard.tsx +2 -2
- package/src/components/CatalogClassic/CatalogClassicActions.tsx +4 -2
- package/src/components/CatalogClassic/CatalogClassicCard.tsx +9 -2
- package/src/components/CatalogClassic/CatalogClassicInfoBlock.tsx +2 -1
- package/src/components/Feedback/ReportDialog.tsx +4 -1
- package/src/components/Filter/FilterCheckboxes.tsx +4 -2
- package/src/components/Footer/FooterItem.tsx +4 -2
- package/src/components/LanguagePicker/LanguagePicker.tsx +9 -2
- package/src/components/Logo/Logo.tsx +7 -1
- package/src/components/Menu/MenuContainer.tsx +1 -0
- package/src/components/Menu/MenuItem.tsx +35 -4
- package/src/components/Navbar/Navbar.tsx +7 -3
- package/src/components/Navbar/NavbarItem.tsx +7 -1
- package/src/components/Search/SearchDialog.tsx +6 -13
- package/src/components/Search/SearchInput.tsx +4 -1
- package/src/components/Search/SearchRecent.tsx +4 -2
- package/src/components/SidebarActions/SidebarActions.tsx +10 -3
- package/src/components/TableOfContent/TableOfContent.tsx +7 -2
- package/src/components/UserMenu/LoginButton.tsx +4 -1
- package/src/components/UserMenu/LogoutMenuItem.tsx +2 -1
- package/src/core/constants/search.ts +4 -0
- package/src/core/hooks/search/use-search-dialog.ts +13 -2
- package/src/core/hooks/use-banner-telemetry.ts +5 -4
- package/src/core/hooks/use-color-switcher.ts +7 -1
- package/src/core/hooks/use-page-actions.ts +38 -44
- package/src/core/hooks/use-product-picker.ts +19 -5
- package/src/core/hooks/use-telemetry-fallback.ts +47 -39
- package/src/core/styles/global.ts +33 -0
- package/src/core/types/l10n.ts +2 -0
- package/src/core/types/search.ts +1 -0
- package/src/core/utils/index.ts +2 -0
- package/src/core/utils/telemetry/generate-before-after-context.ts +59 -0
- package/src/core/utils/telemetry/generate-resource-urn.ts +9 -0
- package/src/core/utils/telemetry/get-base-data-attributes.ts +27 -0
- package/src/layouts/McpNotAllowed.tsx +81 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateResourceUrn = generateResourceUrn;
|
|
4
|
+
/**
|
|
5
|
+
* Generates a resource URN for Realm UI telemetry.
|
|
6
|
+
* @param object - The object type.
|
|
7
|
+
* @param id - The resource ID.
|
|
8
|
+
* @returns The resource URN.
|
|
9
|
+
*/
|
|
10
|
+
function generateResourceUrn(object, id) {
|
|
11
|
+
return `urn:redocly:realm:ui:${object}:${id}`;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=generate-resource-urn.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type BaseDataAttributes<T, K, U> = {
|
|
2
|
+
/** Resource identifier (e.g. UI key, or page URL when tracking navigation). */
|
|
3
|
+
id: T;
|
|
4
|
+
/** Object kind used for telemetry categorization (e.g. `'button'`, `'page'`). */
|
|
5
|
+
object: K;
|
|
6
|
+
/** Resolved URI: the optional `url` when provided, otherwise a Realm UI resource URN. */
|
|
7
|
+
uri: U;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Builds the base fields for Realm UI telemetry payloads: `id`, `object`, and `uri`.
|
|
11
|
+
* When `url` is omitted, {@link generateResourceUrn} derives `uri` as
|
|
12
|
+
* `urn:redocly:realm:ui:{object}:{id}`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getBaseDataAttributes<T, K, U>(id: T, object: K, url?: U): BaseDataAttributes<T, K, U>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getBaseDataAttributes = getBaseDataAttributes;
|
|
4
|
+
const generate_resource_urn_1 = require("./generate-resource-urn");
|
|
5
|
+
/**
|
|
6
|
+
* Builds the base fields for Realm UI telemetry payloads: `id`, `object`, and `uri`.
|
|
7
|
+
* When `url` is omitted, {@link generateResourceUrn} derives `uri` as
|
|
8
|
+
* `urn:redocly:realm:ui:{object}:{id}`.
|
|
9
|
+
*/
|
|
10
|
+
function getBaseDataAttributes(id, object, url) {
|
|
11
|
+
return {
|
|
12
|
+
id,
|
|
13
|
+
object,
|
|
14
|
+
uri: url !== null && url !== void 0 ? url : (0, generate_resource_urn_1.generateResourceUrn)(object, id),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=get-base-data-attributes.js.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = McpNotAllowed;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const styled_components_1 = __importDefault(require("styled-components"));
|
|
9
|
+
const hooks_1 = require("../core/hooks");
|
|
10
|
+
const ConnectMCPButton_1 = require("../components/Buttons/ConnectMCPButton");
|
|
11
|
+
function McpNotAllowed() {
|
|
12
|
+
const { useTranslate } = (0, hooks_1.useThemeHooks)();
|
|
13
|
+
const { translate } = useTranslate();
|
|
14
|
+
return (react_1.default.createElement(NotAllowedWrapper, { "data-component-name": "layouts/McpNotAllowed" },
|
|
15
|
+
react_1.default.createElement(StatusText, null, "405"),
|
|
16
|
+
react_1.default.createElement(Title, { "data-translation-key": "page.mcpNotAllowed.title" }, translate('page.mcpNotAllowed.title', 'Method not allowed')),
|
|
17
|
+
react_1.default.createElement(Description, { "data-translation-key": "page.mcpNotAllowed.description" }, translate('page.mcpNotAllowed.description', 'To use this MCP server, register it in your MCP Client (for example: VS Code, Cursor, or Claude Code).')),
|
|
18
|
+
react_1.default.createElement(ButtonWrapper, null,
|
|
19
|
+
react_1.default.createElement(ConnectMCPButton_1.ConnectMCPButton, { alignment: "start" }))));
|
|
20
|
+
}
|
|
21
|
+
const NotAllowedWrapper = styled_components_1.default.div `
|
|
22
|
+
height: 100%;
|
|
23
|
+
max-width: var(--page-mcp-405-max-width);
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
margin: var(--page-mcp-405-margin-vertical) var(--page-mcp-405-margin-horizontal);
|
|
28
|
+
font-family: var(--page-mcp-405-font-family);
|
|
29
|
+
gap: var(--page-mcp-405-gap);
|
|
30
|
+
|
|
31
|
+
@media (max-width: 480px) {
|
|
32
|
+
margin: var(--page-mcp-405-margin-vertical-mobile) var(--page-mcp-405-margin-horizontal-mobile);
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
const StatusText = styled_components_1.default.div `
|
|
36
|
+
color: var(--page-mcp-405-status-text-color);
|
|
37
|
+
font-size: var(--page-mcp-405-status-font-size);
|
|
38
|
+
line-height: var(--page-mcp-405-status-line-height);
|
|
39
|
+
font-weight: var(--page-mcp-405-status-font-weight);
|
|
40
|
+
`;
|
|
41
|
+
const Title = styled_components_1.default.div `
|
|
42
|
+
font-size: var(--page-mcp-405-title-font-size);
|
|
43
|
+
line-height: var(--page-mcp-405-title-line-height);
|
|
44
|
+
font-weight: var(--page-mcp-405-title-font-weight);
|
|
45
|
+
color: var(--page-mcp-405-title-text-color);
|
|
46
|
+
|
|
47
|
+
@media (max-width: 480px) {
|
|
48
|
+
font-size: var(--page-mcp-405-title-font-size-mobile);
|
|
49
|
+
line-height: var(--page-mcp-405-title-line-height-mobile);
|
|
50
|
+
}
|
|
51
|
+
`;
|
|
52
|
+
const Description = styled_components_1.default.div `
|
|
53
|
+
color: var(--page-mcp-405-description-text-color);
|
|
54
|
+
font-size: var(--page-mcp-405-description-font-size);
|
|
55
|
+
line-height: var(--page-mcp-405-description-line-height);
|
|
56
|
+
font-weight: var(--page-mcp-405-description-font-weight);
|
|
57
|
+
|
|
58
|
+
@media (max-width: 480px) {
|
|
59
|
+
font-size: var(--page-mcp-405-description-font-size-mobile);
|
|
60
|
+
line-height: var(--page-mcp-405-description-line-height-mobile);
|
|
61
|
+
}
|
|
62
|
+
`;
|
|
63
|
+
const ButtonWrapper = styled_components_1.default.div `
|
|
64
|
+
position: relative;
|
|
65
|
+
display: inline-block;
|
|
66
|
+
`;
|
|
67
|
+
//# sourceMappingURL=McpNotAllowed.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/theme",
|
|
3
|
-
"version": "0.67.0-next.
|
|
3
|
+
"version": "0.67.0-next.6",
|
|
4
4
|
"description": "Shared UI components lib",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"theme",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"vitest": "4.1.8",
|
|
64
64
|
"vitest-when": "0.6.2",
|
|
65
65
|
"webpack": "5.105.2",
|
|
66
|
-
"@redocly/realm-asyncapi-sdk": "0.13.0-next.
|
|
66
|
+
"@redocly/realm-asyncapi-sdk": "0.13.0-next.4"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"@tanstack/react-query": "5.62.3",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"openapi-sampler": "^1.7.2",
|
|
82
82
|
"react-calendar": "5.1.0",
|
|
83
83
|
"react-date-picker": "11.0.0",
|
|
84
|
-
"@redocly/config": "0.
|
|
84
|
+
"@redocly/config": "0.50.1"
|
|
85
85
|
},
|
|
86
86
|
"scripts": {
|
|
87
87
|
"watch": "tsgo -p tsconfig.build.json && (concurrently \"tsgo -w -p tsconfig.build.json\" \"tsc-alias -w -p tsconfig.build.json\")",
|
|
@@ -12,6 +12,7 @@ import { Tooltip } from '@redocly/theme/components/Tooltip/Tooltip';
|
|
|
12
12
|
import { GenericIcon } from '@redocly/theme/icons/GenericIcon/GenericIcon';
|
|
13
13
|
import { BREADCRUMB_MAX_LENGTH } from '@redocly/theme/core/constants';
|
|
14
14
|
import { BreadcrumbIcon } from '@redocly/theme/components/Breadcrumbs/BreadcrumbIcon';
|
|
15
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
15
16
|
|
|
16
17
|
type BreadcrumbDropdownProps = {
|
|
17
18
|
children?: React.ReactNode;
|
|
@@ -81,7 +82,7 @@ export function BreadcrumbDropdown({
|
|
|
81
82
|
onItemClick?.(item, index);
|
|
82
83
|
telemetry.sendBreadcrumbClickedMessage([
|
|
83
84
|
{
|
|
84
|
-
|
|
85
|
+
...getBaseDataAttributes('breadcrumbId', 'breadcrumb'),
|
|
85
86
|
link: item.link,
|
|
86
87
|
position: index + 1,
|
|
87
88
|
totalBreadcrumbs: items.length,
|
|
@@ -8,7 +8,7 @@ import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
|
8
8
|
import { Breadcrumb } from '@redocly/theme/components/Breadcrumbs/Breadcrumb';
|
|
9
9
|
import { BreadcrumbDropdown } from '@redocly/theme/components/Breadcrumbs/BreadcrumbDropdown';
|
|
10
10
|
import { BreadcrumbIcon } from '@redocly/theme/components/Breadcrumbs/BreadcrumbIcon';
|
|
11
|
-
import { trimText } from '@redocly/theme/core/utils';
|
|
11
|
+
import { trimText, getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
12
12
|
import { BREADCRUMB_MAX_LENGTH } from '@redocly/theme/core/constants';
|
|
13
13
|
|
|
14
14
|
export function Breadcrumbs(props: {
|
|
@@ -68,7 +68,7 @@ export function Breadcrumbs(props: {
|
|
|
68
68
|
onItemClick={(item, itemIdx) =>
|
|
69
69
|
telemetry.sendBreadcrumbClickedMessage([
|
|
70
70
|
{
|
|
71
|
-
|
|
71
|
+
...getBaseDataAttributes('breadcrumbId', 'breadcrumb'),
|
|
72
72
|
link: item.link,
|
|
73
73
|
position: itemIdx + 1,
|
|
74
74
|
totalBreadcrumbs: siblingsWithActive.length,
|
|
@@ -91,7 +91,7 @@ export function Breadcrumbs(props: {
|
|
|
91
91
|
onClick={() =>
|
|
92
92
|
telemetry.sendBreadcrumbClickedMessage([
|
|
93
93
|
{
|
|
94
|
-
|
|
94
|
+
...getBaseDataAttributes('breadcrumbId', 'breadcrumb'),
|
|
95
95
|
link: breadcrumb.link,
|
|
96
96
|
position: idx + 1,
|
|
97
97
|
totalBreadcrumbs: breadcrumbs.length,
|
|
@@ -119,7 +119,7 @@ export function Breadcrumbs(props: {
|
|
|
119
119
|
onItemClick={(item, itemIdx) =>
|
|
120
120
|
telemetry.sendBreadcrumbClickedMessage([
|
|
121
121
|
{
|
|
122
|
-
|
|
122
|
+
...getBaseDataAttributes('breadcrumbId', 'breadcrumb'),
|
|
123
123
|
link: item.link,
|
|
124
124
|
position: itemIdx + 1,
|
|
125
125
|
totalBreadcrumbs: breadcrumbs.length,
|
|
@@ -9,6 +9,7 @@ import { ChatIcon } from '@redocly/theme/icons/ChatIcon/ChatIcon';
|
|
|
9
9
|
import { AiStarsGradientIcon } from '@redocly/theme/icons/AiStarsGradientIcon/AiStarsGradientIcon';
|
|
10
10
|
import { RedoclyIcon } from '@redocly/theme/icons/RedoclyIcon/RedoclyIcon';
|
|
11
11
|
import { SearchSessionProvider } from '@redocly/theme/core/contexts';
|
|
12
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
12
13
|
|
|
13
14
|
type AIAssistantButtonIconType = 'chat' | 'sparkles' | 'redocly';
|
|
14
15
|
type AIAssistantButtonType = 'button' | 'icon';
|
|
@@ -79,9 +80,7 @@ export function AIAssistantButton() {
|
|
|
79
80
|
setIsOpen(true);
|
|
80
81
|
telemetry.sendSearchAiOpenedMessage([
|
|
81
82
|
{
|
|
82
|
-
|
|
83
|
-
object: 'search',
|
|
84
|
-
uri: 'urn:redocly:realm:ui:search:aiAssistantTriggerButton',
|
|
83
|
+
...getBaseDataAttributes('aiAssistantTriggerButton', 'search'),
|
|
85
84
|
method: 'ai_trigger_button',
|
|
86
85
|
},
|
|
87
86
|
]);
|
|
@@ -6,6 +6,7 @@ import type { JSX } from 'react';
|
|
|
6
6
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
7
7
|
import { EditIcon } from '@redocly/theme/icons/EditIcon/EditIcon';
|
|
8
8
|
import { Button } from '@redocly/theme/components/Button/Button';
|
|
9
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
9
10
|
|
|
10
11
|
export type EditPageButtonProps = {
|
|
11
12
|
to: string;
|
|
@@ -24,7 +25,9 @@ export function EditPageButton({ to }: EditPageButtonProps): JSX.Element {
|
|
|
24
25
|
variant="ghost"
|
|
25
26
|
size="small"
|
|
26
27
|
icon={<EditIcon />}
|
|
27
|
-
onClick={() =>
|
|
28
|
+
onClick={() =>
|
|
29
|
+
telemetry.sendPageEditClickedMessage([getBaseDataAttributes('pageEdit', 'button')])
|
|
30
|
+
}
|
|
28
31
|
data-translation-key="markdown.editPage.text"
|
|
29
32
|
>
|
|
30
33
|
{translate('markdown.editPage.text', 'Edit')}
|
|
@@ -11,7 +11,7 @@ import { ArrowRightIcon } from '@redocly/theme/icons/ArrowRightIcon/ArrowRightIc
|
|
|
11
11
|
import { ArrowUpRightIcon } from '@redocly/theme/icons/ArrowUpRightIcon/ArrowUpRightIcon';
|
|
12
12
|
import { CatalogTags } from '@redocly/theme/components/Catalog/CatalogTags';
|
|
13
13
|
import { CatalogEntityIcon } from '@redocly/theme/components/Catalog/CatalogEntityIcon';
|
|
14
|
-
import { getPathPrefix } from '@redocly/theme/core/utils';
|
|
14
|
+
import { getPathPrefix, getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
15
15
|
|
|
16
16
|
export type CatalogCardProps = {
|
|
17
17
|
entity: BffCatalogEntity;
|
|
@@ -31,7 +31,7 @@ export function CatalogCard({ entity, catalogConfig }: CatalogCardProps): JSX.El
|
|
|
31
31
|
window.location.assign(
|
|
32
32
|
`${pathPrefix}/catalogs/${catalogConfig.slug}/entities/${entity.key}`,
|
|
33
33
|
);
|
|
34
|
-
telemetry.sendCatalogItemClickedMessage();
|
|
34
|
+
telemetry.sendCatalogItemClickedMessage([getBaseDataAttributes('catalogItem', 'card')]);
|
|
35
35
|
}}
|
|
36
36
|
>
|
|
37
37
|
<CardContent>
|
|
@@ -4,7 +4,7 @@ import styled from 'styled-components';
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
5
5
|
import type { ResolvedFilter } from '@redocly/theme/core/types';
|
|
6
6
|
|
|
7
|
-
import { breakpoints } from '@redocly/theme/core/utils';
|
|
7
|
+
import { breakpoints, getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
8
8
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
9
9
|
import { Button } from '@redocly/theme/components/Button/Button';
|
|
10
10
|
import { FilterIcon } from '@redocly/theme/icons/FilterIcon/FilterIcon';
|
|
@@ -42,7 +42,9 @@ export function CatalogClassicActions(props: CatalogClassicActionsProps): JSX.El
|
|
|
42
42
|
iconPosition="left"
|
|
43
43
|
onClick={() => {
|
|
44
44
|
onOpenFilter();
|
|
45
|
-
telemetry.
|
|
45
|
+
telemetry.sendCatalogActionsClickedMessage([
|
|
46
|
+
getBaseDataAttributes('catalogActions', 'button'),
|
|
47
|
+
]);
|
|
46
48
|
}}
|
|
47
49
|
data-translation-key="catalog.filters.title"
|
|
48
50
|
>
|
|
@@ -4,7 +4,12 @@ import styled from 'styled-components';
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
5
5
|
import type { CatalogItem } from '@redocly/theme/core/types';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
slug,
|
|
9
|
+
capitalize,
|
|
10
|
+
getScorecardColorVariable,
|
|
11
|
+
getBaseDataAttributes,
|
|
12
|
+
} from '@redocly/theme/core/utils';
|
|
8
13
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
9
14
|
import { ArrowRightIcon } from '@redocly/theme/icons/ArrowRightIcon/ArrowRightIcon';
|
|
10
15
|
import { Link } from '@redocly/theme/components/Link/Link';
|
|
@@ -38,7 +43,9 @@ export function CatalogClassicCard({ item }: CatalogClassicCardProps): JSX.Eleme
|
|
|
38
43
|
<Link key={item.docsLink || item.link} to={item.docsLink || item.link}>
|
|
39
44
|
<StyledCard
|
|
40
45
|
data-component-name="CatalogClassic/CatalogClassicCard"
|
|
41
|
-
onClick={() =>
|
|
46
|
+
onClick={() =>
|
|
47
|
+
telemetry.sendCatalogItemClickedMessage([getBaseDataAttributes('catalogItem', 'card')])
|
|
48
|
+
}
|
|
42
49
|
>
|
|
43
50
|
<CardContent>
|
|
44
51
|
<CardTitleWrapper>
|
|
@@ -7,6 +7,7 @@ import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
|
7
7
|
import { getScorecardColorVariable } from '@redocly/theme/core/utils';
|
|
8
8
|
import { Tag } from '@redocly/theme/components/Tag/Tag';
|
|
9
9
|
import { Link } from '@redocly/theme/components/Link/Link';
|
|
10
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
10
11
|
|
|
11
12
|
export type CatalogClassicInfoBlockProps = {
|
|
12
13
|
metadata?: {
|
|
@@ -53,7 +54,7 @@ function ScorecardBadge(props: {
|
|
|
53
54
|
<Link to={slug}>
|
|
54
55
|
<Tag
|
|
55
56
|
onClick={() =>
|
|
56
|
-
telemetry.sendScorecardLinkClickedMessage([
|
|
57
|
+
telemetry.sendScorecardLinkClickedMessage([getBaseDataAttributes('scorecardLink', 'tag')])
|
|
57
58
|
}
|
|
58
59
|
withStatusDot
|
|
59
60
|
statusDotColor={`var(${colorVariable})`}
|
|
@@ -8,6 +8,7 @@ import type { SubmitFeedbackParams } from '@redocly/theme/core/types';
|
|
|
8
8
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
9
9
|
import { Comment } from '@redocly/theme/components/Feedback/Comment';
|
|
10
10
|
import { Portal } from '@redocly/theme/components/Portal/Portal';
|
|
11
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
11
12
|
|
|
12
13
|
export type ReportDialogProps = {
|
|
13
14
|
location: string;
|
|
@@ -47,7 +48,9 @@ export function ReportDialog({
|
|
|
47
48
|
path: pathname,
|
|
48
49
|
lang,
|
|
49
50
|
});
|
|
50
|
-
telemetry.sendCodeSnippetReportedMessage(
|
|
51
|
+
telemetry.sendCodeSnippetReportedMessage([
|
|
52
|
+
getBaseDataAttributes('codeSnippet', 'markdocTag'),
|
|
53
|
+
]);
|
|
51
54
|
onSubmit();
|
|
52
55
|
}}
|
|
53
56
|
isDialog={true}
|
|
@@ -11,7 +11,7 @@ import { FilterOptionLabel } from '@redocly/theme/components/Filter/FilterOption
|
|
|
11
11
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
12
12
|
import { CheckboxIcon } from '@redocly/theme/icons/CheckboxIcon/CheckboxIcon';
|
|
13
13
|
import { CounterTag } from '@redocly/theme/components/Tags/CounterTag';
|
|
14
|
-
import { changeTextCasing } from '@redocly/theme/core/utils';
|
|
14
|
+
import { changeTextCasing, getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
15
15
|
|
|
16
16
|
export function FilterCheckboxes({
|
|
17
17
|
filter,
|
|
@@ -36,7 +36,9 @@ export function FilterCheckboxes({
|
|
|
36
36
|
role="link"
|
|
37
37
|
onClick={() => {
|
|
38
38
|
filter.toggleOption(value);
|
|
39
|
-
telemetry.sendFilterCheckboxToggledMessage([
|
|
39
|
+
telemetry.sendFilterCheckboxToggledMessage([
|
|
40
|
+
getBaseDataAttributes('filterId', 'checkbox'),
|
|
41
|
+
]);
|
|
40
42
|
}}
|
|
41
43
|
>
|
|
42
44
|
<CheckboxIcon
|
|
@@ -7,7 +7,7 @@ import type { ResolvedNavItem } from '@redocly/config';
|
|
|
7
7
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
8
8
|
import { LaunchIcon } from '@redocly/theme/icons/LaunchIcon/LaunchIcon';
|
|
9
9
|
import { Link } from '@redocly/theme/components/Link/Link';
|
|
10
|
-
import { breakpoints } from '@redocly/theme/core/utils';
|
|
10
|
+
import { breakpoints, getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
11
11
|
import { GenericIcon } from '@redocly/theme/icons/GenericIcon/GenericIcon';
|
|
12
12
|
|
|
13
13
|
export type FooterItemProps = {
|
|
@@ -44,7 +44,9 @@ export function FooterItem({ item, iconsOnly, className }: FooterItemProps): JSX
|
|
|
44
44
|
external={item.external}
|
|
45
45
|
target={item.target}
|
|
46
46
|
data-testid={item.label}
|
|
47
|
-
onClick={() =>
|
|
47
|
+
onClick={() =>
|
|
48
|
+
telemetry.sendFooterItemClickedMessage([getBaseDataAttributes('footerItem', 'footer')])
|
|
49
|
+
}
|
|
48
50
|
data-translation-key={item.labelTranslationKey}
|
|
49
51
|
>
|
|
50
52
|
{hasIcon ? (
|
|
@@ -4,7 +4,7 @@ import styled from 'styled-components';
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
5
5
|
|
|
6
6
|
import { DropdownMenu } from '@redocly/theme/components/Dropdown/DropdownMenu';
|
|
7
|
-
import { breakpoints } from '@redocly/theme/core/utils';
|
|
7
|
+
import { breakpoints, generateBeforeAfterContext } from '@redocly/theme/core/utils';
|
|
8
8
|
import { useLanguagePicker, useThemeHooks } from '@redocly/theme/core/hooks';
|
|
9
9
|
import { GlobalOutlinedIcon } from '@redocly/theme/icons/GlobalOutlinedIcon/GlobalOutlinedIcon';
|
|
10
10
|
import { Button } from '@redocly/theme/components/Button/Button';
|
|
@@ -41,7 +41,14 @@ export function LanguagePicker(props: LanguagePickerProps): JSX.Element | null {
|
|
|
41
41
|
languageInsensitive: true,
|
|
42
42
|
onAction: () => {
|
|
43
43
|
props.onChangeLanguage(locale.code);
|
|
44
|
-
telemetry.
|
|
44
|
+
telemetry.sendLanguagePickerChangedMessage([
|
|
45
|
+
...generateBeforeAfterContext<'sendLanguagePickerChangedMessage'>(
|
|
46
|
+
'languagePicker',
|
|
47
|
+
'dropdown',
|
|
48
|
+
{ locale: currentLocale.code },
|
|
49
|
+
{ locale: locale.code },
|
|
50
|
+
),
|
|
51
|
+
]);
|
|
45
52
|
},
|
|
46
53
|
active: locale.code === currentLocale.code,
|
|
47
54
|
suffix: locale.code === currentLocale.code && <CheckmarkIcon />,
|
|
@@ -7,6 +7,7 @@ import type { LogoConfig } from '@redocly/theme/core/types';
|
|
|
7
7
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
8
8
|
import { Link } from '@redocly/theme/components/Link/Link';
|
|
9
9
|
import { Image } from '@redocly/theme/components/Image/Image';
|
|
10
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
10
11
|
|
|
11
12
|
export type LogoProps = {
|
|
12
13
|
config: LogoConfig;
|
|
@@ -27,7 +28,12 @@ export function Logo({ config, className, ...otherProps }: LogoProps): JSX.Eleme
|
|
|
27
28
|
return (
|
|
28
29
|
<LogoWrapper data-component-name="Logo/Logo" className={className} {...otherProps}>
|
|
29
30
|
{config.link ? (
|
|
30
|
-
<Link
|
|
31
|
+
<Link
|
|
32
|
+
to={config.link}
|
|
33
|
+
onClick={() =>
|
|
34
|
+
telemetry.sendLogoClickedMessage([getBaseDataAttributes('logo', 'navbar')])
|
|
35
|
+
}
|
|
36
|
+
>
|
|
31
37
|
{image}
|
|
32
38
|
</Link>
|
|
33
39
|
) : (
|
|
@@ -67,6 +67,7 @@ const MenuContainerComponent = styled.div.attrs<{
|
|
|
67
67
|
animation-timing-function: ease;
|
|
68
68
|
position: relative;
|
|
69
69
|
overflow-y: auto;
|
|
70
|
+
scrollbar-gutter: stable;
|
|
70
71
|
flex-grow: ${({ $growContent }) => ($growContent ? 1 : 0)};
|
|
71
72
|
padding-top: var(--menu-container-padding-top);
|
|
72
73
|
display: ${({ $hidden }) => ($hidden ? 'none' : 'block')};
|
|
@@ -11,7 +11,11 @@ import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDow
|
|
|
11
11
|
import { ChevronRightIcon } from '@redocly/theme/icons/ChevronRightIcon/ChevronRightIcon';
|
|
12
12
|
import { HttpTag } from '@redocly/theme/components/Tags/HttpTag';
|
|
13
13
|
import { MenuItemType } from '@redocly/theme/core/constants';
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
getBaseDataAttributes,
|
|
16
|
+
getMenuItemType,
|
|
17
|
+
getOperationColor,
|
|
18
|
+
} from '@redocly/theme/core/utils';
|
|
15
19
|
import { ArrowRightIcon } from '@redocly/theme/icons/ArrowRightIcon/ArrowRightIcon';
|
|
16
20
|
import { GenericIcon } from '@redocly/theme/icons/GenericIcon/GenericIcon';
|
|
17
21
|
import { Tag, ContentWrapper } from '@redocly/theme/components/Tag/Tag';
|
|
@@ -39,7 +43,7 @@ export function MenuItem(props: React.PropsWithChildren<MenuItemProps>): JSX.Ele
|
|
|
39
43
|
const handleOnClick = () => {
|
|
40
44
|
telemetry.sendSidebarItemClickedMessage([
|
|
41
45
|
{
|
|
42
|
-
|
|
46
|
+
...getBaseDataAttributes('sidebarItem', 'sidebar'),
|
|
43
47
|
label: item.label,
|
|
44
48
|
type: item.type === 'link' || item.type === 'group' ? item.type : undefined,
|
|
45
49
|
},
|
|
@@ -107,7 +111,13 @@ export function MenuItem(props: React.PropsWithChildren<MenuItemProps>): JSX.Ele
|
|
|
107
111
|
{name}
|
|
108
112
|
</SidebarTag>
|
|
109
113
|
))}
|
|
110
|
-
<
|
|
114
|
+
<MenuItemLabelText
|
|
115
|
+
$active={item.active}
|
|
116
|
+
$isSeparator={isSeparator}
|
|
117
|
+
data-text={translate(item.labelTranslationKey, item.label)}
|
|
118
|
+
>
|
|
119
|
+
{translate(item.labelTranslationKey, item.label)}
|
|
120
|
+
</MenuItemLabelText>
|
|
111
121
|
{item.badges
|
|
112
122
|
?.filter(({ position }) => position !== 'before')
|
|
113
123
|
.map(({ name, color, icon }) => (
|
|
@@ -308,7 +318,6 @@ const MenuItemLabelWrapper = styled.li<{
|
|
|
308
318
|
css`
|
|
309
319
|
color: ${$deprecated ? 'var(--menu-content-color-disabled)' : 'var(--menu-item-color-active)'};
|
|
310
320
|
background-color: var(--menu-item-bg-color-active);
|
|
311
|
-
font-weight: var(--menu-item-font-weight-active);
|
|
312
321
|
|
|
313
322
|
${ChevronDownIcon} path {
|
|
314
323
|
fill: var(--menu-item-color-active);
|
|
@@ -386,6 +395,28 @@ const MenuItemLabel = styled.span`
|
|
|
386
395
|
}
|
|
387
396
|
`;
|
|
388
397
|
|
|
398
|
+
const MenuItemLabelText = styled.span<{ $active?: boolean; $isSeparator?: boolean }>`
|
|
399
|
+
display: inline-block;
|
|
400
|
+
max-width: 100%;
|
|
401
|
+
font-weight: var(--menu-item-font-weight);
|
|
402
|
+
|
|
403
|
+
&::before {
|
|
404
|
+
content: attr(data-text);
|
|
405
|
+
display: block;
|
|
406
|
+
height: 0;
|
|
407
|
+
overflow: hidden;
|
|
408
|
+
visibility: hidden;
|
|
409
|
+
font-weight: ${({ $isSeparator }) =>
|
|
410
|
+
$isSeparator ? 'var(--menu-item-font-weight)' : 'var(--menu-item-font-weight-active)'};
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
${({ $active }) =>
|
|
414
|
+
$active &&
|
|
415
|
+
css`
|
|
416
|
+
font-weight: var(--menu-item-font-weight-active);
|
|
417
|
+
`}
|
|
418
|
+
`;
|
|
419
|
+
|
|
389
420
|
const SidebarTag = styled(Tag)<{ $bgColor?: string; icon?: React.ReactNode }>`
|
|
390
421
|
${({ $bgColor }) => $bgColor && `background-color: ${$bgColor};`} /* for backward compatibility */
|
|
391
422
|
margin-left: 0;
|
|
@@ -4,7 +4,7 @@ import styled from 'styled-components';
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
5
5
|
import type { ResolvedConfigLinks } from '@redocly/config';
|
|
6
6
|
|
|
7
|
-
import { breakpoints } from '@redocly/theme/core/utils';
|
|
7
|
+
import { breakpoints, getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
8
8
|
import { useThemeHooks, useThemeConfig, useMobileMenu } from '@redocly/theme/core/hooks';
|
|
9
9
|
import { NavbarLogo } from '@redocly/theme/components/Navbar/NavbarLogo';
|
|
10
10
|
import { NavbarMenu } from '@redocly/theme/components/Navbar/NavbarMenu';
|
|
@@ -60,11 +60,15 @@ export function Navbar({ className }: NavbarProps): JSX.Element | null {
|
|
|
60
60
|
isOpen
|
|
61
61
|
? () => {
|
|
62
62
|
closeMobileMenu();
|
|
63
|
-
telemetry.
|
|
63
|
+
telemetry.sendMobileMenuClosedMessage([
|
|
64
|
+
getBaseDataAttributes('mobileMenuClose', 'button'),
|
|
65
|
+
]);
|
|
64
66
|
}
|
|
65
67
|
: () => {
|
|
66
68
|
openMobileMenu();
|
|
67
|
-
telemetry.
|
|
69
|
+
telemetry.sendMobileMenuOpenedMessage([
|
|
70
|
+
getBaseDataAttributes('mobileMenuOpen', 'button'),
|
|
71
|
+
]);
|
|
68
72
|
}
|
|
69
73
|
}
|
|
70
74
|
icon={isOpen ? <CloseIcon /> : <MenuIcon />}
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
getPathnameForLocale,
|
|
13
13
|
withPathPrefix,
|
|
14
14
|
removeTrailingSlash,
|
|
15
|
+
getBaseDataAttributes,
|
|
15
16
|
} from '@redocly/theme/core/utils';
|
|
16
17
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
17
18
|
import { LaunchIcon } from '@redocly/theme/icons/LaunchIcon/LaunchIcon';
|
|
@@ -48,7 +49,12 @@ export function NavbarItem({ navItem, className }: NavbarItemProps): JSX.Element
|
|
|
48
49
|
$active={isActive}
|
|
49
50
|
className={className}
|
|
50
51
|
onClick={() =>
|
|
51
|
-
telemetry.sendNavbarMenuItemClickedMessage([
|
|
52
|
+
telemetry.sendNavbarMenuItemClickedMessage([
|
|
53
|
+
{
|
|
54
|
+
...getBaseDataAttributes('navbarItem', 'navbar'),
|
|
55
|
+
type: item.type,
|
|
56
|
+
},
|
|
57
|
+
])
|
|
52
58
|
}
|
|
53
59
|
external={item.external}
|
|
54
60
|
target={item.target}
|
|
@@ -7,7 +7,7 @@ import type { SearchFacetCount, SearchItemData } from '@redocly/theme/core/types
|
|
|
7
7
|
import { SearchInput } from '@redocly/theme/components/Search/SearchInput';
|
|
8
8
|
import { SearchShortcut } from '@redocly/theme/components/Search/SearchShortcut';
|
|
9
9
|
import { Button } from '@redocly/theme/components/Button/Button';
|
|
10
|
-
import { breakpoints, concatClassNames } from '@redocly/theme/core/utils';
|
|
10
|
+
import { breakpoints, concatClassNames, getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
11
11
|
import { Portal } from '@redocly/theme/components/Portal/Portal';
|
|
12
12
|
import { SearchItem } from '@redocly/theme/components/Search/SearchItem';
|
|
13
13
|
import { SearchRecent } from '@redocly/theme/components/Search/SearchRecent';
|
|
@@ -172,9 +172,8 @@ export function SearchDialog({
|
|
|
172
172
|
addSearchHistoryItem(query);
|
|
173
173
|
telemetry.sendSearchResultClickedMessage([
|
|
174
174
|
{
|
|
175
|
-
|
|
175
|
+
...getBaseDataAttributes('searchResultItem', 'search', item.document.url),
|
|
176
176
|
query: query,
|
|
177
|
-
url: item.document.url,
|
|
178
177
|
totalResults: results.length.toString(),
|
|
179
178
|
index: index.toString(),
|
|
180
179
|
searchEngine: mode,
|
|
@@ -259,9 +258,7 @@ export function SearchDialog({
|
|
|
259
258
|
}
|
|
260
259
|
telemetry.sendSearchAiOpenedMessage([
|
|
261
260
|
{
|
|
262
|
-
|
|
263
|
-
object: 'search',
|
|
264
|
-
uri: 'urn:redocly:realm:ui:search:searchAiButton',
|
|
261
|
+
...getBaseDataAttributes('searchAiButton', 'search'),
|
|
265
262
|
method: 'ai_search_button',
|
|
266
263
|
},
|
|
267
264
|
]);
|
|
@@ -355,9 +352,7 @@ export function SearchDialog({
|
|
|
355
352
|
}
|
|
356
353
|
telemetry.sendSearchAiOpenedMessage([
|
|
357
354
|
{
|
|
358
|
-
|
|
359
|
-
object: 'search',
|
|
360
|
-
uri: 'urn:redocly:realm:ui:search:searchAiInput',
|
|
355
|
+
...getBaseDataAttributes('searchAiInput', 'search'),
|
|
361
356
|
method: 'ai_search_input',
|
|
362
357
|
},
|
|
363
358
|
]);
|
|
@@ -370,9 +365,7 @@ export function SearchDialog({
|
|
|
370
365
|
}
|
|
371
366
|
telemetry.sendSearchAiOpenedMessage([
|
|
372
367
|
{
|
|
373
|
-
|
|
374
|
-
object: 'search',
|
|
375
|
-
uri: 'urn:redocly:realm:ui:search:searchAiInput',
|
|
368
|
+
...getBaseDataAttributes('searchAiInput', 'search'),
|
|
376
369
|
method: 'ai_search_input',
|
|
377
370
|
},
|
|
378
371
|
]);
|
|
@@ -474,7 +467,7 @@ export function SearchDialog({
|
|
|
474
467
|
onSelect={(query, index) => {
|
|
475
468
|
telemetry.sendSearchRecentClickedMessage([
|
|
476
469
|
{
|
|
477
|
-
|
|
470
|
+
...getBaseDataAttributes('searchRecentItem', 'search'),
|
|
478
471
|
query,
|
|
479
472
|
index: index.toString(),
|
|
480
473
|
searchSessionId,
|
|
@@ -9,6 +9,7 @@ import { Button } from '@redocly/theme/components/Button/Button';
|
|
|
9
9
|
import { useInputKeyCommands, useRecentSearches, useThemeHooks } from '@redocly/theme/core/hooks';
|
|
10
10
|
import { CloseFilledIcon } from '@redocly/theme/icons/CloseFilledIcon/CloseFilledIcon';
|
|
11
11
|
import { ChevronLeftIcon } from '@redocly/theme/icons/ChevronLeftIcon/ChevronLeftIcon';
|
|
12
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
12
13
|
|
|
13
14
|
export type SearchInputProps = {
|
|
14
15
|
placeholder?: string;
|
|
@@ -51,7 +52,9 @@ export function SearchInput({
|
|
|
51
52
|
const handleOnReset = () => {
|
|
52
53
|
onChange('');
|
|
53
54
|
addSearchHistoryItem(value);
|
|
54
|
-
telemetry.
|
|
55
|
+
telemetry.sendSearchInputResetClickedMessage([
|
|
56
|
+
getBaseDataAttributes('searchInputReset', 'search'),
|
|
57
|
+
]);
|
|
55
58
|
};
|
|
56
59
|
|
|
57
60
|
return (
|