@grafana/ui
Version:
Grafana Components Library
128 lines (125 loc) • 3.7 kB
JavaScript
import { jsx, jsxs } from 'react/jsx-runtime';
import { cx, css } from '@emotion/css';
import { uniqueId } from 'lodash';
import { useCallback, useRef, useEffect } from 'react';
import { toIconName } from '@grafana/data';
import { useStyles2 } from '../../../themes/ThemeContext.mjs';
import { Icon } from '../../Icon/Icon.mjs';
import { RadioButton, RADIO_GROUP_PADDING } from './RadioButton.mjs';
;
function RadioButtonGroup({
options,
value,
onChange,
onClick,
disabled,
disabledOptions,
size = "md",
id,
className,
fullWidth = false,
autoFocus = false,
"aria-label": ariaLabel,
invalid = false
}) {
const handleOnChange = useCallback(
(option) => {
return () => {
if (onChange) {
onChange(option.value);
}
};
},
[onChange]
);
const handleOnClick = useCallback(
(option) => {
return () => {
if (onClick) {
onClick(option.value);
}
};
},
[onClick]
);
const internalId = id != null ? id : uniqueId("radiogroup-");
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",
{
role: "radiogroup",
"aria-label": ariaLabel,
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);
return /* @__PURE__ */ jsxs(
RadioButton,
{
size,
disabled: isItemDisabled || disabled,
active: value === opt.value,
"aria-label": opt.ariaLabel,
onChange: handleOnChange(opt),
onClick: handleOnClick(opt),
id: `option-${opt.value}-${internalId}`,
name: groupName.current,
description: opt.description,
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,
" ",
opt.component ? /* @__PURE__ */ jsx(opt.component, {}) : null
]
},
`o.label-${i}`
);
})
}
);
}
RadioButtonGroup.displayName = "RadioButtonGroup";
const getStyles = (theme) => {
return {
radioGroup: css({
backgroundColor: theme.colors.background.primary,
display: "inline-flex",
flexDirection: "row",
flexWrap: "nowrap",
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
}),
icon: css({
marginRight: "6px"
}),
img: css({
width: theme.spacing(2),
height: theme.spacing(2),
marginRight: theme.spacing(1)
}),
invalid: css({
border: `1px solid ${theme.colors.error.border}`
})
};
};
export { RadioButtonGroup };
//# sourceMappingURL=RadioButtonGroup.mjs.map