@syncfusion/react-buttons
Version:
Syncfusion React Buttons package is a feature-rich collection of UI components including Button, CheckBox, RadioButton, Switch, Chip, and more for building modern, interactive React applications.
69 lines (68 loc) • 4.37 kB
JavaScript
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useRef, useState, useImperativeHandle, useMemo, useCallback, forwardRef, memo } from 'react';
import { preRender, useProviderContext, useRippleEffect, Color, Size, Variant, Position } from '@syncfusion/react-base';
import { ChevronDownFillIcon } from '@syncfusion/react-icons';
export { Color, Size, Variant, Position };
/**
* The Button component is a versatile element for creating styled buttons with functionalities like toggling, icon positioning, and HTML attribute support, enhancing interaction based on its configuration and state.
*
* ```typescript
* import { Button, Color } from '@syncfusion/react-buttons';
*
* <Button color={Color.Success}>Submit</Button>
* ```
*/
export const Button = forwardRef((props, ref) => {
const buttonRef = useRef(null);
const { disabled = false, iconPosition = Position.Left, icon, className = '', dropIcon = false, toggleable = false, selected, color = Color.Primary, variant = Variant.Filled, size = Size.Medium, isLink = false, onClick, children, ...domProps } = props;
const [isActive, setIsActive] = useState(selected ?? false);
const { dir, ripple } = useProviderContext();
const { rippleMouseDown, Ripple } = useRippleEffect(ripple, { duration: 500 });
const publicAPI = useMemo(() => ({
iconPosition,
icon,
toggleable,
selected,
color,
variant,
size,
isLink
}), [iconPosition, icon, toggleable, selected, color, variant, size, isLink]);
const handleButtonClick = useCallback((event) => {
if (toggleable && selected === undefined) {
setIsActive((prevState) => !prevState);
}
onClick?.(event);
}, [toggleable, selected, onClick]);
useEffect(() => {
if (selected !== undefined) {
setIsActive(selected);
}
}, [selected]);
useEffect(() => {
preRender('btn');
}, []);
useImperativeHandle(ref, () => ({
...publicAPI,
element: buttonRef.current
}), [publicAPI]);
const classNames = [
'sf-btn sf-control sf-align-center',
iconPosition && (iconPosition === Position.Top || iconPosition === Position.Bottom) ? 'sf-btn-vertical' : 'sf-btn-horizontal',
className,
dir === 'rtl' ? 'sf-rtl' : '',
isActive ? 'sf-active' : '',
isLink ? 'sf-btn-link' + (!props.color ? ' sf-btn-info' : '') : '',
!icon && children && `sf-btn sf-btn-${size.toLowerCase().substring(0, 2)}`,
icon && !children && `sf-icon-btn sf-icon-btn-${size.toLowerCase().substring(0, 2)}`,
icon && children ? `sf-icon sf-icon-${size.toLowerCase().substring(0, 2)}` : '',
iconPosition && `sf-btn-${iconPosition.toLowerCase()}`,
color && 'sf-btn-color',
color && (!isLink || props.color) && `sf-btn-${color.toLowerCase()}`,
variant ? `sf-btn-${variant.toLowerCase()}` : '',
size && `sf-btn-${size.toLowerCase().substring(0, 2)}`,
disabled && 'sf-cursor-default'
].filter(Boolean).join(' ');
return (_jsxs("button", { ref: buttonRef, type: 'button', className: classNames, onClick: handleButtonClick, onMouseDown: rippleMouseDown, disabled: disabled, "aria-pressed": toggleable ? isActive : undefined, ...domProps, children: [!children && icon && (_jsx("span", { className: `sf-btn-icon ${typeof icon === 'string' ? icon : ''}`, children: typeof icon !== 'string' && icon })), children && icon && (iconPosition === 'Left' || iconPosition === 'Top') && (_jsx("span", { className: `sf-btn-icon ${typeof icon === 'string' ? icon : ''} sf-icon-${iconPosition.toLowerCase()}`, children: typeof icon !== 'string' && icon })), _jsx(_Fragment, { children: icon && children ? (_jsx("span", { className: 'sf-btn-content', children: children })) : (children) }), children && icon && (iconPosition === 'Right' || iconPosition === 'Bottom') && (_jsx("span", { className: `sf-btn-icon ${typeof icon === 'string' ? icon : ''} sf-icon-${iconPosition.toLowerCase()}`, children: typeof icon !== 'string' && icon })), dropIcon && (_jsx("span", { className: 'sf-btn-icon sf-icons sf-icon-right sf-caret sf-content-center', children: _jsx(ChevronDownFillIcon, {}) })), ripple && _jsx(Ripple, {})] }));
});
export default memo(Button);