import React, { useEffect, useState } from 'react'; import cx from 'classnames'; const tinycolor = require('tinycolor2'); import * as Icons from '@tabler/icons-react'; import Loader from '@/ToolJetUI/Loader/Loader'; export const Button = function Button(props) { const { height, properties, styles, fireEvent, id, dataCy, setExposedVariable, setExposedVariables } = props; const { backgroundColor, textColor, borderRadius, loaderColor, borderColor, boxShadow, iconColor, direction, type, padding, iconVisibility, } = styles; const { loadingState, disabledState } = properties; const [label, setLabel] = useState(typeof properties.text === 'string' ? properties.text : ''); const [disable, setDisable] = useState(disabledState || loadingState); const [visibility, setVisibility] = useState(properties.visibility); const [loading, setLoading] = useState(loadingState); const [hovered, setHovered] = useState(false); const iconName = styles.icon; // Replace with the name of the icon you want // eslint-disable-next-line import/namespace const IconElement = Icons[iconName] == undefined ? Icons['IconHome2'] : Icons[iconName]; useEffect(() => { if (typeof properties.text === 'string') { setLabel(properties.text); setExposedVariable('buttonText', properties.text); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [properties.text]); useEffect(() => { disable !== disabledState && setDisable(disabledState); // eslint-disable-next-line react-hooks/exhaustive-deps }, [disabledState]); useEffect(() => { visibility !== properties.visibility && setVisibility(properties.visibility); // eslint-disable-next-line react-hooks/exhaustive-deps }, [properties.visibility]); useEffect(() => { loading !== properties.loadingState && setLoading(properties.loadingState); // eslint-disable-next-line react-hooks/exhaustive-deps }, [properties.loadingState]); const computedIconColor = '#FFFFFF' === iconColor ? (type === 'primary' ? iconColor : 'var(--icons-strong)') : iconColor; const computedBorderColor = borderColor === '#4368E3' ? (type === 'primary' ? '#4368E3' : 'var(--borders-strong)') : borderColor; const computedTextColor = '#FFFFFF' === textColor ? (type === 'primary' ? 'var(--text-on-solid)' : 'var(--text-primary)') : textColor; const computedLoaderColor = '#FFFFFF' === loaderColor ? (type === 'primary' ? loaderColor : 'var(--primary-brand)') : loaderColor; const computedBgColor = '#4368E3' === backgroundColor ? type === 'primary' ? 'var(--primary-brand)' : 'transparent' : type === 'primary' ? backgroundColor : 'transparent'; const computedStyles = { backgroundColor: computedBgColor, color: computedTextColor, width: '100%', borderRadius: `${borderRadius}px`, height: height == 36 ? (padding == 'default' ? '36px' : '40px') : padding == 'default' ? height : height + 4, '--tblr-btn-color-darker': tinycolor(computedBgColor).darken(8).toString(), '--tblr-btn-color-clicked': tinycolor(computedBgColor).darken(15).toString(), '--loader-color': tinycolor(computedLoaderColor ?? 'var(--icons-on-solid)').toString(), borderColor: computedBorderColor, boxShadow: type == 'primary' && boxShadow, padding: '0px 12px', // cursor: 'pointer', opacity: disable && '50%', display: visibility ? (loading ? 'flex' : '') : 'none', justifyContent: 'center', alignItems: 'center', }; useEffect(() => { const exposedVariables = { click: async function () { if (!disable) { fireEvent('onClick'); } }, setText: async function (text) { setLabel(text); setExposedVariable('buttonText', text); }, disable: async function (value) { setDisable(value); }, visibility: async function (value) { setVisibility(value); }, loading: async function (value) { setLoading(value); }, }; setExposedVariables(exposedVariables); // eslint-disable-next-line react-hooks/exhaustive-deps }, [disable]); useEffect(() => { setExposedVariable('setLoading', async function (loading) { setLoading(loading); setExposedVariable('isLoading', loading); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [loadingState]); useEffect(() => { setExposedVariable('setVisibility', async function (state) { setVisibility(state); setExposedVariable('isVisible', state); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [properties.visibility]); useEffect(() => { setExposedVariable('setDisable', async function (disable) { setDisable(disable); setExposedVariable('isDisabled', disable); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [disabledState]); useEffect(() => { setExposedVariable('isLoading', loading); // eslint-disable-next-line react-hooks/exhaustive-deps }, [loading]); useEffect(() => { setExposedVariable('isVisible', visibility); // eslint-disable-next-line react-hooks/exhaustive-deps }, [visibility]); useEffect(() => { setExposedVariable('isDisabled', disable); // eslint-disable-next-line react-hooks/exhaustive-deps }, [disable]); useEffect(() => { if (hovered) { fireEvent('onHover'); } }, [hovered]); const hasCustomBackground = computedBgColor?.charAt() === '#'; if (hasCustomBackground) { computedStyles['--tblr-btn-color-darker'] = tinycolor(computedBgColor).darken(8).toString(); computedStyles['--tblr-btn-color-clicked'] = tinycolor(computedBgColor).darken(15).toString(); } const handleClick = () => { const event1 = new CustomEvent('submitForm', { detail: { buttonComponentId: id } }); document.dispatchEvent(event1); fireEvent('onClick'); }; const renderButton = () => (
); return <>{renderButton()}; };