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

bamboosnaketool

v1.3.10

Published

Cool tool features and some components.

Readme



bamboosnaketool

快速上手 - 安装

npm install bamboosnaketool

// the github project url
https://github.com/liuyunqi/BambooSnake-ReactAntd

简单介绍

技术栈React + Antd-UI,内置常用的基础工具函数、通用组件、业务组件/函数。统一规范,减少重复开发提升交付质量效率,聚焦内容实现。

(如果为支持firefox-v5.0~5.3版,依赖antd的版本需锁死在v4.15.6,目前发现主要是table表格的支持,低版本position-Fixed会失效。)

推荐使用Typora的.md文档查看工具打开本地modules内的README.md文件,会有明确的模块目录分栏及内容段落,极大提高可读性。

基本依赖

import Bamboo, { enumDataMode as _enumDataMode } from 'bamboosnaketool';
import { Utiles, Components } from 'bamboosnaketool';

// 包含大量的工具函数 及 组件模块
const { AccessorOverdue, dateTransformer: _dateTransformer, CollectionElementCtrl, Table } = Bamboo;
const { Table: { default: KTTable } } = Components;

// 例: 转换日期 - 完整型
let xsdate = _dateTransformer(new Date(), _enumDataMode.FULL);

// 例:表格组件 - KTTable (可任意自定义模块名称)
<KTTable/>

工具函数/ 小工具合集

内置基本工具函数。

// Date对象 转换为 时间字符串(多种款)
dateTransformer = (dt: Date, viewMode?: enumDataMode): string

// 嵌套层级字符替换数据转换函数
/*
  desc: 将对象数组数据进行无限递归转换,替换数据原字段为自定义字段。(且可选是否移除原字段数据)

  @data: [{...}, ...],  // 源数据
  @tranConf: {          // 转换字段配置
    O:N,                // 【O】:old,转换目标字段。【N】:new,更新的定义字段。
    ...
  },
  @options:             // 相关配置
*/
recursionDataKeyNameTransform = <T>(data: T[], tranConf: recursionDataKeyTransformConf = { isChildrenKey: 'children' }, options: recursionDataKeyTransformOpt = {
  needDeleteBefore: true
}): T[]
import Bamboo from 'bamboosnaketool';
const { dateTransformer, mergeUrl, ArrayVeidooTransfrom } = Bamboo;

// 日期转换器 - dateTransformer
dateTransformer = (dt: Date | number, viewMode?: enumDataMode): string;

// 路径合并, 去除拼接处 多或少的 '/'
mergeUrl = (arr: string[]): string;

// 一维数组转二维切割
ArrayVeidooTransfrom = (list: any[], mo: number) :array[];
RegExpValidator - 校验器
基本使用

针对{}对象进行校验。

import Bamboo from 'bamboosnaketool';

const { RegExpValidator, RegExpType } = Bamboo;

// 初始化配置
const creatValidtor = new Validtor({
  regConfig: [
    {
      key: 'name',
      type: RegExpType.CN,
      name: '姓名',
      require: true
    }, {
      key: 'phone',
      type: RegExpType.PHONE,
      name: '手机',
      require: true
    }, {
      key: 'enCode',
      type: RegExpType.EN,
      name: '英文代号',
      require: true
    }
  ]
});


// 执行校验数据
let validResult = creatValidtor.exceValid({
  name: '刘德华2',
  phone: '18163741749',
  enCode: 'code'
});

console.log(validResult);

// 验证结果 - 执行后的 console - validResult
{	// 如果 - 校验失败
    validErrors: [
      {
        key: "name"
        msg: "仅允许中文汉字"
        name: "姓名"
        require: true
        type: 0
        value: "刘德华2"
       }
    ],
    validPassState: false
}

{	// 如果 - 校验成功
    validErrors: [],
    validPassState: true
}
多项联合校验

支持多重联合校验,下例中分别写了CN/EN/PHONE,当然你甚至可以写更多;

// 初始化配置 - 多重联合校验
const creatValidtor = new Validtor({
  regConfig: [
    {
      key: 'name',
      type: [
          RegExpType.CN,
          RegExpType.EN,
          RegExpType.PHONE
      ],
      name: '姓名',
      require: true
    }
  ]
});
便捷调用

同时支持单数据快捷校验,无需实例化直接调用。

import Bamboo from 'bamboosnaketool';

const { RegExpValidator, RegExpType } = Bamboo;

// 单数据的便捷校验
let singleValid = Validtor.exceOnce('', RegExpType.CN);							// 单项校验
let multiSingleValid = Validtor.exceOnce('', [ RegExpType.CN, RegExpType.IP]);	// 多项校验

// 分别的打印结果
/* is singleValid
{
	validErrors: "仅允许中文汉字"
	validPassState: false
}
*/

/* is multiSingleValid
{
	validErrors: {type: 'CN', msg: '仅允许中文汉字'},
				 {type: 'IP', msg: '必须是正确ip格式'}
	validPassState: false
}
*/
配置项说明

可支持的内置校验类型。


// 校验单元格配置格式
interface RegExpValidatorConfItem {
  key: string;            // 关键key
  type: RegExpType | RegExpType[];   // 校验内置类型
  name: string;           // 校验项名称
  require?: boolean;      // 是否必填
}

export enum RegExpType {
  CN,                   // 中文
  EN,                   // 英文字母
  EN_NUMBER,            // 任意英文+数字
  DECIMAL,              // 小数浮点数类型
  INTEGER,              // 整数类型 - 正负都可以
  POSITIVE_INTEGER,     // 整数类型 - 正数
  UP_ZERO_INTEGER,      // 0+正数 (<=0)
  UP_ONE_INTEGER,       // 1+正数 (<=1)
  NUMBER,               // 数字类型
  EMAIL,                // 电子邮箱
  PHONE,                // 手机 18165221849
  TEL,                  // 电话 0731-5632575
  PHONE_TEL,            // 手机 + 电话
  POSTCODE,             // 邮政编码
  HTTP,                 // http (支持 - :post,www,ip,http,https)
  IP,                   // ip地址
  IDENTITY_CARD,        // 身份证
  SYMBOL_CN,          	// 全角
  SYMBOL_EN           	// 半角
}

返回格式

// 校验返回格式
interface RegExpValidatorErrorResponse {
  validPassState: boolean;					// 校验结果状态
  validErrors: RegExpValidatorErrorItem[];	// 校验错误项集合
}
CollectionElementCtrl - HTML元素集合控制器
基本使用

针对元素对象集合进行遍历操作。

内置索引记录器,可以通过使用指令对其进行遍历,对遍历目标元素进行 Attr 属性赋值(如class、style),对非当前active元素进行清理值。

支持对目标元素进行class/ style的配置自定义。

import Bamboo from 'bamboosnaketool';

const { CollectionElementCtrl } = Bamboo;

// 元素集合操作
const $CollectionElementCtrl = new CollectionElementCtrl({
  collectionsElements: [],	// dom对象集合 (可初始化设置/ 通过.setCollectionsElements()插入调用)
  indexRecord: 0,			// 行索引 - rowIndex
  columnIndex: 4,			// 列索引 - 锁定单元格
  needFoucusHTMLElementInput: true	// 是否聚焦input - 是否需要检查当前 纵及列<td>单元格内是否包含input
});
组合使用

可结合 Bamboo.KeywordsContrl 的键盘事件组件搭配使用。(如:操作表格,通过键盘(上下左右)指令在表格的row及td中的元素进行操作。)

演示表格行通过 ↑ ↓ 键盘来做到行来回选中效果。


const TableScanRef = React.createRef<HTMLDivElement>(); // TABLE - 表格 (用于控制-rowSelected)

// 获取Element集合
const tbody = (TableRef.current as HTMLDivElement).children[0].querySelector('.ant-table-tbody');
let trNodes: HTMLTableRowElement[] = [];
tbody?.querySelectorAll('tr').forEach((trElement: HTMLTableRowElement, index: number) => {
    if (index > 0) {
        trNodes.push(trElement);
    }
});

// 装载DOM元素集合到 组件内
$CollectionElementCtrl.setCollectionsElements(trNodes);

// print 是 Bamboo.KeywordsContrl 事件回调里的按键标识
if (print === 'top') {
    $CollectionElementCtrl.reduce();
} else if (print === 'bottom') {
    $CollectionElementCtrl.addition();
}
AccessorOverdue - 存取器 - 过期限制 (save data to localSession):
基本使用

让存储在 localStorage/ sessionStorage 的数据具备过期能力,满足一些需要数据失效的应用场景。

import Bamboo from 'bamboosnaketool';
const { AccessorOverdue } = Bamboo;

// 创建实例
const xAccessorOverdue = new AccessorOverdue({  // 过期存储
  overdueTimeSecond: 3600     // 设置过期时间 - 单位-秒
});

/* 默认的配置 component default optiosn [可选]

{
  projectAlias: 'baseToolAccessOverdue',                            // 命名空间
  saveObject: accessOverdue_saveObjectEnum.sessionStorage,          // 存储对象 'sessionStorage' | 'localStorage'
  overdueTimeSecond: 60                                             // 过期时间 - 1 = 1s (单位/秒)
}
*/

// 写入存储
xAccessorOverdue.setItem('mockKey', {name: '我是需要保持的数据'});

// 提取存储
xAccessorOverdue.getItem('mockKey');		// 根据 [配置项-过期时间] 判断是否过期
xAccessorOverdue.getItem('mockKey', 1);		// 根据本次形参 - 判断是否过期 (单位/秒 = 1s过期)

// 指定删除
xAccessorOverdue.removeItem('mockKey');			// 删除一项
xAccessorOverdue.removeItem(['mockKey', 'mockKey1', 'mockKey2']);	// 删除多选

