'use client'; import classnames from 'classnames'; import React, { useId, useState } from 'react'; import MdHelpButton from '../help/MdHelpButton'; import MdHelpText from '../help/MdHelpText'; import MdIconWarning from '../icons-material/MdIconWarning'; interface Labels { helpTextFor?: string; } export interface MdInputProps extends React.InputHTMLAttributes { label?: string; labels?: Labels; error?: boolean; errorText?: string; supportText?: string; hideErrorIcon?: boolean; helpText?: string; outerWrapperClass?: string; suffix?: string | React.ReactNode; prefixIcon?: React.ReactNode; hideNumberArrows?: boolean; /** * v6.x.x: The mode "normal" is deprecated and will be removed in a future version. Please use "medium" instead */ mode?: 'small' | 'medium' | 'large' | 'normal'; } export const MdInput = React.forwardRef( ( { label, labels = {}, id, error = false, errorText, supportText, hideErrorIcon = false, helpText, outerWrapperClass = '', className = '', suffix = undefined, prefixIcon = null, hideNumberArrows = false, disabled = false, readOnly = false, mode = 'medium', ...otherProps }, ref, ) => { const [helpOpen, setHelpOpen] = useState(false); const uuid = useId(); const inputId = id && id !== '' ? id : uuid; const defaultLabels: Required = { helpTextFor: 'Hjelpetekst for', }; const mergedLabels: Required = { ...defaultLabels, ...labels }; const classNames = classnames( 'md-input', { 'md-input--small': mode === 'small', 'md-input--large': mode === 'large', 'md-input--disabled': !!disabled, 'md-input--readonly': !!readOnly, 'md-input--error': !!error, 'md-input--has-suffix': suffix && suffix !== '', 'md-input--has-prefix': prefixIcon !== null && prefixIcon !== '', 'md-input--hide-number-arrows': !!hideNumberArrows, }, className, ); const wrapperClassNames = classnames('md-input__wrapper', { 'md-input__wrapper--small': mode === 'small', 'md-input__wrapper--large': mode === 'large', }); const outerWrapperClasses = classnames( 'md-input__outer-wrapper', { 'md-input__outer-wrapper--small': mode === 'small', 'md-input__outer-wrapper--large': mode === 'large', }, outerWrapperClass, ); // Build aria-describedby in order of priority: error → support → help text const ariaDescribedBy = [ helpText && helpText !== '' && `md-input_help-text_${inputId}`, error && errorText && errorText !== '' && `md-input_error_${inputId}`, supportText && supportText !== '' && `md-input_support-text_${inputId}`, ] .filter(Boolean) .join(' ') || undefined; const showLabel = (label && label !== '') || (helpText && helpText !== ''); /* Log warning if mode = 'normal' */ if (mode === 'normal') { // eslint-disable-next-line no-console console.warn( 'MdInput: The mode "normal" is deprecated and will be removed in a future version. Please use "medium" instead.', ); } return (
{showLabel && (
{label && label !== '' && } {helpText && helpText !== '' && (
{ return setHelpOpen(!helpOpen); }} expanded={helpOpen} />
)}
{helpText && helpText !== '' && (
{helpText}
)}
)}
{prefixIcon && ( )}
{suffix} {error && !hideErrorIcon && (
)}
{error && errorText && errorText !== '' ? (
{errorText}
) : supportText && supportText !== '' ? (
{supportText}
) : null}
); }, ); MdInput.displayName = 'MdInput'; export default MdInput;