@redocly/theme 0.19.1 → 0.19.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.
@@ -10,5 +10,7 @@ export declare const FilterControls: import("styled-components").StyledComponent
10
10
  export declare const CatalogPageContent: import("styled-components").StyledComponent<"main", any, {}, never>;
11
11
  export declare const CatalogTitle: import("styled-components").StyledComponent<"h2", any, {}, never>;
12
12
  export declare const CatalogDescription: import("styled-components").StyledComponent<"p", any, {}, never>;
13
- export declare const CatalogPageWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
13
+ export declare const CatalogPageWrapper: import("styled-components").StyledComponent<"div", any, {
14
+ withoutFilters?: boolean | undefined;
15
+ }, never>;
14
16
  export declare const CatalogPageDescriptionWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -27,10 +27,10 @@ function Catalog(props) {
27
27
  const { translate } = (0, index_1.useTranslate)();
28
28
  (0, useModalScrollLock_1.default)(isAddingFilter);
29
29
  return (react_1.default.createElement(Highlight_1.HighlightContext.Provider, { value: [filterTerm] },
30
- react_1.default.createElement(exports.CatalogPageWrapper, null,
31
- react_1.default.createElement(FilterTagsWrapper, null,
30
+ react_1.default.createElement(exports.CatalogPageWrapper, { withoutFilters: !filters.length },
31
+ !!filters.length && (react_1.default.createElement(FilterTagsWrapper, null,
32
32
  react_1.default.createElement(Button_1.Button, { variant: "text", size: "small", icon: react_1.default.createElement(PlusIcon_1.PlusIcon, null), onClick: () => setIsAddingFilter(true) }, translate(translationKeys.addFilter, 'Add filter')),
33
- react_1.default.createElement(FilterTags_1.FilterTags, { filters: filters })),
33
+ react_1.default.createElement(FilterTags_1.FilterTags, { filters: filters }))),
34
34
  react_1.default.createElement(FilterContent_1.FilterContent, { setFilterTerm: setFilterTerm, filters: filters, filterTerm: filterTerm, isMobile: false, filterValuesCasing: catalogConfig.filterValuesCasing }),
35
35
  isAddingFilter && (react_1.default.createElement(FilterPopover_1.FilterPopover, { setIsAddingFilter: setIsAddingFilter, filters: filters, filterValuesCasing: catalogConfig.filterValuesCasing })),
36
36
  react_1.default.createElement(exports.CatalogPageContent, null,
@@ -101,16 +101,13 @@ exports.CatalogTitle = (0, styled_components_1.default)(H2_1.H2) `
101
101
  color: var(--catalog-title-text-color);
102
102
  font-weight: var(--catalog-title-font-weight);
103
103
  font-size: var(--catalog-title-font-size);
104
-
105
- && {
106
- margin: 0;
107
- }
104
+ margin: var(--catalog-title-margin);
108
105
  `;
109
106
  exports.CatalogDescription = styled_components_1.default.p `
110
107
  color: var(--catalog-description-text-color);
111
108
  font-weight: var(--catalog-description-font-weight);
112
109
  font-size: var(--catalog-description-font-size);
113
- margin: var(--catalog-description-margin-top) 0 var(--catalog-description-margin-bottom) 0;
110
+ margin: var(--catalog-description-margin);
114
111
  `;
115
112
  exports.CatalogPageWrapper = styled_components_1.default.div `
116
113
  --sidebar-width: var(--catalog-sidebar-width, 285px);
@@ -119,7 +116,6 @@ exports.CatalogPageWrapper = styled_components_1.default.div `
119
116
  flex-direction: column;
120
117
 
121
118
  font-weight: var(--font-weight-regular);
122
- padding: 0;
123
119
 
124
120
  color: var(--text-secondary);
125
121
  font-size: var(--font-size-base);
@@ -138,8 +134,11 @@ exports.CatalogPageWrapper = styled_components_1.default.div `
138
134
  font-weight: var(--link-font-weight);
139
135
  }
140
136
 
137
+ padding: ${({ withoutFilters }) => (withoutFilters ? 'var(--spacing-base) 0 0 0' : '0')};
138
+
141
139
  ${({ theme }) => theme.mediaQueries.medium} {
142
140
  flex-direction: row;
141
+ padding: 0;
143
142
  }
144
143
  `;
145
144
  const FilterTagsWrapper = styled_components_1.default.div.attrs({ 'data-cy': 'Catalog/FilterTags' }) `
@@ -172,6 +171,7 @@ const FilterTagsWrapper = styled_components_1.default.div.attrs({ 'data-cy': 'Ca
172
171
  }
173
172
  `;
174
173
  exports.CatalogPageDescriptionWrapper = styled_components_1.default.div `
174
+ margin: var(--catalog-heading-margin);
175
175
  display: none;
176
176
 
177
177
  ${({ theme }) => theme.mediaQueries.medium} {
@@ -14,12 +14,15 @@ exports.catalog = (0, styled_components_1.css) `
14
14
  --mobile-catalog-filter-padding-vertical: var(--spacing-sm);
15
15
  --mobile-catalog-filter-padding-horizontal: var(--spacing-base);
16
16
 
17
+ --catalog-heading-margin: 0 0 var(--spacing-xl) 0;
18
+
17
19
  /**
18
20
  * @tokens Catalog page title
19
21
  */
20
22
  --catalog-title-text-color: var(--text-primary);
21
23
  --catalog-title-font-weight: var(--font-weight-bold);
22
24
  --catalog-title-font-size: var(--font-size-heading-3);
25
+ --catalog-title-margin: 0 0 var(--spacing-sm) 0;
23
26
 
24
27
  /**
25
28
  * @tokens Catalog page description
@@ -27,8 +30,7 @@ exports.catalog = (0, styled_components_1.css) `
27
30
  --catalog-description-text-color: var(--text-secondary);
28
31
  --catalog-description-font-weight: var(--font-weight-regular);
29
32
  --catalog-description-font-size: var(--font-size-base);
30
- --catalog-description-margin-top: var(--spacing-sm);
31
- --catalog-description-margin-bottom: var(--spacing-xl);
33
+ --catalog-description-margin: 0 0 var(--spacing-sm) 0;
32
34
 
33
35
  /**
34
36
  * @tokens Catalog page separator
@@ -27,10 +27,13 @@ exports.useCatalog = void 0;
27
27
  const React = __importStar(require("react"));
28
28
  const react_router_dom_1 = require("react-router-dom");
29
29
  const telemetry_1 = require("../../mocks/telemetry");
30
+ const usePageData_1 = require("../../mocks/hooks/usePageData");
30
31
  const utils_1 = require("../../utils");
31
32
  function useCatalog(items, config) {
33
+ var _a;
32
34
  const location = (0, react_router_dom_1.useLocation)();
33
35
  const navigate = (0, react_router_dom_1.useNavigate)();
36
+ const pageData = (0, usePageData_1.usePageData)();
34
37
  const searchParams = useSearchParams(location);
35
38
  const [filtersState, setFiltersState] = React.useState(() => {
36
39
  var _a;
@@ -47,7 +50,8 @@ function useCatalog(items, config) {
47
50
  });
48
51
  const [filterTerm, setFilterTerm] = React.useState(() => searchParams.get('filter') || '');
49
52
  const filtersWithOptions = React.useMemo(() => collectFilterOptions(items, config.filters), [items, config.filters]);
50
- const normalizedItems = React.useMemo(() => normalizeItems(items, config), [items, config]);
53
+ const customFields = (_a = pageData === null || pageData === void 0 ? void 0 : pageData.props) === null || _a === void 0 ? void 0 : _a.customFields;
54
+ const normalizedItems = React.useMemo(() => normalizeItems(items, config, customFields || {}), [items, config, customFields]);
51
55
  const toggleOption = React.useCallback((filterIdx, option) => {
52
56
  setFiltersState((prev) => {
53
57
  const newFilterOptions = prev[filterIdx] ? prev[filterIdx] : new Set();
@@ -115,8 +119,8 @@ function useCatalog(items, config) {
115
119
  return React.useMemo(() => {
116
120
  var _a;
117
121
  const filters = filtersWithOptions.map((filter, idx) => {
118
- var _a, _b, _c;
119
- return (Object.assign(Object.assign({}, filter), { toggleOption: (value) => toggleOption(idx, value), selectOption: (value) => selectOption(idx, value), selectedOptions: (_a = filtersState[idx]) !== null && _a !== void 0 ? _a : new Set(), isFilterUsed: ((_c = (_b = filtersState[idx]) === null || _b === void 0 ? void 0 : _b.size) !== null && _c !== void 0 ? _c : 0) > 0 || !!filtersState[idx].from }));
122
+ var _a, _b, _c, _d;
123
+ return (Object.assign(Object.assign({}, filter), { toggleOption: (value) => toggleOption(idx, value), selectOption: (value) => selectOption(idx, value), selectedOptions: (_a = filtersState[idx]) !== null && _a !== void 0 ? _a : new Set(), isFilterUsed: ((_c = (_b = filtersState[idx]) === null || _b === void 0 ? void 0 : _b.size) !== null && _c !== void 0 ? _c : 0) > 0 || !!((_d = filtersState[idx]) === null || _d === void 0 ? void 0 : _d.from) }));
120
124
  });
121
125
  const filteredItems = filterItems(normalizedItems, filters, filterTerm);
122
126
  // add more information to filters state which is known only after filtering items
@@ -178,7 +182,7 @@ function groupByFirstFilter(filters, filteredItems) {
178
182
  function useSearchParams(location) {
179
183
  return React.useMemo(() => new URLSearchParams(location.search), [location.search]);
180
184
  }
181
- function normalizeItems(items, config) {
185
+ function normalizeItems(items, config, customFields) {
182
186
  // because of RBAC some versions can be missing so we need to pick up other default version
183
187
  const hasDeafultVersion = {};
184
188
  for (const item of items) {
@@ -203,9 +207,10 @@ function normalizeItems(items, config) {
203
207
  return items.map((item) => {
204
208
  var _a, _b, _c;
205
209
  const metadata = item.metadata || {};
210
+ const apiCustomFields = customFields[item.fsPath || ''] || {};
206
211
  const link = item.link || ((_a = (0, utils_1.findDeepFirst)(item.items || [], (i) => 'link' in i && !!i.link)) === null || _a === void 0 ? void 0 : _a.link);
207
212
  const firstSidebarItem = (_b = item.sidebar) === null || _b === void 0 ? void 0 : _b[0];
208
- return Object.assign(Object.assign({}, metadata), { publishedAt: metadata.publishedAt || metadata.createdAt, title: (0, utils_1.toStringIfDefined)(metadata === null || metadata === void 0 ? void 0 : metadata.title) || item.label || 'Untitled', description: (0, utils_1.toStringIfDefined)(metadata === null || metadata === void 0 ? void 0 : metadata.description), link: (_c = (0, utils_1.withoutHash)(link)) !== null && _c !== void 0 ? _c : '#', docsLink: (0, utils_1.withoutHash)(firstSidebarItem === null || firstSidebarItem === void 0 ? void 0 : firstSidebarItem.link), image: (0, utils_1.toStringIfDefined)(metadata === null || metadata === void 0 ? void 0 : metadata.image) });
213
+ return Object.assign(Object.assign(Object.assign({}, metadata), apiCustomFields), { publishedAt: metadata.publishedAt || metadata.createdAt, title: (0, utils_1.toStringIfDefined)(metadata === null || metadata === void 0 ? void 0 : metadata.title) || item.label || 'Untitled', description: (0, utils_1.toStringIfDefined)(metadata === null || metadata === void 0 ? void 0 : metadata.description), link: (_c = (0, utils_1.withoutHash)(link)) !== null && _c !== void 0 ? _c : '#', docsLink: (0, utils_1.withoutHash)(firstSidebarItem === null || firstSidebarItem === void 0 ? void 0 : firstSidebarItem.link), image: (0, utils_1.toStringIfDefined)(metadata === null || metadata === void 0 ? void 0 : metadata.image) });
209
214
  });
210
215
  }
211
216
  function collectFilterParents(filtersWithOptions) {
package/lib/config.d.ts CHANGED
@@ -356,7 +356,7 @@ declare const scorecardConfigSchema: {
356
356
  declare const catalogSchema: {
357
357
  readonly type: "object";
358
358
  readonly additionalProperties: true;
359
- readonly required: readonly ["slug", "filters", "items"];
359
+ readonly required: readonly ["slug", "items"];
360
360
  readonly properties: {
361
361
  readonly slug: {
362
362
  readonly type: "string";
@@ -1590,7 +1590,7 @@ export declare const themeConfigSchema: {
1590
1590
  readonly '.*': {
1591
1591
  readonly type: "object";
1592
1592
  readonly additionalProperties: true;
1593
- readonly required: readonly ["slug", "filters", "items"];
1593
+ readonly required: readonly ["slug", "items"];
1594
1594
  readonly properties: {
1595
1595
  readonly slug: {
1596
1596
  readonly type: "string";
package/lib/config.js CHANGED
@@ -314,7 +314,7 @@ const scorecardConfigSchema = {
314
314
  const catalogSchema = {
315
315
  type: 'object',
316
316
  additionalProperties: true,
317
- required: ['slug', 'filters', 'items'],
317
+ required: ['slug', 'items'],
318
318
  properties: {
319
319
  slug: { type: 'string' },
320
320
  filters: { type: 'array', items: catalogFilterSchema },
@@ -2,4 +2,5 @@ import type { ResolvedNavLinkItem } from '../../types/portal';
2
2
  export declare function usePageData(): {
3
3
  prevPage: ResolvedNavLinkItem | null;
4
4
  nextPage: ResolvedNavLinkItem | null;
5
+ props?: any;
5
6
  } | null;
@@ -17,6 +17,7 @@ export type ResolvedNavLinkItem = {
17
17
  httpVerb?: string;
18
18
  separatorLine?: boolean;
19
19
  routeSlug?: string;
20
+ fsPath?: string;
20
21
  active?: boolean;
21
22
  icon?: string;
22
23
  srcSet?: string;
@@ -41,6 +42,7 @@ export type ResolvedNavGroupItem = {
41
42
  menuStyle?: MenuStyle;
42
43
  separatorLine?: boolean;
43
44
  routeSlug?: string;
45
+ fsPath?: string;
44
46
  active?: boolean;
45
47
  icon?: string;
46
48
  srcSet?: string;
@@ -52,6 +54,7 @@ export type ResolvedNavItem = ResolvedNavLinkItem | ResolvedNavGroupItem | {
52
54
  label?: string;
53
55
  labelTranslationKey?: string;
54
56
  routeSlug?: never;
57
+ fsPath?: never;
55
58
  version?: string;
56
59
  isDefault?: boolean;
57
60
  versionFolderId?: string;
@@ -70,6 +73,7 @@ export type ResolvedNavItem = ResolvedNavLinkItem | ResolvedNavGroupItem | {
70
73
  versionFolderId?: string;
71
74
  metadata?: Record<string, unknown>;
72
75
  routeSlug?: never;
76
+ fsPath?: never;
73
77
  label: string;
74
78
  labelTranslationKey?: string;
75
79
  link?: undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/theme",
3
- "version": "0.19.1",
3
+ "version": "0.19.3",
4
4
  "description": "Shared UI components lib",
5
5
  "keywords": [
6
6
  "theme",
@@ -35,18 +35,20 @@ export default function Catalog(props: {
35
35
 
36
36
  return (
37
37
  <HighlightContext.Provider value={[filterTerm]}>
38
- <CatalogPageWrapper>
39
- <FilterTagsWrapper>
40
- <Button
41
- variant="text"
42
- size="small"
43
- icon={<PlusIcon />}
44
- onClick={() => setIsAddingFilter(true)}
45
- >
46
- {translate(translationKeys.addFilter, 'Add filter')}
47
- </Button>
48
- <FilterTags filters={filters} />
49
- </FilterTagsWrapper>
38
+ <CatalogPageWrapper withoutFilters={!filters.length}>
39
+ {!!filters.length && (
40
+ <FilterTagsWrapper>
41
+ <Button
42
+ variant="text"
43
+ size="small"
44
+ icon={<PlusIcon />}
45
+ onClick={() => setIsAddingFilter(true)}
46
+ >
47
+ {translate(translationKeys.addFilter, 'Add filter')}
48
+ </Button>
49
+ <FilterTags filters={filters} />
50
+ </FilterTagsWrapper>
51
+ )}
50
52
  <FilterContent
51
53
  setFilterTerm={setFilterTerm}
52
54
  filters={filters}
@@ -152,27 +154,23 @@ export const CatalogTitle = styled(H2)`
152
154
  color: var(--catalog-title-text-color);
153
155
  font-weight: var(--catalog-title-font-weight);
154
156
  font-size: var(--catalog-title-font-size);
155
-
156
- && {
157
- margin: 0;
158
- }
157
+ margin: var(--catalog-title-margin);
159
158
  `;
160
159
 
161
160
  export const CatalogDescription = styled.p`
162
161
  color: var(--catalog-description-text-color);
163
162
  font-weight: var(--catalog-description-font-weight);
164
163
  font-size: var(--catalog-description-font-size);
165
- margin: var(--catalog-description-margin-top) 0 var(--catalog-description-margin-bottom) 0;
164
+ margin: var(--catalog-description-margin);
166
165
  `;
167
166
 
168
- export const CatalogPageWrapper = styled.div`
167
+ export const CatalogPageWrapper = styled.div<{ withoutFilters?: boolean }>`
169
168
  --sidebar-width: var(--catalog-sidebar-width, 285px);
170
169
 
171
170
  display: flex;
172
171
  flex-direction: column;
173
172
 
174
173
  font-weight: var(--font-weight-regular);
175
- padding: 0;
176
174
 
177
175
  color: var(--text-secondary);
178
176
  font-size: var(--font-size-base);
@@ -191,8 +189,11 @@ export const CatalogPageWrapper = styled.div`
191
189
  font-weight: var(--link-font-weight);
192
190
  }
193
191
 
192
+ padding: ${({ withoutFilters }) => (withoutFilters ? 'var(--spacing-base) 0 0 0' : '0')};
193
+
194
194
  ${({ theme }) => theme.mediaQueries.medium} {
195
195
  flex-direction: row;
196
+ padding: 0;
196
197
  }
197
198
  `;
198
199
 
@@ -227,6 +228,7 @@ const FilterTagsWrapper = styled.div.attrs({ 'data-cy': 'Catalog/FilterTags' })`
227
228
  `;
228
229
 
229
230
  export const CatalogPageDescriptionWrapper = styled.div`
231
+ margin: var(--catalog-heading-margin);
230
232
  display: none;
231
233
 
232
234
  ${({ theme }) => theme.mediaQueries.medium} {
@@ -12,12 +12,15 @@ export const catalog = css`
12
12
  --mobile-catalog-filter-padding-vertical: var(--spacing-sm);
13
13
  --mobile-catalog-filter-padding-horizontal: var(--spacing-base);
14
14
 
15
+ --catalog-heading-margin: 0 0 var(--spacing-xl) 0;
16
+
15
17
  /**
16
18
  * @tokens Catalog page title
17
19
  */
18
20
  --catalog-title-text-color: var(--text-primary);
19
21
  --catalog-title-font-weight: var(--font-weight-bold);
20
22
  --catalog-title-font-size: var(--font-size-heading-3);
23
+ --catalog-title-margin: 0 0 var(--spacing-sm) 0;
21
24
 
22
25
  /**
23
26
  * @tokens Catalog page description
@@ -25,8 +28,7 @@ export const catalog = css`
25
28
  --catalog-description-text-color: var(--text-secondary);
26
29
  --catalog-description-font-weight: var(--font-weight-regular);
27
30
  --catalog-description-font-size: var(--font-size-base);
28
- --catalog-description-margin-top: var(--spacing-sm);
29
- --catalog-description-margin-bottom: var(--spacing-xl);
31
+ --catalog-description-margin: 0 0 var(--spacing-sm) 0;
30
32
 
31
33
  /**
32
34
  * @tokens Catalog page separator
@@ -4,6 +4,7 @@ import { useLocation, useNavigate } from 'react-router-dom';
4
4
  import type { Location } from 'react-router-dom';
5
5
 
6
6
  import { telemetry } from '@portal/telemetry';
7
+ import { usePageData } from '@portal/hooks/usePageData';
7
8
  import type { ResolvedNavItem } from '@theme/types/portal';
8
9
  import type {
9
10
  CatalogItem,
@@ -16,6 +17,7 @@ import type { CatalogConfig, CatalogFilterConfig } from '@theme/config';
16
17
  export function useCatalog(items: ResolvedNavItem[], config: CatalogConfig): FilteredCatalog {
17
18
  const location = useLocation();
18
19
  const navigate = useNavigate();
20
+ const pageData = usePageData();
19
21
  const searchParams = useSearchParams(location);
20
22
  const [filtersState, setFiltersState] = React.useState(() =>
21
23
  (config.filters ?? []).map((f) => {
@@ -33,7 +35,12 @@ export function useCatalog(items: ResolvedNavItem[], config: CatalogConfig): Fil
33
35
  () => collectFilterOptions(items, config.filters),
34
36
  [items, config.filters],
35
37
  );
36
- const normalizedItems = React.useMemo(() => normalizeItems(items, config), [items, config]);
38
+
39
+ const customFields = pageData?.props?.customFields;
40
+ const normalizedItems = React.useMemo(
41
+ () => normalizeItems(items, config, customFields || ({} as any)),
42
+ [items, config, customFields],
43
+ );
37
44
 
38
45
  const toggleOption = React.useCallback((filterIdx, option) => {
39
46
  setFiltersState((prev) => {
@@ -114,7 +121,7 @@ export function useCatalog(items: ResolvedNavItem[], config: CatalogConfig): Fil
114
121
  selectOption: (value: string) => selectOption(idx, value),
115
122
  selectedOptions: filtersState[idx] ?? new Set<string>(),
116
123
  isFilterUsed:
117
- ((filtersState[idx] as any)?.size ?? 0) > 0 || !!(filtersState[idx] as any).from,
124
+ ((filtersState[idx] as any)?.size ?? 0) > 0 || !!(filtersState[idx] as any)?.from,
118
125
  }));
119
126
 
120
127
  const filteredItems = filterItems(normalizedItems, filters, filterTerm);
@@ -198,7 +205,11 @@ function useSearchParams(location: Location) {
198
205
  return React.useMemo(() => new URLSearchParams(location.search), [location.search]);
199
206
  }
200
207
 
201
- function normalizeItems(items: ResolvedNavItem[], config: CatalogConfig): CatalogItem[] {
208
+ function normalizeItems(
209
+ items: ResolvedNavItem[],
210
+ config: CatalogConfig,
211
+ customFields: Record<string, Record<string, unknown>>,
212
+ ): CatalogItem[] {
202
213
  // because of RBAC some versions can be missing so we need to pick up other default version
203
214
  const hasDeafultVersion: Record<string, boolean> = {};
204
215
  for (const item of items) {
@@ -223,10 +234,12 @@ function normalizeItems(items: ResolvedNavItem[], config: CatalogConfig): Catalo
223
234
 
224
235
  return items.map((item) => {
225
236
  const metadata = item.metadata || {};
237
+ const apiCustomFields = customFields[item.fsPath || ''] || {};
226
238
  const link = item.link || findDeepFirst(item.items || [], (i) => 'link' in i && !!i.link)?.link;
227
239
  const firstSidebarItem = (item as any).sidebar?.[0];
228
240
  return {
229
241
  ...metadata,
242
+ ...apiCustomFields,
230
243
  publishedAt: metadata.publishedAt || metadata.createdAt,
231
244
  title: toStringIfDefined(metadata?.title) || item.label || 'Untitled',
232
245
  description: toStringIfDefined(metadata?.description),
package/src/config.ts CHANGED
@@ -354,7 +354,7 @@ const scorecardConfigSchema = {
354
354
  const catalogSchema = {
355
355
  type: 'object',
356
356
  additionalProperties: true,
357
- required: ['slug', 'filters', 'items'],
357
+ required: ['slug', 'items'],
358
358
  properties: {
359
359
  slug: { type: 'string' },
360
360
  filters: { type: 'array', items: catalogFilterSchema },
@@ -3,6 +3,7 @@ import type { ResolvedNavLinkItem } from '@theme/types/portal';
3
3
  export function usePageData(): {
4
4
  prevPage: ResolvedNavLinkItem | null;
5
5
  nextPage: ResolvedNavLinkItem | null;
6
+ props?: any;
6
7
  } | null {
7
8
  return {
8
9
  prevPage: { label: 'Intro', type: 'link', link: '#prev' },
@@ -20,6 +20,7 @@ export type ResolvedNavLinkItem = {
20
20
  httpVerb?: string;
21
21
  separatorLine?: boolean;
22
22
  routeSlug?: string;
23
+ fsPath?: string
23
24
  active?: boolean;
24
25
  icon?: string;
25
26
  srcSet?: string;
@@ -47,6 +48,7 @@ export type ResolvedNavGroupItem = {
47
48
  menuStyle?: MenuStyle;
48
49
  separatorLine?: boolean;
49
50
  routeSlug?: string;
51
+ fsPath?: string
50
52
  active?: boolean;
51
53
  icon?: string;
52
54
  srcSet?: string;
@@ -62,6 +64,7 @@ export type ResolvedNavItem =
62
64
  label?: string;
63
65
  labelTranslationKey?: string;
64
66
  routeSlug?: never;
67
+ fsPath?: never
65
68
 
66
69
  version?: string;
67
70
  isDefault?: boolean;
@@ -84,6 +87,7 @@ export type ResolvedNavItem =
84
87
  versionFolderId?: string;
85
88
  metadata?: Record<string, unknown>;
86
89
  routeSlug?: never;
90
+ fsPath?: never
87
91
 
88
92
  label: string;
89
93
  labelTranslationKey?: string;