配置项中,projectAlias 有效防止命名冲突,saveObject可以指定存储的方式。

提取返回

不管isInvalid状态是否过期,数据永远是会保留返回。

// 执行 .getItem('mockKey')
{
  isInvalid: boolean;			// 是否已过期 - (true-无效已过期、false有效)
  value: any;					// setItem 之前存储的数据内容
}
配置项说明
// 配置props - options
export interface accessOverdue_defaultOption {
  projectAlias?: string;
  saveObject?: accessOverdue_saveObjectEnum;
  overdueTimeSecond?: number;
}

export enum accessOverdue_saveObjectEnum {
  sessionStorage = 'sessionStorage',
  localStorage = 'localStorage'
}

// 实例可调用的api
{
  setItem (key: string, data: any): void        // 写入存储
  getItem (key: string, overdueTimeSecond?: number): { isInvalid: boolean, value: { creatertime: number, value: any }}  // 提取存储
  removeItem (keys: string | string[]): void    // 指定删除
}
Debounced / Throttle - 防抖/ 节流 (control event frequency):

防止高频触发、开销; 防抖 - 短暂时间内的多次执行,以最后一次执行为触发; 节流 - 一段周期内只执行一次;

import Bamboo from 'bamboosnaketool';
const { Debounced, Throttle } = Bamboo;

// 防抖 - 创建实例
const debounced = new Debounced().use((fn: Function) => {
  typeof fn === 'function' && fn();
}, 500);

// 调用-防抖
debounced(() => {
  // u can do any things...
});

// 实例可调用的api
{
  /**
   * @param func 需要包装的函数
   * @param delay 延迟时间,单位ms
   * @param immediate 是否默认执行一次(第一次不延迟)
   */
  use = (func: Function, delay: number, immediate: boolean = false): Function
}

---------------------------[ 不华丽且低调的分割线 ]----------------------------------

// 节流 - 创建实例
const throttle = new Throttle().use((fn: Function) => {
  typeof fn === 'function' && fn();
}, 500);

// 调用
destroy();     // 销毁
open();        // 开启
close();       // 关闭

{
  /**
   * @param func 需要包装的函数
   * @param delay 延迟时间,单位ms
   * @param immediate 是否默认执行一次(第一次不延迟)
   */
  use = (func: Function, delay: number, immediate: boolean = false): Function
}
KeywordsContrl - 键盘事件捕捉器

方便快捷的获取按键捕捉及回调事件。

import Bamboo from 'bamboosnaketool';

const { KeywordsContrl } = Bamboo;

// 键盘事件
const $keywordsContrl = new KeywordsContrl();

// 按键事件回调
$keywordsContrl.allEventCallback = (eventName, data) => {
    const { keyCode, print } = data;
    
    // keyCode if enter -> 13
    // print if up -> 'top | bottom | enter ... keywordsContrl_eventType'
}

// 事件类型定义
export enum keywordsContrl_eventType {
  prev = 'prev',
  next = 'next',
  top  = 'top',
  right = 'right',
  bottom = 'bottom',
  left = 'left',
  delete = 'delete',
  enter = 'enter',
  focus = 'focus',
  blur = 'blur',
  tableIsReady = 'tableIsReady',
  init = 'init'
}
CreatTableHtmlElement - 打印模板表格

适用于生成表格相关的纸质打印单据。

此组件会很方便快速构造一个表格,并将数据渲染在表格内,有需要时可以达成纸质分页及各处自定义内容插槽(为了更符合单据的各种样式),同时支持尺寸自定义。

基本使用

下列示例仅根据 [ 表头配置 + 数据 ] 就能快速生成一个表格。

import { CreatTableHtmlElement } from 'bamboosnaketool';

// 配置表头 width 29.7cm
const printColumns = [
  {
    key: 'mainBarcode',
    name: '条码',
    width: 3
  }, {
    key: 'goodsName',
    name: '品名、剂型号、规格、生产企业',
    width: 5.5
  }, {
    key: 'permitHolder',
    name: '上市许可持有人',
    width: 3.7
  }
];

// 模拟数据
const mockDatas = [
  { mainBarcode: '98500001', goodsName: '阿莫西林-5g*20/盒-江苏制药六厂', permitHolder: '刘备'  },
  { mainBarcode: '98500002', goodsName: '云南白药牙膏250g/支-云南利民制药厂', permitHolder: '孙权'  },
  { mainBarcode: '98500003', goodsName: '天然养生枸杞 500g/罐-六元堂股份药业', permitHolder: '曹操'  },
  // more...
];

let TABLEhtml = CreatTableHtmlElement(printColumns, mockDatas)();

可以自定义尺寸属性,如示例

let options = {
  cssUnit: 'cm',		// 内置默认是 'px',这里的单位会影响 printColumns[ item.width ]
  ...					// ’欧佛阔斯‘,还有很多其他的属性
};
let TABLEhtml = CreatTableHtmlElement(printColumns, mockDatas, options)(/** 有需的话可配置插槽对象 **/);
插槽 Slot

该组件中插槽其实是满足打印需求非常关键的一个功能,因为很多实际应用场景下,需要打印的纸质单据并不是内容仅有表格,可能会有下列罗列情况:

1.打印多张,但第一张有个额外的小表格或一段前言声明之类的(那么第一张纸由于被其他内容占据可能表格被裁切高度只能有50%高,而后面其他页都是100%全高);

2.打印多张,需要在每一张都盖上 印章;

3.打印的每一张,内容表格的前后都需要添加一些内容(可能是一个元素结构,也可能是一段文本内容);

不再多举例,下面我们看看如何达成这些需求:

import { CreatTableHtmlElement, CreatTableHtmlElement_InnterSlotModeEnum } from 'bamboosnaketool';

// 复制一份上述示例,增加插槽内容演示
let TABLEhtml = CreatTableHtmlElement(printColumns, mockDatas, options)(
    {
      slotInner: [            // 表格集合组插槽 - 每个表格单元中的内容
        {
          mode: CreatTableHtmlElement_InnterSlotModeEnum.ONLY_FIRST_BEFORE,
          HTMLtext: '仅第一个表格前方渲染的内容'
        },
        {
          mode: CreatTableHtmlElement_InnterSlotModeEnum.ONLY_LAST_BEFORE,
          HTMLtext: '仅最后一个表格的前方渲染的内容'
        },
        // has more...
      ],
      // 表格集合组外部插槽
      slotStamp: `<img src="${setimageDataUrl}" style="position: absolute; right: 1.5cm; bottom: 1.5cm; width: 4cm; height: 4cm;"/>`,
      slotBefore: '开端xxx内容',
      slotAfter: '落款xxxx内容',
});
打印单据示例

下面是一个带有表头的单据打印需求场景(由于无法上图)

import CreatTableHtmlElement, { CreatTableHtmlElement_InnterSlotModeEnum } from 'bamboosnaketool';

let setimageDataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA......';

let title = {
    billName: '大标题XXXXX单据',
    storeName: '香樟东路门店',
    billCode: '90000816',
    shippingDate: '2021-10-21 19:58:23'
};
let deliveryHTMLtext = `
  <div style="margin-bottom: 0.5cm;">
    <h3 style="text-align: left; height: 0.8cm; line-height: 0.8cm;">${ title.billName }</h3>
    <div style="display: flex;">
      <div style="flex: 1;">
        <span>收货门店:${title.storeName}</span>
      </div>
      <div style="flex: 1;">
        <span>单据编号:${title.billCode}</span>
      </div>
      <div style="flex: 1;">
        <span>开票日期:${title.shippingDate}</span>
      </div>
    </div>
  </div>
`;

let TABLEhtml = CreatTableHtmlElement(printColumns, list.map(item => {
  item['supplierState'] = '合格';
  return item;
}), {
  pageLimit: 14,
  cssUnit: 'cm',          // 单位 px/ pt/ cm...
  pagerPhysicsWidth: '29.7cm',
  tableHeight: '20.4cm',
  tablePaddingTop: '1cm',           // 内部padding-top
  tablePaddingBottom: '1cm',        // 内部padding-bottom
  tableSpace: '0',
  tableBorderWidth: '0.01cm',
  tableTHPadding: '0.06cm',
  tableTDPadding: '0.2cm 0.1cm',
  tableFontSize: '0.2cm',

  valueBoxHeight: '0.36cm',       // 高度
  // valueBoxMaxHeight: '0.72cm',    // 最大高度
  valueBoxMaxHeight: '1.08cm',    // 最大高度
  valueBoxLineHeight: '0.36cm',   // 行高  h 1/2
  valueBoxLineClamp: '2',         // 最大显示行数
})({
  slotInner: [{
    mode: CreatTableHtmlElement_InnterSlotModeEnum.ONLY_FIRST_BEFORE,
    HTMLtext: deliveryHTMLtext
  }],
  slotStamp: `<img src="${setimageDataUrl}" style="position: absolute; right: 1.5cm; bottom: 1.5cm; width: 4cm; height: 4cm;"/>`
});
打印应用

创建一个新窗口文档,将已生成好的表格插入。

// 打开弹窗打印执行
const openWindowPrint = (TITLE: string, HTMtext: string, options = {}) => {
  try {
    let wind = window.open('', '_blank');
    (wind as Window).document.body.innerHTML = creatPrintDocumentWrapper(TITLE, HTMtext, options);
    (wind as Window).print();
  } catch (err) {
    // 发生错误时进行交互提示
    /*
    Modal.error({
      title: '发生错误',
      content: '打开打印弹窗失败,当前游览器可能弹窗已被阻止,通过【设置 - 允许弹窗]】后再重试打印。'
    });
    */
  }
}


