@grafana/ui
Version:
Grafana Components Library
363 lines (356 loc) • 10.9 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var jsxRuntime = require('react/jsx-runtime');
var css = require('@emotion/css');
var React = require('react');
var data = require('@grafana/data');
var ThemeContext = require('../../themes/ThemeContext.cjs');
var mixins = require('../../themes/mixins.cjs');
var commonStyles = require('../Forms/commonStyles.cjs');
var Icon = require('../Icon/Icon.cjs');
var Tooltip = require('../Tooltip/Tooltip.cjs');
function _interopNamespaceCompat(e) {
if (e && typeof e === 'object' && 'default' in e) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceCompat(React);
"use strict";
const allButtonVariants = ["primary", "secondary", "accent", "destructive", "success"];
const allButtonFills = ["solid", "outline", "text"];
const Button = React__namespace.forwardRef(
({
"aria-label": ariaLabel,
size = "md",
fill = "solid",
variant = fill === "text" ? "accent" : "primary",
icon,
fullWidth,
children,
className,
type = "button",
tooltip,
disabled,
tooltipPlacement,
iconPlacement = "left",
onClick,
...otherProps
}, ref) => {
const theme = ThemeContext.useTheme2();
const styles = getButtonStyles({
theme,
size,
variant,
fill,
fullWidth,
iconOnly: !children
});
const buttonStyles = css.cx(
styles.button,
{
[styles.disabled]: disabled
},
className
);
const hasTooltip = Boolean(tooltip);
const iconComponent = icon && /* @__PURE__ */ jsxRuntime.jsx(IconRenderer, { icon, size, className: styles.icon });
const button = /* @__PURE__ */ jsxRuntime.jsxs(
"button",
{
className: buttonStyles,
type,
onClick: disabled ? void 0 : onClick,
...otherProps,
"aria-disabled": hasTooltip && disabled,
disabled: !hasTooltip && disabled,
ref: tooltip ? void 0 : ref,
"aria-label": ariaLabel != null ? ariaLabel : !children && typeof tooltip === "string" ? tooltip : void 0,
children: [
iconPlacement === "left" && iconComponent,
children && /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles.content, children }),
iconPlacement === "right" && iconComponent
]
}
);
if (tooltip) {
return /* @__PURE__ */ jsxRuntime.jsx(Tooltip.Tooltip, { ref, content: tooltip, placement: tooltipPlacement, children: button });
}
return button;
}
);
Button.displayName = "Button";
const LinkButton = React__namespace.forwardRef(
({
"aria-label": ariaLabel,
variant = "primary",
size = "md",
fill = "solid",
icon,
iconPlacement = "left",
fullWidth,
children,
className,
onBlur,
onFocus,
disabled,
tooltip,
tooltipPlacement,
href,
...otherProps
}, ref) => {
const sanitizedHref = href ? data.textUtil.sanitizeUrl(href) : href;
const theme = ThemeContext.useTheme2();
const styles = getButtonStyles({
theme,
fullWidth,
size,
variant,
fill,
iconOnly: !children
});
const linkButtonStyles = css.cx(
styles.button,
{
[css.css(styles.disabled, {
pointerEvents: "none"
})]: disabled
},
className
);
const iconComponent = icon && /* @__PURE__ */ jsxRuntime.jsx(IconRenderer, { icon, size, className: styles.icon });
const button = /* @__PURE__ */ jsxRuntime.jsxs(
"a",
{
className: linkButtonStyles,
...otherProps,
href: sanitizedHref,
tabIndex: disabled ? -1 : 0,
"aria-disabled": disabled,
ref: tooltip ? void 0 : ref,
"aria-label": ariaLabel != null ? ariaLabel : !children && typeof tooltip === "string" ? tooltip : void 0,
children: [
iconPlacement === "left" && iconComponent,
children && /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles.content, children }),
iconPlacement === "right" && iconComponent
]
}
);
if (tooltip) {
return /* @__PURE__ */ jsxRuntime.jsx(Tooltip.Tooltip, { ref, content: tooltip, placement: tooltipPlacement, children: button });
}
return button;
}
);
LinkButton.displayName = "LinkButton";
const IconRenderer = ({ icon, size, className, iconType }) => {
if (!icon) {
return null;
}
if (React__namespace.isValidElement(icon)) {
return React__namespace.cloneElement(icon, {
className,
size
});
}
return /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { name: icon, size, className, type: iconType });
};
const getButtonStyles = (props) => {
const { theme, variant, fill = "solid", size, iconOnly, fullWidth } = props;
const { height, padding, fontSize } = commonStyles.getPropertiesForButtonSize(size, theme);
const variantStyles = getPropertiesForVariant(theme, variant, fill);
const disabledStyles = getPropertiesForDisabled(theme, variant, fill);
const focusStyle = mixins.getButtonFocusStyles(theme);
const paddingMinusBorder = theme.spacing.gridSize * padding - 1;
return {
button: css.css({
label: "button",
display: "inline-flex",
alignItems: "center",
gap: theme.spacing(1),
fontSize,
fontWeight: theme.typography.fontWeightMedium,
fontFamily: theme.typography.fontFamily,
padding: `0 ${paddingMinusBorder}px`,
height: theme.spacing(height),
// Deduct border from line-height for perfect vertical centering on windows and linux
lineHeight: `${theme.spacing.gridSize * height - 2}px`,
verticalAlign: "middle",
cursor: "pointer",
borderRadius: theme.shape.radius.default,
"&:focus": focusStyle,
"&:focus-visible": focusStyle,
"&:focus:not(:focus-visible)": mixins.getMouseFocusStyles(theme),
...fullWidth && {
flexGrow: 1,
justifyContent: "center"
},
...variantStyles,
":disabled": disabledStyles,
"&[disabled]": disabledStyles,
[theme.transitions.handleMotion("no-preference", "reduce")]: {
transition: theme.transitions.create(["background-color", "border-color", "color"], {
duration: theme.transitions.duration.short
})
}
}),
disabled: css.css(disabledStyles, {
"&:hover": css.css(disabledStyles),
"&:focus": css.css(disabledStyles),
"&:focus-visible": css.css(disabledStyles)
}),
img: css.css({
width: "16px",
height: "16px",
margin: theme.spacing(0, 1, 0, 0.5)
}),
icon: iconOnly ? css.css({
// Important not to set margin bottom here as it would override internal icon bottom margin
marginRight: theme.spacing(-padding / 2),
marginLeft: theme.spacing(-padding / 2)
}) : void 0,
content: css.css({
display: "flex",
flexDirection: "row",
alignItems: "center",
whiteSpace: "nowrap",
overflow: "hidden",
height: "100%"
})
};
};
function getActiveButtonStyles(color, fill) {
return {
background: fill === "solid" ? color.main : "transparent"
};
}
function getButtonVariantStyles(theme, color, fill) {
let outlineBorderColor = color.border;
let borderColor = "transparent";
let hoverBorderColor = "transparent";
if (color.name === "secondary") {
borderColor = color.border;
hoverBorderColor = theme.colors.emphasize(color.border, 0.25);
outlineBorderColor = theme.colors.border.strong;
}
if (fill === "outline") {
return {
background: "transparent",
color: color.text,
border: `1px solid ${outlineBorderColor}`,
"&:hover, &:focus": {
background: color.transparent,
borderColor: theme.colors.emphasize(outlineBorderColor, 0.25),
color: color.text
},
"&:active": {
...getActiveButtonStyles(color, fill)
}
};
}
if (fill === "text") {
return {
background: "transparent",
color: color.text,
border: "1px solid transparent",
"&:hover, &:focus": {
background: color.transparent,
textDecoration: "none",
outline: "none"
},
"&:active": {
...getActiveButtonStyles(color, fill)
}
};
}
return {
background: color.main,
color: color.contrastText,
border: `1px solid ${borderColor}`,
"&:hover": {
background: color.shade,
color: color.contrastText,
boxShadow: theme.shadows.z1,
borderColor: hoverBorderColor
},
"&:focus": {
background: color.shade,
color: color.contrastText
},
"&:active": {
...getActiveButtonStyles(color, fill)
}
};
}
function getPropertiesForDisabled(theme, variant, fill) {
const disabledStyles = {
cursor: "not-allowed",
boxShadow: "none",
color: theme.colors.text.disabled,
transition: "none",
background: theme.colors.action.disabledBackground
};
if (fill === "text") {
return {
...disabledStyles,
background: "transparent",
border: `1px solid transparent`
};
}
if (fill === "outline") {
return {
...disabledStyles,
background: "transparent",
border: `1px solid ${theme.colors.border.weak}`
};
}
return {
...disabledStyles,
background: theme.colors.action.disabledBackground,
border: `1px solid transparent`
};
}
function getPropertiesForVariant(theme, variant, fill) {
switch (variant) {
case "secondary":
return getButtonVariantStyles(theme, theme.colors.secondary, fill);
case "destructive":
return getButtonVariantStyles(theme, theme.colors.error, fill);
case "success":
return getButtonVariantStyles(theme, theme.colors.success, fill);
case "accent":
return getButtonVariantStyles(theme, theme.colors.accent, fill);
case "primary":
default:
return getButtonVariantStyles(theme, theme.colors.primary, fill);
}
}
const clearButtonStyles = (theme) => {
return css.css({
background: "transparent",
color: theme.colors.text.primary,
border: "none",
padding: 0
});
};
exports.Button = Button;
exports.IconRenderer = IconRenderer;
exports.LinkButton = LinkButton;
exports.allButtonFills = allButtonFills;
exports.allButtonVariants = allButtonVariants;
exports.clearButtonStyles = clearButtonStyles;
exports.getActiveButtonStyles = getActiveButtonStyles;
exports.getButtonStyles = getButtonStyles;
exports.getPropertiesForVariant = getPropertiesForVariant;
//# sourceMappingURL=Button.cjs.map