1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-02 06:07:06 +01:00
metamask-extension/ui/components/ui/form-field/form-field.js
Harsh Shukla 7b323b8a30
Part of #17670: Replace Typography with Text component for 11 files. (#18837)
* Part of #17670: Replace Typography with Text component for 10 files.

* Update radio-group.component.js

* Update create-password.test.js.snap

* Update custom-spending-cap.test.js.snap

* Update add-network-modal.test.js.snap

* Update recovery-phrase-reminder.js
2023-04-28 16:18:46 -07:00

300 lines
7.9 KiB
JavaScript

import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Box from '../box/box';
import {
TextAlign,
DISPLAY,
TextVariant,
AlignItems,
TextColor,
} from '../../../helpers/constants/design-system';
import NumericInput from '../numeric-input/numeric-input.component';
import InfoTooltip from '../info-tooltip/info-tooltip';
import { Text } from '../../component-library';
export default function FormField({
dataTestId,
titleText = '',
TitleTextCustomComponent,
titleUnit = '',
TitleUnitCustomComponent,
tooltipText = '',
TooltipCustomComponent,
titleDetail = '',
titleDetailWrapperProps,
titleHeadingWrapperProps,
error,
onChange = undefined,
value = 0,
numeric,
detailText = '',
autoFocus = false,
password = false,
allowDecimals = false,
disabled = false,
placeholder,
warning,
passwordStrength,
passwordStrengthText,
id,
inputProps,
wrappingLabelProps,
inputRef,
}) {
return (
<div
className={classNames('form-field', {
'form-field__row--error': error,
})}
>
<Box as="label" {...wrappingLabelProps}>
<div className="form-field__heading">
<Box
className="form-field__heading-title"
display={DISPLAY.FLEX}
alignItems={AlignItems.baseline}
{...titleHeadingWrapperProps}
>
{TitleTextCustomComponent ||
(titleText && (
<Text
tag="label"
htmlFor={id}
html
variant={TextVariant.bodySmBold}
as="h6"
display={DISPLAY.INLINE_BLOCK}
>
{titleText}
</Text>
))}
{TitleUnitCustomComponent ||
(titleUnit && (
<Text
tag={TextVariant.bodySm}
variant={TextVariant.bodySm}
as="h6"
color={TextColor.textAlternative}
display={DISPLAY.INLINE_BLOCK}
>
{titleUnit}
</Text>
))}
{TooltipCustomComponent ||
(tooltipText && (
<InfoTooltip position="top" contentText={tooltipText} />
))}
</Box>
{titleDetail && (
<Box
className="form-field__heading-detail"
textAlign={TextAlign.End}
marginRight={2}
{...titleDetailWrapperProps}
>
{titleDetail}
</Box>
)}
</div>
{numeric ? (
<NumericInput
error={error}
onChange={onChange}
value={value}
detailText={detailText}
autoFocus={autoFocus}
allowDecimals={allowDecimals}
disabled={disabled}
dataTestId={dataTestId}
placeholder={placeholder}
id={id}
inputRef={inputRef}
/>
) : (
<input
className={classNames('form-field__input', {
'form-field__input--error': error,
'form-field__input--warning': warning,
})}
onChange={(e) => onChange(e.target.value)}
value={value}
type={password ? 'password' : 'text'}
autoFocus={autoFocus}
disabled={disabled}
data-testid={dataTestId}
placeholder={placeholder}
id={id}
ref={inputRef}
{...inputProps}
/>
)}
{error && (
<Text
color={TextColor.errorDefault}
variant={TextVariant.bodySm}
as="h6"
className="form-field__error"
>
{error}
</Text>
)}
{warning && (
<Text
color={TextColor.textAlternative}
variant={TextVariant.bodySm}
as="h6"
className="form-field__warning"
>
{warning}
</Text>
)}
{passwordStrength && (
<Text
color={TextColor.textDefault}
variant={TextVariant.bodySm}
as="h6"
className="form-field__password-strength"
>
{passwordStrength}
</Text>
)}
{passwordStrengthText && (
<Text
color={TextColor.textAlternative}
variant={TextVariant.bodyXs}
as="h6"
className="form-field__password-strength-text"
>
{passwordStrengthText}
</Text>
)}
</Box>
</div>
);
}
FormField.propTypes = {
/**
* Identifier for testing purpose
*/
dataTestId: PropTypes.string,
/**
* Form Fields Title
*/
titleText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
/**
* A custom component to replace the title text Typography component
* titleText will be ignored if this is provided
*/
TitleTextCustomComponent: PropTypes.node,
/**
* Show unit (eg. ETH)
*/
titleUnit: PropTypes.string,
/**
* A custom component to replace the title unit Typography component
* titleUnit will be ignored if this is provided
*/
TitleUnitCustomComponent: PropTypes.node,
/**
* Add Tooltip and text content
*/
tooltipText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
/**
* A custom component to replace the tooltip component
* tooltipText will be ignored if this is provided
*/
TooltipCustomComponent: PropTypes.node,
/**
* Show content (text, image, component) in title
*/
titleDetail: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
/**
* Props to pass to wrapping Box component of the titleDetail component
* Accepts all props of the Box component
*/
titleDetailWrapperProps: PropTypes.shape({
...Box.propTypes,
}),
/**
* Props to pass to wrapping Box component of the titleHeading component
* Accepts all props of the Box component
*/
titleHeadingWrapperProps: PropTypes.shape({
...Box.propTypes,
}),
/**
* Show error message
*/
error: PropTypes.string,
/**
* Show warning message
*/
warning: PropTypes.string,
/**
* Handler when fields change
*/
onChange: PropTypes.func,
/**
* Field value
*/
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
/**
* Show detail text if field mode is numeric
*/
detailText: PropTypes.string,
/**
* Set autofocus on render
*/
autoFocus: PropTypes.bool,
/**
* Set numeric mode, the default is text
*/
numeric: PropTypes.bool,
/**
* Set password mode
*/
password: PropTypes.bool,
/**
* Allow decimals on the field
*/
allowDecimals: PropTypes.bool,
/**
* Check if the form disabled
*/
disabled: PropTypes.bool,
/**
* Set the placeholder text for the input field
*/
placeholder: PropTypes.string,
/**
* Show password strength according to the score
*/
passwordStrength: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
/**
* Show password strength description
*/
passwordStrengthText: PropTypes.string,
/**
* The id of the input element. Should be used when the wrapping label is changed to a div to ensure accessibility.
*/
id: PropTypes.string,
/**
* Any additional input attributes or overrides not provided by exposed props
*/
inputProps: PropTypes.object,
/**
* The FormField is wrapped in a Box component that is rendered as a <label/> using the polymorphic "as" prop.
* This object allows you to override the rendering of the label by using the wrapperProps={{ as: 'div' }} prop.
* If used ensure the id prop is set on the input and a label element is present using htmlFor with the same id to ensure accessibility.
*/
wrappingLabelProps: PropTypes.object,
/**
* ref for input component
*/
inputRef: PropTypes.object,
};