@carbon/react
Version:
React components for the Carbon Design System
169 lines (158 loc) • 5.77 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');
require('../Text/index.js');
var keys = require('../../internal/keyboard/keys.js');
var match = require('../../internal/keyboard/match.js');
var useId = require('../../internal/useId.js');
var deprecate = require('../../prop-types/deprecate.js');
var usePrefix = require('../../internal/usePrefix.js');
var AccordionProvider = require('./AccordionProvider.js');
var Text = require('../Text/Text.js');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
const defaultRenderToggle = props => /*#__PURE__*/React__default["default"].createElement("button", _rollupPluginBabelHelpers["extends"]({
type: "button"
}, props));
function AccordionItem({
children,
className: customClassName = '',
open = false,
onHeadingClick,
renderExpando = defaultRenderToggle,
// remove renderExpando in next major release
renderToggle,
title = 'title',
disabled: controlledDisabled,
handleAnimationEnd,
...rest
}) {
const [isOpen, setIsOpen] = React.useState(open);
const [prevIsOpen, setPrevIsOpen] = React.useState(open);
const accordionState = React.useContext(AccordionProvider.AccordionContext);
const disabledIsControlled = typeof controlledDisabled === 'boolean';
const disabled = disabledIsControlled ? controlledDisabled : accordionState.disabled;
const id = useId.useId('accordion-item');
const prefix = usePrefix.usePrefix();
const className = cx__default["default"]({
[`${prefix}--accordion__item`]: true,
[`${prefix}--accordion__item--active`]: isOpen && !disabled,
[`${prefix}--accordion__item--disabled`]: disabled,
[customClassName]: !!customClassName
});
const Toggle = renderToggle || renderExpando; // remove renderExpando in next major release
const content = React__default["default"].useCallback(node => {
if (!node) {
return;
}
if (isOpen) {
// accordion closes
node.style.maxBlockSize = '';
}
}, [isOpen]);
if (open !== prevIsOpen) {
setIsOpen(open);
setPrevIsOpen(open);
}
// When the AccordionItem heading is clicked, toggle the open state of the
// panel
function onClick(event) {
const nextValue = !isOpen;
setIsOpen(nextValue);
if (onHeadingClick) {
// TODO: normalize signature, potentially:
// onHeadingClick :: (event: Event, state: { isOpen: Boolean }) => any
onHeadingClick({
isOpen: nextValue,
event
});
}
}
// If the AccordionItem is open, and the user hits the ESC key, then close it
function onKeyDown(event) {
if (isOpen && match.match(event, keys.Escape)) {
setIsOpen(false);
}
}
function onAnimationEnd(event) {
if (handleAnimationEnd) {
handleAnimationEnd(event);
}
}
return /*#__PURE__*/React__default["default"].createElement("li", _rollupPluginBabelHelpers["extends"]({
className: className
}, rest), /*#__PURE__*/React__default["default"].createElement(Toggle, {
disabled: disabled,
"aria-controls": id,
"aria-expanded": isOpen,
className: `${prefix}--accordion__heading`,
onClick: onClick,
onKeyDown: onKeyDown,
type: "button"
}, /*#__PURE__*/React__default["default"].createElement(iconsReact.ChevronRight, {
className: `${prefix}--accordion__arrow`
}), /*#__PURE__*/React__default["default"].createElement(Text.Text, {
as: "div",
className: `${prefix}--accordion__title`
}, title)), /*#__PURE__*/React__default["default"].createElement("div", {
ref: content,
className: `${prefix}--accordion__wrapper`,
onTransitionEnd: onAnimationEnd
}, /*#__PURE__*/React__default["default"].createElement("div", {
id: id,
className: `${prefix}--accordion__content`
}, children)));
}
AccordionItem.propTypes = {
/**
* Provide the contents of your AccordionItem
*/
children: PropTypes__default["default"].node,
/**
* Specify an optional className to be applied to the container node
*/
className: PropTypes__default["default"].string,
/**
* Specify whether an individual AccordionItem should be disabled
*/
disabled: PropTypes__default["default"].bool,
/**
* The handler of the massaged `click` event.
*/
onClick: PropTypes__default["default"].func,
/**
* The handler of the massaged `click` event on the heading.
*/
onHeadingClick: PropTypes__default["default"].func,
/**
* `true` to open the expand.
*/
open: PropTypes__default["default"].bool,
/**
* The callback function to render the expand button.
* Can be a React component class.
*/
renderExpando: deprecate["default"](PropTypes__default["default"].func, 'The `renderExpando` prop has been deprecated and will be removed in the next major release of Carbon. Use the `renderToggle` prop instead.'),
/**
* The callback function to render the expand button.
* Can be a React component class.
*/
renderToggle: PropTypes__default["default"].func,
/**
* The accordion title.
*/
title: PropTypes__default["default"].node
};
exports["default"] = AccordionItem;