import { isFn, lowercase, reduce, each, deprecate, log } from '@formily/shared' import { ComponentWithStyleComponent, ISchemaFieldWrapper, ISchemaFormRegistry, ISchemaFieldComponent, ISchemaFieldComponentProps, ISchemaVirtualFieldComponentProps } from '../types' import pascalCase from 'pascal-case' const registry: ISchemaFormRegistry = { fields: {}, virtualFields: {}, wrappers: [], formItemComponent: ({ children }) => children, formComponent: 'form', previewText: null } export const getRegistry = () => { return { fields: registry.fields, virtualFields: registry.virtualFields, formItemComponent: registry.formItemComponent, formComponent: registry.formComponent, previewText: registry.previewText } } export const cleanRegistry = () => { registry.fields = {} registry.virtualFields = {} registry.wrappers = [] registry.previewText = null } export function registerFormComponent( component: React.JSXElementConstructor ) { if (isFn(component)) { registry.formComponent = component } } function compose(payload: T, args: P[], revert: boolean) { return reduce( args, (buf: T, fn: P) => { return isFn(fn) ? fn(buf) : buf }, payload, revert ) } export function registerFormField( name: string, component: ComponentWithStyleComponent, noWrapper: boolean = false ) { if ( name && (isFn(component) || typeof component.styledComponentId === 'string') ) { name = lowercase(name) if (registry.fields[name]) { log.warn( 'Component registration naming conflict. Please change the name. Globally registered components will no longer support overlay registration in the future.' ) } if (noWrapper) { registry.fields[name] = component registry.fields[name].__WRAPPERS__ = [] } else { registry.fields[name] = compose(component, registry.wrappers, true) registry.fields[name].__WRAPPERS__ = registry.wrappers } registry.fields[name].displayName = pascalCase(name) } } export function registerFormFields(object: ISchemaFormRegistry['fields']) { each( object, (component, key) => { registerFormField(key, component) } ) } export function registerVirtualBox( name: string, component: ComponentWithStyleComponent ) { if ( name && (isFn(component) || typeof component.styledComponentId === 'string') ) { name = lowercase(name) registry.virtualFields[name] = component registry.virtualFields[name].displayName = pascalCase(name) } } export function registerFormItemComponent( component: React.JSXElementConstructor ) { if (isFn(component)) { registry.formItemComponent = component } } type FieldMiddleware = ISchemaFieldWrapper export const registerFieldMiddleware = deprecate< FieldMiddleware, FieldMiddleware, FieldMiddleware >(function registerFieldMiddleware( ...wrappers: ISchemaFieldWrapper[] ) { registry.wrappers = registry.wrappers.concat(wrappers) each( registry.fields, (component, key) => { if ( !component.__WRAPPERS__.some(wrapper => wrappers.indexOf(wrapper) > -1) ) { registry.fields[key] = compose(registry.fields[key], wrappers, true) registry.fields[key].__WRAPPERS__ = wrappers } } ) }) export function registerPreviewTextComponent( component: React.JSXElementConstructor ) { if (isFn(component)) { registry.previewText = component } }