@redocly/theme 0.59.0-next.1 → 0.59.0-next.3
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/LICENSE +7 -1
- package/lib/components/Accordion/Accordion.js +17 -7
- package/lib/components/Accordion/AccordionBody.js +17 -7
- package/lib/components/Admonition/Admonition.js +17 -7
- package/lib/components/Badge/Badge.js +17 -7
- package/lib/components/Breadcrumbs/Breadcrumb.js +17 -7
- package/lib/components/Breadcrumbs/BreadcrumbDropdown.js +17 -7
- package/lib/components/Button/Button.js +17 -7
- package/lib/components/Buttons/AIAssistantButton.js +17 -7
- package/lib/components/Buttons/CopyButton.js +17 -7
- package/lib/components/Catalog/Catalog.d.ts +6 -0
- package/lib/components/Catalog/Catalog.js +7 -6
- package/lib/components/Catalog/CatalogEntities.js +17 -7
- package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.js +17 -7
- package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.js +17 -7
- package/lib/components/Catalog/CatalogEntity/CatalogEntityMetadata.js +17 -7
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityApiDescriptionRelations.js +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations.js +17 -7
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityTeamRelations.js +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +17 -7
- package/lib/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.js +17 -7
- package/lib/components/Catalog/CatalogFilter/CatalogFilterContent.js +17 -7
- package/lib/components/Catalog/CatalogFilter/CatalogFilterDateRange.js +17 -7
- package/lib/components/Catalog/CatalogFilter/CatalogFilterSelect.js +17 -7
- package/lib/components/Catalog/CatalogSortButton.js +17 -7
- package/lib/components/Catalog/CatalogTableView/CatalogTableHeaderCell.js +17 -7
- package/lib/components/Catalog/CatalogViewModeToggle.js +17 -7
- package/lib/components/CatalogClassic/CatalogClassicActions.js +17 -7
- package/lib/components/CatalogClassic/CatalogClassicCard.js +17 -7
- package/lib/components/CatalogClassic/CatalogClassicHighlight.js +17 -7
- package/lib/components/CatalogClassic/CatalogClassicVirtualizedGroups.js +17 -7
- package/lib/components/CodeBlock/CodeBlock.js +17 -7
- package/lib/components/CodeBlock/CodeBlockContainer.js +17 -7
- package/lib/components/CodeBlock/CodeBlockTabs.js +17 -7
- package/lib/components/Dropdown/Dropdown.d.ts +16 -2
- package/lib/components/Dropdown/Dropdown.js +22 -12
- package/lib/components/Dropdown/DropdownMenuItem.js +17 -7
- package/lib/components/Feedback/Comment.js +17 -7
- package/lib/components/Feedback/Feedback.js +17 -7
- package/lib/components/Feedback/Mood.js +17 -7
- package/lib/components/Feedback/Rating.js +17 -7
- package/lib/components/Feedback/Reasons.js +17 -7
- package/lib/components/Feedback/Scale.js +17 -7
- package/lib/components/Feedback/Sentiment.js +17 -7
- package/lib/components/Feedback/Stars.js +17 -7
- package/lib/components/Filter/FilterContent.js +17 -7
- package/lib/components/Filter/FilterInput.js +17 -7
- package/lib/components/Image/Image.js +17 -7
- package/lib/components/JsonViewer/JsonViewer.js +17 -7
- package/lib/components/JsonViewer/helpers.js +17 -7
- package/lib/components/LastUpdated/LastUpdated.js +17 -7
- package/lib/components/Link/Link.js +17 -7
- package/lib/components/Markdown/Markdown.js +17 -7
- package/lib/components/Marker/Marker.js +17 -7
- package/lib/components/Menu/MenuContainer.js +17 -7
- package/lib/components/Menu/MenuItem.js +18 -8
- package/lib/components/Menu/MenuMobile.js +17 -7
- package/lib/components/Navbar/NavbarItem.js +3 -3
- package/lib/components/PageActions/PageActions.js +17 -7
- package/lib/components/PageNavigation/NextButton.js +17 -7
- package/lib/components/Panel/Panel.js +17 -7
- package/lib/components/Panel/PanelBody.js +17 -7
- package/lib/components/Search/FilterFields/SearchFilterFieldSelect.js +17 -7
- package/lib/components/Search/FilterFields/SearchFilterFieldTags.js +1 -2
- package/lib/components/Search/SearchAiConversationInput.d.ts +2 -1
- package/lib/components/Search/SearchAiConversationInput.js +28 -10
- package/lib/components/Search/SearchAiDialog.js +17 -7
- package/lib/components/Search/SearchDialog.js +23 -10
- package/lib/components/Search/SearchFilter.js +17 -7
- package/lib/components/Search/SearchGroups.js +19 -9
- package/lib/components/Search/SearchHighlight.js +17 -7
- package/lib/components/Search/SearchItem.js +17 -7
- package/lib/components/Search/SearchRecent.js +17 -7
- package/lib/components/Search/SearchShortcut.js +17 -7
- package/lib/components/Search/SearchSuggestedPages.js +17 -7
- package/lib/components/Search/SearchTrigger.js +17 -7
- package/lib/components/Search/variables.js +5 -1
- package/lib/components/Segmented/Segmented.js +17 -7
- package/lib/components/Select/Select.js +17 -7
- package/lib/components/Select/SelectInput.js +18 -8
- package/lib/components/Sidebar/Sidebar.js +17 -7
- package/lib/components/SidebarActions/styled.js +17 -7
- package/lib/components/SkipContent/SkipContent.js +17 -7
- package/lib/components/Switch/Switch.js +17 -7
- package/lib/components/TableOfContent/TableOfContent.js +17 -7
- package/lib/components/Tag/Tag.d.ts +2 -1
- package/lib/components/Tag/Tag.js +67 -18
- package/lib/components/Tag/variables.dark.js +135 -36
- package/lib/components/Tag/variables.js +78 -61
- package/lib/components/Tooltip/Tooltip.js +17 -7
- package/lib/components/VersionPicker/VersionPicker.js +17 -7
- package/lib/core/constants/search.d.ts +5 -4
- package/lib/core/constants/search.js +4 -5
- package/lib/core/contexts/CodeSnippetContext.js +17 -7
- package/lib/core/hooks/use-tabs.d.ts +3 -2
- package/lib/core/hooks/use-tabs.js +115 -57
- package/lib/core/templates/Markdown.js +17 -7
- package/lib/core/types/hooks.d.ts +6 -3
- package/lib/core/types/l10n.d.ts +1 -1
- package/lib/core/utils/download-code-walkthrough.js +17 -7
- package/lib/core/utils/get-file-icon.js +17 -7
- package/lib/icons/AiStarsIcon/AiStarsIcon.js +11 -2
- package/lib/icons/GenericIcon/GenericIcon.js +17 -7
- package/lib/icons/RedoclyIcon/RedoclyIcon.js +4 -7
- package/lib/icons/Spinner/Spinner.js +17 -7
- package/lib/index.js +17 -7
- package/lib/layouts/OIDCForbidden.js +17 -7
- package/lib/layouts/ThreePanelLayout.js +17 -7
- package/lib/markdoc/components/Cards/Cards.js +17 -7
- package/lib/markdoc/components/CodeGroup/CodeGroup.js +17 -7
- package/lib/markdoc/components/CodeWalkthrough/CodeContainer.js +17 -7
- package/lib/markdoc/components/CodeWalkthrough/CodePanel.js +17 -7
- package/lib/markdoc/components/CodeWalkthrough/CodePanelHeader.js +17 -7
- package/lib/markdoc/components/CodeWalkthrough/CodePanelPreview.js +17 -7
- package/lib/markdoc/components/CodeWalkthrough/CodePanelToolbar.js +17 -7
- package/lib/markdoc/components/CodeWalkthrough/CodeStep.js +17 -7
- package/lib/markdoc/components/CodeWalkthrough/CodeToggle.js +17 -7
- package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.js +17 -7
- package/lib/markdoc/components/CodeWalkthrough/Input.js +17 -7
- package/lib/markdoc/components/Heading/Heading.js +17 -7
- package/lib/markdoc/components/HtmlBlock/HtmlBlock.js +17 -7
- package/lib/markdoc/components/InlineSvg/InlineSvg.js +17 -7
- package/lib/markdoc/components/MarkdocExample/MarkdocExample.js +17 -7
- package/lib/markdoc/components/Tabs/TabList.d.ts +3 -1
- package/lib/markdoc/components/Tabs/TabList.js +214 -54
- package/lib/markdoc/components/Tabs/Tabs.d.ts +2 -1
- package/lib/markdoc/components/Tabs/Tabs.js +74 -19
- package/lib/markdoc/default.d.ts +104 -1
- package/lib/markdoc/default.js +17 -7
- package/package.json +6 -6
- package/src/components/Catalog/Catalog.tsx +15 -4
- package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityApiDescriptionRelations.tsx +1 -1
- package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityTeamRelations.tsx +1 -1
- package/src/components/Dropdown/Dropdown.tsx +84 -79
- package/src/components/Menu/MenuItem.tsx +1 -0
- package/src/components/Navbar/NavbarItem.tsx +6 -5
- package/src/components/Search/FilterFields/SearchFilterFieldTags.tsx +3 -3
- package/src/components/Search/SearchAiConversationInput.tsx +12 -2
- package/src/components/Search/SearchDialog.tsx +6 -3
- package/src/components/Search/SearchGroups.tsx +2 -0
- package/src/components/Search/variables.ts +5 -1
- package/src/components/Select/SelectInput.tsx +1 -0
- package/src/components/Tag/Tag.tsx +36 -20
- package/src/components/Tag/variables.dark.ts +135 -36
- package/src/components/Tag/variables.ts +78 -61
- package/src/core/constants/search.ts +8 -4
- package/src/core/hooks/use-tabs.ts +168 -86
- package/src/core/types/hooks.ts +6 -1
- package/src/core/types/l10n.ts +1 -0
- package/src/icons/AiStarsIcon/AiStarsIcon.tsx +11 -2
- package/src/icons/RedoclyIcon/RedoclyIcon.tsx +4 -22
- package/src/markdoc/components/Tabs/TabList.tsx +312 -105
- package/src/markdoc/components/Tabs/Tabs.tsx +136 -11
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/theme",
|
|
3
|
-
"version": "0.59.0-next.
|
|
3
|
+
"version": "0.59.0-next.3",
|
|
4
4
|
"description": "Shared UI components lib",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"theme",
|
|
7
7
|
"redocly"
|
|
8
8
|
],
|
|
9
9
|
"author": "team@redocly.com",
|
|
10
|
-
"license": "
|
|
10
|
+
"license": "MIT",
|
|
11
11
|
"main": "lib/index.js",
|
|
12
12
|
"types": "lib/index.d.ts",
|
|
13
13
|
"exports": {
|
|
@@ -63,10 +63,10 @@
|
|
|
63
63
|
"styled-system": "5.1.5",
|
|
64
64
|
"ts-node": "10.9.2",
|
|
65
65
|
"ts-node-dev": "2.0.0",
|
|
66
|
-
"tsc-alias": "1.8.
|
|
66
|
+
"tsc-alias": "1.8.16",
|
|
67
67
|
"tsconfig-paths": "4.2.0",
|
|
68
68
|
"tsconfig-paths-webpack-plugin": "3.5.2",
|
|
69
|
-
"typescript": "5.
|
|
69
|
+
"typescript": "5.9.3",
|
|
70
70
|
"vitest": "3.2.4",
|
|
71
71
|
"vitest-when": "0.6.2",
|
|
72
72
|
"webpack": "5.94.0"
|
|
@@ -84,10 +84,10 @@
|
|
|
84
84
|
"lodash.debounce": "^4.0.8",
|
|
85
85
|
"lodash.throttle": "4.1.1",
|
|
86
86
|
"nprogress": "0.2.0",
|
|
87
|
-
"openapi-sampler": "1.6.
|
|
87
|
+
"openapi-sampler": "1.6.2",
|
|
88
88
|
"react-calendar": "5.1.0",
|
|
89
89
|
"react-date-picker": "11.0.0",
|
|
90
|
-
"@redocly/config": "0.
|
|
90
|
+
"@redocly/config": "0.36.0",
|
|
91
91
|
"@redocly/realm-asyncapi-sdk": "0.5.0-next.0"
|
|
92
92
|
},
|
|
93
93
|
"scripts": {
|
|
@@ -20,8 +20,11 @@ import { CatalogViewModeToggle } from '@redocly/theme/components/Catalog/Catalog
|
|
|
20
20
|
import { CatalogSortButton } from '@redocly/theme/components/Catalog/CatalogSortButton';
|
|
21
21
|
import { CatalogEntities } from '@redocly/theme/components/Catalog/CatalogEntities';
|
|
22
22
|
|
|
23
|
+
type CatalogFiltersWithCounts = Record<string, { value: string; count: number }[]>;
|
|
24
|
+
|
|
23
25
|
export type CatalogProps = {
|
|
24
26
|
catalogConfig: CatalogEntityConfig;
|
|
27
|
+
filters?: CatalogFiltersWithCounts;
|
|
25
28
|
entitiesTypes: string[];
|
|
26
29
|
initialEntitiesList?: BffCatalogEntityList;
|
|
27
30
|
catalogSwitcherItems: CatalogSwitcherItem[];
|
|
@@ -29,9 +32,11 @@ export type CatalogProps = {
|
|
|
29
32
|
};
|
|
30
33
|
|
|
31
34
|
const customCatalogOptionsCasing = (str: string): string => {
|
|
32
|
-
|
|
35
|
+
const trimmedStr = str.trim();
|
|
36
|
+
if (!trimmedStr) return trimmedStr;
|
|
37
|
+
|
|
38
|
+
const words = trimmedStr.split(/[\s-_]+/);
|
|
33
39
|
|
|
34
|
-
const words = str.split(/[\s-_]+/);
|
|
35
40
|
return words
|
|
36
41
|
.map((word, index) => {
|
|
37
42
|
if (index === 0 && word.toLowerCase() === 'api') {
|
|
@@ -45,6 +50,7 @@ const customCatalogOptionsCasing = (str: string): string => {
|
|
|
45
50
|
export function Catalog(props: CatalogProps): JSX.Element {
|
|
46
51
|
const {
|
|
47
52
|
catalogConfig,
|
|
53
|
+
filters: serverFilters,
|
|
48
54
|
entitiesTypes,
|
|
49
55
|
initialEntitiesList,
|
|
50
56
|
catalogSwitcherItems,
|
|
@@ -72,7 +78,12 @@ export function Catalog(props: CatalogProps): JSX.Element {
|
|
|
72
78
|
onChangeCollapseSidebarClick,
|
|
73
79
|
layout,
|
|
74
80
|
collapsedSidebar,
|
|
75
|
-
} = useCatalog(
|
|
81
|
+
} = useCatalog(
|
|
82
|
+
catalogConfig,
|
|
83
|
+
serverFilters,
|
|
84
|
+
initialEntitiesList?.page.total || 0,
|
|
85
|
+
initialViewMode,
|
|
86
|
+
);
|
|
76
87
|
|
|
77
88
|
return (
|
|
78
89
|
<>
|
|
@@ -94,7 +105,7 @@ export function Catalog(props: CatalogProps): JSX.Element {
|
|
|
94
105
|
filters={filters}
|
|
95
106
|
filterTerm={searchQuery}
|
|
96
107
|
hideSearch={true}
|
|
97
|
-
showCounter={
|
|
108
|
+
showCounter={true}
|
|
98
109
|
filterValuesCasing={customCatalogOptionsCasing}
|
|
99
110
|
/>
|
|
100
111
|
}
|
|
@@ -46,7 +46,7 @@ export function CatalogEntityApiDescriptionRelations({
|
|
|
46
46
|
}: CatalogEntityApiDescriptionRelationsProps): JSX.Element {
|
|
47
47
|
return (
|
|
48
48
|
<div data-component-name="Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityApiDescriptionRelations">
|
|
49
|
-
<Tabs key={entity.id} size={TabsSize.MEDIUM}>
|
|
49
|
+
<Tabs key={entity.id} forceReady={relations.length > 0} size={TabsSize.MEDIUM}>
|
|
50
50
|
<TabItem
|
|
51
51
|
label="Operations"
|
|
52
52
|
icon={<MoleculesIcon />}
|
package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityTeamRelations.tsx
CHANGED
|
@@ -74,7 +74,7 @@ export function CatalogEntityTeamRelations({
|
|
|
74
74
|
}: CatalogEntityTeamRelationsProps): JSX.Element {
|
|
75
75
|
return (
|
|
76
76
|
<div data-component-name="Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityTeamRelations">
|
|
77
|
-
<Tabs size={TabsSize.MEDIUM}>
|
|
77
|
+
<Tabs forceReady={relations.length > 0} size={TabsSize.MEDIUM}>
|
|
78
78
|
<TabItem label="Members" icon={<PeopleIcon />} onClick={() => setFilter('type:user')}>
|
|
79
79
|
<CatalogEntityRelationsTable
|
|
80
80
|
key="members-table"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React, { cloneElement, useRef } from 'react';
|
|
1
|
+
import React, { cloneElement, useRef, forwardRef } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
|
-
import type { PropsWithChildren, ReactElement
|
|
4
|
+
import type { PropsWithChildren, ReactElement } from 'react';
|
|
5
5
|
|
|
6
6
|
import { useOutsideClick, useControlledState } from '@redocly/theme/core/hooks';
|
|
7
7
|
import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon';
|
|
@@ -32,84 +32,89 @@ export type DropdownProps = PropsWithChildren<{
|
|
|
32
32
|
onClose?: () => void;
|
|
33
33
|
}>;
|
|
34
34
|
|
|
35
|
-
export
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
placement={placement}
|
|
104
|
-
alignment={alignment}
|
|
105
|
-
isOpen={isOpen}
|
|
106
|
-
onClick={closeOnClick ? handleChildClick : undefined}
|
|
35
|
+
export const Dropdown = forwardRef<HTMLDivElement, DropdownProps>(
|
|
36
|
+
(
|
|
37
|
+
{
|
|
38
|
+
children,
|
|
39
|
+
className,
|
|
40
|
+
active,
|
|
41
|
+
trigger,
|
|
42
|
+
triggerEvent = 'click',
|
|
43
|
+
closeOnClick = true,
|
|
44
|
+
withArrow,
|
|
45
|
+
dataAttributes,
|
|
46
|
+
placement,
|
|
47
|
+
alignment,
|
|
48
|
+
onClick,
|
|
49
|
+
onClose,
|
|
50
|
+
},
|
|
51
|
+
ref,
|
|
52
|
+
) => {
|
|
53
|
+
const dropdownRef = useRef<HTMLDivElement | null>(null);
|
|
54
|
+
const [isOpen, setIsOpen] = useControlledState<boolean>(false, active);
|
|
55
|
+
|
|
56
|
+
const handleOpen = () => {
|
|
57
|
+
setIsOpen(true);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const handleClose = () => {
|
|
61
|
+
setIsOpen(false);
|
|
62
|
+
onClose?.();
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const handleChildClick = () => {
|
|
66
|
+
handleClose();
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const handleToggle = (event: React.UIEvent) => {
|
|
70
|
+
event.stopPropagation();
|
|
71
|
+
event.preventDefault();
|
|
72
|
+
setIsOpen(!isOpen);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const handleKeyDown = (event: React.KeyboardEvent) => {
|
|
76
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
77
|
+
handleToggle(event);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
useOutsideClick((ref as React.RefObject<HTMLElement | null>) || dropdownRef, handleClose);
|
|
82
|
+
|
|
83
|
+
const triggerChild = React.Children.only(trigger) as ReactElement<TriggerProps>;
|
|
84
|
+
|
|
85
|
+
const dropdownTrigger = cloneElement(triggerChild, {
|
|
86
|
+
onClick: triggerEvent === 'click' ? handleToggle : undefined,
|
|
87
|
+
icon: withArrow ? isOpen ? <ChevronUpIcon /> : <ChevronDownIcon /> : undefined,
|
|
88
|
+
...(withArrow ? { iconPosition: 'right' } : {}),
|
|
89
|
+
...triggerChild.props,
|
|
90
|
+
onKeyDown: triggerEvent === 'click' ? handleKeyDown : undefined,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<DropdownWrapper
|
|
95
|
+
data-component-name="Dropdown/Dropdown"
|
|
96
|
+
data-testid="dropdown"
|
|
97
|
+
{...dataAttributes}
|
|
98
|
+
className={className}
|
|
99
|
+
ref={ref || dropdownRef}
|
|
100
|
+
onPointerEnter={triggerEvent === 'hover' ? handleOpen : undefined}
|
|
101
|
+
onPointerLeave={triggerEvent === 'hover' ? handleClose : undefined}
|
|
102
|
+
onClick={onClick}
|
|
107
103
|
>
|
|
108
|
-
{
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
104
|
+
{dropdownTrigger}
|
|
105
|
+
|
|
106
|
+
<ChildrenWrapper
|
|
107
|
+
placement={placement}
|
|
108
|
+
alignment={alignment}
|
|
109
|
+
isOpen={isOpen}
|
|
110
|
+
onClick={closeOnClick ? handleChildClick : undefined}
|
|
111
|
+
>
|
|
112
|
+
{children}
|
|
113
|
+
</ChildrenWrapper>
|
|
114
|
+
</DropdownWrapper>
|
|
115
|
+
);
|
|
116
|
+
},
|
|
117
|
+
);
|
|
113
118
|
|
|
114
119
|
const DropdownWrapper = styled.div`
|
|
115
120
|
--button-gap: var(--spacing-xxs);
|
|
@@ -82,6 +82,7 @@ export function MenuItem(props: React.PropsWithChildren<MenuItemProps>): JSX.Ele
|
|
|
82
82
|
role={item.link ? 'none' : 'link'}
|
|
83
83
|
tabIndex={!item.link ? 0 : undefined}
|
|
84
84
|
data-testid="menu-item-label"
|
|
85
|
+
data-active={item.active}
|
|
85
86
|
>
|
|
86
87
|
{hasChevron ? <ChevronWrapper>{chevron}</ChevronWrapper> : null}
|
|
87
88
|
<MenuItemIcon icon={item.icon} srcSet={item.srcSet} />
|
|
@@ -34,12 +34,13 @@ export function NavbarItem({ navItem, className }: NavbarItemProps): JSX.Element
|
|
|
34
34
|
if (navItem.type !== 'link' && !navItem.items) return null;
|
|
35
35
|
|
|
36
36
|
const item = navItem as ResolvedNavLinkItem;
|
|
37
|
-
const normalizedPath =
|
|
38
|
-
(item.link && item.link !== '/' ? removeTrailingSlash(item.link) : item.link) || '';
|
|
37
|
+
const normalizedPath = (item.link ? removeTrailingSlash(item.link) : item.link) || '';
|
|
39
38
|
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
const pathWithPathPrefix = withPathPrefix(
|
|
40
|
+
getPathnameForLocale(normalizedPath, defaultLocale, currentLocale, locales),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const isActive = removeTrailingSlash(pathname) === removeTrailingSlash(pathWithPathPrefix);
|
|
43
44
|
|
|
44
45
|
const itemContent = (
|
|
45
46
|
<NavbarMenuItem
|
|
@@ -3,7 +3,7 @@ import styled from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
import type { SearchFacet, SearchFacetCount } from '@redocly/theme/core/types';
|
|
5
5
|
|
|
6
|
-
import { Tag
|
|
6
|
+
import { Tag } from '@redocly/theme/components/Tag/Tag';
|
|
7
7
|
|
|
8
8
|
type SearchFilterFieldTagsProps = {
|
|
9
9
|
className?: string;
|
|
@@ -47,6 +47,7 @@ export function SearchFilterFieldTags({
|
|
|
47
47
|
}}
|
|
48
48
|
active={active}
|
|
49
49
|
borderless
|
|
50
|
+
selectable
|
|
50
51
|
>
|
|
51
52
|
{value} {isCounterVisible && <span>{count}</span>}
|
|
52
53
|
</FilterTagWrapper>
|
|
@@ -62,9 +63,8 @@ const FilterTagsWrapper = styled.div`
|
|
|
62
63
|
gap: var(--search-filter-field-tags-gap);
|
|
63
64
|
`;
|
|
64
65
|
|
|
65
|
-
const FilterTagWrapper = styled(Tag)
|
|
66
|
+
const FilterTagWrapper = styled(Tag)`
|
|
66
67
|
text-transform: uppercase;
|
|
67
68
|
cursor: pointer;
|
|
68
|
-
${({ color }) => color && `background-color: var(--tag-operation-bg-color-${color});`}
|
|
69
69
|
margin: var(--search-filter-field-tags-tag-margin);
|
|
70
70
|
`;
|
|
@@ -13,6 +13,7 @@ type SearchAiConversationInputProps = {
|
|
|
13
13
|
isGeneratingResponse: boolean;
|
|
14
14
|
placeholder?: string;
|
|
15
15
|
className?: string;
|
|
16
|
+
disabled?: boolean;
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
export function SearchAiConversationInput({
|
|
@@ -20,6 +21,7 @@ export function SearchAiConversationInput({
|
|
|
20
21
|
onMessageSent,
|
|
21
22
|
className,
|
|
22
23
|
placeholder,
|
|
24
|
+
disabled,
|
|
23
25
|
}: SearchAiConversationInputProps): JSX.Element {
|
|
24
26
|
const { useTranslate } = useThemeHooks();
|
|
25
27
|
const { translate } = useTranslate();
|
|
@@ -36,6 +38,8 @@ export function SearchAiConversationInput({
|
|
|
36
38
|
}, [isGeneratingResponse]);
|
|
37
39
|
|
|
38
40
|
const handleSendMessage = () => {
|
|
41
|
+
if (disabled) return;
|
|
42
|
+
|
|
39
43
|
setQuery('');
|
|
40
44
|
onMessageSent(query);
|
|
41
45
|
};
|
|
@@ -46,7 +50,7 @@ export function SearchAiConversationInput({
|
|
|
46
50
|
}
|
|
47
51
|
};
|
|
48
52
|
|
|
49
|
-
const isDisabled = isGeneratingResponse || query.trim().length === 0;
|
|
53
|
+
const isDisabled = disabled || isGeneratingResponse || query.trim().length === 0;
|
|
50
54
|
|
|
51
55
|
return (
|
|
52
56
|
<SearchAiConversationInputWrapper
|
|
@@ -62,7 +66,7 @@ export function SearchAiConversationInput({
|
|
|
62
66
|
onChange={(e) => setQuery(e.target.value)}
|
|
63
67
|
onKeyUp={handleOnKeyUp}
|
|
64
68
|
value={query}
|
|
65
|
-
disabled={isGeneratingResponse}
|
|
69
|
+
disabled={disabled || isGeneratingResponse}
|
|
66
70
|
maxLength={AI_SEARCH_MAX_MESSAGE_LENGTH}
|
|
67
71
|
/>
|
|
68
72
|
|
|
@@ -111,6 +115,10 @@ const ConversationInput = styled.input`
|
|
|
111
115
|
border-color: var(--search-ai-conversation-input-border-color-focus);
|
|
112
116
|
}
|
|
113
117
|
|
|
118
|
+
&:disabled {
|
|
119
|
+
background-color: var(--search-ai-conversation-input-bg-color-disabled);
|
|
120
|
+
}
|
|
121
|
+
|
|
114
122
|
&:focus:disabled {
|
|
115
123
|
border-color: var(--search-ai-conversation-input-border-color-disabled);
|
|
116
124
|
}
|
|
@@ -126,6 +134,8 @@ const SendButton = styled(Button)`
|
|
|
126
134
|
display: flex;
|
|
127
135
|
align-items: center;
|
|
128
136
|
justify-content: center;
|
|
137
|
+
border-radius: var(--search-ai-conversation-input-send-button-border-radius);
|
|
138
|
+
padding: var(--search-ai-conversation-input-send-button-padding);
|
|
129
139
|
|
|
130
140
|
&:hover {
|
|
131
141
|
background-color: var(--search-ai-conversation-input-send-button-bg-color-hover);
|
|
@@ -48,6 +48,7 @@ export function SearchDialog({
|
|
|
48
48
|
const products = useProducts();
|
|
49
49
|
const currentProduct = useCurrentProduct();
|
|
50
50
|
const [product, setProduct] = useState(currentProduct);
|
|
51
|
+
const searchSessionId = `search-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
|
|
51
52
|
const [mode, setMode] = useState<'search' | 'ai-dialog'>(initialMode);
|
|
52
53
|
const autoSearchDisabled = mode !== 'search';
|
|
53
54
|
const {
|
|
@@ -62,7 +63,7 @@ export function SearchDialog({
|
|
|
62
63
|
advancedSearch,
|
|
63
64
|
askAi,
|
|
64
65
|
groupField,
|
|
65
|
-
} = useSearch(product?.name, autoSearchDisabled);
|
|
66
|
+
} = useSearch(product?.name, autoSearchDisabled, searchSessionId);
|
|
66
67
|
const {
|
|
67
68
|
isFilterOpen,
|
|
68
69
|
onFilterToggle,
|
|
@@ -72,7 +73,7 @@ export function SearchDialog({
|
|
|
72
73
|
onQuickFilterReset,
|
|
73
74
|
} = useSearchFilter(filter, setFilter);
|
|
74
75
|
const { addSearchHistoryItem } = useRecentSearches();
|
|
75
|
-
const aiSearch = useAiSearch({ filter });
|
|
76
|
+
const aiSearch = useAiSearch({ filter }, searchSessionId);
|
|
76
77
|
|
|
77
78
|
const searchInputRef = useRef<HTMLInputElement>(null);
|
|
78
79
|
const modalRef = useRef<HTMLDivElement>(null);
|
|
@@ -150,13 +151,14 @@ export function SearchDialog({
|
|
|
150
151
|
totalResults: results.length.toString(),
|
|
151
152
|
index: index.toString(),
|
|
152
153
|
searchEngine: mode,
|
|
154
|
+
searchSessionId,
|
|
153
155
|
});
|
|
154
156
|
onClose();
|
|
155
157
|
}}
|
|
156
158
|
/>
|
|
157
159
|
);
|
|
158
160
|
},
|
|
159
|
-
[onClose, product, products, addSearchHistoryItem, query, telemetry, mode],
|
|
161
|
+
[onClose, product, products, addSearchHistoryItem, query, telemetry, mode, searchSessionId],
|
|
160
162
|
);
|
|
161
163
|
|
|
162
164
|
const showLoadMore = useCallback(
|
|
@@ -389,6 +391,7 @@ export function SearchDialog({
|
|
|
389
391
|
telemetry.sendSearchRecentClickedMessage({
|
|
390
392
|
query,
|
|
391
393
|
index: index.toString(),
|
|
394
|
+
searchSessionId,
|
|
392
395
|
});
|
|
393
396
|
setQuery(query);
|
|
394
397
|
focusSearchInput();
|
|
@@ -45,6 +45,7 @@ export function SearchGroups({
|
|
|
45
45
|
borderless
|
|
46
46
|
active={!searchFilter.some((item) => item.isQuickFilter)}
|
|
47
47
|
onClick={() => searchFilter.some((item) => item.isQuickFilter) && onQuickFilterReset()}
|
|
48
|
+
selectable
|
|
48
49
|
>
|
|
49
50
|
All
|
|
50
51
|
</GroupTag>
|
|
@@ -61,6 +62,7 @@ export function SearchGroups({
|
|
|
61
62
|
onClick={() => handleGroupTagClick(value, facet.field, active, currentValues)}
|
|
62
63
|
active={active}
|
|
63
64
|
borderless
|
|
65
|
+
selectable
|
|
64
66
|
>
|
|
65
67
|
{value} {isCounterVisible && <span>{count}</span>}
|
|
66
68
|
</GroupTag>
|
|
@@ -171,6 +171,7 @@ export const search = css`
|
|
|
171
171
|
--search-ai-assistant-bg-color: var(--layer-color);
|
|
172
172
|
--search-ai-assistant-text-color: var(--text-color-primary);
|
|
173
173
|
--search-ai-assistant-border: 1px solid var(--border-color-primary);
|
|
174
|
+
--search-ai-assistant-message-max-width: 80%;
|
|
174
175
|
|
|
175
176
|
--search-ai-resources-gap: var(--spacing-base);
|
|
176
177
|
--search-ai-resources-title-font-weight: var(--font-weight-medium);
|
|
@@ -232,6 +233,7 @@ export const search = css`
|
|
|
232
233
|
* @tokens AI Search Conversation Input
|
|
233
234
|
*/
|
|
234
235
|
--search-ai-conversation-input-bg-color: var(--bg-color);
|
|
236
|
+
--search-ai-conversation-input-bg-color-disabled: var(--color-warm-grey-1);
|
|
235
237
|
--search-ai-conversation-input-padding: var(--spacing-sm) var(--spacing-md);
|
|
236
238
|
--search-ai-conversation-input-border: 1px solid var(--border-color-secondary);
|
|
237
239
|
--search-ai-conversation-input-border-radius: var(--border-radius-lg);
|
|
@@ -241,10 +243,12 @@ export const search = css`
|
|
|
241
243
|
--search-ai-conversation-input-border-color-disabled: var(--border-color-secondary);
|
|
242
244
|
|
|
243
245
|
--search-ai-conversation-input-send-button-right: 12px;
|
|
246
|
+
--search-ai-conversation-input-send-button-padding: 5px;
|
|
244
247
|
--search-ai-conversation-input-send-button-bg-color: var(--button-bg-color-primary);
|
|
245
248
|
--search-ai-conversation-input-send-button-bg-color-hover: var(--button-bg-color-primary-hover);
|
|
246
249
|
--search-ai-conversation-input-send-button-bg-color-disabled: var(--button-bg-color-disabled);
|
|
247
250
|
--search-ai-conversation-input-send-button-border-disabled: 1px solid var(--button-border-color-disabled);
|
|
251
|
+
--search-ai-conversation-input-send-button-border-radius: var(--border-radius);
|
|
248
252
|
|
|
249
253
|
/**
|
|
250
254
|
* @tokens AI Search Response
|
|
@@ -277,7 +281,7 @@ export const search = css`
|
|
|
277
281
|
|
|
278
282
|
--search-ai-suggestions-gap: var(--spacing-sm);
|
|
279
283
|
--search-ai-suggestions-margin-left: var(--spacing-xs);
|
|
280
|
-
--search-ai-suggestion-item-gap: var(--spacing-
|
|
284
|
+
--search-ai-suggestion-item-gap: var(--spacing-xxs);
|
|
281
285
|
|
|
282
286
|
--search-ai-suggestions-title-text-color: var(--text-color-description);
|
|
283
287
|
--search-ai-suggestions-title-font-size: var(--font-size-base);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import styled from 'styled-components';
|
|
2
|
+
import styled, { css } from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
5
5
|
|
|
@@ -56,6 +56,7 @@ export type TagProps = {
|
|
|
56
56
|
maxLength?: number;
|
|
57
57
|
textTransform?: 'uppercase' | 'lowercase' | 'capitalize' | 'none';
|
|
58
58
|
variant?: 'outline' | 'filled';
|
|
59
|
+
selectable?: boolean;
|
|
59
60
|
};
|
|
60
61
|
|
|
61
62
|
export function Tag({
|
|
@@ -75,6 +76,7 @@ export function Tag({
|
|
|
75
76
|
maxLength,
|
|
76
77
|
textTransform,
|
|
77
78
|
variant = 'filled',
|
|
79
|
+
selectable,
|
|
78
80
|
...otherProps
|
|
79
81
|
}: TagProps): JSX.Element {
|
|
80
82
|
const truncateText = (text: string, maxLen: number): string => {
|
|
@@ -152,6 +154,7 @@ export function Tag({
|
|
|
152
154
|
hasCloseButton={closable}
|
|
153
155
|
textTransform={textTransform}
|
|
154
156
|
variant={variant}
|
|
157
|
+
selectable={selectable}
|
|
155
158
|
{...otherProps}
|
|
156
159
|
>
|
|
157
160
|
{withStatusDot ? <StatusDot color={statusDotColor} /> : icon ? icon : null}
|
|
@@ -186,16 +189,28 @@ const CloseButton = styled.div`
|
|
|
186
189
|
justify-content: center;
|
|
187
190
|
align-self: stretch;
|
|
188
191
|
border-radius: 0 var(--tag-border-radius) var(--tag-border-radius) 0;
|
|
192
|
+
margin: calc(-1 * var(--tag-border-width));
|
|
193
|
+
padding: var(--tag-border-width);
|
|
189
194
|
|
|
190
195
|
&:hover {
|
|
191
196
|
background: var(--tag-close-button-bg-color-hover);
|
|
192
197
|
}
|
|
198
|
+
|
|
199
|
+
&:focus-visible {
|
|
200
|
+
background: var(--tag-close-button-bg-color-focus);
|
|
201
|
+
}
|
|
193
202
|
`;
|
|
194
203
|
|
|
195
|
-
const TagWrapper = styled.div.attrs(({ className, color, size }: TagProps) => ({
|
|
196
|
-
className:
|
|
197
|
-
|
|
198
|
-
|
|
204
|
+
const TagWrapper = styled.div.attrs(({ className, color, size, variant }: TagProps) => ({
|
|
205
|
+
className: [
|
|
206
|
+
className,
|
|
207
|
+
'tag-default',
|
|
208
|
+
color && `tag-${color}`,
|
|
209
|
+
size && `tag-size-${size}`,
|
|
210
|
+
`tag-variant-${variant || 'filled'}`,
|
|
211
|
+
]
|
|
212
|
+
.filter(Boolean)
|
|
213
|
+
.join(' '),
|
|
199
214
|
}))<
|
|
200
215
|
TagProps & {
|
|
201
216
|
hasCloseButton?: boolean;
|
|
@@ -227,12 +242,11 @@ const TagWrapper = styled.div.attrs(({ className, color, size }: TagProps) => ({
|
|
|
227
242
|
`text-transform: ${textTransform ? `${textTransform}` : 'var(--tag-text-transform)'};`}
|
|
228
243
|
|
|
229
244
|
color: var(--tag-color);
|
|
230
|
-
background-color:
|
|
231
|
-
|
|
232
|
-
${({ borderless, variant }) =>
|
|
245
|
+
background-color: var(--tag-bg-color);
|
|
246
|
+
${({ borderless }) =>
|
|
233
247
|
borderless
|
|
234
248
|
? ''
|
|
235
|
-
: `border: var(--tag-border-width) var(--tag-border-style)
|
|
249
|
+
: `border: var(--tag-border-width) var(--tag-border-style) var(--tag-border-color);`}
|
|
236
250
|
border-radius: var(--tag-border-radius);
|
|
237
251
|
|
|
238
252
|
svg {
|
|
@@ -240,18 +254,20 @@ const TagWrapper = styled.div.attrs(({ className, color, size }: TagProps) => ({
|
|
|
240
254
|
height: var(--tag-icon-height);
|
|
241
255
|
}
|
|
242
256
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
257
|
+
${({ selectable }) =>
|
|
258
|
+
selectable &&
|
|
259
|
+
css`
|
|
260
|
+
&:hover {
|
|
261
|
+
background-color: var(--tag-bg-color-hover);
|
|
262
|
+
border-color: var(--tag-border-color-hover);
|
|
263
|
+
}
|
|
249
264
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
265
|
+
&:focus-visible {
|
|
266
|
+
outline: 1px solid var(--tag-border-color-focused);
|
|
267
|
+
outline-offset: 2px;
|
|
268
|
+
border-radius: var(--tag-border-radius-focused);
|
|
269
|
+
}
|
|
270
|
+
`};
|
|
255
271
|
`;
|
|
256
272
|
|
|
257
273
|
const StatusDot = styled.div<{ color: string }>`
|