@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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextSize.esm.js","sources":["../../src/TextSize/TextSize.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, {\n ChangeEvent,\n MouseEvent,\n useMemo,\n useState,\n useEffect,\n useCallback,\n} from 'react';\n\nimport {\n withStyles,\n makeStyles,\n useTheme,\n Box,\n MenuItem,\n ListItemText,\n Slider,\n IconButton,\n Typography,\n Theme,\n} from '@material-ui/core';\nimport AddIcon from '@material-ui/icons/Add';\nimport RemoveIcon from '@material-ui/icons/Remove';\n\nimport { useShadowRootElements } from '@backstage/plugin-techdocs-react';\n\nconst boxShadow =\n '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)';\n\nconst StyledSlider = withStyles(theme => ({\n root: {\n height: 2,\n padding: '15px 0',\n },\n thumb: {\n height: 18,\n width: 18,\n backgroundColor: theme.palette.common.white,\n boxShadow: boxShadow,\n marginTop: -9,\n marginLeft: -9,\n '&:focus, &:hover, &$active': {\n boxShadow:\n '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)',\n // Reset on touch devices, it doesn't add specificity\n '@media (hover: none)': {\n boxShadow: boxShadow,\n },\n },\n },\n active: {},\n valueLabel: {\n top: '100%',\n left: '50%',\n transform: 'scale(1) translate(-50%, -5px) !important',\n '& *': {\n color: theme.palette.textSubtle,\n fontSize: theme.typography.caption.fontSize,\n background: 'transparent',\n },\n },\n track: {\n height: 2,\n },\n rail: {\n height: 2,\n opacity: 0.5,\n },\n mark: {\n height: 10,\n width: 1,\n marginTop: -4,\n },\n markActive: {\n opacity: 1,\n backgroundColor: 'currentColor',\n },\n}))(Slider);\n\nconst settings = {\n key: 'techdocs.addons.settings.textsize',\n defaultValue: 100,\n};\n\nconst marks = [\n {\n value: 90,\n },\n {\n value: 100,\n },\n {\n value: 115,\n },\n {\n value: 130,\n },\n {\n value: 150,\n },\n];\n\nconst useStyles = makeStyles(theme => ({\n container: {\n color: theme.palette.textSubtle,\n display: 'flex',\n alignItems: 'center',\n margin: 0,\n minWidth: 200,\n },\n menuItem: {\n '&:hover': {\n background: 'transparent',\n },\n },\n decreaseButton: {\n marginRight: theme.spacing(1),\n },\n increaseButton: {\n marginLeft: theme.spacing(1),\n },\n}));\n\nexport const TextSizeAddon = () => {\n const classes = useStyles();\n const theme = useTheme();\n const [body] = useShadowRootElements(['body']);\n\n const [value, setValue] = useState<number>(() => {\n const initialValue = localStorage?.getItem(settings.key);\n return initialValue ? parseInt(initialValue, 10) : settings.defaultValue;\n });\n\n const values = useMemo(() => marks.map(mark => mark.value), []);\n const index = useMemo(() => values.indexOf(value), [values, value]);\n const min = useMemo(() => values[0], [values]);\n const max = useMemo(() => values[values.length - 1], [values]);\n\n const getValueText = useCallback(() => `${value}%`, [value]);\n\n const handleChangeCommitted = useCallback(\n (_event: ChangeEvent<{}>, newValue: number | number[]) => {\n if (!Array.isArray(newValue)) {\n setValue(newValue);\n localStorage?.setItem(settings.key, String(newValue));\n }\n },\n [setValue],\n );\n\n const handleDecreaseClick = useCallback(\n (event: MouseEvent) => {\n handleChangeCommitted(event, values[index - 1]);\n },\n [index, values, handleChangeCommitted],\n );\n\n const handleIncreaseClick = useCallback(\n (event: MouseEvent) => {\n handleChangeCommitted(event, values[index + 1]);\n },\n [index, values, handleChangeCommitted],\n );\n\n useEffect(() => {\n if (!body) return;\n const htmlFontSize =\n (\n theme.typography as Theme['typography'] & {\n htmlFontSize?: number;\n }\n )?.htmlFontSize ?? 16;\n body.style.setProperty(\n '--md-typeset-font-size',\n `${htmlFontSize * (value / 100)}px`,\n );\n }, [body, value, theme]);\n\n return (\n <MenuItem className={classes.menuItem} button disableRipple>\n <ListItemText\n primary={\n <Typography variant=\"subtitle2\" color=\"textPrimary\">\n Text size\n </Typography>\n }\n secondary={\n <Box className={classes.container}>\n <IconButton\n className={classes.decreaseButton}\n size=\"small\"\n edge=\"start\"\n disabled={value === min}\n onClick={handleDecreaseClick}\n aria-label=\"Decrease text size\"\n >\n <RemoveIcon />\n </IconButton>\n <StyledSlider\n value={value}\n aria-labelledby=\"text-size-slider\"\n getAriaValueText={getValueText}\n valueLabelDisplay=\"on\"\n valueLabelFormat={getValueText}\n marks={marks}\n step={null}\n min={min}\n max={max}\n onChangeCommitted={handleChangeCommitted}\n />\n <IconButton\n className={classes.increaseButton}\n size=\"small\"\n edge=\"end\"\n disabled={value === max}\n onClick={handleIncreaseClick}\n aria-label=\"Increase text size\"\n >\n <AddIcon />\n </IconButton>\n </Box>\n }\n disableTypography\n />\n </MenuItem>\n );\n};\n"],"names":[],"mappings":"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"}
package/dist/index.esm.js CHANGED
@@ -1,549 +1,2 @@
1
- import { useApi, configApiRef, createPlugin } from '@backstage/core-plugin-api';
2
- import { useShadowRootElements, useShadowRootSelection, createTechDocsAddonExtension, TechDocsAddonLocations } from '@backstage/plugin-techdocs-react';
3
- import React, { useState, useCallback, useEffect, useMemo } from 'react';
4
- import { useLocalStorageValue } from '@react-hookz/web';
5
- import { withStyles, Button, makeStyles, Portal, Paper, Slider, useTheme, MenuItem, ListItemText, Typography, Box, IconButton } from '@material-ui/core';
6
- import ChevronRightIcon from '@material-ui/icons/ChevronRight';
7
- import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
8
- import parseGitUrl from 'git-url-parse';
9
- import { replaceGithubUrlType, replaceGitLabUrlType } from '@backstage/integration';
10
- import { scmIntegrationsApiRef } from '@backstage/integration-react';
11
- import BugReportIcon from '@material-ui/icons/BugReport';
12
- import { Link, GitHubIcon } from '@backstage/core-components';
13
- import AddIcon from '@material-ui/icons/Add';
14
- import RemoveIcon from '@material-ui/icons/Remove';
15
- import PhotoSwipeLightbox from 'photoswipe/lightbox';
16
- import PhotoSwipe from 'photoswipe';
17
- import 'photoswipe/style.css';
18
-
19
- const NESTED_LIST_TOGGLE = ".md-nav__item--nested .md-toggle";
20
- const EXPANDABLE_NAVIGATION_LOCAL_STORAGE = "@backstage/techdocs-addons/nav-expanded";
21
- const StyledButton = withStyles({
22
- root: {
23
- position: "absolute",
24
- left: "220px",
25
- top: "19px",
26
- padding: 0,
27
- minWidth: 0
28
- }
29
- })(Button);
30
- const CollapsedIcon = withStyles({
31
- root: {
32
- height: "20px",
33
- width: "20px"
34
- }
35
- })(ChevronRightIcon);
36
- const ExpandedIcon = withStyles({
37
- root: {
38
- height: "20px",
39
- width: "20px"
40
- }
41
- })(ExpandMoreIcon);
42
- const ExpandableNavigationAddon = () => {
43
- const defaultValue = { expandAllNestedNavs: false };
44
- const { value: expanded, set: setExpanded } = useLocalStorageValue(
45
- EXPANDABLE_NAVIGATION_LOCAL_STORAGE,
46
- { defaultValue }
47
- );
48
- const [hasNavSubLevels, setHasNavSubLevels] = useState(false);
49
- const [...checkboxToggles] = useShadowRootElements([
50
- NESTED_LIST_TOGGLE
51
- ]);
52
- const shouldToggle = useCallback(
53
- (item) => {
54
- const isExpanded = item.checked;
55
- const shouldExpand = expanded == null ? void 0 : expanded.expandAllNestedNavs;
56
- if (shouldExpand && !isExpanded) {
57
- return true;
58
- }
59
- if (!shouldExpand && isExpanded) {
60
- return true;
61
- }
62
- return false;
63
- },
64
- [expanded]
65
- );
66
- useEffect(() => {
67
- if (!(checkboxToggles == null ? void 0 : checkboxToggles.length))
68
- return;
69
- setHasNavSubLevels(true);
70
- checkboxToggles.forEach((item) => {
71
- if (shouldToggle(item))
72
- item.click();
73
- });
74
- }, [expanded, shouldToggle, checkboxToggles]);
75
- const handleState = () => {
76
- setExpanded((prevState) => ({
77
- expandAllNestedNavs: !(prevState == null ? void 0 : prevState.expandAllNestedNavs)
78
- }));
79
- };
80
- return /* @__PURE__ */ React.createElement(React.Fragment, null, hasNavSubLevels ? /* @__PURE__ */ React.createElement(
81
- StyledButton,
82
- {
83
- size: "small",
84
- onClick: handleState,
85
- "aria-label": (expanded == null ? void 0 : expanded.expandAllNestedNavs) ? "collapse-nav" : "expand-nav"
86
- },
87
- (expanded == null ? void 0 : expanded.expandAllNestedNavs) ? /* @__PURE__ */ React.createElement(ExpandedIcon, null) : /* @__PURE__ */ React.createElement(CollapsedIcon, null)
88
- ) : null);
89
- };
90
-
91
- const ADDON_FEEDBACK_CONTAINER_ID = "techdocs-report-issue";
92
- const ADDON_FEEDBACK_CONTAINER_SELECTOR = `#${ADDON_FEEDBACK_CONTAINER_ID}`;
93
- const PAGE_EDIT_LINK_SELECTOR = '[title^="Edit this page"]';
94
- const PAGE_FEEDBACK_LINK_SELECTOR = '[title^="Leave feedback for"]';
95
- const PAGE_MAIN_CONTENT_SELECTOR = '[data-md-component="main"] .md-content';
96
-
97
- const resolveBlobUrl = (url, type) => {
98
- if (type === "github") {
99
- return replaceGithubUrlType(url, "blob");
100
- } else if (type === "gitlab") {
101
- return replaceGitLabUrlType(url, "blob");
102
- }
103
- console.error(
104
- `Invalid SCM type ${type} found in ReportIssue addon for URL ${url}!`
105
- );
106
- return url;
107
- };
108
- const getTitle = (selection) => {
109
- const text = selection.toString().substring(0, 70);
110
- const ellipsis = text.length === 70 ? "..." : "";
111
- return `Documentation feedback: ${text}${ellipsis}`;
112
- };
113
- const getBody = (selection, markdownUrl, appTitle) => {
114
- const title = "## Documentation Feedback \u{1F4DD}";
115
- const subheading = "#### The highlighted text:";
116
- const commentHeading = "#### The comment on the text:";
117
- const commentPlaceholder = "_>replace this line with your comment<_";
118
- const highlightedTextAsQuote = selection.toString().trim().split("\n").map((line) => `> ${line.trim()}`).join("\n");
119
- const facts = [
120
- `${appTitle} URL: <${window.location.href}>
121
- Markdown URL: <${markdownUrl}>`
122
- ];
123
- return `${title}
124
-
125
- ${subheading}
126
-
127
- ${highlightedTextAsQuote}
128
-
129
- ${commentHeading}
130
- ${commentPlaceholder}
131
-
132
- ___
133
- ${facts}`;
134
- };
135
- const useGitTemplate = (debounceTime) => {
136
- var _a, _b;
137
- const initialTemplate = { title: "", body: "" };
138
- const selection = useShadowRootSelection(debounceTime);
139
- const [editLink] = useShadowRootElements([PAGE_EDIT_LINK_SELECTOR]);
140
- const url = (_a = editLink == null ? void 0 : editLink.href) != null ? _a : "";
141
- const scmIntegrationsApi = useApi(scmIntegrationsApiRef);
142
- const configApi = useApi(configApiRef);
143
- const appTitle = configApi.getOptionalString("app.title") || "Backstage";
144
- if (!selection || !url)
145
- return initialTemplate;
146
- const type = (_b = scmIntegrationsApi.byUrl(url)) == null ? void 0 : _b.type;
147
- if (!type)
148
- return initialTemplate;
149
- return {
150
- title: getTitle(selection),
151
- body: getBody(selection, resolveBlobUrl(url, type), appTitle)
152
- };
153
- };
154
- const useGitRepository = () => {
155
- var _a, _b;
156
- const scmIntegrationsApi = useApi(scmIntegrationsApiRef);
157
- const [editLink] = useShadowRootElements([PAGE_EDIT_LINK_SELECTOR]);
158
- const url = (_a = editLink == null ? void 0 : editLink.href) != null ? _a : "";
159
- if (!url)
160
- return null;
161
- const type = (_b = scmIntegrationsApi.byUrl(url)) == null ? void 0 : _b.type;
162
- if (!type)
163
- return null;
164
- return { ...parseGitUrl(resolveBlobUrl(url, type)), type };
165
- };
166
-
167
- const useStyles$2 = makeStyles((theme) => ({
168
- root: {
169
- display: "grid",
170
- gridGap: theme.spacing(1),
171
- gridAutoFlow: "column",
172
- justifyContent: "center",
173
- alignItems: "center",
174
- color: theme.palette.common.black,
175
- fontSize: theme.typography.button.fontSize
176
- }
177
- }));
178
- const getIcon = ({ type }) => {
179
- if (type === "github") {
180
- return GitHubIcon;
181
- }
182
- return BugReportIcon;
183
- };
184
- const getName = ({ type }) => {
185
- if (type === "github") {
186
- return "Github";
187
- }
188
- return "Gitlab";
189
- };
190
- const getUrl = (repository, template) => {
191
- const { title, body } = template;
192
- const encodedTitle = encodeURIComponent(title);
193
- const encodedBody = encodeURIComponent(body);
194
- const { protocol, resource, owner, name, type } = repository;
195
- const url = `${protocol}://${resource}/${owner}/${name}`;
196
- const encodedUrl = encodeURI(url);
197
- if (type === "github") {
198
- return `${encodedUrl}/issues/new?title=${encodedTitle}&body=${encodedBody}`;
199
- }
200
- return `${encodedUrl}/issues/new?issue[title]=${encodedTitle}&issue[description]=${encodedBody}`;
201
- };
202
- const IssueLink = ({ template, repository }) => {
203
- const classes = useStyles$2();
204
- const Icon = getIcon(repository);
205
- const url = getUrl(repository, template);
206
- return /* @__PURE__ */ React.createElement(Link, { className: classes.root, to: url, target: "_blank" }, /* @__PURE__ */ React.createElement(Icon, null), " Open new ", getName(repository), " issue");
207
- };
208
-
209
- const useStyles$1 = makeStyles((theme) => ({
210
- root: {
211
- transform: "translate(-100%, -100%)",
212
- position: "absolute",
213
- padding: theme.spacing(1),
214
- zIndex: theme.zIndex.tooltip,
215
- background: theme.palette.common.white
216
- }
217
- }));
218
- const ReportIssueAddon = ({
219
- debounceTime = 500,
220
- templateBuilder: buildTemplate
221
- }) => {
222
- const classes = useStyles$1();
223
- const [style, setStyle] = useState();
224
- const repository = useGitRepository();
225
- const defaultTemplate = useGitTemplate(debounceTime);
226
- const selection = useShadowRootSelection(debounceTime);
227
- const [mainContent, feedbackLink] = useShadowRootElements([
228
- PAGE_MAIN_CONTENT_SELECTOR,
229
- PAGE_FEEDBACK_LINK_SELECTOR
230
- ]);
231
- let [feedbackContainer] = useShadowRootElements([
232
- ADDON_FEEDBACK_CONTAINER_SELECTOR
233
- ]);
234
- if (feedbackLink) {
235
- feedbackLink.style.display = "none";
236
- }
237
- useEffect(() => {
238
- if (
239
- // todo(backstage/techdocs-core) handle non-repo rendering
240
- !repository || !selection || !selection.containsNode(mainContent, true) || (selection == null ? void 0 : selection.containsNode(feedbackContainer, true))
241
- ) {
242
- return;
243
- }
244
- const mainContentPosition = mainContent.getBoundingClientRect();
245
- const selectionPosition = selection.getRangeAt(0).getBoundingClientRect();
246
- const distanceFromTop = selectionPosition.top - mainContentPosition.top;
247
- const minDistanceFromTop = 50;
248
- let top = distanceFromTop < minDistanceFromTop ? 101 : distanceFromTop - 16;
249
- if (mainContentPosition.top < 0) {
250
- const absMainContentTop = Math.abs(mainContentPosition.top);
251
- if (distanceFromTop - absMainContentTop < minDistanceFromTop) {
252
- top += 89;
253
- }
254
- }
255
- setStyle({
256
- top: `${top}px`,
257
- left: `${selectionPosition.left + selectionPosition.width / 2}px`
258
- });
259
- }, [selection, mainContent, feedbackContainer]);
260
- if (!selection || !repository || !["github", "gitlab"].includes(repository.type))
261
- return null;
262
- if (!feedbackContainer) {
263
- feedbackContainer = document.createElement("div");
264
- feedbackContainer.setAttribute("id", ADDON_FEEDBACK_CONTAINER_ID);
265
- mainContent.prepend(feedbackContainer);
266
- }
267
- return /* @__PURE__ */ React.createElement(Portal, { container: feedbackContainer }, /* @__PURE__ */ React.createElement(
268
- Paper,
269
- {
270
- "data-testid": "report-issue-addon",
271
- className: classes.root,
272
- style
273
- },
274
- /* @__PURE__ */ React.createElement(
275
- IssueLink,
276
- {
277
- repository,
278
- template: buildTemplate ? buildTemplate({ selection }) : defaultTemplate
279
- }
280
- )
281
- ));
282
- };
283
-
284
- 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)";
285
- const StyledSlider = withStyles((theme) => ({
286
- root: {
287
- height: 2,
288
- padding: "15px 0"
289
- },
290
- thumb: {
291
- height: 18,
292
- width: 18,
293
- backgroundColor: theme.palette.common.white,
294
- boxShadow,
295
- marginTop: -9,
296
- marginLeft: -9,
297
- "&:focus, &:hover, &$active": {
298
- 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)",
299
- // Reset on touch devices, it doesn't add specificity
300
- "@media (hover: none)": {
301
- boxShadow
302
- }
303
- }
304
- },
305
- active: {},
306
- valueLabel: {
307
- top: "100%",
308
- left: "50%",
309
- transform: "scale(1) translate(-50%, -5px) !important",
310
- "& *": {
311
- color: theme.palette.textSubtle,
312
- fontSize: theme.typography.caption.fontSize,
313
- background: "transparent"
314
- }
315
- },
316
- track: {
317
- height: 2
318
- },
319
- rail: {
320
- height: 2,
321
- opacity: 0.5
322
- },
323
- mark: {
324
- height: 10,
325
- width: 1,
326
- marginTop: -4
327
- },
328
- markActive: {
329
- opacity: 1,
330
- backgroundColor: "currentColor"
331
- }
332
- }))(Slider);
333
- const settings = {
334
- key: "techdocs.addons.settings.textsize",
335
- defaultValue: 100
336
- };
337
- const marks = [
338
- {
339
- value: 90
340
- },
341
- {
342
- value: 100
343
- },
344
- {
345
- value: 115
346
- },
347
- {
348
- value: 130
349
- },
350
- {
351
- value: 150
352
- }
353
- ];
354
- const useStyles = makeStyles((theme) => ({
355
- container: {
356
- color: theme.palette.textSubtle,
357
- display: "flex",
358
- alignItems: "center",
359
- margin: 0,
360
- minWidth: 200
361
- },
362
- menuItem: {
363
- "&:hover": {
364
- background: "transparent"
365
- }
366
- },
367
- decreaseButton: {
368
- marginRight: theme.spacing(1)
369
- },
370
- increaseButton: {
371
- marginLeft: theme.spacing(1)
372
- }
373
- }));
374
- const TextSizeAddon = () => {
375
- const classes = useStyles();
376
- const theme = useTheme();
377
- const [body] = useShadowRootElements(["body"]);
378
- const [value, setValue] = useState(() => {
379
- const initialValue = localStorage == null ? void 0 : localStorage.getItem(settings.key);
380
- return initialValue ? parseInt(initialValue, 10) : settings.defaultValue;
381
- });
382
- const values = useMemo(() => marks.map((mark) => mark.value), []);
383
- const index = useMemo(() => values.indexOf(value), [values, value]);
384
- const min = useMemo(() => values[0], [values]);
385
- const max = useMemo(() => values[values.length - 1], [values]);
386
- const getValueText = useCallback(() => `${value}%`, [value]);
387
- const handleChangeCommitted = useCallback(
388
- (_event, newValue) => {
389
- if (!Array.isArray(newValue)) {
390
- setValue(newValue);
391
- localStorage == null ? void 0 : localStorage.setItem(settings.key, String(newValue));
392
- }
393
- },
394
- [setValue]
395
- );
396
- const handleDecreaseClick = useCallback(
397
- (event) => {
398
- handleChangeCommitted(event, values[index - 1]);
399
- },
400
- [index, values, handleChangeCommitted]
401
- );
402
- const handleIncreaseClick = useCallback(
403
- (event) => {
404
- handleChangeCommitted(event, values[index + 1]);
405
- },
406
- [index, values, handleChangeCommitted]
407
- );
408
- useEffect(() => {
409
- var _a, _b;
410
- if (!body)
411
- return;
412
- const htmlFontSize = (_b = (_a = theme.typography) == null ? void 0 : _a.htmlFontSize) != null ? _b : 16;
413
- body.style.setProperty(
414
- "--md-typeset-font-size",
415
- `${htmlFontSize * (value / 100)}px`
416
- );
417
- }, [body, value, theme]);
418
- return /* @__PURE__ */ React.createElement(MenuItem, { className: classes.menuItem, button: true, disableRipple: true }, /* @__PURE__ */ React.createElement(
419
- ListItemText,
420
- {
421
- primary: /* @__PURE__ */ React.createElement(Typography, { variant: "subtitle2", color: "textPrimary" }, "Text size"),
422
- secondary: /* @__PURE__ */ React.createElement(Box, { className: classes.container }, /* @__PURE__ */ React.createElement(
423
- IconButton,
424
- {
425
- className: classes.decreaseButton,
426
- size: "small",
427
- edge: "start",
428
- disabled: value === min,
429
- onClick: handleDecreaseClick,
430
- "aria-label": "Decrease text size"
431
- },
432
- /* @__PURE__ */ React.createElement(RemoveIcon, null)
433
- ), /* @__PURE__ */ React.createElement(
434
- StyledSlider,
435
- {
436
- value,
437
- "aria-labelledby": "text-size-slider",
438
- getAriaValueText: getValueText,
439
- valueLabelDisplay: "on",
440
- valueLabelFormat: getValueText,
441
- marks,
442
- step: null,
443
- min,
444
- max,
445
- onChangeCommitted: handleChangeCommitted
446
- }
447
- ), /* @__PURE__ */ React.createElement(
448
- IconButton,
449
- {
450
- className: classes.increaseButton,
451
- size: "small",
452
- edge: "end",
453
- disabled: value === max,
454
- onClick: handleIncreaseClick,
455
- "aria-label": "Increase text size"
456
- },
457
- /* @__PURE__ */ React.createElement(AddIcon, null)
458
- )),
459
- disableTypography: true
460
- }
461
- ));
462
- };
463
-
464
- const LightBoxAddon = () => {
465
- const images = useShadowRootElements(["img"]);
466
- useEffect(() => {
467
- let dataSourceImages = null;
468
- let lightbox = new PhotoSwipeLightbox({
469
- pswpModule: PhotoSwipe,
470
- initialZoomLevel: 1,
471
- secondaryZoomLevel: (zoomLevelObject) => {
472
- const imageWidth = zoomLevelObject.elementSize.x;
473
- const imageHeight = zoomLevelObject.elementSize.y;
474
- const viewportWidth = zoomLevelObject.panAreaSize.x;
475
- const viewportHeight = zoomLevelObject.panAreaSize.y;
476
- const widthScale = viewportWidth / imageWidth;
477
- const heightScale = viewportHeight / imageHeight;
478
- const scaleFactor = Math.min(widthScale, heightScale);
479
- return scaleFactor;
480
- },
481
- wheelToZoom: true,
482
- 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>',
483
- 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>',
484
- 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>',
485
- 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">
486
- <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">
487
- </svg>`
488
- });
489
- images.forEach((image, index) => {
490
- image.onclick = () => {
491
- if (dataSourceImages === null) {
492
- dataSourceImages = images.map((dataSourceImage) => {
493
- return {
494
- element: dataSourceImage,
495
- src: dataSourceImage.src,
496
- msrc: dataSourceImage.src,
497
- alt: dataSourceImage.alt,
498
- width: dataSourceImage.clientWidth,
499
- height: dataSourceImage.clientHeight
500
- };
501
- });
502
- }
503
- lightbox.loadAndOpen(index, dataSourceImages);
504
- return false;
505
- };
506
- });
507
- lightbox.init();
508
- return () => {
509
- lightbox.destroy();
510
- lightbox = null;
511
- };
512
- }, [images]);
513
- return null;
514
- };
515
-
516
- const techdocsModuleAddonsContribPlugin = createPlugin({
517
- id: "techdocsModuleAddonsContrib"
518
- });
519
- const ExpandableNavigation = techdocsModuleAddonsContribPlugin.provide(
520
- createTechDocsAddonExtension({
521
- name: "ExpandableNavigation",
522
- location: TechDocsAddonLocations.PrimarySidebar,
523
- component: ExpandableNavigationAddon
524
- })
525
- );
526
- const ReportIssue = techdocsModuleAddonsContribPlugin.provide(
527
- createTechDocsAddonExtension({
528
- name: "ReportIssue",
529
- location: TechDocsAddonLocations.Content,
530
- component: ReportIssueAddon
531
- })
532
- );
533
- const TextSize = techdocsModuleAddonsContribPlugin.provide(
534
- createTechDocsAddonExtension({
535
- name: "TextSize",
536
- location: TechDocsAddonLocations.Settings,
537
- component: TextSizeAddon
538
- })
539
- );
540
- const LightBox = techdocsModuleAddonsContribPlugin.provide(
541
- createTechDocsAddonExtension({
542
- name: "LightBox",
543
- location: TechDocsAddonLocations.Content,
544
- component: LightBoxAddon
545
- })
546
- );
547
-
548
- export { ExpandableNavigation, LightBox, ReportIssue, TextSize, techdocsModuleAddonsContribPlugin };
1
+ export { ExpandableNavigation, LightBox, ReportIssue, TextSize, techdocsModuleAddonsContribPlugin } from './plugin.esm.js';
549
2
  //# sourceMappingURL=index.esm.js.map