/**
 * 新建文档包裹容器
 * @param title    新建文档标题
 * @param HTMLdom  新建文档元素内容
 * @param options  配置项
 */

interface creatPrintDocumentWrapper_options {
  htmlWidth?: string;        // 文档整宽 (例:21cm)
  page_sizeMode?: 'A4';      // 尺寸标准名
  page_composeType?: 'landscape' | 'portrait'; // landscape 横版 / portrait 竖版
}

const creatPrintDocumentWrapper = (title: string = 'Print Document', HTMLdom: string, options: creatPrintDocumentWrapper_options = {}) => {

  let defOpts: creatPrintDocumentWrapper_options = {
    htmlWidth: '21cm',                      // 文档整宽
    page_sizeMode: 'A4',                    // 尺寸标准名
    page_composeType: 'portrait',           // landscape 横版 / portrait 竖版
    ...options
  };

  return `
    <!DOCTYPE html>
    <html lang=\"en\">
      <head>
        <meta charset=\"UTF-8\">
        <title>${ title }</title>
      </head>
      <style>
        @page {
          size: ${defOpts.page_sizeMode} ${defOpts.page_composeType};
        }
        * {
          margin: 0;
          padding: 0;
        }
        html {
          width: ${defOpts.htmlWidth};
          font-size: 0.3cm;
        }
        body {
          margin: 0;
        }
      </style>
      <body>
        ${ HTMLdom }
      </body>
    </html>
  `;
}
结构关系

特别准备了这一部分,因为对组件构成的关系理解对使用组件到实际应用场景非常关键,由于用不了图片进行关系示意,所以相互结构关系的理解非常重要,我尝试将它说清楚一些。

我们先列出构成文档的参与者,按文档流的形式 由上至下。

[顶部插槽]start
[内容插槽组:
  [
    [第一个表格
       [首个前]
       [每个前]
       [表格]
       [每个后]
       [首个后]
       [印章]
    ],
    [第二个表格(也许)
       [每个前]
       [表格]
       [每个后]
       [印章]
    ],
    [ 也许中间有若干个表格 ....],
    [最后一个表格
       [末尾前]
       [每个前]
       [表格]
       [每个后]
       [末尾后]
       [印章]
    ],
  ]
]
[底部插槽]end

上述假设了完整的配置结构组成了一个大篇幅,可能会存在分页,原则上每个页面内容在纵向填充是尽可能饱满(不浪费打印纸)。

分页情况:

首页会顶部插槽+第一个表格的组成;

中间的每个页面表格+前后填充饱满;

末尾页表格+底部插槽内容;

配置项说明
// 表格列配置
export interface CreatTableHtmlElement_columnsConf {
  key: string,
  name: string,
  width?: string | number,
  align?: string
}

// 每个单元表格 - 插槽配置 CreatTableHtmlElement_concatSlot.slotInner 
interface CreatTableHtmlElement_slotInnerInter {
  HTMLtext: string;
  mode: CreatTableHtmlElement_InnterSlotModeEnum;
}

// 全插槽配置
export interface CreatTableHtmlElement_concatSlot {
  slotBefore?: string;                    // 插入总结构的头始
  slotAfter?: string;                     // 插入总结构内的末尾
  slotStamp?: string;                     // 插入公章
  slotInner?: [] | CreatTableHtmlElement_slotInnerInter[];      // 插入 table-item 内的具体位置
}

// 每个单元表格 - 插槽类型 slotInner集合的mode类型
export enum CreatTableHtmlElement_InnterSlotModeEnum {    // 插入模式 - 可能插入多个或单个于  table-item DIV 中
  ONLY_FIRST_BEFORE = 'ONLY_FIRST_BEFORE', // 仅首个 - 表格之前插入
  ONLY_FIRST_AFTER = 'ONLY_FIRST_AFTER',   // 仅首个 - 表格之后插入
  ONLY_LAST_BEFORE = 'ONLY_LAST_BEFORE',   // 仅末尾 - 表格之前插入
  ONLY_LAST_AFTER = 'ONLY_LAST_AFTER',     // 仅末尾 - 表格之后插入
  EVERY_BEFORE = 'EVERY_BEFORE',           // 每个之前
  EVERY_AFTER = 'EVERY_AFTER',             // 每个之后
  UNDO = 'UNDO',                           // 无动作
};

// 组件配置项
export interface CreatTableHtmlElement_options {
  pageLimit?: number;                 // 是否需要区别表格 - 数据总长度超出单页时将创建多个表格(便于打印)
  cssUnit?: 'px' | 'pt' | 'cm';       // 尺寸单位,影响内部style配置及column.width

  pagerPhysicsWidth?: string;         // 纸张横向尺寸
  tableHeight?: string;               // 是否限制 - 单个表格容器高度

  tablePaddingTop?: string;           // 表格单元内边距 padding-top
  tablePaddingBottom?: string;        // 表格单元内边距 padding-bottom
  tableSpace?: string;                // 表格单元 margin-top
  tableBorderColor?: string;          // 表格边框色
  tableBorderWidth?: string;          // 表格边框线宽
  tableZebraColor?: string;           // 表头thead - 背景色
  tableTHPadding?: string;            // 表头thead - 内边距 padding
  tableTDPadding?: string;            // 表格td 内边距 padding
  tableFontSize?: string;             // 表格th、td - 字体大小

  valueBoxHeight?: string;            // 高度
  valueBoxMaxHeight?: string;         // 最大高度
  valueBoxLineHeight?: string;        // 行高  h 1/2
  valueBoxLineClamp?: string;         // 最大显示行数
}

公共组件

React、antd-UI

组件:

Table - 表格组件:(github - public)

内置pagination分页、支持表格列单元格自定义模板渲染、ACTIONS操作栏多功能渲染等;

目前表格使用 antd-UI ,表格组件封装了 Table-antd 和 Pagination-antd;

基本使用
// 使用bamboo表格组件
import Bamboo from 'bamboosnaketool';
const { Table: BamTable } = Bamboo;

return (
    <BamTable dataSource={ dataSourceList } columns={ columns } rowKey={ 'id' } ALLEVENTCallback={ tableLLEVENTCallback }/>
)
lib - 页面模块组成

目前开发作者习惯性的文件方式搭配。假设有一个页面模块demoPage

src <
    demoPage <
    	index.tsx;			// 页面模块
		index.less;			// 页面样式
		columns.ts;			// 根据key生成的export对象,该对象符合 antd-column-item 及 结合组件内部封装的新属性
		columns.d.ts;		// key - tableCloumn 前端枚举 - 页面中如有用到关键字段推荐从这里统一使用
column - 列头配置

推荐方式为独立的 列头配置文件 和 列头.d。

基础的列头配置如下(类似antd的常规使用格式),如果是涉及到内置组件的后面会详细提及。

// 根目录
...,
mock,
pages --> homePage --> [ index.tsx, index.less, columns.ts, columns.d.ts ],
...otherlibs
// columns.ts

import { ColumnsType } from 'antd/es/table';
import { columnItemDecorator, Table_ColumnsTypeMine } from 'bamboosnaketool';
import { keys } from './columns.d';

// 字段配置
const originalConfMax = (
  columnItemDecorator
)({
  [keys.mainbarCode]: { name: '商品条码' },
  [keys.goodCode]: { name: '商品编码' }
}, keys);

/*
originalConfMax =  // 生成后的数据格式为:type is Object
{
  mainbarCode:{
    dataIndex: "mainbarCode",
    key: "mainbarCode",
    name: "商品条码",
    title: "商品条码"
  },
  ...
}
columnItemDecorator 是数据装饰的函数,通过编码人员简单的columnitem配置就能生产完整的数据,数据符合antd的api及bamboo组件封装props要求,且写少做多。
*/

// 将其导出
export const column_ALL: Table_ColumnsTypeMine = [
  originalConfMax[keys.goodName],
  originalConfMax[keys.mainbarCode]
];
// columns.d.ts

// ts 字段枚举配置
export enum keys {
  mainbarCode = 'mainbarCode',      // 商品条码
  goodCode = 'goodCode',            // 商品条码
  ...
}

columns.d.ts 的keys是枚举对象,键值对形式,其中【键】命名后不可更改,【值】则根据实际数据字段自由更改(建议项目中任何使用该字段时都引用 keys )。

这里之所以使用columns.tscolumns.d.ts构成方式,而不直接定义在index.tsx里是因为有以下几种应用情况:

  1. keys 适用于导入提供其他相关模块引用,做到字段易维护统一;(比如页面的逻辑、mock模拟数据、等)

  2. column.ts 内可通过函数生成单或多个配置内容,适用于某页面有多个tabs切换多表格场景;

columnItemDecorator 是执行 ’编译‘ 配置的关键函数,如涉及特殊情况需要在其他页面配置也是可以的,如下代码。

1.下面变量如 hasModelPredict, billRunStatus 可以是 useState/ Props,可以在任何地方嵌入任何变量作为条件进行逻辑约束;

2.condition 中使用了 evalString 方式,这种方式非常灵活,可以支持非常繁琐复杂的判断逻辑;

import { keys } from 'somePageModule';
import Bamboo, {
    Table_ColumnCustomType, columnItemDecorator
} from 'bamboosnaketool';

