UNPKG

@carbon/react

Version:

React components for the Carbon Design System

114 lines (112 loc) 4.56 kB
/** * Copyright IBM Corp. 2016, 2026 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import { usePrefix } from "../../internal/usePrefix.js"; import { Text } from "../Text/Text.js"; import { Enter, Space } from "../../internal/keyboard/keys.js"; import { matches } from "../../internal/keyboard/match.js"; import { useFallbackId } from "../../internal/useId.js"; import { noopFn } from "../../internal/noopFn.js"; import { deprecate } from "../../prop-types/deprecate.js"; import { isComponentElement } from "../../internal/utils.js"; import { useFeatureFlag } from "../FeatureFlags/index.js"; import { AILabel } from "../AILabel/index.js"; import classNames from "classnames"; import React, { cloneElement } from "react"; import PropTypes from "prop-types"; import { jsx, jsxs } from "react/jsx-runtime"; import { CheckmarkFilled, RadioButton, RadioButtonChecked } from "@carbon/icons-react"; //#region src/components/RadioTile/RadioTile.tsx /** * Copyright IBM Corp. 2016, 2025 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ const RadioTile = React.forwardRef(({ children, className: customClassName, decorator, disabled, light, checked, name, value, id, onChange = noopFn, tabIndex = 0, hasRoundedCorners, slug, required, ...rest }, ref) => { const prefix = usePrefix(); const inputId = useFallbackId(id); const className = classNames(customClassName, `${prefix}--tile`, `${prefix}--tile--selectable`, `${prefix}--tile--radio`, { [`${prefix}--tile--is-selected`]: checked, [`${prefix}--tile--light`]: light, [`${prefix}--tile--disabled`]: disabled, [`${prefix}--tile--slug`]: slug, [`${prefix}--tile--slug-rounded`]: slug && hasRoundedCorners, [`${prefix}--tile--decorator`]: decorator, [`${prefix}--tile--decorator-rounded`]: decorator && hasRoundedCorners }); const { "aria-describedby": ariaDescribedBy, "aria-labelledby": ariaLabelledBy, ...labelProps } = rest; const v12TileRadioIcons = useFeatureFlag("enable-v12-tile-radio-icons"); function icon() { if (v12TileRadioIcons) if (checked) return /* @__PURE__ */ jsx(RadioButtonChecked, {}); else return /* @__PURE__ */ jsx(RadioButton, {}); else return /* @__PURE__ */ jsx(CheckmarkFilled, {}); } function handleOnChange(evt) { onChange(value, name, evt); } function handleOnKeyDown(evt) { if (matches(evt, [Enter, Space])) { evt.preventDefault(); onChange(value, name, evt); } } const candidate = slug ?? decorator; const normalizedDecorator = isComponentElement(candidate, AILabel) ? cloneElement(candidate, { size: "xs" }) : candidate; return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("input", { checked, className: `${prefix}--tile-input`, disabled, id: inputId, name, onChange: !disabled ? handleOnChange : void 0, onKeyDown: !disabled ? handleOnKeyDown : void 0, tabIndex: !disabled ? tabIndex : void 0, type: "radio", value, ...ariaDescribedBy && { "aria-describedby": ariaDescribedBy }, ...ariaLabelledBy && { "aria-labelledby": ariaLabelledBy }, ref, required }), /* @__PURE__ */ jsxs("label", { ...labelProps, htmlFor: inputId, className, children: [ /* @__PURE__ */ jsx("span", { className: `${prefix}--tile__checkmark`, children: icon() }), /* @__PURE__ */ jsx(Text, { className: `${prefix}--tile-content`, children }), slug ? normalizedDecorator : decorator ? /* @__PURE__ */ jsx("div", { className: `${prefix}--tile--inner-decorator`, children: normalizedDecorator }) : "" ] })] }); }); RadioTile.displayName = "RadioTile"; RadioTile.propTypes = { checked: PropTypes.bool, children: PropTypes.node, className: PropTypes.string, decorator: PropTypes.node, disabled: PropTypes.bool, hasRoundedCorners: PropTypes.bool, id: PropTypes.string, light: deprecate(PropTypes.bool, "The `light` prop for `RadioTile` is no longer needed and has been deprecated in v11 in favor of the new `Layer` component. It will be removed in the next major release."), name: PropTypes.string, onChange: PropTypes.func, required: PropTypes.bool, slug: deprecate(PropTypes.node, "The `slug` prop for `RadioTile` has been deprecated in favor of the new `decorator` prop. It will be removed in the next major release."), tabIndex: PropTypes.number, value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired }; //#endregion export { RadioTile as default };