npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fx-schema-form-antd

v2.0.0

Published

自动生成表单组件

Readme

react-schema-form-antd

通过json-schema,ui-schema,以及antd自动生成表单组件。前后端可以复用一份JsonSchema来验证字段,错误消息前后端统一,这个可以有。

点击这里查看demo

Note: 组件之间的功能组合使用hoc来实现。

目录

安装

Requires React 15.0.0+.

Note: 当前使用tsc -d来编译,代码为es6代码;

通过npm来安装

$ npm install fx-schema-form-react --save

Note: 当前组件库默认使用了antd的样式,你也可以使用其他样式来代替。

cdn

Note: 暂时没有cdn。

依赖项

  • JsonSchema
  • antd
  • redux
  • higher order component
  • react-redux
  • recompose
  • react-act
  • avj
  • json-pointer

默认使用

import React from "react";
import ReactDom from "react-dom";
import { Card, Button, Form } from "antd";
import { createStore, combineReducers } from "redux";
import { Provider } from "react-redux";

import { SchemaForm, createForms, hocFactory, defaultTheme } from "./index";

const schema = {
    type: "object",
    title: "测试SCHEMA",
    required: [ "name"],
    removeAdditional: true,
    properties: {
        name: { 
            type: "string", 
            title: "昵称", 
            default: "nora", 
            description: "昵称,必填" 
        }
    }
};

let uiSchema: any = ["name"];

const globalOptions = {
    "ui:temp": ["formItem"]
};
let reducer = createForms.createOne("test", {
    name: "nick"
});

let store = createStore<any>(combineReducers({
    test: reducer.reducer
}));

store.subscribe(() => {
    console.log(store.getState());
});

ReactDom.render(
    <Provider store={store}>
        <SchemaForm schemaKey={"test"} schema={schema} RootComponent={Form} uiSchema={uiSchema} globalOptions={globalOptions}>
            <Form.Item labelCol={{ xs: 6, offset: 12 }} wrapperCol={{ xs: 6, offset: 12 }}>
                <Button onClick={() => {
                    reducer.actions.validateAllField.bind(reducer)();

                    if (store.getState().test.meta.data.isValid) {
                        alert("提交表单");
                    }

                }}>提交</Button>
            </Form.Item>
        </SchemaForm>
    </Provider>
    , document.getElementById("root"), console.log);

如果配置正确,会看到如下图效果:

表单定制化

Note: JsonSchema用于定义数据结构以及验证规则; 而表单的展现形式需要手动配置;

uiSchema配置

JsonSchema

const schema = {
    type: "object",
    title: "测试SCHEMA",
    required: [ "geo"],
    removeAdditional: true,
    properties: {
        name: { type: "string", "title": "昵称", "default": "nora", description: "昵称,必填" },
        number: { type: "number", "title": "测试number类型" },
        integer: { type: "integer", "title": "测试integer类型" },
        boolean: { type: "boolean", "title": "测试boolean类型", default: true },
        array: { type: "array", items: { type: "string", "title": "测试array类型ITEM", minLength: 3 }, "title": "测试array类型" },
        object: {
            type: "object",
            title: "测试对象的生成",
            default: {},
            properties: {
                settings: {
                    type: "boolean",
                    title: "测试boolean类型",
                    default: true
                }
            }
        },
        array1: {
            type: "array",
            title: "测试无限极数组类型",
            items: {
                type: "object",
                required: ["test"],
                properties: {
                    test: { type: "string", title: "无限极测试数据", minLength: 3 },
                    children: { $ref: "test#/properties/array1" }
                }
            }
        },
        null: { type: "null", "title": "测试null类型" },
        muti: { type: ["string", "integer", "number"], "title": "测试多类型" },
        geo: {
            type: "object",
            title: "geo position",
            required: ["lou", "lat"],
            properties: {
                lou: {
                    type: "number",
                    minimum: 0,
                    maximum: 100,
                    title: "纬度"
                },
                lat: {
                    type: "number",
                    title: "经度"
                }
            }
        },
    }
};

UiSchema