const columnFactory = (
    columnItemDecorator
)({
    [keys.forecastCount]: {
        name: '预测数量',
        width: 80,
        condition: [
            // 条件满足 ->> 开启模型预测 + 且模型运行已完成 + 预测数量有值
            `${Boolean(
                (hasModelPredict && billRunStatus) &&
                (
                    billRunStatus === ENUM_InitiativeBillRunModelStatus.MODEL_RUN_SUCCESS ||
                    billRunStatus === ENUM_InitiativeBillRunModelStatus.DELIVERY_CREAT_ING ||
                    billRunStatus === ENUM_InitiativeBillRunModelStatus.DELIVERY_CREAT_FAIL ||
                    billRunStatus === ENUM_InitiativeBillRunModelStatus.DELIVERY_CREAT_SUCCESS
                )
            )} && record['${[keys.forecastCount]}']!==undefined`,
            {
                customType: Table_ColumnCustomType.LINKBUTTON,
                optionsApi: {
                    style: { width: 56 },
                    maxLength: 4
                }
            },
            {	// 其实该处整个{}对象配置可以省略,组件内部会默认使用 NORMALRENDER 渲染正常文本显示。
                customType: Table_ColumnCustomType.NORMALRENDER,  // 默认渲染普通文本 - 该处可不设
            }
        ]
    }
});

let setOverColumns = columnCombo.map((icloum: any, index: number) => {
    if (icloum.key === keys.forecastCount) {
        return columnFactory[keys.forecastCount];
    }
    return icloum;
});
operation - 操作栏配置

(多功能配置ACTIONS)

操作栏支持多种可调配的交互操作方式,如下:

点击回调、点击模态框弹窗(Modal)、点击确认气泡框(Popconfirm)、隐藏、隐藏且占位、禁用锁定、仅某一条符合某条件、多渲染模式同时并存、仅图标、图标+文字、悬停是否显示title、仅图标锁定。

// 配置单个操作对象的大致包含
{
    text: '查看明细',	  // 文本
    eventType,			// 事件交互方式
    eventSubstance,		// 对应各个eventType的不同格式配置
    condition,			// 显示方式
    viewMode 			// 渲染方式
}

下面内容过于丰富,为便于理解,这里系统的归纳下:

事件交互方式:

{ ..., eventType: [?] }

通过内置的枚举进行模式选择。(默认方式:CALLBACK)

| 对象 | 名称 | 说明 | | ------------------------------ | ---------- | ------------------------------------------------------------ | | Table_enumEventType.CALLBACK | 函数回调 | 触发会响应绑定的函数进行事件响应。 | | Table_enumEventType.MODALBOX | 模态框 | 可自定义模态框内容文本,并绑定弹窗 confrim/cancel 事件函数。 | | Table_enumEventType.POPCONFIRM | 气泡确认框 | 点击目标文字会在点击附近出现气泡确认框再次确认。功能与模态框类似可自定义文本内容及事件绑定。 |

物料:

{ ..., eventSubstance: [?] }

配套对应不同 eventType , 配置完全不同;

| 对象 | 名称 | 配置格式 | 说明 | | ------------------------------ | ---------- | ------------------------------------------------------------ | ---- | | Table_enumEventType.CALLBACK | 函数回调 | ( record: any ) => void; | - | | Table_enumEventType.MODALBOX | 模态框 | { title: (string | JSX.html), content: (string | JSX.html), ok: Function, cancel: Function} | - | | Table_enumEventType.POPCONFIRM | 气泡确认框 | 与 [模态框] 一致。↑↑↑ | - |

显示方式:

{..., condition: { [?key]: boolean | evalString }}

渲染条件允许配置多个,内含 { hide, transparent, locked }, 优先级按此序列;条件书写为 eval(string), 内置关键字为 'record';

| 对象 | 名称 | 优先级权重 | 说明 | | ----------- | -------- | ---------- | ------------------------------------ | | hide | 隐藏 | 1(最高) | 条件成立则不显示,不干涉元素布局占位 | | transparent | 占位隐藏 | 2 | 条件成立则不显示,干涉元素布局占位 | | locked | 锁定 | 3 | 条件成立则禁用置灰 |

渲染方式:

{ ..., viewMode: [?] }

渲染显示模式有三种,文字/ icon, { Table_enumViewMode.DEFAULT, Table_enumViewMode.ICON, Table_enumViewMode.ICONTEXT }。

| 对象 | 名称 | 说明 | | --------------------------- | ---------- | -------------------------- | | Table_enumViewMode.DEFAULT | 默认 | 只显示文本 | | Table_enumViewMode.ICON | 仅图标 | 只显示自定义配置的图标 | | Table_enumViewMode.ICONTEXT | 图标兼文本 | 同时显示图标和文本的组合体 |

代码参考如下:

// tableMock.tsx 
import { HomeOutlined } from '@ant-design/icons';
import { Table_enumEventType, Table_enumViewMode, Table_sActions as ActionInterface } from 'bamboosnaketool';


// 这是一个配置好的 操作栏 - ACTIONS
export const setActionsTestMock : ActionInterface[] = [
  // 事件交互
  {
    text: '点击回调',
    condition: {
      hide: `['2', '3'].includes(record.key)`
    },
    eventType: Table_enumEventType.CALLBACK,
    eventSubstance(record: RowProps) {
      alert('can run xxx function event.');
    }
  }, {
    text: '模态框',
    condition: {
      hide: `['2', '3'].includes(record.key)`
    },
    eventType: Table_enumEventType.MODALBOX,
    eventSubstance: {
      title: '模态框标题',
      content: (
      <div>
        这是一段询问的内容,吧啦吧啦。。。
      </div>),
      ok(record) {
        alert('ok')
      },
      cancel() {
        alert('cancel')
      }
    }
  }, {
    text: '气泡确认框',
    condition: {
      hide: `['2', '3'].includes(record.key)`
    },
    eventType: Table_enumEventType.POPCONFIRM,
    eventSubstance: {
      title: '气泡标题',
      content: '嗯哼?',
      ok(record) {
        alert('ok')
      },
      cancel() {
        alert('cancel')
      }
    }
  },

  // 按鈕狀態
  {
    text: '隐藏且占位',
    condition: {
      transparent: `true`,
      hide: `['1', '3'].includes(record.key)`
    },
    eventType: Table_enumEventType.CALLBACK,
    eventSubstance(record: RowProps) {
      alert('can run xxx function event.');
    }
  },
  {
    text: '显示图标',
    icon: <HomeOutlined/>,
    condition: {
      hide: `['1', '2'].includes(record.key)`
    },
    eventType: Table_enumEventType.CALLBACK,
    eventSubstance() {

    },
    viewMode: Table_enumViewMode.ICONTEXT
  }
  ....    /* 还有非常多种 */
]

上述还有非常多种,具体可以参考 后期补全,示例文件删了。(同时你可以使用该文件内的数据生成示例参考,datasource、columns、actions 都是齐全的)

eventType : 事件响应模式 { Table_enumEventType.CALLBACK, Table_enumEventType.MODALBOX, Table_enumEventType.POPCONFIRM };
eventSubstance : 配套对应不同 eventType , 配置完全不同;
condition : 渲染条件,内含 { hide, transparent, locked }, 优先级按此序列;条件书写为 eval(string), 内置关键字为 'record';
viewMode : 渲染显示模式,文字/ icon, { Table_enumViewMode.DEFAULT, Table_enumViewMode.ICON, Table_enumViewMode.ICONTEXT }。

将配置完成的 [操作栏] 数据与 [column] 数据进行数组合并。


import { setActionsTestMock } from '../tableMock.tsx';
import { ColumnRender_operationAction } from 'bamboosnaketool';

export const setColumns = [
  {
    title: '创建人',
    dataIndex: 'str3',
    key: 'str3',
  },
  {
    title: '操作',
    key: 'action',
    render: (text: string, record: any, index: number) => {

      let setActionsTest = setActionsTestMock;

      // if 条件变更 setActions ...
      return ColumnRender_operationAction(text, record, index, setActionsTest);
    }
  }
];

更多细节建议利用mock数据做一个例子,并花30分逐个尝试并理解为最佳。这里就没有逐一全部写清楚了。

column-Item - 配置定制化模板

支持表格单元格渲染,输入框类型、货币格式转换、时间戳转字符串、进度条(节状、直条、或任意款式)、高亮link内容等错综复杂的万象需求...,都可按照目前组件提供的内置模板模式达成。

配置示例:


// 这里就写局部结构,完整内容参考已上述过的【列头配置】
{
  [keys.salesForecast]: {
    name: '链接文本',             // 其实这里是  列头名称,为方便理解这个改为了 ’示例模板名称‘
    condition: [
      'record.id !== "3"',
      {
        customType: Table_ColumnCustomType.LINKBUTTON,
        customSettings: {
          style: {
            fontWeight: 'bold'
          }
        }
      }
    ]
  },

  [keys.replenishNumber]: {
    name: '输入框',               // 其实这里是  列头名称,为方便理解这个改为了 ’示例模板名称‘
    condition: [
      'record.id !== "3"',
      {
        customType: Table_ColumnCustomType.INPUT,
        optionsApi: {
          style: { width: 56 },
          maxLength: 4
        }
      },
      {                                                   // 其实该处整个{}对象配置可以省略,组件内部会默认使用 NORMALRENDER 渲染正常文本显示。
        customType: Table_ColumnCustomType.NORMALRENDER,  // 默认渲染普通文本 - 该处可不设
      }
    ]
  }
}

上述代码示例中出现了三个组件内置模板,Table_ColumnCustomType { LINKBUTTON, INPUT, NORMALRENDER }。

optionsApi 为antd-api,这里的设置参数全部是直接 setProps 到 antd-DOM 上的。根据不同的组件查看官方具体的api。 customSettings 设置一些自定义的dom属性,比如 customSettings.style, 这些最终也会以 setProps 方式应用到 DOM 的行间样式属性中;

