@grafana/ui
Version:
Grafana Components Library
220 lines (217 loc) • 6.95 kB
JavaScript
import { jsxs, jsx } from 'react/jsx-runtime';
import { cx, css } from '@emotion/css';
import { forwardRef, useId } from 'react';
import { deprecationWarning } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { useStyles2 } from '../../themes/ThemeContext.mjs';
import { getMouseFocusStyles, getFocusStyles } from '../../themes/mixins.mjs';
import { useFieldContext } from '../Forms/FieldContext.mjs';
import { Icon } from '../Icon/Icon.mjs';
"use strict";
const Switch = forwardRef(
({
value,
checked,
onChange,
id: idProp,
label,
disabled: disabledProp,
invalid: invalidProp = false,
...inputProps
}, ref) => {
var _a;
if (checked) {
deprecationWarning("Switch", "checked prop", "value");
}
const styles = useStyles2(getSwitchStyles);
const generatedId = useId();
const fieldContext = useFieldContext();
const invalid = invalidProp != null ? invalidProp : fieldContext.invalid;
const disabled = disabledProp != null ? disabledProp : fieldContext.disabled;
const switchId = (_a = idProp != null ? idProp : fieldContext.id) != null ? _a : generatedId;
return /* @__PURE__ */ jsxs("div", { className: cx(styles.switch, invalid && styles.invalid), "data-testid": selectors.components.Switch.container, children: [
/* @__PURE__ */ jsx(
"input",
{
type: "checkbox",
role: "switch",
disabled,
checked: value,
onChange: (event) => {
!disabled && (onChange == null ? void 0 : onChange(event));
},
id: switchId,
"aria-invalid": !!invalid,
...inputProps,
ref
}
),
/* @__PURE__ */ jsx("label", { htmlFor: switchId, "aria-label": label }),
/* @__PURE__ */ jsx(Icon, { name: "check", size: "xs" })
] });
}
);
Switch.displayName = "Switch";
const InlineSwitch = forwardRef(
({
transparent,
className,
showLabel,
label,
value,
disabled: disabledProp,
id: idProp,
invalid: invalidProp,
...props
}, ref) => {
var _a;
const styles = useStyles2(getSwitchStyles, transparent);
const defaultId = useId();
const fieldContext = useFieldContext();
const invalid = invalidProp != null ? invalidProp : fieldContext.invalid;
const disabled = disabledProp != null ? disabledProp : fieldContext.disabled;
const id = (_a = idProp != null ? idProp : fieldContext.id) != null ? _a : defaultId;
return /* @__PURE__ */ jsxs("div", { className: cx(styles.inlineContainer, className, disabled && styles.disabled, invalid && styles.invalid), children: [
showLabel && /* @__PURE__ */ jsx(
"label",
{
htmlFor: id,
className: cx(styles.inlineLabel, value && styles.inlineLabelEnabled, "inline-switch-label"),
children: label
}
),
/* @__PURE__ */ jsx(
Switch,
{
...props,
disabled,
invalid,
id,
label: showLabel ? void 0 : label,
ref,
value
}
)
] });
}
);
InlineSwitch.displayName = "Switch";
const getSwitchStyles = (theme, transparent) => ({
switch: css({
width: theme.spacing(4),
height: theme.spacing(2),
position: "relative",
lineHeight: 1,
input: {
height: "100%",
width: "100% !important",
opacity: 0,
zIndex: -1e3,
position: "absolute",
"&:checked": {
"~ label": {
background: theme.colors.accent.main,
borderColor: theme.colors.accent.main,
"&:hover": {
background: theme.colors.accent.shade
}
},
"~ svg": {
transform: `translate3d(${theme.spacing(2.25)}, -50%, 0)`,
background: theme.colors.accent.contrastText,
color: theme.colors.accent.main
}
},
"&:disabled": {
"~ label": {
background: theme.colors.action.disabledBackground,
borderColor: theme.colors.border.weak,
cursor: "not-allowed"
},
"~ svg": {
background: theme.colors.text.disabled
}
},
"&:disabled:checked": {
"~ label": {
background: theme.colors.accent.transparent
},
"~ svg": {
color: theme.colors.accent.contrastText
}
},
"&:focus ~ label, &:focus-visible ~ label": getFocusStyles(theme),
"&:focus:not(:focus-visible) ~ label": getMouseFocusStyles(theme)
},
label: {
width: "100%",
height: "100%",
cursor: "pointer",
borderRadius: theme.shape.radius.pill,
background: theme.components.input.background,
border: `1px solid ${theme.components.input.borderColor}`,
[theme.transitions.handleMotion("no-preference")]: {
transition: "all 0.3s ease"
},
"&:hover": {
borderColor: theme.components.input.borderHover
}
},
svg: {
position: "absolute",
display: "block",
color: "transparent",
width: theme.spacing(1.5),
height: theme.spacing(1.5),
borderRadius: theme.shape.radius.circle,
background: theme.colors.text.secondary,
boxShadow: theme.shadows.z1,
left: 0,
pointerEvents: "none",
top: "50%",
transform: `translate3d(${theme.spacing(0.25)}, -50%, 0)`,
[theme.transitions.handleMotion("no-preference")]: {
transition: "transform 0.2s cubic-bezier(0.19, 1, 0.22, 1)"
},
"@media (forced-colors: active)": {
border: `1px solid ${theme.colors.accent.contrastText}`
}
}
}),
inlineContainer: css({
padding: theme.spacing(0, 1),
height: theme.spacing(theme.components.height.md),
display: "inline-flex",
alignItems: "center",
background: transparent ? "transparent" : theme.components.input.background,
border: `1px solid ${transparent ? "transparent" : theme.components.input.borderColor}`,
borderRadius: theme.shape.radius.default,
"&:hover": {
border: `1px solid ${transparent ? "transparent" : theme.components.input.borderHover}`,
".inline-switch-label": {
color: theme.colors.text.primary
}
}
}),
disabled: css({
backgroundColor: transparent ? "transparent" : "rgba(204, 204, 220, 0.04)",
color: "rgba(204, 204, 220, 0.6)",
border: `1px solid ${transparent ? "transparent" : "rgba(204, 204, 220, 0.04)"}`
}),
inlineLabel: css({
cursor: "pointer",
paddingRight: theme.spacing(1),
color: theme.colors.text.secondary,
whiteSpace: "nowrap"
}),
inlineLabelEnabled: css({
color: theme.colors.text.primary
}),
invalid: css({
"input ~ label, input:checked ~ label, input:hover ~ label": {
border: `1px solid ${theme.colors.error.border}`
}
})
});
export { InlineSwitch, Switch };
//# sourceMappingURL=Switch.mjs.map