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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@jzl/aa-form

v0.0.6

Published

## 起因

Downloads

10

Readme

auto-antd-form

起因

Form 使用双向绑定,开发效率高,代码可读性好。

  1. 双向绑定表达,表达简单直观。支持嵌套字段

  2. 提供 validate 机制,配合 <FormContext><FormButton>, 自动管理相关状态。

  3. 组件使用方式和 antd 一致,几乎没有学习成本,可以直接参考 antd 的文档。

  4. 扩展性强,符合 value,onChange 模式的组件,通过简单的包装,可以快速融入进这套模式中

  5. 性能。每次修改,只有被编辑的那个组件会触发渲染,form 再大,也不会有性能问题。

使用

  1. 首先安装 react react-dom immer -react antd
  2. yarn add @jzl/aa-form
  3. 如果使用 antd 的按需加载,为了样式生效,需要在 webpack 的 modules 的 rules 中 配置添加
  {
    test: /node_modules[\\/]@jzl[\\/]aa-form[\\/].*\.(j|t)sx?$/,
    use: {
      loader: "babel-loader",
      options: {
        // your options
      }
    }
  },

Basic Usage

import { FormContext, FormInput, FormCheckbox } from '@jzl/aa-form';

// function component
return (
  <FormContext
    initState={{
      text: '',
      done: false,
    }}
  >
    <FormInput
      className="input-class"
      label="text"
      path="text"
      rules={(value: string) => {
        // return 非空字符串表示验证有错误,提示就是这个字符串
        if (value === 'todo') {
          return '不能输入 todo';
        }
      }}
      placeholder="输入todo文本"
    />
    <FormCheckbox label="done" path="done" />
  </FormContext>
);

一个复杂的例子

demo

FormContext

// 使用 state 为受控模式,需要在 onContextChange 对state 进行更新
// 传入state后,会忽略 initState
{
  initState?: M;
  state?: M;
  validateAtFirst?: boolean; // 默认是点击过 FormButton 后才开始做validate 检查,如果开始就要检查,设置为true
  onSubmit({ state }: { state: M }, e: React.FormEvent<HTMLFormElement>): void; // 只有 validate 检查成功后,才会触发
  onContextChange?({ state }: { state: M }): void; // 这个form的state,有任何的改变
}

提供的组件和设施 (待添加)

  1. 组件
FormInput, FormTextArea,FormInputNumber

FormCheckbox

FormSelect, FormRadioGroup, FormTagGroup

FormDate, FormDateRange
  1. 设施
// 下面两个用于提供上下文(公共model),状态的检验和 submit 事件等
FormContext: 提供共享上下文,比如 model(如果组件提供的 model,优先级更改), 一些通用样式,比如 label 占多宽

FormButton: 和 FormContext 配合,自动管理验证和提交

FormWrapper: 自定义复杂类型,比如需要动态修改的数组,Map。请参考本文档的 `一个复杂的例子`.

API

From 组件,如 Input, Select, Radio 等,

export type ValidateFn<M> = ((value: any, model: M) => string | void) | string;

export interface ICommonOption {
  key?: string;
  title: string;
  value: any;
}
// 通用属性如下
// 一般情况,你只需要关注2,3个属性
{
  path?: string; // 字段名
  onChange?(param: IChangeParam<M>): void; // onChange 事件,此时 value 已经修改
  beforeChange?(
    param: IChangeParam<M> & {
      oldValue?: any;
    },
  ): boolean | void; // change 发生前,可以拿到 old value. 函数return false, 阻止修改
  transformViewToModel?(value: any, props: ICommonFormOuterProps<M>): any;
  transformModelToView?(mValue: any, props: ICommonFormOuterProps<M>): any;
  label?: string | React.ReactNode;
  itemProps?: FormItemProps; // antd Form.Item 的 props
  noFormItem?: boolean; // 默认所以的组件都会包裹在 <Form.Item>里,设置 true,直接返回组件
  rules?: ValidateFn<M> | ValidateFn<M>[]; // validate 规则
  suffixTip?: React.ReactNode; // 组件后面的提示文案
  [x: string]: any; // 其他组件属性
}

FormWrapper 要求 children 是一个函数,函数的参数如下 model 定义如下

export type IAaFormModel<M> = {
  state: M; // 最新的 state
  setKey(key: string, value: any): M; // 修改某一个字段,返回新的 state
  update(updateFn: (draft: Draft<M>) => void): M; // 包装了 immer 的produce,在函数里直接修改 state,返回新的 state
};

Validate

在组件上添加 rules 接受 (value: any, Model: M) => string | any 返回值只要是非空字符串,就表明出错,提示信息就是返回的字符串

// yourRuleFn 接受 value, 以及 state: M, 通过这两个
// 返回值只要是非空字符串,就表明出错,
<FormInput path="text" rules={yourRuleFn} />

点击按钮后,检查所有规则,如果有错,阻止提交,给出提示(提示的样式见 antd Form.Item) 同时 disable FormButton,直到满足所有规则。

组件可以自己提供 defaultRuleFn: (value, model) => string | any 通过 defaultRuleFn 去控制状态默认的的合法性,比如上传组件,正在上传中,最近的状态不是合法的,可以设置为 请等待上传完毕

对 Antd 的修改

  1. 统一 onChange 的参数(antd 中 Input 传的是 Event,CheckBox 传的 checked value)。不过双向绑定的机制,几乎不需要关注 onChange 方法。
  2. FormDate 默认的 value 是时间戳,为 number 类型,13 位数字。传入 unix={true} value 是 10 位数字。
  3. label 直接设置,其他 Antd 的 Form.Item 的属性,通过 itemProps 传入, 具体见antd 文档
  4. 所有接受选项的组件,统一成传入 options 数组, 每一项提供 title 和 value { title: string, value: number|string }, 便于生成代码生成
  <FormInput label="input label" itemProps={...customItemProps}>

value 的取值规则

  1. 默认 _.get(mode, path) (path 支持嵌套)
  2. 组件提供,比如 FormDateFormDateRange 会把 antd 返回的 moment 改为 timestamp
function FormDate(props: IFormComponentProps) {// ...}
FormDate.transformModelToView = function(timestamp: number, props: IProps) {
  // 把model上的value,转成antd 需要的moment
};

FormDate.transformViewToModel = function(momentInst: Moment, props: IProps) {
  // 把 antd 组件的 moment 转成时间戳
};
  1. 使用组件时传入transformModelToViewtransformViewToModel

上面 3 个规则,优先级越来越高。

自定义

只要符合 value, onChange 模式的组件,可以快速融入这套体系,比如基于react-color的改造,只需要下面几行代码。

import * as React from 'react';
import { FormRender } from '@jzl/auto-form';
import { SketchPicker, ColorResult } from 'react-color';
import { IRenderProps } from '@jzl/auto-form/lib/form-render';
import { ICommonFormOuterProps } from '@jzl/auto-form/lib/types';

export function FormColor<M>(rawProps: ICommonFormOuterProps<M>) {
  return (
    <FormRender
      {...rawProps}
      render={(props: IRenderProps<M>) => {
        function handleChange(e: ColorResult) {
          props.onChange(e.hex);
        }
        return (
          <SketchPicker onChangeComplete={handleChange} color={props.value} />
        );
      }}
    ></FormRender>
  );
}