@carbon/react
Version:
React components for the Carbon Design System
157 lines (153 loc) • 4.2 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.
*/
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
import PropTypes from 'prop-types';
import React, { forwardRef, useState } from 'react';
import cx from 'classnames';
import { IconButton } from '../IconButton/index.js';
import { usePrefix } from '../../internal/usePrefix.js';
import { noopFn } from '../../internal/noopFn.js';
const frFn = forwardRef;
const IconSwitch = frFn((props, ref) => {
const {
align,
children,
className,
disabled,
enterDelayMs,
index,
leaveDelayMs = 0,
name,
onClick = noopFn,
onKeyDown = noopFn,
selected = false,
size,
text,
...other
} = props;
const prefix = usePrefix();
const [isHovered, setIsHovered] = useState(false);
const handleClick = event => {
event.preventDefault();
onClick({
index,
name,
text
});
};
const handleKeyDown = event => {
// TODO: `which` was deprecated years ago. When can its usage be deleted?
const key = event.key || event.which;
onKeyDown({
index,
name,
text,
key
});
};
const handleMouseEnter = () => {
setIsHovered(true);
};
const handleMouseLeave = () => {
setIsHovered(false);
};
const classes = cx(className, `${prefix}--content-switcher-btn`, {
[`${prefix}--content-switcher--selected`]: selected
});
const iconButtonClasses = cx(`${prefix}--content-switcher-popover__wrapper`, {
[`${prefix}--content-switcher-popover--selected`]: selected,
[`${prefix}--content-switcher-popover--disabled`]: disabled
});
return /*#__PURE__*/React.createElement(IconButton, _extends({
label: text,
type: "button",
ref: ref,
role: "tab",
tabIndex: selected || isHovered ? 0 : -1,
onMouseEnter: handleMouseEnter,
onMouseLeave: handleMouseLeave,
onFocus: handleMouseEnter,
onBlur: handleMouseLeave,
"aria-selected": selected,
"aria-label": text,
wrapperClasses: iconButtonClasses
}, other, {
align: align,
className: classes,
disabled: disabled,
enterDelayMs: enterDelayMs,
leaveDelayMs: leaveDelayMs,
onClick: handleClick,
onKeyDown: handleKeyDown,
size: size
}), children);
});
IconSwitch.displayName = 'IconSwitch';
IconSwitch.propTypes = {
/**
* Specify how the trigger should align with the tooltip
*/
align: PropTypes.oneOf(['top', 'top-left', 'top-right', 'bottom', 'bottom-left', 'bottom-right', 'left', 'right']),
/**
* Children to be rendered inside of the `IconSwitch`.
*/
children: PropTypes.node,
/**
* Specify an optional className to be added to your `IconSwitch`.
*/
className: PropTypes.string,
/**
* Whether the `IconSwitch` should be disabled.
*/
disabled: PropTypes.bool,
/**
* Specify the duration in milliseconds to delay before displaying the tooltip
*/
enterDelayMs: PropTypes.number,
/**
* The index of the `IconSwitch`.
*
* Reserved for usage in `ContentSwitcher`.
*/
index: PropTypes.number,
/**
* Specify the duration in milliseconds to delay before hiding the tooltip
*/
leaveDelayMs: PropTypes.number,
/**
* The name of the `IconSwitch`.
*/
name: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
/**
* A handler that is invoked when a user clicks on the control.
*
* Reserved for usage in `ContentSwitcher`.
*/
onClick: PropTypes.func,
/**
* A handler that is invoked on the key down event for the control.
*
* Reserved for usage in `ContentSwitcher`.
*/
onKeyDown: PropTypes.func,
/**
* Whether the `IconSwitch` is selected.
*
* Reserved for usage in `ContentSwitcher`.
*/
selected: PropTypes.bool,
// TODO: Icon only variant of what? Isn't the `IconSwitch` always icon only?
/**
* Passed in from `ContentSwitcher` to render icon-only variant
*/
size: PropTypes.oneOf(['sm', 'md', 'lg']),
/**
* `Tooltip` text.
*/
text: PropTypes.string
};
export { IconSwitch as default };