UNPKG

@carbon/react

Version:

React components for the Carbon Design System

170 lines (165 loc) 6.02 kB
/** * Copyright IBM Corp. 2016, 2023 * * 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 { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js'; import { RadioButtonChecked, RadioButton, CheckmarkFilled } from '@carbon/icons-react'; import cx from 'classnames'; import PropTypes from 'prop-types'; import React, { cloneElement } from 'react'; import { Enter, Space } from '../../internal/keyboard/keys.js'; import { matches } from '../../internal/keyboard/match.js'; import { useFallbackId } from '../../internal/useId.js'; import { usePrefix } from '../../internal/usePrefix.js'; import deprecate from '../../prop-types/deprecate.js'; import { noopFn } from '../../internal/noopFn.js'; import '../Text/index.js'; import { useFeatureFlag } from '../FeatureFlags/index.js'; import { AILabel } from '../AILabel/index.js'; import { isComponentElement } from '../../internal/utils.js'; import { Text } from '../Text/Text.js'; var _RadioButtonChecked, _RadioButton, _CheckmarkFilled; const RadioTile = /*#__PURE__*/React.forwardRef(function RadioTile({ 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 = cx(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 v12TileRadioIcons = useFeatureFlag('enable-v12-tile-radio-icons'); function icon() { if (v12TileRadioIcons) { if (checked) { return _RadioButtonChecked || (_RadioButtonChecked = /*#__PURE__*/React.createElement(RadioButtonChecked, null)); } else { return _RadioButton || (_RadioButton = /*#__PURE__*/React.createElement(RadioButton, null)); } } else { return _CheckmarkFilled || (_CheckmarkFilled = /*#__PURE__*/React.createElement(CheckmarkFilled, null)); } } function handleOnChange(evt) { onChange(value, name, evt); } function handleOnKeyDown(evt) { if (matches(evt, [Enter, Space])) { evt.preventDefault(); onChange(value, name, evt); } } // AILabel is always size `xs` const candidate = slug ?? decorator; const candidateIsAILabel = isComponentElement(candidate, AILabel); const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, { size: 'xs' }) : null; return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("input", { checked: checked, className: `${prefix}--tile-input`, disabled: disabled, id: inputId, name: name, onChange: !disabled ? handleOnChange : undefined, onKeyDown: !disabled ? handleOnKeyDown : undefined, tabIndex: !disabled ? tabIndex : undefined, type: "radio", value: value, ref: ref, required: required }), /*#__PURE__*/React.createElement("label", _extends({}, rest, { htmlFor: inputId, className: className }), /*#__PURE__*/React.createElement("span", { className: `${prefix}--tile__checkmark` }, icon()), /*#__PURE__*/React.createElement(Text, { className: `${prefix}--tile-content` }, children), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React.createElement("div", { className: `${prefix}--tile--inner-decorator` }, normalizedDecorator) : '')); }); RadioTile.displayName = 'RadioTile'; RadioTile.propTypes = { /** * Specify whether the `RadioTile` should be checked. */ checked: PropTypes.bool, /** * The `RadioTile` content. */ children: PropTypes.node, /** * Provide an optional `className` to be applied to the underlying `<label>`. */ className: PropTypes.string, /** * **Experimental**: Provide a `decorator` component to be rendered inside the `RadioTile` component */ decorator: PropTypes.node, /** * Specify whether the `RadioTile` should be disabled. */ disabled: PropTypes.bool, /** * Specify if the `ExpandableTile` component should be rendered with rounded corners. * Only valid when `slug` prop is present */ hasRoundedCorners: PropTypes.bool, /** * Provide a unique id for the underlying `<input>`. */ id: PropTypes.string, /** * `true` to use the light version. For use on `$layer-01` backgrounds only. * Don't use this to make tile background color same as container background color. */ 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.'), /** * Provide a `name` for the underlying `<input>`. */ name: PropTypes.string, /** * Provide an optional `onChange` hook that is called each time the value of * the underlying `<input>` changes. */ onChange: PropTypes.func, /** * `true` to specify if the control is required. */ required: PropTypes.bool, /** * **Experimental**: Provide a `Slug` component to be rendered inside the `RadioTile` component */ 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.'), /** * Specify the tab index of the underlying `<input>`. */ tabIndex: PropTypes.number, /** * Specify the value of the underlying `<input>`. */ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired }; export { RadioTile as default };