@redocly/theme 0.70.0-next.4 → 0.70.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/Buttons/ConnectMCPButton.js +8 -13
- package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.d.ts +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.js +1 -1
- package/lib/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.js +30 -11
- package/lib/components/Catalog/CatalogFilter/CatalogFilterDateRange.js +2 -1
- package/lib/components/Dropdown/Dropdown.d.ts +4 -2
- package/lib/components/Dropdown/Dropdown.js +28 -8
- package/lib/components/Dropdown/DropdownMenu.d.ts +1 -0
- package/lib/components/Dropdown/DropdownMenu.js +1 -1
- package/lib/components/Feedback/Reasons.js +3 -2
- package/lib/components/Filter/FilterCheckboxes.js +30 -11
- package/lib/components/Filter/FilterDateRange.js +36 -2
- package/lib/components/Image/Image.js +24 -4
- package/lib/components/Search/SearchAiActivity.d.ts +10 -0
- package/lib/components/Search/SearchAiActivity.js +278 -0
- package/lib/components/Search/SearchAiDialog.js +5 -1
- package/lib/components/Search/SearchAiMessage.d.ts +2 -1
- package/lib/components/Search/SearchAiMessage.js +20 -108
- package/lib/components/Search/SearchItem.js +1 -8
- package/lib/components/Search/variables.js +15 -2
- package/lib/components/Segmented/Segmented.js +23 -3
- package/lib/components/Select/Select.js +10 -3
- package/lib/components/Select/SelectInput.d.ts +1 -0
- package/lib/components/Select/SelectInput.js +5 -11
- package/lib/components/SplitButton/SplitButton.js +37 -3
- package/lib/core/constants/mcp.d.ts +2 -2
- package/lib/core/constants/mcp.js +3 -8
- package/lib/core/constants/search.js +5 -1
- package/lib/core/hooks/index.d.ts +2 -0
- package/lib/core/hooks/index.js +2 -0
- package/lib/core/hooks/menu/use-collapse.js +1 -1
- package/lib/core/hooks/search/use-search-ai-activity.d.ts +11 -0
- package/lib/core/hooks/search/use-search-ai-activity.js +15 -0
- package/lib/core/hooks/use-connect-mcp-button.js +2 -1
- package/lib/core/hooks/use-full-height.d.ts +1 -1
- package/lib/core/hooks/use-full-height.js +8 -8
- package/lib/core/hooks/use-tab-list.d.ts +31 -0
- package/lib/core/hooks/use-tab-list.js +49 -0
- package/lib/core/styles/global.d.ts +2 -0
- package/lib/core/styles/global.js +80 -76
- package/lib/core/styles/index.d.ts +1 -0
- package/lib/core/styles/index.js +3 -1
- package/lib/core/styles/search-ai-appear.d.ts +1 -0
- package/lib/core/styles/search-ai-appear.js +18 -0
- package/lib/core/types/dropdown.d.ts +1 -0
- package/lib/core/types/dropdown.js +3 -0
- package/lib/core/types/index.d.ts +1 -0
- package/lib/core/types/l10n.d.ts +1 -1
- package/lib/core/types/mcp.d.ts +2 -1
- package/lib/core/types/search.d.ts +23 -0
- package/lib/core/utils/Dynamic.d.ts +8 -1
- package/lib/core/utils/Dynamic.js +34 -3
- package/lib/core/utils/assign-ref.d.ts +2 -0
- package/lib/core/utils/assign-ref.js +12 -0
- package/lib/core/utils/content-segments.d.ts +12 -1
- package/lib/core/utils/content-segments.js +90 -5
- package/lib/core/utils/dropdown.d.ts +2 -0
- package/lib/core/utils/dropdown.js +12 -0
- package/lib/core/utils/index.d.ts +2 -0
- package/lib/core/utils/index.js +2 -0
- package/lib/core/utils/mcp.d.ts +2 -1
- package/lib/core/utils/mcp.js +5 -0
- package/lib/core/utils/search-ai-activity.d.ts +4 -0
- package/lib/core/utils/search-ai-activity.js +83 -0
- package/lib/markdoc/tags/connect-mcp.js +15 -0
- package/package.json +2 -2
- package/src/components/Buttons/ConnectMCPButton.tsx +8 -14
- package/src/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.tsx +3 -1
- package/src/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.tsx +37 -22
- package/src/components/Catalog/CatalogFilter/CatalogFilterDateRange.tsx +3 -2
- package/src/components/Dropdown/Dropdown.tsx +28 -6
- package/src/components/Dropdown/DropdownMenu.tsx +7 -1
- package/src/components/Feedback/Reasons.tsx +3 -2
- package/src/components/Filter/FilterCheckboxes.tsx +33 -18
- package/src/components/Filter/FilterDateRange.tsx +3 -2
- package/src/components/Image/Image.tsx +26 -5
- package/src/components/Search/SearchAiActivity.tsx +318 -0
- package/src/components/Search/SearchAiDialog.tsx +4 -3
- package/src/components/Search/SearchAiMessage.tsx +27 -135
- package/src/components/Search/SearchItem.tsx +2 -9
- package/src/components/Search/variables.ts +15 -2
- package/src/components/Segmented/Segmented.tsx +25 -16
- package/src/components/Select/Select.tsx +12 -6
- package/src/components/Select/SelectInput.tsx +10 -18
- package/src/components/SplitButton/SplitButton.tsx +8 -2
- package/src/core/constants/mcp.ts +3 -9
- package/src/core/constants/search.ts +5 -1
- package/src/core/hooks/__mocks__/index.ts +1 -0
- package/src/core/hooks/__mocks__/use-theme-hooks.ts +1 -0
- package/src/core/hooks/index.ts +2 -0
- package/src/core/hooks/menu/use-collapse.ts +1 -1
- package/src/core/hooks/search/use-search-ai-activity.ts +31 -0
- package/src/core/hooks/use-connect-mcp-button.ts +7 -2
- package/src/core/hooks/use-full-height.ts +8 -8
- package/src/core/hooks/use-tab-list.ts +63 -0
- package/src/core/styles/global.ts +80 -75
- package/src/core/styles/index.ts +2 -1
- package/src/core/styles/search-ai-appear.ts +16 -0
- package/src/core/types/dropdown.ts +1 -0
- package/src/core/types/index.ts +1 -0
- package/src/core/types/l10n.ts +1 -1
- package/src/core/types/mcp.ts +3 -1
- package/src/core/types/search.ts +21 -0
- package/src/core/utils/Dynamic.tsx +67 -35
- package/src/core/utils/assign-ref.ts +9 -0
- package/src/core/utils/content-segments.ts +98 -6
- package/src/core/utils/dropdown.ts +14 -0
- package/src/core/utils/index.ts +2 -0
- package/src/core/utils/mcp.ts +7 -1
- package/src/core/utils/search-ai-activity.ts +110 -0
- package/src/icons/CheckboxIcon/CheckboxIcon.tsx +1 -0
- package/src/icons/ChevronSortIcon/ChevronSortIcon.tsx +1 -0
- package/src/markdoc/tags/connect-mcp.ts +16 -1
|
@@ -19,55 +19,50 @@ const CopyIcon_1 = require("../../icons/CopyIcon/CopyIcon");
|
|
|
19
19
|
const CheckmarkFilledIcon_1 = require("../../icons/CheckmarkFilledIcon/CheckmarkFilledIcon");
|
|
20
20
|
const hooks_1 = require("../../core/hooks");
|
|
21
21
|
const constants_1 = require("../../core/constants");
|
|
22
|
-
const MENU_OPTIONS =
|
|
23
|
-
{
|
|
24
|
-
key: 'cursor',
|
|
22
|
+
const MENU_OPTIONS = {
|
|
23
|
+
cursor: {
|
|
25
24
|
icon: CursorIcon_1.CursorIcon,
|
|
26
25
|
titleTranslationKey: 'page.actions.connectMcp.cursor',
|
|
27
26
|
titleDefault: 'Connect to Cursor',
|
|
28
27
|
descriptionTranslationKey: 'page.actions.connectMcp.cursorDescription',
|
|
29
28
|
descriptionDefault: 'Install MCP server on Cursor',
|
|
30
29
|
},
|
|
31
|
-
{
|
|
32
|
-
key: 'vscode',
|
|
30
|
+
vscode: {
|
|
33
31
|
icon: VSCodeIcon_1.VSCodeIcon,
|
|
34
32
|
titleTranslationKey: 'page.actions.connectMcp.vscode',
|
|
35
33
|
titleDefault: 'Connect to VS Code',
|
|
36
34
|
descriptionTranslationKey: 'page.actions.connectMcp.vscodeDescription',
|
|
37
35
|
descriptionDefault: 'Install MCP server on VS Code',
|
|
38
36
|
},
|
|
39
|
-
{
|
|
40
|
-
key: 'claude-code',
|
|
37
|
+
'claude-code': {
|
|
41
38
|
icon: ClaudeIcon_1.ClaudeIcon,
|
|
42
39
|
titleTranslationKey: 'page.actions.connectMcp.claudeCode',
|
|
43
40
|
titleDefault: 'Connect to Claude Code',
|
|
44
41
|
descriptionTranslationKey: 'page.actions.connectMcp.claudeCodeDescription',
|
|
45
42
|
descriptionDefault: 'Copy the Claude Code CLI command',
|
|
46
43
|
},
|
|
47
|
-
{
|
|
48
|
-
key: 'codex',
|
|
44
|
+
codex: {
|
|
49
45
|
icon: CodexIcon_1.CodexIcon,
|
|
50
46
|
titleTranslationKey: 'page.actions.connectMcp.codex',
|
|
51
47
|
titleDefault: 'Connect to Codex CLI',
|
|
52
48
|
descriptionTranslationKey: 'page.actions.connectMcp.codexDescription',
|
|
53
49
|
descriptionDefault: 'Copy the Codex CLI command',
|
|
54
50
|
},
|
|
55
|
-
{
|
|
56
|
-
key: 'copy',
|
|
51
|
+
copy: {
|
|
57
52
|
icon: CopyIcon_1.CopyIcon,
|
|
58
53
|
titleTranslationKey: 'page.actions.connectMcp.copyConfig',
|
|
59
54
|
titleDefault: 'Copy MCP Configuration',
|
|
60
55
|
descriptionTranslationKey: 'page.actions.connectMcp.copyConfigDescription',
|
|
61
56
|
descriptionDefault: 'Copy MCP JSON Configuration',
|
|
62
57
|
},
|
|
63
|
-
|
|
58
|
+
};
|
|
64
59
|
// Copy actions keep the dropdown open so the copied checkmark is visible.
|
|
65
60
|
const COPY_OPTIONS = ['claude-code', 'codex', 'copy'];
|
|
66
61
|
function ConnectMCPButton({ placement = 'bottom', alignment = 'end', options = constants_1.DEFAULT_MCP_OPTIONS, }) {
|
|
67
62
|
const { useTranslate } = (0, hooks_1.useThemeHooks)();
|
|
68
63
|
const { translate } = useTranslate();
|
|
69
64
|
const { copiedOption, visibleOptions, handleAction } = (0, hooks_1.useConnectMCPButton)({ options });
|
|
70
|
-
const menuOptions =
|
|
65
|
+
const menuOptions = visibleOptions.map((key) => (Object.assign({ key }, MENU_OPTIONS[key])));
|
|
71
66
|
const primaryOption = menuOptions[0];
|
|
72
67
|
const dropdownOptions = menuOptions.slice(1);
|
|
73
68
|
if (!primaryOption)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { CatalogEntityRelationsGraphProps } from '../../../../components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph';
|
|
2
|
-
export declare const CatalogEntityRelationsGraph: import("
|
|
2
|
+
export declare const CatalogEntityRelationsGraph: import("../../../../core/utils").DynamicComponent<CatalogEntityRelationsGraphProps>;
|
package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.js
CHANGED
|
@@ -35,5 +35,5 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.CatalogEntityRelationsGraph = void 0;
|
|
37
37
|
const utils_1 = require("../../../../core/utils");
|
|
38
|
-
exports.CatalogEntityRelationsGraph = (0, utils_1.dynamic)(() => Promise.resolve().then(() => __importStar(require('
|
|
38
|
+
exports.CatalogEntityRelationsGraph = (0, utils_1.dynamic)(() => Promise.resolve().then(() => __importStar(require('../../../../components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph'))).then((mod) => mod.CatalogEntityRelationsGraph));
|
|
39
39
|
//# sourceMappingURL=CatalogEntityRelationsGraph.lazy.js.map
|
|
@@ -101,17 +101,20 @@ function CatalogFilterCheckboxes({ filter, filterValuesCasing, showCounter = tru
|
|
|
101
101
|
react_1.default.createElement(FilterInput_1.FilterInput, { value: searchTerm, onChange: setSearchTerm })),
|
|
102
102
|
react_1.default.createElement(FilterOptions_1.FilterOptions, null, filteredOptions.map(({ value, count }) => {
|
|
103
103
|
const id = 'filter--' + filter.property + '--' + value;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
react_1.default.createElement(
|
|
111
|
-
|
|
112
|
-
filter.
|
|
113
|
-
|
|
114
|
-
|
|
104
|
+
const checked = filter.selectedOptions instanceof Set
|
|
105
|
+
? filter.selectedOptions.has(value) ||
|
|
106
|
+
filter.selectedOptions.has(value === null || value === void 0 ? void 0 : value.toLowerCase())
|
|
107
|
+
: false;
|
|
108
|
+
return (react_1.default.createElement(FilterCheckboxOption, { key: id },
|
|
109
|
+
react_1.default.createElement(CheckboxIcon_1.CheckboxIcon, { checked: checked }),
|
|
110
|
+
react_1.default.createElement(FilterOptionLabel_1.FilterOptionLabel, { "data-translation-key": value },
|
|
111
|
+
react_1.default.createElement(FilterCheckboxInput, { checked: checked, onChange: () => {
|
|
112
|
+
filter.toggleOption(value);
|
|
113
|
+
telemetry.sendCatalogEntitiesFilterCheckboxToggledMessage([
|
|
114
|
+
Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('catalogEntitiesFilterCheckboxId', 'checkbox')), { category: filter.property, value: value }),
|
|
115
|
+
]);
|
|
116
|
+
} }),
|
|
117
|
+
highlightText((0, utils_1.changeTextCasing)(translate(value), filterValuesCasing) || '')),
|
|
115
118
|
showCounter && react_1.default.createElement(CounterTag_1.CounterTag, { borderless: true }, count)));
|
|
116
119
|
})))));
|
|
117
120
|
}
|
|
@@ -147,6 +150,22 @@ const HighlightedText = styled_components_1.default.span `
|
|
|
147
150
|
`;
|
|
148
151
|
const FilterCheckboxOption = (0, styled_components_1.default)(FilterOption_1.FilterOption) `
|
|
149
152
|
padding-left: var(--filter-option-checkbox-padding-left);
|
|
153
|
+
|
|
154
|
+
&:has(input:focus-visible) {
|
|
155
|
+
outline: 1px solid var(--button-border-color-focused);
|
|
156
|
+
outline-offset: -1px;
|
|
157
|
+
}
|
|
158
|
+
`;
|
|
159
|
+
const FilterCheckboxInput = styled_components_1.default.input.attrs({ type: 'checkbox' }) `
|
|
160
|
+
position: absolute;
|
|
161
|
+
width: 1px;
|
|
162
|
+
height: 1px;
|
|
163
|
+
margin: -1px;
|
|
164
|
+
padding: 0;
|
|
165
|
+
overflow: hidden;
|
|
166
|
+
clip: rect(0 0 0 0);
|
|
167
|
+
white-space: nowrap;
|
|
168
|
+
border: 0;
|
|
150
169
|
`;
|
|
151
170
|
const FilterSearchWrapper = styled_components_1.default.div `
|
|
152
171
|
padding-bottom: var(--spacing-xs);
|
|
@@ -46,6 +46,7 @@ const hooks_1 = require("../../../core/hooks");
|
|
|
46
46
|
const utils_1 = require("../../../core/utils");
|
|
47
47
|
const Accordion_1 = require("../../../components/Accordion/Accordion");
|
|
48
48
|
function CatalogFilterDateRange({ filter, className, }) {
|
|
49
|
+
const [today] = (0, react_1.useState)(() => new Date());
|
|
49
50
|
const { useTranslate } = (0, hooks_1.useThemeHooks)();
|
|
50
51
|
const { translate } = useTranslate();
|
|
51
52
|
const from = (0, react_1.useMemo)(() => (filter.selectedOptions.from ? new Date(filter.selectedOptions.from) : undefined), [filter.selectedOptions.from]);
|
|
@@ -62,7 +63,7 @@ function CatalogFilterDateRange({ filter, className, }) {
|
|
|
62
63
|
react_1.default.createElement(DateRangeWrapper, null,
|
|
63
64
|
react_1.default.createElement(DateRangeRow, null,
|
|
64
65
|
react_1.default.createElement("span", null, translate('filter.dateRange.from', 'From:')),
|
|
65
|
-
react_1.default.createElement(DatePicker_1.DatePicker, { closeCalendar: true, format: "y-MM-dd", dayPlaceholder: "DD", monthPlaceholder: "MM", yearPlaceholder: "YYYY", value: from, maxDate:
|
|
66
|
+
react_1.default.createElement(DatePicker_1.DatePicker, { closeCalendar: true, format: "y-MM-dd", dayPlaceholder: "DD", monthPlaceholder: "MM", yearPlaceholder: "YYYY", value: from, maxDate: today, onChange: (from) => {
|
|
66
67
|
if (Array.isArray(from))
|
|
67
68
|
return;
|
|
68
69
|
filter.selectOption(Object.assign(Object.assign({}, filter.selectedOptions), { from: (0, utils_1.formatDateWithoutTimeZone)(from), to: (0, utils_1.formatDateWithoutTimeZone)(to) }));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { RenderableChildren } from '../../core/types';
|
|
2
|
+
import type { DropdownAlignment, RenderableChildren } from '../../core/types';
|
|
3
3
|
type DropdownMenuContext = {
|
|
4
4
|
close: () => void;
|
|
5
5
|
isOpen: boolean;
|
|
@@ -9,13 +9,15 @@ export type DropdownProps = {
|
|
|
9
9
|
children: RenderableChildren<DropdownMenuContext>;
|
|
10
10
|
triggerEvent?: 'click' | 'hover';
|
|
11
11
|
placement?: 'top' | 'bottom';
|
|
12
|
-
alignment?:
|
|
12
|
+
alignment?: DropdownAlignment;
|
|
13
13
|
active?: boolean;
|
|
14
14
|
closeOnClick?: boolean;
|
|
15
15
|
dataAttributes?: Record<string, string>;
|
|
16
16
|
className?: string;
|
|
17
17
|
withArrow?: boolean;
|
|
18
18
|
portalled?: boolean;
|
|
19
|
+
/** Element the menu lines up with when it is not the dropdown itself, e.g. a whole split button. */
|
|
20
|
+
alignmentAnchorRef?: React.RefObject<HTMLElement | null>;
|
|
19
21
|
onClick?: (event: React.UIEvent) => void;
|
|
20
22
|
onClose?: () => void;
|
|
21
23
|
onOpen?: () => void;
|
|
@@ -38,15 +38,17 @@ const react_1 = __importStar(require("react"));
|
|
|
38
38
|
const react_dom_1 = require("react-dom");
|
|
39
39
|
const styled_components_1 = __importStar(require("styled-components"));
|
|
40
40
|
const hooks_1 = require("../../core/hooks");
|
|
41
|
+
const utils_1 = require("../../core/utils");
|
|
41
42
|
const ChevronDownIcon_1 = require("../../icons/ChevronDownIcon/ChevronDownIcon");
|
|
42
43
|
const ChevronUpIcon_1 = require("../../icons/ChevronUpIcon/ChevronUpIcon");
|
|
43
44
|
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? react_1.useLayoutEffect : react_1.useEffect;
|
|
44
|
-
exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigger, triggerEvent = 'click', closeOnClick = true, withArrow, dataAttributes, placement, alignment, portalled = false, onClick, onClose, onOpen, }, ref) => {
|
|
45
|
+
exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigger, triggerEvent = 'click', closeOnClick = true, withArrow, dataAttributes, placement, alignment, portalled = false, alignmentAnchorRef, onClick, onClose, onOpen, }, ref) => {
|
|
45
46
|
var _a, _b;
|
|
46
47
|
const dropdownRef = (0, react_1.useRef)(null);
|
|
47
48
|
const menuRef = (0, react_1.useRef)(null);
|
|
48
49
|
const [isOpen, setIsOpen] = (0, hooks_1.useControlledState)(false, active);
|
|
49
50
|
const [menuStyle, setMenuStyle] = (0, react_1.useState)({});
|
|
51
|
+
const [fittedAlignment, setFittedAlignment] = (0, react_1.useState)(alignment);
|
|
50
52
|
const wrapperRef = ref || dropdownRef;
|
|
51
53
|
const handleOpen = () => {
|
|
52
54
|
setIsOpen(true);
|
|
@@ -78,13 +80,13 @@ exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigg
|
|
|
78
80
|
}
|
|
79
81
|
};
|
|
80
82
|
const updateMenuPosition = (0, react_1.useCallback)(() => {
|
|
81
|
-
var _a;
|
|
82
|
-
var
|
|
83
|
+
var _a, _b;
|
|
84
|
+
var _c, _d, _e;
|
|
83
85
|
const wrapper = wrapperRef.current;
|
|
84
86
|
if (!wrapper)
|
|
85
87
|
return;
|
|
86
|
-
const rect = wrapper.getBoundingClientRect();
|
|
87
|
-
const menuHeight = (
|
|
88
|
+
const rect = ((_c = alignmentAnchorRef === null || alignmentAnchorRef === void 0 ? void 0 : alignmentAnchorRef.current) !== null && _c !== void 0 ? _c : wrapper).getBoundingClientRect();
|
|
89
|
+
const menuHeight = (_d = (_a = menuRef.current) === null || _a === void 0 ? void 0 : _a.offsetHeight) !== null && _d !== void 0 ? _d : 0;
|
|
88
90
|
const fitsBelow = rect.bottom + menuHeight <= window.innerHeight;
|
|
89
91
|
const fitsAbove = rect.top - menuHeight >= 0;
|
|
90
92
|
const openUpward = placement === 'top' ? fitsAbove || !fitsBelow : !fitsBelow && fitsAbove;
|
|
@@ -95,7 +97,7 @@ exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigg
|
|
|
95
97
|
else {
|
|
96
98
|
style.top = rect.bottom;
|
|
97
99
|
}
|
|
98
|
-
if (alignment === 'end') {
|
|
100
|
+
if ((0, utils_1.fitDropdownAlignment)(rect, (_e = (_b = menuRef.current) === null || _b === void 0 ? void 0 : _b.offsetWidth) !== null && _e !== void 0 ? _e : 0, alignment) === 'end') {
|
|
99
101
|
style.right = window.innerWidth - rect.right;
|
|
100
102
|
}
|
|
101
103
|
else {
|
|
@@ -106,7 +108,25 @@ exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigg
|
|
|
106
108
|
style.zIndex = zIndex;
|
|
107
109
|
}
|
|
108
110
|
setMenuStyle(style);
|
|
109
|
-
}, [placement, alignment, wrapperRef]);
|
|
111
|
+
}, [placement, alignment, wrapperRef, alignmentAnchorRef]);
|
|
112
|
+
/* The absolute-positioned menu is placed by CSS, so the side is measured once it is
|
|
113
|
+
shown and again on resize; a side that runs off the viewport flips to the other one. */
|
|
114
|
+
const updateFittedAlignment = (0, react_1.useCallback)(() => {
|
|
115
|
+
var _a;
|
|
116
|
+
const wrapper = wrapperRef.current;
|
|
117
|
+
const menu = menuRef.current;
|
|
118
|
+
if (!wrapper || !menu)
|
|
119
|
+
return;
|
|
120
|
+
const rect = ((_a = alignmentAnchorRef === null || alignmentAnchorRef === void 0 ? void 0 : alignmentAnchorRef.current) !== null && _a !== void 0 ? _a : wrapper).getBoundingClientRect();
|
|
121
|
+
setFittedAlignment((0, utils_1.fitDropdownAlignment)(rect, menu.offsetWidth, alignment));
|
|
122
|
+
}, [alignment, wrapperRef, alignmentAnchorRef]);
|
|
123
|
+
useIsomorphicLayoutEffect(() => {
|
|
124
|
+
if (portalled || !isOpen)
|
|
125
|
+
return;
|
|
126
|
+
updateFittedAlignment();
|
|
127
|
+
window.addEventListener('resize', updateFittedAlignment);
|
|
128
|
+
return () => window.removeEventListener('resize', updateFittedAlignment);
|
|
129
|
+
}, [portalled, isOpen, updateFittedAlignment]);
|
|
110
130
|
useIsomorphicLayoutEffect(() => {
|
|
111
131
|
if (!portalled || !isOpen)
|
|
112
132
|
return;
|
|
@@ -123,7 +143,7 @@ exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigg
|
|
|
123
143
|
const triggerChild = react_1.default.Children.only(trigger);
|
|
124
144
|
const isLinkTrigger = Boolean(((_a = triggerChild.props) === null || _a === void 0 ? void 0 : _a.to) || ((_b = triggerChild.props) === null || _b === void 0 ? void 0 : _b.href));
|
|
125
145
|
const dropdownTrigger = (0, react_1.cloneElement)(triggerChild, Object.assign(Object.assign(Object.assign({ onClick: triggerEvent === 'click' ? handleToggle : undefined, 'aria-haspopup': 'menu', 'aria-expanded': isOpen, icon: withArrow ? isOpen ? react_1.default.createElement(ChevronUpIcon_1.ChevronUpIcon, null) : react_1.default.createElement(ChevronDownIcon_1.ChevronDownIcon, null) : undefined }, (withArrow ? { iconPosition: 'right' } : {})), triggerChild.props), { onKeyDown: triggerEvent === 'click' || !isLinkTrigger ? handleKeyDown : undefined }));
|
|
126
|
-
const menu = (react_1.default.createElement(ChildrenWrapper, { ref: menuRef, $placement: placement, $alignment:
|
|
146
|
+
const menu = (react_1.default.createElement(ChildrenWrapper, { ref: menuRef, $placement: placement, $alignment: fittedAlignment, $isOpen: isOpen, $portalled: portalled, style: portalled ? menuStyle : undefined, onClick: closeOnClick ? handleChildClick : undefined }, menuContent));
|
|
127
147
|
const portalledMenu = isOpen && typeof document !== 'undefined' ? (0, react_dom_1.createPortal)(menu, document.body) : null;
|
|
128
148
|
return (react_1.default.createElement(DropdownWrapper, Object.assign({ "data-component-name": "Dropdown/Dropdown", "data-testid": "dropdown" }, dataAttributes, { className: className, ref: wrapperRef, onPointerEnter: triggerEvent === 'hover' ? handleOpen : undefined, onPointerLeave: triggerEvent === 'hover' ? handleClose : undefined, onClick: onClick }),
|
|
129
149
|
dropdownTrigger,
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import type { ReactNode, JSX } from 'react';
|
|
3
3
|
import type { DropdownMenuItemProps } from '../../components/Dropdown/DropdownMenuItem';
|
|
4
4
|
export type DropdownMenuProps = {
|
|
5
|
+
id?: string;
|
|
5
6
|
className?: string;
|
|
6
7
|
role?: string;
|
|
7
8
|
footer?: React.ReactNode;
|
|
@@ -15,7 +15,7 @@ function DropdownMenu(props) {
|
|
|
15
15
|
if ('items' in props) {
|
|
16
16
|
content = props.items.map((item, idx) => (react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, Object.assign({ key: idx }, item), item.content)));
|
|
17
17
|
}
|
|
18
|
-
return (react_1.default.createElement(DropdownMenuWrapper, { "data-component-name": "Dropdown/DropdownMenu", "data-testid": "dropdown-menu", className: props.className, role: props.role || 'menu' },
|
|
18
|
+
return (react_1.default.createElement(DropdownMenuWrapper, { "data-component-name": "Dropdown/DropdownMenu", "data-testid": "dropdown-menu", id: props.id, className: props.className, role: props.role || 'menu' },
|
|
19
19
|
content,
|
|
20
20
|
props.footer || null));
|
|
21
21
|
}
|
|
@@ -43,6 +43,7 @@ const hooks_1 = require("../../core/hooks");
|
|
|
43
43
|
function Reasons({ settings, onChange, className }) {
|
|
44
44
|
const { label, component = 'checkbox', items = [] } = settings;
|
|
45
45
|
const [checkedState, setCheckedState] = React.useState(new Array(items.length).fill(false));
|
|
46
|
+
const idPrefix = React.useId();
|
|
46
47
|
const { useTranslate } = (0, hooks_1.useThemeHooks)();
|
|
47
48
|
const { translate } = useTranslate();
|
|
48
49
|
if (!items.length) {
|
|
@@ -59,8 +60,8 @@ function Reasons({ settings, onChange, className }) {
|
|
|
59
60
|
React.createElement(Label, null, label ||
|
|
60
61
|
translate('feedback.settings.reasons.label', 'Which statement describes your thoughts about this page?')),
|
|
61
62
|
items.map((reason, idx) => (React.createElement(OptionWrapper, { key: reason },
|
|
62
|
-
React.createElement("input", { type: component, value: reason, checked: checkedState[idx], name: "reasons", onChange: () => handleOptionChange(idx) }),
|
|
63
|
-
React.createElement("label", { "data-translation-key": `feedback.settings.reasons.items.${idx + 1}`,
|
|
63
|
+
React.createElement("input", { id: `${idPrefix}-${idx}`, type: component, value: reason, checked: checkedState[idx], name: "reasons", onChange: () => handleOptionChange(idx) }),
|
|
64
|
+
React.createElement("label", { "data-translation-key": `feedback.settings.reasons.items.${idx + 1}`, htmlFor: `${idPrefix}-${idx}` }, translate(`feedback.settings.reasons.items.${idx + 1}`, reason)))))));
|
|
64
65
|
}
|
|
65
66
|
const ReasonsWrapper = styled_components_1.default.div `
|
|
66
67
|
font-family: var(--feedback-font-family);
|
|
@@ -22,22 +22,41 @@ function FilterCheckboxes({ filter, filterValuesCasing, showCounter = true, }) {
|
|
|
22
22
|
react_1.default.createElement(FilterTitle_1.FilterTitle, { "data-translation-key": filter.titleTranslationKey }, translate(filter.titleTranslationKey, filter.title)),
|
|
23
23
|
react_1.default.createElement(FilterOptions_1.FilterOptions, null, (filter.filteredOptions || filter.options).map(({ value, count }) => {
|
|
24
24
|
const id = 'filter--' + filter.property + '--' + value;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
react_1.default.createElement(
|
|
32
|
-
|
|
33
|
-
filter.
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
const checked = filter.selectedOptions instanceof Set
|
|
26
|
+
? filter.selectedOptions.has(value) ||
|
|
27
|
+
filter.selectedOptions.has(value === null || value === void 0 ? void 0 : value.toLowerCase())
|
|
28
|
+
: false;
|
|
29
|
+
return (react_1.default.createElement(FilterCheckboxOption, { key: id },
|
|
30
|
+
react_1.default.createElement(CheckboxIcon_1.CheckboxIcon, { checked: checked }),
|
|
31
|
+
react_1.default.createElement(FilterOptionLabel_1.FilterOptionLabel, { "data-translation-key": value },
|
|
32
|
+
react_1.default.createElement(FilterCheckboxInput, { checked: checked, onChange: () => {
|
|
33
|
+
filter.toggleOption(value);
|
|
34
|
+
telemetry.sendFilterCheckboxToggledMessage([
|
|
35
|
+
(0, utils_1.getBaseDataAttributes)('filterId', 'checkbox'),
|
|
36
|
+
]);
|
|
37
|
+
} }),
|
|
38
|
+
(0, utils_1.changeTextCasing)(translate(value), filterValuesCasing)),
|
|
36
39
|
showCounter && react_1.default.createElement(CounterTag_1.CounterTag, { borderless: true }, count)));
|
|
37
40
|
}))));
|
|
38
41
|
}
|
|
39
42
|
const FilterCheckboxOption = (0, styled_components_1.default)(FilterOption_1.FilterOption) `
|
|
40
43
|
padding-left: var(--filter-option-checkbox-padding-left);
|
|
44
|
+
|
|
45
|
+
&:has(input:focus-visible) {
|
|
46
|
+
outline: 1px solid var(--button-border-color-focused);
|
|
47
|
+
outline-offset: -1px;
|
|
48
|
+
}
|
|
49
|
+
`;
|
|
50
|
+
const FilterCheckboxInput = styled_components_1.default.input.attrs({ type: 'checkbox' }) `
|
|
51
|
+
position: absolute;
|
|
52
|
+
width: 1px;
|
|
53
|
+
height: 1px;
|
|
54
|
+
margin: -1px;
|
|
55
|
+
padding: 0;
|
|
56
|
+
overflow: hidden;
|
|
57
|
+
clip: rect(0 0 0 0);
|
|
58
|
+
white-space: nowrap;
|
|
59
|
+
border: 0;
|
|
41
60
|
`;
|
|
42
61
|
const FilterCheckboxesWrapper = styled_components_1.default.div `
|
|
43
62
|
display: flex;
|
|
@@ -1,10 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
5
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
39
|
exports.FilterDateRange = FilterDateRange;
|
|
7
|
-
const react_1 =
|
|
40
|
+
const react_1 = __importStar(require("react"));
|
|
8
41
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
9
42
|
const FilterOptions_1 = require("../../components/Filter/FilterOptions");
|
|
10
43
|
const FilterTitle_1 = require("../../components/Filter/FilterTitle");
|
|
@@ -12,6 +45,7 @@ const DatePicker_1 = require("../../components/DatePicker/DatePicker");
|
|
|
12
45
|
const hooks_1 = require("../../core/hooks");
|
|
13
46
|
const utils_1 = require("../../core/utils");
|
|
14
47
|
function FilterDateRange({ filter }) {
|
|
48
|
+
const [today] = (0, react_1.useState)(() => new Date());
|
|
15
49
|
const { useTranslate } = (0, hooks_1.useThemeHooks)();
|
|
16
50
|
const { translate } = useTranslate();
|
|
17
51
|
const from = filter.selectedOptions.from ? new Date(filter.selectedOptions.from) : undefined;
|
|
@@ -22,7 +56,7 @@ function FilterDateRange({ filter }) {
|
|
|
22
56
|
react_1.default.createElement(DateRangeWrapper, null,
|
|
23
57
|
react_1.default.createElement(DateRangeRow, null,
|
|
24
58
|
react_1.default.createElement("span", null, translate('filter.dateRange.from', 'From:')),
|
|
25
|
-
react_1.default.createElement(DatePicker_1.DatePicker, { closeCalendar: true, format: "y-MM-dd", dayPlaceholder: "DD", monthPlaceholder: "MM", yearPlaceholder: "YYYY", value: from, maxDate:
|
|
59
|
+
react_1.default.createElement(DatePicker_1.DatePicker, { closeCalendar: true, format: "y-MM-dd", dayPlaceholder: "DD", monthPlaceholder: "MM", yearPlaceholder: "YYYY", value: from, maxDate: today, onChange: (from) => {
|
|
26
60
|
if (Array.isArray(from))
|
|
27
61
|
return;
|
|
28
62
|
filter.selectOption(Object.assign(Object.assign({}, filter.selectedOptions), { from: (0, utils_1.formatDateWithoutTimeZone)(from), to: (0, utils_1.formatDateWithoutTimeZone)(to) }));
|
|
@@ -43,6 +43,7 @@ const Button_1 = require("../../components/Button/Button");
|
|
|
43
43
|
function Image(props) {
|
|
44
44
|
const { src, srcSet, images: galleryImages, alt, className, width, height, border, caption, framed, style, withLightbox, lightboxStyle, } = props;
|
|
45
45
|
const lightboxContainerRef = (0, react_1.useRef)(null);
|
|
46
|
+
const lightboxTriggerRef = (0, react_1.useRef)(null);
|
|
46
47
|
const [lightboxImage, setLightboxImage] = (0, react_1.useState)(undefined);
|
|
47
48
|
const parsedSourceSetMap = (0, react_1.useMemo)(() => {
|
|
48
49
|
return srcSet ? (0, utils_1.parseSrcSet)(srcSet) : new Map();
|
|
@@ -53,28 +54,47 @@ function Image(props) {
|
|
|
53
54
|
setLightboxImage(undefined);
|
|
54
55
|
}
|
|
55
56
|
}, []);
|
|
56
|
-
const handleImageClick = (0, react_1.useCallback)((src) => {
|
|
57
|
+
const handleImageClick = (0, react_1.useCallback)((src, trigger) => {
|
|
57
58
|
if (!withLightbox || lightboxImage) {
|
|
58
59
|
return;
|
|
59
60
|
}
|
|
61
|
+
lightboxTriggerRef.current = trigger;
|
|
60
62
|
setLightboxImage(src);
|
|
61
63
|
}, [withLightbox, lightboxImage]);
|
|
64
|
+
const getLightboxTriggerProps = (imageSrc) => withLightbox
|
|
65
|
+
? {
|
|
66
|
+
role: 'button',
|
|
67
|
+
tabIndex: 0,
|
|
68
|
+
'aria-label': alt ? undefined : 'Open image',
|
|
69
|
+
onClick: (e) => handleImageClick(imageSrc, e.currentTarget),
|
|
70
|
+
onKeyDown: (e) => {
|
|
71
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
72
|
+
e.preventDefault();
|
|
73
|
+
handleImageClick(imageSrc, e.currentTarget);
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
: {};
|
|
62
78
|
const handleCloseLightbox = (0, react_1.useCallback)(() => {
|
|
63
79
|
setLightboxImage(undefined);
|
|
64
80
|
}, []);
|
|
65
81
|
(0, hooks_1.useModalScrollLock)(!!lightboxImage);
|
|
66
82
|
(0, react_1.useEffect)(() => {
|
|
67
|
-
var _a;
|
|
83
|
+
var _a, _b;
|
|
68
84
|
if (lightboxImage) {
|
|
69
85
|
(_a = lightboxContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
70
86
|
}
|
|
87
|
+
else {
|
|
88
|
+
(_b = lightboxTriggerRef.current) === null || _b === void 0 ? void 0 : _b.focus();
|
|
89
|
+
lightboxTriggerRef.current = null;
|
|
90
|
+
}
|
|
71
91
|
}, [lightboxImage]);
|
|
72
92
|
const combinedStyles = Object.assign(Object.assign(Object.assign({}, (withLightbox && { cursor: 'pointer' })), (border && { border })), (typeof style === 'string' ? (0, utils_1.parseStyleString)(style) : style));
|
|
73
93
|
const lightboxOverlayStyles = typeof lightboxStyle === 'string' ? (0, utils_1.parseStyleString)(lightboxStyle) : lightboxStyle;
|
|
74
|
-
const images = src ? (react_1.default.createElement("img", { src: src, alt: alt, className: className, width: width, height: height, style: combinedStyles,
|
|
94
|
+
const images = src ? (react_1.default.createElement("img", Object.assign({ src: src, alt: alt, className: className, width: width, height: height, style: combinedStyles }, getLightboxTriggerProps(src)))) : (Array.from(parsedSourceSetMap).map(([key, value]) => (react_1.default.createElement(ColorModeAwareImage, Object.assign({ key: key, $colorMode: key, src: value, alt: alt, className: className, width: width, height: height, $withLightbox: withLightbox, style: combinedStyles }, getLightboxTriggerProps(value))))));
|
|
75
95
|
const hasGallery = Array.isArray(galleryImages) && galleryImages.length > 0;
|
|
76
96
|
const visibleGalleryImages = hasGallery ? galleryImages.slice(0, 3) : [];
|
|
77
|
-
const gallery = hasGallery ? (react_1.default.createElement(GalleryRow, null, visibleGalleryImages.map((galleryImageSrc, index) => (react_1.default.createElement("img", { key: `${galleryImageSrc}-${index}`, src: galleryImageSrc, alt: alt, style: withLightbox ? { cursor: 'pointer' } : undefined,
|
|
97
|
+
const gallery = hasGallery ? (react_1.default.createElement(GalleryRow, null, visibleGalleryImages.map((galleryImageSrc, index) => (react_1.default.createElement("img", Object.assign({ key: `${galleryImageSrc}-${index}`, src: galleryImageSrc, alt: alt, style: withLightbox ? { cursor: 'pointer' } : undefined }, getLightboxTriggerProps(galleryImageSrc))))))) : null;
|
|
78
98
|
const hasCaption = Boolean(caption);
|
|
79
99
|
const hasWrapper = Boolean(framed || hasCaption || hasGallery);
|
|
80
100
|
const wrapperContent = hasGallery ? gallery : images;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type JSX } from 'react';
|
|
2
|
+
import type { ToolCall } from '../../core/types';
|
|
3
|
+
export type SearchAiActivityProps = {
|
|
4
|
+
/** One run of consecutive tool calls; an empty list means the assistant has not called a tool yet. */
|
|
5
|
+
toolCalls: ToolCall[];
|
|
6
|
+
/** The assistant works on this group now; once it moves on, a call without a result counts as finished. */
|
|
7
|
+
isActive: boolean;
|
|
8
|
+
className?: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function SearchAiActivity({ toolCalls, isActive, className, }: SearchAiActivityProps): JSX.Element;
|