UNPKG

@gravityforms/components

Version:

UI components for use in Gravity Forms development. Both React and vanilla js flavors.

167 lines (152 loc) 5.63 kB
import { React, PropTypes, classnames } from '@gravityforms/libraries'; import { spacerClasses } from '@gravityforms/utils'; import RingLoader from '../../modules/Loaders/RingLoader'; import Tooltip from '../../modules/Tooltip'; const { forwardRef, useEffect, useRef, useState } = React; /** * @module Label * @description A label component. * * @since 1.1.18 * * @param {object} props Component props. * @param {JSX.Element|string} props.children React element children. * @param {object} props.customAttributes Custom attributes for the component. * @param {string|Array|object} props.customClasses Custom classes for the component. * @param {string} props.htmlFor The for attribute for the label. * @param {string} props.icon The icon for the label tooltip. * @param {string} props.iconPrefix The icon prefix for the label. * @param {boolean} props.isVisible If label is visible (true) or hidden (false). * @param {string} props.label Label text. * @param {object} props.loaderProps Props passed to the RingLoader when loading. All RingLoader props can be overridden. * @param {boolean} props.loading If true, displays a RingLoader inline with the label text. * @param {number} props.loadingDelay Delay in ms before the loading indicator appears. Prevents flash for fast operations. Default 0. * @param {string} props.loadingText Optional text to display in place of label while loading. If empty, the label text remains. * @param {boolean} props.locked If the label is locked (disables form element and puts an icon with optional tooltip next to label). * @param {string} props.lockedMessage The message to display when the label is locked, in a tooltip. (optional) * @param {string} props.size The font size for the label. * @param {string|number|Array|object} props.spacing The spacing for the component, as a string, number, array, or object. * @param {string} props.tagName The HTML tag to use for the label element (e.g., 'label', 'legend'). * @param {string} props.weight The font weight for the label. * @param {object|null} ref Ref to the component. * * @return {JSX.Element} The Label component. * * @example * import Label from '@gravityforms/components/react/admin/elements/Label'; * * return <Label htmlFor="input-id">{ 'Input label' }</Label>; * */ const Label = forwardRef( ( { children = null, customAttributes = {}, customClasses = [], htmlFor = '', icon = 'lock', iconPrefix = 'gravity-component-icon', isVisible = true, label = '', loaderProps = { customClasses: 'gform-label__loader', lineWeight: 2, size: 16, spacing: [ 0, 2, 0, 0 ], }, loading = false, loadingDelay = 0, loadingText = '', locked = false, lockedMessage = '', size = 'text-sm', spacing = '', tagName = 'label', weight = 'medium', }, ref ) => { const [ delayedLoading, setDelayedLoading ] = useState( false ); const timerRef = useRef( null ); useEffect( () => { if ( loading && loadingDelay > 0 ) { timerRef.current = setTimeout( () => { setDelayedLoading( true ); }, loadingDelay ); } else { clearTimeout( timerRef.current ); setDelayedLoading( loading ); } return () => clearTimeout( timerRef.current ); }, [ loading, loadingDelay ] ); const isLoading = loadingDelay > 0 ? delayedLoading : loading; if ( ! label && ! children && ! ( isLoading && loadingText ) ) { return null; } const componentProps = { className: classnames( { 'gform-label': true, 'gform-label--loading': isLoading, 'gform-legend': tagName === 'legend', [ `gform-typography--size-${ size }` ]: true, [ `gform-typography--weight-${ weight }` ]: true, 'gform-visually-hidden': ! isVisible, ...spacerClasses( spacing ), }, customClasses ), ref, ...customAttributes, }; if ( tagName === 'label' && htmlFor ) { componentProps.htmlFor = htmlFor; } const tooltipProps = { content: lockedMessage, icon, iconPrefix, iconPreset: 'status-locked', maxWidth: 300, position: 'right', spacing: [ 0, 0, 0, 2 ], tagName: 'span', theme: 'port', }; const Tag = tagName; return ( <Tag { ...componentProps }> { isLoading && <RingLoader { ...loaderProps } /> } { isLoading && loadingText ? loadingText : label } { children } { locked && <Tooltip { ...tooltipProps } /> } </Tag> ); } ); Label.propTypes = { children: PropTypes.oneOfType( [ PropTypes.arrayOf( PropTypes.node ), PropTypes.node, ] ), customAttributes: PropTypes.object, customClasses: PropTypes.oneOfType( [ PropTypes.string, PropTypes.array, PropTypes.object, ] ), htmlFor: PropTypes.string, iconPrefix: PropTypes.string, isVisible: PropTypes.bool, label: PropTypes.string, loaderProps: PropTypes.object, loading: PropTypes.bool, loadingDelay: PropTypes.number, loadingText: PropTypes.string, locked: PropTypes.bool, lockedMessage: PropTypes.string, size: PropTypes.string, spacing: PropTypes.oneOfType( [ PropTypes.string, PropTypes.number, PropTypes.array, PropTypes.object, ] ), tagName: PropTypes.string, weight: PropTypes.string, }; Label.displayName = 'Label'; export default Label;