@carbon/react
Version:
React components for the Carbon Design System
184 lines (177 loc) • 6.45 kB
JavaScript
/**
* 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.
*/
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
var iconsReact = require('@carbon/icons-react');
var cx = require('classnames');
var PropTypes = require('prop-types');
var React = require('react');
var keys = require('../../internal/keyboard/keys.js');
var match = require('../../internal/keyboard/match.js');
var useId = require('../../internal/useId.js');
var usePrefix = require('../../internal/usePrefix.js');
var deprecate = require('../../prop-types/deprecate.js');
var noopFn = require('../../internal/noopFn.js');
var Text = require('../Text/Text.js');
require('../Text/TextDirection.js');
var index = require('../FeatureFlags/index.js');
var index$1 = require('../AILabel/index.js');
var utils = require('../../internal/utils.js');
var _RadioButtonChecked, _RadioButton, _CheckmarkFilled;
const RadioTile = /*#__PURE__*/React.forwardRef(({
children,
className: customClassName,
decorator,
disabled,
light,
checked,
name,
value,
id,
onChange = noopFn.noopFn,
tabIndex = 0,
hasRoundedCorners,
slug,
required,
...rest
}, ref) => {
const prefix = usePrefix.usePrefix();
const inputId = useId.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 {
'aria-describedby': ariaDescribedBy,
'aria-labelledby': ariaLabelledBy,
...labelProps
} = rest;
const v12TileRadioIcons = index.useFeatureFlag('enable-v12-tile-radio-icons');
function icon() {
if (v12TileRadioIcons) {
if (checked) {
return _RadioButtonChecked || (_RadioButtonChecked = /*#__PURE__*/React.createElement(iconsReact.RadioButtonChecked, null));
} else {
return _RadioButton || (_RadioButton = /*#__PURE__*/React.createElement(iconsReact.RadioButton, null));
}
} else {
return _CheckmarkFilled || (_CheckmarkFilled = /*#__PURE__*/React.createElement(iconsReact.CheckmarkFilled, null));
}
}
function handleOnChange(evt) {
onChange(value, name, evt);
}
function handleOnKeyDown(evt) {
if (match.matches(evt, [keys.Enter, keys.Space])) {
evt.preventDefault();
onChange(value, name, evt);
}
}
// AILabel is always size `xs`
const candidate = slug ?? decorator;
const candidateIsAILabel = utils.isComponentElement(candidate, index$1.AILabel);
const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/React.cloneElement(candidate, {
size: 'xs'
}) : candidate;
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("input", _rollupPluginBabelHelpers.extends({
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
}, ariaDescribedBy && {
'aria-describedby': ariaDescribedBy
}, ariaLabelledBy && {
'aria-labelledby': ariaLabelledBy
}, {
ref: ref,
required: required
})), /*#__PURE__*/React.createElement("label", _rollupPluginBabelHelpers.extends({}, labelProps, {
htmlFor: inputId,
className: className
}), /*#__PURE__*/React.createElement("span", {
className: `${prefix}--tile__checkmark`
}, icon()), /*#__PURE__*/React.createElement(Text.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.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.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
};
exports.default = RadioTile;