import React, { useEffect, useRef, useState } from 'react'; import { resolveReferences } from '@/_helpers/utils'; import { useCurrentState } from '@/_stores/currentStateStore'; import * as Icons from '@tabler/icons-react'; import Loader from '@/ToolJetUI/Loader/Loader'; import SolidIcon from '@/_ui/Icon/SolidIcons'; import Label from '@/_ui/Label'; export const PasswordInput = function PasswordInput({ height, validate, properties, styles, setExposedVariable, fireEvent, component, darkMode, dataCy, isResizing, adjustHeightBasedOnAlignment, currentLayout, }) { const textInputRef = useRef(); const labelRef = useRef(); const { loadingState, disabledState, label, placeholder } = properties; const { padding, borderRadius, borderColor, backgroundColor, textColor, boxShadow, width, alignment, direction, color, auto, errTextColor, iconColor, accentColor, } = styles; const [disable, setDisable] = useState(disabledState || loadingState); const [passwordValue, setPasswordValue] = useState(properties.value); const [visibility, setVisibility] = useState(properties.visibility); const { isValid, validationError } = validate(passwordValue); const [showValidationError, setShowValidationError] = useState(false); const currentState = useCurrentState(); const isMandatory = resolveReferences(component?.definition?.validation?.mandatory?.value, currentState); const [labelWidth, setLabelWidth] = useState(0); const defaultAlignment = alignment === 'side' || alignment === 'top' ? alignment : 'side'; const [iconVisibility, setIconVisibility] = useState(false); const [loading, setLoading] = useState(loadingState); const [isFocused, setIsFocused] = useState(false); const tinycolor = require('tinycolor2'); const _width = (width / 100) * 70; // Max width which label can go is 70% for better UX calculate width based on this value const computedStyles = { height: height == 36 ? (padding == 'default' ? '36px' : '40px') : padding == 'default' ? height : height + 4, borderRadius: `${borderRadius}px`, color: darkMode && textColor === '#11181C' ? '#ECEDEE' : textColor, borderColor: isFocused ? accentColor : ['#D7DBDF'].includes(borderColor) ? darkMode ? '#6D757D7A' : '#6A727C47' : borderColor, '--tblr-input-border-color-darker': tinycolor(borderColor).darken(24).toString(), backgroundColor: darkMode && ['#fff', '#ffffff'].includes(backgroundColor) ? '#313538' : backgroundColor, boxShadow: boxShadow, padding: styles.iconVisibility ? '8px 10px 8px 29px' : '8px 10px 8px 10px', overflow: 'hidden', textOverflow: 'ellipsis', }; const loaderStyle = { right: direction === 'right' && defaultAlignment === 'side' && ((label?.length > 0 && width > 0) || (auto && width == 0 && label && label?.length != 0)) ? `${labelWidth + 11}px` : '11px', top: `${ defaultAlignment === 'top' ? ((label?.length > 0 && width > 0) || (auto && width == 0 && label && label?.length != 0)) && 'calc(50% + 10px)' : '' }`, transform: defaultAlignment === 'top' && ((label?.length > 0 && width > 0) || (auto && width == 0 && label && label?.length != 0)) && ' translateY(-50%)', zIndex: 3, }; useEffect(() => { setExposedVariable('label', label); // eslint-disable-next-line react-hooks/exhaustive-deps }, [label]); useEffect(() => { if (labelRef?.current) { const absolutewidth = labelRef?.current?.getBoundingClientRect()?.width; setLabelWidth(absolutewidth); } else setLabelWidth(0); // eslint-disable-next-line react-hooks/exhaustive-deps }, [ isResizing, width, auto, defaultAlignment, component?.definition?.styles?.iconVisibility?.value, label?.length, isMandatory, padding, direction, alignment, isMandatory, labelRef?.current?.getBoundingClientRect()?.width, ]); 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 !== loadingState && setLoading(loadingState); // eslint-disable-next-line react-hooks/exhaustive-deps }, [loadingState]); useEffect(() => { setExposedVariable('isValid', isValid); // eslint-disable-next-line react-hooks/exhaustive-deps }, [isValid]); useEffect(() => { setPasswordValue(properties.value); setExposedVariable('value', properties?.value ?? ''); // eslint-disable-next-line react-hooks/exhaustive-deps }, [properties.value]); useEffect(() => { setExposedVariable('setFocus', async function () { textInputRef.current.focus(); }); setExposedVariable('setBlur', async function () { textInputRef.current.blur(); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { setExposedVariable('setText', async function (text) { setPasswordValue(text); setExposedVariable('value', text).then(fireEvent('onChange')); }); setExposedVariable('clear', async function () { setPasswordValue(''); setExposedVariable('value', '').then(fireEvent('onChange')); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [setPasswordValue]); 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]; // eslint-disable-next-line import/namespace useEffect(() => { if (alignment == 'top' && ((label?.length > 0 && width > 0) || (auto && width == 0 && label && label?.length != 0))) adjustHeightBasedOnAlignment(true); else adjustHeightBasedOnAlignment(false); // eslint-disable-next-line react-hooks/exhaustive-deps }, [alignment, label?.length, currentLayout, width, auto]); useEffect(() => { setExposedVariable('isMandatory', isMandatory); // eslint-disable-next-line react-hooks/exhaustive-deps }, [isMandatory]); useEffect(() => { setExposedVariable('isLoading', loading); // eslint-disable-next-line react-hooks/exhaustive-deps }, [loading]); useEffect(() => { setExposedVariable('setLoading', async function (loading) { setLoading(loading); setExposedVariable('isLoading', loading); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [properties.loadingState]); useEffect(() => { setExposedVariable('isVisible', visibility); // eslint-disable-next-line react-hooks/exhaustive-deps }, [visibility]); 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('isDisabled', disable); // eslint-disable-next-line react-hooks/exhaustive-deps }, [disable]); const renderInput = () => ( <>
{showValidationError && visibility && (
{showValidationError && validationError}
)} ); return
{renderInput()}
; };