@backstage/plugin-techdocs-module-addons-contrib 1.1.9 → 1.1.10-next.0

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @backstage/plugin-techdocs-module-addons-contrib
2
2
 
3
+ ## 1.1.10-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @backstage/core-components@0.14.5-next.0
9
+ - @backstage/plugin-techdocs-react@1.2.4-next.0
10
+ - @backstage/core-plugin-api@1.9.2
11
+ - @backstage/integration@1.10.0
12
+ - @backstage/integration-react@1.1.26
13
+
3
14
  ## 1.1.9
4
15
 
5
16
  ### Patch Changes
@@ -0,0 +1,81 @@
1
+ import React, { useState, useCallback, useEffect } from 'react';
2
+ import { useLocalStorageValue } from '@react-hookz/web';
3
+ import { withStyles, Button } from '@material-ui/core';
4
+ import ChevronRightIcon from '@material-ui/icons/ChevronRight';
5
+ import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
6
+ import { useShadowRootElements } from '@backstage/plugin-techdocs-react';
7
+
8
+ const NESTED_LIST_TOGGLE = ".md-nav__item--nested .md-toggle";
9
+ const EXPANDABLE_NAVIGATION_LOCAL_STORAGE = "@backstage/techdocs-addons/nav-expanded";
10
+ const StyledButton = withStyles({
11
+ root: {
12
+ position: "absolute",
13
+ left: "220px",
14
+ top: "19px",
15
+ padding: 0,
16
+ minWidth: 0
17
+ }
18
+ })(Button);
19
+ const CollapsedIcon = withStyles({
20
+ root: {
21
+ height: "20px",
22
+ width: "20px"
23
+ }
24
+ })(ChevronRightIcon);
25
+ const ExpandedIcon = withStyles({
26
+ root: {
27
+ height: "20px",
28
+ width: "20px"
29
+ }
30
+ })(ExpandMoreIcon);
31
+ const ExpandableNavigationAddon = () => {
32
+ const defaultValue = { expandAllNestedNavs: false };
33
+ const { value: expanded, set: setExpanded } = useLocalStorageValue(
34
+ EXPANDABLE_NAVIGATION_LOCAL_STORAGE,
35
+ { defaultValue }
36
+ );
37
+ const [hasNavSubLevels, setHasNavSubLevels] = useState(false);
38
+ const [...checkboxToggles] = useShadowRootElements([
39
+ NESTED_LIST_TOGGLE
40
+ ]);
41
+ const shouldToggle = useCallback(
42
+ (item) => {
43
+ const isExpanded = item.checked;
44
+ const shouldExpand = expanded == null ? void 0 : expanded.expandAllNestedNavs;
45
+ if (shouldExpand && !isExpanded) {
46
+ return true;
47
+ }
48
+ if (!shouldExpand && isExpanded) {
49
+ return true;
50
+ }
51
+ return false;
52
+ },
53
+ [expanded]
54
+ );
55
+ useEffect(() => {
56
+ if (!(checkboxToggles == null ? void 0 : checkboxToggles.length))
57
+ return;
58
+ setHasNavSubLevels(true);
59
+ checkboxToggles.forEach((item) => {
60
+ if (shouldToggle(item))
61
+ item.click();
62
+ });
63
+ }, [expanded, shouldToggle, checkboxToggles]);
64
+ const handleState = () => {
65
+ setExpanded((prevState) => ({
66
+ expandAllNestedNavs: !(prevState == null ? void 0 : prevState.expandAllNestedNavs)
67
+ }));
68
+ };
69
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, hasNavSubLevels ? /* @__PURE__ */ React.createElement(
70
+ StyledButton,
71
+ {
72
+ size: "small",
73
+ onClick: handleState,
74
+ "aria-label": (expanded == null ? void 0 : expanded.expandAllNestedNavs) ? "collapse-nav" : "expand-nav"
75
+ },
76
+ (expanded == null ? void 0 : expanded.expandAllNestedNavs) ? /* @__PURE__ */ React.createElement(ExpandedIcon, null) : /* @__PURE__ */ React.createElement(CollapsedIcon, null)
77
+ ) : null);
78
+ };
79
+
80
+ export { ExpandableNavigationAddon };
81
+ //# sourceMappingURL=ExpandableNavigation.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpandableNavigation.esm.js","sources":["../../src/ExpandableNavigation/ExpandableNavigation.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useEffect, useCallback, useState } from 'react';\nimport { useLocalStorageValue } from '@react-hookz/web';\nimport { Button, withStyles } from '@material-ui/core';\nimport ChevronRightIcon from '@material-ui/icons/ChevronRight';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\n\nimport { useShadowRootElements } from '@backstage/plugin-techdocs-react';\n\nconst NESTED_LIST_TOGGLE = '.md-nav__item--nested .md-toggle';\n\nconst EXPANDABLE_NAVIGATION_LOCAL_STORAGE =\n '@backstage/techdocs-addons/nav-expanded';\n\nconst StyledButton = withStyles({\n root: {\n position: 'absolute',\n left: '220px',\n top: '19px',\n padding: 0,\n minWidth: 0,\n },\n})(Button);\n\nconst CollapsedIcon = withStyles({\n root: {\n height: '20px',\n width: '20px',\n },\n})(ChevronRightIcon);\n\nconst ExpandedIcon = withStyles({\n root: {\n height: '20px',\n width: '20px',\n },\n})(ExpandMoreIcon);\n\ntype expandableNavigationLocalStorage = {\n expandAllNestedNavs: boolean;\n};\n\n/**\n * Show expand/collapse navigation button next to site name in main\n * navigation menu if documentation site has nested navigation.\n */\nexport const ExpandableNavigationAddon = () => {\n const defaultValue = { expandAllNestedNavs: false };\n const { value: expanded, set: setExpanded } =\n useLocalStorageValue<expandableNavigationLocalStorage>(\n EXPANDABLE_NAVIGATION_LOCAL_STORAGE,\n { defaultValue },\n );\n const [hasNavSubLevels, setHasNavSubLevels] = useState<boolean>(false);\n\n const [...checkboxToggles] = useShadowRootElements<HTMLInputElement>([\n NESTED_LIST_TOGGLE,\n ]);\n\n const shouldToggle = useCallback(\n (item: HTMLInputElement) => {\n const isExpanded = item.checked;\n const shouldExpand = expanded?.expandAllNestedNavs;\n\n // Is collapsed but should expand\n if (shouldExpand && !isExpanded) {\n return true;\n }\n\n // Is expanded but should collapse\n if (!shouldExpand && isExpanded) {\n return true;\n }\n\n return false;\n },\n [expanded],\n );\n\n useEffect(() => {\n // There is no nested navs\n if (!checkboxToggles?.length) return;\n\n setHasNavSubLevels(true);\n checkboxToggles.forEach(item => {\n if (shouldToggle(item)) item.click();\n });\n }, [expanded, shouldToggle, checkboxToggles]);\n\n const handleState = () => {\n setExpanded(prevState => ({\n expandAllNestedNavs: !prevState?.expandAllNestedNavs,\n }));\n };\n\n return (\n <>\n {hasNavSubLevels ? (\n <StyledButton\n size=\"small\"\n onClick={handleState}\n aria-label={\n expanded?.expandAllNestedNavs ? 'collapse-nav' : 'expand-nav'\n }\n >\n {expanded?.expandAllNestedNavs ? <ExpandedIcon /> : <CollapsedIcon />}\n </StyledButton>\n ) : null}\n </>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { useEffect } from 'react';
2
+ import { useShadowRootElements } from '@backstage/plugin-techdocs-react';
3
+ import PhotoSwipeLightbox from 'photoswipe/lightbox';
4
+ import PhotoSwipe from 'photoswipe';
5
+ import 'photoswipe/style.css';
6
+
7
+ const LightBoxAddon = () => {
8
+ const images = useShadowRootElements(["img"]);
9
+ useEffect(() => {
10
+ let dataSourceImages = null;
11
+ let lightbox = new PhotoSwipeLightbox({
12
+ pswpModule: PhotoSwipe,
13
+ initialZoomLevel: 1,
14
+ secondaryZoomLevel: (zoomLevelObject) => {
15
+ const imageWidth = zoomLevelObject.elementSize.x;
16
+ const imageHeight = zoomLevelObject.elementSize.y;
17
+ const viewportWidth = zoomLevelObject.panAreaSize.x;
18
+ const viewportHeight = zoomLevelObject.panAreaSize.y;
19
+ const widthScale = viewportWidth / imageWidth;
20
+ const heightScale = viewportHeight / imageHeight;
21
+ const scaleFactor = Math.min(widthScale, heightScale);
22
+ return scaleFactor;
23
+ },
24
+ wheelToZoom: true,
25
+ arrowPrevSVG: '<svg class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge css-c1sh5i" focusable="false" aria-hidden="true" viewBox="0 0 24 24" data-testid="ArrowBackIosIcon" aria-label="fontSize large"><path d="M11.67 3.87 9.9 2.1 0 12l9.9 9.9 1.77-1.77L3.54 12z"></path></svg>',
26
+ arrowNextSVG: '<svg class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge css-c1sh5i" focusable="false" aria-hidden="true" viewBox="0 0 24 24" data-testid="ArrowForwardIosIcon" aria-label="fontSize large"><path d="M6.23 20.23 8 22l10-10L8 2 6.23 3.77 14.46 12z"></path></svg>',
27
+ closeSVG: '<svg class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge css-c1sh5i" focusable="false" aria-hidden="true" viewBox="0 0 24 24" data-testid="CloseIcon" aria-label="fontSize large"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></svg>',
28
+ zoomSVG: `<svg class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge css-c1sh5i" focusable="false" aria-hidden="true" viewBox="0 0 24 24" data-testid="ZoomIcon" aria-label="fontSize large">
29
+ <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path><path d="M12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z" id="photoswipe-zoom-icon-zoomin-path"></path><path d="M12 10H 7 V 9 H 12 Z" id="photoswipe-zoom-icon-zoomout-path">
30
+ </svg>`
31
+ });
32
+ images.forEach((image, index) => {
33
+ image.onclick = () => {
34
+ if (dataSourceImages === null) {
35
+ dataSourceImages = images.map((dataSourceImage) => {
36
+ return {
37
+ element: dataSourceImage,
38
+ src: dataSourceImage.src,
39
+ msrc: dataSourceImage.src,
40
+ alt: dataSourceImage.alt,
41
+ width: dataSourceImage.clientWidth,
42
+ height: dataSourceImage.clientHeight
43
+ };
44
+ });
45
+ }
46
+ lightbox.loadAndOpen(index, dataSourceImages);
47
+ return false;
48
+ };
49
+ });
50
+ lightbox.init();
51
+ return () => {
52
+ lightbox.destroy();
53
+ lightbox = null;
54
+ };
55
+ }, [images]);
56
+ return null;
57
+ };
58
+
59
+ export { LightBoxAddon };
60
+ //# sourceMappingURL=LightBox.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LightBox.esm.js","sources":["../../src/LigthBox/LightBox.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect } from 'react';\nimport { useShadowRootElements } from '@backstage/plugin-techdocs-react';\n// @ts-ignore\nimport PhotoSwipeLightbox, { DataSource, ZoomLevel } from 'photoswipe/lightbox';\nimport PhotoSwipe from 'photoswipe';\nimport 'photoswipe/style.css';\nimport './lightbox.css';\n\nexport const LightBoxAddon = () => {\n const images = useShadowRootElements<HTMLImageElement>(['img']);\n\n useEffect(() => {\n let dataSourceImages: DataSource | null = null;\n\n let lightbox = new PhotoSwipeLightbox({\n pswpModule: PhotoSwipe,\n initialZoomLevel: 1,\n secondaryZoomLevel: (zoomLevelObject: ZoomLevel) => {\n // photoswipe/lightbox won't zoom the image further then the given width and height.\n // therefore we need to calculate the zoom factor needed to fit the complete image in the viewport manually.\n const imageWidth = zoomLevelObject.elementSize.x;\n const imageHeight = zoomLevelObject.elementSize.y;\n const viewportWidth = zoomLevelObject.panAreaSize.x;\n const viewportHeight = zoomLevelObject.panAreaSize.y;\n\n const widthScale = viewportWidth / imageWidth;\n const heightScale = viewportHeight / imageHeight;\n\n const scaleFactor = Math.min(widthScale, heightScale);\n return scaleFactor;\n },\n wheelToZoom: true,\n arrowPrevSVG:\n '<svg class=\"MuiSvgIcon-root MuiSvgIcon-fontSizeLarge css-c1sh5i\" focusable=\"false\" aria-hidden=\"true\" viewBox=\"0 0 24 24\" data-testid=\"ArrowBackIosIcon\" aria-label=\"fontSize large\"><path d=\"M11.67 3.87 9.9 2.1 0 12l9.9 9.9 1.77-1.77L3.54 12z\"></path></svg>',\n arrowNextSVG:\n '<svg class=\"MuiSvgIcon-root MuiSvgIcon-fontSizeLarge css-c1sh5i\" focusable=\"false\" aria-hidden=\"true\" viewBox=\"0 0 24 24\" data-testid=\"ArrowForwardIosIcon\" aria-label=\"fontSize large\"><path d=\"M6.23 20.23 8 22l10-10L8 2 6.23 3.77 14.46 12z\"></path></svg>',\n closeSVG:\n '<svg class=\"MuiSvgIcon-root MuiSvgIcon-fontSizeLarge css-c1sh5i\" focusable=\"false\" aria-hidden=\"true\" viewBox=\"0 0 24 24\" data-testid=\"CloseIcon\" aria-label=\"fontSize large\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>',\n zoomSVG: `<svg class=\"MuiSvgIcon-root MuiSvgIcon-fontSizeLarge css-c1sh5i\" focusable=\"false\" aria-hidden=\"true\" viewBox=\"0 0 24 24\" data-testid=\"ZoomIcon\" aria-label=\"fontSize large\">\n <path d=\"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z\"></path><path d=\"M12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z\" id=\"photoswipe-zoom-icon-zoomin-path\"></path><path d=\"M12 10H 7 V 9 H 12 Z\" id=\"photoswipe-zoom-icon-zoomout-path\">\n </svg>`,\n });\n\n images.forEach((image, index) => {\n image.onclick = () => {\n if (dataSourceImages === null) {\n dataSourceImages = images.map(dataSourceImage => {\n return {\n element: dataSourceImage,\n src: dataSourceImage.src,\n msrc: dataSourceImage.src,\n alt: dataSourceImage.alt,\n width: dataSourceImage.clientWidth,\n height: dataSourceImage.clientHeight,\n };\n });\n }\n lightbox.loadAndOpen(index, dataSourceImages);\n return false;\n };\n });\n lightbox.init();\n\n return () => {\n lightbox.destroy();\n lightbox = null;\n };\n }, [images]);\n\n return null;\n};\n"],"names":[],"mappings":";;;;;;AAwBO,MAAM,gBAAgB,MAAM;AACjC,EAAA,MAAM,MAAS,GAAA,qBAAA,CAAwC,CAAC,KAAK,CAAC,CAAA,CAAA;AAE9D,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,gBAAsC,GAAA,IAAA,CAAA;AAE1C,IAAI,IAAA,QAAA,GAAW,IAAI,kBAAmB,CAAA;AAAA,MACpC,UAAY,EAAA,UAAA;AAAA,MACZ,gBAAkB,EAAA,CAAA;AAAA,MAClB,kBAAA,EAAoB,CAAC,eAA+B,KAAA;AAGlD,QAAM,MAAA,UAAA,GAAa,gBAAgB,WAAY,CAAA,CAAA,CAAA;AAC/C,QAAM,MAAA,WAAA,GAAc,gBAAgB,WAAY,CAAA,CAAA,CAAA;AAChD,QAAM,MAAA,aAAA,GAAgB,gBAAgB,WAAY,CAAA,CAAA,CAAA;AAClD,QAAM,MAAA,cAAA,GAAiB,gBAAgB,WAAY,CAAA,CAAA,CAAA;AAEnD,QAAA,MAAM,aAAa,aAAgB,GAAA,UAAA,CAAA;AACnC,QAAA,MAAM,cAAc,cAAiB,GAAA,WAAA,CAAA;AAErC,QAAA,MAAM,WAAc,GAAA,IAAA,CAAK,GAAI,CAAA,UAAA,EAAY,WAAW,CAAA,CAAA;AACpD,QAAO,OAAA,WAAA,CAAA;AAAA,OACT;AAAA,MACA,WAAa,EAAA,IAAA;AAAA,MACb,YACE,EAAA,mQAAA;AAAA,MACF,YACE,EAAA,iQAAA;AAAA,MACF,QACE,EAAA,8SAAA;AAAA,MACF,OAAS,EAAA,CAAA;AAAA;AAAA,cAAA,CAAA;AAAA,KAGV,CAAA,CAAA;AAED,IAAO,MAAA,CAAA,OAAA,CAAQ,CAAC,KAAA,EAAO,KAAU,KAAA;AAC/B,MAAA,KAAA,CAAM,UAAU,MAAM;AACpB,QAAA,IAAI,qBAAqB,IAAM,EAAA;AAC7B,UAAmB,gBAAA,GAAA,MAAA,CAAO,IAAI,CAAmB,eAAA,KAAA;AAC/C,YAAO,OAAA;AAAA,cACL,OAAS,EAAA,eAAA;AAAA,cACT,KAAK,eAAgB,CAAA,GAAA;AAAA,cACrB,MAAM,eAAgB,CAAA,GAAA;AAAA,cACtB,KAAK,eAAgB,CAAA,GAAA;AAAA,cACrB,OAAO,eAAgB,CAAA,WAAA;AAAA,cACvB,QAAQ,eAAgB,CAAA,YAAA;AAAA,aAC1B,CAAA;AAAA,WACD,CAAA,CAAA;AAAA,SACH;AACA,QAAS,QAAA,CAAA,WAAA,CAAY,OAAO,gBAAgB,CAAA,CAAA;AAC5C,QAAO,OAAA,KAAA,CAAA;AAAA,OACT,CAAA;AAAA,KACD,CAAA,CAAA;AACD,IAAA,QAAA,CAAS,IAAK,EAAA,CAAA;AAEd,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,OAAQ,EAAA,CAAA;AACjB,MAAW,QAAA,GAAA,IAAA,CAAA;AAAA,KACb,CAAA;AAAA,GACF,EAAG,CAAC,MAAM,CAAC,CAAA,CAAA;AAEX,EAAO,OAAA,IAAA,CAAA;AACT;;;;"}
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ import { makeStyles } from '@material-ui/core';
3
+ import BugReportIcon from '@material-ui/icons/BugReport';
4
+ import { Link, GitHubIcon } from '@backstage/core-components';
5
+
6
+ const useStyles = makeStyles((theme) => ({
7
+ root: {
8
+ display: "grid",
9
+ gridGap: theme.spacing(1),
10
+ gridAutoFlow: "column",
11
+ justifyContent: "center",
12
+ alignItems: "center",
13
+ color: theme.palette.common.black,
14
+ fontSize: theme.typography.button.fontSize
15
+ }
16
+ }));
17
+ const getIcon = ({ type }) => {
18
+ if (type === "github") {
19
+ return GitHubIcon;
20
+ }
21
+ return BugReportIcon;
22
+ };
23
+ const getName = ({ type }) => {
24
+ if (type === "github") {
25
+ return "Github";
26
+ }
27
+ return "Gitlab";
28
+ };
29
+ const getUrl = (repository, template) => {
30
+ const { title, body } = template;
31
+ const encodedTitle = encodeURIComponent(title);
32
+ const encodedBody = encodeURIComponent(body);
33
+ const { protocol, resource, owner, name, type } = repository;
34
+ const url = `${protocol}://${resource}/${owner}/${name}`;
35
+ const encodedUrl = encodeURI(url);
36
+ if (type === "github") {
37
+ return `${encodedUrl}/issues/new?title=${encodedTitle}&body=${encodedBody}`;
38
+ }
39
+ return `${encodedUrl}/issues/new?issue[title]=${encodedTitle}&issue[description]=${encodedBody}`;
40
+ };
41
+ const IssueLink = ({ template, repository }) => {
42
+ const classes = useStyles();
43
+ const Icon = getIcon(repository);
44
+ const url = getUrl(repository, template);
45
+ return /* @__PURE__ */ React.createElement(Link, { className: classes.root, to: url, target: "_blank" }, /* @__PURE__ */ React.createElement(Icon, null), " Open new ", getName(repository), " issue");
46
+ };
47
+
48
+ export { IssueLink };
49
+ //# sourceMappingURL=IssueLink.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IssueLink.esm.js","sources":["../../src/ReportIssue/IssueLink.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\n\nimport { makeStyles } from '@material-ui/core';\nimport BugReportIcon from '@material-ui/icons/BugReport';\n\nimport { Link, GitHubIcon } from '@backstage/core-components';\n\nimport { ReportIssueTemplate, Repository } from './types';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n display: 'grid',\n gridGap: theme.spacing(1),\n gridAutoFlow: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n color: theme.palette.common.black,\n fontSize: theme.typography.button.fontSize,\n },\n}));\n\ntype IssueLinkProps = {\n template: ReportIssueTemplate;\n repository: Repository;\n};\n\nconst getIcon = ({ type }: Repository) => {\n if (type === 'github') {\n return GitHubIcon;\n }\n return BugReportIcon;\n};\n\nconst getName = ({ type }: Repository) => {\n if (type === 'github') {\n return 'Github';\n }\n return 'Gitlab';\n};\n\nconst getUrl = (repository: Repository, template: ReportIssueTemplate) => {\n const { title, body } = template;\n const encodedTitle = encodeURIComponent(title);\n const encodedBody = encodeURIComponent(body);\n const { protocol, resource, owner, name, type } = repository;\n\n const url = `${protocol}://${resource}/${owner}/${name}`;\n const encodedUrl = encodeURI(url);\n if (type === 'github') {\n return `${encodedUrl}/issues/new?title=${encodedTitle}&body=${encodedBody}`;\n }\n return `${encodedUrl}/issues/new?issue[title]=${encodedTitle}&issue[description]=${encodedBody}`;\n};\n\nexport const IssueLink = ({ template, repository }: IssueLinkProps) => {\n const classes = useStyles();\n\n const Icon = getIcon(repository);\n const url = getUrl(repository, template);\n\n return (\n <Link className={classes.root} to={url} target=\"_blank\">\n <Icon /> Open new {getName(repository)} issue\n </Link>\n );\n};\n"],"names":[],"mappings":";;;;;AAyBA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,IAAM,EAAA;AAAA,IACJ,OAAS,EAAA,MAAA;AAAA,IACT,OAAA,EAAS,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IACxB,YAAc,EAAA,QAAA;AAAA,IACd,cAAgB,EAAA,QAAA;AAAA,IAChB,UAAY,EAAA,QAAA;AAAA,IACZ,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,MAAO,CAAA,KAAA;AAAA,IAC5B,QAAA,EAAU,KAAM,CAAA,UAAA,CAAW,MAAO,CAAA,QAAA;AAAA,GACpC;AACF,CAAE,CAAA,CAAA,CAAA;AAOF,MAAM,OAAU,GAAA,CAAC,EAAE,IAAA,EAAuB,KAAA;AACxC,EAAA,IAAI,SAAS,QAAU,EAAA;AACrB,IAAO,OAAA,UAAA,CAAA;AAAA,GACT;AACA,EAAO,OAAA,aAAA,CAAA;AACT,CAAA,CAAA;AAEA,MAAM,OAAU,GAAA,CAAC,EAAE,IAAA,EAAuB,KAAA;AACxC,EAAA,IAAI,SAAS,QAAU,EAAA;AACrB,IAAO,OAAA,QAAA,CAAA;AAAA,GACT;AACA,EAAO,OAAA,QAAA,CAAA;AACT,CAAA,CAAA;AAEA,MAAM,MAAA,GAAS,CAAC,UAAA,EAAwB,QAAkC,KAAA;AACxE,EAAM,MAAA,EAAE,KAAO,EAAA,IAAA,EAAS,GAAA,QAAA,CAAA;AACxB,EAAM,MAAA,YAAA,GAAe,mBAAmB,KAAK,CAAA,CAAA;AAC7C,EAAM,MAAA,WAAA,GAAc,mBAAmB,IAAI,CAAA,CAAA;AAC3C,EAAA,MAAM,EAAE,QAAU,EAAA,QAAA,EAAU,KAAO,EAAA,IAAA,EAAM,MAAS,GAAA,UAAA,CAAA;AAElD,EAAM,MAAA,GAAA,GAAM,GAAG,QAAQ,CAAA,GAAA,EAAM,QAAQ,CAAI,CAAA,EAAA,KAAK,IAAI,IAAI,CAAA,CAAA,CAAA;AACtD,EAAM,MAAA,UAAA,GAAa,UAAU,GAAG,CAAA,CAAA;AAChC,EAAA,IAAI,SAAS,QAAU,EAAA;AACrB,IAAA,OAAO,CAAG,EAAA,UAAU,CAAqB,kBAAA,EAAA,YAAY,SAAS,WAAW,CAAA,CAAA,CAAA;AAAA,GAC3E;AACA,EAAA,OAAO,CAAG,EAAA,UAAU,CAA4B,yBAAA,EAAA,YAAY,uBAAuB,WAAW,CAAA,CAAA,CAAA;AAChG,CAAA,CAAA;AAEO,MAAM,SAAY,GAAA,CAAC,EAAE,QAAA,EAAU,YAAiC,KAAA;AACrE,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAE1B,EAAM,MAAA,IAAA,GAAO,QAAQ,UAAU,CAAA,CAAA;AAC/B,EAAM,MAAA,GAAA,GAAM,MAAO,CAAA,UAAA,EAAY,QAAQ,CAAA,CAAA;AAEvC,EAAA,2CACG,IAAK,EAAA,EAAA,SAAA,EAAW,OAAQ,CAAA,IAAA,EAAM,IAAI,GAAK,EAAA,MAAA,EAAO,QAC7C,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,UAAK,CAAE,EAAA,YAAA,EAAW,OAAQ,CAAA,UAAU,GAAE,QACzC,CAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,84 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { makeStyles, Portal, Paper } from '@material-ui/core';
3
+ import { useGitRepository, useGitTemplate } from './hooks.esm.js';
4
+ import { PAGE_MAIN_CONTENT_SELECTOR, PAGE_FEEDBACK_LINK_SELECTOR, ADDON_FEEDBACK_CONTAINER_SELECTOR, ADDON_FEEDBACK_CONTAINER_ID } from './constants.esm.js';
5
+ import { IssueLink } from './IssueLink.esm.js';
6
+ import { useShadowRootSelection, useShadowRootElements } from '@backstage/plugin-techdocs-react';
7
+
8
+ const useStyles = makeStyles((theme) => ({
9
+ root: {
10
+ transform: "translate(-100%, -100%)",
11
+ position: "absolute",
12
+ padding: theme.spacing(1),
13
+ zIndex: theme.zIndex.tooltip,
14
+ background: theme.palette.common.white
15
+ }
16
+ }));
17
+ const ReportIssueAddon = ({
18
+ debounceTime = 500,
19
+ templateBuilder: buildTemplate
20
+ }) => {
21
+ const classes = useStyles();
22
+ const [style, setStyle] = useState();
23
+ const repository = useGitRepository();
24
+ const defaultTemplate = useGitTemplate(debounceTime);
25
+ const selection = useShadowRootSelection(debounceTime);
26
+ const [mainContent, feedbackLink] = useShadowRootElements([
27
+ PAGE_MAIN_CONTENT_SELECTOR,
28
+ PAGE_FEEDBACK_LINK_SELECTOR
29
+ ]);
30
+ let [feedbackContainer] = useShadowRootElements([
31
+ ADDON_FEEDBACK_CONTAINER_SELECTOR
32
+ ]);
33
+ if (feedbackLink) {
34
+ feedbackLink.style.display = "none";
35
+ }
36
+ useEffect(() => {
37
+ if (
38
+ // todo(backstage/techdocs-core) handle non-repo rendering
39
+ !repository || !selection || !selection.containsNode(mainContent, true) || (selection == null ? void 0 : selection.containsNode(feedbackContainer, true))
40
+ ) {
41
+ return;
42
+ }
43
+ const mainContentPosition = mainContent.getBoundingClientRect();
44
+ const selectionPosition = selection.getRangeAt(0).getBoundingClientRect();
45
+ const distanceFromTop = selectionPosition.top - mainContentPosition.top;
46
+ const minDistanceFromTop = 50;
47
+ let top = distanceFromTop < minDistanceFromTop ? 101 : distanceFromTop - 16;
48
+ if (mainContentPosition.top < 0) {
49
+ const absMainContentTop = Math.abs(mainContentPosition.top);
50
+ if (distanceFromTop - absMainContentTop < minDistanceFromTop) {
51
+ top += 89;
52
+ }
53
+ }
54
+ setStyle({
55
+ top: `${top}px`,
56
+ left: `${selectionPosition.left + selectionPosition.width / 2}px`
57
+ });
58
+ }, [selection, mainContent, feedbackContainer]);
59
+ if (!selection || !repository || !["github", "gitlab"].includes(repository.type))
60
+ return null;
61
+ if (!feedbackContainer) {
62
+ feedbackContainer = document.createElement("div");
63
+ feedbackContainer.setAttribute("id", ADDON_FEEDBACK_CONTAINER_ID);
64
+ mainContent.prepend(feedbackContainer);
65
+ }
66
+ return /* @__PURE__ */ React.createElement(Portal, { container: feedbackContainer }, /* @__PURE__ */ React.createElement(
67
+ Paper,
68
+ {
69
+ "data-testid": "report-issue-addon",
70
+ className: classes.root,
71
+ style
72
+ },
73
+ /* @__PURE__ */ React.createElement(
74
+ IssueLink,
75
+ {
76
+ repository,
77
+ template: buildTemplate ? buildTemplate({ selection }) : defaultTemplate
78
+ }
79
+ )
80
+ ));
81
+ };
82
+
83
+ export { ReportIssueAddon };
84
+ //# sourceMappingURL=ReportIssue.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReportIssue.esm.js","sources":["../../src/ReportIssue/ReportIssue.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useState, useEffect } from 'react';\n\nimport { makeStyles, Portal, Paper } from '@material-ui/core';\n\nimport { useGitTemplate, useGitRepository } from './hooks';\nimport { ReportIssueTemplateBuilder } from './types';\nimport {\n PAGE_MAIN_CONTENT_SELECTOR,\n PAGE_FEEDBACK_LINK_SELECTOR,\n ADDON_FEEDBACK_CONTAINER_ID,\n ADDON_FEEDBACK_CONTAINER_SELECTOR,\n} from './constants';\nimport { IssueLink } from './IssueLink';\n\nimport {\n useShadowRootElements,\n useShadowRootSelection,\n} from '@backstage/plugin-techdocs-react';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n transform: 'translate(-100%, -100%)',\n position: 'absolute',\n padding: theme.spacing(1),\n zIndex: theme.zIndex.tooltip,\n background: theme.palette.common.white,\n },\n}));\n\ntype Style = {\n top: string;\n left: string;\n};\n\n/**\n * Props customizing the <ReportIssue /> Addon.\n *\n * @public\n */\nexport type ReportIssueProps = {\n /**\n * Number of milliseconds after a user highlights some text before the report\n * issue link appears above the highlighted text. Defaults to 500ms.\n */\n debounceTime?: number;\n\n /**\n * An optional function defining how a custom issue title and body should be\n * constructed, given some selected text.\n */\n templateBuilder?: ReportIssueTemplateBuilder;\n};\n\n/**\n * Show report issue button when text is highlighted\n */\nexport const ReportIssueAddon = ({\n debounceTime = 500,\n templateBuilder: buildTemplate,\n}: ReportIssueProps) => {\n const classes = useStyles();\n const [style, setStyle] = useState<Style>();\n\n const repository = useGitRepository();\n\n const defaultTemplate = useGitTemplate(debounceTime);\n\n const selection = useShadowRootSelection(debounceTime);\n\n const [mainContent, feedbackLink] = useShadowRootElements([\n PAGE_MAIN_CONTENT_SELECTOR,\n PAGE_FEEDBACK_LINK_SELECTOR,\n ]);\n\n let [feedbackContainer] = useShadowRootElements([\n ADDON_FEEDBACK_CONTAINER_SELECTOR,\n ]);\n\n if (feedbackLink) {\n feedbackLink.style.display = 'none';\n }\n\n // calculates the position of the selected text to be able to set the position of the addon\n useEffect(() => {\n if (\n // todo(backstage/techdocs-core) handle non-repo rendering\n !repository ||\n !selection ||\n !selection.containsNode(mainContent!, true) ||\n selection?.containsNode(feedbackContainer!, true)\n ) {\n return;\n }\n\n const mainContentPosition = mainContent!.getBoundingClientRect();\n const selectionPosition = selection.getRangeAt(0).getBoundingClientRect();\n\n // Calculating the distance between the selection's top and the main content's top\n const distanceFromTop = selectionPosition.top - mainContentPosition.top;\n const minDistanceFromTop = 50;\n\n // Defining a base value for 'top'\n let top = distanceFromTop < minDistanceFromTop ? 101 : distanceFromTop - 16;\n\n // Checking if the main content is off-screen towards the top\n if (mainContentPosition.top < 0) {\n const absMainContentTop = Math.abs(mainContentPosition.top);\n\n // Adjusting 'top' if the selection is close to the top edge and the main content is off-screen\n if (distanceFromTop - absMainContentTop < minDistanceFromTop) {\n top += 89;\n }\n }\n\n setStyle({\n top: `${top}px`,\n left: `${selectionPosition.left + selectionPosition.width / 2}px`,\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selection, mainContent, feedbackContainer]);\n\n if (\n !selection ||\n !repository ||\n !['github', 'gitlab'].includes(repository.type)\n )\n return null;\n\n if (!feedbackContainer) {\n feedbackContainer = document.createElement('div');\n feedbackContainer.setAttribute('id', ADDON_FEEDBACK_CONTAINER_ID);\n mainContent!.prepend(feedbackContainer);\n }\n\n return (\n <Portal container={feedbackContainer}>\n <Paper\n data-testid=\"report-issue-addon\"\n className={classes.root}\n style={style}\n >\n <IssueLink\n repository={repository}\n template={\n buildTemplate ? buildTemplate({ selection }) : defaultTemplate\n }\n />\n </Paper>\n </Portal>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ const ADDON_FEEDBACK_CONTAINER_ID = "techdocs-report-issue";
2
+ const ADDON_FEEDBACK_CONTAINER_SELECTOR = `#${ADDON_FEEDBACK_CONTAINER_ID}`;
3
+ const PAGE_EDIT_LINK_SELECTOR = '[title^="Edit this page"]';
4
+ const PAGE_FEEDBACK_LINK_SELECTOR = '[title^="Leave feedback for"]';
5
+ const PAGE_MAIN_CONTENT_SELECTOR = '[data-md-component="main"] .md-content';
6
+
7
+ export { ADDON_FEEDBACK_CONTAINER_ID, ADDON_FEEDBACK_CONTAINER_SELECTOR, PAGE_EDIT_LINK_SELECTOR, PAGE_FEEDBACK_LINK_SELECTOR, PAGE_MAIN_CONTENT_SELECTOR };
8
+ //# sourceMappingURL=constants.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.esm.js","sources":["../../src/ReportIssue/constants.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const ADDON_FEEDBACK_CONTAINER_ID = 'techdocs-report-issue';\nexport const ADDON_FEEDBACK_CONTAINER_SELECTOR = `#${ADDON_FEEDBACK_CONTAINER_ID}`;\nexport const PAGE_EDIT_LINK_SELECTOR = '[title^=\"Edit this page\"]';\nexport const PAGE_FEEDBACK_LINK_SELECTOR = '[title^=\"Leave feedback for\"]';\nexport const PAGE_MAIN_CONTENT_SELECTOR =\n '[data-md-component=\"main\"] .md-content';\n"],"names":[],"mappings":"AAgBO,MAAM,2BAA8B,GAAA,wBAAA;AAC9B,MAAA,iCAAA,GAAoC,IAAI,2BAA2B,CAAA,EAAA;AACzE,MAAM,uBAA0B,GAAA,4BAAA;AAChC,MAAM,2BAA8B,GAAA,gCAAA;AACpC,MAAM,0BACX,GAAA;;;;"}
@@ -0,0 +1,79 @@
1
+ import parseGitUrl from 'git-url-parse';
2
+ import { useApi, configApiRef } from '@backstage/core-plugin-api';
3
+ import { replaceGithubUrlType, replaceGitLabUrlType } from '@backstage/integration';
4
+ import { scmIntegrationsApiRef } from '@backstage/integration-react';
5
+ import { useShadowRootSelection, useShadowRootElements } from '@backstage/plugin-techdocs-react';
6
+ import { PAGE_EDIT_LINK_SELECTOR } from './constants.esm.js';
7
+
8
+ const resolveBlobUrl = (url, type) => {
9
+ if (type === "github") {
10
+ return replaceGithubUrlType(url, "blob");
11
+ } else if (type === "gitlab") {
12
+ return replaceGitLabUrlType(url, "blob");
13
+ }
14
+ console.error(
15
+ `Invalid SCM type ${type} found in ReportIssue addon for URL ${url}!`
16
+ );
17
+ return url;
18
+ };
19
+ const getTitle = (selection) => {
20
+ const text = selection.toString().substring(0, 70);
21
+ const ellipsis = text.length === 70 ? "..." : "";
22
+ return `Documentation feedback: ${text}${ellipsis}`;
23
+ };
24
+ const getBody = (selection, markdownUrl, appTitle) => {
25
+ const title = "## Documentation Feedback \u{1F4DD}";
26
+ const subheading = "#### The highlighted text:";
27
+ const commentHeading = "#### The comment on the text:";
28
+ const commentPlaceholder = "_>replace this line with your comment<_";
29
+ const highlightedTextAsQuote = selection.toString().trim().split("\n").map((line) => `> ${line.trim()}`).join("\n");
30
+ const facts = [
31
+ `${appTitle} URL: <${window.location.href}>
32
+ Markdown URL: <${markdownUrl}>`
33
+ ];
34
+ return `${title}
35
+
36
+ ${subheading}
37
+
38
+ ${highlightedTextAsQuote}
39
+
40
+ ${commentHeading}
41
+ ${commentPlaceholder}
42
+
43
+ ___
44
+ ${facts}`;
45
+ };
46
+ const useGitTemplate = (debounceTime) => {
47
+ var _a, _b;
48
+ const initialTemplate = { title: "", body: "" };
49
+ const selection = useShadowRootSelection(debounceTime);
50
+ const [editLink] = useShadowRootElements([PAGE_EDIT_LINK_SELECTOR]);
51
+ const url = (_a = editLink == null ? void 0 : editLink.href) != null ? _a : "";
52
+ const scmIntegrationsApi = useApi(scmIntegrationsApiRef);
53
+ const configApi = useApi(configApiRef);
54
+ const appTitle = configApi.getOptionalString("app.title") || "Backstage";
55
+ if (!selection || !url)
56
+ return initialTemplate;
57
+ const type = (_b = scmIntegrationsApi.byUrl(url)) == null ? void 0 : _b.type;
58
+ if (!type)
59
+ return initialTemplate;
60
+ return {
61
+ title: getTitle(selection),
62
+ body: getBody(selection, resolveBlobUrl(url, type), appTitle)
63
+ };
64
+ };
65
+ const useGitRepository = () => {
66
+ var _a, _b;
67
+ const scmIntegrationsApi = useApi(scmIntegrationsApiRef);
68
+ const [editLink] = useShadowRootElements([PAGE_EDIT_LINK_SELECTOR]);
69
+ const url = (_a = editLink == null ? void 0 : editLink.href) != null ? _a : "";
70
+ if (!url)
71
+ return null;
72
+ const type = (_b = scmIntegrationsApi.byUrl(url)) == null ? void 0 : _b.type;
73
+ if (!type)
74
+ return null;
75
+ return { ...parseGitUrl(resolveBlobUrl(url, type)), type };
76
+ };
77
+
78
+ export { getBody, getTitle, useGitRepository, useGitTemplate };
79
+ //# sourceMappingURL=hooks.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.esm.js","sources":["../../src/ReportIssue/hooks.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport parseGitUrl from 'git-url-parse';\n\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport {\n replaceGithubUrlType,\n replaceGitLabUrlType,\n} from '@backstage/integration';\nimport { scmIntegrationsApiRef } from '@backstage/integration-react';\nimport {\n useShadowRootElements,\n useShadowRootSelection,\n} from '@backstage/plugin-techdocs-react';\n\nimport { PAGE_EDIT_LINK_SELECTOR } from './constants';\n\nconst resolveBlobUrl = (url: string, type: string) => {\n if (type === 'github') {\n return replaceGithubUrlType(url, 'blob');\n } else if (type === 'gitlab') {\n return replaceGitLabUrlType(url, 'blob');\n }\n // eslint-disable-next-line no-console\n console.error(\n `Invalid SCM type ${type} found in ReportIssue addon for URL ${url}!`,\n );\n return url;\n};\n\nexport const getTitle = (selection: Selection) => {\n const text = selection.toString().substring(0, 70);\n const ellipsis = text.length === 70 ? '...' : '';\n return `Documentation feedback: ${text}${ellipsis}`;\n};\n\nexport const getBody = (\n selection: Selection,\n markdownUrl: string,\n appTitle: string,\n) => {\n const title = '## Documentation Feedback 📝';\n const subheading = '#### The highlighted text:';\n const commentHeading = '#### The comment on the text:';\n const commentPlaceholder = '_>replace this line with your comment<_';\n const highlightedTextAsQuote = selection\n .toString()\n .trim()\n .split('\\n')\n .map(line => `> ${line.trim()}`)\n .join('\\n');\n\n const facts = [\n `${appTitle} URL: <${window.location.href}> \\nMarkdown URL: <${markdownUrl}>`,\n ];\n\n return `${title}\\n\\n ${subheading} \\n\\n ${highlightedTextAsQuote}\\n\\n ${commentHeading} \\n ${commentPlaceholder}\\n\\n ___\\n${facts}`;\n};\n\nexport const useGitTemplate = (debounceTime?: number) => {\n const initialTemplate = { title: '', body: '' };\n const selection = useShadowRootSelection(debounceTime);\n const [editLink] = useShadowRootElements([PAGE_EDIT_LINK_SELECTOR]);\n const url = (editLink as HTMLAnchorElement)?.href ?? '';\n const scmIntegrationsApi = useApi(scmIntegrationsApiRef);\n const configApi = useApi(configApiRef);\n const appTitle = configApi.getOptionalString('app.title') || 'Backstage';\n if (!selection || !url) return initialTemplate;\n\n const type = scmIntegrationsApi.byUrl(url)?.type;\n\n if (!type) return initialTemplate;\n\n return {\n title: getTitle(selection),\n body: getBody(selection, resolveBlobUrl(url, type), appTitle),\n };\n};\n\nexport const useGitRepository = () => {\n const scmIntegrationsApi = useApi(scmIntegrationsApiRef);\n\n const [editLink] = useShadowRootElements([PAGE_EDIT_LINK_SELECTOR]);\n const url = (editLink as HTMLAnchorElement)?.href ?? '';\n\n if (!url) return null;\n\n const type = scmIntegrationsApi.byUrl(url)?.type;\n\n if (!type) return null;\n\n return { ...parseGitUrl(resolveBlobUrl(url, type)), type };\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,188 @@
1
+ import React, { useState, useMemo, useCallback, useEffect } from 'react';
2
+ import { withStyles, Slider, makeStyles, useTheme, MenuItem, ListItemText, Typography, Box, IconButton } from '@material-ui/core';
3
+ import AddIcon from '@material-ui/icons/Add';
4
+ import RemoveIcon from '@material-ui/icons/Remove';
5
+ import { useShadowRootElements } from '@backstage/plugin-techdocs-react';
6
+
7
+ const boxShadow = "0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.13),0 0 0 1px rgba(0,0,0,0.02)";
8
+ const StyledSlider = withStyles((theme) => ({
9
+ root: {
10
+ height: 2,
11
+ padding: "15px 0"
12
+ },
13
+ thumb: {
14
+ height: 18,
15
+ width: 18,
16
+ backgroundColor: theme.palette.common.white,
17
+ boxShadow,
18
+ marginTop: -9,
19
+ marginLeft: -9,
20
+ "&:focus, &:hover, &$active": {
21
+ boxShadow: "0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)",
22
+ // Reset on touch devices, it doesn't add specificity
23
+ "@media (hover: none)": {
24
+ boxShadow
25
+ }
26
+ }
27
+ },
28
+ active: {},
29
+ valueLabel: {
30
+ top: "100%",
31
+ left: "50%",
32
+ transform: "scale(1) translate(-50%, -5px) !important",
33
+ "& *": {
34
+ color: theme.palette.textSubtle,
35
+ fontSize: theme.typography.caption.fontSize,
36
+ background: "transparent"
37
+ }
38
+ },
39
+ track: {
40
+ height: 2
41
+ },
42
+ rail: {
43
+ height: 2,
44
+ opacity: 0.5
45
+ },
46
+ mark: {
47
+ height: 10,
48
+ width: 1,
49
+ marginTop: -4
50
+ },
51
+ markActive: {
52
+ opacity: 1,
53
+ backgroundColor: "currentColor"
54
+ }
55
+ }))(Slider);
56
+ const settings = {
57
+ key: "techdocs.addons.settings.textsize",
58
+ defaultValue: 100
59
+ };
60
+ const marks = [
61
+ {
62
+ value: 90
63
+ },
64
+ {
65
+ value: 100
66
+ },
67
+ {
68
+ value: 115
69
+ },
70
+ {
71
+ value: 130
72
+ },
73
+ {
74
+ value: 150
75
+ }
76
+ ];
77
+ const useStyles = makeStyles((theme) => ({
78
+ container: {
79
+ color: theme.palette.textSubtle,
80
+ display: "flex",
81
+ alignItems: "center",
82
+ margin: 0,
83
+ minWidth: 200
84
+ },
85
+ menuItem: {
86
+ "&:hover": {
87
+ background: "transparent"
88
+ }
89
+ },
90
+ decreaseButton: {
91
+ marginRight: theme.spacing(1)
92
+ },
93
+ increaseButton: {
94
+ marginLeft: theme.spacing(1)
95
+ }
96
+ }));
97
+ const TextSizeAddon = () => {
98
+ const classes = useStyles();
99
+ const theme = useTheme();
100
+ const [body] = useShadowRootElements(["body"]);
101
+ const [value, setValue] = useState(() => {
102
+ const initialValue = localStorage == null ? void 0 : localStorage.getItem(settings.key);
103
+ return initialValue ? parseInt(initialValue, 10) : settings.defaultValue;
104
+ });
105
+ const values = useMemo(() => marks.map((mark) => mark.value), []);
106
+ const index = useMemo(() => values.indexOf(value), [values, value]);
107
+ const min = useMemo(() => values[0], [values]);
108
+ const max = useMemo(() => values[values.length - 1], [values]);
109
+ const getValueText = useCallback(() => `${value}%`, [value]);
110
+ const handleChangeCommitted = useCallback(
111
+ (_event, newValue) => {
112
+ if (!Array.isArray(newValue)) {
113
+ setValue(newValue);
114
+ localStorage == null ? void 0 : localStorage.setItem(settings.key, String(newValue));
115
+ }
116
+ },
117
+ [setValue]
118
+ );
119
+ const handleDecreaseClick = useCallback(
120
+ (event) => {
121
+ handleChangeCommitted(event, values[index - 1]);
122
+ },
123
+ [index, values, handleChangeCommitted]
124
+ );
125
+ const handleIncreaseClick = useCallback(
126
+ (event) => {
127
+ handleChangeCommitted(event, values[index + 1]);
128
+ },
129
+ [index, values, handleChangeCommitted]
130
+ );
131
+ useEffect(() => {
132
+ var _a, _b;
133
+ if (!body)
134
+ return;
135
+ const htmlFontSize = (_b = (_a = theme.typography) == null ? void 0 : _a.htmlFontSize) != null ? _b : 16;
136
+ body.style.setProperty(
137
+ "--md-typeset-font-size",
138
+ `${htmlFontSize * (value / 100)}px`
139
+ );
140
+ }, [body, value, theme]);
141
+ return /* @__PURE__ */ React.createElement(MenuItem, { className: classes.menuItem, button: true, disableRipple: true }, /* @__PURE__ */ React.createElement(
142
+ ListItemText,
143
+ {
144
+ primary: /* @__PURE__ */ React.createElement(Typography, { variant: "subtitle2", color: "textPrimary" }, "Text size"),
145
+ secondary: /* @__PURE__ */ React.createElement(Box, { className: classes.container }, /* @__PURE__ */ React.createElement(
146
+ IconButton,
147
+ {
148
+ className: classes.decreaseButton,
149
+ size: "small",
150
+ edge: "start",
151
+ disabled: value === min,
152
+ onClick: handleDecreaseClick,
153
+ "aria-label": "Decrease text size"
154
+ },
155
+ /* @__PURE__ */ React.createElement(RemoveIcon, null)
156
+ ), /* @__PURE__ */ React.createElement(
157
+ StyledSlider,
158
+ {
159
+ value,
160
+ "aria-labelledby": "text-size-slider",
161
+ getAriaValueText: getValueText,
162
+ valueLabelDisplay: "on",
163
+ valueLabelFormat: getValueText,
164
+ marks,
165
+ step: null,
166
+ min,
167
+ max,
168
+ onChangeCommitted: handleChangeCommitted
169
+ }
170
+ ), /* @__PURE__ */ React.createElement(
171
+ IconButton,
172
+ {
173
+ className: classes.increaseButton,
174
+ size: "small",
175
+ edge: "end",
176
+ disabled: value === max,
177
+ onClick: handleIncreaseClick,
178
+ "aria-label": "Increase text size"
179
+ },
180
+ /* @__PURE__ */ React.createElement(AddIcon, null)
181
+ )),
182
+ disableTypography: true
183
+ }
184
+ ));
185
+ };
186
+
187
+ export { TextSizeAddon };
188
+ //# sourceMappingURL=TextSize.esm.js.map