# sula ruler
# 介绍
Sula-Ruler 是基于 rc-field-form
的 List 组件实现的,同时对于组件间通信和关联方面做了增强。Sula-Ruler主要解决了前端中台规则组件(例如左值、比较符、右值的复杂表单组件)开发成本高的问题。
# 特性
统一的表单组件管理能力 组件间通信与关联能力增强 内置视觉与交互规范 高效、高体验开发规则类复杂表单组件
# ruler 核心
# 使用方法
import Ruler from '@sula/ruler';
const {
List,
Row,
Field,
} = Ruler;
示例
import React from "react";
import Ruler from "@sula/ruler";
import { Row, Col, Button, Select, Input } from "antd";
export default props => {
const onChange = value => {}
const onFieldValueChange = ctx => {
if (ctx.value === '95') {
ctx.setSiblingSource('level', [{ text: '终极', value: 'Super' }])
ctx.setSiblingValue('level', 'Super')
} else {
if (ctx.getSiblingValue('level') === 'High') {
ctx.setSiblingValue('level', 'High')
}
}
}
const onFieldDidMount = ctx => {
if (ctx.name === 'level') {
ctx.setSource([{ text: '高级', value: 'High' }])
}
}
return (
<div>
<Ruler
onChange={onChange}
onFieldValueChange={onFieldValueChange}
onFieldDidMount={onFieldDidMount}
>
{(lists, { add, remove }) => {
const listElems = lists.map(list => {
return (
<Ruler.List name={list.name} key={list.key}>
{(conditions, op) => {
const conditionElems = conditions.map(condition => {
return (
<Ruler.Row name={condition.name} key={condition.key}>
<Row type="flex">
<Col>
<Ruler.Field
name="singer"
key="singer"
rules={[{ required: true }]}
>
<Input
placeholder={`${list.name}-${condition.name}-singer`}
/>
</Ruler.Field>
</Col>
<Col>
<Ruler.Field name="level" key="level">
{({
prevValue,
value,
getSiblingValue,
source,
}) => {
const singerValue = getSiblingValue('singer')
return (
<Input
placeholder={`${list.name}-${condition.name}-level`}
/>
)
}}
</Ruler.Field>
</Col>
</Row>
</Ruler.Row>
)
})
return (
<div
style={{
marginBottom: 16,
border: '1px solid green',
padding: 8,
}}
>
<Select style={{ width: 120 }} />
{conditionElems}
<div>
<Button
icon="plus"
onClick={() => {
op.add()
}}
>{`listName: ${list.name} - add field`}</Button>
<Button
type="danger"
icon="minus"
onClick={() => {
op.remove(1)
}}
>{`listName: ${list.name} - remove field 1`}</Button>
</div>
</div>
)
}}
</Ruler.List>
)
})
return (
<div>
{listElems}
<div>
<Button
type="primary"
onClick={() => {
add()
}}
>
add list
</Button>{' '}
<Button
onClick={() => {
remove(0)
}}
>
remove list 0
</Button>
</div>
</div>
)
}}
</Ruler>
<br />
</div>
)
};
# API
Ruler
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
onChange | 变化回调 | Function(value: any[]) | - |
value | 规则组件值 | any[] | - |
onFieldValueChange | 输入值变化时,用于一行中的组件存在关联的场景 | Function(ctx: Ctx) ,见下 | - |
onFieldDidMount | 当添加一个field时,产生的回调,通常你可以在这里设置field的初始数据源 | Function(ctx: Ctx) ,见下 | - |
disabled | 是否禁用 | boolean | false |
children | 渲染子元素 | Function(lists: {name: number, key: number}[], operation: {add: Function, remove: Function(name: number)}): React.ReactElement | - |
hasValidate | 是否支持校验条件,false时会使用更紧凑的展现方式 | boolean | true |
interface Ctx {
name: string;
meta: Meta;
prevValue: any;
value: any;
getSiblingValue: (name: string) => any;
setSiblingValue: (name: string, value: any) => void;
setSiblingValues: (values: { name: string; value: any }[]) => void;
setSiblingSource: (name: string, source: any) => void;
setSource(source: { text: string; value: any }[]); // 只有在onFieldDidMount才会有
}
Ruler.List
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
name | 永远为0~N(N为当前list个数)间的一个数字 | number | - |
key | 用于React数组节点的唯一key | number | - |
children | 渲染子元素 | Function(rows: {name: number, key: number}[], operation: {add: Function, remove: Function(name: number)}): React.ReactElement | - |
Ruler.Row
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
name | 永远为0~N(N为当前Row个数)间的一个数字 | number | - |
key | 用于React数组节点的唯一key | number | - |
Ruler.Field
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
name | 对应该表单组件在value中的key,例如name为level,value为[[{level: 'High'}]] | string | - |
key | 唯一key | string | - |
rules | 检验条件 | string | - |
children | 渲染子元素,render模式用于根据行其他表单元素不同值采用不同的呈现 | ReactElement | Function(ctx: Ctx): ReactElement ,ctx见下 |
interface Ctx {
name: string;
meta: Meta;
prevValue: any;
value: any;
getSiblingValue: (name: string) => any;
}
# RulerRow 行条件
# 使用方法
import RulerRow from '@sula-ruler/row';
# API
RulerRow
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
add | 增加一行的调用方法 | Function | - |
remove | 删除当前行的调用方法 | Function(name: number) | - |
fields | 一行中的表单元素定义 | Field[] ,见下 | - |
key | 用于React数组节点的唯一key | number | - |
name | 永远为0~N(N为当前Row个数)间的一个数字 | number | - |
style | 样式 | React.CSSProperties | - |
className | 样式类 | string | - |
interface Field {
name: string;
| defaultValue: any; // 该field的初始值
getValueFromEvent?: (...args: EventArgs) => any;
valuePropName?: string;
trigger?: string;
children: React.ReactElement | ((ctx: Ctx) => React.ReactNode);
rules?: Rule[];
render: React.ReactElement | ((ctx: Ctx) => React.ReactNode);
span?: number;
}
interface Ctx {
name: string;
meta: Meta;
prevValue: any;
value: any;
getSiblingValue: (name: string) => any;
}
# RuleList 多行条件
# 使用方法
import RulerList from '@sula-ruler/list';
# API
RulerList
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
range | list中展示的行数范围 | [number, number] | - |
fields | 一行中的表单元素定义 | Field[] ,见下 | - |
key | 用于React数组节点的唯一key | number | - |
name | 永远为0~N(N为当前Row个数)间的一个数字 | number | - |
children | 渲染子元素 | Function(lists: {name: number, key: number}[], operation: {add: Function, remove: Function(name: number)}): React.ReactElement | - |
interface Field {
name: string;
getValueFromEvent?: (...args: EventArgs) => any;
valuePropName?: string;
trigger?: string;
children: React.ReactElement | ((ctx: Ctx) => React.ReactNode);
rules?: Rule[];
render: React.ReactElement | ((ctx: Ctx) => React.ReactNode);
span?: number;
}
interface Ctx {
name: string;
meta: Meta;
prevValue: any;
value: any;
getSiblingValue: (name: string) => any;
}
# Condition 多条件
# 使用方法
import Condition from "@sula-ruler/condition";
示例:
import React from 'react';
import Condition from '@sula-ruler/condition';
import { Input } from 'antd';
const fields = [{
name: "source",
span: 8,
render: (ctx) => {
const { source = [] } = ctx;
return (
<Select placeholder="远程数据源" style={{ width: "100%" }}>
{source.map((item) => {
return <Option key={item.id}>{item.title}</Option>;
})}
</Select>
)}
}, {
name: 'fruit',
span: 8,
defaultValue: '苹果',
render: <Input placeholder="水果" />
}, {
name: 'price',
span: 8,
defaultValue: 10,
render: <Input placeholder="价格" />
}]
const ConditionRule = (props) => {
const [value, setValue] = React.useState([{fruit: '苹果', price: 10}]);
const handleChange = (val) => {
console.log('value: ', val);
setValue(val);
};
const onFieldDidMount = (ctx) => {
fetch({
url: 'https://jsonplaceholder.typicode.com/posts'
}).then(source => {
if(ctx.name === 'source') {
ctx.setSource(source);
}
});
}
const onFieldValueChange = ctx => {
const { value, setSiblingValue } = ctx;
if (value === "apple") {
setSiblingValue("price", 10);
} else {
setSiblingValue("price", 15);
}
};
return <Condition
range={[1]}
onChange={handleChange}
value={value}
fields={fields}
onFieldDidMount={onFieldDidMount}
onFieldValueChange={onFieldValueChange}
/>
}
export default () => <ConditionRule />;
# API
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
range | list中展示的行数范围 | [number] | - |
fields | 一行中的表单元素定义 | Field[] ,见下 | - |
onChange | 变化回调 | Function(value: any[]) | - |
onFieldValueChange | 输入值变化时,用于一行中的组件存在关联的场景 | Function(ctx: Ctx) ,见下 | - |
onFieldDidMount | 当添加一个field时,产生的回调,通常你可以在这里设置field的初始数据源 | Function(ctx: Ctx) ,见下 | - |
value | 规则组件值 | any[] | - |
disabled | 是否禁用 | boolean | false |
hasValidate | 是否支持校验条件,false时会使用更紧凑的展现方式 | boolean | true |
# ConditionGroup 分组多行条件
ConditionGroup对Ruler和RulerList进行了封装,你可以直接使用ConditionGroup是实现分组多条件呈现。
# 使用方法
import ConditionGroup from '@sula-ruler/condition-group';
示例:
import React from "react";
import ConditionGroup from "@sula-ruler/condition-group";
import { Input } from "antd";
const fields = [
{
name: "fruit",
span: 12,
render: <Input placeholder="水果" />
},
{
name: "price",
span: 12,
render: <Input placeholder="价格" />
}
];
const ConditionGroupRule = props => {
const [value, setValue] = React.useState([[{fruit: '苹果', price: 10}]]);
const handleChange = val => {
console.log("value: ", val);
setValue(val);
};
return (
<ConditionGroup
titleRender={name => `Group ${name}`}
onChange={handleChange}
value={value}
fields={fields}
range={[1]}
groupRange={[1]}
></ConditionGroup>
);
};
export default () => <ConditionGroupRule />;
# API
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
range | list中展示的行数范围 | [number] | - |
fields | 一行中的表单元素定义 | Field[] ,见下 | - |
onChange | 变化回调 | Function(value: any[]) | - |
onFieldValueChange | 输入值变化时,用于一行中的组件存在关联的场景 | Function(ctx: Ctx) ,见下 | - |
onFieldDidMount | 当添加一个field时,产生的回调,通常你可以在这里设置field的初始数据源 | Function(ctx: Ctx) ,见下 | - |
value | 规则组件值 | any[] | - |
disabled | 是否禁用 | boolean | false |
hasValidate | 是否支持校验条件,false时会使用更紧凑的展现方式 | boolean | true |
titleRender | 组标题 | Function() | - |
groupRange | 最少组数 | [number] | - |