Learn about our RFC process, Open RFC meetings & more.Join in the discussion! »

@jimengio/meson-form

0.5.1 • Public • Published

Meson Form

React form component with focus on immer and JSON

Snippets and Preview http://fe.jimu.io/meson-form/ . This library is now based on antd@4.x .

Usage

yarn add @jimengio/meson-form

Define forms JSON-like configs(with functions and enumerables):

let formItems: IMesonFieldItem[] = [
  {
    type: "input",
    name: "name",
    label: "名字",
  },
  {
    type: "input",
    shouldHide: (form) => {
      return form.amount && form.amount > 6;
    },
    label: "单价",
    name: "price",
    required: true,
  },
];

Normal way of rendering a form(with cancel/submit buttons):

import { MesonForm } from "@jimengio/meson-form";
 
<MesonForm
  initialValue={{}}
  items={formItems}
  onSubmit={(form) => {
    console.log("data to submit:", form);
  }}
/>;

Or, only render form fields, and control with your own buttons:

import { useMesonFields } from "@jimengio/meson-form";
 
let fieldsPlugin = useMesonFields({
  initialValue: {},
  items: formItems,
  onSubmit: (form) => {
    console.log("After validation:", form);
  },
});
 
// ReactNode
fieldsPlugin.ui;
 
// trigger submit
fieldsPlugin.checkAndSubmit();
 
// reset form data
fieldsPlugin.resetForm(data);

Modal usages

Used with a modal container:

import { MesonFormModal } from "@jimengio/meson-form";
 
let [formVisible, setFormVisible] = useState(false);
 
<MesonFormModal
  title={lingual.labelShouldBeBoolean}
  visible={formVisible}
  onClose={() => {
    setFormVisible(false);
  }}
  width={800}
  items={formItems}
  initialValue={{}}
  hideClose={false}
  onSubmit={(form) => {
    setFormVisible(false);
    console.log("form", form);
  }}
/>;

Props for MesonFormDrawer and MesonFormDropdown are mostly same as MesonFormModal's.

Field Types

IMesonFieldItem has some types, roughly in 3 kinds:

  • control types:
Type Usage
input renders antd <Input/>
textarea renders antd <TextArea/>
number renders antd <InputNumber/>
select renders antd <Select/>
dropdown-select renders custom select
tree-select renders antd <TreeSelect/>
dropdown-tree renders cursom tree select
radio renders radio groups
switch renders antd <Switch/>
date-picker renders antd <DatePicker/>
  • custom control types:
Type Usage
custom render a custom ReactNode, corresponding to 1 property
custom-multiple render a custom ReactNode, controlling multiple form properties
registered render a user registered renderer, by a name
  • layout types:
Type Usage
group no visual change, just grouping...
decorative any ReactNode, for decoration, no access to form data
nested get fields nested inside a field

Custom type

Custom type provides the chance to render your own field:

{
  type'custom',
  name"size",
  label"自定义",
  render: (value, onChange, form, onCheck) => {
    return (
      <div className={row}>
        <div>
          <Input
            value={value}
            onChange={(event) => {
              let newValue = event.target.value;
              onChange(newValue);
            }}
            onBlur={() => {
              onCheck(value);
            }}
          />
        </div>
      </div>
    );
  },
},

Notice the usages of those methods:

  • onChange: (x: any) => void updates current property in form form data.
  • onCheck: (x: any) => void perform validations on the value, which may cause its error message being displayed.

Explanations on props

关于表单的具体参数:

export let MesonForm: FC<{
  /** 初始值, 后续的更新都在表单内部进行, 包括自定义渲染也是把修改传回到组件内部,
   * 可能会需要通过 key 重置表单, 比如 load 服务端数据回来需要重新初始化的情况
   */
  initialValue: any;
  /** JSON 结构的表单定义, 建议定义变量传过来, 一来定义会比较长, 二来 TS 类型推断在变量加类型的情况才准确 */
  items: IMesonFieldItem[];
  onSubmit: (form: { [k: string]: any }, onServerErrors?: (x: IMesonErrors) => void, transferData?: any) => void;
  onCancel?: () => void;
  className?: string;
  /**
   * items 所在区域容器的样式
   */
  itemsClassName?: string;
  /**
   * label 所在区域容器的样式
   */
  labelClassName?: string;
  /**
   * verification-error-text 所在区域容器的样式
   */
  errorClassName?: string;
  style?: CSSProperties;
  /**
   * Footer 默认提供了几种布局, 但是更可能还是需要直接提供一个渲染方案进行自定义
   */
  footerLayout?: EMesonFooterLayout;
  hideFooter?: boolean;
  /**
   * 控制 Label 是否不显示
   * 但优先级低于 `hideLabel` (IMesonFieldItem)
   */
  noLabel?: boolean;
  /**
   * 每个 item 输入框部分填满余下空间
   */
  fullWidth?: boolean;
  renderFooter?: (isLoading: boolean, onSubmit: () => void, onCancel: () => void) => ReactNode;
  isLoading?: boolean;
  /** 可能用在记录是否有修改的地方. 另外每个 item 上修改值的时候也有各自的 onChange 钩子 */
  onFieldChange?: (name: string, v: any, form: any, modifyForm: FuncMesonModifyForm<any>) => void;
  submitOnEdit?: boolean;
}> = (props) => {
  // Form
};

Workflow

https://github.com/jimengio/ts-workflow

License

MIT

Keywords

none

Install

npm i @jimengio/meson-form

DownloadsWeekly Downloads

280

Version

0.5.1

License

MIT

Unpacked Size

270 kB

Total Files

110

Last publish

Collaborators

  • avatar
  • avatar
  • avatar
  • avatar
  • avatar