@syncfusion/react-buttons
Version:
A package of feature-rich Pure React components such as Button, CheckBox and RadioButton.
150 lines (149 loc) • 6.09 kB
JavaScript
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useRef, useState, useImperativeHandle, forwardRef } from 'react';
import { preRender, SvgIcon, useProviderContext, useRippleEffect } from '@syncfusion/react-base';
import * as React from 'react';
/**
* Specifies the position of an icon relative to text content in a button component.
*/
export var IconPosition;
(function (IconPosition) {
/**
* Positions the icon to the left of text content in a button.
*/
IconPosition["Left"] = "Left";
/**
* Positions the icon to the right of text content in a button.
*/
IconPosition["Right"] = "Right";
/**
* Positions the icon above text content in a button.
*/
IconPosition["Top"] = "Top";
/**
* Positions the icon below text content in a button.
*/
IconPosition["Bottom"] = "Bottom";
})(IconPosition || (IconPosition = {}));
/**
* Specifies the type of Color to display the Button with distinctive colors.
*/
export var Color;
(function (Color) {
/**
* The button is displayed with colors that indicate success.
*/
Color["Success"] = "Success";
/**
* The button is displayed with colors that indicate information.
*/
Color["Info"] = "Info";
/**
* The button is displayed with colors that indicate a warning.
*/
Color["Warning"] = "Warning";
/**
* The button is displayed with colors that indicate danger.
*/
Color["Danger"] = "Danger";
/**
* The button is displayed with colors that indicate it is a primary button.
*/
Color["Primary"] = "Primary";
/**
* The button is displayed with colors that indicate it is a secondary button.
*/
Color["Secondary"] = "Secondary";
})(Color || (Color = {}));
/**
* Defines the visual style variants for a button component, controlling background, border, and text appearance.
*/
export var Variant;
(function (Variant) {
/**
* Displays a solid background color with contrasting text.
*/
Variant["Filled"] = "Filled";
/**
* Displays a border with a transparent background and colored text.
*/
Variant["Outlined"] = "Outlined";
/**
* Displays only colored text without background and border.
*/
Variant["Flat"] = "Flat";
})(Variant || (Variant = {}));
/**
* Specifies the size of the Button for layout purposes.
*/
export var Size;
(function (Size) {
/**
* The button is displayed in a smaller size.
*/
Size["Small"] = "Small";
/**
* The button is displayed in a medium size.
*/
Size["Medium"] = "Medium";
/**
* The button is displayed in a larger size.
*/
Size["Large"] = "Large";
})(Size || (Size = {}));
/**
* 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
* <Button color={Color.Success}>Submit</Button>
* ```
*/
export const Button = forwardRef((props, ref) => {
const buttonRef = useRef(null);
const { disabled = false, iconPosition = IconPosition.Left, icon, className = '', dropIcon = false, togglable = false, selected, color = Color.Primary, variant = Variant.Filled, size, isLink = false, onClick, children, ...domProps } = props;
const [isActive, setIsActive] = useState(selected ?? false);
const { dir, ripple } = useProviderContext();
const { rippleMouseDown, Ripple } = useRippleEffect(ripple, { duration: 500 });
const caretIcon = 'M5 8.5L12 15.5L19 8.5';
const publicAPI = {
iconPosition,
icon,
togglable,
selected,
color,
variant,
size,
isLink
};
const handleButtonClick = (event) => {
if (togglable && selected === undefined) {
setIsActive((prevState) => !prevState);
}
onClick?.(event);
};
useEffect(() => {
if (selected !== undefined) {
setIsActive(selected);
}
}, [selected]);
useEffect(() => {
preRender('btn');
}, []);
useImperativeHandle(ref, () => ({
...publicAPI,
element: buttonRef.current
}), [publicAPI]);
const classNames = [
'sf-btn',
className,
dir === 'rtl' ? 'sf-rtl' : '',
isActive ? 'sf-active' : '',
isLink ? 'sf-link' : '',
icon && !children ? 'sf-icon-btn' : '',
iconPosition && `sf-${iconPosition.toLowerCase()}`,
color && color.toLowerCase() !== 'secondary' ? `sf-${color.toLowerCase()}` : '',
variant ? `sf-${variant.toLowerCase()}` : '',
size && size.toLowerCase() !== 'medium' ? `sf-${size.toLowerCase()}` : ''
].filter(Boolean).join(' ');
return (_jsxs("button", { ref: buttonRef, type: 'button', className: classNames, onClick: handleButtonClick, onMouseDown: rippleMouseDown, disabled: disabled, ...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-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', children: _jsx(SvgIcon, { fill: 'currentColor', width: '16', height: '16', viewBox: '0 0 23 23', d: caretIcon }) })), ripple && _jsx(Ripple, {})] }));
});
export default React.memo(Button);