@grafana/ui
Version:
Grafana Components Library
155 lines (152 loc) • 4.97 kB
JavaScript
import { jsx, jsxs } from 'react/jsx-runtime';
import { cx, css } from '@emotion/css';
import { useId, useCallback, useRef, useEffect } from 'react';
import { toIconName } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { useStyles2 } from '../../../themes/ThemeContext.mjs';
import { Icon } from '../../Icon/Icon.mjs';
import { useFieldContext } from '../FieldContext.mjs';
import { RadioButton, RADIO_GROUP_PADDING } from './RadioButton.mjs';
"use strict";
function RadioButtonGroup({
options,
value,
onChange,
onClick,
disabled: disabledProp,
disabledOptions,
size = "md",
id: idProp,
className,
fullWidth = false,
autoFocus = false,
"aria-label": ariaLabel,
"aria-describedby": ariaDescribedByProp,
"aria-labelledby": ariaLabelledByProp,
"data-testid": dataTestId,
invalid: invalidProp,
...rest
}) {
var _a;
const fieldContext = useFieldContext();
const generatedId = useId();
const disabled = disabledProp != null ? disabledProp : fieldContext.disabled;
const invalid = invalidProp != null ? invalidProp : fieldContext.invalid;
const internalId = (_a = idProp != null ? idProp : fieldContext.id) != null ? _a : generatedId;
const ariaDescribedBy = ariaDescribedByProp != null ? ariaDescribedByProp : fieldContext["aria-describedby"];
const ariaLabelledBy = ariaLabelledByProp != null ? ariaLabelledByProp : fieldContext["aria-labelledby"];
const handleOnChange = useCallback(
(option) => {
return () => {
if (onChange) {
onChange(option.value);
}
};
},
[onChange]
);
const handleOnClick = useCallback(
(option) => {
return () => {
if (onClick) {
onClick(option.value);
}
};
},
[onClick]
);
const groupName = useRef(internalId);
const styles = useStyles2(getStyles);
const activeButtonRef = useRef(null);
useEffect(() => {
if (autoFocus && activeButtonRef.current) {
activeButtonRef.current.focus();
}
}, [autoFocus]);
return /* @__PURE__ */ jsx(
"div",
{
...rest,
role: "radiogroup",
"aria-label": ariaLabel,
"aria-labelledby": ariaLabelledBy,
"data-testid": dataTestId != null ? dataTestId : selectors.components.RadioGroup.container,
className: cx(styles.radioGroup, fullWidth && styles.fullWidth, invalid && styles.invalid, className),
children: options.map((opt, i) => {
const isItemDisabled = disabledOptions && opt.value && disabledOptions.includes(opt.value);
const icon = opt.icon ? toIconName(opt.icon) : void 0;
const hasNonIconPart = Boolean(opt.imgUrl || opt.label || opt.component);
const labelTitle = typeof opt.label === "string" ? opt.label : void 0;
return /* @__PURE__ */ jsxs(
RadioButton,
{
size,
disabled: isItemDisabled || disabled,
active: value === opt.value,
"aria-label": opt.ariaLabel,
"aria-invalid": !!invalid,
"aria-describedby": ariaDescribedBy,
onChange: handleOnChange(opt),
onClick: handleOnClick(opt),
name: groupName.current,
description: opt.description,
title: labelTitle,
fullWidth,
ref: value === opt.value ? activeButtonRef : void 0,
children: [
icon && /* @__PURE__ */ jsx(Icon, { name: icon, className: cx(hasNonIconPart && styles.icon) }),
opt.imgUrl && /* @__PURE__ */ jsx("img", { src: opt.imgUrl, alt: opt.label, className: styles.img }),
opt.label != null && /* @__PURE__ */ jsx("span", { className: styles.labelText, children: opt.label }),
opt.component ? /* @__PURE__ */ jsx(opt.component, {}) : null
]
},
`o.label-${i}`
);
})
}
);
}
RadioButtonGroup.displayName = "RadioButtonGroup";
const getStyles = (theme) => {
return {
radioGroup: css({
display: "inline-flex",
flexDirection: "row",
flexWrap: "nowrap",
maxWidth: "100%",
minWidth: 0,
border: `1px solid ${theme.components.input.borderColor}`,
borderRadius: theme.shape.radius.default,
padding: RADIO_GROUP_PADDING,
"&:hover": {
borderColor: theme.components.input.borderHover
}
}),
fullWidth: css({
display: "flex",
flexGrow: 1,
minWidth: 0,
width: "100%"
}),
icon: css({
marginRight: "6px",
flexShrink: 0
}),
img: css({
width: theme.spacing(2),
height: theme.spacing(2),
marginRight: theme.spacing(1),
flexShrink: 0
}),
labelText: css({
minWidth: 0,
overflow: "hidden",
textOverflow: "ellipsis"
}),
invalid: css({
border: `1px solid ${theme.colors.error.border}`
})
};
};
export { RadioButtonGroup };
//# sourceMappingURL=RadioButtonGroup.mjs.map