@redocly/theme 0.67.0 → 0.68.0-next.1
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/Buttons/ConnectMCPButton.d.ts +1 -1
- package/lib/components/Buttons/ConnectMCPButton.js +50 -17
- package/lib/components/Buttons/variables.js +3 -0
- package/lib/components/Catalog/CatalogEntities.js +2 -11
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.js +3 -16
- package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.d.ts +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +3 -9
- package/lib/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.js +1 -7
- package/lib/components/Feedback/Feedback.js +4 -1
- package/lib/components/Feedback/Reasons.js +2 -3
- package/lib/components/Menu/MenuItem.js +2 -1
- package/lib/components/Search/SearchAiDialog.js +2 -1
- package/lib/components/Search/SearchAiResponse.js +2 -1
- package/lib/components/Search/SearchTrigger.js +3 -3
- package/lib/core/constants/common.d.ts +1 -0
- package/lib/core/constants/common.js +2 -1
- package/lib/core/constants/search.d.ts +1 -0
- package/lib/core/constants/search.js +2 -1
- package/lib/core/hooks/search/use-search-dialog.js +2 -1
- package/lib/core/hooks/use-active-heading.js +5 -2
- package/lib/core/hooks/use-telemetry-fallback.d.ts +1 -1
- package/lib/core/hooks/use-telemetry-fallback.js +1 -1
- package/lib/core/styles/dark.js +11 -0
- package/lib/core/styles/global.js +36 -34
- package/lib/markdoc/components/NumberedList/NumberedItem.d.ts +25 -0
- package/lib/markdoc/components/NumberedList/NumberedItem.js +217 -0
- package/lib/markdoc/components/NumberedList/NumberedList.d.ts +5 -0
- package/lib/markdoc/components/NumberedList/NumberedList.js +28 -0
- package/lib/markdoc/components/NumberedList/variables.d.ts +1 -0
- package/lib/markdoc/components/NumberedList/variables.js +42 -0
- package/lib/markdoc/components/default.d.ts +2 -0
- package/lib/markdoc/components/default.js +2 -0
- package/lib/markdoc/default.js +4 -0
- package/lib/markdoc/tags/numbered-item.d.ts +2 -0
- package/lib/markdoc/tags/numbered-item.js +35 -0
- package/lib/markdoc/tags/numbered-list.d.ts +2 -0
- package/lib/markdoc/tags/numbered-list.js +28 -0
- package/package.json +3 -3
- package/src/components/Buttons/ConnectMCPButton.tsx +110 -63
- package/src/components/Buttons/variables.ts +3 -0
- package/src/components/Catalog/CatalogEntities.tsx +7 -11
- package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.tsx +8 -9
- package/src/components/Catalog/CatalogEntity/CatalogEntitySchema.tsx +6 -8
- package/src/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.tsx +2 -4
- package/src/components/Feedback/Feedback.tsx +11 -1
- package/src/components/Feedback/Reasons.tsx +2 -4
- package/src/components/Menu/MenuItem.tsx +5 -2
- package/src/components/Search/SearchAiDialog.tsx +1 -1
- package/src/components/Search/SearchAiResponse.tsx +1 -1
- package/src/components/Search/SearchTrigger.tsx +3 -3
- package/src/core/constants/common.ts +2 -0
- package/src/core/constants/search.ts +2 -0
- package/src/core/hooks/search/use-search-dialog.ts +2 -1
- package/src/core/hooks/use-active-heading.ts +7 -2
- package/src/core/hooks/use-telemetry-fallback.ts +1 -1
- package/src/core/styles/dark.ts +12 -0
- package/src/core/styles/global.ts +2 -0
- package/src/markdoc/components/NumberedList/NumberedItem.tsx +274 -0
- package/src/markdoc/components/NumberedList/NumberedList.tsx +37 -0
- package/src/markdoc/components/NumberedList/variables.ts +39 -0
- package/src/markdoc/components/default.ts +2 -0
- package/src/markdoc/default.ts +4 -0
- package/src/markdoc/tags/numbered-item.ts +46 -0
- package/src/markdoc/tags/numbered-list.ts +34 -0
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useState, useRef } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
5
5
|
import type { MCPOption } from '@redocly/theme/core/types';
|
|
6
6
|
|
|
7
|
-
import { Dropdown } from '@redocly/theme/components/Dropdown/Dropdown';
|
|
8
7
|
import { DropdownMenu } from '@redocly/theme/components/Dropdown/DropdownMenu';
|
|
9
8
|
import { DropdownMenuItem } from '@redocly/theme/components/Dropdown/DropdownMenuItem';
|
|
10
9
|
import { Button } from '@redocly/theme/components/Button/Button';
|
|
@@ -12,21 +11,9 @@ import { CursorIcon } from '@redocly/theme/icons/CursorIcon/CursorIcon';
|
|
|
12
11
|
import { VSCodeIcon } from '@redocly/theme/icons/VSCodeIcon/VSCodeIcon';
|
|
13
12
|
import { CopyIcon } from '@redocly/theme/icons/CopyIcon/CopyIcon';
|
|
14
13
|
import { CheckmarkFilledIcon } from '@redocly/theme/icons/CheckmarkFilledIcon/CheckmarkFilledIcon';
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
18
|
-
|
|
19
|
-
type TriggerButtonProps = {
|
|
20
|
-
text: string;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const TriggerButton = React.memo(({ text }: TriggerButtonProps): JSX.Element => {
|
|
24
|
-
return (
|
|
25
|
-
<StyledButton variant="secondary" icon={<ConnectIcon />}>
|
|
26
|
-
{text}
|
|
27
|
-
</StyledButton>
|
|
28
|
-
);
|
|
29
|
-
});
|
|
14
|
+
import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon';
|
|
15
|
+
import { ChevronUpIcon } from '@redocly/theme/icons/ChevronUpIcon/ChevronUpIcon';
|
|
16
|
+
import { useConnectMCPButton, useOutsideClick, useThemeHooks } from '@redocly/theme/core/hooks';
|
|
30
17
|
|
|
31
18
|
type MenuOption = {
|
|
32
19
|
key: MCPOption;
|
|
@@ -74,57 +61,93 @@ export function ConnectMCPButton({
|
|
|
74
61
|
placement = 'bottom',
|
|
75
62
|
alignment = 'end',
|
|
76
63
|
options = ['cursor', 'vscode', 'copy'],
|
|
77
|
-
}: ConnectMCPButtonProps): JSX.Element {
|
|
64
|
+
}: ConnectMCPButtonProps): JSX.Element | null {
|
|
78
65
|
const { useTranslate } = useThemeHooks();
|
|
79
66
|
const { translate } = useTranslate();
|
|
67
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
68
|
+
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
80
69
|
|
|
81
|
-
const { isCopied,
|
|
82
|
-
options,
|
|
83
|
-
});
|
|
70
|
+
const { isCopied, visibleOptions, handleAction } = useConnectMCPButton({ options });
|
|
84
71
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
72
|
+
useOutsideClick(wrapperRef, () => setIsOpen(false));
|
|
73
|
+
|
|
74
|
+
const menuOptions = MENU_OPTIONS.filter((option) => visibleOptions.includes(option.key));
|
|
75
|
+
const primaryOption = menuOptions[0];
|
|
76
|
+
const dropdownOptions = menuOptions.slice(1);
|
|
77
|
+
|
|
78
|
+
if (!primaryOption) return null;
|
|
79
|
+
|
|
80
|
+
const PrimaryIcon = primaryOption.icon;
|
|
81
|
+
// When copy is the primary action there is no dropdown item to show the copied state, so the
|
|
82
|
+
// primary button itself must reflect it.
|
|
83
|
+
const showPrimaryCopied = primaryOption.key === 'copy' && isCopied;
|
|
84
|
+
|
|
85
|
+
const handleMenuAction = (key: MCPOption) => {
|
|
86
|
+
handleAction(key);
|
|
87
|
+
setIsOpen(false);
|
|
88
|
+
};
|
|
89
89
|
|
|
90
90
|
return (
|
|
91
|
-
<ConnectMCPButtonWrapper data-component-name="Buttons/ConnectMCPButton">
|
|
92
|
-
<
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
91
|
+
<ConnectMCPButtonWrapper ref={wrapperRef} data-component-name="Buttons/ConnectMCPButton">
|
|
92
|
+
<SplitButtonGroup>
|
|
93
|
+
<PrimaryButton
|
|
94
|
+
variant="secondary"
|
|
95
|
+
icon={
|
|
96
|
+
showPrimaryCopied ? (
|
|
97
|
+
<CheckmarkFilledIcon color="var(--color-success-base)" />
|
|
98
|
+
) : (
|
|
99
|
+
<PrimaryIcon />
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
onClick={() => handleAction(primaryOption.key)}
|
|
103
|
+
>
|
|
104
|
+
{translate(primaryOption.titleTranslationKey, primaryOption.titleDefault)}
|
|
105
|
+
</PrimaryButton>
|
|
106
|
+
{dropdownOptions.length > 0 && (
|
|
107
|
+
<ChevronButton
|
|
108
|
+
variant="secondary"
|
|
109
|
+
aria-label={translate('page.actions.connectMcp.moreOptions', 'More options')}
|
|
110
|
+
aria-expanded={isOpen}
|
|
111
|
+
aria-haspopup="menu"
|
|
112
|
+
onClick={() => setIsOpen((prev) => !prev)}
|
|
113
|
+
>
|
|
114
|
+
{isOpen ? <ChevronUpIcon /> : <ChevronDownIcon />}
|
|
115
|
+
</ChevronButton>
|
|
116
|
+
)}
|
|
117
|
+
</SplitButtonGroup>
|
|
118
|
+
|
|
119
|
+
{isOpen && dropdownOptions.length > 0 && (
|
|
120
|
+
<DropdownWrapper $placement={placement} $alignment={alignment}>
|
|
121
|
+
<DropdownMenu>
|
|
122
|
+
{dropdownOptions.map((option) => {
|
|
123
|
+
const Icon = option.icon;
|
|
124
|
+
const showCheckmark = option.key === 'copy' && isCopied;
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<DropdownMenuItem key={option.key} onAction={() => handleMenuAction(option.key)}>
|
|
128
|
+
<MenuItemContent>
|
|
129
|
+
<MenuItemIcon>
|
|
130
|
+
{showCheckmark ? (
|
|
131
|
+
<CheckmarkFilledIcon color="var(--color-success-base)" />
|
|
132
|
+
) : (
|
|
133
|
+
<Icon />
|
|
134
|
+
)}
|
|
135
|
+
</MenuItemIcon>
|
|
136
|
+
<MenuItemText>
|
|
137
|
+
<MenuItemTitle>
|
|
138
|
+
{translate(option.titleTranslationKey, option.titleDefault)}
|
|
139
|
+
</MenuItemTitle>
|
|
140
|
+
<MenuItemDescription>
|
|
141
|
+
{translate(option.descriptionTranslationKey, option.descriptionDefault)}
|
|
142
|
+
</MenuItemDescription>
|
|
143
|
+
</MenuItemText>
|
|
144
|
+
</MenuItemContent>
|
|
145
|
+
</DropdownMenuItem>
|
|
146
|
+
);
|
|
147
|
+
})}
|
|
148
|
+
</DropdownMenu>
|
|
149
|
+
</DropdownWrapper>
|
|
150
|
+
)}
|
|
128
151
|
</ConnectMCPButtonWrapper>
|
|
129
152
|
);
|
|
130
153
|
}
|
|
@@ -134,8 +157,32 @@ const ConnectMCPButtonWrapper = styled.div`
|
|
|
134
157
|
position: relative;
|
|
135
158
|
`;
|
|
136
159
|
|
|
137
|
-
const
|
|
160
|
+
const SplitButtonGroup = styled.div`
|
|
161
|
+
display: inline-flex;
|
|
162
|
+
align-items: stretch;
|
|
163
|
+
`;
|
|
164
|
+
|
|
165
|
+
const PrimaryButton = styled(Button)`
|
|
138
166
|
--button-gap: var(--connect-mcp-button-gap);
|
|
167
|
+
border-top-right-radius: 0;
|
|
168
|
+
border-bottom-right-radius: 0;
|
|
169
|
+
`;
|
|
170
|
+
|
|
171
|
+
const ChevronButton = styled(Button)`
|
|
172
|
+
border-top-left-radius: 0;
|
|
173
|
+
border-bottom-left-radius: 0;
|
|
174
|
+
border-left: none;
|
|
175
|
+
padding-inline: var(--connect-mcp-button-chevron-padding-inline);
|
|
176
|
+
`;
|
|
177
|
+
|
|
178
|
+
const DropdownWrapper = styled.div<{ $placement?: string; $alignment?: string }>`
|
|
179
|
+
position: absolute;
|
|
180
|
+
top: ${({ $placement }) => ($placement === 'top' ? 'auto' : '100%')};
|
|
181
|
+
bottom: ${({ $placement }) => ($placement === 'top' ? '100%' : 'auto')};
|
|
182
|
+
left: ${({ $alignment }) => ($alignment === 'start' ? '0' : 'auto')};
|
|
183
|
+
right: ${({ $alignment }) => ($alignment === 'end' ? '0' : 'auto')};
|
|
184
|
+
padding-top: var(--dropdown-menu-padding-top);
|
|
185
|
+
z-index: var(--dropdown-menu-z-index);
|
|
139
186
|
`;
|
|
140
187
|
|
|
141
188
|
const MenuItemContent = styled.div`
|
|
@@ -58,6 +58,9 @@ export const connectMCPButton = css`
|
|
|
58
58
|
/* Button gap */
|
|
59
59
|
--connect-mcp-button-gap: var(--spacing-xs);
|
|
60
60
|
|
|
61
|
+
/* Chevron button */
|
|
62
|
+
--connect-mcp-button-chevron-padding-inline: var(--spacing-xs);
|
|
63
|
+
|
|
61
64
|
/* Menu item layout */
|
|
62
65
|
--connect-mcp-button-menu-item-gap: var(--spacing-sm);
|
|
63
66
|
--connect-mcp-button-menu-item-padding-block: var(--spacing-xxs);
|
|
@@ -3,11 +3,8 @@ import React, { JSX, useEffect } from 'react';
|
|
|
3
3
|
import type { CatalogEntityConfig } from '@redocly/config';
|
|
4
4
|
|
|
5
5
|
import { BffCatalogEntity, BffCatalogEntityList } from '@redocly/theme/core/types';
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
useCatalogEntities,
|
|
9
|
-
useCatalogEntityDetails,
|
|
10
|
-
} from '@redocly/theme/core/hooks';
|
|
6
|
+
import { useThemeHooks, useCatalogEntities } from '@redocly/theme/core/hooks';
|
|
7
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
11
8
|
import { ArrowDownIcon } from '@redocly/theme/icons/ArrowDownIcon/ArrowDownIcon';
|
|
12
9
|
import { CatalogCardView } from '@redocly/theme/components/Catalog/CatalogCardView/CatalogCardView';
|
|
13
10
|
import { CatalogTableView } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogTableView';
|
|
@@ -45,9 +42,6 @@ export function CatalogEntities(props: CatalogEntitiesProps): JSX.Element {
|
|
|
45
42
|
isColumnSorted,
|
|
46
43
|
} = props;
|
|
47
44
|
|
|
48
|
-
const { getEntityDetailsLink } = useCatalogEntityDetails({
|
|
49
|
-
catalogConfig,
|
|
50
|
-
});
|
|
51
45
|
const { useTelemetry, useFetchCatalogEntities } = useThemeHooks();
|
|
52
46
|
const telemetry = useTelemetry();
|
|
53
47
|
const { initialFilter } = useCatalogEntities({
|
|
@@ -76,10 +70,12 @@ export function CatalogEntities(props: CatalogEntitiesProps): JSX.Element {
|
|
|
76
70
|
if (searchQuery) {
|
|
77
71
|
telemetry.sendCatalogEntitiesListSearchResultClickedMessage([
|
|
78
72
|
{
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
...getBaseDataAttributes(
|
|
74
|
+
'catalogEntitiesListSearchResultId',
|
|
75
|
+
'catalogEntitiesListSearchResult',
|
|
76
|
+
),
|
|
82
77
|
query: searchQuery,
|
|
78
|
+
entityId: entity.id,
|
|
83
79
|
entityKey: entity.key,
|
|
84
80
|
entityType: entity.type,
|
|
85
81
|
},
|
package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.tsx
CHANGED
|
@@ -8,7 +8,8 @@ import type { BffCatalogEntity, BffCatalogRelatedEntity } from '@redocly/theme/c
|
|
|
8
8
|
import { CatalogColumn } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogTableView';
|
|
9
9
|
import { CatalogActionsRow } from '@redocly/theme/components/Catalog/CatalogActionsRow';
|
|
10
10
|
import { CatalogEntityRelationsTableContent } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTableContent';
|
|
11
|
-
import {
|
|
11
|
+
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
12
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
12
13
|
import { reverseRelationMap } from '@redocly/theme/core/constants';
|
|
13
14
|
|
|
14
15
|
export type CatalogEntityRelationsTableProps = {
|
|
@@ -51,22 +52,20 @@ export function CatalogEntityRelationsTable({
|
|
|
51
52
|
}: CatalogEntityRelationsTableProps): JSX.Element {
|
|
52
53
|
const { useTelemetry } = useThemeHooks();
|
|
53
54
|
const telemetry = useTelemetry();
|
|
54
|
-
const { getEntityDetailsLink } = useCatalogEntityDetails({
|
|
55
|
-
catalogConfig,
|
|
56
|
-
entitiesCatalogConfig,
|
|
57
|
-
});
|
|
58
55
|
|
|
59
56
|
const onRowClick = (relatedEntity: BffCatalogRelatedEntity) => {
|
|
60
57
|
if (searchQuery) {
|
|
61
|
-
telemetry.
|
|
58
|
+
telemetry.sendCatalogEntitiesRelatedEntitiesListSearchResultClickedMessage([
|
|
62
59
|
{
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
...getBaseDataAttributes(
|
|
61
|
+
'catalogEntitiesRelatedEntitiesListSearchResultId',
|
|
62
|
+
'catalogEntitiesRelatedEntitiesListSearchResult',
|
|
63
|
+
),
|
|
66
64
|
query: searchQuery,
|
|
67
65
|
entityKey: entity.key,
|
|
68
66
|
entityType: entity.type,
|
|
69
67
|
relationType: reverseRelationMap[relatedEntity.relationType],
|
|
68
|
+
relatedEntityId: relatedEntity.id,
|
|
70
69
|
relatedEntityKey: relatedEntity.key,
|
|
71
70
|
relatedEntityType: relatedEntity.type,
|
|
72
71
|
},
|
|
@@ -5,8 +5,9 @@ import * as Sampler from 'openapi-sampler';
|
|
|
5
5
|
import type { CatalogEntityConfig } from '@redocly/config';
|
|
6
6
|
import type { BffCatalogEntity, BffCatalogRelatedEntity } from '@redocly/theme/core/types';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
9
9
|
import { useCatalogEntitySchema } from '@redocly/theme/core/hooks';
|
|
10
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
10
11
|
import { JsonViewer } from '@redocly/theme/components/JsonViewer/JsonViewer';
|
|
11
12
|
import { CopyButton } from '@redocly/theme/components/Buttons/CopyButton';
|
|
12
13
|
|
|
@@ -24,7 +25,6 @@ export type CatalogEntitySchemaProps = {
|
|
|
24
25
|
export function CatalogEntitySchema({
|
|
25
26
|
entity,
|
|
26
27
|
relatedEntity,
|
|
27
|
-
catalogConfig,
|
|
28
28
|
RedocSchema,
|
|
29
29
|
StoreProvider,
|
|
30
30
|
GraphqlTypeRenderer,
|
|
@@ -35,9 +35,6 @@ export function CatalogEntitySchema({
|
|
|
35
35
|
const { definition, parsedSchema, rawSchema } = useCatalogEntitySchema({ entity, relatedEntity });
|
|
36
36
|
const isGraphql = entity.metadata?.specType === 'graphql';
|
|
37
37
|
const graphqlSDL = entity?.metadata?.sdl;
|
|
38
|
-
const { getEntityDetailsLink } = useCatalogEntityDetails({
|
|
39
|
-
catalogConfig,
|
|
40
|
-
});
|
|
41
38
|
|
|
42
39
|
return (
|
|
43
40
|
<MetadataWrapper data-component-name="Catalog/CatalogEntity/CatalogEntitySchema">
|
|
@@ -54,9 +51,10 @@ export function CatalogEntitySchema({
|
|
|
54
51
|
onCopyClick={() =>
|
|
55
52
|
telemetry.sendCatalogEntitiesCopyDataSchemaClickedMessage([
|
|
56
53
|
{
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
...getBaseDataAttributes('catalogEntitiesCopyDataSchemaId', 'button'),
|
|
55
|
+
entityId: entity.id,
|
|
56
|
+
entityKey: entity.key,
|
|
57
|
+
entityType: entity.type,
|
|
60
58
|
},
|
|
61
59
|
])
|
|
62
60
|
}
|
|
@@ -12,7 +12,7 @@ import { FilterInput } from '@redocly/theme/components/Filter/FilterInput';
|
|
|
12
12
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
13
13
|
import { CheckboxIcon } from '@redocly/theme/icons/CheckboxIcon/CheckboxIcon';
|
|
14
14
|
import { CounterTag } from '@redocly/theme/components/Tags/CounterTag';
|
|
15
|
-
import { changeTextCasing } from '@redocly/theme/core/utils';
|
|
15
|
+
import { changeTextCasing, getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
16
16
|
import { Accordion } from '@redocly/theme/components/Accordion/Accordion';
|
|
17
17
|
|
|
18
18
|
export type CatalogFilterCheckboxesProps = FilterProps & {
|
|
@@ -104,9 +104,7 @@ export function CatalogFilterCheckboxes({
|
|
|
104
104
|
filter.toggleOption(value);
|
|
105
105
|
telemetry.sendCatalogEntitiesFilterCheckboxToggledMessage([
|
|
106
106
|
{
|
|
107
|
-
|
|
108
|
-
object: 'checkbox',
|
|
109
|
-
uri: window.location.href,
|
|
107
|
+
...getBaseDataAttributes('catalogEntitiesFilterCheckboxId', 'checkbox'),
|
|
110
108
|
category: filter.property,
|
|
111
109
|
value: value,
|
|
112
110
|
},
|
|
@@ -11,6 +11,7 @@ import { Comment } from '@redocly/theme/components/Feedback/Comment';
|
|
|
11
11
|
import { Mood } from '@redocly/theme/components/Feedback/Mood';
|
|
12
12
|
import { Scale } from '@redocly/theme/components/Feedback/Scale';
|
|
13
13
|
import { DEFAULT_FEEDBACK_TYPE } from '@redocly/theme/core/constants';
|
|
14
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
14
15
|
|
|
15
16
|
const feedbackComponents = {
|
|
16
17
|
rating: Rating,
|
|
@@ -58,7 +59,16 @@ export function Feedback(props: FeedbackProps & { path?: string }) {
|
|
|
58
59
|
settings={settings}
|
|
59
60
|
onSubmit={(values) => {
|
|
60
61
|
submitFeedback({ type, values, path });
|
|
61
|
-
telemetry.sendFeedbackMessage(
|
|
62
|
+
telemetry.sendFeedbackMessage([
|
|
63
|
+
{
|
|
64
|
+
...getBaseDataAttributes<
|
|
65
|
+
'feedbackFormId',
|
|
66
|
+
'feedbackForm',
|
|
67
|
+
'urn:redocly:realm:ui:feedbackForm:feedbackFormId'
|
|
68
|
+
>('feedbackFormId', 'feedbackForm'),
|
|
69
|
+
feedbackType: type,
|
|
70
|
+
},
|
|
71
|
+
]);
|
|
62
72
|
}}
|
|
63
73
|
/>
|
|
64
74
|
</FeedbackWrapper>
|
|
@@ -16,7 +16,7 @@ export type ReasonsProps = {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
export function Reasons({ settings, onChange, className }: ReasonsProps): JSX.Element | null {
|
|
19
|
-
const { label, component, items = [] } = settings;
|
|
19
|
+
const { label, component = 'checkbox', items = [] } = settings;
|
|
20
20
|
const [checkedState, setCheckedState] = React.useState(new Array(items.length).fill(false));
|
|
21
21
|
const { useTranslate } = useThemeHooks();
|
|
22
22
|
const { translate } = useTranslate();
|
|
@@ -25,8 +25,6 @@ export function Reasons({ settings, onChange, className }: ReasonsProps): JSX.El
|
|
|
25
25
|
return null;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
const input_type = component || 'checkbox';
|
|
29
|
-
|
|
30
28
|
const handleOptionChange = (position: number) => {
|
|
31
29
|
const updatedCheckedState =
|
|
32
30
|
component === 'checkbox'
|
|
@@ -53,7 +51,7 @@ export function Reasons({ settings, onChange, className }: ReasonsProps): JSX.El
|
|
|
53
51
|
{items.map((reason, idx) => (
|
|
54
52
|
<OptionWrapper key={reason}>
|
|
55
53
|
<input
|
|
56
|
-
type={
|
|
54
|
+
type={component}
|
|
57
55
|
value={reason}
|
|
58
56
|
checked={checkedState[idx]}
|
|
59
57
|
name="reasons"
|
|
@@ -10,7 +10,7 @@ import { Link } from '@redocly/theme/components/Link/Link';
|
|
|
10
10
|
import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon';
|
|
11
11
|
import { ChevronRightIcon } from '@redocly/theme/icons/ChevronRightIcon/ChevronRightIcon';
|
|
12
12
|
import { HttpTag } from '@redocly/theme/components/Tags/HttpTag';
|
|
13
|
-
import { MenuItemType } from '@redocly/theme/core/constants';
|
|
13
|
+
import { DEFAULT_LINE_POSITION, MenuItemType } from '@redocly/theme/core/constants';
|
|
14
14
|
import {
|
|
15
15
|
getBaseDataAttributes,
|
|
16
16
|
getMenuItemType,
|
|
@@ -178,7 +178,10 @@ export function MenuItem(props: React.PropsWithChildren<MenuItemProps>): JSX.Ele
|
|
|
178
178
|
</MenuItemNestedWrapper>
|
|
179
179
|
) : null}
|
|
180
180
|
{item.separatorLine ? (
|
|
181
|
-
<MenuItemSeparatorLine
|
|
181
|
+
<MenuItemSeparatorLine
|
|
182
|
+
$depth={depth}
|
|
183
|
+
$linePosition={item.linePosition ?? DEFAULT_LINE_POSITION}
|
|
184
|
+
/>
|
|
182
185
|
) : null}
|
|
183
186
|
</MenuItemWrapper>
|
|
184
187
|
);
|
|
@@ -59,7 +59,7 @@ export function SearchAiDialog({
|
|
|
59
59
|
|
|
60
60
|
const conversationEndRef = React.useRef<HTMLDivElement>(null);
|
|
61
61
|
|
|
62
|
-
const suggestions = aiAssistant?.suggestions;
|
|
62
|
+
const suggestions = aiAssistant?.suggestions ?? [];
|
|
63
63
|
|
|
64
64
|
const placeholder = isGeneratingResponse
|
|
65
65
|
? translate('search.ai.generatingResponse', 'Generating response...')
|
|
@@ -42,7 +42,7 @@ export function SearchAiResponse(props: SearchAiResponseProps): JSX.Element {
|
|
|
42
42
|
|
|
43
43
|
let responseContainer = null;
|
|
44
44
|
|
|
45
|
-
const suggestions = aiAssistant?.suggestions;
|
|
45
|
+
const suggestions = aiAssistant?.suggestions ?? [];
|
|
46
46
|
|
|
47
47
|
const hasPendingOrReceivedResponse = response || isGeneratingResponse || error;
|
|
48
48
|
if (hasPendingOrReceivedResponse) {
|
|
@@ -7,6 +7,7 @@ import { useThemeConfig, useThemeHooks } from '@redocly/theme/core/hooks';
|
|
|
7
7
|
import { Button } from '@redocly/theme/components/Button/Button';
|
|
8
8
|
import { SearchIcon } from '@redocly/theme/icons/SearchIcon/SearchIcon';
|
|
9
9
|
import { breakpoints, getUserAgent } from '@redocly/theme/core/utils';
|
|
10
|
+
import { DEFAULT_KEYBOARD_SHORTCUTS } from '@redocly/theme/core/constants';
|
|
10
11
|
|
|
11
12
|
export type SearchTriggerProps = {
|
|
12
13
|
onClick: () => void;
|
|
@@ -18,8 +19,7 @@ export function SearchTrigger({ onClick, className }: SearchTriggerProps): JSX.E
|
|
|
18
19
|
const { useTranslate } = useThemeHooks();
|
|
19
20
|
const { translate } = useTranslate();
|
|
20
21
|
|
|
21
|
-
const
|
|
22
|
-
const keyShortcuts = themeSettings?.search?.shortcuts ?? [defaultKeyShortcut];
|
|
22
|
+
const keyShortcuts = themeSettings?.search?.shortcuts ?? [DEFAULT_KEYBOARD_SHORTCUTS];
|
|
23
23
|
let mainShortcutKey: string | null | undefined = null;
|
|
24
24
|
|
|
25
25
|
if (keyShortcuts) {
|
|
@@ -52,7 +52,7 @@ export function SearchTrigger({ onClick, className }: SearchTriggerProps): JSX.E
|
|
|
52
52
|
>
|
|
53
53
|
<SearchIcon />
|
|
54
54
|
{translate('search.navbar.label', 'Search')}
|
|
55
|
-
{mainShortcutKey ===
|
|
55
|
+
{mainShortcutKey === DEFAULT_KEYBOARD_SHORTCUTS ? (
|
|
56
56
|
<span>{isMac ? '⌘K' : 'Ctrl+K'}</span>
|
|
57
57
|
) : (
|
|
58
58
|
<span>{mainShortcutKey}</span>
|
|
@@ -46,6 +46,8 @@ export const AI_SEARCH_MAX_MESSAGE_LENGTH = 45000;
|
|
|
46
46
|
|
|
47
47
|
export const SEARCH_DEBOUNCE_TIME_MS = 300;
|
|
48
48
|
|
|
49
|
+
export const DEFAULT_KEYBOARD_SHORTCUTS = '⌘+K,CTRL+K';
|
|
50
|
+
|
|
49
51
|
export const TOOL_CALL_DISPLAY_TEXT: Partial<
|
|
50
52
|
Record<string, { inProgressText: string; completedText: string }>
|
|
51
53
|
> = {
|
|
@@ -6,6 +6,7 @@ import { useThemeHooks } from '../use-theme-hooks';
|
|
|
6
6
|
import { useThemeConfig } from '../use-theme-config';
|
|
7
7
|
import { useSearchSession } from '../../contexts';
|
|
8
8
|
import { getBaseDataAttributes } from '../../utils';
|
|
9
|
+
import { DEFAULT_KEYBOARD_SHORTCUTS } from '../../constants';
|
|
9
10
|
|
|
10
11
|
export function useSearchDialog() {
|
|
11
12
|
const [isOpen, setIsOpen] = useState(false);
|
|
@@ -14,7 +15,7 @@ export function useSearchDialog() {
|
|
|
14
15
|
const { useTelemetry } = useThemeHooks();
|
|
15
16
|
const telemetry = useTelemetry();
|
|
16
17
|
const { refreshSearchSessionId } = useSearchSession();
|
|
17
|
-
const keyShortcuts = themeSettings?.search?.shortcuts ?? [
|
|
18
|
+
const keyShortcuts = themeSettings?.search?.shortcuts ?? [DEFAULT_KEYBOARD_SHORTCUTS];
|
|
18
19
|
const hotKeys = keyShortcuts?.join(',');
|
|
19
20
|
|
|
20
21
|
useEffect(() => {
|
|
@@ -64,8 +64,13 @@ export function useActiveHeading(
|
|
|
64
64
|
const headers = Array.from(allHeaders);
|
|
65
65
|
|
|
66
66
|
if (displayedHeadingsRef.current && displayedHeadingsRef.current.length > 0) {
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
// Resolve targets by id so anchors that are not headings (e.g. numbered
|
|
68
|
+
// list items with a lifted headline) can be scrolled to and tracked.
|
|
69
|
+
return displayedHeadingsRef.current
|
|
70
|
+
.map((heading) =>
|
|
71
|
+
heading?.id ? allContent.querySelector<HTMLElement>(`[id="${heading.id}"]`) : null,
|
|
72
|
+
)
|
|
73
|
+
.filter((element): element is HTMLElement => element !== null);
|
|
69
74
|
}
|
|
70
75
|
|
|
71
76
|
return headers;
|
|
@@ -8,7 +8,7 @@ export const useTelemetryFallback = () => ({
|
|
|
8
8
|
sendCatalogEntitiesCopyDataSchemaClickedMessage: () => {},
|
|
9
9
|
sendCatalogEntitiesViewModeChangedMessage: () => {},
|
|
10
10
|
sendCatalogEntitiesRelatedEntitiesListSearchQueryMessage: () => {},
|
|
11
|
-
|
|
11
|
+
sendCatalogEntitiesRelatedEntitiesListSearchResultClickedMessage: () => {},
|
|
12
12
|
sendCatalogEntitiesListSearchQueryMessage: () => {},
|
|
13
13
|
sendCatalogEntitiesListSearchResultClickedMessage: () => {},
|
|
14
14
|
sendRedirectMessage: () => {},
|
package/src/core/styles/dark.ts
CHANGED
|
@@ -60,6 +60,17 @@ const badgesDarkMode = css`
|
|
|
60
60
|
// @tokens End
|
|
61
61
|
`
|
|
62
62
|
|
|
63
|
+
const numberedListDarkMode = css`
|
|
64
|
+
/**
|
|
65
|
+
* @tokens Markdown Numbered List
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
--md-numbered-list-marker-bg-color: var(--color-warm-grey-3); // @presenter Color
|
|
69
|
+
--md-numbered-list-marker-bg-color-hover: var(--color-warm-grey-4); // @presenter Color
|
|
70
|
+
|
|
71
|
+
// @tokens End
|
|
72
|
+
`
|
|
73
|
+
|
|
63
74
|
|
|
64
75
|
export const darkMode = css`
|
|
65
76
|
/* === Dark Theme Colors === */
|
|
@@ -352,6 +363,7 @@ export const darkMode = css`
|
|
|
352
363
|
${bannerDarkMode}
|
|
353
364
|
${admonitionDarkMode}
|
|
354
365
|
${badgesDarkMode}
|
|
366
|
+
${numberedListDarkMode}
|
|
355
367
|
${activeBrandPaletteDark}
|
|
356
368
|
${codeBlockDarkMode}
|
|
357
369
|
/**
|
|
@@ -29,6 +29,7 @@ import { productPicker } from '@redocly/theme/components/Product/variables';
|
|
|
29
29
|
import { markdown } from '@redocly/theme/components/Markdown/variables';
|
|
30
30
|
import { banner } from '@redocly/theme/components/Banner/variables';
|
|
31
31
|
import { markdownTabs } from '@redocly/theme/markdoc/components/Tabs/variables';
|
|
32
|
+
import { markdownNumberedList } from '@redocly/theme/markdoc/components/NumberedList/variables';
|
|
32
33
|
import { diagram } from '@redocly/theme/markdoc/components/Diagram/variables';
|
|
33
34
|
import { lastUpdated } from '@redocly/theme/components/LastUpdated/variables';
|
|
34
35
|
import { logo } from '@redocly/theme/components/Logo/variables';
|
|
@@ -1344,6 +1345,7 @@ export const styles = css<{ palette?: string }>`
|
|
|
1344
1345
|
${logo}
|
|
1345
1346
|
${markdown}
|
|
1346
1347
|
${markdownTabs}
|
|
1348
|
+
${markdownNumberedList}
|
|
1347
1349
|
${diagram}
|
|
1348
1350
|
${menu}
|
|
1349
1351
|
${mobileMenu}
|