为了方便理解,从概念上 optionsApi 可看作【setApis】,customSettings可看作【setPropertys】。

渲染条件 condition

这里condition(条件)要特别说下,它决定了每个列配置的最终渲染结果,根据条件满足与否执行A/ B;类似if else 无限递归

condition本身是数组,参考概念格式为 condition = [ boolean, A, B ] 或 [ boolean, A ] 。

c[0] 是布尔类型,成功则执行A,否则执行B;  
A/B  是一个单个模板完整的配置方案;  
B 非必填,不填时则渲染默认模板 Table_ColumnCustomType.NORMALRENDER(默认文本显示);  

c[0]:书写可以是 true/ false/ 表达式, 或 eval(string),string数据关键字为 'record';

同时为满足相对复杂的业务需求,这里支持无限层级的类似 if else 嵌套,代码如下:


// 类似 if else 方式
{
  name: '补货数量',
  condition: [
    true,
    {
      customType: Table_ColumnCustomType.INPUT,
      optionsApi: {
        style: { width: 56 },
        maxLength: 4
      }
    },{
      customType: Table_ColumnCustomType.TEXT,
      optionsApi: {
        style: { width: 56 },
        maxLength: 4
      }
    }
  ]
}

// 伪代码理解
// [false, 3, [false, 5, [true, 18]]]    - 结果:18
// [true, 996, [true, 42, [false, 23]]]  - 结果:996
// [false, 5]						     - 结果:由于未设置B,则指向默认Table_ColumnCustomType.NORMALRENDER,或优先外部配置的 isItemRender


// 递归无限层级
{
  name: '补货数量',
  condition: [
    true,
    {
      customType: Table_ColumnCustomType.INPUT,
      optionsApi: {
        style: { width: 56 },
        maxLength: 4
      }
    },[
      true,
      {
        customType: Table_ColumnCustomType.TEXT,
        optionsApi: {
          style: { width: 56 },
          maxLength: 4
        }
      }, [ 无限层级... ]
    ]
  ]
}
模板 template

目前使用的模板都是内置的。在 ./template.tsx 中。 需要新增则需要扩展 Table_ColumnCustomType 类型名称 及 对应的 render 函数。

理想的最优解为之后迭代,让今后使用者能够外部定义追加扩展模板及模板类型名称。

表格事件 eventHandle

通过配置表格组件Props - ALLEVENTCallback, 传入一个方法,该方法仅会响应 template 模板事件。


// 全表格事件回调捕捉函数
const tableLLEVENTCallback: ALLEVENTCallbackType = (TYPE, data) => {

  // 输入框 - 每次输入
  if (TYPE === Enum_ALLEVENT.INPUT_onChange) {
    const { e, record, columnItem, index } = data;
    let key = columnItem.key;
    let value = e.target.value;
    
    //...
  }
  // 输入框 - 回车 / 失焦
  else if (TYPE === Enum_ALLEVENT.INPUT_onPressEnter || TYPE === Enum_ALLEVENT.INPUT_onBlur) {

  }
  // 点击 预测销量
  else if (TYPE === Enum_ALLEVENT.LINKBUTTON_onClick) {
    // do anything...
  }
}

顺便提一嘴,操作栏 ACTION 的事件回调函数为 eventSubstance。在配置 ACTION-item 时被一并配置,根据ACTION类型不同会有所不同。

Props Api

interface IProps  {
  dispatch: Dispatch;

  columns: ColumnsType<ColumnsTypeMine>;   // 表格列头
  dataSource: any[];                       // 表格数据
  rowKey?: string | undefined;             // 自定义关键参数 default: id
  isShowPagination?: boolean;              // 是否显示分页组件
  defaultFirstPage?: number | undefined;   // 默认开始页码
  pageCurrent?: number | undefined;        // 当前页码
  pageTotal?: number | undefined;          // 总页码数
  pageLimit?: number | undefined;          // 单页数据数量
  pageSizeOptions?: string[] | undefined;  // 单页数量变更

  onPaginationChange?: ((page: number, pageSize: number) => void) | undefined;   		// 分页组件事件回调
  onPaginationShowSizeChange?: ((current: number, size: number) => void) | undefined;	// 是否显示分页组件
  ALLEVENTCallback?: ALLEVENTCallbackType; // 公共回调函数 (可用于解决column-render组合任何组件的无限触发事件回调)

  reloadApiTable?: TableProps<any>;        // antd - table - api
  reloadApiPagination?: PaginationProps;   // antd - pagination- api
}
TS报错

参数声明 isItemRender 是 [boolean, ColumnCustomType],但如果直接写成 isItemRender: [true, ColumnCustomType.TEXTLINESINGLE],会造成props报错,原因是TS自动解析为 联合类型,而不是索引指定类型;

import Bamboo from 'bamboosnaketool';
const { Table: BamTable } = Bamboo;
// 这样指定个声明可以解决TS报错误识别问题
// 如不额外将 setIsItemRender 拿出来做TS会自动认为 [true, ColumnCustomType.TEXTLINESINGLE] 是 (boolean | ColumnCustomType)[],fuok!
const setIsItemRender: [boolean, ColumnCustomType] = [true, ColumnCustomType.TEXTLINESINGLE];

// table setProps - FAST
const setTableProps = {
  dataSource: dataSourceList,
  columns: saColumns,
  isItemRender: setIsItemRender,
  // isItemRender: [true, ColumnCustomType.TEXTLINESINGLE]
}

// render
<BamTable { ...setTableProps } />

解决其它含antd@type 的报错解决。页面调用时由于TS默认会识别 ‘small’ | ‘checkbox’ 为 string 类型。

import { SizeType } from 'antd/lib/config-provider/SizeContext.d';
import { RowSelectionType } from 'antd/lib/table/interface.d';
import Bamboo from 'bamboosnaketool';
const { Table: BamTable } = Bamboo;

const sizeType: SizeType = 'small';
const rowSelectionType: RowSelectionType = 'checkbox';

/* 或亦可如此,更爲简洁
{ 
	size: ('small' as SizeType),
	rowSelection: {
		type: 'checkbox' as RowSelectionType
	}
}
*/

// table setProps - FAST
const setTableProps = {
  dataSource: dataSourceList,
  columns: saColumns,
  reloadApiTable: {
      size: sizeType,
      rowSelection: {
        type: rowSelectionType,
        onChange: (selectedRowKeys: React.Key[], selectedRows: any[]) => {
          setCheckeds(prev => {
            return [...selectedRowKeys]
          });
        },
        getCheckboxProps: (record: any) => ({
          // disabled: record.name === 'Disabled User', // Column configuration not to be checked
          name: record.name,
        }),
      }
  }
}

// render
<BamTable { ...setTableProps } />
TreeAbundant - 丰富的树组件 (Tabs + Tree):

使用antd的 tree + tabs 组件拼搭的封装组件。

基本使用
import Bamboo, { Components } from 'bamboosnaketool';

const { TreeAbundant, TreeAbundant_enumEVENTTYPE, TreeAbundant_eventHandle } = Bamboo;

// 丰富树组件 - 全事件回调
const treeAbundant_eventHandle: TreeAbundant_eventHandle = (TYPE, data) => {
  if (TreeAbundant_enumEVENTTYPE.RADIO_CHANGE === TYPE) {
    let value = data;
  } else if (TreeAbundant_enumEVENTTYPE.TREE_CHECKED === TYPE) {
    let { checkedKeysValue, checkedNodes } = data;
  }
}

// 门店-丰富树props配置
const setTreeAbund = {
  treeDataSource: storeTreeDatasource,        // 树状嵌套数组数据
  defaultTreeExpandedKeys: storeTreeDatasource.length > 0 ? [storeTreeDatasource[0].key] : [],   // 默认展开yf首层级
  effectTreeCheckedKeys: storeConfrimCodes,   // array
  isShowTabs: false,                          // 是否显示tabs
  eventHandle: treeAbundant_eventHandle
};

// render ...
<TreeAbundant { ...setTreeAbund }/>

*为确保同步更新,effectTreeCheckedKeys必须始终配置,如果有没配置则填入空数组“[]”。

api参考

interface IProps  {
  dispatch: Dispatch;
  
  treeDataSource: any[];                    // tree组件数据
  eventHandle: intfEventHandle;             // 公共回调事件
  effectTreeCheckedKeys: React.Key[];       // 再次定义多选 (default: 'key')

  dataNodeKeyConf?: intfDataNodeKeyConf;    // 关键字段自定义配置 [title, key, children]
  isShowTabs?: boolean;                     // tab选项卡 - 是否显示
  tabsItems?: intfTabsItem[];               // tab选项卡渲染数据  [{ label: string, value: string }, ...]
  defaultRadioValue?: string;               // 默认radioValue
  defaultTreeExpandedKeys?: React.Key[];    // 设置默认展开 (default: 'key')
  defaultTreeCheckedKeys?: React.Key[];     // 设置默认多选 (default: 'key')
  defaultSelectedKeys?: React.Key[];        // 设置默认选中 (default: 'key')
  treeOptiosApis?: TreeProps;               // 树组件 apis - antd

  mainStyle?: React.CSSProperties;          // 主结构样式自定义
  tabBoxStyle?: React.CSSProperties;        // tab容器结构样式自定义
  treeBoxStyle?: React.CSSProperties;       // 树容器结构样式自定义
}
TableColumnsLayer - 表格列显示/隐藏组件
功能
  1. 动态变动表格列数据;
  2. 支持列数据存储/取赋值;
  3. 支持列数据拖动排序;
基本使用
  1. 给定表格列数据,此列数据需要可以变动
import Bamboo, { Utiles, Components } from 'bamboosnaketool';
import initColumn from './columns';			// 附属xx页面模块的表格配置

