@backstage/plugin-techdocs-module-addons-contrib
Version:
Plugin module for contributed TechDocs Addons
192 lines (189 loc) • 5.23 kB
JavaScript
import { jsx, jsxs } from 'react/jsx-runtime';
import { useState, useMemo, useCallback, useEffect } from 'react';
import { withStyles, Slider, makeStyles, useTheme, MenuItem, ListItemText, Typography, Box, IconButton } from '@material-ui/core';
import AddIcon from '@material-ui/icons/Add';
import RemoveIcon from '@material-ui/icons/Remove';
import { useShadowRootElements } from '@backstage/plugin-techdocs-react';
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)";
const StyledSlider = withStyles((theme) => ({
root: {
height: 2,
padding: "15px 0"
},
thumb: {
height: 18,
width: 18,
backgroundColor: theme.palette.common.white,
boxShadow,
marginTop: -9,
marginLeft: -9,
"&:focus, &:hover, &$active": {
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)",
// Reset on touch devices, it doesn't add specificity
"@media (hover: none)": {
boxShadow
}
}
},
active: {},
valueLabel: {
top: "100%",
left: "50%",
transform: "scale(1) translate(-50%, -5px) !important",
"& *": {
color: theme.palette.textSubtle,
fontSize: theme.typography.caption.fontSize,
background: "transparent"
}
},
track: {
height: 2
},
rail: {
height: 2,
opacity: 0.5
},
mark: {
height: 10,
width: 1,
marginTop: -4
},
markActive: {
opacity: 1,
backgroundColor: "currentColor"
}
}))(Slider);
const settings = {
key: "techdocs.addons.settings.textsize",
defaultValue: 100
};
const marks = [
{
value: 90
},
{
value: 100
},
{
value: 115
},
{
value: 130
},
{
value: 150
}
];
const useStyles = makeStyles((theme) => ({
container: {
color: theme.palette.textSubtle,
display: "flex",
alignItems: "center",
margin: 0,
minWidth: 200
},
menuItem: {
"&:hover": {
background: "transparent"
}
},
decreaseButton: {
marginRight: theme.spacing(1)
},
increaseButton: {
marginLeft: theme.spacing(1)
}
}));
const TextSizeAddon = () => {
const classes = useStyles();
const theme = useTheme();
const [body] = useShadowRootElements(["body"]);
const [value, setValue] = useState(() => {
const initialValue = localStorage?.getItem(settings.key);
return initialValue ? parseInt(initialValue, 10) : settings.defaultValue;
});
const values = useMemo(() => marks.map((mark) => mark.value), []);
const index = useMemo(() => values.indexOf(value), [values, value]);
const min = useMemo(() => values[0], [values]);
const max = useMemo(() => values[values.length - 1], [values]);
const getValueText = useCallback(() => `${value}%`, [value]);
const handleChangeCommitted = useCallback(
(_event, newValue) => {
if (!Array.isArray(newValue)) {
setValue(newValue);
localStorage?.setItem(settings.key, String(newValue));
}
},
[setValue]
);
const handleDecreaseClick = useCallback(
(event) => {
handleChangeCommitted(event, values[index - 1]);
},
[index, values, handleChangeCommitted]
);
const handleIncreaseClick = useCallback(
(event) => {
handleChangeCommitted(event, values[index + 1]);
},
[index, values, handleChangeCommitted]
);
useEffect(() => {
if (!body) return;
const htmlFontSize = theme.typography?.htmlFontSize ?? 16;
body.style.setProperty(
"--md-typeset-font-size",
`${htmlFontSize * (value / 100)}px`
);
}, [body, value, theme]);
return /* @__PURE__ */ jsx(MenuItem, { className: classes.menuItem, button: true, disableRipple: true, children: /* @__PURE__ */ jsx(
ListItemText,
{
primary: /* @__PURE__ */ jsx(Typography, { variant: "subtitle2", color: "textPrimary", children: "Text size" }),
secondary: /* @__PURE__ */ jsxs(Box, { className: classes.container, children: [
/* @__PURE__ */ jsx(
IconButton,
{
className: classes.decreaseButton,
size: "small",
edge: "start",
disabled: value === min,
onClick: handleDecreaseClick,
"aria-label": "Decrease text size",
children: /* @__PURE__ */ jsx(RemoveIcon, {})
}
),
/* @__PURE__ */ jsx(
StyledSlider,
{
value,
"aria-labelledby": "text-size-slider",
getAriaValueText: getValueText,
valueLabelDisplay: "on",
valueLabelFormat: getValueText,
marks,
step: null,
min,
max,
onChangeCommitted: handleChangeCommitted
}
),
/* @__PURE__ */ jsx(
IconButton,
{
className: classes.increaseButton,
size: "small",
edge: "end",
disabled: value === max,
onClick: handleIncreaseClick,
"aria-label": "Increase text size",
children: /* @__PURE__ */ jsx(AddIcon, {})
}
)
] }),
disableTypography: true
}
) });
};
export { TextSizeAddon };
//# sourceMappingURL=TextSize.esm.js.map