components.widgets.Form.fields.StandardField.StandardField.jsx Maven / Gradle / Ivy
The newest version!
import React, { useContext } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import omit from 'lodash/omit'
import get from 'lodash/get'
import has from 'lodash/has'
import { EventHandlersContext } from '@i-novus/n2o-components/lib/inputs/eventHandlersContext'
import Toolbar from '../../../../buttons/Toolbar'
import { Spinner } from '../../../../snippets/Spinner/Spinner'
import { useResolved } from '../../../../../core/Expression/useResolver'
import Control from './Control'
import Label from './Label'
import Measure from './Measure'
import Description from './Description'
import FieldActions from './FieldActions'
import { FieldActionsPropTypes } from './FieldPropTypes'
/**
* Компонент - поле формы
* @reactProps {string} id - уникальный идентификатор поля
* @reactProps {boolean} visible - отображать / не отображать Поле
* @reactProps {string} label - лэйбл поля
* @reactProps {string} labelClass - css-класс для лейбела
* @reactProps {string} controlClass - css-класс для контрола
* @reactProps {object} labelStyle- объект стилей для лейбела
* @reactProps {object} controlStyle - объект стилей для контрола
* @reactProps {string} className - css-класс для поля
* @reactProps {boolean} required - обязательное / необязательное поле
* @reactProps {boolean} disabled - контрол доступен только для чтения / нет
* @reactProps {boolean} enabled - контрол активирован / нет
* @reactProps {string|element} control - строка с названием компонента (тем, которое указано в мэпе index.tsx) или элемент
* @reactProps {string} description - описание поля (находится под контролом)
* @reactProps {string} measure - единица измерения, находится после контрола (например, км, кг, л)
* @reactProps {object} style - объект с css-стилями для поля
* @reactProps {object} fieldActions - объект для создания экшенов, связанных с полем
* @reactProps {function} onChange - вызывается при изменении контрола
* @reactProps {boolean} loading - показывать лоадер(спиннер) или нет
* @reactProps {boolean} autofocus - есть автофокус на это поле или нет
* @reactProps {string} validationClass - css-класс валидации(has-error, has-warning или has-success)
* @reactProps {object} message - содержит поле text c текстом сообщения(ошибки)
* @reactProps {string|node} help - подскзка рядом с лейблом
* @example
*
*/
function StandardField({
id,
value,
visible,
label,
control,
description,
measure,
required,
className,
labelPosition,
labelAlignment,
labelWidth,
style,
fieldActions,
loading,
autoFocus,
labelStyle,
labelClass,
validationClass,
onChange,
onFocus,
onBlur,
placeholder,
touched,
message,
colLength,
help,
toolbar,
form,
noLabel: propsNoLabel,
noLabelBlock: propsNoLabelBlock,
model,
...rest
}) {
const eventHandlerContext = useContext(EventHandlersContext)
const {
noLabelBlock = false,
noLabel = false,
} = useResolved({ noLabelBlock: propsNoLabelBlock, noLabel: propsNoLabel }, model)
if (!visible) {
return null
}
const validationMap = {
'is-valid': 'text-success',
'is-invalid': 'text-danger',
'has-warning': 'text-warning',
}
const getLabelWidthPixels = (labelWidth) => {
switch (labelWidth) {
case 'default':
return 180
case 'min' || '100%':
return undefined
default:
return labelWidth
}
}
const labelWidthPixels = getLabelWidthPixels(labelWidth)
const styleHelper = labelWidthPixels && colLength > 1
? {
maxWidth: `calc(100% - ${labelWidthPixels})`,
}
: { width: '100%' }
const extendedLabelStyle = {
width: labelWidthPixels,
flex: labelWidthPixels ? 'none' : undefined,
...labelStyle,
}
const fieldId = `field-${rest.form}-id`
return (
{!noLabelBlock && (
)}
{toolbar && (
)}
{loading && (
)}
{touched && message && message.text}
)
}
StandardField.propTypes = {
label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
control: PropTypes.oneOfType([
PropTypes.func,
PropTypes.node,
PropTypes.string,
PropTypes.object,
]),
visible: PropTypes.bool,
required: PropTypes.bool,
disabled: PropTypes.bool,
autoFocus: PropTypes.bool,
onChange: PropTypes.func,
description: PropTypes.string,
measure: PropTypes.string,
className: PropTypes.string,
style: PropTypes.object,
fieldActions: FieldActionsPropTypes,
valiastionClass: PropTypes.string,
loading: PropTypes.bool,
touched: PropTypes.bool,
labelWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
labelAlignment: PropTypes.oneOf(['left', 'right']),
labelPosition: PropTypes.oneOf(['top-left', 'top-right', 'left', 'right']),
message: PropTypes.object,
help: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
id: PropTypes.string,
labelStyle: PropTypes.object,
controlStyle: PropTypes.object,
labelClass: PropTypes.string,
validationClass: PropTypes.oneOfType([PropTypes.string, PropTypes.oneOf([false])]),
controlClass: PropTypes.string,
enabled: PropTypes.bool,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
placeholder: PropTypes.string,
toolbar: PropTypes.array,
colLength: PropTypes.number,
containerKey: PropTypes.string,
dataProvider: PropTypes.object,
form: PropTypes.string,
noLabelBlock: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
noLabel: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
value: PropTypes.any,
}
StandardField.defaultProps = {
visible: true,
required: false,
control: ,
loading: false,
className: '',
style: {},
enabled: true,
disabled: false,
onChange: () => {},
}
export default StandardField