/* @flow */ import React, { useCallback, useEffect, useMemo, useState } from 'react' import classnames from 'classnames' import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props' import { globalProps } from '../utilities/globalProps.js' import useZxcvbn from './useZxcvbn' import useHaveIBeenPwned from './useHaveIBeenPwned' import { Body, Caption, CircleIconButton, Flex, Icon, PbReactPopover, ProgressSimple, TextInput } from '../' type PassphraseProps = { aria?: object, averageThreshold?: number, checkPwned?: boolean, common?: boolean, confirmation?: boolean, className?: string, data?: object, dark?: boolean, id?: string, inputProps?: {}, label?: string, minLength?: number, onChange: (String) => void, showTipsBelow?: 'always' | 'xs' | 'sm' | 'md' | 'lg' | 'xl', onStrengthChange?: (number) => void, strongThreshold?: number, tips?: Array, uncontrolled?: boolean, value: string, } const Passphrase = (props: PassphraseProps) => { const { aria = {}, averageThreshold = 2, checkPwned = false, className, common = false, confirmation = false, dark = false, data = {}, id, inputProps = {}, label = confirmation ? 'Confirm Passphrase' : 'Passphrase', minLength = 12, onChange = () => {}, showTipsBelow = 'always', onStrengthChange, strongThreshold = 3, tips = [], uncontrolled = false, value = '', } = props const ariaProps = buildAriaProps(aria) const [uncontrolledValue, setUncontrolledValue] = useState('') const handleChange = useCallback( (e) => uncontrolled ? setUncontrolledValue(e.target.value) : onChange(e), [uncontrolled, onChange] ) const displayValue = useMemo( () => (uncontrolled ? uncontrolledValue : value), [value, uncontrolledValue, uncontrolled], ) const [showPopover, setShowPopover] = useState(false) const toggleShowPopover = () => setShowPopover(!showPopover) const handleShouldClosePopover = (shouldClosePopover) => { setShowPopover(!shouldClosePopover) } const [showPassphrase, setShowPassphrase] = useState(false) const toggleShowPassphrase = () => setShowPassphrase(!showPassphrase) const classes = classnames(buildCss('pb_passphrase'), globalProps(props), className) const isPwned = checkPwned ? useHaveIBeenPwned(displayValue, minLength) : false const { percent: progressPercent, variant: progressVariant, text: strengthLabel, strength } = useZxcvbn({ passphrase: displayValue, common, isPwned, confirmation, averageThreshold, minLength, strongThreshold }) useEffect(() => { if (typeof onStrengthChange === 'function') { onStrengthChange(strength) } }, [strength]) const tipClass = classnames( 'passphrase-popover', (showTipsBelow === 'always' ? null : `show-below-${showTipsBelow}`), ) const dataProps = useMemo( () => (buildDataProps(Object.assign({}, data, { strength }))), [data, strength] ) const popoverReference = ( ) return (
) } export default Passphrase