import React, { useRef, useLayoutEffect } from 'react'; import { createControllerBox, Schema } from '@formily/react-schema-renderer'; import { IFormTextBox } from '../types'; import { toArr } from '@formily/shared'; import { FormItemProps as ItemProps } from 'antd/lib/form'; import { version } from 'antd'; import { AntdSchemaFieldAdaptor, pickFormItemProps } from '@formily/antd'; import styled from 'styled-components'; const isV4 = /^4\./.test(version); export const FormTextBox = createControllerBox( 'text-box', styled(({ props, form, className, children }) => { const schema = new Schema(props); const mergeProps = schema.getExtendsComponentProps(); const { title, label, text, gutter, style } = Object.assign( { gutter: 5, }, mergeProps, ); const formItemProps = pickFormItemProps(mergeProps); const ref: React.RefObject = useRef(); const arrChildren = toArr(children); const split = text.split('%s'); let index = 0; useLayoutEffect(() => { if (ref.current) { const elements = ref.current.querySelectorAll('.text-box-field'); const syncLayouts = Array.prototype.map.call( elements, (el: HTMLElement) => { return [ el, () => { const ctrl = el.querySelector('.ant-form-item-children'); setTimeout(() => { if (ctrl) { const editable = form.getFormState(state => state.editable); el.style.width = editable ? ctrl.getBoundingClientRect().width + 'px' : 'auto'; } }); }, ]; }, ); syncLayouts.forEach(([el, handler]) => { handler(); el.addEventListener('DOMSubtreeModified', handler); }); return () => { syncLayouts.forEach(([el, handler]) => { el.removeEventListener('DOMSubtreeModified', handler); }); }; } }, []); const newChildren = split.reduce((buf, item, key) => { return buf.concat( item ? (

{item}

) : null, arrChildren[key] ? (
{arrChildren[key]}
) : null, ); }, []); const textChildren = (
{newChildren}
); if (!title && !label) return textChildren; return ( {textChildren} ); })` display: flex; .text-box-words:nth-child(1) { margin-left: 0; } .text-box-words { margin-bottom: 0 !important; ${isV4 ? 'line-height:32px' : ''} } .text-box-field { display: inline-block; .ant-form-item { margin-bottom: 0 !important; } } .next-form-item { margin-bottom: 0 !important; } .preview-text { text-align: center !important; } `, ); export default FormTextBox;