import React, { createContext, useContext } from 'react' import { isArr, isValid } from '@formily/shared' import { observer, useField } from '@formily/react' import { InputProps } from 'antd/lib/input' import { InputNumberProps } from 'antd/lib/input-number' import { SelectProps } from 'antd/lib/select' import { TreeSelectProps } from 'antd/lib/tree-select' import { CascaderProps } from 'antd/lib/cascader' import { DatePickerProps, RangePickerProps as DateRangePickerProps, } from 'antd/lib/date-picker' import { TimePickerProps, TimeRangePickerProps } from 'antd/lib/time-picker' import { Tag, Space, Popover } from 'antd' import cls from 'classnames' import { formatMomentValue, usePrefixCls } from '@formily/antd/esm/__builtins__' import { FullscreenOutlined } from '@ant-design/icons'; const PlaceholderContext = createContext('N/A') const Placeholder = PlaceholderContext.Provider const usePlaceholder = (value?: any) => { const placeholder = useContext(PlaceholderContext) || 'N/A' return isValid(value) && value !== '' ? value : placeholder } const Input: React.FC = (props) => { const prefixCls = usePrefixCls('description-text', props) return ( {props.addonBefore} {props.prefix} {usePlaceholder(props.value)} {props.suffix} {props.addonAfter} ) } const URL: React.FC = (props) => { const prefixCls = usePrefixCls('description-text', props) const content = props.value && ( {props.value} ) return ( {props.addonBefore} {props.prefix} {content} {props.suffix} {props.addonAfter} ) } const InputNumber: React.FC = (props) => { const prefixCls = usePrefixCls('description-text', props) const value = usePlaceholder(props.value); return ( {props.addonBefore} {props.prefix} {props.formatter ? props.formatter(value) : value} {props.suffix} {props.addonAfter} ) } const TextArea: React.FC = (props) => { const prefixCls = usePrefixCls('description-text', props) const ellipsis = props.ellipsis === true ? {} : props.ellipsis; const content = props.ellipsis ? (
{usePlaceholder(props.text||props.value)}
) : usePlaceholder(props.value) return ( {props.addonBefore} {props.prefix} {content} {props.suffix} {props.addonAfter} ) } const Select: React.FC> = observer((props) => { const field = useField() const prefixCls = usePrefixCls('description-text', props) const dataSource: any[] = field?.dataSource?.length ? field.dataSource : props?.options?.length ? props.options : [] const placeholder = usePlaceholder() const getSelected = () => { const value = props.value if (props.mode === 'multiple' || props.mode === 'tags') { if (props.labelInValue) { return isArr(value) ? value : [] } else { return isArr(value) ? value.map((val) => ({ label: val, value: val })) : [] } } else { if (props.labelInValue) { return isValid(value) ? [value] : [] } else { return isValid(value) ? [{ label: value, value }] : [] } } } const getLabels = () => { const selected = getSelected() if (!selected.length) return {placeholder} return selected.map(({ value, label }, key) => { const text = dataSource?.find((item) => item.value == value)?.label || label return {text || placeholder} }) } return (
{getLabels()}
) }) const ObjectSelect: React.FC> = observer((props) => { const field = useField() const prefixCls = usePrefixCls('description-text', props) const dataSource: any[] = field?.dataSource?.length ? field.dataSource : props?.options?.length ? props.options : [] const placeholder = usePlaceholder() const getSelected = () => { const value = props.value if (props.mode === 'multiple' || props.mode === 'tags') { if (props.labelInValue) { return isArr(value) ? value : [] } else { return isArr(value) ? value.map((val) => ({ label: val, value: val })) : [] } } else { if (props.labelInValue) { return isValid(value) ? [value] : [] } else { return isValid(value) ? [{ label: value, value }] : [] } } } const getLabels = () => { const selected = getSelected() if (!selected.length) return {placeholder} return selected.map(({ value, label }, key) => { const text = dataSource?.find((item) => item.value == value)?.label || label return {text || placeholder} }) } return (
{getLabels()}
) }) const TreeSelect: React.FC> = observer((props) => { const field = useField() const placeholder = usePlaceholder() const prefixCls = usePrefixCls('description-text', props) const dataSource = field?.dataSource?.length ? field.dataSource : props?.options?.length ? props.options : [] const getSelected = () => { const value = props.value if (props.multiple) { if (props.labelInValue) { return isArr(value) ? value : [] } else { return isArr(value) ? value.map((val) => ({ label: val, value: val })) : [] } } else { if (props.labelInValue) { return value ? [value] : [] } else { return value ? [{ label: value, value }] : [] } } } const findLabel = (value: any, dataSource: any[]) => { for (let i = 0; i < dataSource?.length; i++) { const item = dataSource[i] if (item?.value === value) { return item?.label } else { const childLabel = findLabel(value, item?.children) if (childLabel) return childLabel } } } const getLabels = () => { const selected = getSelected() if (!selected?.length) return {placeholder} return selected.map(({ value, label }, key) => { return ( {findLabel(value, dataSource) || label || placeholder} ) }) } return (
{getLabels()}
) }) const Cascader: React.FC = observer((props) => { const field = useField() const placeholder = usePlaceholder() const prefixCls = usePrefixCls('description-text', props) const dataSource: any[] = field?.dataSource?.length ? field.dataSource : props?.options?.length ? props.options : [] const getSelected = () => { return isArr(props.value) ? props.value : [] } const findLabel = (value: any, dataSource: any[]) => { for (let i = 0; i < dataSource?.length; i++) { const item = dataSource[i] if (item?.value === value) { return item?.label } else { const childLabel = findLabel(value, item?.children) if (childLabel) return childLabel } } } const getLabels = () => { const selected = getSelected() if (!selected?.length) { return placeholder } return selected .map((value) => { return findLabel(value, dataSource) || placeholder }) .join('/') } return (
{getLabels()}
) }) const DatePicker: React.FC = (props) => { const placeholder = usePlaceholder() const prefixCls = usePrefixCls('description-text', props) const getLabels = () => { const labels = formatMomentValue(props.value, props.format, placeholder) return isArr(labels) ? labels.join('~') : labels } return
{getLabels()}
} const DateRangePicker: React.FC = (props) => { const placeholder = usePlaceholder() const prefixCls = usePrefixCls('description-text', props) const getLabels = () => { const labels = formatMomentValue(props.value, props.format, placeholder) return isArr(labels) ? labels.join('~') : labels } return (
{getLabels()}
) } const TimePicker: React.FC = (props) => { const placeholder = usePlaceholder() const prefixCls = usePrefixCls('description-text', props) const getLabels = () => { const labels = formatMomentValue(props.value, props.format, placeholder) return isArr(labels) ? labels.join('~') : labels } return (
{getLabels()}
) } const TimeRangePicker: React.FC = (props) => { const placeholder = usePlaceholder() const prefixCls = usePrefixCls('description-text', props) const getLabels = () => { const labels = formatMomentValue(props.value, props.format, placeholder) return isArr(labels) ? labels.join('~') : labels } return (
{getLabels()}
) } export const Display = { Input, URL, TextArea, Select, ObjectSelect, TreeSelect, Cascader, DatePicker, DateRangePicker, TimePicker, TimeRangePicker, Placeholder, InputNumber, usePlaceholder, } export default Display;