UNPKG

@react-ui-org/react-ui

Version:

React UI is a themeable UI library for React apps.

112 lines (96 loc) 2.93 kB
import PropTypes from 'prop-types'; import React, { useMemo } from 'react'; import { withGlobalProps } from '../../providers/globalProps'; import { classNames } from '../../helpers/classNames/classNames'; import { transferProps } from '../../helpers/transferProps'; import { isChildrenEmpty } from '../../helpers/isChildrenEmpty/isChildrenEmpty'; import { FormLayoutContext } from './FormLayoutContext'; import styles from './FormLayout.module.scss'; const PREDEFINED_LABEL_WIDTH_VALUES = ['auto', 'default', 'limited']; export const FormLayout = ({ autoWidth, children, fieldLayout, labelWidth, ...restProps }) => { const childProps = useMemo(() => ({ layout: fieldLayout }), [fieldLayout]); if (isChildrenEmpty(children)) { return null; } const hasCustomLabelWidth = !PREDEFINED_LABEL_WIDTH_VALUES.includes(labelWidth); const fieldLayoutClass = (layout) => { if (layout === 'horizontal') { return styles.isRootFieldLayoutHorizontal; } return styles.isRootFieldLayoutVertical; }; const labelWidthClass = (width) => { if (hasCustomLabelWidth) { return styles.hasRootLabelWidthCustom; } if (width === 'auto') { return styles.hasRootLabelWidthAuto; } if (width === 'limited') { return styles.hasRootLabelWidthLimited; } return styles.hasRootLabelWidthDefault; }; return ( <div {...transferProps(restProps)} className={classNames( styles.root, fieldLayoutClass(fieldLayout), autoWidth && styles.isRootAutoWidth, fieldLayout === 'horizontal' && labelWidthClass(labelWidth), )} {...hasCustomLabelWidth ? { style: { '--rui-custom-label-width': labelWidth } } : {}} > <FormLayoutContext.Provider value={childProps}> {children} </FormLayoutContext.Provider> </div> ); }; FormLayout.defaultProps = { autoWidth: false, children: null, fieldLayout: 'vertical', labelWidth: 'default', }; FormLayout.propTypes = { /** * If `true`, FormLayout will take up only as much horizontal space as necessary. */ autoWidth: PropTypes.bool, /** * Supported form field components: * * `CheckboxField` * * `FileInputField` * * `FormLayoutCustomField` * * `Radio` * * `SelectField` * * `TextArea` * * `TextField` * * `Toggle` * * If none are provided nothing is rendered. */ children: PropTypes.node, /** * Layout that is forced on children form fields. */ fieldLayout: PropTypes.oneOf(['horizontal', 'vertical']), /** * Width of the column with form field labels. Only available if the `fieldLayout` is set to * `horizontal`. */ labelWidth: PropTypes.oneOfType([ PropTypes.oneOf(PREDEFINED_LABEL_WIDTH_VALUES), PropTypes.string, ]), }; export const FormLayoutWithGlobalProps = withGlobalProps(FormLayout, 'FormLayout'); export default FormLayoutWithGlobalProps;