All Downloads are FREE. Search and download functionalities are using the official Maven repository.

components.widgets.Form.fields.RangeField.RangeField.jsx Maven / Gradle / Ivy

The newest version!
import React, { useMemo } from 'react'
import PropTypes from 'prop-types'
import { compose, withHandlers, mapProps } from 'recompose'
import get from 'lodash/get'
import classNames from 'classnames'
import { omit } from 'lodash'

import Control from '../StandardField/Control'
import Measure from '../StandardField/Measure'
import Label from '../StandardField/Label'
import FieldActions from '../StandardField/FieldActions'
import InlineSpinner from '../../../../snippets/Spinner/InlineSpinner'
import Description from '../StandardField/Description'
import { FieldActionsPropTypes } from '../StandardField/FieldPropTypes'

/**
 * Компонент - RangeField формы
 * @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 - подскзка рядом с лейблом
 * @reactProps {string|boolean} - разделитель между полями
 * @return {node|null}
 * @example
 * 
 */
export function RangeFieldComponent({
    beginControl,
    endControl,
    id,
    visible,
    label,
    description,
    measure,
    required,
    className,
    labelPosition,
    labelAlignment,
    labelWidth,
    style,
    fieldActions,
    loading,
    autoFocus,
    labelStyle,
    labelClass,
    validationClass,
    onFocus,
    onBlur,
    placeholder,
    touched,
    message,
    help,
    onBeginValueChange,
    onEndValueChange,
    begin,
    end,
    divider,
    ...props
}) {
    const omited = omit(props, ['control', 'controlClass', 'value', 'onChange', 'controlStyle'])
    const validationMap = {
        'is-valid': 'text-success',
        'is-invalid': 'text-danger',
        'has-warning': 'text-warning',
    }

    const labelWidthPixels = useMemo(() => {
        switch (labelWidth) {
            case 'default':
                return 180
            case 'min' || '100%':
                return undefined
            default:
                return labelWidth
        }
    }, [labelWidth])

    const extendedLabelStyle = {
        width: labelWidthPixels,
        flex: labelWidthPixels ? 'none' : undefined,
        ...labelStyle,
    }

    return visible ? (
        
) : null } RangeFieldComponent.propTypes = { label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), control: PropTypes.node, 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]), divider: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]), beginControl: PropTypes.object, endControl: PropTypes.object, id: PropTypes.string, labelStyle: PropTypes.object, controlStyle: PropTypes.object, labelClass: PropTypes.string, validationClass: PropTypes.string, controlClass: PropTypes.string, onFocus: PropTypes.func, onBlur: PropTypes.func, placeholder: PropTypes.string, value: PropTypes.object, onBeginValueChange: PropTypes.func, onEndValueChange: PropTypes.func, begin: PropTypes.oneOf(['string', null]), end: PropTypes.oneOf(['string', null]), enabled: PropTypes.bool, } RangeFieldComponent.defaultProps = { visible: true, required: false, control: , loading: false, className: '', style: {}, enabled: true, disabled: false, onChange: () => {}, divider: false, } const isValid = period => period !== '' export const RangeField = compose( mapProps(props => ({ ...props, begin: get(props, 'value.begin', null), end: get(props, 'value.end', null), })), withHandlers({ onBeginValueChange: ({ end, onChange }) => (begin) => { if (isValid(begin)) { onChange({ begin, end }) } }, onEndValueChange: ({ begin, onChange }) => (end) => { if (isValid(end)) { onChange({ begin, end }) } }, }), )(RangeFieldComponent) export default RangeField




© 2015 - 2024 Weber Informatics LLC | Privacy Policy