@backstage/plugin-techdocs 0.13.4 → 0.15.1-next.0

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/dist/index.esm.js CHANGED
@@ -1,23 +1,18 @@
1
- import { createApiRef, createRouteRef, useRouteRef, useApi, configApiRef, createPlugin, createApiFactory, discoveryApiRef, identityApiRef, fetchApiRef, createRoutableExtension, createComponentExtension } from '@backstage/core-plugin-api';
1
+ import { createApiRef, useApi, configApiRef, createRouteRef, useRouteRef, useApp, createPlugin, createApiFactory, discoveryApiRef, identityApiRef, fetchApiRef, createRoutableExtension } from '@backstage/core-plugin-api';
2
2
  import { ResponseError, NotFoundError } from '@backstage/errors';
3
3
  import { EventSourcePolyfill } from 'event-source-polyfill';
4
- import React, { useEffect, useState, useReducer, useRef, useMemo, createContext, useContext, useCallback } from 'react';
5
- import { makeStyles, ListItemText, ListItem, Divider, Card, CardMedia, CardContent, CardActions, Grid, TextField, InputAdornment, IconButton, CircularProgress, createStyles, Button as Button$1, Drawer, Typography, useTheme } from '@material-ui/core';
6
- import { Link, SubvalueCell, Table, EmptyState, Button, WarningPanel, CodeSnippet, PageWithHeader, Content, ContentHeader, SupportButton, ItemCardGrid, ItemCardHeader, Progress, LogViewer, ErrorPage, SidebarPinStateContext, HeaderLabel, Header, Page, HeaderTabs, MissingAnnotationEmptyState } from '@backstage/core-components';
7
- import TextTruncate from 'react-text-truncate';
8
- import { FilteredEntityLayout, FilterContainer, EntityListContainer } from '@backstage/plugin-catalog';
9
- import { favoriteEntityIcon, favoriteEntityTooltip, EntityRefLinks, getEntityRelations, formatEntityRefTitle, useEntityListProvider, useStarredEntities, CATALOG_FILTER_EXISTS, EntityListProvider, UserListPicker, EntityOwnerPicker, EntityTagPicker, EntityRefLink, catalogApiRef, useOwnUser, isOwnerOf, useEntity } from '@backstage/plugin-catalog-react';
10
- import useCopyToClipboard from 'react-use/lib/useCopyToClipboard';
11
- import { capitalize } from 'lodash';
12
- import { RELATION_OWNED_BY } from '@backstage/catalog-model';
13
- import ShareIcon from '@material-ui/icons/Share';
4
+ import React, { useState, useCallback, useEffect, useReducer, useRef, useMemo, createContext, useContext } from 'react';
14
5
  import { useNavigate as useNavigate$1, useParams, Routes, Route } from 'react-router-dom';
6
+ import { withStyles, Tooltip, ThemeProvider, SvgIcon, makeStyles, ListItemText, ListItem, Divider, TextField, InputAdornment, IconButton, CircularProgress, createStyles, Button, Drawer, Grid, Typography, useTheme, lighten, alpha, Card, CardMedia, CardContent, CardActions } from '@material-ui/core';
15
7
  import { scmIntegrationsApiRef } from '@backstage/integration-react';
8
+ import { Link, LogViewer, ErrorPage, Progress, SidebarPinStateContext, HeaderLabel, Header, Page, Content, ItemCardGrid, ItemCardHeader, Button as Button$1, WarningPanel, CodeSnippet, SubvalueCell, Table, EmptyState, PageWithHeader, ContentHeader, SupportButton, MissingAnnotationEmptyState } from '@backstage/core-components';
16
9
  import { replaceGitHubUrlType } from '@backstage/integration';
17
10
  import FeedbackOutlinedIcon from '@material-ui/icons/FeedbackOutlined';
18
11
  import ReactDOM from 'react-dom';
19
12
  import parseGitUrl from 'git-url-parse';
13
+ import MenuIcon from '@material-ui/icons/Menu';
20
14
  import DOMPurify from 'dompurify';
15
+ import TextTruncate from 'react-text-truncate';
21
16
  import { SearchContextProvider, useSearch } from '@backstage/plugin-search';
22
17
  import SearchIcon from '@material-ui/icons/Search';
23
18
  import Autocomplete from '@material-ui/lab/Autocomplete';
@@ -28,6 +23,15 @@ import Close from '@material-ui/icons/Close';
28
23
  import useAsync from 'react-use/lib/useAsync';
29
24
  import useAsyncRetry from 'react-use/lib/useAsyncRetry';
30
25
  import CodeIcon from '@material-ui/icons/Code';
26
+ import { RELATION_OWNED_BY } from '@backstage/catalog-model';
27
+ import { getEntityRelations, EntityRefLink, EntityRefLinks, useEntityList, humanizeEntityRef, useStarredEntities, CATALOG_FILTER_EXISTS, EntityListProvider, UserListPicker, EntityOwnerPicker, EntityTagPicker, useEntity } from '@backstage/plugin-catalog-react';
28
+ import useCopyToClipboard from 'react-use/lib/useCopyToClipboard';
29
+ import { capitalize } from 'lodash';
30
+ import ShareIcon from '@material-ui/icons/Share';
31
+ import { withStyles as withStyles$1 } from '@material-ui/styles';
32
+ import Star from '@material-ui/icons/Star';
33
+ import StarBorder from '@material-ui/icons/StarBorder';
34
+ import { FilteredEntityLayout, FilterContainer, EntityListContainer } from '@backstage/plugin-catalog';
31
35
 
