@grafana/ui
Version:
Grafana Components Library
197 lines (194 loc) • 6.41 kB
JavaScript
import { jsxs, jsx } from 'react/jsx-runtime';
import { cx, css } from '@emotion/css';
import * as React from 'react';
import { useCallback } from 'react';
import { useStyles2 } from '../../themes/ThemeContext.mjs';
import { getMouseFocusStyles, getFocusStyles } from '../../themes/mixins.mjs';
import { getLabelStyles } from './Label.mjs';
"use strict";
const Checkbox = React.forwardRef(
({ label, description, value, htmlValue, onChange, disabled, className, indeterminate, invalid, ...inputProps }, ref) => {
const handleOnChange = useCallback(
(e) => {
if (onChange) {
onChange(e);
}
},
[onChange]
);
const styles = useStyles2(getCheckboxStyles, invalid);
return /* @__PURE__ */ jsxs("label", { className: cx(styles.wrapper, className), children: [
/* @__PURE__ */ jsxs("div", { className: styles.checkboxWrapper, children: [
/* @__PURE__ */ jsx(
"input",
{
type: "checkbox",
className: cx(styles.input, indeterminate && styles.inputIndeterminate),
checked: value,
disabled,
onChange: handleOnChange,
value: htmlValue,
...inputProps,
ref: (element) => {
if (element && indeterminate) {
element.indeterminate = true;
}
if (ref) {
if (typeof ref === "function") {
ref(element);
} else {
ref.current = element;
}
}
}
}
),
/* @__PURE__ */ jsx("span", { className: styles.checkmark })
] }),
label && /* @__PURE__ */ jsx("span", { className: styles.label, children: label }),
description && /* @__PURE__ */ jsx("span", { className: styles.description, children: description })
] });
}
);
const getCheckboxStyles = (theme, invalid = false) => {
const labelStyles = getLabelStyles(theme);
const checkboxSize = 2;
const labelPadding = 1;
const getBorderColor = (color) => {
return invalid ? theme.colors.error.border : color;
};
return {
wrapper: css({
display: "inline-grid",
alignItems: "center",
columnGap: theme.spacing(labelPadding),
// gridAutoRows is needed to prevent https://github.com/grafana/grafana/issues/68570 in safari
gridAutoRows: "max-content",
position: "relative",
verticalAlign: "middle"
}),
input: css({
position: "absolute",
zIndex: 1,
top: 0,
left: 0,
width: "100% !important",
// global styles unset this
height: "100%",
opacity: 0,
"&:focus + span, &:focus-visible + span": getFocusStyles(theme),
"&:focus:not(:focus-visible) + span": getMouseFocusStyles(theme),
/**
* Using adjacent sibling selector to style checked state.
* Primarily to limit the classes necessary to use when these classes will be used
* for angular components styling
* */
"&:checked + span": {
background: theme.colors.primary.main,
border: `1px solid ${getBorderColor(theme.colors.primary.main)}`,
"&:hover": {
background: theme.colors.primary.shade
},
"&:after": {
content: '""',
position: "absolute",
zIndex: 2,
left: theme.spacing(0.5),
top: 0,
width: theme.spacing(0.75),
height: theme.spacing(1.5),
border: `solid ${theme.colors.primary.contrastText}`,
borderWidth: "0 3px 3px 0",
transform: "rotate(45deg)"
}
},
"&:disabled + span": {
backgroundColor: theme.colors.action.disabledBackground,
cursor: "not-allowed",
border: `1px solid ${getBorderColor(theme.colors.action.disabledBackground)}`,
"&:hover": {
backgroundColor: theme.colors.action.disabledBackground
},
"&:after": {
borderColor: theme.colors.action.disabledText
}
}
}),
inputIndeterminate: css({
"&:indeterminate + span": {
border: `1px solid ${getBorderColor(theme.colors.primary.main)}`,
background: theme.colors.primary.main,
"&:hover": {
background: theme.colors.primary.shade
},
"&:after": {
content: '""',
position: "absolute",
zIndex: 2,
left: "2px",
right: "2px",
top: "calc(50% - 1.5px)",
height: "3px",
border: `1.5px solid ${theme.colors.primary.contrastText}`,
backgroundColor: theme.colors.primary.contrastText,
width: "auto",
transform: "none"
}
},
"&:disabled[aria-checked='mixed'] + span": {
backgroundColor: theme.colors.action.disabledBackground,
border: `1px solid ${getBorderColor(theme.colors.error.transparent)}`,
"&:after": {
borderColor: theme.colors.action.disabledText
}
}
}),
checkboxWrapper: css({
display: "flex",
alignItems: "center",
gridColumnStart: 1,
gridRowStart: 1
}),
checkmark: css({
position: "relative",
zIndex: 2,
display: "inline-block",
width: theme.spacing(checkboxSize),
height: theme.spacing(checkboxSize),
borderRadius: theme.shape.radius.sm,
background: theme.components.input.background,
border: `1px solid ${getBorderColor(theme.components.input.borderColor)}`,
"&:hover": {
cursor: "pointer",
borderColor: getBorderColor(theme.components.input.borderHover)
}
}),
label: cx(
labelStyles.label,
css({
gridColumnStart: 2,
gridRowStart: 1,
position: "relative",
zIndex: 2,
cursor: "pointer",
maxWidth: "fit-content",
lineHeight: theme.typography.bodySmall.lineHeight,
marginBottom: 0
})
),
description: cx(
labelStyles.description,
css({
gridColumnStart: 2,
gridRowStart: 2,
lineHeight: theme.typography.bodySmall.lineHeight,
marginTop: 0,
// Enable interacting with description when checkbox is disabled
zIndex: 1
})
)
};
};
Checkbox.displayName = "Checkbox";
export { Checkbox, getCheckboxStyles };
//# sourceMappingURL=Checkbox.mjs.map