@redocly/theme 0.69.0-next.8 → 0.69.0-next.9
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/Accordion/Accordion.js +5 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations.js +5 -3
- package/lib/components/Catalog/CatalogViewModeToggle.d.ts +1 -1
- package/lib/components/Catalog/CatalogViewModeToggle.js +2 -43
- package/lib/components/Filter/FilterInput.js +4 -2
- package/lib/components/JsonViewer/Helpers.js +12 -42
- package/lib/components/Panel/Panel.js +5 -1
- package/lib/components/Search/FilterFields/SearchFilterFieldSelect.js +22 -32
- package/lib/components/Search/SearchItem.js +5 -3
- package/lib/components/Search/variables.js +1 -0
- package/lib/components/Select/Select.js +10 -5
- package/lib/components/Sidebar/Sidebar.js +2 -38
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.js +5 -17
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.js +1 -0
- package/lib/core/hooks/menu/use-menu-item-expanded.js +1 -0
- package/lib/core/hooks/use-local-state.js +1 -0
- package/lib/core/hooks/use-mobile-menu.js +10 -2
- package/package.json +1 -1
- package/src/components/Accordion/Accordion.tsx +7 -3
- package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations.tsx +6 -4
- package/src/components/Catalog/CatalogViewModeToggle.tsx +2 -17
- package/src/components/Filter/FilterInput.tsx +5 -3
- package/src/components/JsonViewer/Helpers.tsx +13 -9
- package/src/components/Panel/Panel.tsx +7 -3
- package/src/components/Search/FilterFields/SearchFilterFieldSelect.tsx +32 -40
- package/src/components/Search/SearchItem.tsx +6 -1
- package/src/components/Search/variables.ts +1 -0
- package/src/components/Select/Select.tsx +12 -6
- package/src/components/Sidebar/Sidebar.tsx +2 -6
- package/src/core/hooks/code-walkthrough/use-code-walkthrough-controls.ts +6 -20
- package/src/core/hooks/code-walkthrough/use-code-walkthrough-steps.ts +1 -0
- package/src/core/hooks/menu/use-menu-item-expanded.ts +1 -0
- package/src/core/hooks/use-local-state.ts +1 -0
- package/src/core/hooks/use-mobile-menu.ts +11 -3
|
@@ -47,6 +47,11 @@ const ChevronRightIcon_1 = require("../../icons/ChevronRightIcon/ChevronRightIco
|
|
|
47
47
|
function Accordion({ expanded = true, isExpandable = true, renderChildrenHidden = false, header, className, children, onToggle, dataTestId, }) {
|
|
48
48
|
const [isExpanded, setExpanded] = (0, react_1.useState)(expanded);
|
|
49
49
|
const [animate, setAnimate] = (0, react_1.useState)(false);
|
|
50
|
+
const [prevExpanded, setPrevExpanded] = (0, react_1.useState)(expanded);
|
|
51
|
+
if (prevExpanded !== expanded) {
|
|
52
|
+
setPrevExpanded(expanded);
|
|
53
|
+
setExpanded(expanded);
|
|
54
|
+
}
|
|
50
55
|
const toggle = ({ target }) => {
|
|
51
56
|
if (target instanceof HTMLAnchorElement || !isExpandable)
|
|
52
57
|
return;
|
|
@@ -54,7 +59,6 @@ function Accordion({ expanded = true, isExpandable = true, renderChildrenHidden
|
|
|
54
59
|
setExpanded(!isExpanded);
|
|
55
60
|
onToggle === null || onToggle === void 0 ? void 0 : onToggle(!isExpanded);
|
|
56
61
|
};
|
|
57
|
-
(0, react_1.useEffect)(() => setExpanded(expanded), [expanded]);
|
|
58
62
|
return (react_1.default.createElement(AccordionWrapper, { className: className, "data-testid": dataTestId, "data-component-name": "Accordion/Accordion" },
|
|
59
63
|
header &&
|
|
60
64
|
(typeof header === 'function' ? (header({ expanded: isExpanded })) : (react_1.default.createElement(AccordionHeader_1.AccordionHeader, { "data-testid": "accordion-header", onClick: toggle, expanded: isExpanded, isExpandable: isExpandable },
|
package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations.js
CHANGED
|
@@ -48,9 +48,11 @@ function CatalogEntityRelations({ entity, entitiesCatalogConfig, initialRelation
|
|
|
48
48
|
const { useCatalogSort, useFetchCatalogEntitiesRelations } = (0, hooks_1.useThemeHooks)();
|
|
49
49
|
const { sortOption, setSortOption, handleSortClick, isColumnSorted } = useCatalogSort();
|
|
50
50
|
const [filter, setFilter] = (0, react_1.useState)(ENTITY_DEFAULT_FILTERS[entity.type]);
|
|
51
|
-
(0, react_1.
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
const [prevEntityKey, setPrevEntityKey] = (0, react_1.useState)(entity.key);
|
|
52
|
+
if (prevEntityKey !== entity.key) {
|
|
53
|
+
setPrevEntityKey(entity.key);
|
|
54
|
+
setFilter(ENTITY_DEFAULT_FILTERS[entity.type]);
|
|
55
|
+
}
|
|
54
56
|
const combinedFilter = (0, react_1.useMemo)(() => {
|
|
55
57
|
const baseFilter = filter !== null && filter !== void 0 ? filter : ENTITY_DEFAULT_FILTERS[entity.type];
|
|
56
58
|
if (entity.version && entity.revision) {
|
|
@@ -4,4 +4,4 @@ export type CatalogViewModeToggleProps = {
|
|
|
4
4
|
viewMode: CatalogViewMode;
|
|
5
5
|
onViewModeChange: (mode: CatalogViewMode) => void;
|
|
6
6
|
};
|
|
7
|
-
export declare function CatalogViewModeToggle({ viewMode
|
|
7
|
+
export declare function CatalogViewModeToggle({ viewMode, onViewModeChange }: CatalogViewModeToggleProps): React.JSX.Element;
|
|
@@ -1,55 +1,14 @@
|
|
|
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
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
38
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
6
|
exports.CatalogViewModeToggle = CatalogViewModeToggle;
|
|
40
|
-
const react_1 =
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
41
8
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
42
9
|
const TableIcon_1 = require("../../icons/TableIcon/TableIcon");
|
|
43
10
|
const CardsIcon_1 = require("../../icons/CardsIcon/CardsIcon");
|
|
44
|
-
function
|
|
45
|
-
const [viewMode, setViewMode] = (0, react_1.useState)(null);
|
|
46
|
-
(0, react_1.useEffect)(() => {
|
|
47
|
-
setViewMode(initialViewMode);
|
|
48
|
-
}, [initialViewMode]);
|
|
49
|
-
return viewMode;
|
|
50
|
-
}
|
|
51
|
-
function CatalogViewModeToggle({ viewMode: initialViewMode, onViewModeChange, }) {
|
|
52
|
-
const viewMode = useViewMode(initialViewMode);
|
|
11
|
+
function CatalogViewModeToggle({ viewMode, onViewModeChange }) {
|
|
53
12
|
return (react_1.default.createElement(ViewModeToggleWrapper, { "data-component-name": "Catalog/CatalogViewModeToggle" },
|
|
54
13
|
react_1.default.createElement(ViewModeButton, { className: viewMode === 'table' ? 'active' : '', onClick: () => onViewModeChange('table') },
|
|
55
14
|
react_1.default.createElement(TableIcon_1.TableIcon, { size: "var(--catalog-view-mode-table-icon-size)" })),
|
|
@@ -44,9 +44,11 @@ const SearchIcon_1 = require("../../icons/SearchIcon/SearchIcon");
|
|
|
44
44
|
function FilterInput(props) {
|
|
45
45
|
const { value: initialValue, onChange, dataTestId } = props;
|
|
46
46
|
const [value, setValue] = (0, react_1.useState)(initialValue);
|
|
47
|
-
(0, react_1.
|
|
47
|
+
const [prevInitialValue, setPrevInitialValue] = (0, react_1.useState)(initialValue);
|
|
48
|
+
if (prevInitialValue !== initialValue) {
|
|
49
|
+
setPrevInitialValue(initialValue);
|
|
48
50
|
setValue(initialValue);
|
|
49
|
-
}
|
|
51
|
+
}
|
|
50
52
|
const handleChange = (e) => {
|
|
51
53
|
const newValue = e.target.value;
|
|
52
54
|
setValue(newValue);
|
|
@@ -1,43 +1,10 @@
|
|
|
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
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
38
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
6
|
exports.JsonValue = JsonValue;
|
|
40
|
-
const react_1 =
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
41
8
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
42
9
|
const Button_1 = require("../../components/Button/Button");
|
|
43
10
|
const ShowMoreToggleButton_1 = require("../../components/Button/ShowMoreToggleButton");
|
|
@@ -47,14 +14,15 @@ function JsonValue(props) {
|
|
|
47
14
|
const indent = ' '.repeat(level * 2);
|
|
48
15
|
const [isExpandedState, setExpanded] = react_1.default.useState(expandAllSignal !== null && expandAllSignal !== void 0 ? expandAllSignal : level < defaultExpandLevel);
|
|
49
16
|
const isExpanded = expandAllSignal !== undefined && level > 0 ? expandAllSignal : isExpandedState;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
17
|
+
const [prevExpandAllSignal, setPrevExpandAllSignal] = react_1.default.useState(expandAllSignal);
|
|
18
|
+
const [prevLevel, setPrevLevel] = react_1.default.useState(level);
|
|
19
|
+
if (prevExpandAllSignal !== expandAllSignal || prevLevel !== level) {
|
|
20
|
+
setPrevExpandAllSignal(expandAllSignal);
|
|
21
|
+
setPrevLevel(level);
|
|
22
|
+
if (expandAllSignal !== undefined && !(expandAllSignal === false && level === 0)) {
|
|
55
23
|
setExpanded(expandAllSignal);
|
|
56
24
|
}
|
|
57
|
-
}
|
|
25
|
+
}
|
|
58
26
|
const keys = (value && Object.keys(value).filter((key) => value[key] !== undefined)) || []; // filter out undefined properties
|
|
59
27
|
const valueType = typeof value;
|
|
60
28
|
const isPrimitive = (valueType !== 'object' && value !== null) || keys.length === 0;
|
|
@@ -94,11 +62,13 @@ function JsonKeyValue(props) {
|
|
|
94
62
|
const isCollapsible = typeof value === 'object' && value !== null && keys.length > 0;
|
|
95
63
|
const [isExpandedState, setExpanded] = react_1.default.useState(expandAllSignal !== null && expandAllSignal !== void 0 ? expandAllSignal : level < defaultExpandLevel);
|
|
96
64
|
const isExpanded = expandAllSignal !== undefined ? expandAllSignal : isExpandedState;
|
|
97
|
-
|
|
65
|
+
const [prevExpandAllSignal, setPrevExpandAllSignal] = react_1.default.useState(expandAllSignal);
|
|
66
|
+
if (prevExpandAllSignal !== expandAllSignal) {
|
|
67
|
+
setPrevExpandAllSignal(expandAllSignal);
|
|
98
68
|
if (expandAllSignal !== undefined) {
|
|
99
69
|
setExpanded(expandAllSignal);
|
|
100
70
|
}
|
|
101
|
-
}
|
|
71
|
+
}
|
|
102
72
|
const openingPunctuation = Array.isArray(value) ? '[' : '{';
|
|
103
73
|
const closingPunctuation = Array.isArray(value) ? ']' : '}';
|
|
104
74
|
const valueElement = isCollapsible ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
@@ -47,6 +47,11 @@ const ChevronRightIcon_1 = require("../../icons/ChevronRightIcon/ChevronRightIco
|
|
|
47
47
|
function Panel({ expanded = true, isExpandable = true, renderChildrenHidden = false, header, footer, className = 'panel-default', children, onToggle, description, }) {
|
|
48
48
|
const [isExpanded, setExpanded] = (0, react_1.useState)(expanded);
|
|
49
49
|
const [animate, setAnimate] = (0, react_1.useState)(false);
|
|
50
|
+
const [prevExpanded, setPrevExpanded] = (0, react_1.useState)(expanded);
|
|
51
|
+
if (prevExpanded !== expanded) {
|
|
52
|
+
setPrevExpanded(expanded);
|
|
53
|
+
setExpanded(expanded);
|
|
54
|
+
}
|
|
50
55
|
const toggle = ({ target }) => {
|
|
51
56
|
if (target instanceof HTMLAnchorElement || !isExpandable)
|
|
52
57
|
return;
|
|
@@ -54,7 +59,6 @@ function Panel({ expanded = true, isExpandable = true, renderChildrenHidden = fa
|
|
|
54
59
|
setExpanded(!isExpanded);
|
|
55
60
|
onToggle === null || onToggle === void 0 ? void 0 : onToggle(!isExpanded);
|
|
56
61
|
};
|
|
57
|
-
(0, react_1.useEffect)(() => setExpanded(expanded), [expanded]);
|
|
58
62
|
return (react_1.default.createElement(PanelWrapper, { className: className, "data-testid": typeof header === 'string' ? ('panel-' + header).replace(/ /g, '-').toLowerCase() : null, "data-component-name": "Panel/Panel" },
|
|
59
63
|
header &&
|
|
60
64
|
(typeof header === 'function' ? (header({ expanded: isExpanded, toggle })) : (react_1.default.createElement(PanelHeader_1.PanelHeader, { "data-testid": "panel-header", toggle: toggle, expanded: isExpanded, isExpandable: isExpandable },
|
|
@@ -47,13 +47,7 @@ function SearchFilterFieldSelect({ facet, filter, query, selectedValues, onChang
|
|
|
47
47
|
const { useFacetQuery, useTranslate } = (0, hooks_1.useThemeHooks)();
|
|
48
48
|
const { translate } = useTranslate();
|
|
49
49
|
const { searchFacet, setSearchFacet, setSearchFacetQuery } = useFacetQuery(facet.field);
|
|
50
|
-
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
51
|
-
const [selectOptions, setSelectOptions] = (0, react_1.useState)([]);
|
|
52
50
|
const isMultiple = facet.type === 'multi-select';
|
|
53
|
-
(0, react_1.useEffect)(() => {
|
|
54
|
-
setSelectOptions(getSelectOptions());
|
|
55
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
56
|
-
}, [searchFacet, facet]);
|
|
57
51
|
const onSearch = (value) => {
|
|
58
52
|
if (value === null) {
|
|
59
53
|
setSearchFacet(null);
|
|
@@ -67,38 +61,34 @@ function SearchFilterFieldSelect({ facet, filter, query, selectedValues, onChang
|
|
|
67
61
|
});
|
|
68
62
|
}
|
|
69
63
|
};
|
|
70
|
-
const
|
|
71
|
-
return searchFacet
|
|
72
|
-
? searchFacet.values.map(facetValueToSelectOption)
|
|
73
|
-
: facet.values.map(facetValueToSelectOption);
|
|
74
|
-
};
|
|
75
|
-
const facetValueToSelectOption = (facetValue) => {
|
|
76
|
-
if (!facetValue) {
|
|
77
|
-
return { element: null, value: '' };
|
|
78
|
-
}
|
|
79
|
-
if (typeof facetValue === 'string') {
|
|
80
|
-
return {
|
|
81
|
-
element: (react_1.default.createElement(FilterSelectOptionWrapper, null,
|
|
82
|
-
react_1.default.createElement(FilterSelectOptionText, null, facetValue))),
|
|
83
|
-
value: facetValue,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
const { value, count, isCounterVisible } = facetValue;
|
|
88
|
-
return {
|
|
89
|
-
element: (react_1.default.createElement(FilterSelectOptionWrapper, null,
|
|
90
|
-
react_1.default.createElement(FilterSelectOptionText, null, value),
|
|
91
|
-
isCounterVisible && react_1.default.createElement(CounterTag_1.CounterTag, null, count))),
|
|
92
|
-
value: value,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
};
|
|
64
|
+
const selectOptions = (0, react_1.useMemo)(() => (searchFacet ? searchFacet.values : facet.values).map(facetValueToSelectOption), [searchFacet, facet]);
|
|
96
65
|
return (react_1.default.createElement(Select_1.Select, { value: selectedValues.length
|
|
97
66
|
? isMultiple
|
|
98
67
|
? selectedValues.map((value) => facetValueToSelectOption(value))
|
|
99
68
|
: facetValueToSelectOption(selectedValues[0])
|
|
100
69
|
: undefined, options: selectOptions, onChange: onChange, placeholder: `${translate('search.filter.field.placeholder', 'Search')} ${facet.name.toLowerCase()}...`, alignment: "start", multiple: isMultiple, searchable: true, footer: selectOptions.length === MAX_SELECT_OPTIONS ? (react_1.default.createElement(FilterSelectFooter, null, translate('search.filter.field.footer', 'Search to show more items...'))) : null, onSearch: onSearch, checkmarkIconPosition: "start" }));
|
|
101
70
|
}
|
|
71
|
+
function facetValueToSelectOption(facetValue) {
|
|
72
|
+
if (!facetValue) {
|
|
73
|
+
return { element: null, value: '' };
|
|
74
|
+
}
|
|
75
|
+
if (typeof facetValue === 'string') {
|
|
76
|
+
return {
|
|
77
|
+
element: (react_1.default.createElement(FilterSelectOptionWrapper, null,
|
|
78
|
+
react_1.default.createElement(FilterSelectOptionText, null, facetValue))),
|
|
79
|
+
value: facetValue,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const { value, count, isCounterVisible } = facetValue;
|
|
84
|
+
return {
|
|
85
|
+
element: (react_1.default.createElement(FilterSelectOptionWrapper, null,
|
|
86
|
+
react_1.default.createElement(FilterSelectOptionText, null, value),
|
|
87
|
+
isCounterVisible && react_1.default.createElement(CounterTag_1.CounterTag, null, count))),
|
|
88
|
+
value: value,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
102
92
|
const FilterSelectOptionWrapper = styled_components_1.default.div `
|
|
103
93
|
width: 100%;
|
|
104
94
|
display: flex;
|
|
@@ -48,7 +48,7 @@ const utils_1 = require("../../core/utils");
|
|
|
48
48
|
const ReturnKeyIcon_1 = require("../../icons/ReturnKeyIcon/ReturnKeyIcon");
|
|
49
49
|
const hooks_1 = require("../../core/hooks");
|
|
50
50
|
function SearchItem({ onClick, item, className, product, innerRef, }) {
|
|
51
|
-
var _a, _b, _c
|
|
51
|
+
var _a, _b, _c;
|
|
52
52
|
const ref = (0, react_1.useRef)(null);
|
|
53
53
|
const { useTranslate } = (0, hooks_1.useThemeHooks)();
|
|
54
54
|
const { translate } = useTranslate();
|
|
@@ -95,11 +95,13 @@ function SearchItem({ onClick, item, className, product, innerRef, }) {
|
|
|
95
95
|
react_1.default.createElement("div", null,
|
|
96
96
|
(0, SearchHighlight_1.searchHighlight)(parameter.place),
|
|
97
97
|
` → `,
|
|
98
|
-
((_b = parameter.path) === null || _b === void 0 ? void 0 : _b.length) ? (
|
|
98
|
+
((_b = parameter.path) === null || _b === void 0 ? void 0 : _b.length) ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
99
|
+
(0, SearchHighlight_1.searchHighlight)(parameter.path.join(' → ')),
|
|
100
|
+
` → `)) : null,
|
|
99
101
|
(0, SearchHighlight_1.searchHighlight)(parameter.name)),
|
|
100
102
|
react_1.default.createElement("div", null, (0, SearchHighlight_1.searchHighlight)(parameter.description)))) : (shouldShowPath && (react_1.default.createElement(SearchItemPath, null, highlight.path && highlight.path.length
|
|
101
103
|
? (0, SearchHighlight_1.searchHighlight)(highlight.path.join(' → '))
|
|
102
|
-
: (
|
|
104
|
+
: (_c = document.path) === null || _c === void 0 ? void 0 : _c.join(' → '))))),
|
|
103
105
|
react_1.default.createElement(ReturnKeyIcon_1.ReturnKeyIcon, { color: "var(--search-item-text-color)" })));
|
|
104
106
|
}
|
|
105
107
|
const SearchItemWrapper = (0, styled_components_1.default)(Link_1.Link) `
|
|
@@ -98,6 +98,7 @@ exports.search = (0, styled_components_1.css) `
|
|
|
98
98
|
--search-message-line-height: var(--line-height-lg); // @presenter LineHeight
|
|
99
99
|
--search-message-text-color: var(--text-color-secondary); // @presenter Color
|
|
100
100
|
--search-message-gap: var(--spacing-md);
|
|
101
|
+
--search-message-padding: var(--spacing-md);
|
|
101
102
|
|
|
102
103
|
--search-header-buttons-gap: var(--spacing-sm);
|
|
103
104
|
--search-header-buttons-padding-left: var(--spacing-sm);
|
|
@@ -71,13 +71,18 @@ function Select(props) {
|
|
|
71
71
|
(0, hooks_1.useOutsideClick)(selectRef, () => {
|
|
72
72
|
setDropdownActive(false);
|
|
73
73
|
});
|
|
74
|
-
(0, react_1.
|
|
74
|
+
const [prevOptions, setPrevOptions] = (0, react_1.useState)(options);
|
|
75
|
+
const [prevValue, setPrevValue] = (0, react_1.useState)(value);
|
|
76
|
+
const [prevMultiple, setPrevMultiple] = (0, react_1.useState)(multiple);
|
|
77
|
+
if (prevOptions !== options) {
|
|
78
|
+
setPrevOptions(options);
|
|
75
79
|
setFilteredOptions(options);
|
|
76
|
-
}
|
|
77
|
-
(
|
|
80
|
+
}
|
|
81
|
+
if (prevValue !== value || prevMultiple !== multiple) {
|
|
82
|
+
setPrevValue(value);
|
|
83
|
+
setPrevMultiple(multiple);
|
|
78
84
|
setSelectedOptions(getSelectedOptionsFromPropsValue());
|
|
79
|
-
|
|
80
|
-
}, [multiple, value]);
|
|
85
|
+
}
|
|
81
86
|
const changeSearchValue = (newSearchValue) => {
|
|
82
87
|
if (newSearchValue === searchValue) {
|
|
83
88
|
return;
|
|
@@ -1,54 +1,18 @@
|
|
|
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
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
38
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
6
|
exports.SidebarHeader = void 0;
|
|
40
7
|
exports.Sidebar = Sidebar;
|
|
41
|
-
const react_1 =
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
42
9
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
43
10
|
const utils_1 = require("../../core/utils");
|
|
44
11
|
const hooks_1 = require("../../core/hooks");
|
|
45
12
|
const MenuContainer_1 = require("../../components/Menu/MenuContainer");
|
|
46
13
|
function Sidebar({ versions, menu, footer, header, growContent, collapsed, className, menuItemsAnimation, }) {
|
|
47
14
|
const { isOpen } = (0, hooks_1.useMobileMenu)();
|
|
48
|
-
const
|
|
49
|
-
(0, react_1.useEffect)(() => {
|
|
50
|
-
setMappedCollapsed(collapsed && !isOpen);
|
|
51
|
-
}, [isOpen, collapsed, setMappedCollapsed]);
|
|
15
|
+
const mappedCollapsed = collapsed && !isOpen;
|
|
52
16
|
const { sidebar } = (0, hooks_1.useThemeConfig)();
|
|
53
17
|
if (sidebar === null || sidebar === void 0 ? void 0 : sidebar.hide) {
|
|
54
18
|
return null;
|
|
@@ -16,9 +16,6 @@ function useCodeWalkthroughControls(filters, inputs, toggles, enableDeepLink) {
|
|
|
16
16
|
const location = (0, react_router_1.useLocation)();
|
|
17
17
|
const navigate = (0, react_router_1.useNavigate)();
|
|
18
18
|
const searchParams = (0, react_1.useMemo)(() => new URLSearchParams(location.search), [location.search]);
|
|
19
|
-
const filtersRef = (0, react_1.useRef)(filters);
|
|
20
|
-
const inputsRef = (0, react_1.useRef)(inputs);
|
|
21
|
-
const togglesRef = (0, react_1.useRef)(toggles);
|
|
22
19
|
const getInitialState = () => {
|
|
23
20
|
var _a, _b;
|
|
24
21
|
var _c, _d;
|
|
@@ -36,18 +33,10 @@ function useCodeWalkthroughControls(filters, inputs, toggles, enableDeepLink) {
|
|
|
36
33
|
return state;
|
|
37
34
|
};
|
|
38
35
|
const [controlsState, setControlsState] = (0, react_1.useState)(getInitialState);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
JSON.stringify(toggles) === JSON.stringify(togglesRef.current),
|
|
44
|
-
];
|
|
45
|
-
if (sameProps.every(Boolean)) {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
filtersRef.current = filters;
|
|
49
|
-
inputsRef.current = inputs;
|
|
50
|
-
togglesRef.current = toggles;
|
|
36
|
+
const controlsKey = JSON.stringify([filters, inputs, toggles]);
|
|
37
|
+
const [prevControlsKey, setPrevControlsKey] = (0, react_1.useState)(controlsKey);
|
|
38
|
+
if (prevControlsKey !== controlsKey) {
|
|
39
|
+
setPrevControlsKey(controlsKey);
|
|
51
40
|
const newState = getInitialState();
|
|
52
41
|
// Preserve existing values where control type hasn't changed
|
|
53
42
|
Object.entries(newState).forEach(([id, control]) => {
|
|
@@ -58,8 +47,7 @@ function useCodeWalkthroughControls(filters, inputs, toggles, enableDeepLink) {
|
|
|
58
47
|
}
|
|
59
48
|
});
|
|
60
49
|
setControlsState(newState);
|
|
61
|
-
|
|
62
|
-
}, [filters, inputs, toggles, enableDeepLink]);
|
|
50
|
+
}
|
|
63
51
|
const changeControlState = (id, value) => {
|
|
64
52
|
setControlsState((prev) => {
|
|
65
53
|
const control = prev[id];
|
|
@@ -171,6 +171,7 @@ function useCodeWalkthroughSteps({ steps, enableDeepLink, root, }) {
|
|
|
171
171
|
}
|
|
172
172
|
const rootTopOffset = (_c = (_a = root.current) === null || _a === void 0 ? void 0 : _a.offsetTop) !== null && _c !== void 0 ? _c : 0;
|
|
173
173
|
if (!activeStep && rootTopOffset <= options.navbarHeight) {
|
|
174
|
+
// oxlint-disable-next-line react-you-might-not-need-an-effect/no-derived-state -- seeded from root.current.offsetTop, a post-layout measurement
|
|
174
175
|
setActiveStep(((_b = visibleSteps[0]) === null || _b === void 0 ? void 0 : _b.id) || null);
|
|
175
176
|
}
|
|
176
177
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -11,6 +11,7 @@ function useMenuItemExpanded(item) {
|
|
|
11
11
|
// it's important for transitions
|
|
12
12
|
const [controlledValue, setControlledValue] = (0, react_1.useState)(isItemExpanded(item));
|
|
13
13
|
(0, react_1.useEffect)(() => {
|
|
14
|
+
// oxlint-disable-next-line react-you-might-not-need-an-effect/no-derived-state -- deferred a commit on purpose so CSS transitions still run
|
|
14
15
|
setIsExpanded(controlledValue);
|
|
15
16
|
}, [controlledValue]);
|
|
16
17
|
(0, react_1.useEffect)(() => {
|
|
@@ -22,6 +22,7 @@ function useLocalState(key, initialValue) {
|
|
|
22
22
|
(0, react_1.useEffect)(() => {
|
|
23
23
|
if (!(0, js_utils_1.isBrowser)())
|
|
24
24
|
return;
|
|
25
|
+
// oxlint-disable-next-line react-you-might-not-need-an-effect/no-derived-state -- localStorage is read after mount so SSR and client hydrate from the same value
|
|
25
26
|
setValue(getStoredValue(key, initialValue));
|
|
26
27
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
27
28
|
}, [key]);
|
|
@@ -7,9 +7,17 @@ const use_modal_scroll_lock_1 = require("./use-modal-scroll-lock");
|
|
|
7
7
|
function useMobileMenu(initialState = false) {
|
|
8
8
|
const location = (0, react_router_1.useLocation)();
|
|
9
9
|
const [isOpen, setIsOpen] = (0, react_1.useState)(initialState);
|
|
10
|
-
|
|
10
|
+
const locationKey = `${location.pathname}${location.hash}`;
|
|
11
|
+
const [prevLocationKey, setPrevLocationKey] = (0, react_1.useState)(locationKey);
|
|
12
|
+
if (isOpen && prevLocationKey !== locationKey) {
|
|
13
|
+
setPrevLocationKey(locationKey);
|
|
14
|
+
setIsOpen(false);
|
|
15
|
+
}
|
|
11
16
|
(0, use_modal_scroll_lock_1.useModalScrollLock)(isOpen);
|
|
12
|
-
const openMobileMenu = () =>
|
|
17
|
+
const openMobileMenu = () => {
|
|
18
|
+
setPrevLocationKey(locationKey);
|
|
19
|
+
setIsOpen(true);
|
|
20
|
+
};
|
|
13
21
|
const closeMobileMenu = () => setIsOpen(false);
|
|
14
22
|
return { isOpen, openMobileMenu, closeMobileMenu };
|
|
15
23
|
}
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import type { BaseSyntheticEvent, PropsWithChildren, ReactNode, JSX } from 'react';
|
|
@@ -32,6 +32,12 @@ export function Accordion({
|
|
|
32
32
|
}: PropsWithChildren<AccordionProps>): JSX.Element {
|
|
33
33
|
const [isExpanded, setExpanded] = useState(expanded);
|
|
34
34
|
const [animate, setAnimate] = useState(false);
|
|
35
|
+
const [prevExpanded, setPrevExpanded] = useState(expanded);
|
|
36
|
+
|
|
37
|
+
if (prevExpanded !== expanded) {
|
|
38
|
+
setPrevExpanded(expanded);
|
|
39
|
+
setExpanded(expanded);
|
|
40
|
+
}
|
|
35
41
|
|
|
36
42
|
const toggle = ({ target }: BaseSyntheticEvent): void => {
|
|
37
43
|
if (target instanceof HTMLAnchorElement || !isExpandable) return;
|
|
@@ -40,8 +46,6 @@ export function Accordion({
|
|
|
40
46
|
onToggle?.(!isExpanded);
|
|
41
47
|
};
|
|
42
48
|
|
|
43
|
-
useEffect(() => setExpanded(expanded), [expanded]);
|
|
44
|
-
|
|
45
49
|
return (
|
|
46
50
|
<AccordionWrapper
|
|
47
51
|
className={className}
|
package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { JSX, useState,
|
|
1
|
+
import React, { JSX, useState, useMemo } from 'react';
|
|
2
2
|
|
|
3
3
|
import type { CatalogEntityConfig, EntitiesCatalogConfig } from '@redocly/config';
|
|
4
4
|
import type { BffCatalogEntity, BffCatalogRelatedEntityList } from '@redocly/theme/core/types';
|
|
@@ -35,10 +35,12 @@ export function CatalogEntityRelations({
|
|
|
35
35
|
const { sortOption, setSortOption, handleSortClick, isColumnSorted } = useCatalogSort();
|
|
36
36
|
|
|
37
37
|
const [filter, setFilter] = useState<string | undefined>(ENTITY_DEFAULT_FILTERS[entity.type]);
|
|
38
|
+
const [prevEntityKey, setPrevEntityKey] = useState(entity.key);
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
if (prevEntityKey !== entity.key) {
|
|
41
|
+
setPrevEntityKey(entity.key);
|
|
42
|
+
setFilter(ENTITY_DEFAULT_FILTERS[entity.type]);
|
|
43
|
+
}
|
|
42
44
|
|
|
43
45
|
const combinedFilter = useMemo(() => {
|
|
44
46
|
const baseFilter = filter ?? ENTITY_DEFAULT_FILTERS[entity.type];
|
|
@@ -1,31 +1,16 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import { TableIcon } from '@redocly/theme/icons/TableIcon/TableIcon';
|
|
5
5
|
import { CardsIcon } from '@redocly/theme/icons/CardsIcon/CardsIcon';
|
|
6
6
|
import { CatalogViewMode } from '@redocly/theme/core/types';
|
|
7
7
|
|
|
8
|
-
function useViewMode(initialViewMode: CatalogViewMode) {
|
|
9
|
-
const [viewMode, setViewMode] = useState<CatalogViewMode | null>(null);
|
|
10
|
-
|
|
11
|
-
useEffect(() => {
|
|
12
|
-
setViewMode(initialViewMode);
|
|
13
|
-
}, [initialViewMode]);
|
|
14
|
-
|
|
15
|
-
return viewMode;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
8
|
export type CatalogViewModeToggleProps = {
|
|
19
9
|
viewMode: CatalogViewMode;
|
|
20
10
|
onViewModeChange: (mode: CatalogViewMode) => void;
|
|
21
11
|
};
|
|
22
12
|
|
|
23
|
-
export function CatalogViewModeToggle({
|
|
24
|
-
viewMode: initialViewMode,
|
|
25
|
-
onViewModeChange,
|
|
26
|
-
}: CatalogViewModeToggleProps) {
|
|
27
|
-
const viewMode = useViewMode(initialViewMode);
|
|
28
|
-
|
|
13
|
+
export function CatalogViewModeToggle({ viewMode, onViewModeChange }: CatalogViewModeToggleProps) {
|
|
29
14
|
return (
|
|
30
15
|
<ViewModeToggleWrapper data-component-name="Catalog/CatalogViewModeToggle">
|
|
31
16
|
<ViewModeButton
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
@@ -16,10 +16,12 @@ export function FilterInput(props: FilterInputProps): JSX.Element {
|
|
|
16
16
|
const { value: initialValue, onChange, dataTestId } = props;
|
|
17
17
|
|
|
18
18
|
const [value, setValue] = useState(initialValue);
|
|
19
|
+
const [prevInitialValue, setPrevInitialValue] = useState(initialValue);
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
if (prevInitialValue !== initialValue) {
|
|
22
|
+
setPrevInitialValue(initialValue);
|
|
21
23
|
setValue(initialValue);
|
|
22
|
-
}
|
|
24
|
+
}
|
|
23
25
|
|
|
24
26
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
25
27
|
const newValue = e.target.value;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
@@ -23,14 +23,16 @@ export function JsonValue(props: {
|
|
|
23
23
|
expandAllSignal ?? level < defaultExpandLevel,
|
|
24
24
|
);
|
|
25
25
|
const isExpanded = expandAllSignal !== undefined && level > 0 ? expandAllSignal : isExpandedState;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
const [prevExpandAllSignal, setPrevExpandAllSignal] = React.useState(expandAllSignal);
|
|
27
|
+
const [prevLevel, setPrevLevel] = React.useState(level);
|
|
28
|
+
|
|
29
|
+
if (prevExpandAllSignal !== expandAllSignal || prevLevel !== level) {
|
|
30
|
+
setPrevExpandAllSignal(expandAllSignal);
|
|
31
|
+
setPrevLevel(level);
|
|
32
|
+
if (expandAllSignal !== undefined && !(expandAllSignal === false && level === 0)) {
|
|
31
33
|
setExpanded(expandAllSignal);
|
|
32
34
|
}
|
|
33
|
-
}
|
|
35
|
+
}
|
|
34
36
|
|
|
35
37
|
const keys: string[] =
|
|
36
38
|
(value && Object.keys(value).filter((key) => value[key] !== undefined)) || []; // filter out undefined properties
|
|
@@ -131,12 +133,14 @@ function JsonKeyValue(props: {
|
|
|
131
133
|
expandAllSignal ?? level < defaultExpandLevel,
|
|
132
134
|
);
|
|
133
135
|
const isExpanded = expandAllSignal !== undefined ? expandAllSignal : isExpandedState;
|
|
136
|
+
const [prevExpandAllSignal, setPrevExpandAllSignal] = React.useState(expandAllSignal);
|
|
134
137
|
|
|
135
|
-
|
|
138
|
+
if (prevExpandAllSignal !== expandAllSignal) {
|
|
139
|
+
setPrevExpandAllSignal(expandAllSignal);
|
|
136
140
|
if (expandAllSignal !== undefined) {
|
|
137
141
|
setExpanded(expandAllSignal);
|
|
138
142
|
}
|
|
139
|
-
}
|
|
143
|
+
}
|
|
140
144
|
|
|
141
145
|
const openingPunctuation = Array.isArray(value) ? '[' : '{';
|
|
142
146
|
const closingPunctuation = Array.isArray(value) ? ']' : '}';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import type { BaseSyntheticEvent, PropsWithChildren, ReactNode, JSX } from 'react';
|
|
@@ -34,6 +34,12 @@ export function Panel({
|
|
|
34
34
|
}: PropsWithChildren<PanelProps>): JSX.Element {
|
|
35
35
|
const [isExpanded, setExpanded] = useState(expanded);
|
|
36
36
|
const [animate, setAnimate] = useState(false);
|
|
37
|
+
const [prevExpanded, setPrevExpanded] = useState(expanded);
|
|
38
|
+
|
|
39
|
+
if (prevExpanded !== expanded) {
|
|
40
|
+
setPrevExpanded(expanded);
|
|
41
|
+
setExpanded(expanded);
|
|
42
|
+
}
|
|
37
43
|
|
|
38
44
|
const toggle = ({ target }: BaseSyntheticEvent): void => {
|
|
39
45
|
if (target instanceof HTMLAnchorElement || !isExpandable) return;
|
|
@@ -42,8 +48,6 @@ export function Panel({
|
|
|
42
48
|
onToggle?.(!isExpanded);
|
|
43
49
|
};
|
|
44
50
|
|
|
45
|
-
useEffect(() => setExpanded(expanded), [expanded]);
|
|
46
|
-
|
|
47
51
|
return (
|
|
48
52
|
<PanelWrapper
|
|
49
53
|
className={className}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import type { SearchFacet, SearchFacetCount, SearchFilterItem } from '@redocly/theme/core/types';
|
|
@@ -27,15 +27,8 @@ export function SearchFilterFieldSelect({
|
|
|
27
27
|
const { useFacetQuery, useTranslate } = useThemeHooks();
|
|
28
28
|
const { translate } = useTranslate();
|
|
29
29
|
const { searchFacet, setSearchFacet, setSearchFacetQuery } = useFacetQuery(facet.field);
|
|
30
|
-
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
31
|
-
const [selectOptions, setSelectOptions] = useState<any[]>([]);
|
|
32
30
|
const isMultiple = facet.type === 'multi-select';
|
|
33
31
|
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
setSelectOptions(getSelectOptions());
|
|
36
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
37
|
-
}, [searchFacet, facet]);
|
|
38
|
-
|
|
39
32
|
const onSearch = (value: string | null) => {
|
|
40
33
|
if (value === null) {
|
|
41
34
|
setSearchFacet(null);
|
|
@@ -49,38 +42,10 @@ export function SearchFilterFieldSelect({
|
|
|
49
42
|
}
|
|
50
43
|
};
|
|
51
44
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const facetValueToSelectOption = (facetValue?: SearchFacetCount | string) => {
|
|
59
|
-
if (!facetValue) {
|
|
60
|
-
return { element: null, value: '' };
|
|
61
|
-
}
|
|
62
|
-
if (typeof facetValue === 'string') {
|
|
63
|
-
return {
|
|
64
|
-
element: (
|
|
65
|
-
<FilterSelectOptionWrapper>
|
|
66
|
-
<FilterSelectOptionText>{facetValue}</FilterSelectOptionText>
|
|
67
|
-
</FilterSelectOptionWrapper>
|
|
68
|
-
),
|
|
69
|
-
value: facetValue,
|
|
70
|
-
};
|
|
71
|
-
} else {
|
|
72
|
-
const { value, count, isCounterVisible } = facetValue as SearchFacetCount;
|
|
73
|
-
return {
|
|
74
|
-
element: (
|
|
75
|
-
<FilterSelectOptionWrapper>
|
|
76
|
-
<FilterSelectOptionText>{value}</FilterSelectOptionText>
|
|
77
|
-
{isCounterVisible && <CounterTag>{count}</CounterTag>}
|
|
78
|
-
</FilterSelectOptionWrapper>
|
|
79
|
-
),
|
|
80
|
-
value: value,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
};
|
|
45
|
+
const selectOptions = useMemo(
|
|
46
|
+
() => (searchFacet ? searchFacet.values : facet.values).map(facetValueToSelectOption),
|
|
47
|
+
[searchFacet, facet],
|
|
48
|
+
);
|
|
84
49
|
|
|
85
50
|
return (
|
|
86
51
|
<Select
|
|
@@ -113,6 +78,33 @@ export function SearchFilterFieldSelect({
|
|
|
113
78
|
);
|
|
114
79
|
}
|
|
115
80
|
|
|
81
|
+
function facetValueToSelectOption(facetValue?: SearchFacetCount | string) {
|
|
82
|
+
if (!facetValue) {
|
|
83
|
+
return { element: null, value: '' };
|
|
84
|
+
}
|
|
85
|
+
if (typeof facetValue === 'string') {
|
|
86
|
+
return {
|
|
87
|
+
element: (
|
|
88
|
+
<FilterSelectOptionWrapper>
|
|
89
|
+
<FilterSelectOptionText>{facetValue}</FilterSelectOptionText>
|
|
90
|
+
</FilterSelectOptionWrapper>
|
|
91
|
+
),
|
|
92
|
+
value: facetValue,
|
|
93
|
+
};
|
|
94
|
+
} else {
|
|
95
|
+
const { value, count, isCounterVisible } = facetValue as SearchFacetCount;
|
|
96
|
+
return {
|
|
97
|
+
element: (
|
|
98
|
+
<FilterSelectOptionWrapper>
|
|
99
|
+
<FilterSelectOptionText>{value}</FilterSelectOptionText>
|
|
100
|
+
{isCounterVisible && <CounterTag>{count}</CounterTag>}
|
|
101
|
+
</FilterSelectOptionWrapper>
|
|
102
|
+
),
|
|
103
|
+
value: value,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
116
108
|
const FilterSelectOptionWrapper = styled.div`
|
|
117
109
|
width: 100%;
|
|
118
110
|
display: flex;
|
|
@@ -114,7 +114,12 @@ export function SearchItem({
|
|
|
114
114
|
<div>
|
|
115
115
|
{searchHighlight(parameter.place)}
|
|
116
116
|
{` → `}
|
|
117
|
-
{parameter.path?.length ?
|
|
117
|
+
{parameter.path?.length ? (
|
|
118
|
+
<>
|
|
119
|
+
{searchHighlight(parameter.path.join(' → '))}
|
|
120
|
+
{` → `}
|
|
121
|
+
</>
|
|
122
|
+
) : null}
|
|
118
123
|
{searchHighlight(parameter.name)}
|
|
119
124
|
</div>
|
|
120
125
|
<div>{searchHighlight(parameter.description)}</div>
|
|
@@ -97,6 +97,7 @@ export const search = css`
|
|
|
97
97
|
--search-message-line-height: var(--line-height-lg); // @presenter LineHeight
|
|
98
98
|
--search-message-text-color: var(--text-color-secondary); // @presenter Color
|
|
99
99
|
--search-message-gap: var(--spacing-md);
|
|
100
|
+
--search-message-padding: var(--spacing-md);
|
|
100
101
|
|
|
101
102
|
--search-header-buttons-gap: var(--spacing-sm);
|
|
102
103
|
--search-header-buttons-padding-left: var(--spacing-sm);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { Fragment,
|
|
1
|
+
import React, { Fragment, useId, useRef, useState } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
@@ -68,14 +68,20 @@ export function Select<T>(props: SelectProps<T>): JSX.Element {
|
|
|
68
68
|
setDropdownActive(false);
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
const [prevOptions, setPrevOptions] = useState(options);
|
|
72
|
+
const [prevValue, setPrevValue] = useState(value);
|
|
73
|
+
const [prevMultiple, setPrevMultiple] = useState(multiple);
|
|
74
|
+
|
|
75
|
+
if (prevOptions !== options) {
|
|
76
|
+
setPrevOptions(options);
|
|
72
77
|
setFilteredOptions(options);
|
|
73
|
-
}
|
|
78
|
+
}
|
|
74
79
|
|
|
75
|
-
|
|
80
|
+
if (prevValue !== value || prevMultiple !== multiple) {
|
|
81
|
+
setPrevValue(value);
|
|
82
|
+
setPrevMultiple(multiple);
|
|
76
83
|
setSelectedOptions(getSelectedOptionsFromPropsValue());
|
|
77
|
-
|
|
78
|
-
}, [multiple, value]);
|
|
84
|
+
}
|
|
79
85
|
|
|
80
86
|
const changeSearchValue = (newSearchValue: string | null) => {
|
|
81
87
|
if (newSearchValue === searchValue) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
@@ -36,11 +36,7 @@ export function Sidebar({
|
|
|
36
36
|
menuItemsAnimation,
|
|
37
37
|
}: SidebarProps): JSX.Element | null {
|
|
38
38
|
const { isOpen } = useMobileMenu();
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
setMappedCollapsed(collapsed && !isOpen);
|
|
43
|
-
}, [isOpen, collapsed, setMappedCollapsed]);
|
|
39
|
+
const mappedCollapsed = collapsed && !isOpen;
|
|
44
40
|
|
|
45
41
|
const { sidebar } = useThemeConfig();
|
|
46
42
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState, useEffect, useMemo
|
|
1
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
2
2
|
import { useLocation, useNavigate } from 'react-router';
|
|
3
3
|
|
|
4
4
|
import type {
|
|
@@ -50,10 +50,6 @@ export function useCodeWalkthroughControls(
|
|
|
50
50
|
const navigate = useNavigate();
|
|
51
51
|
const searchParams = useMemo(() => new URLSearchParams(location.search), [location.search]);
|
|
52
52
|
|
|
53
|
-
const filtersRef = useRef(filters);
|
|
54
|
-
const inputsRef = useRef(inputs);
|
|
55
|
-
const togglesRef = useRef(toggles);
|
|
56
|
-
|
|
57
53
|
const getInitialState = () => {
|
|
58
54
|
const state: CodeWalkthroughControlsState = {};
|
|
59
55
|
|
|
@@ -90,20 +86,11 @@ export function useCodeWalkthroughControls(
|
|
|
90
86
|
|
|
91
87
|
const [controlsState, setControlsState] = useState(getInitialState);
|
|
92
88
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
JSON.stringify(filters) === JSON.stringify(filtersRef.current),
|
|
96
|
-
JSON.stringify(inputs) === JSON.stringify(inputsRef.current),
|
|
97
|
-
JSON.stringify(toggles) === JSON.stringify(togglesRef.current),
|
|
98
|
-
];
|
|
99
|
-
|
|
100
|
-
if (sameProps.every(Boolean)) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
89
|
+
const controlsKey = JSON.stringify([filters, inputs, toggles]);
|
|
90
|
+
const [prevControlsKey, setPrevControlsKey] = useState(controlsKey);
|
|
103
91
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
togglesRef.current = toggles;
|
|
92
|
+
if (prevControlsKey !== controlsKey) {
|
|
93
|
+
setPrevControlsKey(controlsKey);
|
|
107
94
|
|
|
108
95
|
const newState = getInitialState();
|
|
109
96
|
|
|
@@ -120,8 +107,7 @@ export function useCodeWalkthroughControls(
|
|
|
120
107
|
});
|
|
121
108
|
|
|
122
109
|
setControlsState(newState);
|
|
123
|
-
|
|
124
|
-
}, [filters, inputs, toggles, enableDeepLink]);
|
|
110
|
+
}
|
|
125
111
|
|
|
126
112
|
const changeControlState = (id: string, value: string | boolean) => {
|
|
127
113
|
setControlsState((prev) => {
|
|
@@ -252,6 +252,7 @@ export function useCodeWalkthroughSteps({
|
|
|
252
252
|
|
|
253
253
|
const rootTopOffset = root.current?.offsetTop ?? 0;
|
|
254
254
|
if (!activeStep && rootTopOffset <= options.navbarHeight) {
|
|
255
|
+
// oxlint-disable-next-line react-you-might-not-need-an-effect/no-derived-state -- seeded from root.current.offsetTop, a post-layout measurement
|
|
255
256
|
setActiveStep(visibleSteps[0]?.id || null);
|
|
256
257
|
}
|
|
257
258
|
|
|
@@ -16,6 +16,7 @@ export function useMenuItemExpanded(item: ItemState): [boolean, Dispatch<SetStat
|
|
|
16
16
|
const [controlledValue, setControlledValue] = useState(isItemExpanded(item));
|
|
17
17
|
|
|
18
18
|
useEffect(() => {
|
|
19
|
+
// oxlint-disable-next-line react-you-might-not-need-an-effect/no-derived-state -- deferred a commit on purpose so CSS transitions still run
|
|
19
20
|
setIsExpanded(controlledValue);
|
|
20
21
|
}, [controlledValue]);
|
|
21
22
|
|
|
@@ -21,6 +21,7 @@ export function useLocalState<T>(key: string, initialValue: T): [T, (value: T) =
|
|
|
21
21
|
// then client loads the actual stored value without hydration mismatch
|
|
22
22
|
useEffect(() => {
|
|
23
23
|
if (!isBrowser()) return;
|
|
24
|
+
// oxlint-disable-next-line react-you-might-not-need-an-effect/no-derived-state -- localStorage is read after mount so SSR and client hydrate from the same value
|
|
24
25
|
setValue(getStoredValue(key, initialValue));
|
|
25
26
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
26
27
|
}, [key]);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useState } from 'react';
|
|
2
2
|
import { useLocation } from 'react-router';
|
|
3
3
|
|
|
4
4
|
import { useModalScrollLock } from './use-modal-scroll-lock';
|
|
@@ -6,11 +6,19 @@ import { useModalScrollLock } from './use-modal-scroll-lock';
|
|
|
6
6
|
export function useMobileMenu(initialState = false) {
|
|
7
7
|
const location = useLocation();
|
|
8
8
|
const [isOpen, setIsOpen] = useState(initialState);
|
|
9
|
+
const locationKey = `${location.pathname}${location.hash}`;
|
|
10
|
+
const [prevLocationKey, setPrevLocationKey] = useState(locationKey);
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
if (isOpen && prevLocationKey !== locationKey) {
|
|
13
|
+
setPrevLocationKey(locationKey);
|
|
14
|
+
setIsOpen(false);
|
|
15
|
+
}
|
|
11
16
|
useModalScrollLock(isOpen);
|
|
12
17
|
|
|
13
|
-
const openMobileMenu = () =>
|
|
18
|
+
const openMobileMenu = () => {
|
|
19
|
+
setPrevLocationKey(locationKey);
|
|
20
|
+
setIsOpen(true);
|
|
21
|
+
};
|
|
14
22
|
const closeMobileMenu = () => setIsOpen(false);
|
|
15
23
|
|
|
16
24
|
return { isOpen, openMobileMenu, closeMobileMenu };
|