const { default: TableColumnsLayer } = Components;
const [ columns, setColumns ] = useState(initColumn);  // 声明

// 定义列变动通知方法
const onColumnChange = (data:any, close:any) => {
	// 选择的列数据
	let { columns, width } = data;

	// 如果操作列单独拿出来的,需要手动放进去
	setColumns([...columns, ACTION_OPERATION]);

	// 关闭列选择弹出窗
	close();
}

// JSX中渲染注册触发事件按钮,及参数配置项
<TableColumnsLayer columns={ columns } onChange={ onColumnChange }>
	<Button type="primary" ghost>
	  列选择
	</Button>
</TableColumnsLayer>
配置项

| 配置项 | 类型 | 说明 | 默认值 | | ----------- | ------ | ------------------------------------------------------------------------------------- | ------ | | columns | 数组 | 表格的列数据 | 必填 | | onChange | 函数 | 回调函数,会回调给用户2个参数,一个data(包含columns和width),一个是关闭弹出窗口的方法 | 必填 | | table | ref | 默认插件会自己去找table,用户也可以传入table的ref,这样会更加准确 | 非必填 | | needStorage | 布尔值 | 是否存储此次操作的列数据,如果存储,下次进来会读取存储中的数据 | false |

注意事项
  1. 未传入ref,组件会自己去找,多个表格的情况有可能会出错,最好把表格的ref传入
  2. 如果操作列没有放到column,而是后面加入,那么回调方法中回调的列数据不包含操作列,需要手动把列数据放入,否则可能会出现操作列不见的情况
FileUploadExcelToData - 上传文件组件

内置生成一个button按钮,点击该按钮后弹窗windows-fileSelectWindow(windows系统自带文件选择窗口); 可以配置一些导入数量的相关数量限制tips阻断;

基本使用
import Bamboo, { Components, FileUploadExcelToData_callback } from 'bamboosnaketool';

const { FileUploadExcelToData } = Bamboo;
// 或 const { FileUploadExcelToData } = Components;

const excelAnaylsDataDispose: FileUploadExcelToData_callback = (
    data,
    options
) => {
    const { file, onSuccess, onError } = options;
}
/*
import { UploadRequestOption } from 'rc-upload/lib/interface';
(
    data: { jsonData: any[], excelColumns: string[] },
    options: UploadRequestOption
) => any
*/

// 文件上传props
const fileExcelUploadProps = {
    isLoading: isLoadingImportExcel,
    isDisabled: isLockEdit,
    buttonText: '上传文件',
    singleUploadMaxLength: 100000,
    slowMaybeMaxLength: 100000,
    callback: excelAnaylsDataDispose,
    uploadApiOptions: {
        multiple: false,
        maxCount: 1
    },
    buttonApiOptions: {
        icon: <UploadOutlined />
    }
};

// render...
<FileUploadExcelToData { ...fileExcelUploadProps } />
    
// 前置拦截功能待未来实现 (比如点击不是直接选择文件,而是判断条件)
功能

校验导入的文件类型MIME是否正确;

将导入文件的二进制类型转换为可读JSON数据对象;

对超出预设数量的导入操作进行拦截/提示;

自定义按钮;

配置项说明