let uiSchema = ["name", "array", {
     "key": "array1",
     "items": [{ key: "array1/-/test" }, { key: "array1/-/children" }]
 }];
  • 默认字段
    • key:string 用于确定是哪个字段,格式为 */*形式(例如: name; array1/-/test),这里的-代表数组的索引;
    • field:string 用于自定义field组件
    • theme:string 用于自定义的样式
    • widget:string 用于自定义组件
    • items:Array 用于显示子元素
    • ui:temp:Array 用于定义模板
    • ui:item.hoc:Array 用于自定义hoc
    • options:Object  设置项
      • hoc:Object 设置hoc的参数项
      • widget:Object 设置widget的参数,这里的widget需要替换成具体的widget的名称
      • temp:Object 设置模板的配置参数,这里的temp需要替换成具体的temp的名称,可以有多个

Note: 如果直接设置成string类型,自动转换成{key:string}格式。

供选择的表单组件

widget字段最终的展现形式。一个字段一般可以由多个widget来表现。比如一个string字段,可以使用text,textarea,select,radio等来表现,这个取决于个人喜好。

Note: 组件可以自行添加。

input

用于显示文本的组件

select

用于下拉展示的组件

number

用于显示数字的组件

redio

用户展示单选组的组件

模板

模板是包装widget的组件,可以使用多个模板来包装。

  • 默认模板
    • card antd中的Card组件
    • col antd中的col组件
    • formitem antd中的FormItem组件
    • row antd中的Row组件

Note: 模板之间的组合取决于样式库的组件,比如antd中,默认使用FormItem来包装widget。当然也可以使用Card,Row,Col等容器组件。这里FormItem包装了错误信息的显示,你也可以自定一个组件来显示错误信息。数组类型的字段使用默认使用三个模板["row", "col", "card"]

HOCS

HOC用于包装组件,相当于一个装饰器模式;

默认的hoc

  • SchemaForm组件:

    • merge 用于合并JsonSchema和UiSchema。
      1. 使用参数:
        • schema
        • uiSchema
        • schemaKey
        • schemaFormOptions
      2. 注入属性:
        • mergeSchemaList 合并JsonSchema和UiSchema后的数组,SchemaForm遍历这个数组来生成SchemaFormItem组件。
        • schemaFormOptions 合并数据时产生的中间数据。
  • SchemaFormItem组件:

    • make 用于包装hoc的hoc;这里获取uiSchema中ui:item.hoc:Array字段的值,来动态包装hoc。
      1. 注入属性:
        • getHocOptions 获取字段的配置参数的方法。
    • array 用于处理数组类型的hoc。
      1. 注入属性:
        • arrayItems 数组中的操作按钮,添加,显示/隐藏等。
        • createItemChildButtons 数组子元素的操作按钮,删除,上下排序等。
    • field 用于判断当前字段的Field组件和Widget组件。
      1. 使用参数:
        • currentTheme 当前的样式;通过ThemeHoc注入;
        • mergeSchema 合并后的字段配置;通过SchemaForm调用SchemaFormItem后注入
      2. 注入属性:
        • FieldComponent Field组件
        • WidgetComponent Widget组件
    • temp 用于创建模板的hoc,使用UiSchema中的ui:temp字段。
      1. 注入属性:
        • uiSchemaOptions 当前字段UiSchema中的的options配置
        • globalOptions 全局参数到temp
        • tempKey 模板的名称到temp
    • theme 用于调用当前使用的样式,使用UiSchema中的theme字段。
      1. 注入属性:
        • currentTheme 当前使用的样式。
    • validate 用于验证字段的合法性,传递validate方法到组件。
      1. 输入属性:
        • validate 验证方法。
        • updateItemData 更新值方法。
  • 组件使用hoc情况

    • SchemaForm
      • merge
    • SchemaFormItem
      • make

Note: SchemaFormItem中使用make来动态包装Hoc;这里的Hoc顺序:ThemeHoc -> FieldHoc -> ValidateHoc -> ArrayHoc -> TempHoc;这个顺序不能改变,但是每个hoc之间可以插入新的hoc。

字段

字段组件用于确定如何来显示子组件。可以同时设置uiSchema中的field值来指定。默认使用JsonSchema中的type来确定使用的字段类型。

  • 默认字段
    • array 显示数组类型的字段;遍历数组元素,嵌套一层SchemaForm,并且传递arrayIndex数组索引字段。
    • normal 显示普通类型的字段;直接展示widget组件
    • object 显示对象类型的字段;嵌套一层SchemaForm

高级配置

自定义hoc

如果默认的hoc功能不够用,可以自定义hoc来扩展SchemaFormItem组件。 比如需要一个显示/隐藏的功能:


import React from "react";
import { compose } from "recompose";
import { BaseFactory } from "fx-schema-form-core";
import jpp from "json-pointer";

import { ThemeHocOutProps } from "./theme";
import { MakeHocOutProps } from "./make";
import { RC } from "../../types";
import { SchemaFormItemBaseProps } from "../../components/formitem/props";
import { ValidateHocOutProps } from "./validate";
import { mapMetaStateToProps } from "../select";

export interface ConditionHocOutProps {

}

export interface ConditionSettings {
    fields: Array<{
        key: string,
        val: any
    }>;
}

/**
 * condition hoc
 * 用于组件的显示隐藏
 *  1. 根据hoc设置中的condition字段来配置显示/隐藏的时机
 *  2. 从formData中获取所需的值,与设置的值做对比,如果都匹配,则显示,否则隐藏
 * @param hocFactory  hoc的工厂方法
 * @param Component 需要包装的组件
 */
export const ConditionHoc = (hocFactory: BaseFactory<any>, Component: any): RC<SchemaFormItemBaseProps & MakeHocOutProps, any> => {
    class Hoc extends React.Component<SchemaFormItemBaseProps & MakeHocOutProps, any> {
        private fieldKey = "ui:condition";

        /**
         * render
         */
        public render(): JSX.Element {
            const { getHocOptions, formData, formDefaultData } = this.props;
            const hocOptions = getHocOptions();
            const { condition: conditionHocOptions } = hocOptions;
            const { fields } = conditionHocOptions as ConditionSettings;
            let isShow = true, jFormData = jpp(Object.assign({}, formDefaultData, formData));

            if (fields && fields.length) {
                isShow = fields.reduce((prev: boolean, { key, val }) => {
                    if (!jFormData.has(key)) {
                        return prev && false;
                    } else {
                        let data = jFormData.get(key);

                        return prev && (data === val);
                    }
                }, isShow);
            }

            if (!isShow) {
                return null;
            }

            return <Component {...this.props} />;
        }
    }

    return Hoc;
};

hocFactory.add("condition",ConditionHoc);

设置uiScham的值,当object/settings的值为true的时候,显示name字段;

[{
    "key": "name",
    "ui:item.hoc": ["theme", "field", "validate", "array", "condition", "temp"],
    "options": {
        "hoc": {
            "condition": {
                "fields": [{ "key": "/object/settings", "val": true }]
            }
        }
    }
}, "object/settings"];

自定义字段

自定义模板

自定义组件

License

Apache 2