@grafana/ui
Version:
Grafana Components Library
143 lines (140 loc) • 3.99 kB
JavaScript
import { jsx, jsxs } from 'react/jsx-runtime';
import { css, cx } from '@emotion/css';
import { useState, useId } from 'react';
import { useStyles2 } from '../../themes/ThemeContext.mjs';
import { IconButton } from '../IconButton/IconButton.mjs';
"use strict";
const getStyles = (theme) => ({
collapse: css({
label: "collapse",
marginBottom: theme.spacing(1),
backgroundColor: theme.colors.background.primary,
border: `1px solid ${theme.colors.border.weak}`,
position: "relative",
borderRadius: theme.shape.radius.default,
width: "100%",
display: "flex",
flexDirection: "column",
flex: "1 1 0"
}),
collapseBody: css({
label: "collapse__body",
padding: theme.spacing(theme.components.panel.padding),
paddingTop: 0,
flex: 1,
overflow: "hidden",
display: "flex",
flexDirection: "column"
}),
bodyContentWrapper: css({
label: "bodyContentWrapper",
flex: 1
}),
loader: css({
label: "collapse__loader",
height: "2px",
position: "relative",
overflow: "hidden",
background: "none",
margin: theme.spacing(0.5)
}),
loaderActive: css({
label: "collapse__loader_active",
"&:after": {
content: "' '",
display: "block",
width: "25%",
top: 0,
height: "250%",
position: "absolute",
[theme.transitions.handleMotion("no-preference", "reduce")]: {
animation: "loader 2s cubic-bezier(0.17, 0.67, 0.83, 0.67) 500ms",
animationIterationCount: 100
},
[theme.transitions.handleMotion("reduce")]: {
animationDuration: "10s",
animationIterationCount: 20
},
left: "-25%",
background: theme.colors.primary.main
},
"@keyframes loader": {
from: {
left: "-25%",
opacity: 0.1
},
to: {
left: "100%",
opacity: 1
}
}
}),
header: css({
cursor: "pointer",
label: "collapse__header",
padding: theme.spacing(1),
display: "flex",
gap: theme.spacing(1)
}),
button: css({
marginRight: 0
}),
headerLabel: css({
label: "collapse__header-label",
fontWeight: theme.typography.fontWeightMedium,
fontSize: theme.typography.size.md,
display: "flex",
flex: 1
})
});
const ControlledCollapse = ({ isOpen, onToggle, ...otherProps }) => {
const [open, setOpen] = useState(isOpen);
return /* @__PURE__ */ jsx(
Collapse,
{
isOpen: open,
...otherProps,
onToggle: () => {
setOpen(!open);
if (onToggle) {
onToggle(!open);
}
}
}
);
};
const Collapse = ({ isOpen, label, loading, onToggle, className, children }) => {
const style = useStyles2(getStyles);
const labelId = useId();
const contentId = useId();
const onClickToggle = () => {
if (onToggle) {
onToggle(!isOpen);
}
};
const panelClass = cx([style.collapse, className]);
const loaderClass = loading ? cx([style.loader, style.loaderActive]) : style.loader;
return /* @__PURE__ */ jsxs("div", { className: panelClass, children: [
/* @__PURE__ */ jsxs("div", { className: style.header, onClick: onClickToggle, children: [
/* @__PURE__ */ jsx(
IconButton,
{
"aria-describedby": labelId,
"aria-expanded": isOpen,
"aria-controls": contentId,
className: style.button,
"aria-labelledby": labelId,
name: isOpen ? "angle-down" : "angle-right"
}
),
/* @__PURE__ */ jsx("div", { id: labelId, className: style.headerLabel, children: label })
] }),
isOpen && /* @__PURE__ */ jsxs("div", { className: style.collapseBody, id: contentId, children: [
/* @__PURE__ */ jsx("div", { className: loaderClass }),
/* @__PURE__ */ jsx("div", { className: style.bodyContentWrapper, children })
] })
] });
};
Collapse.displayName = "Collapse";
export { Collapse, ControlledCollapse };
//# sourceMappingURL=Collapse.mjs.map