| 配置项 | 类型 | 说明 | 默认值 | 必填 | | --------------------- | ------------------------------------------------------------ | ------------------------------------------------------- | ------------------------------------------------------------ | ---- | | isDisabled | boolean | 是否禁用 | false | 否 | | isLoading | boolean | 是否是载入状态 | false | 否 | | fileTypeStr | { override: boolean; // 是否覆盖 names: string[]; // 文件类型编码} | 文件类型编码,MIME | { false, [] } | 否 | | singleUploadMaxLength | number | 单次上传最大数量,超过限制时候会msg.warn + 逻辑阻断; | 3000 | 否 | | slowMaybeMaxLength | number | 执行时可能较慢提示,modal.confrim,确认后再执行 | 2000 | 否 | | buttonText | string | 按钮文本 | "导入" | 否 | | callback | function | | null | 否 | | uploadApiOptions | { ...antd-options } | antd-Upload,的相关再定义api。(不要覆盖customRequest) | {} | 否 | | buttonApiOptions | { ...antd-options } | antd-Button,的相关再定义api。 | { type: 'primary', ghost: true, title: '选择一份excel文件' } | 否 |

ImportFileExcelDataVerifyTool - Excel导入数据校验与转换

场景:想把excel的中文列头转成英文字段并且拿到转换后的数组,key是excel的列头中文,toKey是需要将原来的中文列头转成什么字段,type表示列值的类型,如果设置了type,那么转换后的数据类型会转成设置的type类型,类型枚举可使用ExcelType,目前包括的枚举(STRING, NUMBER, BOOLEAN, DATETIME, DATE, TIME, FLOAT)

基本使用
import Bamboo, { Utiles, Components } from 'bamboosnaketool';
const { ImportFileExcelDataVerifyTool } = Bamboo; 
const { ExcelRule } = Utiles;

new importFileExcelDataVerifyTool({
  file: ev.target.files[0], //file对象 必传
  columns: [
    { 
      key: "列名比如商品编码", 
      type: ExcelType.STRING, //数据类型,用于转换数据,具体类型可以查看ExcelType枚举
      toKey: "把列头字段转换成的字段比如goodCode", 
    },
  ],
})
.valid() // 开始进行数据校验 必须有
.then((res)=>{
  // 没有任何错误,将返回数据
  // res 为 { total: 总行数, data: 数据数组 }
  console.log(res);
})
设置预警值

场景:有限定用户excel数据量大小,并且需要告知用户数据量已经超出询问用户是否继续导入

import Bamboo, { Utiles, Components } from 'bamboosnaketool';
const { ImportFileExcelDataVerifyTool } = Bamboo; 
const { ExcelRule } = Utiles;

new importFileExcelDataVerifyTool({
  file: ev.target.files[0], //file对象 必传
  columns: [
    { 
      key: "列名比如商品编码", 
      type: 'string|number|boolean|float', //数据类型,用于转换数据
      toKey: "把列头字段转换成的字段比如goodCode", 
    },
  ],
})
.warn((msg, confirm, cancel)=>{
  //配置了warn字段必须加
  // confirm() // 调用此函数表示继续操作
  // cancel() // 此函数表示取消操作
})
.valid() // 开始进行数据校验 必须有
.then((res)=>{
  // 没有任何错误,将返回数据
  // res 为 { total: 总行数, data: 数据数组 }
  console.log(res);
})
设置起始行

场景:需要从指定的excel行开始读取数据,可以设置startIndex配置,默认从第一行开始

import Bamboo, { Utiles, Components } from 'bamboosnaketool';

const { ImportFileExcelDataVerifyTool } = Bamboo; 
const { ExcelRule } = Utiles;

importFileExcelDataVerifyTool({
  startIndex:0, //开始行数
  file: ev.target.files[0], //file对象 必传
  columns: [
    { 
      key: "列名比如商品编码", 
    },
  ],
})
.valid()
.then((res)=>{
  // 没有任何错误,将返回数据
  // res 为 { total: 总行数, data: 数据数组 }
  console.log(res);
})
验证

场景:需要对上传的excel数据字段值进行校验,插件本身提供内置的验证,具体可使用插件暴露出的ExcelRule枚举查看,如果想要自己定义验证,可以使用ExcelRule.Customer,然后定义valid回调函数,回调函数会传入读取到的行数据(注:如果定义了转换的key,那么读取到的行数据中的列字段是经过转换的,不是excel显示的中文),回调函数如果返回true,表示验证通过,验证结束后,错误的验证消息会通过catch方法来进行捕捉,错误的消息可以通过配置msg字段来提示,如果不配置插件会使用自己定义的消息提示,一般来说如果使用了内置的验证会提示内置的验证提示,比如使用身份证号验证将默认提示xxx必须是身份证号,没有的内置验证将提示xxx格式错误

import Bamboo, { Utiles, Components } from 'bamboosnaketool';
const { ImportFileExcelDataVerifyTool } = Bamboo; 
const { ExcelRule } = Utiles;

new importFileExcelDataVerifyTool({
  file: ev.target.files[0], //file对象 必传
  columns: [
    { 
      key: "列名比如商品编码", 
      toKey: "把列头字段转换成的字段比如goodCode", 
      rules:[
        {type:ExcelRule.CUSTOMER, valid:(row)=>{return row.goodCode=='a'}, msg:'自定义错误消息'}, //自定义校验
        {type:ExcelRule.NUMBER, msg:'商品编码必须是数字'}, //使用内部校验规则 可以使用 ExcelRule枚举提供的校验规则
      ]
    },
  ],
})
.valid() // 开始进行数据校验 必须有
.then((res)=>{
  // 没有任何错误,将返回数据
  // res 为 { total: 总行数, data: 数据数组 }
  console.log(res);
}).catch((error)=>{ 

  // 1.校验规则错误 2.interceptor设置的函数返回false
  console.log(error); // {msg:}
})
手动添加数据

场景:1. 需要在行数据上添加字段 2. 想要遍历指定字段然后中断读取操作 可以使用interceptor方法,此方法会回调给用户行数据和验证过后的错误消息,此函数如果返回false则表示中断excel读取操作,如果返回false此函数会触发catch回调


new importFileExcelDataVerifyTool({
  file: ev.target.files[0], //file对象 必传
  columns: [
    { 
      key: "列名比如商品编码", 
      type: 'string|number|boolean|float', //数据类型,用于转换数据
      toKey: "把列头字段转换成的字段比如goodCode", 
    },
  ],
})
.interceptor((rowData:any, err:[])=>{
  // 此方法不是必需要要有的,如果有数据转换或者要在行数据里面加些字段可以使用
  // 使用interceptor来进行数据装换, data为行数据
  rowData.field = Math.random();
  console.log(rowData);

  // return false直接中断操作抛出异常
  return true;
})
.valid() // 开始进行数据校验 必须有
.then((res)=>{
  // 没有任何错误,将返回数据
  // res 为 { total: 总行数, data: 数据数组 }
  console.log(res);
}).catch((error)=>{ 

  // 1.校验规则错误 2.interceptor设置的函数返回false
  console.log(error); // {msg:}
})
配置项说明

| 配置项 | 类型 | 说明 | 默认 | | ------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | file | file对象 | file对象 | 必填 | | sheet | 数字 | excel中如果有多个工作簿,可以通过sheet配置项来配置读取第几个工作簿的数据 | 0 | | isDebugger | 布尔 | 是否显示警告在控制台中 | false | | mimeType | 数组 | 设置可以读取的文件类型,默认 | ["application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ] | | max | 数字 | 最大行数 | 500 | | warn | 数字 | 预警行数 | 500 | | columns | 数组 | 配置excel列 | 必填 | | columns.key | 字符串 | 列名比如商品编码 | | | columns.type | ExcelType | 列名类型,描述此列数值的类型 | | | columns.toKey | 字符串 | 重命名key,比如key为商品编码,toKey为goodCode,那么导出的数据就是{goodCode:''}这种形式 | | | columns.rules | 数组 | rules:[{type:ExcelRule.CUSTOMER, valid:(row)=>{return row.goodCode=='a'}, msg:'自定义错误消息'},{type:ExcelRule.NUMBER, msg:'商品编码必须是数字'}] 注:msg可以为空,如果为空则会采用插件自带的提示 验证类型的可使用ExcelRule的枚举类型| |

方法说明

| 方法 | 说明 | | ----------- | ----------------------------------------------------------------------------------------------------------------------------- | | valid | 校验方法,必须调用 | | warn | 配置了warn字段必须调用,会有三个参数回调给用户(msg, confirm, cancel) msg为消息,confirm为用户继续操作,cancel表示取消数据读取 | | interceptor | 此方法会回调给用户当前行数据和错误消息,如果用户在此方法中返回false,会中断读取数据操作,并且会调用catch抛出异常 | | then | 数据读取完成无错误会回调给用户一个对象,{ total: 总行数, data: 数据数组 } | | catch | 数据读取中如果有校验错误或者在intercepotor里返回false都会触发此方法,并回调给用户一个对象{type:'error', msg:['错误消息']} |

枚举类型

| 类型 | 说明 | | --------- | ---------- | | ExcelRule | 内置规则枚举(NUMBER整数验证 MOBILE手机号验证 IDCARD身份证验证 NUMERIC小数验证 NOT_EMPTY非空验证 CUSTOMER自定义验证) | | ExcelType | 列类型枚举(STRING字符串 NUMBER整数数值包括负数 FLOAT小数 BOOLEAN布尔类型 DATETIME年月日时分秒格式 DATE年月日格式 TIME时分秒格式) |

FreeCustomRowLine - 增减行自由定义配置组件

支持能预先自由配置各种元素组合的单行模板(文字/ antd组件/ 自定义元素...)。 根据配置的单行模板,能够去生成n行该模板的独立数据控制,排序样式,单元素填值时的基础校验,最终生成表单数据。 同时支持单行的删除。(未来会支持 up down调序)。

基本使用

如下述示例,组成的是支持整单满[?]元,赠送[x?],[number?]的设置项;

import Bamboo, { FreeCustomRowLine, FreeCustomRowLine_EVENTTYPE, FreeCustomRowLine_ELEMENTTEMP } from 'bamboosnaketool';
const { FreeCustomRowLine } = Bamboo;

// 配置增减行
const freeCustomRowLineConfProps = {
  templateRow: [
    {
        elementTEMP: FreeCustomRowLine_ELEMENTTEMP.INNERHTML,
        style: { width: 38, marginRight: 8 }
    },
    '整单满',
    {
      elementTEMP: FreeCustomRowLine_ELEMENTTEMP.INPUTNUMBER,
      placeholder: '价格',
      maxLength: 8,
      style: { width: 100, marginLeft: 4, marginRight: 4 },
      apiOptions: {
        min: 0
      }
    },
    '元,赠送',
    {
      elementTEMP: FreeCustomRowLine_ELEMENTTEMP.INPUT,
      placeholder: '搜索商品',
      maxLength: 10,
      style: { width: 200, marginLeft: 4, marginRight: 4 }
    },
    ',',
    {
      elementTEMP: FreeCustomRowLine_ELEMENTTEMP.INPUTNUMBER,
      placeholder: '数量',
      maxLength: 4,
      style: { width: 90, marginLeft: 4, marginRight: 4 },
      apiOptions: {
        min: 0
      }
    }
  ],
  callback: (TYPE: EVENTTYPE, data: any) => {
    console.log(TYPE, data)
  }
};

// render...
<FreeCustomRowLine {...freeCustomRowLineConfProps} />

如何简单理解上述呢?templateRow 是确定单行模板的如下:

// 支持类型
{
    templateRow: [ string文本 | 内置模板对象 | JSX.Element ]
}

最终组件内部会平铺该数组内的所有内容组成完整的单行预模板;

初始化插入数据

支持通过数据对组件进行首次初始化的渲染生成。

下面的配置会初始化生成下列文本(由于无法附图,文字描述):

条件1:整单满 [inputNumber] 元,赠送 [input-autocomplate] ,数量 [inputNumber] 责任人 [select],备注:[input] (删除、锁定、向上移动、向下移动)

import Bamboo, { FreeCustomRowLine_ELEMENTTEMP } from 'bamboosnaketool';

const __awardLineMockDatas = [
  [
    { "value": `<span style="padding: 1px 5px; color: #fff; background-color: #FF7157; display: inline-block">类型</span>` },
    { "value": 128, disabled: true },
    {
      "value": "异步2",
      "valueId": "async2",
      "options": [
        { "value": "async1", "label": "异步1" },
        { "value": "async2", "label": "异步2" },
        { "value": "async3", "label": "异步3" }
      ]
    },
    { "value": 1 },
    { "value": "选项1", "valueId": "a1" },
    { "value": "撒大大" }
  ]
];

// 配置增减行
const shoppingAwardGiftConfProps = {
  datasource: __awardLineMockDatas,
  templateRow: [
      {
        elementTEMP: FreeCustomRowLine_ELEMENTTEMP.INNERHTML,
        style: { width: 38, marginRight: 8 }
      },
      '整单满',
      {
        stamp: 'PRICE',
        elementTEMP: ELEMENTTEMP.INPUTNUMBER,
        placeholder: '价格',
        maxLength: 8,
        style: { width: 100, marginLeft: 4, marginRight: 4 },
        apiOptions: {
          min: 0
        }
      },
      '元,赠送',
      {
        stamp: 'SEARCH_GOODS',
        elementTEMP: ELEMENTTEMP.AUTOCOMPLETE,
        placeholder: '搜索商品',
        maxLength: 10,
        style: { width: 200, marginLeft: 4, marginRight: 4 }
      },
      ',数量',
      {
        stamp: 'NUMBER',
        elementTEMP: ELEMENTTEMP.INPUTNUMBER,
        placeholder: '数量',
        maxLength: 4,
        style: { width: 90, marginLeft: 4, marginRight: 4 },
        apiOptions: {
          min: 0
        }
      },
      '责任人',
      {
        stamp: 'PRINCIPAL',
        elementTEMP: ELEMENTTEMP.SELECT,
        placeholder: '选择性',
        style: { width: 90, marginLeft: 4, marginRight: 4 },
        options: [
          { value: 'fzr1', label: '吴亦凡' },
          { value: 'fzr2', label: '鹿晗' },
          { value: 'fzr3', label: '黄子韬' }
        ],
        apiOptions: {}
      },
      ',备注:',
      {
        stamp: 'REMARK',
        elementTEMP: ELEMENTTEMP.INPUT,
        placeholder: '请输入备注内容',
        maxLength: 10,
        style: { width: 200, marginLeft: 4, marginRight: 4 }
      }
  ]
}
顶部按钮组

组件内置了顶部按钮组 ,该组可配置 [新增一行]、 [重置]、[自定义];

其中 [新增一行]、 [重置]为内置,组件Props { showAddButton, showResetButton } 为 true 时显示,否则隐藏;

同时也支持配置多个自定义按钮,通过配置后可以更灵活的实现应用。

// 可通过配置属性 customManaButtons 实现
import Bamboo, { FreeCustomRowLine_ManaButton } from 'bamboosnaketool';
import { PlusOutlined, DeleteOutlined } from '@ant-design/icons';
let freeCustomRowLineConfProps = {
    ...,
    customManaButtons: [
    	{
    		text: '自定义按钮1',
    		type: FreeCustomRowLine_ManaButton.CUSTOM,
    		stamp: 'ANY_NAME_1',
    		style: {
    			color: 'red'
			},
    		apiOptions: {
                icon: <PlusOutlined/>
            }
		},
        {
    		text: '自定义按钮2',
    		type: FreeCustomRowLine_ManaButton.CUSTOM,
    		stamp: 'ANY_NAME_2',
    		style: {
    			color: 'yellow'
			},
    		apiOptions: {
                icon: <DeleteOutlined/>
            }
		}
    ]
}

// render...
<FreeCustomRowLine {...freeCustomRowLineConfProps} />
// 事件响应回调 - 顶部按钮组

import Bamboo, { FreeCustomRowLine_ManaButtonProps } from 'bamboosnaketool';
let freeCustomRowLineConfProps = {
    ...,
    buttonsCallback: (TYPE: FreeCustomRowLine_ManaButton, data?: Pick<FreeCustomRowLine_ManaButtonProps, 'stamp'>) => {
        if (TYPE === FreeCustomRowLine_ManaButton.CUSTOM) {
            // 这里使用配置的stamp值进行多个自定义按钮情况的区别
            let stamp = data?.stamp;
            // do somethings ...
        }
    }
};
选项的构成 - options

我们把配置项中 templateRow 里的每一个索引内容称之为 '单元'。

options配置合法字段使用 { value: any, label: string };

那么单元目前除String文本外,就都是antd的封装组件了,其中 autocomplate、selecet都会是涉及到多选的options选项,那么这个怎么配?

下拉选项首先我们分为两种 初始配置异步设置 的,这两者带来的方式上也是不一样的,初始配置的只需配置一次覆盖所有生成行,异步设置的可以支持到 每一行的都不一样;

初始配置:适合固定的选择内容,比如每行都需要指定的选择 '负责人',而关联这次数据的的所有负责人池一共8人,那么原则上所有行的下拉负责人选项都可以是一致的;

异步配置:适合非固定选择内容,比如每行都需要模糊搜索到某个指定的内容,然后从模糊匹配到的下拉结果中选出一项,那么每一行最终选中的对象可能都不一致;

(!!!异步配置优先级高于初始配置,故异步配置动作是后置于初始配置,最终数据的渲染显示会是异步配置动作为准)

**初始配置

// 方式一  -  初始配置
const shoppingAwardGiftConfProps = {
  templateRow: [
    '选择责任人',
    {
      stamp: 'PRINCIPAL',
      elementTEMP: ELEMENTTEMP.SELECT,
      placeholder: '请选择负责人',
      style: { width: 90, marginLeft: 4, marginRight: 4 },
      options: [
        { value: 'fzr1', label: '吴亦凡' },
        { value: 'fzr2', label: '鹿晗' },
        { value: 'fzr3', label: '黄子韬' }
      ],
      apiOptions: {}
    }
 ],
 // other - config
}

**异步配置

异步的数据插入是根据行的,需要在回调内进行插入。

下面模拟在INPUT框输入后,模拟请求获取XX数据,使用内置函数options进行插入。

(!!!函数 slotFn ,在部分回调事件中不存在,只在具体行被操作后的响应动作存在,这是一个闭包函数,内置包裹了当前操作的rowIndex行索引和rItemIndex单元索引,直接对其进行数据操作插入即可)

import { FreeCustomRowLine_EVENTTYPE, FreeCustomRowLine_callBackProps } from 'bamboosnaketool';

// 方式二  -  异步配置
const shoppingAwardGiftConfProps = {
  templateRow: [
    '选择商品',
    {
        stamp: 'SEARCH_GOODS',
        elementTEMP: ELEMENTTEMP.AUTOCOMPLETE,
        placeholder: '搜索商品',
        maxLength: 10,
        style: { width: 200, marginLeft: 4, marginRight: 4 }
    }
 ],
 callback: (TYPE: FreeCustomRowLine_EVENTTYPE, data: FreeCustomRowLine_callBackProps) => {
     
     const { stamp, slotFn } = data;
     
     if (TYPE === FreeCustomRowLine_EVENTTYPE.INPUT) {
         if (stamp === 'SEARCH_GOODS') {
          let arr = [
            { value: 'async1', label: '异步1'},
            { value: 'async2', label: '异步2'},
            { value: 'async3', label: '异步3'}
          ];
          slotFn && slotFn({ options: arr });
        }
     }
 }
 // other - config
}
内置模板

演示内置模板单元的使用;

[
	...,
    {
      elementTEMP: FreeCustomRowLine_ELEMENTTEMP.INPUTNUMBER,
      placeholder: '数量',
      maxLength: 4,
      style: { width: 90, marginLeft: 4, marginRight: 4 },
      apiOptions: {
         min: 0
      }
    }
]

// 内置的模板 elementTEMP 作为它的type类型指定,可通过枚举 ELEMENTTEMP 来选取指定 (完整的单模板内容参考下面#完整参数类型)
// 目前支持 几种应用场景
// 普通输入框、纯数字输入框、支持搜索下拉的自动完成输入框、和普通文本SPAN标签元素,如下
enum FreeCustomRowLine_ELEMENTTEMP {
  INPUT,             // 输入框 - 普通
  INPUTNUMBER,       // 输入框 - 数字
  AUTOCOMPLETE,      // 输入框 - 自动完成
  SELECT,            // 下拉选择项
  SPAN,              // 文本内容
  INNERHTML          // 元素方式
}

// 根据对元素类型的规范理解使用 [placeholder/ maxLength/ value ];
// [style] 为通用类型,可对样式进行实际展示需要微调;
// apiOptions - 是antd的内置API支持,这些单元模板枚举完整的对应了antd的实际组件,具体可参考官方文档;
配置按钮

配置单行模板后缀(右侧)的控制按钮组。

支持删除一行,锁定一行(貌似没有需求会用到,暂未开发),向上移动一行,向下移动一行,

import { FreeCustomRowLine_LINEBUTTONS } from 'bamboosnaketool';

// 默认仅显示[删除]按钮,目前完整按钮包含4个 [ 删除/ 锁定行/ 向上移动/ 向下移动 ]
{
  lineButtons: [
  	 [ true,  { type: FreeCustomRowLine_LINEBUTTONS.DELETE }],
  	 [ false, { type: FreeCustomRowLine_LINEBUTTONS.LOCK }],
  	 [ false, { type: FreeCustomRowLine_LINEBUTTONS.MOVE_UP }],
  	 [ false, { type: FreeCustomRowLine_LINEBUTTONS.MOVE_DOWN }]
  ],
  // ...
}
// 为 true 则显示反之隐藏,渲染顺序会根据当前配置内的数组排序为准

// 按钮会默认赋值内置的中文文本名称,也可以对text属性进行自定义,例↓:
[ true, { type: FreeCustomRowLine_LINEBUTTONS.DELETE, text: '剔除' }]

// 如需隐藏文本名称,可使用 hideText 配置如下:
[ true, { type: FreeCustomRowLine_LINEBUTTONS.DELETE, hideText: true }]
    
// 如何给按钮配置icon,且能同时结合 hideText 达到效果  (apiOptions - 参考antd组件api)
import { DeleteOutlined } from '@ant-design/icons';
[ true, { type: FreeCustomRowLine_LINEBUTTONS.DELETE, hideText: true, apiOtions: { icon: <DeleteOutlined>} }]
禁用

对单元进行禁用属性设置。(仅对支持disabled的对象有效)

方式有两种:渲染数据内 / 初始配置;

{ disabled: true }

回调响应

所有事件的响应都会callback统一抛出,可根据返回的行号几行内单元号进行具体的需求操作。

import { FreeCustomRowLine_callBackProps } from 'bamboosnaketool';
const freeCustomRowLineConfProps = {
  templateRow: [
    ...
  ],
  callback: (TYPE: FreeCustomRowLine_EVENTTYPE, data: FreeCustomRowLine_callBackProps) => {
    const { allLineDatas, rowIndex, valIndex, value, slotFn?, prevAllLineDatas?, stamp? } = data;
    console.log(TYPE, data);
  }
};

// 回调响应事件类型
export enum FreeCustomRowLine_EVENTTYPE {
  INIT  ='INIT',        // 初始化
  INPUT = 'INPUT',      // 输入响应
  SELECT = 'SELECT',    // 选中
  ADD   = 'ADD',        // 新增一行
  DELETE = 'DELETE',    // 删除一行
  FOCUS = 'FOCUS',      // INPUT类型聚焦
  BLUR  = 'BLUR'        // INPUT类型失焦
}

// 响应回调返回的data数据
data = {
  allLineDatas,		// 完整的数据
  rowIndex,			// 行的下标
  valIndex,         // 单行内的下标
  value,			// 响应 value / id
  slotFn,           // 行数据设置函数 - 闭包(直接设参,内置精确索引)
  stamp				// 印章 - 可用户多一种途径区别单元类型
}
完整参数类型
// 控件模板类型(antd)
export enum FreeCustomRowLine_ELEMENTTEMP {
  INPUT,             // 输入框 - 普通
  INPUTNUMBER,       // 输入框 - 数字
  AUTOCOMPLETE,      // 输入框 - 自动完成
  SELECT,            // 下拉选择项
  SPAN,              // 文本内容
  INNERHTML          // 元素方式
}

// 模板单item配置
export interface templateRowItemConf {
  elementTEMP: FreeCustomRowLine_ELEMENTTEMP; // 模板类型
  stamp?: string;                    // 印记 - 可用于回调事件做单元区别(多提供一种定位单元手动,处index定位外)
  text?: string;                            // 文本
  value?: string | number;                  // inputValue -  仅input [select/ input/ textarea/ ...]类型支持
  options?: any[];                          // select-options / autocomplate-options (仅支持antd - select/ autocomplate 组件)
  disabled?: boolean;                       // 是否禁用该单元
  style?: CSSStyleDeclaration | {};         // 样式
  placeholder?: string;                     // 框内描述      - 仅input类型支持
  maxLength?: string | number;              // 最大输入长度  -  仅input类型支持
  apiOptions?: {[x:string]: any}            // antd-ui api
}

// 完整单行描述
export type templateRows = Array<templateRowItemConf | string | JSX.Element>

// 回调响应事件类型
export enum FreeCustomRowLine_EVENTT