design-react-kit
Version:
Componenti React per Bootstrap 5
1 lines • 19.4 kB
Source Map (JSON)
{"version":3,"sources":["../../src/Input/TextArea.tsx","../../src/Input/InputContainer.tsx","../../src/Input/utils.tsx","../../src/utils.tsx"],"sourcesContent":["import React, { ReactNode, Ref, TextareaHTMLAttributes } from 'react';\n\nimport type { CSSModule } from 'reactstrap/types/lib/utils';\nimport { InputContainer } from './InputContainer';\nimport { getClasses, getFormControlClass, getValidationTextControlClass, useFocus } from './utils';\n\nexport interface TextAreaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n /** Etichetta del campo TextArea. */\n label?: string | ReactNode;\n /** Testo di esempio da utilizzare per il campo. */\n placeholder?: string;\n /** Testo di validazione per l'elemento del moduleo */\n validationText?: string;\n /** Testo di aiuto per l'elemento del moduleo form. Richiede che il componente `TextArea` abbia la prop `id` impostata. */\n infoText?: string;\n /** Il valore nel campo TextArea. */\n value?: string | number;\n /** Da utilizzare per impedire la modifica del valore contenuto. */\n readOnly?: boolean;\n /** Associato all'attributo readOnly mostra il campo con lo stile classico, mantenento lo stato di sola lettura. */\n normalized?: boolean;\n /** Utilizzare per mostrare il successo nella validazione del valore nel campo TextArea */\n valid?: boolean;\n innerRef?: Ref<HTMLTextAreaElement>;\n /** Oggetto contenente la nuova mappatura per le classi CSS. */\n cssModule?: CSSModule;\n /** Classi aggiuntive da usare per il wrapper del componente TextArea */\n wrapperClassName?: string;\n /** Classi aggiuntive da usare per il componente TextArea */\n className?: string;\n testId?: string;\n}\n\nexport const TextArea = ({\n id,\n className,\n cssModule,\n innerRef,\n label,\n validationText,\n infoText,\n placeholder,\n normalized,\n value,\n wrapperClassName: originalWrapperClass,\n valid,\n testId,\n ...attributes\n}: TextAreaProps) => {\n const { toggleFocusLabel, toggleBlurLabel, isFocused } = useFocus<HTMLTextAreaElement>({\n onFocus: attributes.onFocus,\n onBlur: attributes.onBlur\n });\n\n const validationTextControlClass = getValidationTextControlClass({ valid }, cssModule);\n\n const extraAttributes: { ['aria-describedby']?: string } = {};\n\n //Chiamo questa funzione per impostare classNames a 'form-control'\n const formControlClass = getFormControlClass({}, cssModule);\n // associate the input field with the help text\n const infoId = id ? `${id}Description` : undefined;\n if (id) {\n extraAttributes['aria-describedby'] = infoId;\n }\n\n // Styling\n const { activeClass, extraLabelClass, validationTextClass, inputClasses, wrapperClass } = getClasses(\n className,\n 'textarea',\n {\n valid,\n placeholder,\n value,\n label,\n validationText,\n normalized: Boolean(normalized),\n formControlClass,\n validationTextControlClass,\n isFocused,\n originalWrapperClass\n },\n cssModule\n );\n\n // set of attributes always shared by the Input components\n const sharedAttributes = {\n id,\n onFocus: toggleFocusLabel,\n onBlur: toggleBlurLabel,\n value,\n ref: innerRef\n };\n\n // set of attributes always shared by the wrapper component\n const containerProps = {\n id,\n infoId,\n infoText,\n activeClass,\n extraLabelClass,\n label,\n validationTextClass,\n validationText,\n wrapperClass\n };\n\n if (placeholder) {\n return (\n <InputContainer {...containerProps}>\n <textarea\n {...attributes}\n {...extraAttributes}\n {...sharedAttributes}\n className={inputClasses}\n placeholder={placeholder}\n data-testid={testId}\n />\n </InputContainer>\n );\n }\n\n if (normalized) {\n return (\n <InputContainer {...containerProps}>\n <textarea\n {...attributes}\n {...extraAttributes}\n {...sharedAttributes}\n className={inputClasses}\n readOnly\n data-testid={testId}\n />\n </InputContainer>\n );\n }\n if (label || validationText) {\n return (\n <InputContainer {...containerProps}>\n <textarea\n {...attributes}\n {...extraAttributes}\n {...sharedAttributes}\n className={inputClasses}\n data-testid={testId}\n />\n </InputContainer>\n );\n }\n\n return (\n <textarea\n {...attributes}\n {...extraAttributes}\n className={inputClasses}\n {...sharedAttributes}\n ref={innerRef}\n data-testid={testId}\n />\n );\n};\n","import React, { FC, HTMLAttributes, ReactNode } from 'react';\n\nexport interface InputContainerProps extends HTMLAttributes<HTMLElement> {\n wrapperClass: string;\n activeClass: string;\n extraLabelClass: string;\n validationTextClass: string;\n label: string | ReactNode | undefined;\n validationText: string | undefined;\n id: string | undefined;\n infoId: string | undefined;\n infoText: string | undefined;\n /** Indica che il componente ha un bottone a destra rispetto all'input */\n hasButtonRight?: boolean;\n /** Componente per il bottone */\n buttonRight?: ReactNode;\n /** Indica che il componente ha una icona a sinistra rispetto all'input */\n hasIconLeft?: boolean;\n /** Componente per l'icona */\n iconLeft?: ReactNode;\n testId?: string;\n}\n\nexport const InputContainer: FC<InputContainerProps> = ({\n id,\n infoId,\n infoText,\n testId,\n activeClass,\n extraLabelClass,\n label,\n validationTextClass,\n validationText,\n wrapperClass,\n hasButtonRight,\n buttonRight,\n hasIconLeft,\n iconLeft,\n children\n}) => {\n if (hasButtonRight || hasIconLeft) {\n return (\n <div className={wrapperClass} data-testid={testId}>\n <div className='input-group'>\n {hasIconLeft && <span className='input-group-text'>{iconLeft}</span>}\n <label htmlFor={id} className={activeClass + ' ' + extraLabelClass}>\n {label}\n </label>\n {children}\n {infoText && (\n <small id={infoId} className='form-text'>\n {infoText}\n </small>\n )}\n <div className={validationTextClass}>{validationText}</div>\n {hasButtonRight && <div className='input-group-append'>{buttonRight}</div>}\n </div>\n </div>\n );\n }\n return (\n <div className={wrapperClass} data-testid={testId}>\n <label htmlFor={id} className={activeClass + ' ' + extraLabelClass}>\n {label}\n </label>\n {children}\n {infoText && (\n <small id={infoId} className='form-text'>\n {infoText}\n </small>\n )}\n <div className={validationTextClass}>{validationText}</div>\n </div>\n );\n};\n","import classNames from 'classnames';\nimport { useCallback, useState } from 'react';\nimport type { CSSModule } from 'reactstrap/types/lib/utils';\nimport { mapToCssModules } from '../utils';\nimport type { InputProps } from './Input';\n\ntype ValidationProps = Pick<InputProps, 'valid'>;\ntype TypeProps = Pick<InputProps, 'plaintext' | 'type'> & {\n staticInput?: boolean;\n};\ntype FormControlProps = Pick<InputProps, 'normalized'> & TypeProps;\n\nfunction getFormControlClassInternal({ plaintext, staticInput, type = 'text', normalized }: FormControlProps) {\n const formControlClass = 'form-control';\n if (plaintext || staticInput || normalized) {\n return `${formControlClass}-plaintext`;\n }\n if (type === 'file') {\n return `${formControlClass}-file`;\n }\n if (['radio', 'checkbox'].indexOf(type) > -1) {\n return null;\n }\n return formControlClass;\n}\n\nexport function getFormControlClass(props: FormControlProps, cssModule?: CSSModule) {\n return mapToCssModules(getFormControlClassInternal(props), cssModule);\n}\n\nexport function getValidationTextControlClass({ valid }: ValidationProps, cssModule?: CSSModule) {\n return mapToCssModules(\n classNames({\n 'form-text': true,\n 'form-feedback just-validate-error-label': valid == false\n }),\n cssModule\n );\n}\n\nexport function getTag({ tag, plaintext, staticInput, type = 'text' }: Pick<InputProps, 'tag'> & TypeProps) {\n if (tag) {\n return tag;\n }\n if (['radio', 'checkbox'].indexOf(type) > -1) {\n return 'input';\n }\n if (plaintext || staticInput) {\n return 'p';\n }\n return 'input';\n}\n\ntype InputClassesParams = ValidationProps &\n Pick<InputProps, 'bsSize' | 'placeholder' | 'value' | 'label' | 'validationText' | 'normalized'> & {\n isFocused: boolean;\n inputPassword?: boolean;\n formControlClass?: string;\n validationTextControlClass?: string;\n originalWrapperClass: InputProps['wrapperClassName'];\n };\n\nexport function getClasses(\n className: string | undefined,\n type: string,\n {\n isFocused,\n valid,\n bsSize,\n placeholder,\n value,\n label,\n validationText,\n normalized,\n inputPassword,\n formControlClass,\n validationTextControlClass,\n originalWrapperClass\n }: InputClassesParams,\n cssModule?: CSSModule\n) {\n const hasPlainCondition = placeholder || label || validationText;\n const baseCondition = hasPlainCondition && !normalized && !inputPassword;\n const passwordOnlyCondition = inputPassword && !hasPlainCondition && !normalized;\n const normalizedOnlyCondition = normalized && !hasPlainCondition && !inputPassword;\n\n const classes = mapToCssModules(\n classNames(\n className,\n {\n 'is-invalid': valid == false,\n 'just-validate-success-field': valid,\n [`form-control-${bsSize}`]: bsSize\n },\n formControlClass\n ),\n cssModule\n );\n const wrapperClass = mapToCssModules(classNames(originalWrapperClass, 'form-group'), cssModule);\n const validationTextClass = mapToCssModules(\n classNames(\n {\n 'valid-feedback': valid,\n 'invalid-feedback form-feedback just-validate-error-label': valid == false\n },\n validationTextControlClass\n ),\n cssModule\n );\n\n const inputClasses = mapToCssModules(\n classNames(\n classes,\n !baseCondition && {\n // we can model here only if stylings\n 'form-control-plaintext': normalizedOnlyCondition,\n 'form-control': passwordOnlyCondition,\n 'input-password': passwordOnlyCondition\n }\n ),\n cssModule\n );\n\n const activeClass = mapToCssModules(\n classNames({\n active: isFocused || placeholder || value || ['date', 'time'].includes(type)\n }),\n cssModule\n );\n\n const extraLabelClass = mapToCssModules(\n classNames({\n 'input-number-label': ['number', 'currency', 'adaptive', 'percentage'].includes(type)\n })\n );\n\n return {\n wrapperClass,\n inputClasses,\n activeClass,\n extraLabelClass,\n validationTextClass\n };\n}\n\nexport function useFocus<T extends HTMLInputElement | HTMLTextAreaElement>({\n onFocus,\n onBlur\n}: {\n onFocus: React.FocusEventHandler<T> | undefined;\n onBlur: React.FocusEventHandler<T> | undefined;\n}) {\n const [isFocused, setFocus] = useState(false);\n\n const toggleFocusLabel = useCallback(\n (e: React.FocusEvent<T>) => {\n setFocus(true);\n onFocus?.(e);\n },\n [onFocus]\n );\n\n const toggleBlurLabel = useCallback(\n (e: React.FocusEvent<T>) => {\n if (e.target.value === '') {\n setFocus(!isFocused);\n }\n onBlur?.(e);\n },\n [isFocused, onBlur]\n );\n\n return { toggleFocusLabel, toggleBlurLabel, isFocused };\n}\n","export const noop = () => {};\n\nexport const logError = (message: string) => {\n if (typeof console !== 'undefined') {\n if (console.error) {\n console.error(message);\n } else {\n console.log(message);\n }\n }\n};\n\n// @internal Used for testing purposes only\nexport const flushMessageCache = () => {\n for (const key in messages) {\n delete messages[key];\n }\n};\n\nconst messages: Record<string, 1> = {};\nexport const notifyDeprecation = (message: string, options: { once: boolean } = { once: true }) => {\n if (!options.once) {\n logError(message);\n } else {\n if (!messages[message]) {\n logError(message);\n messages[message] = 1;\n }\n }\n};\n\nexport function mapToCssModules(className: string | null, cssModules?: Record<string, string>) {\n const finalClassNames = className == null ? '' : className;\n if (!cssModules) {\n return finalClassNames;\n }\n return finalClassNames\n .split(' ')\n .map((klass) => cssModules[klass] ?? klass)\n .join(' ');\n}\n\ntype UnknownObject = Record<string, unknown>;\n\nexport function pick<T extends UnknownObject>(obj: T, keys: keyof T | Array<keyof T>): Partial<T> {\n const keysArray = Array.isArray(keys) ? keys : [keys];\n const newObj: Partial<T> = {};\n for (const key of keysArray) {\n if (key in obj) {\n newObj[key] = obj[key];\n }\n }\n return newObj;\n}\n\nexport function omit<T extends UnknownObject>(obj: T, keys: keyof T | Array<keyof T>): Partial<T> {\n const keysLookup = new Set(Array.isArray(keys) ? keys : [keys]);\n\n const newObj: Partial<T> = {};\n for (const key in obj) {\n if (!keysLookup.has(key)) {\n newObj[key] = obj[key];\n }\n }\n return newObj;\n}\n"],"mappings":"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","names":["TextArea_exports","__export","TextArea","__toCommonJS","import_react","import_react","InputContainer","id","infoId","infoText","testId","activeClass","extraLabelClass","label","validationTextClass","validationText","wrapperClass","hasButtonRight","buttonRight","hasIconLeft","iconLeft","children","React","import_classnames","import_react","mapToCssModules","className","cssModules","finalClassNames","klass","getFormControlClassInternal","plaintext","staticInput","type","normalized","formControlClass","getFormControlClass","props","cssModule","mapToCssModules","getValidationTextControlClass","valid","classNames","getClasses","className","type","isFocused","valid","bsSize","placeholder","value","label","validationText","normalized","inputPassword","formControlClass","validationTextControlClass","originalWrapperClass","cssModule","hasPlainCondition","baseCondition","passwordOnlyCondition","normalizedOnlyCondition","classes","mapToCssModules","classNames","wrapperClass","validationTextClass","inputClasses","activeClass","extraLabelClass","useFocus","onFocus","onBlur","setFocus","toggleFocusLabel","e","toggleBlurLabel","TextArea","id","className","cssModule","innerRef","label","validationText","infoText","placeholder","normalized","value","originalWrapperClass","valid","testId","attributes","toggleFocusLabel","toggleBlurLabel","isFocused","useFocus","validationTextControlClass","getValidationTextControlClass","extraAttributes","formControlClass","getFormControlClass","infoId","activeClass","extraLabelClass","validationTextClass","inputClasses","wrapperClass","getClasses","sharedAttributes","containerProps","React","InputContainer"]}