32
36
  const techdocsStorageApiRef = createApiRef({
33
37
  id: "plugin.techdocs.storageservice"
@@ -148,577 +152,232 @@ class TechDocsStorageClient {
148
152
  }
149
153
  }
150
154
 
151
- const useStyles$2 = makeStyles({
152
- flexContainer: {
153
- flexWrap: "wrap"
154
- },
155
- itemText: {
156
- width: "100%",
157
- marginBottom: "1rem"
158
- }
159
- });
160
- const DocsResultListItem = ({
161
- result,
162
- lineClamp = 5,
163
- asListItem = true,
164
- asLink = true,
165
- title
155
+ const isSvgNeedingInlining = (attrName, attrVal, apiOrigin) => {
156
+ const isSrcToSvg = attrName === "src" && attrVal.endsWith(".svg");
157
+ const isRelativeUrl = !attrVal.match(/^([a-z]*:)?\/\//i);
158
+ const pointsToOurBackend = attrVal.startsWith(apiOrigin);
159
+ return isSrcToSvg && (isRelativeUrl || pointsToOurBackend);
160
+ };
161
+ const addBaseUrl = ({
162
+ techdocsStorageApi,
163
+ entityId,
164
+ path
166
165
  }) => {
167
- const classes = useStyles$2();
168
- const TextItem = () => {
169
- var _a;
170
- return /* @__PURE__ */ React.createElement(ListItemText, {
171
- className: classes.itemText,
172
- primaryTypographyProps: { variant: "h6" },
173
- primary: title ? title : `${result.title} | ${(_a = result.entityTitle) != null ? _a : result.name} docs`,
174
- secondary: /* @__PURE__ */ React.createElement(TextTruncate, {
175
- line: lineClamp,
176
- truncateText: "\u2026",
177
- text: result.text,
178
- element: "span"
179
- })
180
- });
166
+ return async (dom) => {
167
+ const apiOrigin = await techdocsStorageApi.getApiOrigin();
168
+ const updateDom = async (list, attributeName) => {
169
+ for (const elem of list) {
170
+ if (elem.hasAttribute(attributeName)) {
171
+ const elemAttribute = elem.getAttribute(attributeName);
172
+ if (!elemAttribute)
173
+ return;
174
+ const newValue = await techdocsStorageApi.getBaseUrl(elemAttribute, entityId, path);
175
+ if (isSvgNeedingInlining(attributeName, elemAttribute, apiOrigin)) {
176
+ try {
177
+ const svg = await fetch(newValue, { credentials: "include" });
178
+ const svgContent = await svg.text();
179
+ elem.setAttribute(attributeName, `data:image/svg+xml;base64,${btoa(svgContent)}`);
180
+ } catch (e) {
181
+ elem.setAttribute("alt", `Error: ${elemAttribute}`);
182
+ }
183
+ } else {
184
+ elem.setAttribute(attributeName, newValue);
185
+ }
186
+ }
187
+ }
188
+ };
189
+ await Promise.all([
190
+ updateDom(dom.querySelectorAll("img"), "src"),
191
+ updateDom(dom.querySelectorAll("script"), "src"),
192
+ updateDom(dom.querySelectorAll("source"), "src"),
193
+ updateDom(dom.querySelectorAll("link"), "href"),
194
+ updateDom(dom.querySelectorAll("a[download]"), "href")
195
+ ]);
196
+ return dom;
181
197
  };
182
- const LinkWrapper = ({ children }) => asLink ? /* @__PURE__ */ React.createElement(Link, {
183
- to: result.location
184
- }, children) : /* @__PURE__ */ React.createElement(React.Fragment, null, children);
185
- const ListItemWrapper = ({ children }) => asListItem ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ListItem, {
186
- alignItems: "flex-start",
187
- className: classes.flexContainer
188
- }, children), /* @__PURE__ */ React.createElement(Divider, {
189
- component: "li"
190
- })) : /* @__PURE__ */ React.createElement(React.Fragment, null, children);
191
- return /* @__PURE__ */ React.createElement(LinkWrapper, null, /* @__PURE__ */ React.createElement(ListItemWrapper, null, /* @__PURE__ */ React.createElement(TextItem, null)));
192
198
  };
193
199
 
194
- const rootRouteRef = createRouteRef({
195
- id: "techdocs:index-page"
196
- });
197
- const rootDocsRouteRef = createRouteRef({
198
- id: "techdocs:reader-page",
199
- params: ["namespace", "kind", "name"]
200
- });
201
- const rootCatalogDocsRouteRef = createRouteRef({
202
- id: "techdocs:catalog-reader-view"
203
- });
200
+ const addGitFeedbackLink = (scmIntegrationsApi) => {
201
+ return (dom) => {
202
+ const sourceAnchor = dom.querySelector('[title="Edit this page"]');
203
+ if (!sourceAnchor || !sourceAnchor.href) {
204
+ return dom;
205
+ }
206
+ const sourceURL = new URL(sourceAnchor.href);
207
+ const integration = scmIntegrationsApi.byUrl(sourceURL);
208
+ if ((integration == null ? void 0 : integration.type) !== "github" && (integration == null ? void 0 : integration.type) !== "gitlab") {
209
+ return dom;
210
+ }
211
+ const title = dom.querySelector("article>h1").childNodes[0].textContent;
212
+ const issueTitle = encodeURIComponent(`Documentation Feedback: ${title}`);
213
+ const issueDesc = encodeURIComponent(`Page source:
214
+ ${sourceAnchor.href}
204
215
 
205
- function createCopyDocsUrlAction(copyToClipboard) {
206
- return (row) => {
207
- return {
208
- icon: () => /* @__PURE__ */ React.createElement(ShareIcon, {
209
- fontSize: "small"
210
- }),
211
- tooltip: "Click to copy documentation link to clipboard",
212
- onClick: () => copyToClipboard(`${window.location.origin}${row.resolved.docsUrl}`)
213
- };
214
- };
215
- }
216
- function createStarEntityAction(isStarredEntity, toggleStarredEntity) {
217
- return ({ entity }) => {
218
- const isStarred = isStarredEntity(entity);
219
- return {
220
- cellStyle: { paddingLeft: "1em" },
221
- icon: () => favoriteEntityIcon(isStarred),
222
- tooltip: favoriteEntityTooltip(isStarred),
223
- onClick: () => toggleStarredEntity(entity)
224
- };
216
+ Feedback:`);
217
+ const gitUrl = (integration == null ? void 0 : integration.type) === "github" ? replaceGitHubUrlType(sourceURL.href, "blob") : sourceURL.href;
218
+ const gitInfo = parseGitUrl(gitUrl);
219
+ const repoPath = `/${gitInfo.organization}/${gitInfo.name}`;
220
+ const feedbackLink = sourceAnchor.cloneNode();
221
+ switch (integration == null ? void 0 : integration.type) {
222
+ case "gitlab":
223
+ feedbackLink.href = `${sourceURL.origin}${repoPath}/issues/new?issue[title]=${issueTitle}&issue[description]=${issueDesc}`;
224
+ break;
225
+ case "github":
226
+ feedbackLink.href = `${sourceURL.origin}${repoPath}/issues/new?title=${issueTitle}&body=${issueDesc}`;
227
+ break;
228
+ default:
229
+ return dom;
230
+ }
231
+ ReactDOM.render(React.createElement(FeedbackOutlinedIcon), feedbackLink);
232
+ feedbackLink.style.paddingLeft = "5px";
233
+ feedbackLink.title = "Leave feedback for this page";
234
+ feedbackLink.id = "git-feedback-link";
235
+ sourceAnchor == null ? void 0 : sourceAnchor.insertAdjacentElement("beforebegin", feedbackLink);
236
+ return dom;
225
237
  };
226
- }
238
+ };
227
239
 
228
- var actionFactories = /*#__PURE__*/Object.freeze({
229
- __proto__: null,
230
- createCopyDocsUrlAction: createCopyDocsUrlAction,
231
- createStarEntityAction: createStarEntityAction
232
- });
240
+ const addSidebarToggle = () => {
241
+ return (dom) => {
242
+ const mkdocsToggleSidebar = dom.querySelector('.md-header label[for="__drawer"]');
243
+ const article = dom.querySelector("article");
244
+ if (!mkdocsToggleSidebar || !article) {
245
+ return dom;
246
+ }
247
+ const toggleSidebar = mkdocsToggleSidebar.cloneNode();
248
+ ReactDOM.render(React.createElement(MenuIcon), toggleSidebar);
249
+ toggleSidebar.style.paddingLeft = "5px";
250
+ toggleSidebar.classList.add("md-content__button");
251
+ toggleSidebar.title = "Toggle Sidebar";
252
+ toggleSidebar.id = "toggle-sidebar";
253
+ article == null ? void 0 : article.prepend(toggleSidebar);
254
+ return dom;
255
+ };
256
+ };
233
257
 
234
- function customTitle(entity) {
235
- return entity.metadata.title || entity.metadata.name;
236
- }
237
- function createNameColumn() {
238
- return {
239
- title: "Document",
240
- field: "entity.metadata.name",
241
- highlight: true,
242
- render: (row) => /* @__PURE__ */ React.createElement(SubvalueCell, {
243
- value: /* @__PURE__ */ React.createElement(Link, {
244
- to: row.resolved.docsUrl
245
- }, customTitle(row.entity)),
246
- subvalue: row.entity.metadata.description
247
- })
258
+ const rewriteDocLinks = () => {
259
+ return (dom) => {
260
+ const updateDom = (list, attributeName) => {
261
+ Array.from(list).filter((elem) => elem.hasAttribute(attributeName)).forEach((elem) => {
262
+ const elemAttribute = elem.getAttribute(attributeName);
263
+ if (elemAttribute) {
264
+ if (elemAttribute.match(/^https?:\/\//i)) {
265
+ elem.setAttribute("target", "_blank");
266
+ }
267
+ try {
268
+ const normalizedWindowLocation = normalizeUrl(window.location.href);
269
+ elem.setAttribute(attributeName, new URL(elemAttribute, normalizedWindowLocation).toString());
270
+ } catch (_e) {
271
+ elem.replaceWith(elem.textContent || elemAttribute);
272
+ }
273
+ }
274
+ });
275
+ };
276
+ updateDom(Array.from(dom.getElementsByTagName("a")), "href");
277
+ return dom;
248
278
  };
279
+ };
280
+ function normalizeUrl(input) {
281
+ const url = new URL(input);
282
+ if (!url.pathname.endsWith("/") && !url.pathname.endsWith(".html")) {
283
+ url.pathname += "/";
284
+ }
285
+ return url.toString();
249
286
  }
250
- function createOwnerColumn() {
251
- return {
252
- title: "Owner",
253
- field: "resolved.ownedByRelationsTitle",
254
- render: ({ resolved }) => /* @__PURE__ */ React.createElement(EntityRefLinks, {
255
- entityRefs: resolved.ownedByRelations,
256
- defaultKind: "group"
257
- })
287
+
288
+ const addLinkClickListener = ({
289
+ baseUrl,
290
+ onClick
291
+ }) => {
292
+ return (dom) => {
293
+ Array.from(dom.getElementsByTagName("a")).forEach((elem) => {
294
+ elem.addEventListener("click", (e) => {
295
+ const target = elem;
296
+ const href = target.getAttribute("href");
297
+ if (!href)
298
+ return;
299
+ if (href.startsWith(baseUrl) && !elem.hasAttribute("download")) {
300
+ e.preventDefault();
301
+ onClick(e, href);
302
+ }
303
+ });
304
+ });
305
+ return dom;
258
306
  };
259
- }
260
- function createTypeColumn() {
261
- return {
262
- title: "Type",
263
- field: "entity.spec.type"
307
+ };
308
+
309
+ const CopyToClipboardTooltip = withStyles((theme) => ({
310
+ tooltip: {
311
+ fontSize: "inherit",
312
+ color: theme.palette.text.primary,
313
+ margin: 0,
314
+ padding: theme.spacing(0.5),
315
+ backgroundColor: "transparent",
316
+ boxShadow: "none"
317
+ }
318
+ }))(Tooltip);
319
+ const CopyToClipboardIcon = () => /* @__PURE__ */ React.createElement(SvgIcon, null, /* @__PURE__ */ React.createElement("path", {
320
+ d: "M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"
321
+ }));
322
+ const CopyToClipboardButton = ({ text }) => {
323
+ const [open, setOpen] = useState(false);
324
+ const handleClick = useCallback(() => {
325
+ navigator.clipboard.writeText(text);
326
+ setOpen(true);
327
+ }, [text]);
328
+ const handleClose = useCallback(() => {
329
+ setOpen(false);
330
+ }, [setOpen]);
331
+ return /* @__PURE__ */ React.createElement(CopyToClipboardTooltip, {
332
+ title: "Copied to clipboard",
333
+ placement: "left",
334
+ open,
335
+ onClose: handleClose,
336
+ leaveDelay: 1e3
337
+ }, /* @__PURE__ */ React.createElement("button", {
338
+ className: "md-clipboard md-icon",
339
+ onClick: handleClick
340
+ }, /* @__PURE__ */ React.createElement(CopyToClipboardIcon, null)));
341
+ };
342
+ const copyToClipboard = (theme) => {
343
+ return (dom) => {
344
+ var _a;
345
+ const codes = dom.querySelectorAll("pre > code");
346
+ for (const code of codes) {
347
+ const text = code.textContent || "";
348
+ const container = document.createElement("div");
349
+ (_a = code == null ? void 0 : code.parentElement) == null ? void 0 : _a.prepend(container);
350
+ ReactDOM.render(/* @__PURE__ */ React.createElement(ThemeProvider, {
351
+ theme
352
+ }, /* @__PURE__ */ React.createElement(CopyToClipboardButton, {
353
+ text
354
+ })), container);
355
+ }
356
+ return dom;
264
357
  };
265
- }
358
+ };
266
359
 
267
- var columnFactories = /*#__PURE__*/Object.freeze({
268
- __proto__: null,
269
- createNameColumn: createNameColumn,
270
- createOwnerColumn: createOwnerColumn,
271
- createTypeColumn: createTypeColumn
272
- });
360
+ const removeMkdocsHeader = () => {
361
+ return (dom) => {
362
+ var _a;
363
+ (_a = dom.querySelector(".md-header")) == null ? void 0 : _a.remove();
364
+ return dom;
365
+ };
366
+ };
273
367
 
274
- function toLowerMaybe(str, config) {
275
- return config.getOptionalBoolean("techdocs.legacyUseCaseSensitiveTripletPaths") ? str : str.toLocaleLowerCase("en-US");
276
- }
368
+ const simplifyMkdocsFooter = () => {
369
+ return (dom) => {
370
+ var _a, _b;
371
+ (_a = dom.querySelector(".md-footer .md-copyright")) == null ? void 0 : _a.remove();
372
+ (_b = dom.querySelector(".md-footer-copyright")) == null ? void 0 : _b.remove();
373
+ return dom;
374
+ };
375
+ };
277
376
 
278
- const DocsTable$1 = ({
279
- entities,
280
- title,
281
- loading,
282
- columns,
283
- actions
284
- }) => {
285
- const [, copyToClipboard] = useCopyToClipboard();
286
- const getRouteToReaderPageFor = useRouteRef(rootDocsRouteRef);
287
- const config = useApi(configApiRef);
288
- if (!entities)
289
- return null;
290
- const documents = entities.map((entity) => {
291
- var _a;
292
- const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);
293
- return {
294
- entity,
295
- resolved: {
296
- docsUrl: getRouteToReaderPageFor({
297
- namespace: toLowerMaybe((_a = entity.metadata.namespace) != null ? _a : "default", config),
298
- kind: toLowerMaybe(entity.kind, config),
299
- name: toLowerMaybe(entity.metadata.name, config)
300
- }),
301
- ownedByRelations,
302
- ownedByRelationsTitle: ownedByRelations.map((r) => formatEntityRefTitle(r, { defaultKind: "group" })).join(", ")
303
- }
304
- };
305
- });
306
- const defaultColumns = [
307
- createNameColumn(),
308
- createOwnerColumn(),
309
- createTypeColumn()
310
- ];
311
- const defaultActions = [
312
- createCopyDocsUrlAction(copyToClipboard)
313
- ];
314
- return /* @__PURE__ */ React.createElement(React.Fragment, null, loading || documents && documents.length > 0 ? /* @__PURE__ */ React.createElement(Table, {
315
- isLoading: loading,
316
- options: {
317
- paging: true,
318
- pageSize: 20,
319
- search: true,
320
- actionsColumnIndex: -1
321
- },
322
- data: documents,
323
- columns: columns || defaultColumns,
324
- actions: actions || defaultActions,
325
- title: title ? `${title} (${documents.length})` : `All (${documents.length})`
326
- }) : /* @__PURE__ */ React.createElement(EmptyState, {
327
- missing: "data",
328
- title: "No documents to show",
329
- description: "Create your own document. Check out our Getting Started Information",
330
- action: /* @__PURE__ */ React.createElement(Button, {
331
- color: "primary",
332
- to: "https://backstage.io/docs/features/techdocs/getting-started",
333
- variant: "contained"
334
- }, "DOCS")
335
- }));
336
- };
337
-
338
- var DocsTable$2 = /*#__PURE__*/Object.freeze({
339
- __proto__: null,
340
- DocsTable: DocsTable$1
341
- });
342
-
343
- const EntityListDocsTable = ({
344
- columns,
345
- actions
346
- }) => {
347
- var _a, _b;
348
- const { loading, error, entities, filters } = useEntityListProvider();
349
- const { isStarredEntity, toggleStarredEntity } = useStarredEntities();
350
- const [, copyToClipboard] = useCopyToClipboard();
351
- const title = capitalize((_b = (_a = filters.user) == null ? void 0 : _a.value) != null ? _b : "all");
352
- const defaultActions = [
353
- createCopyDocsUrlAction(copyToClipboard),
354
- createStarEntityAction(isStarredEntity, toggleStarredEntity)
355
- ];
356
- if (error) {
357
- return /* @__PURE__ */ React.createElement(WarningPanel, {
358
- severity: "error",
359
- title: "Could not load available documentation."
360
- }, /* @__PURE__ */ React.createElement(CodeSnippet, {
361
- language: "text",
362
- text: error.toString()
363
- }));
364
- }
365
- return /* @__PURE__ */ React.createElement(DocsTable$1, {
366
- title,
367
- entities,
368
- loading,
369
- actions: actions || defaultActions,
370
- columns
371
- });
372
- };
373
- EntityListDocsTable.columns = columnFactories;
374
- EntityListDocsTable.actions = actionFactories;
375
-
376
- const TechDocsPageWrapper = ({ children }) => {
377
- var _a;
378
- const configApi = useApi(configApiRef);
379
- const generatedSubtitle = `Documentation available in ${(_a = configApi.getOptionalString("organization.name")) != null ? _a : "Backstage"}`;
380
- return /* @__PURE__ */ React.createElement(PageWithHeader, {
381
- title: "Documentation",
382
- subtitle: generatedSubtitle,
383
- themeId: "documentation"
384
- }, children);
385
- };
386
-
387
- class TechDocsFilter {
388
- getCatalogFilters() {
389
- return {
390
- "metadata.annotations.backstage.io/techdocs-ref": CATALOG_FILTER_EXISTS
391
- };
392
- }
393
- }
394
- const TechDocsPicker = () => {
395
- const { updateFilters } = useEntityListProvider();
396
- useEffect(() => {
397
- updateFilters({
398
- techdocs: new TechDocsFilter()
399
- });
400
- }, [updateFilters]);
401
- return null;
402
- };
403
-
404
- const DefaultTechDocsHome = ({
405
- initialFilter = "all",
406
- columns,
407
- actions
408
- }) => {
409
- return /* @__PURE__ */ React.createElement(TechDocsPageWrapper, null, /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(ContentHeader, {
410
- title: ""
411
- }, /* @__PURE__ */ React.createElement(SupportButton, null, "Discover documentation in your ecosystem.")), /* @__PURE__ */ React.createElement(EntityListProvider, null, /* @__PURE__ */ React.createElement(FilteredEntityLayout, null, /* @__PURE__ */ React.createElement(FilterContainer, null, /* @__PURE__ */ React.createElement(TechDocsPicker, null), /* @__PURE__ */ React.createElement(UserListPicker, {
412
- initialFilter
413
- }), /* @__PURE__ */ React.createElement(EntityOwnerPicker, null), /* @__PURE__ */ React.createElement(EntityTagPicker, null)), /* @__PURE__ */ React.createElement(EntityListContainer, null, /* @__PURE__ */ React.createElement(EntityListDocsTable, {
414
- actions,
415
- columns
416
- }))))));
417
- };
418
-
419
- const DocsCardGrid$1 = ({
420
- entities
421
- }) => {
422
- const getRouteToReaderPageFor = useRouteRef(rootDocsRouteRef);
423
- const config = useApi(configApiRef);
424
- if (!entities)
425
- return null;
426
- return /* @__PURE__ */ React.createElement(ItemCardGrid, {
427
- "data-testid": "docs-explore"
428
- }, !(entities == null ? void 0 : entities.length) ? null : entities.map((entity, index) => {
429
- var _a, _b;
430
- return /* @__PURE__ */ React.createElement(Card, {
431
- key: index
432
- }, /* @__PURE__ */ React.createElement(CardMedia, null, /* @__PURE__ */ React.createElement(ItemCardHeader, {
433
- title: (_a = entity.metadata.title) != null ? _a : entity.metadata.name
434
- })), /* @__PURE__ */ React.createElement(CardContent, null, entity.metadata.description), /* @__PURE__ */ React.createElement(CardActions, null, /* @__PURE__ */ React.createElement(Button, {
435
- to: getRouteToReaderPageFor({
436
- namespace: toLowerMaybe((_b = entity.metadata.namespace) != null ? _b : "default", config),
437
- kind: toLowerMaybe(entity.kind, config),
438
- name: toLowerMaybe(entity.metadata.name, config)
439
- }),
440
- color: "primary",
441
- "data-testid": "read_docs"
442
- }, "Read Docs")));
443
- }));
444
- };
445
-
446
- var DocsCardGrid$2 = /*#__PURE__*/Object.freeze({
447
- __proto__: null,
448
- DocsCardGrid: DocsCardGrid$1
449
- });
450
-
451
- const EntityListDocsGrid = () => {
452
- const { loading, error, entities } = useEntityListProvider();
453
- if (error) {
454
- return /* @__PURE__ */ React.createElement(WarningPanel, {
455
- severity: "error",
456
- title: "Could not load available documentation."
457
- }, /* @__PURE__ */ React.createElement(CodeSnippet, {
458
- language: "text",
459
- text: error.toString()
460
- }));
461
- }
462
- if (loading || !entities) {
463
- return /* @__PURE__ */ React.createElement(Progress, null);
464
- }
465
- entities.sort((a, b) => {
466
- var _a, _b;
467
- return ((_a = a.metadata.title) != null ? _a : a.metadata.name).localeCompare((_b = b.metadata.title) != null ? _b : b.metadata.name);
468
- });
469
- return /* @__PURE__ */ React.createElement(DocsCardGrid$1, {
470
- entities
471
- });
472
- };
473
-
474
- const techdocsPlugin = createPlugin({
475
- id: "techdocs",
476
- apis: [
477
- createApiFactory({
478
- api: techdocsStorageApiRef,
479
- deps: {
480
- configApi: configApiRef,
481
- discoveryApi: discoveryApiRef,
482
- identityApi: identityApiRef,
483
- fetchApi: fetchApiRef
484
- },
485
- factory: ({ configApi, discoveryApi, identityApi, fetchApi }) => new TechDocsStorageClient({
486
- configApi,
487
- discoveryApi,
488
- identityApi,
489
- fetchApi
490
- })
491
- }),
492
- createApiFactory({
493
- api: techdocsApiRef,
494
- deps: {
495
- configApi: configApiRef,
496
- discoveryApi: discoveryApiRef,
497
- fetchApi: fetchApiRef
498
- },
499
- factory: ({ configApi, discoveryApi, fetchApi }) => new TechDocsClient({
500
- configApi,
501
- discoveryApi,
502
- fetchApi
503
- })
504
- })
505
- ],
506
- routes: {
507
- root: rootRouteRef,
508
- docRoot: rootDocsRouteRef,
509
- entityContent: rootCatalogDocsRouteRef
510
- }
511
- });
512
- const TechdocsPage = techdocsPlugin.provide(createRoutableExtension({
513
- name: "TechdocsPage",
514
- component: () => Promise.resolve().then(function () { return Router$1; }).then((m) => m.Router),
515
- mountPoint: rootRouteRef
516
- }));
517
- const EntityTechdocsContent = techdocsPlugin.provide(createRoutableExtension({
518
- name: "EntityTechdocsContent",
519
- component: () => Promise.resolve().then(function () { return Router$1; }).then((m) => m.EmbeddedDocsRouter),
520
- mountPoint: rootCatalogDocsRouteRef
521
- }));
522
- const DocsCardGrid = techdocsPlugin.provide(createComponentExtension({
523
- name: "DocsCardGrid",
524
- component: {
525
- lazy: () => Promise.resolve().then(function () { return DocsCardGrid$2; }).then((m) => m.DocsCardGrid)
526
- }
527
- }));
528
- const DocsTable = techdocsPlugin.provide(createComponentExtension({
529
- name: "DocsTable",
530
- component: {
531
- lazy: () => Promise.resolve().then(function () { return DocsTable$2; }).then((m) => m.DocsTable)
532
- }
533
- }));
534
- const TechDocsCustomHome$2 = techdocsPlugin.provide(createRoutableExtension({
535
- name: "TechDocsCustomHome",
536
- component: () => Promise.resolve().then(function () { return TechDocsCustomHome$1; }).then((m) => m.TechDocsCustomHome),
537
- mountPoint: rootRouteRef
538
- }));
539
- const TechDocsIndexPage$2 = techdocsPlugin.provide(createRoutableExtension({
540
- name: "TechDocsIndexPage",
541
- component: () => Promise.resolve().then(function () { return TechDocsIndexPage$1; }).then((m) => m.TechDocsIndexPage),
542
- mountPoint: rootRouteRef
543
- }));
544
- const TechDocsReaderPage = techdocsPlugin.provide(createRoutableExtension({
545
- name: "TechDocsReaderPage",
546
- component: () => Promise.resolve().then(function () { return TechDocsPage$1; }).then((m) => m.TechDocsPage),
547
- mountPoint: rootDocsRouteRef
548
- }));
549
-
550
- const isSvgNeedingInlining = (attrName, attrVal, apiOrigin) => {
551
- const isSrcToSvg = attrName === "src" && attrVal.endsWith(".svg");
552
- const isRelativeUrl = !attrVal.match(/^([a-z]*:)?\/\//i);
553
- const pointsToOurBackend = attrVal.startsWith(apiOrigin);
554
- return isSrcToSvg && (isRelativeUrl || pointsToOurBackend);
555
- };
556
- const addBaseUrl = ({
557
- techdocsStorageApi,
558
- entityId,
559
- path
560
- }) => {
561
- return async (dom) => {
562
- const apiOrigin = await techdocsStorageApi.getApiOrigin();
563
- const updateDom = async (list, attributeName) => {
564
- for (const elem of list) {
565
- if (elem.hasAttribute(attributeName)) {
566
- const elemAttribute = elem.getAttribute(attributeName);
567
- if (!elemAttribute)
568
- return;
569
- const newValue = await techdocsStorageApi.getBaseUrl(elemAttribute, entityId, path);
570
- if (isSvgNeedingInlining(attributeName, elemAttribute, apiOrigin)) {
571
- try {
572
- const svg = await fetch(newValue, { credentials: "include" });
573
- const svgContent = await svg.text();
574
- elem.setAttribute(attributeName, `data:image/svg+xml;base64,${btoa(svgContent)}`);
575
- } catch (e) {
576
- elem.setAttribute("alt", `Error: ${elemAttribute}`);
577
- }
578
- } else {
579
- elem.setAttribute(attributeName, newValue);
580
- }
581
- }
582
- }
583
- };
584
- await Promise.all([
585
- updateDom(dom.querySelectorAll("img"), "src"),
586
- updateDom(dom.querySelectorAll("script"), "src"),
587
- updateDom(dom.querySelectorAll("source"), "src"),
588
- updateDom(dom.querySelectorAll("link"), "href"),
589
- updateDom(dom.querySelectorAll("a[download]"), "href")
590
- ]);
591
- return dom;
592
- };
593
- };
594
-
595
- const addGitFeedbackLink = (scmIntegrationsApi) => {
596
- return (dom) => {
597
- const sourceAnchor = dom.querySelector('[title="Edit this page"]');
598
- if (!sourceAnchor || !sourceAnchor.href) {
599
- return dom;
600
- }
601
- const sourceURL = new URL(sourceAnchor.href);
602
- const integration = scmIntegrationsApi.byUrl(sourceURL);
603
- if ((integration == null ? void 0 : integration.type) !== "github" && (integration == null ? void 0 : integration.type) !== "gitlab") {
604
- return dom;
605
- }
606
- const title = dom.querySelector("article>h1").childNodes[0].textContent;
607
- const issueTitle = encodeURIComponent(`Documentation Feedback: ${title}`);
608
- const issueDesc = encodeURIComponent(`Page source:
609
- ${sourceAnchor.href}
610
-
611
- Feedback:`);
612
- const gitUrl = (integration == null ? void 0 : integration.type) === "github" ? replaceGitHubUrlType(sourceURL.href, "blob") : sourceURL.href;
613
- const gitInfo = parseGitUrl(gitUrl);
614
- const repoPath = `/${gitInfo.organization}/${gitInfo.name}`;
615
- const feedbackLink = sourceAnchor.cloneNode();
616
- switch (integration == null ? void 0 : integration.type) {
617
- case "gitlab":
618
- feedbackLink.href = `${sourceURL.origin}${repoPath}/issues/new?issue[title]=${issueTitle}&issue[description]=${issueDesc}`;
619
- break;
620
- case "github":
621
- feedbackLink.href = `${sourceURL.origin}${repoPath}/issues/new?title=${issueTitle}&body=${issueDesc}`;
622
- break;
623
- default:
624
- return dom;
625
- }
626
- ReactDOM.render(React.createElement(FeedbackOutlinedIcon), feedbackLink);
627
- feedbackLink.style.paddingLeft = "5px";
628
- feedbackLink.title = "Leave feedback for this page";
629
- feedbackLink.id = "git-feedback-link";
630
- sourceAnchor == null ? void 0 : sourceAnchor.insertAdjacentElement("beforebegin", feedbackLink);
631
- return dom;
632
- };
633
- };
634
-
635
- const rewriteDocLinks = () => {
636
- return (dom) => {
637
- const updateDom = (list, attributeName) => {
638
- Array.from(list).filter((elem) => elem.hasAttribute(attributeName)).forEach((elem) => {
639
- const elemAttribute = elem.getAttribute(attributeName);
640
- if (elemAttribute) {
641
- if (elemAttribute.match(/^https?:\/\//i)) {
642
- elem.setAttribute("target", "_blank");
643
- }
644
- try {
645
- const normalizedWindowLocation = normalizeUrl(window.location.href);
646
- elem.setAttribute(attributeName, new URL(elemAttribute, normalizedWindowLocation).toString());
647
- } catch (_e) {
648
- elem.replaceWith(elem.textContent || elemAttribute);
649
- }
650
- }
651
- });
652
- };
653
- updateDom(Array.from(dom.getElementsByTagName("a")), "href");
654
- return dom;
655
- };
656
- };
657
- function normalizeUrl(input) {
658
- const url = new URL(input);
659
- if (!url.pathname.endsWith("/") && !url.pathname.endsWith(".html")) {
660
- url.pathname += "/";
661
- }
662
- return url.toString();
663
- }
664
-
665
- const addLinkClickListener = ({
666
- baseUrl,
667
- onClick
668
- }) => {
669
- return (dom) => {
670
- Array.from(dom.getElementsByTagName("a")).forEach((elem) => {
671
- elem.addEventListener("click", (e) => {
672
- const target = elem;
673
- const href = target.getAttribute("href");
674
- if (!href)
675
- return;
676
- if (href.startsWith(baseUrl) && !elem.hasAttribute("download")) {
677
- e.preventDefault();
678
- onClick(e, href);
679
- }
680
- });
681
- });
682
- return dom;
683
- };
684
- };
685
-
686
- const copyToClipboard = () => {
687
- return (dom) => {
688
- Array.from(dom.querySelectorAll("pre > code")).forEach((codeElem) => {
689
- var _a;
690
- const button = document.createElement("button");
691
- const toBeCopied = codeElem.textContent || "";
692
- button.className = "md-clipboard md-icon";
693
- button.title = "Copy to clipboard";
694
- button.innerHTML = '<svg viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg>';
695
- button.addEventListener("click", () => navigator.clipboard.writeText(toBeCopied));
696
- (_a = codeElem == null ? void 0 : codeElem.parentElement) == null ? void 0 : _a.prepend(button);
697
- });
698
- return dom;
699
- };
700
- };
701
-
702
- const removeMkdocsHeader = () => {
703
- return (dom) => {
704
- var _a;
705
- (_a = dom.querySelector(".md-header")) == null ? void 0 : _a.remove();
706
- return dom;
707
- };
708
- };
709
-
710
- const simplifyMkdocsFooter = () => {
711
- return (dom) => {
712
- var _a;
713
- (_a = dom.querySelector(".md-footer-copyright")) == null ? void 0 : _a.remove();
714
- return dom;
715
- };
716
- };
717
-
718
- const onCssReady = ({
719
- docStorageUrl,
720
- onLoading,
721
- onLoaded
377
+ const onCssReady = ({
378
+ docStorageUrl,
379
+ onLoading,
380
+ onLoaded
722
381
  }) => {
723
382
  return (dom) => {
724
383
  const cssPages = Array.from(dom.querySelectorAll('head > link[rel="stylesheet"]')).filter((elem) => {
@@ -830,17 +489,67 @@ const transform = async (html, transformers) => {
830
489
  return dom;
831
490
  };
832
491
 
833
- const TechDocsSearchBar = ({
834
- entityId,
835
- debounceTime = 150
836
- }) => {
492
+ const useStyles$3 = makeStyles({
493
+ flexContainer: {
494
+ flexWrap: "wrap"
495
+ },
496
+ itemText: {
497
+ width: "100%",
498
+ marginBottom: "1rem"
499
+ }
500
+ });
501
+ const TechDocsSearchResultListItem = (props) => {
502
+ const {
503
+ result,
504
+ lineClamp = 5,
505
+ asListItem = true,
506
+ asLink = true,
507
+ title
508
+ } = props;
509
+ const classes = useStyles$3();
510
+ const TextItem = () => {
511
+ var _a;
512
+ return /* @__PURE__ */ React.createElement(ListItemText, {
513
+ className: classes.itemText,
514
+ primaryTypographyProps: { variant: "h6" },
515
+ primary: title ? title : `${result.title} | ${(_a = result.entityTitle) != null ? _a : result.name} docs`,
516
+ secondary: /* @__PURE__ */ React.createElement(TextTruncate, {
517
+ line: lineClamp,
518
+ truncateText: "\u2026",
519
+ text: result.text,
520
+ element: "span"
521
+ })
522
+ });
523
+ };
524
+ const LinkWrapper = ({ children }) => asLink ? /* @__PURE__ */ React.createElement(Link, {
525
+ to: result.location
526
+ }, children) : /* @__PURE__ */ React.createElement(React.Fragment, null, children);
527
+ const ListItemWrapper = ({ children }) => asListItem ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ListItem, {
528
+ alignItems: "flex-start",
529
+ className: classes.flexContainer
530
+ }, children), /* @__PURE__ */ React.createElement(Divider, {
531
+ component: "li"
532
+ })) : /* @__PURE__ */ React.createElement(React.Fragment, null, children);
533
+ return /* @__PURE__ */ React.createElement(LinkWrapper, null, /* @__PURE__ */ React.createElement(ListItemWrapper, null, /* @__PURE__ */ React.createElement(TextItem, null)));
534
+ };
535
+ const DocsResultListItem = TechDocsSearchResultListItem;
536
+
537
+ const useStyles$2 = makeStyles({
538
+ root: {
539
+ width: "100%"
540
+ }
541
+ });
542
+ const TechDocsSearchBar = (props) => {
543
+ const { entityId, debounceTime = 150 } = props;
837
544
  const [open, setOpen] = useState(false);
838
545
  const navigate = useNavigate();
839
546
  const {
840
547
  term,
841
548
  setTerm,
549
+ setFilters,
842
550
  result: { loading, value: searchVal }
843
551
  } = useSearch();
552
+ const classes = useStyles$2();
844
553
  const [options, setOptions] = useState([]);
845
554
  useEffect(() => {
846
555
  let mounted = true;
@@ -854,6 +563,17 @@ const TechDocsSearchBar = ({
854
563
  }, [loading, searchVal]);
855
564
  const [value, setValue] = useState(term);
856
565
  useDebounce(() => setTerm(value), debounceTime, [value]);
566
+ const { kind, name, namespace } = entityId;
567
+ useEffect(() => {
568
+ setFilters((prevFilters) => {
569
+ return {
570
+ ...prevFilters,
571
+ kind,
572
+ namespace,
573
+ name
574
+ };
575
+ });
576
+ }, [kind, namespace, name, setFilters]);
857
577
  const handleQuery = (e) => {
858
578
  if (!open) {
859
579
  setOpen(true);
@@ -866,10 +586,8 @@ const TechDocsSearchBar = ({
866
586
  navigate(location);
867
587
  }
868
588
  };
869
- return /* @__PURE__ */ React.createElement(Grid, {
870
- item: true,
871
- xs: 12
872
- }, /* @__PURE__ */ React.createElement(Autocomplete, {
589
+ return /* @__PURE__ */ React.createElement(Autocomplete, {
590
+ classes: { root: classes.root },
873
591
  "data-testid": "techdocs-search-bar",
874
592
  size: "small",
875
593
  open,
@@ -888,7 +606,7 @@ const TechDocsSearchBar = ({
888
606
  noOptionsText: "No results found",
889
607
  value: null,
890
608
  options,
891
- renderOption: ({ document }) => /* @__PURE__ */ React.createElement(DocsResultListItem, {
609
+ renderOption: ({ document }) => /* @__PURE__ */ React.createElement(TechDocsSearchResultListItem, {
892
610
  result: document,
893
611
  lineClamp: 3,
894
612
  asListItem: false,
@@ -918,7 +636,7 @@ const TechDocsSearchBar = ({
918
636
  }) : null, params.InputProps.endAdornment)
919
637
  }
920
638
  })
921
- }));
639
+ });
922
640
  };
923
641
  const TechDocsSearch = (props) => {
924
642
  const initialState = {
@@ -987,7 +705,7 @@ const TechDocsBuildLogsDrawerContent = ({
987
705
  const TechDocsBuildLogs = ({ buildLog }) => {
988
706
  const classes = useDrawerStyles();
989
707
  const [open, setOpen] = useState(false);
990
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Button$1, {
708
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Button, {
991
709
  color: "inherit",
992
710
  onClick: () => setOpen(true)
993
711
  }, "Show Build Logs"), /* @__PURE__ */ React.createElement(Drawer, {
@@ -1014,7 +732,10 @@ const TechDocsNotFound = ({ errorMessage }) => {
1014
732
  });
1015
733
  };
1016
734
 
1017
- const useStyles$1 = makeStyles(() => ({
735
+ const useStyles$1 = makeStyles((theme) => ({
736
+ root: {
737
+ marginBottom: theme.spacing(2)
738
+ },
1018
739
  message: {
1019
740
  wordBreak: "break-word",
1020
741
  overflowWrap: "anywhere"
@@ -1033,6 +754,7 @@ const TechDocsStateIndicator = () => {
1033
754
  const ReaderProgress = state === "CHECKING" ? /* @__PURE__ */ React.createElement(Progress, null) : null;
1034
755
  if (state === "INITIAL_BUILD") {
1035
756
  StateAlert = /* @__PURE__ */ React.createElement(Alert, {
757
+ classes: { root: classes.root },
1036
758
  variant: "outlined",
1037
759
  severity: "info",
1038
760
  icon: /* @__PURE__ */ React.createElement(CircularProgress, {
@@ -1052,17 +774,19 @@ const TechDocsStateIndicator = () => {
1052
774
  }),
1053
775
  action: /* @__PURE__ */ React.createElement(TechDocsBuildLogs, {
1054
776
  buildLog
1055
- })
777
+ }),
778
+ classes: { root: classes.root }
1056
779
  }, "A newer version of this documentation is being prepared and will be available shortly.");
1057
780
  }
1058
781
  if (state === "CONTENT_STALE_READY") {
1059
782
  StateAlert = /* @__PURE__ */ React.createElement(Alert, {
1060
783
  variant: "outlined",
1061
784
  severity: "success",
1062
- action: /* @__PURE__ */ React.createElement(Button$1, {
785
+ action: /* @__PURE__ */ React.createElement(Button, {
1063
786
  color: "inherit",
1064
787
  onClick: () => contentReload()
1065
- }, "Refresh")
788
+ }, "Refresh"),
789
+ classes: { root: classes.root }
1066
790
  }, "A newer version of this documentation is now available, please refresh to view.");
1067
791
  }
1068
792
  if (state === "CONTENT_STALE_ERROR") {
@@ -1072,7 +796,7 @@ const TechDocsStateIndicator = () => {
1072
796
  action: /* @__PURE__ */ React.createElement(TechDocsBuildLogs, {
1073
797
  buildLog
1074
798
  }),
1075
- classes: { message: classes.message }
799
+ classes: { root: classes.root, message: classes.message }
1076
800
  }, "Building a newer version of this documentation failed.", " ", syncErrorMessage);
1077
801
  }
1078
802
  if (state === "CONTENT_NOT_FOUND") {
@@ -1082,7 +806,7 @@ const TechDocsStateIndicator = () => {
1082
806
  action: /* @__PURE__ */ React.createElement(TechDocsBuildLogs, {
1083
807
  buildLog
1084
808
  }),
1085
- classes: { message: classes.message }
809
+ classes: { root: classes.root, message: classes.message }
1086
810
  }, "Building a newer version of this documentation failed.", " ", syncErrorMessage), /* @__PURE__ */ React.createElement(TechDocsNotFound, {
1087
811
  errorMessage: contentErrorMessage
1088
812
  }));
@@ -1238,12 +962,13 @@ function useReaderState(kind, namespace, name, path) {
1238
962
 
1239
963
  const useStyles = makeStyles((theme) => ({
1240
964
  searchBar: {
1241
- marginLeft: "20rem",
1242
- maxWidth: "calc(100% - 20rem * 2 - 3rem)",
1243
- marginTop: theme.spacing(1),
965
+ maxWidth: "calc(100% - 16rem * 2 - 2.4rem)",
966
+ marginTop: 0,
967
+ marginBottom: theme.spacing(1),
968
+ marginLeft: "calc(16rem + 1.2rem)",
1244
969
  "@media screen and (max-width: 76.1875em)": {
1245
- marginLeft: "10rem",
1246
- maxWidth: "calc(100% - 10rem)"
970
+ marginLeft: "0",
971
+ maxWidth: "100%"
1247
972
  }
1248
973
  }
1249
974
  }));
@@ -1265,6 +990,7 @@ const withTechDocsReaderProvider = (Component, entityRef) => (props) => /* @__PU
1265
990
  ...props
1266
991
  }));
1267
992
  const useTechDocsReader = () => useContext(TechDocsReaderContext);
993
+ const headings = ["h1", "h2", "h3", "h4", "h5", "h6"];
1268
994
  const useTechDocsReaderDom = (entityRef) => {
1269
995
  const navigate = useNavigate$1();
1270
996
  const theme = useTheme();
@@ -1281,9 +1007,16 @@ const useTechDocsReaderDom = (entityRef) => {
1281
1007
  if (!dom || !sidebars)
1282
1008
  return;
1283
1009
  const mdTabs = dom.querySelector(".md-container > .md-tabs");
1010
+ const sidebarsCollapsed = window.matchMedia("screen and (max-width: 76.1875em)").matches;
1011
+ const newTop = Math.max(dom.getBoundingClientRect().top, 0);
1284
1012
  sidebars.forEach((sidebar) => {
1285
- const newTop = Math.max(dom.getBoundingClientRect().top, 0);
1286
- sidebar.style.top = mdTabs ? `${newTop + mdTabs.getBoundingClientRect().height}px` : `${newTop}px`;
1013
+ if (sidebarsCollapsed) {
1014
+ sidebar.style.top = "0px";
1015
+ } else if (mdTabs) {
1016
+ sidebar.style.top = `${newTop + mdTabs.getBoundingClientRect().height}px`;
1017
+ } else {
1018
+ sidebar.style.top = `${newTop}px`;
1019
+ }
1287
1020
  });
1288
1021
  }, [dom, sidebars]);
1289
1022
  useEffect(() => {
@@ -1322,179 +1055,463 @@ const useTechDocsReaderDom = (entityRef) => {
1322
1055
  path: contentPath
1323
1056
  }),
1324
1057
  rewriteDocLinks(),
1058
+ addSidebarToggle(),
1325
1059
  removeMkdocsHeader(),
1326
1060
  simplifyMkdocsFooter(),
1327
1061
  addGitFeedbackLink(scmIntegrationsApi),
1328
1062
  injectCss({
1329
1063
  css: `
1330
- body {
1331
- font-family: ${theme.typography.fontFamily};
1332
- --md-text-color: ${theme.palette.text.primary};
1333
- --md-text-link-color: ${theme.palette.primary.main};
1064
+ /*
1065
+ As the MkDocs output is rendered in shadow DOM, the CSS variable definitions on the root selector are not applied. Instead, they have to be applied on :host.
1066
+ As there is no way to transform the served main*.css yet (for example in the backend), we have to copy from main*.css and modify them.
1067
+ */
1068
+ :host {
1069
+ /* FONT */
1070
+ --md-default-fg-color: ${theme.palette.text.primary};
1071
+ --md-default-fg-color--light: ${theme.palette.text.secondary};
1072
+ --md-default-fg-color--lighter: ${lighten(theme.palette.text.secondary, 0.7)};
1073
+ --md-default-fg-color--lightest: ${lighten(theme.palette.text.secondary, 0.3)};
1074
+
1075
+ /* BACKGROUND */
1076
+ --md-default-bg-color:${theme.palette.background.default};
1077
+ --md-default-bg-color--light: ${theme.palette.background.paper};
1078
+ --md-default-bg-color--lighter: ${lighten(theme.palette.background.paper, 0.7)};
1079
+ --md-default-bg-color--lightest: ${lighten(theme.palette.background.paper, 0.3)};
1080
+
1081
+ /* PRIMARY */
1082
+ --md-primary-fg-color: ${theme.palette.primary.main};
1083
+ --md-primary-fg-color--light: ${theme.palette.primary.light};
1084
+ --md-primary-fg-color--dark: ${theme.palette.primary.dark};
1085
+ --md-primary-bg-color: ${theme.palette.primary.contrastText};
1086
+ --md-primary-bg-color--light: ${lighten(theme.palette.primary.contrastText, 0.7)};
1087
+
1088
+ /* ACCENT */
1089
+ --md-accent-fg-color: var(--md-primary-fg-color);
1334
1090
 
1091
+ /* SHADOW */
1092
+ --md-shadow-z1: ${theme.shadows[1]};
1093
+ --md-shadow-z2: ${theme.shadows[2]};
1094
+ --md-shadow-z3: ${theme.shadows[3]};
1095
+
1096
+ /* EXTENSIONS */
1097
+ --md-admonition-fg-color: var(--md-default-fg-color);
1098
+ --md-admonition-bg-color: var(--md-default-bg-color);
1099
+ /* Admonitions and others are using SVG masks to define icons. These masks are defined as CSS variables. */
1100
+ --md-admonition-icon--note: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>');
1101
+ --md-admonition-icon--abstract: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 5h16v2H4V5m0 4h16v2H4V9m0 4h16v2H4v-2m0 4h10v2H4v-2z"/></svg>');
1102
+ --md-admonition-icon--info: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 002 12a10 10 0 0010 10 10 10 0 0010-10A10 10 0 0012 2z"/></svg>');
1103
+ --md-admonition-icon--tip: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.55 11.2c-.23-.3-.5-.56-.76-.82-.65-.6-1.4-1.03-2.03-1.66C13.3 7.26 13 4.85 13.91 3c-.91.23-1.75.75-2.45 1.32-2.54 2.08-3.54 5.75-2.34 8.9.04.1.08.2.08.33 0 .22-.15.42-.35.5-.22.1-.46.04-.64-.12a.83.83 0 01-.15-.17c-1.1-1.43-1.28-3.48-.53-5.12C5.89 10 5 12.3 5.14 14.47c.04.5.1 1 .27 1.5.14.6.4 1.2.72 1.73 1.04 1.73 2.87 2.97 4.84 3.22 2.1.27 4.35-.12 5.96-1.6 1.8-1.66 2.45-4.32 1.5-6.6l-.13-.26c-.2-.46-.47-.87-.8-1.25l.05-.01m-3.1 6.3c-.28.24-.73.5-1.08.6-1.1.4-2.2-.16-2.87-.82 1.19-.28 1.89-1.16 2.09-2.05.17-.8-.14-1.46-.27-2.23-.12-.74-.1-1.37.18-2.06.17.38.37.76.6 1.06.76 1 1.95 1.44 2.2 2.8.04.14.06.28.06.43.03.82-.32 1.72-.92 2.27h.01z"/></svg>');
1104
+ --md-admonition-icon--success: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2m-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>');
1105
+ --md-admonition-icon--question: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.07 11.25l-.9.92C13.45 12.89 13 13.5 13 15h-2v-.5c0-1.11.45-2.11 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41a2 2 0 00-2-2 2 2 0 00-2 2H8a4 4 0 014-4 4 4 0 014 4 3.2 3.2 0 01-.93 2.25M13 19h-2v-2h2M12 2A10 10 0 002 12a10 10 0 0010 10 10 10 0 0010-10c0-5.53-4.5-10-10-10z"/></svg>');
1106
+ --md-admonition-icon--warning: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 14h-2v-4h2m0 8h-2v-2h2M1 21h22L12 2 1 21z"/></svg>');
1107
+ --md-admonition-icon--failure: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2c5.53 0 10 4.47 10 10s-4.47 10-10 10S2 17.53 2 12 6.47 2 12 2m3.59 5L12 10.59 8.41 7 7 8.41 10.59 12 7 15.59 8.41 17 12 13.41 15.59 17 17 15.59 13.41 12 17 8.41 15.59 7z"/></svg>');
1108
+ --md-admonition-icon--danger: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.5 20l4.86-9.73H13V4l-5 9.73h3.5V20M12 2c2.75 0 5.1 1 7.05 2.95C21 6.9 22 9.25 22 12s-1 5.1-2.95 7.05C17.1 21 14.75 22 12 22s-5.1-1-7.05-2.95C3 17.1 2 14.75 2 12s1-5.1 2.95-7.05C6.9 3 9.25 2 12 2z"/></svg>');
1109
+ --md-admonition-icon--bug: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 12h-4v-2h4m0 6h-4v-2h4m6-6h-2.81a5.985 5.985 0 00-1.82-1.96L17 4.41 15.59 3l-2.17 2.17a6.002 6.002 0 00-2.83 0L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8z"/></svg>');
1110
+ --md-admonition-icon--example: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 13v-2h14v2H7m0 6v-2h14v2H7M7 7V5h14v2H7M3 8V5H2V4h2v4H3m-1 9v-1h3v4H2v-1h2v-.5H3v-1h1V17H2m2.25-7a.75.75 0 01.75.75c0 .2-.08.39-.21.52L3.12 13H5v1H2v-.92L4 11H2v-1h2.25z"/></svg>');
1111
+ --md-admonition-icon--quote: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 17h3l2-4V7h-6v6h3M6 17h3l2-4V7H5v6h3l-2 4z"/></svg>');
1112
+ --md-footnotes-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.42L5.83 13H21V7h-2z"/></svg>');
1113
+ --md-details-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42z"/></svg>');
1114
+ --md-tasklist-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/></svg>');
1115
+ --md-tasklist-icon--checked: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>');
1116
+ --md-nav-icon--prev: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>');
1117
+ --md-nav-icon--next: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42z"/></svg>');
1118
+ --md-toc-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 9h14V7H3v2m0 4h14v-2H3v2m0 4h14v-2H3v2m16 0h2v-2h-2v2m0-10v2h2V7h-2m0 6h2v-2h-2v2z"/></svg>');
1119
+ --md-clipboard-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1z"/></svg>');
1120
+ --md-search-result-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h7c-.41-.25-.8-.56-1.14-.9-.33-.33-.61-.7-.86-1.1H6V4h7v5h5v1.18c.71.16 1.39.43 2 .82V8l-6-6m6.31 16.9c1.33-2.11.69-4.9-1.4-6.22-2.11-1.33-4.91-.68-6.22 1.4-1.34 2.11-.69 4.89 1.4 6.22 1.46.93 3.32.93 4.79.02L22 23.39 23.39 22l-3.08-3.1m-3.81.1a2.5 2.5 0 0 1-2.5-2.5 2.5 2.5 0 0 1 2.5-2.5 2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5z"/></svg>');
1121
+ --md-source-forks-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M5 3.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0zm0 2.122a2.25 2.25 0 1 0-1.5 0v.878A2.25 2.25 0 0 0 5.75 8.5h1.5v2.128a2.251 2.251 0 1 0 1.5 0V8.5h1.5a2.25 2.25 0 0 0 2.25-2.25v-.878a2.25 2.25 0 1 0-1.5 0v.878a.75.75 0 0 1-.75.75h-4.5A.75.75 0 0 1 5 6.25v-.878zm3.75 7.378a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0zm3-8.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5z"/></svg>');
1122
+ --md-source-repositories-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 1 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 0 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 0 1 1-1h8zM5 12.25v3.25a.25.25 0 0 0 .4.2l1.45-1.087a.25.25 0 0 1 .3 0L8.6 15.7a.25.25 0 0 0 .4-.2v-3.25a.25.25 0 0 0-.25-.25h-3.5a.25.25 0 0 0-.25.25z"/></svg>');
1123
+ --md-source-stars-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.75.75 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694v.001z"/></svg>');
1124
+ --md-source-version-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M2.5 7.775V2.75a.25.25 0 0 1 .25-.25h5.025a.25.25 0 0 1 .177.073l6.25 6.25a.25.25 0 0 1 0 .354l-5.025 5.025a.25.25 0 0 1-.354 0l-6.25-6.25a.25.25 0 0 1-.073-.177zm-1.5 0V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.75 1.75 0 0 1 1 7.775zM6 5a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"/></svg>');
1125
+ --md-version-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc.--><path d="m310.6 246.6-127.1 128c-7.1 6.3-15.3 9.4-23.5 9.4s-16.38-3.125-22.63-9.375l-127.1-128C.224 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75s3.12 25.75-6.08 34.85z"/></svg>');
1126
+ }
1127
+
1128
+ :host > * {
1129
+ /* CODE */
1335
1130
  --md-code-fg-color: ${theme.palette.text.primary};
1336
1131
  --md-code-bg-color: ${theme.palette.background.paper};
1337
- --md-accent-fg-color: ${theme.palette.primary.main};
1338
- --md-default-fg-color--lightest: ${theme.palette.textVerySubtle};
1339
- }
1340
- .codehilite .gd, .highlight .gd {
1341
- background-color: ${isDarkTheme ? "rgba(248,81,73,0.65)" : "#fdd"};
1342
- }
1343
- .codehilite .gi, .highlight .gi {
1344
- background-color: ${isDarkTheme ? "rgba(46,160,67,0.65)" : "#dfd"};
1345
- }
1346
- .highlight .kd {
1347
- color: ${isDarkTheme ? "#4aaaf7" : "#3b78e7"};
1348
- }
1349
- .highlight .k {
1350
- color: ${isDarkTheme ? "#4aaaf7" : "#3b78e7"};
1351
- }
1352
- .highlight .nx {
1353
- color: ${isDarkTheme ? "#ff53a3" : "#ec407a"};
1354
- }
1355
- .highlight .s1 {
1356
- color: ${isDarkTheme ? "#1cad46" : "rgb(13, 144, 79)"};
1357
- }
1358
- .highlight .kt {
1359
- color: ${isDarkTheme ? "#4aaaf7" : "#3e61a2"};
1360
- }
1361
- .md-main__inner { margin-top: 0; }
1362
- .md-sidebar { position: fixed; bottom: 100px; width: 20rem; }
1363
- .md-sidebar--secondary { right: 2rem; }
1364
- .md-content { margin-bottom: 50px }
1365
- .md-footer { position: fixed; bottom: 0px; }
1366
- .md-footer-nav__link { width: 20rem;}
1367
- .md-content { margin-left: 20rem; max-width: calc(100% - 20rem * 2 - 3rem); }
1368
- .md-typeset { font-size: 1rem; }
1369
- .md-typeset h1, .md-typeset h2, .md-typeset h3 { font-weight: bold; }
1370
- .md-nav { font-size: 1rem; }
1371
- .md-grid { max-width: 90vw; margin: 0 }
1372
- .md-typeset blockquote {
1373
- color: ${theme.palette.textSubtle};
1374
- border-left: 0.2rem solid ${theme.palette.textVerySubtle};
1375
- }
1376
- .md-typeset hr {
1377
- border-bottom: 0.05rem dotted ${theme.palette.textVerySubtle};
1378
- }
1379
- .md-typeset table:not([class]) {
1380
- font-size: 1rem;
1381
- border: 1px solid ${theme.palette.text.primary};
1382
- border-bottom: none;
1383
- border-collapse: collapse;
1384
- }
1385
- .md-typeset table:not([class]) td, .md-typeset table:not([class]) th {
1386
- border-bottom: 1px solid ${theme.palette.text.primary};
1387
- }
1388
- .md-typeset table:not([class]) th { font-weight: bold; }
1389
- .md-typeset .admonition, .md-typeset details {
1390
- font-size: inherit;
1132
+ --md-code-hl-color: ${alpha(theme.palette.warning.main, 0.5)};
1133
+ --md-code-hl-keyword-color: ${isDarkTheme ? theme.palette.primary.light : theme.palette.primary.dark};
1134
+ --md-code-hl-function-color: ${isDarkTheme ? theme.palette.secondary.light : theme.palette.secondary.dark};
1135
+ --md-code-hl-string-color: ${isDarkTheme ? theme.palette.success.light : theme.palette.success.dark};
1136
+ --md-code-hl-number-color: ${isDarkTheme ? theme.palette.error.light : theme.palette.error.dark};
1137
+ --md-code-hl-constant-color: var(--md-code-hl-function-color);
1138
+ --md-code-hl-special-color: var(--md-code-hl-function-color);
1139
+ --md-code-hl-name-color: var(--md-code-fg-color);
1140
+ --md-code-hl-comment-color: var(--md-default-fg-color--light);
1141
+ --md-code-hl-generic-color: var(--md-default-fg-color--light);
1142
+ --md-code-hl-variable-color: var(--md-default-fg-color--light);
1143
+ --md-code-hl-operator-color: var(--md-default-fg-color--light);
1144
+ --md-code-hl-punctuation-color: var(--md-default-fg-color--light);
1145
+
1146
+ /* TYPESET */
1147
+ --md-typeset-font-size: 1rem;
1148
+ --md-typeset-color: var(--md-default-fg-color);
1149
+ --md-typeset-a-color: var(--md-accent-fg-color);
1150
+ --md-typeset-table-color: ${theme.palette.text.primary};
1151
+ --md-typeset-del-color: ${isDarkTheme ? alpha(theme.palette.error.dark, 0.5) : alpha(theme.palette.error.light, 0.5)};
1152
+ --md-typeset-ins-color: ${isDarkTheme ? alpha(theme.palette.success.dark, 0.5) : alpha(theme.palette.success.light, 0.5)};
1153
+ --md-typeset-mark-color: ${isDarkTheme ? alpha(theme.palette.warning.dark, 0.5) : alpha(theme.palette.warning.light, 0.5)};
1391
1154
  }
1392
-
1393
- /* style the checkmarks of the task list */
1394
- .md-typeset .task-list-control .task-list-indicator::before {
1395
- background-color: ${theme.palette.action.disabledBackground};
1155
+
1156
+ @media screen and (max-width: 76.1875em) {
1157
+ :host > * {
1158
+ /* TYPESET */
1159
+ --md-typeset-font-size: .9rem;
1160
+ }
1396
1161
  }
1397
- .md-typeset .task-list-control [type="checkbox"]:checked + .task-list-indicator:before {
1398
- background-color: ${theme.palette.success.main};
1162
+
1163
+ @media screen and (max-width: 600px) {
1164
+ :host > * {
1165
+ /* TYPESET */
1166
+ --md-typeset-font-size: .7rem;
1167
+ }
1399
1168
  }
1400
- /**/
1169
+ `
1170
+ }),
1171
+ injectCss({
1172
+ css: `
1173
+ body {
1174
+ --md-text-color: var(--md-default-fg-color);
1175
+ --md-text-link-color: var(--md-accent-fg-color);
1176
+ --md-text-font-family: ${theme.typography.fontFamily};
1177
+ font-family: var(--md-text-font-family);
1178
+ background-color: unset;
1179
+ }
1180
+ `
1181
+ }),
1182
+ injectCss({
1183
+ css: `
1184
+ .md-grid {
1185
+ max-width: 100%;
1186
+ margin: 0;
1187
+ }
1401
1188
 
1402
- @media screen and (max-width: 76.1875em) {
1403
1189
  .md-nav {
1404
- background-color: ${theme.palette.background.default};
1405
- transition: none !important
1190
+ font-size: calc(var(--md-typeset-font-size) * 0.9);
1191
+ }
1192
+ .md-nav__link {
1193
+ display: flex;
1194
+ align-items: center;
1195
+ justify-content: space-between;
1196
+ }
1197
+ .md-nav__icon {
1198
+ height: 20px !important;
1199
+ width: 20px !important;
1200
+ margin-left:${theme.spacing(1)}px;
1201
+ }
1202
+ .md-nav__icon svg {
1203
+ margin: 0;
1204
+ width: 20px !important;
1205
+ height: 20px !important;
1206
+ }
1207
+ .md-nav__icon:after {
1208
+ width: 20px !important;
1209
+ height: 20px !important;
1210
+ }
1211
+
1212
+ .md-main__inner {
1213
+ margin-top: 0;
1214
+ }
1215
+
1216
+ .md-sidebar {
1217
+ height: calc(100% - 100px);
1218
+ position: fixed;
1219
+ width: 16rem;
1406
1220
  }
1407
- .md-sidebar--secondary { display: none; }
1408
- .md-sidebar--primary { left: ${isPinned ? "242px" : "72px"}; width: 10rem }
1409
- .md-content { margin-left: 10rem; max-width: calc(100% - 10rem); }
1410
- .md-content__inner { font-size: 0.9rem }
1221
+ .md-sidebar .md-sidebar__scrollwrap {
1222
+ max-height: calc(100% - 100px);
1223
+ }
1224
+ .md-sidebar--secondary {
1225
+ right: ${theme.spacing(3)}px;
1226
+ }
1227
+
1228
+ .md-content {
1229
+ max-width: calc(100% - 16rem * 2);
1230
+ margin-left: 16rem;
1231
+ margin-bottom: 50px;
1232
+ }
1233
+
1411
1234
  .md-footer {
1412
- position: static;
1413
- padding-left: 10rem;
1235
+ position: fixed;
1236
+ bottom: 0px;
1237
+ }
1238
+ .md-footer__title {
1239
+ background-color: unset;
1414
1240
  }
1415
1241
  .md-footer-nav__link {
1416
- /* footer links begin to overlap at small sizes without setting width */
1417
- width: 50%;
1242
+ width: 16rem;
1418
1243
  }
1419
- .md-nav--primary .md-nav__title {
1420
- white-space: normal;
1421
- height: auto;
1422
- line-height: 1rem;
1423
- cursor: auto;
1244
+
1245
+ .md-dialog {
1246
+ background-color: unset;
1424
1247
  }
1425
- .md-nav--primary > .md-nav__title [for="none"] {
1426
- padding-top: 0;
1248
+
1249
+ @media screen and (max-width: 76.1875em) {
1250
+ .md-nav {
1251
+ transition: none !important;
1252
+ background-color: var(--md-default-bg-color)
1253
+ }
1254
+ .md-nav--primary .md-nav__title {
1255
+ cursor: auto;
1256
+ color: var(--md-default-fg-color);
1257
+ font-weight: 700;
1258
+ white-space: normal;
1259
+ line-height: 1rem;
1260
+ height: auto;
1261
+ display: flex;
1262
+ flex-flow: column;
1263
+ row-gap: 1.6rem;
1264
+ padding: 1.2rem .8rem .8rem;
1265
+ background-color: var(--md-default-bg-color);
1266
+ }
1267
+ .md-nav--primary .md-nav__title~.md-nav__list {
1268
+ box-shadow: none;
1269
+ }
1270
+ .md-nav--primary .md-nav__title ~ .md-nav__list > :first-child {
1271
+ border-top: none;
1272
+ }
1273
+ .md-nav--primary .md-nav__title .md-nav__button {
1274
+ display: none;
1275
+ }
1276
+ .md-nav--primary .md-nav__title .md-nav__icon {
1277
+ color: var(--md-default-fg-color);
1278
+ position: static;
1279
+ height: auto;
1280
+ margin: 0 0 0 -0.2rem;
1281
+ }
1282
+ .md-nav--primary > .md-nav__title [for="none"] {
1283
+ padding-top: 0;
1284
+ }
1285
+ .md-nav--primary .md-nav__item {
1286
+ border-top: none;
1287
+ }
1288
+ .md-nav--primary :is(.md-nav__title,.md-nav__item) {
1289
+ font-size : var(--md-typeset-font-size);
1290
+ }
1291
+ .md-nav .md-source {
1292
+ display: none;
1293
+ }
1294
+
1295
+ .md-sidebar {
1296
+ height: 100%;
1297
+ }
1298
+ .md-sidebar--primary {
1299
+ width: 12.1rem !important;
1300
+ z-index: 200;
1301
+ left: ${isPinned ? "calc(-12.1rem + 242px)" : "calc(-12.1rem + 72px)"} !important;
1302
+ }
1303
+ .md-sidebar--secondary:not([hidden]) {
1304
+ display: none;
1305
+ }
1306
+
1307
+ .md-content {
1308
+ max-width: 100%;
1309
+ margin-left: 0;
1310
+ }
1311
+
1312
+ .md-header__button {
1313
+ margin: 0.4rem 0;
1314
+ margin-left: 0.4rem;
1315
+ padding: 0;
1316
+ }
1317
+
1318
+ .md-overlay {
1319
+ left: 0;
1320
+ }
1321
+
1322
+ .md-footer {
1323
+ position: static;
1324
+ padding-left: 0;
1325
+ }
1326
+ .md-footer-nav__link {
1327
+ /* footer links begin to overlap at small sizes without setting width */
1328
+ width: 50%;
1329
+ }
1427
1330
  }
1428
- }
1429
- `
1430
- }),
1431
- injectCss({
1432
- css: `
1433
- .md-nav__link, .md-typeset a, .md-typeset a::before, .md-typeset .headerlink {
1434
- transition: none;
1331
+
1332
+ @media screen and (max-width: 600px) {
1333
+ .md-sidebar--primary {
1334
+ left: -12.1rem !important;
1335
+ width: 12.1rem;
1336
+ }
1435
1337
  }
1436
1338
  `
1437
1339
  }),
1438
1340
  injectCss({
1439
1341
  css: `
1342
+ .md-typeset {
1343
+ font-size: var(--md-typeset-font-size);
1344
+ }
1345
+
1346
+ ${headings.reduce((style, heading) => {
1347
+ const styles = theme.typography[heading];
1348
+ const { lineHeight, fontFamily, fontWeight, fontSize } = styles;
1349
+ const calculate = (value) => {
1350
+ let factor = 1;
1351
+ if (typeof value === "number") {
1352
+ factor = value / 16 * 0.6;
1353
+ }
1354
+ if (typeof value === "string") {
1355
+ factor = value.replace("rem", "");
1356
+ }
1357
+ return `calc(${factor} * var(--md-typeset-font-size))`;
1358
+ };
1359
+ return style.concat(`
1360
+ .md-typeset ${heading} {
1361
+ color: var(--md-default-fg-color);
1362
+ line-height: ${lineHeight};
1363
+ font-family: ${fontFamily};
1364
+ font-weight: ${fontWeight};
1365
+ font-size: ${calculate(fontSize)};
1366
+ }
1367
+ `);
1368
+ }, "")}
1369
+
1370
+ .md-typeset .md-content__button {
1371
+ color: var(--md-default-fg-color);
1372
+ }
1373
+
1374
+ .md-typeset hr {
1375
+ border-bottom: 0.05rem dotted ${theme.palette.divider};
1376
+ }
1377
+
1378
+ .md-typeset details {
1379
+ font-size: var(--md-typeset-font-size) !important;
1380
+ }
1381
+ .md-typeset details summary {
1382
+ padding-left: 2.5rem !important;
1383
+ }
1384
+ .md-typeset details summary:before,
1385
+ .md-typeset details summary:after {
1386
+ top: 50% !important;
1387
+ width: 20px !important;
1388
+ height: 20px !important;
1389
+ transform: rotate(0deg) translateY(-50%) !important;
1390
+ }
1391
+ .md-typeset details[open] > summary:after {
1392
+ transform: rotate(90deg) translateX(-50%) !important;
1393
+ }
1394
+
1395
+ .md-typeset blockquote {
1396
+ color: var(--md-default-fg-color--light);
1397
+ border-left: 0.2rem solid var(--md-default-fg-color--light);
1398
+ }
1399
+
1400
+ .md-typeset table:not([class]) {
1401
+ font-size: var(--md-typeset-font-size);
1402
+ border: 1px solid var(--md-default-fg-color);
1403
+ border-bottom: none;
1404
+ border-collapse: collapse;
1405
+ }
1406
+ .md-typeset table:not([class]) th {
1407
+ font-weight: bold;
1408
+ }
1409
+ .md-typeset table:not([class]) td, .md-typeset table:not([class]) th {
1410
+ border-bottom: 1px solid var(--md-default-fg-color);
1411
+ }
1412
+
1440
1413
  .md-typeset pre > code::-webkit-scrollbar-thumb {
1441
1414
  background-color: hsla(0, 0%, 0%, 0.32);
1442
1415
  }
1443
1416
  .md-typeset pre > code::-webkit-scrollbar-thumb:hover {
1444
1417
  background-color: hsla(0, 0%, 0%, 0.87);
1445
1418
  }
1446
- `
1419
+ `
1420
+ }),
1421
+ injectCss({
1422
+ css: `
1423
+ /*
1424
+ Disable CSS animations on link colors as they lead to issues in dark mode.
1425
+ The dark mode color theme is applied later and theirfore there is always an animation from light to dark mode when navigation between pages.
1426
+ */
1427
+ .md-dialog, .md-nav__link, .md-footer__link, .md-typeset a, .md-typeset a::before, .md-typeset .headerlink {
1428
+ transition: none;
1429
+ }
1430
+ `
1447
1431
  }),
1448
1432
  injectCss({
1449
1433
  css: `
1450
- :host {
1451
- --md-admonition-icon--note: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>');
1452
- --md-admonition-icon--abstract: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 5h16v2H4V5m0 4h16v2H4V9m0 4h16v2H4v-2m0 4h10v2H4v-2z"/></svg>');
1453
- --md-admonition-icon--info: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 002 12a10 10 0 0010 10 10 10 0 0010-10A10 10 0 0012 2z"/></svg>');
1454
- --md-admonition-icon--tip: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.55 11.2c-.23-.3-.5-.56-.76-.82-.65-.6-1.4-1.03-2.03-1.66C13.3 7.26 13 4.85 13.91 3c-.91.23-1.75.75-2.45 1.32-2.54 2.08-3.54 5.75-2.34 8.9.04.1.08.2.08.33 0 .22-.15.42-.35.5-.22.1-.46.04-.64-.12a.83.83 0 01-.15-.17c-1.1-1.43-1.28-3.48-.53-5.12C5.89 10 5 12.3 5.14 14.47c.04.5.1 1 .27 1.5.14.6.4 1.2.72 1.73 1.04 1.73 2.87 2.97 4.84 3.22 2.1.27 4.35-.12 5.96-1.6 1.8-1.66 2.45-4.32 1.5-6.6l-.13-.26c-.2-.46-.47-.87-.8-1.25l.05-.01m-3.1 6.3c-.28.24-.73.5-1.08.6-1.1.4-2.2-.16-2.87-.82 1.19-.28 1.89-1.16 2.09-2.05.17-.8-.14-1.46-.27-2.23-.12-.74-.1-1.37.18-2.06.17.38.37.76.6 1.06.76 1 1.95 1.44 2.2 2.8.04.14.06.28.06.43.03.82-.32 1.72-.92 2.27h.01z"/></svg>');
1455
- --md-admonition-icon--success: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2m-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>');
1456
- --md-admonition-icon--question: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.07 11.25l-.9.92C13.45 12.89 13 13.5 13 15h-2v-.5c0-1.11.45-2.11 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41a2 2 0 00-2-2 2 2 0 00-2 2H8a4 4 0 014-4 4 4 0 014 4 3.2 3.2 0 01-.93 2.25M13 19h-2v-2h2M12 2A10 10 0 002 12a10 10 0 0010 10 10 10 0 0010-10c0-5.53-4.5-10-10-10z"/></svg>');
1457
- --md-admonition-icon--warning: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 14h-2v-4h2m0 8h-2v-2h2M1 21h22L12 2 1 21z"/></svg>');
1458
- --md-admonition-icon--failure: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2c5.53 0 10 4.47 10 10s-4.47 10-10 10S2 17.53 2 12 6.47 2 12 2m3.59 5L12 10.59 8.41 7 7 8.41 10.59 12 7 15.59 8.41 17 12 13.41 15.59 17 17 15.59 13.41 12 17 8.41 15.59 7z"/></svg>');
1459
- --md-admonition-icon--danger: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.5 20l4.86-9.73H13V4l-5 9.73h3.5V20M12 2c2.75 0 5.1 1 7.05 2.95C21 6.9 22 9.25 22 12s-1 5.1-2.95 7.05C17.1 21 14.75 22 12 22s-5.1-1-7.05-2.95C3 17.1 2 14.75 2 12s1-5.1 2.95-7.05C6.9 3 9.25 2 12 2z"/></svg>');
1460
- --md-admonition-icon--bug: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 12h-4v-2h4m0 6h-4v-2h4m6-6h-2.81a5.985 5.985 0 00-1.82-1.96L17 4.41 15.59 3l-2.17 2.17a6.002 6.002 0 00-2.83 0L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8z"/></svg>');
1461
- --md-admonition-icon--example: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 13v-2h14v2H7m0 6v-2h14v2H7M7 7V5h14v2H7M3 8V5H2V4h2v4H3m-1 9v-1h3v4H2v-1h2v-.5H3v-1h1V17H2m2.25-7a.75.75 0 01.75.75c0 .2-.08.39-.21.52L3.12 13H5v1H2v-.92L4 11H2v-1h2.25z"/></svg>');
1462
- --md-admonition-icon--quote: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 17h3l2-4V7h-6v6h3M6 17h3l2-4V7H5v6h3l-2 4z"/></svg>');
1434
+ /* HIGHLIGHT */
1435
+ .highlight .md-clipboard:after {
1436
+ content: unset;
1437
+ }
1438
+
1439
+ .highlight .nx {
1440
+ color: ${isDarkTheme ? "#ff53a3" : "#ec407a"};
1463
1441
  }
1464
- :host {
1465
- --md-footnotes-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.42L5.83 13H21V7h-2z"/></svg>');
1442
+
1443
+ /* CODE HILITE */
1444
+ .codehilite .gd {
1445
+ background-color: ${isDarkTheme ? "rgba(248,81,73,0.65)" : "#fdd"};
1446
+ }
1447
+
1448
+ .codehilite .gi {
1449
+ background-color: ${isDarkTheme ? "rgba(46,160,67,0.65)" : "#dfd"};
1450
+ }
1451
+
1452
+ /* TABBED */
1453
+ .tabbed-set>input:nth-child(1):checked~.tabbed-labels>:nth-child(1),
1454
+ .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),
1455
+ .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),
1456
+ .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),
1457
+ .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),
1458
+ .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),
1459
+ .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),
1460
+ .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),
1461
+ .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),
1462
+ .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),
1463
+ .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),
1464
+ .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),
1465
+ .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),
1466
+ .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),
1467
+ .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),
1468
+ .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),
1469
+ .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),
1470
+ .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),
1471
+ .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),
1472
+ .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20) {
1473
+ color: var(--md-accent-fg-color);
1474
+ border-color: var(--md-accent-fg-color);
1475
+ }
1476
+
1477
+ /* TASK-LIST */
1478
+ .task-list-control .task-list-indicator::before {
1479
+ background-color: ${theme.palette.action.disabledBackground};
1480
+ }
1481
+ .task-list-control [type="checkbox"]:checked + .task-list-indicator:before {
1482
+ background-color: ${theme.palette.success.main};
1466
1483
  }
1467
- :host {
1468
- --md-details-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.59 16.58L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42z"/></svg>');
1484
+
1485
+ /* ADMONITION */
1486
+ .admonition {
1487
+ font-size: var(--md-typeset-font-size) !important;
1488
+ }
1489
+ .admonition .admonition-title {
1490
+ padding-left: 2.5rem !important;
1469
1491
  }
1470
- :host {
1471
- --md-tasklist-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/></svg>');
1472
- --md-tasklist-icon--checked: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>');
1492
+
1493
+ .admonition .admonition-title:before {
1494
+ top: 50% !important;
1495
+ width: 20px !important;
1496
+ height: 20px !important;
1497
+ transform: translateY(-50%) !important;
1473
1498
  }
1474
- `
1499
+ `
1475
1500
  })
1476
1501
  ]), [
1477
- techdocsSanitizer,
1478
- techdocsStorageApi,
1479
1502
  kind,
1480
1503
  name,
1481
1504
  namespace,
1482
1505
  scmIntegrationsApi,
1483
- theme.typography.fontFamily,
1484
- theme.palette.text.primary,
1485
- theme.palette.primary.main,
1486
- theme.palette.background.paper,
1487
- theme.palette.background.default,
1488
- theme.palette.textVerySubtle,
1489
- theme.palette.textSubtle,
1490
- theme.palette.action.disabledBackground,
1491
- theme.palette.success.main,
1506
+ techdocsSanitizer,
1507
+ techdocsStorageApi,
1508
+ theme,
1492
1509
  isDarkTheme,
1493
1510
  isPinned
1494
1511
  ]);
1495
1512
  const postRender = useCallback(async (transformedElement) => transform(transformedElement, [
1496
1513
  scrollIntoAnchor(),
1497
- copyToClipboard(),
1514
+ copyToClipboard(theme),
1498
1515
  addLinkClickListener({
1499
1516
  baseUrl: window.location.origin,
1500
1517
  onClick: (event, url) => {
@@ -1530,7 +1547,7 @@ const useTechDocsReaderDom = (entityRef) => {
1530
1547
  setSidebars(Array.from(renderedElement.querySelectorAll(".md-sidebar")));
1531
1548
  }
1532
1549
  })
1533
- ]), [navigate, techdocsStorageApi]);
1550
+ ]), [theme, navigate, techdocsStorageApi]);
1534
1551
  useEffect(() => {
1535
1552
  if (!rawPage)
1536
1553
  return () => {
@@ -1586,24 +1603,31 @@ const TheReader = ({
1586
1603
  ref: shadowDomRef
1587
1604
  }));
1588
1605
  };
1589
- const Reader = ({
1590
- entityRef,
1591
- onReady = () => {
1592
- },
1593
- withSearch = true
1594
- }) => /* @__PURE__ */ React.createElement(TechDocsReaderProvider, {
1595
- entityRef
1596
- }, /* @__PURE__ */ React.createElement(TheReader, {
1597
- entityRef,
1598
- onReady,
1599
- withSearch
1600
- }));
1606
+ const Reader = (props) => {
1607
+ const { entityRef, onReady = () => {
1608
+ }, withSearch = true } = props;
1609
+ return /* @__PURE__ */ React.createElement(TechDocsReaderProvider, {
1610
+ entityRef
1611
+ }, /* @__PURE__ */ React.createElement(TheReader, {
1612
+ entityRef,
1613
+ onReady,
1614
+ withSearch
1615
+ }));
1616
+ };
1601
1617
 
1602
- const TechDocsPageHeader = ({
1603
- entityRef,
1604
- entityMetadata,
1605
- techDocsMetadata
1606
- }) => {
1618
+ const rootRouteRef = createRouteRef({
1619
+ id: "techdocs:index-page"
1620
+ });
1621
+ const rootDocsRouteRef = createRouteRef({
1622
+ id: "techdocs:reader-page",
1623
+ params: ["namespace", "kind", "name"]
1624
+ });
1625
+ const rootCatalogDocsRouteRef = createRouteRef({
1626
+ id: "techdocs:catalog-reader-view"
1627
+ });
1628
+
1629
+ const TechDocsReaderPageHeader = (props) => {
1630
+ const { entityRef, entityMetadata, techDocsMetadata, children } = props;
1607
1631
  const { name } = entityRef;
1608
1632
  const { site_name: siteName, site_description: siteDescription } = techDocsMetadata || {};
1609
1633
  const { locationMetadata, spec } = entityMetadata || {};
@@ -1643,8 +1667,9 @@ const TechDocsPageHeader = ({
1643
1667
  subtitle: siteDescription && siteDescription !== "None" ? siteDescription : "",
1644
1668
  type: "Docs",
1645
1669
  typeLink: docsRootLink
1646
- }, labels);
1670
+ }, labels, children);
1647
1671
  };
1672
+ const TechDocsPageHeader = TechDocsReaderPageHeader;
1648
1673
 
1649
1674
  const LegacyTechDocsPage = () => {
1650
1675
  const [documentReady, setDocumentReady] = useState(false);
@@ -1669,7 +1694,7 @@ const LegacyTechDocsPage = () => {
1669
1694
  }
1670
1695
  return /* @__PURE__ */ React.createElement(Page, {
1671
1696
  themeId: "documentation"
1672
- }, /* @__PURE__ */ React.createElement(TechDocsPageHeader, {
1697
+ }, /* @__PURE__ */ React.createElement(TechDocsReaderPageHeader, {
1673
1698
  techDocsMetadata: techdocsMetadataValue,
1674
1699
  entityMetadata: entityMetadataValue,
1675
1700
  entityRef: {
@@ -1689,7 +1714,9 @@ const LegacyTechDocsPage = () => {
1689
1714
  })));
1690
1715
  };
1691
1716
 
1692
- const TechDocsPage = ({ children }) => {
1717
+ const TechDocsReaderPage$1 = (props) => {
1718
+ const { children } = props;
1719
+ const { NotFoundErrorPage } = useApp().getComponents();
1693
1720
  const outlet = useOutlet();
1694
1721
  const [documentReady, setDocumentReady] = useState(false);
1695
1722
  const { namespace, kind, name } = useParams();
@@ -1702,15 +1729,12 @@ const TechDocsPage = ({ children }) => {
1702
1729
  }, [kind, namespace, name, techdocsApi, documentReady]);
1703
1730
  const { value: entityMetadataValue, error: entityMetadataError } = useAsync(() => {
1704
1731
  return techdocsApi.getEntityMetadata({ kind, namespace, name });
1705
- }, [kind, namespace, name, techdocsApi]);
1706
- const onReady = useCallback(() => {
1707
- setDocumentReady(true);
1708
- }, [setDocumentReady]);
1709
- if (entityMetadataError) {
1710
- return /* @__PURE__ */ React.createElement(TechDocsNotFound, {
1711
- errorMessage: entityMetadataError.message
1712
- });
1713
- }
1732
+ }, [kind, namespace, name, techdocsApi]);
1733
+ const onReady = useCallback(() => {
1734
+ setDocumentReady(true);
1735
+ }, [setDocumentReady]);
1736
+ if (entityMetadataError)
1737
+ return /* @__PURE__ */ React.createElement(NotFoundErrorPage, null);
1714
1738
  if (!children)
1715
1739
  return outlet || /* @__PURE__ */ React.createElement(LegacyTechDocsPage, null);
1716
1740
  return /* @__PURE__ */ React.createElement(Page, {
@@ -1722,145 +1746,328 @@ const TechDocsPage = ({ children }) => {
1722
1746
  onReady
1723
1747
  }) : children);
1724
1748
  };
1749
+ const TechDocsPage = TechDocsReaderPage$1;
1725
1750
 
1726
- var TechDocsPage$1 = /*#__PURE__*/Object.freeze({
1751
+ var TechDocsReaderPage$2 = /*#__PURE__*/Object.freeze({
1727
1752
  __proto__: null,
1753
+ TechDocsReaderPage: TechDocsReaderPage$1,
1728
1754
  TechDocsPage: TechDocsPage
1729
1755
  });
1730
1756
 
1731
- const panels = {
1732
- DocsTable: DocsTable$1,
1733
- DocsCardGrid: DocsCardGrid$1
1757
+ function toLowerMaybe(str, config) {
1758
+ return config.getOptionalBoolean("techdocs.legacyUseCaseSensitiveTripletPaths") ? str : str.toLocaleLowerCase("en-US");
1759
+ }
1760
+
1761
+ const DocsCardGrid = (props) => {
1762
+ const { entities } = props;
1763
+ const getRouteToReaderPageFor = useRouteRef(rootDocsRouteRef);
1764
+ const config = useApi(configApiRef);
1765
+ if (!entities)
1766
+ return null;
1767
+ return /* @__PURE__ */ React.createElement(ItemCardGrid, {
1768
+ "data-testid": "docs-explore"
1769
+ }, !(entities == null ? void 0 : entities.length) ? null : entities.map((entity, index) => {
1770
+ var _a, _b;
1771
+ return /* @__PURE__ */ React.createElement(Card, {
1772
+ key: index
1773
+ }, /* @__PURE__ */ React.createElement(CardMedia, null, /* @__PURE__ */ React.createElement(ItemCardHeader, {
1774
+ title: (_a = entity.metadata.title) != null ? _a : entity.metadata.name
1775
+ })), /* @__PURE__ */ React.createElement(CardContent, null, entity.metadata.description), /* @__PURE__ */ React.createElement(CardActions, null, /* @__PURE__ */ React.createElement(Button$1, {
1776
+ to: getRouteToReaderPageFor({
1777
+ namespace: toLowerMaybe((_b = entity.metadata.namespace) != null ? _b : "default", config),
1778
+ kind: toLowerMaybe(entity.kind, config),
1779
+ name: toLowerMaybe(entity.metadata.name, config)
1780
+ }),
1781
+ color: "primary",
1782
+ "data-testid": "read_docs"
1783
+ }, "Read Docs")));
1784
+ }));
1734
1785
  };
1735
- const CustomPanel = ({
1736
- config,
1737
- entities,
1738
- index
1739
- }) => {
1740
- const useStyles = makeStyles({
1741
- panelContainer: {
1742
- marginBottom: "2rem",
1743
- ...config.panelCSS ? config.panelCSS : {}
1744
- }
1786
+
1787
+ const EntityListDocsGrid = () => {
1788
+ const { loading, error, entities } = useEntityList();
1789
+ if (error) {
1790
+ return /* @__PURE__ */ React.createElement(WarningPanel, {
1791
+ severity: "error",
1792
+ title: "Could not load available documentation."
1793
+ }, /* @__PURE__ */ React.createElement(CodeSnippet, {
1794
+ language: "text",
1795
+ text: error.toString()
1796
+ }));
1797
+ }
1798
+ if (loading || !entities) {
1799
+ return /* @__PURE__ */ React.createElement(Progress, null);
1800
+ }
1801
+ entities.sort((a, b) => {
1802
+ var _a, _b;
1803
+ return ((_a = a.metadata.title) != null ? _a : a.metadata.name).localeCompare((_b = b.metadata.title) != null ? _b : b.metadata.name);
1745
1804
  });
1746
- const classes = useStyles();
1747
- const { value: user } = useOwnUser();
1748
- const Panel = panels[config.panelType];
1749
- const shownEntities = entities.filter((entity) => {
1750
- if (config.filterPredicate === "ownedByUser") {
1751
- if (!user) {
1752
- return false;
1753
- }
1754
- return isOwnerOf(user, entity);
1755
- }
1756
- return typeof config.filterPredicate === "function" && config.filterPredicate(entity);
1805
+ return /* @__PURE__ */ React.createElement(DocsCardGrid, {
1806
+ entities
1757
1807
  });
1758
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ContentHeader, {
1759
- title: config.title,
1760
- description: config.description
1761
- }, index === 0 ? /* @__PURE__ */ React.createElement(SupportButton, null, "Discover documentation in your ecosystem.") : null), /* @__PURE__ */ React.createElement("div", {
1762
- className: classes.panelContainer
1763
- }, /* @__PURE__ */ React.createElement(Panel, {
1764
- "data-testid": "techdocs-custom-panel",
1765
- entities: shownEntities
1766
- })));
1767
1808
  };
1768
- const TechDocsCustomHome = ({
1769
- tabsConfig
1770
- }) => {
1771
- const [selectedTab, setSelectedTab] = useState(0);
1772
- const catalogApi = useApi(catalogApiRef);
1773
- const {
1774
- value: entities,
1775
- loading,
1776
- error
1777
- } = useAsync(async () => {
1778
- const response = await catalogApi.getEntities({
1779
- filter: {
1780
- "metadata.annotations.backstage.io/techdocs-ref": CATALOG_FILTER_EXISTS
1781
- },
1782
- fields: [
1783
- "apiVersion",
1784
- "kind",
1785
- "metadata",
1786
- "relations",
1787
- "spec.owner",
1788
- "spec.type"
1789
- ]
1790
- });
1791
- return response.items.filter((entity) => {
1792
- var _a;
1793
- return !!((_a = entity.metadata.annotations) == null ? void 0 : _a["backstage.io/techdocs-ref"]);
1794
- });
1795
- });
1796
- const currentTabConfig = tabsConfig[selectedTab];
1797
- if (loading) {
1798
- return /* @__PURE__ */ React.createElement(TechDocsPageWrapper, null, /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(Progress, null)));
1809
+
1810
+ const YellowStar = withStyles$1({
1811
+ root: {
1812
+ color: "#f3ba37"
1813
+ }
1814
+ })(Star);
1815
+ const actionFactories = {
1816
+ createCopyDocsUrlAction(copyToClipboard) {
1817
+ return (row) => {
1818
+ return {
1819
+ icon: () => /* @__PURE__ */ React.createElement(ShareIcon, {
1820
+ fontSize: "small"
1821
+ }),
1822
+ tooltip: "Click to copy documentation link to clipboard",
1823
+ onClick: () => copyToClipboard(`${window.location.origin}${row.resolved.docsUrl}`)
1824
+ };
1825
+ };
1826
+ },
1827
+ createStarEntityAction(isStarredEntity, toggleStarredEntity) {
1828
+ return ({ entity }) => {
1829
+ const isStarred = isStarredEntity(entity);
1830
+ return {
1831
+ cellStyle: { paddingLeft: "1em" },
1832
+ icon: () => isStarred ? /* @__PURE__ */ React.createElement(YellowStar, null) : /* @__PURE__ */ React.createElement(StarBorder, null),
1833
+ tooltip: isStarred ? "Remove from favorites" : "Add to favorites",
1834
+ onClick: () => toggleStarredEntity(entity)
1835
+ };
1836
+ };
1837
+ }
1838
+ };
1839
+
1840
+ function customTitle(entity) {
1841
+ return entity.metadata.title || entity.metadata.name;
1842
+ }
1843
+ const columnFactories = {
1844
+ createNameColumn() {
1845
+ return {
1846
+ title: "Document",
1847
+ field: "entity.metadata.name",
1848
+ highlight: true,
1849
+ render: (row) => /* @__PURE__ */ React.createElement(SubvalueCell, {
1850
+ value: /* @__PURE__ */ React.createElement(Link, {
1851
+ to: row.resolved.docsUrl
1852
+ }, customTitle(row.entity)),
1853
+ subvalue: row.entity.metadata.description
1854
+ })
1855
+ };
1856
+ },
1857
+ createOwnerColumn() {
1858
+ return {
1859
+ title: "Owner",
1860
+ field: "resolved.ownedByRelationsTitle",
1861
+ render: ({ resolved }) => /* @__PURE__ */ React.createElement(EntityRefLinks, {
1862
+ entityRefs: resolved.ownedByRelations,
1863
+ defaultKind: "group"
1864
+ })
1865
+ };
1866
+ },
1867
+ createTypeColumn() {
1868
+ return {
1869
+ title: "Type",
1870
+ field: "entity.spec.type"
1871
+ };
1799
1872
  }
1873
+ };
1874
+
1875
+ const DocsTable = (props) => {
1876
+ const { entities, title, loading, columns, actions } = props;
1877
+ const [, copyToClipboard] = useCopyToClipboard();
1878
+ const getRouteToReaderPageFor = useRouteRef(rootDocsRouteRef);
1879
+ const config = useApi(configApiRef);
1880
+ if (!entities)
1881
+ return null;
1882
+ const documents = entities.map((entity) => {
1883
+ var _a;
1884
+ const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);
1885
+ return {
1886
+ entity,
1887
+ resolved: {
1888
+ docsUrl: getRouteToReaderPageFor({
1889
+ namespace: toLowerMaybe((_a = entity.metadata.namespace) != null ? _a : "default", config),
1890
+ kind: toLowerMaybe(entity.kind, config),
1891
+ name: toLowerMaybe(entity.metadata.name, config)
1892
+ }),
1893
+ ownedByRelations,
1894
+ ownedByRelationsTitle: ownedByRelations.map((r) => humanizeEntityRef(r, { defaultKind: "group" })).join(", ")
1895
+ }
1896
+ };
1897
+ });
1898
+ const defaultColumns = [
1899
+ columnFactories.createNameColumn(),
1900
+ columnFactories.createOwnerColumn(),
1901
+ columnFactories.createTypeColumn()
1902
+ ];
1903
+ const defaultActions = [
1904
+ actionFactories.createCopyDocsUrlAction(copyToClipboard)
1905
+ ];
1906
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, loading || documents && documents.length > 0 ? /* @__PURE__ */ React.createElement(Table, {
1907
+ isLoading: loading,
1908
+ options: {
1909
+ paging: true,
1910
+ pageSize: 20,
1911
+ search: true,
1912
+ actionsColumnIndex: -1
1913
+ },
1914
+ data: documents,
1915
+ columns: columns || defaultColumns,
1916
+ actions: actions || defaultActions,
1917
+ title: title ? `${title} (${documents.length})` : `All (${documents.length})`
1918
+ }) : /* @__PURE__ */ React.createElement(EmptyState, {
1919
+ missing: "data",
1920
+ title: "No documents to show",
1921
+ description: "Create your own document. Check out our Getting Started Information",
1922
+ action: /* @__PURE__ */ React.createElement(Button$1, {
1923
+ color: "primary",
1924
+ to: "https://backstage.io/docs/features/techdocs/getting-started",
1925
+ variant: "contained"
1926
+ }, "DOCS")
1927
+ }));
1928
+ };
1929
+ DocsTable.columns = columnFactories;
1930
+ DocsTable.actions = actionFactories;
1931
+
1932
+ const EntityListDocsTable = (props) => {
1933
+ var _a, _b;
1934
+ const { columns, actions } = props;
1935
+ const { loading, error, entities, filters } = useEntityList();
1936
+ const { isStarredEntity, toggleStarredEntity } = useStarredEntities();
1937
+ const [, copyToClipboard] = useCopyToClipboard();
1938
+ const title = capitalize((_b = (_a = filters.user) == null ? void 0 : _a.value) != null ? _b : "all");
1939
+ const defaultActions = [
1940
+ actionFactories.createCopyDocsUrlAction(copyToClipboard),
1941
+ actionFactories.createStarEntityAction(isStarredEntity, toggleStarredEntity)
1942
+ ];
1800
1943
  if (error) {
1801
- return /* @__PURE__ */ React.createElement(TechDocsPageWrapper, null, /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(WarningPanel, {
1944
+ return /* @__PURE__ */ React.createElement(WarningPanel, {
1802
1945
  severity: "error",
1803
1946
  title: "Could not load available documentation."
1804
1947
  }, /* @__PURE__ */ React.createElement(CodeSnippet, {
1805
1948
  language: "text",
1806
1949
  text: error.toString()
1807
- }))));
1950
+ }));
1808
1951
  }
1809
- return /* @__PURE__ */ React.createElement(TechDocsPageWrapper, null, /* @__PURE__ */ React.createElement(HeaderTabs, {
1810
- selectedIndex: selectedTab,
1811
- onChange: (index) => setSelectedTab(index),
1812
- tabs: tabsConfig.map(({ label }, index) => ({
1813
- id: index.toString(),
1814
- label
1815
- }))
1816
- }), /* @__PURE__ */ React.createElement(Content, {
1817
- "data-testid": "techdocs-content"
1818
- }, currentTabConfig.panels.map((config, index) => /* @__PURE__ */ React.createElement(CustomPanel, {
1819
- key: index,
1820
- config,
1821
- entities: !!entities ? entities : [],
1822
- index
1823
- }))));
1952
+ return /* @__PURE__ */ React.createElement(DocsTable, {
1953
+ title,
1954
+ entities,
1955
+ loading,
1956
+ actions: actions || defaultActions,
1957
+ columns
1958
+ });
1824
1959
  };
1960
+ EntityListDocsTable.columns = columnFactories;
1961
+ EntityListDocsTable.actions = actionFactories;
1825
1962
 
1826
- var TechDocsCustomHome$1 = /*#__PURE__*/Object.freeze({
1827
- __proto__: null,
1828
- TechDocsCustomHome: TechDocsCustomHome
1829
- });
1963
+ const TechDocsPageWrapper = (props) => {
1964
+ var _a;
1965
+ const { children } = props;
1966
+ const configApi = useApi(configApiRef);
1967
+ const generatedSubtitle = `Documentation available in ${(_a = configApi.getOptionalString("organization.name")) != null ? _a : "Backstage"}`;
1968
+ return /* @__PURE__ */ React.createElement(PageWithHeader, {
1969
+ title: "Documentation",
1970
+ subtitle: generatedSubtitle,
1971
+ themeId: "documentation"
1972
+ }, children);
1973
+ };
1830
1974
 
1831
- const LegacyTechDocsHome = () => {
1832
- const tabsConfig = [
1833
- {
1834
- label: "Overview",
1835
- panels: [
1836
- {
1837
- title: "Overview",
1838
- description: "Explore your internal technical ecosystem through documentation.",
1839
- panelType: "DocsCardGrid",
1840
- filterPredicate: () => true
1841
- }
1842
- ]
1843
- },
1844
- {
1845
- label: "Owned Documents",
1846
- panels: [
1847
- {
1848
- title: "Owned documents",
1849
- description: "Access your documentation.",
1850
- panelType: "DocsTable",
1851
- filterPredicate: "ownedByUser"
1852
- }
1853
- ]
1854
- }
1855
- ];
1856
- return /* @__PURE__ */ React.createElement(TechDocsCustomHome, {
1857
- tabsConfig
1858
- });
1975
+ class TechDocsFilter {
1976
+ getCatalogFilters() {
1977
+ return {
1978
+ "metadata.annotations.backstage.io/techdocs-ref": CATALOG_FILTER_EXISTS
1979
+ };
1980
+ }
1981
+ }
1982
+ const TechDocsPicker = () => {
1983
+ const { updateFilters } = useEntityList();
1984
+ useEffect(() => {
1985
+ updateFilters({
1986
+ techdocs: new TechDocsFilter()
1987
+ });
1988
+ }, [updateFilters]);
1989
+ return null;
1990
+ };
1991
+
1992
+ const DefaultTechDocsHome = (props) => {
1993
+ const { initialFilter = "all", columns, actions } = props;
1994
+ return /* @__PURE__ */ React.createElement(TechDocsPageWrapper, null, /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(ContentHeader, {
1995
+ title: ""
1996
+ }, /* @__PURE__ */ React.createElement(SupportButton, null, "Discover documentation in your ecosystem.")), /* @__PURE__ */ React.createElement(EntityListProvider, null, /* @__PURE__ */ React.createElement(FilteredEntityLayout, null, /* @__PURE__ */ React.createElement(FilterContainer, null, /* @__PURE__ */ React.createElement(TechDocsPicker, null), /* @__PURE__ */ React.createElement(UserListPicker, {
1997
+ initialFilter
1998
+ }), /* @__PURE__ */ React.createElement(EntityOwnerPicker, null), /* @__PURE__ */ React.createElement(EntityTagPicker, null)), /* @__PURE__ */ React.createElement(EntityListContainer, null, /* @__PURE__ */ React.createElement(EntityListDocsTable, {
1999
+ actions,
2000
+ columns
2001
+ }))))));
1859
2002
  };
1860
2003
 
2004
+ const techdocsPlugin = createPlugin({
2005
+ id: "techdocs",
2006
+ apis: [
2007
+ createApiFactory({
2008
+ api: techdocsStorageApiRef,
2009
+ deps: {
2010
+ configApi: configApiRef,
2011
+ discoveryApi: discoveryApiRef,
2012
+ identityApi: identityApiRef,
2013
+ fetchApi: fetchApiRef
2014
+ },
2015
+ factory: ({ configApi, discoveryApi, identityApi, fetchApi }) => new TechDocsStorageClient({
2016
+ configApi,
2017
+ discoveryApi,
2018
+ identityApi,
2019
+ fetchApi
2020
+ })
2021
+ }),
2022
+ createApiFactory({
2023
+ api: techdocsApiRef,
2024
+ deps: {
2025
+ configApi: configApiRef,
2026
+ discoveryApi: discoveryApiRef,
2027
+ fetchApi: fetchApiRef
2028
+ },
2029
+ factory: ({ configApi, discoveryApi, fetchApi }) => new TechDocsClient({
2030
+ configApi,
2031
+ discoveryApi,
2032
+ fetchApi
2033
+ })
2034
+ })
2035
+ ],
2036
+ routes: {
2037
+ root: rootRouteRef,
2038
+ docRoot: rootDocsRouteRef,
2039
+ entityContent: rootCatalogDocsRouteRef
2040
+ }
2041
+ });
2042
+ const TechdocsPage = techdocsPlugin.provide(createRoutableExtension({
2043
+ name: "TechdocsPage",
2044
+ component: () => Promise.resolve().then(function () { return Router$1; }).then((m) => m.Router),
2045
+ mountPoint: rootRouteRef
2046
+ }));
2047
+ const EntityTechdocsContent = techdocsPlugin.provide(createRoutableExtension({
2048
+ name: "EntityTechdocsContent",
2049
+ component: () => Promise.resolve().then(function () { return Router$1; }).then((m) => m.EmbeddedDocsRouter),
2050
+ mountPoint: rootCatalogDocsRouteRef
2051
+ }));
2052
+ const TechDocsCustomHome = techdocsPlugin.provide(createRoutableExtension({
2053
+ name: "TechDocsCustomHome",
2054
+ component: () => import('./esm/TechDocsCustomHome-a4f542cd.esm.js').then((m) => m.TechDocsCustomHome),
2055
+ mountPoint: rootRouteRef
2056
+ }));
2057
+ const TechDocsIndexPage$2 = techdocsPlugin.provide(createRoutableExtension({
2058
+ name: "TechDocsIndexPage",
2059
+ component: () => Promise.resolve().then(function () { return TechDocsIndexPage$1; }).then((m) => m.TechDocsIndexPage),
2060
+ mountPoint: rootRouteRef
2061
+ }));
2062
+ const TechDocsReaderPage = techdocsPlugin.provide(createRoutableExtension({
2063
+ name: "TechDocsReaderPage",
2064
+ component: () => Promise.resolve().then(function () { return TechDocsReaderPage$2; }).then((m) => m.TechDocsReaderPage),
2065
+ mountPoint: rootDocsRouteRef
2066
+ }));
2067
+
1861
2068
  const TechDocsIndexPage = () => {
1862
2069
  const outlet = useOutlet();
1863
- return outlet || /* @__PURE__ */ React.createElement(LegacyTechDocsHome, null);
2070
+ return outlet || /* @__PURE__ */ React.createElement(DefaultTechDocsHome, null);
1864
2071
  };
1865
2072
 
1866
2073
  var TechDocsIndexPage$1 = /*#__PURE__*/Object.freeze({
@@ -1892,10 +2099,10 @@ const Router = () => {
1892
2099
  element: /* @__PURE__ */ React.createElement(TechDocsIndexPage, null)
1893
2100
  }), /* @__PURE__ */ React.createElement(Route, {
1894
2101
  path: "/:namespace/:kind/:name/*",
1895
- element: /* @__PURE__ */ React.createElement(TechDocsPage, null)
2102
+ element: /* @__PURE__ */ React.createElement(TechDocsReaderPage$1, null)
1896
2103
  }));
1897
2104
  };
1898
- const EmbeddedDocsRouter = (_props) => {
2105
+ const EmbeddedDocsRouter = () => {
1899
2106
  var _a;
1900
2107
  const { entity } = useEntity();
1901
2108
  const projectId = (_a = entity.metadata.annotations) == null ? void 0 : _a[TECHDOCS_ANNOTATION];
@@ -1919,5 +2126,5 @@ var Router$1 = /*#__PURE__*/Object.freeze({
1919
2126
  EmbeddedDocsRouter: EmbeddedDocsRouter
1920
2127
  });
1921
2128
 
1922
- export { DefaultTechDocsHome, DocsCardGrid, DocsResultListItem, DocsTable, EmbeddedDocsRouter, EntityListDocsGrid, EntityListDocsTable, EntityTechdocsContent, Reader, Router, TechDocsClient, TechDocsCustomHome$2 as TechDocsCustomHome, TechDocsIndexPage$2 as TechDocsIndexPage, TechDocsPage, TechDocsPageHeader, TechDocsPageWrapper, TechDocsPicker, TechDocsReaderPage, TechDocsSearch, TechDocsStateIndicator, TechDocsStorageClient, TechdocsPage, isTechDocsAvailable, techdocsPlugin as plugin, techdocsApiRef, techdocsPlugin, techdocsStorageApiRef, useTechDocsReader, useTechDocsReaderDom, withTechDocsReaderProvider };
2129
+ export { DefaultTechDocsHome, DocsCardGrid, DocsResultListItem, DocsTable, EmbeddedDocsRouter, EntityListDocsGrid, EntityListDocsTable, EntityTechdocsContent, Reader, Router, TechDocsClient, TechDocsCustomHome, TechDocsIndexPage$2 as TechDocsIndexPage, TechDocsPage, TechDocsPageHeader, TechDocsPageWrapper, TechDocsPicker, TechDocsReaderPage, TechDocsReaderPageHeader, TechDocsSearch, TechDocsSearchResultListItem, TechDocsStateIndicator, TechDocsStorageClient, TechdocsPage, isTechDocsAvailable, techdocsPlugin as plugin, techdocsApiRef, techdocsPlugin, techdocsStorageApiRef, useTechDocsReader, useTechDocsReaderDom, withTechDocsReaderProvider };
1923
2130
  //# sourceMappingURL=index.esm.js.map