plain-design 1.0.0-beta.131 → 1.0.0-beta.133
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plain-design.commonjs.min.js +2 -2
- package/dist/plain-design.min.css +5 -4
- package/dist/plain-design.min.js +2 -2
- package/dist/report.html +2 -2
- package/package.json +1 -1
- package/src/packages/components/AutoTable/auto-table.scss +21 -0
- package/src/packages/components/AutoTable/filter/useTableOption.filter.state.ts +3 -2
- package/src/packages/components/AutoTable/use/useTableOption.column.popper.tsx +1 -1
- package/src/packages/components/AutoTable/use/useTableOption.fill.tsx +2 -2
- package/src/packages/components/AutoTable/use/useTableOption.hooks.tsx +4 -2
- package/src/packages/components/AutoTable/use/useTableOption.pagination.tsx +1 -1
- package/src/packages/components/AutoTable/use/useTableOption.table.tsx +5 -3
- package/src/packages/components/AutoTable/use/useTableOption.tips.tsx +2 -2
- package/src/packages/components/AutoTable/utils/TableOption.space.tsx +5 -2
- package/src/packages/components/Dropdown/index.tsx +14 -1
- package/src/packages/components/Form/form.scss +4 -0
- package/src/packages/components/Form/layout/useFormLayout.tsx +1 -0
- package/src/packages/components/FormItem/index.tsx +7 -0
- package/src/packages/components/Input/useSuggestionInput.tsx +2 -1
- package/src/packages/components/ListOption/index.tsx +20 -0
- package/src/packages/components/ListPanel/index.tsx +30 -0
- package/src/packages/components/ListPanel/list-panel.scss +20 -0
- package/src/packages/components/Select/createPublicSelectRender.tsx +4 -2
- package/src/packages/components/Select/decodeSelectRenderNode.tsx +4 -2
- package/src/packages/components/Select/index.tsx +13 -1
- package/src/packages/components/Select/select.utils.tsx +3 -2
- package/src/packages/components/Table/plc/use/useTableAutoSpan.tsx +112 -0
- package/src/packages/components/Table/plc/utils/plc.utils.ts +3 -0
- package/src/packages/components/Table/standard/PlcOperation/PlcOperation.tsx +3 -3
- package/src/packages/components/Table/table/Table.tsx +10 -6
- package/src/packages/components/Table/table/body/cell.tsx +34 -3
- package/src/packages/components/Table/table/body/useCellValue.tsx +14 -5
- package/src/packages/components/Table/table/head/head-cell.tsx +6 -0
- package/src/packages/components/Table/table/table.scss +4 -0
- package/src/packages/components/Table/table/use/useTableFormEditor.tsx +5 -1
- package/src/packages/components/Table/table/use/useTableModifyEditor.tsx +8 -2
- package/src/packages/components/Table/table/utils/createTableHooks.ts +5 -3
- package/src/packages/components/Table/table/utils/table.utils.ts +3 -2
- package/src/packages/components/VirtualTable/index.tsx +6 -0
- package/src/packages/components/VirtualTable/virtual-table.scss +3 -3
- package/src/packages/components/createSimpleDate/index.ts +49 -0
- package/src/packages/components/useContextmenuOptions/index.tsx +40 -0
- package/src/packages/components/useTableFilter/index.ts +73 -0
- package/src/packages/entry.tsx +26 -0
package/package.json
CHANGED
|
@@ -38,6 +38,21 @@
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
@include comp(table) {
|
|
42
|
+
&.table-border {
|
|
43
|
+
margin: $margin 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@include comp(auto-table-tips) {
|
|
48
|
+
|
|
49
|
+
& + .#{componentName(table)} {
|
|
50
|
+
&.table-border {
|
|
51
|
+
margin-top: 0;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
41
56
|
& + .#{componentName(auto-table)}, & + .#{componentName(tab-group)} {
|
|
42
57
|
margin-top: $margin;
|
|
43
58
|
}
|
|
@@ -146,6 +161,12 @@
|
|
|
146
161
|
}
|
|
147
162
|
}
|
|
148
163
|
|
|
164
|
+
&[data-no-clear=true] {
|
|
165
|
+
.auto-table-tips-label {
|
|
166
|
+
padding-right: 4px
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
149
170
|
/* & + .#{componentName(button)} {
|
|
150
171
|
@include comp(icon) {
|
|
151
172
|
position: relative;
|
|
@@ -84,9 +84,10 @@ export const useTableOptionFilterState = AutoModule.createRegistration(({ hooks,
|
|
|
84
84
|
* @author 韦胜健
|
|
85
85
|
* @date 2023.1.3 21:29
|
|
86
86
|
*/
|
|
87
|
-
const clearAll = (reload?: boolean) => {
|
|
87
|
+
const clearAll = async (reload?: boolean) => {
|
|
88
|
+
await hooks.onClearFilter.exec(undefined);
|
|
88
89
|
state.filters.forEach(i => i.clear());
|
|
89
|
-
reload !== false && methods.pageMethods.reload();
|
|
90
|
+
reload !== false && await methods.pageMethods.reload();
|
|
90
91
|
};
|
|
91
92
|
|
|
92
93
|
/**
|
|
@@ -233,7 +233,7 @@ export const useTableOptionColumnPopper = AutoModule.createRegistration((
|
|
|
233
233
|
|
|
234
234
|
const open = async (plc: tPlc) => {
|
|
235
235
|
popperHandler.close();
|
|
236
|
-
const wrapperStyles = { width: '
|
|
236
|
+
const wrapperStyles = { width: '700px' };
|
|
237
237
|
const field = plc.props.searchField || plc.props.field;
|
|
238
238
|
if (!field) {return;}
|
|
239
239
|
const excludeCode = nextPlcExcludeCode();
|
|
@@ -80,7 +80,7 @@ export const useTableOptionFill = AutoModule.createRegistration((
|
|
|
80
80
|
};
|
|
81
81
|
})();
|
|
82
82
|
|
|
83
|
-
await delay(73)
|
|
83
|
+
await delay(73);
|
|
84
84
|
/**
|
|
85
85
|
* 计算可以用来渲染行的高度
|
|
86
86
|
* parent.top+parent.height可以得到父节点底边界的top值;
|
|
@@ -105,7 +105,7 @@ export const useTableOptionFill = AutoModule.createRegistration((
|
|
|
105
105
|
const showRows = Math.floor(availableHeight / bodyRowHeight);
|
|
106
106
|
|
|
107
107
|
/*更新分页查询信息*/
|
|
108
|
-
pagination.state.size = showRows;
|
|
108
|
+
pagination.state.size = config.pageSize || showRows;
|
|
109
109
|
pagination.state.pageSizeOptions.indexOf(showRows) === -1 && (pagination.state.pageSizeOptions.unshift(showRows));
|
|
110
110
|
state.showRows = showRows;
|
|
111
111
|
state.init = true;
|
|
@@ -53,6 +53,7 @@ export const useTableOptionHooks = AutoModule.createRegistration(() => {
|
|
|
53
53
|
onCollectSortData: createSyncHooks<(sortData: iTableSortData[]) => void>(true), // 收集排序数据
|
|
54
54
|
onQueryParam: createSyncHooks<(queryParam: iFilterHandlerQueryParam | null) => void>(), // 收集筛选参数
|
|
55
55
|
onTips: createSyncHooks<(tips: TableOptionSpace.iTableOptionTipMeta[]) => void>(true), // 渲染提示
|
|
56
|
+
onClearFilter: createHooks<() => void>(), // 清空筛选动作
|
|
56
57
|
|
|
57
58
|
/*---------------------------------------触发动作-------------------------------------------*/
|
|
58
59
|
// 触发新建动作
|
|
@@ -63,8 +64,9 @@ export const useTableOptionHooks = AutoModule.createRegistration(() => {
|
|
|
63
64
|
/*---------------------------------------table事件-------------------------------------------*/
|
|
64
65
|
onClickRow: createHooks<(data: { node: iTableNode, e: iMouseEvent }) => void>(),
|
|
65
66
|
onDblclickRow: createHooks<(data: { node: iTableNode, e: iMouseEvent }) => void>(),
|
|
66
|
-
onClickCell: createHooks<(data: { node: iTableNode, e: iMouseEvent }) => void>(),
|
|
67
|
-
onDblclickCell: createHooks<(data: { node: iTableNode, e: iMouseEvent }) => void>(),
|
|
67
|
+
onClickCell: createHooks<(data: { node: iTableNode, e: iMouseEvent, plc: tPlc }) => void>(),
|
|
68
|
+
onDblclickCell: createHooks<(data: { node: iTableNode, e: iMouseEvent, plc: tPlc }) => void>(),
|
|
69
|
+
onContextmenuCell: createHooks<(data: { node: iTableNode, e: iMouseEvent, plc: tPlc }) => void>(),
|
|
68
70
|
onClickHead: createHooks<(data: { plc: tPlcType, e: iMouseEvent }) => void>(),
|
|
69
71
|
|
|
70
72
|
/*---------------------------------------load-------------------------------------------*/
|
|
@@ -30,7 +30,7 @@ export const useTableOptionPagination = AutoModule.createRegistration((
|
|
|
30
30
|
createInitialData: (): iAutoTablePageData => {
|
|
31
31
|
return {
|
|
32
32
|
page: 1,
|
|
33
|
-
size: config.showRows,
|
|
33
|
+
size: config.pageSize || config.showRows,
|
|
34
34
|
hasNext: true,
|
|
35
35
|
total: null as null | number,
|
|
36
36
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {Table} from "../../Table";
|
|
2
2
|
import {iTableNode} from "../../Table/table/utils/table.utils";
|
|
3
|
-
import {tPlcType} from "../../Table/plc/utils/plc.utils";
|
|
3
|
+
import {tPlc, tPlcType} from "../../Table/plc/utils/plc.utils";
|
|
4
4
|
import {PlainObject} from "@peryl/utils/event";
|
|
5
5
|
import '../utils/TableOption.space';
|
|
6
6
|
import {PlcIndex} from "../../Table/standard/PlcIndex";
|
|
@@ -35,8 +35,9 @@ export const useTableOptionTable = AutoModule.createRegistration((
|
|
|
35
35
|
const handler = {
|
|
36
36
|
onClickRow: (node: iTableNode, e: iMouseEvent) => {hooks.onClickRow.exec({ node, e });},
|
|
37
37
|
onDblclickRow: (node: iTableNode, e: iMouseEvent) => {hooks.onDblclickRow.exec({ node, e });},
|
|
38
|
-
onClickCell: (node: iTableNode, e: iMouseEvent) => {hooks.onClickCell.exec({ node, e });},
|
|
39
|
-
onDblclickCell: (node: iTableNode, e: iMouseEvent) => {hooks.onDblclickCell.exec({ node, e });},
|
|
38
|
+
onClickCell: (node: iTableNode, e: iMouseEvent, plc: tPlc) => {hooks.onClickCell.exec({ node, e, plc });},
|
|
39
|
+
onDblclickCell: (node: iTableNode, e: iMouseEvent, plc: tPlc) => {hooks.onDblclickCell.exec({ node, e, plc });},
|
|
40
|
+
onContextmenuCell: (node: iTableNode, e: iMouseEvent, plc: tPlc) => {hooks.onContextmenuCell.exec({ node, e, plc });},
|
|
40
41
|
onClickHead: (plc: tPlcType, e: iMouseEvent) => {hooks.onClickHead.exec({ plc, e });},
|
|
41
42
|
onCurrentChange: (data: PlainObject | null) => {hooks.onCurrentChange.exec(data);},
|
|
42
43
|
onCollectPlcData: hooks.onCollectPlcData.exec,
|
|
@@ -73,6 +74,7 @@ export const useTableOptionTable = AutoModule.createRegistration((
|
|
|
73
74
|
config: cache.tablePropsConfig,
|
|
74
75
|
headRowHeight: config.headRowHeight,
|
|
75
76
|
bodyRowHeight: config.bodyRowHeight,
|
|
77
|
+
...config.tableProps,
|
|
76
78
|
...handler,
|
|
77
79
|
})}
|
|
78
80
|
v-slots={{ default: () => hooks.onRenderColumns.exec(), }}
|
|
@@ -77,10 +77,10 @@ export const RenderTableOptionTipItem = designComponent({
|
|
|
77
77
|
}),
|
|
78
78
|
});
|
|
79
79
|
return () => (
|
|
80
|
-
<div onClick={props.tip.onClick} className="auto-table-tips-item">
|
|
80
|
+
<div onClick={props.tip.onClick} className="auto-table-tips-item" data-no-clear={!props.tip.onClear || props.tip.noClear}>
|
|
81
81
|
<span className="auto-table-tips-label" ref={onRef.el}>{props.tip.display()}</span>
|
|
82
82
|
<div className="auto-table-tips-separator"/>
|
|
83
|
-
{!!props.tip.onClear && <Icon className="auto-table-tips-close" icon="pi-close" onClick={props.tip.onClear}/>}
|
|
83
|
+
{!!props.tip.onClear && !props.tip.noClear && <Icon className="auto-table-tips-close" icon="pi-close" onClick={props.tip.onClear}/>}
|
|
84
84
|
</div>
|
|
85
85
|
);
|
|
86
86
|
},
|
|
@@ -12,7 +12,7 @@ import {FilterFormSingle} from "../../FilterFormSingle";
|
|
|
12
12
|
import {Pagination} from "../../Pagination";
|
|
13
13
|
import {tPlc} from "../../Table/plc/utils/plc.utils";
|
|
14
14
|
import {iEffects} from '@peryl/utils/createEffects';
|
|
15
|
-
import {iTableNode, iTableSortData} from "../../Table/table/utils/table.utils";
|
|
15
|
+
import {iTableNode, iTablePropsType, iTableSortData} from "../../Table/table/utils/table.utils";
|
|
16
16
|
import {eTableOptionEditType} from "./TableOption.utils";
|
|
17
17
|
|
|
18
18
|
export namespace TableOptionSpace {
|
|
@@ -36,6 +36,7 @@ export namespace TableOptionSpace {
|
|
|
36
36
|
loadOnStart?: boolean, // 是否页面初始化的时候就加载数据
|
|
37
37
|
copyDefaultExcludeKeys: string[], // 复制一行的时候,不复制的属性
|
|
38
38
|
showRows: number, // 显示的行数(自动计算表格的高度)
|
|
39
|
+
pageSize?: number, // 查询的行数
|
|
39
40
|
showRowsMode: 'fixed' | 'auto', // 显示行数的模式,自动根据 加载的数据展示还是固定行数
|
|
40
41
|
sort?: iTableOptionSortParam | iTableOptionSortParam[], // 排序方式
|
|
41
42
|
getCache: (key: string) => iTableOptionCacheData | undefined, // 获取缓存配置信息
|
|
@@ -68,7 +69,8 @@ export namespace TableOptionSpace {
|
|
|
68
69
|
paginationAttrs?: Partial<typeof Pagination.use.props>, // 给分页组件传递的属性设置
|
|
69
70
|
parentOption?: Record<string, any>, // 父表的option
|
|
70
71
|
parentMap?: Record<string, any>, // 父表的字段映射
|
|
71
|
-
minShowRows?: number,
|
|
72
|
+
minShowRows?: number, // BaseTable的minShowRows
|
|
73
|
+
tableProps?: Partial<iTablePropsType>, // 传递给table的控制属性
|
|
72
74
|
// todo
|
|
73
75
|
noHead?: boolean, // 不显示表头
|
|
74
76
|
}
|
|
@@ -146,6 +148,7 @@ export namespace TableOptionSpace {
|
|
|
146
148
|
display: () => RenderNode,
|
|
147
149
|
onClear?: (e: iMouseEvent) => void,
|
|
148
150
|
onClick: () => void,
|
|
151
|
+
noClear?: boolean,
|
|
149
152
|
}
|
|
150
153
|
|
|
151
154
|
/**
|
|
@@ -11,6 +11,8 @@ import {DropdownGroup} from "../DropdownGroup";
|
|
|
11
11
|
import {unit} from "@peryl/utils/unit";
|
|
12
12
|
import {Popup} from "../Popup";
|
|
13
13
|
import {ePopupTrigger, iPopupAnimation, iPopupPlacement, iPopupTrigger} from "../usePopup/utils/popup.utils";
|
|
14
|
+
import ApplicationConfigurationProvider from "../ApplicationConfigurationProvider";
|
|
15
|
+
import {removeUnit} from "@peryl/utils/removeUnit";
|
|
14
16
|
|
|
15
17
|
export const Dropdown = designComponent({
|
|
16
18
|
name: '-dropdown',
|
|
@@ -30,6 +32,7 @@ export const Dropdown = designComponent({
|
|
|
30
32
|
|
|
31
33
|
id: { type: String }, // 调试plain-popper标识
|
|
32
34
|
optionWidth: {}, // option选项宽度
|
|
35
|
+
scrollHeight: { type: Number }, // 选项过多时自定义滚动高度
|
|
33
36
|
},
|
|
34
37
|
emits: {
|
|
35
38
|
onUpdateModelValue: (val?: boolean) => true,
|
|
@@ -46,6 +49,8 @@ export const Dropdown = designComponent({
|
|
|
46
49
|
},
|
|
47
50
|
setup({ props, slots, event: { emit }, scopeSlots, attrs }) {
|
|
48
51
|
|
|
52
|
+
const configuration = ApplicationConfigurationProvider.inject();
|
|
53
|
+
|
|
49
54
|
const { styleComputed } = useStyle();
|
|
50
55
|
|
|
51
56
|
const model = useModel(() => props.modelValue, emit.onUpdateModelValue);
|
|
@@ -58,6 +63,14 @@ export const Dropdown = designComponent({
|
|
|
58
63
|
|
|
59
64
|
const dropdownContentWidth = computed(() => !props.optionWidth ? undefined : unit(props.optionWidth as any)!);
|
|
60
65
|
|
|
66
|
+
const scrollHeight = computed((): number => {
|
|
67
|
+
if (props.scrollHeight != null) {return props.scrollHeight;}
|
|
68
|
+
const fontSize = Number(removeUnit(configuration.value.theme.vars[`font-size-${styleComputed.value.size}`]));
|
|
69
|
+
const paddingY = Number(removeUnit(configuration.value.theme.vars[`dropdown-size-${styleComputed.value.size}-padding-y`]));
|
|
70
|
+
const itemHeight = fontSize + paddingY * 2 + 6 + 2;
|
|
71
|
+
return itemHeight * 6;
|
|
72
|
+
});
|
|
73
|
+
|
|
61
74
|
const handler: iDropdownContext["handler"] = {
|
|
62
75
|
onClickOption: (optionContext) => {
|
|
63
76
|
if (optionContext.hasChildren.value) {
|
|
@@ -110,7 +123,7 @@ export const Dropdown = designComponent({
|
|
|
110
123
|
} else {
|
|
111
124
|
return renderDropdownPanel({
|
|
112
125
|
...publicDropdownPanelParams,
|
|
113
|
-
attrs: { style: { height: '
|
|
126
|
+
attrs: { style: { height: scrollHeight.value + 'px', width: dropdownContentWidth.value, }, key },
|
|
114
127
|
content: <>
|
|
115
128
|
<Scroll>
|
|
116
129
|
{children}
|
|
@@ -71,6 +71,7 @@ export const FormItemLayoutPropsOption = {
|
|
|
71
71
|
colon: { type: Boolean as PropType<boolean | null>, default: null }, // label的冒号
|
|
72
72
|
validateMessagePosition: { type: String as PropType<typeof FormValidateMessagePosition.TYPE> }, // 校验消息的位置
|
|
73
73
|
negativeInnerMarginTop: { type: Boolean }, // inner节点启用负的marginTop值
|
|
74
|
+
tip: { type: [String, Function] as PropType<string | (() => any)> }, // 提示说明
|
|
74
75
|
} as const;
|
|
75
76
|
|
|
76
77
|
/**
|
|
@@ -5,6 +5,9 @@ import {StyleProps, ThemeStatus, useStyle} from "../../uses/useStyle";
|
|
|
5
5
|
import {FormItemLayoutPropsOption, useFormLayout} from "../Form/layout/useFormLayout";
|
|
6
6
|
import {useFormItemValidation} from "../Form/validate/useFormItemValidation";
|
|
7
7
|
import {FormItemValidateMessage} from "./FormItemValidateMessage";
|
|
8
|
+
import Tooltip from "../Tooltip";
|
|
9
|
+
import {getFunctionValue} from "@peryl/utils/getFunctionValue";
|
|
10
|
+
import Icon from "../Icon";
|
|
8
11
|
|
|
9
12
|
export const FormItem = designComponent({
|
|
10
13
|
name: '-form-item',
|
|
@@ -104,6 +107,10 @@ export const FormItem = designComponent({
|
|
|
104
107
|
{slots.labelSlot(props.label)}
|
|
105
108
|
{slots.labelAppend()}
|
|
106
109
|
{formItemLayout.colon.value && <i> :</i>}
|
|
110
|
+
{!!props.tip && <Tooltip v-slots={{
|
|
111
|
+
default: () => <Icon icon="pi-info-circle" className="form-item-cell-tip"/>,
|
|
112
|
+
popper: () => getFunctionValue(props.tip)
|
|
113
|
+
}}/>}
|
|
107
114
|
</div>
|
|
108
115
|
)}
|
|
109
116
|
<div className="form-item-content box-message-reference" style={formItemLayout.contentStyles.value}>
|
|
@@ -136,9 +136,10 @@ export function useSuggestionInput({ props, hooks, editComputed, styleComputed,
|
|
|
136
136
|
searchText,
|
|
137
137
|
props: {
|
|
138
138
|
scrollNum: 6,
|
|
139
|
-
scrollHeight:
|
|
139
|
+
scrollHeight: 200,
|
|
140
140
|
},
|
|
141
141
|
onRefScroll: innerOnRef.scroll,
|
|
142
|
+
scrollHeight: { value: 200 }
|
|
142
143
|
});
|
|
143
144
|
matchOptionPropsList = _matchOptionPropsList;
|
|
144
145
|
return (
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {designComponent, getComponentCls, iHTMLDivElement, useClassCache} from "@peryl/react-compose";
|
|
2
|
+
|
|
3
|
+
export const ListOption = designComponent({
|
|
4
|
+
name: 'list-option',
|
|
5
|
+
inheritPropsType: iHTMLDivElement,
|
|
6
|
+
props: {
|
|
7
|
+
label: { type: String }
|
|
8
|
+
},
|
|
9
|
+
slots: ['default'],
|
|
10
|
+
setup({ props, slots }) {
|
|
11
|
+
|
|
12
|
+
const classes = useClassCache(() => [getComponentCls('list-option')]);
|
|
13
|
+
|
|
14
|
+
return () => (
|
|
15
|
+
<div className={classes.value}>
|
|
16
|
+
{slots.default(props.label)}
|
|
17
|
+
</div>
|
|
18
|
+
);
|
|
19
|
+
},
|
|
20
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {designComponent, getComponentCls, iHTMLDivElement, useClassCache} from "@peryl/react-compose";
|
|
2
|
+
import {StyleProps, useStyle} from "../../uses/useStyle";
|
|
3
|
+
import {EditProps, useEdit} from "../../uses/useEdit";
|
|
4
|
+
import './list-panel.scss';
|
|
5
|
+
|
|
6
|
+
export const ListPanel = designComponent({
|
|
7
|
+
name: 'list-panel',
|
|
8
|
+
inheritPropsType: iHTMLDivElement,
|
|
9
|
+
props: {
|
|
10
|
+
...StyleProps,
|
|
11
|
+
...EditProps,
|
|
12
|
+
},
|
|
13
|
+
slots: ['default'],
|
|
14
|
+
setup({ props, slots }) {
|
|
15
|
+
|
|
16
|
+
useEdit();
|
|
17
|
+
const { styleComputed } = useStyle();
|
|
18
|
+
|
|
19
|
+
const classes = useClassCache(() => [
|
|
20
|
+
getComponentCls('list-panel'),
|
|
21
|
+
`list-panel-size-${styleComputed.value.size}`
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
return () => (
|
|
25
|
+
<div className={classes.value}>
|
|
26
|
+
{slots.default()}
|
|
27
|
+
</div>
|
|
28
|
+
);
|
|
29
|
+
},
|
|
30
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
@include comp(list-panel) {
|
|
2
|
+
|
|
3
|
+
padding: 0 2px;
|
|
4
|
+
|
|
5
|
+
@include sizeMixin(list-panel, ()) {
|
|
6
|
+
|
|
7
|
+
@include comp(list-option) {
|
|
8
|
+
font-size: $font-size;
|
|
9
|
+
padding: plv(dropdown-size-#{$name}-padding-y) plv(dropdown-size-#{$name}-padding-x);
|
|
10
|
+
border-radius: $border-radius;
|
|
11
|
+
margin: 2px 0;
|
|
12
|
+
cursor: pointer;
|
|
13
|
+
transition: all ease 300ms;
|
|
14
|
+
&:hover {
|
|
15
|
+
background-color: plv(secondary-2);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -22,6 +22,7 @@ export function createPublicSelectRender(
|
|
|
22
22
|
slots,
|
|
23
23
|
editComputed,
|
|
24
24
|
styleComputed,
|
|
25
|
+
scrollHeight,
|
|
25
26
|
}: iSelectCompositionParams,
|
|
26
27
|
{
|
|
27
28
|
isActivated,
|
|
@@ -123,7 +124,7 @@ export function createPublicSelectRender(
|
|
|
123
124
|
const hover = createSelectHover({
|
|
124
125
|
defaultCurrent,
|
|
125
126
|
refs,
|
|
126
|
-
scrollHeight: () =>
|
|
127
|
+
scrollHeight: () => scrollHeight.value,
|
|
127
128
|
getMatchOptionsLength: () => optionListHandler.getMatchOptionPropsList().length
|
|
128
129
|
});
|
|
129
130
|
|
|
@@ -236,7 +237,7 @@ export function createPublicSelectRender(
|
|
|
236
237
|
const render = () => {
|
|
237
238
|
/*如果显示的选项大于6个,则使用虚拟滚动显示,否则直接显示*/
|
|
238
239
|
return (matchOptionPropsList.length > props.scrollNum ?
|
|
239
|
-
(<div style={{ height: unit(
|
|
240
|
+
(<div style={{ height: unit(scrollHeight.value)! }}>
|
|
240
241
|
<VirtualList data={matchOptionPropsList} size={(() => {
|
|
241
242
|
const { virtualRowSize } = props;
|
|
242
243
|
return virtualRowSize == null ? SelectDefaultVirtualRowSize[styleComputed.value.size] : virtualRowSize;
|
|
@@ -260,6 +261,7 @@ export function createPublicSelectRender(
|
|
|
260
261
|
props,
|
|
261
262
|
onRefScroll: onRef.scroll,
|
|
262
263
|
innerState,
|
|
264
|
+
scrollHeight,
|
|
263
265
|
});
|
|
264
266
|
optionPropsList = ret.optionPropsList;
|
|
265
267
|
matchOptionPropsList = ret.matchOptionPropsList;
|
|
@@ -12,6 +12,7 @@ export function decodeSelectRenderNode(
|
|
|
12
12
|
props,
|
|
13
13
|
onRefScroll,
|
|
14
14
|
innerState,
|
|
15
|
+
scrollHeight,
|
|
15
16
|
}: {
|
|
16
17
|
renderNode: RenderNode,
|
|
17
18
|
searchText: string,
|
|
@@ -22,7 +23,8 @@ export function decodeSelectRenderNode(
|
|
|
22
23
|
scrollHeight: number,
|
|
23
24
|
},
|
|
24
25
|
onRefScroll: (scroll: any) => void,
|
|
25
|
-
innerState?: { renderKey: string }
|
|
26
|
+
innerState?: { renderKey: string },
|
|
27
|
+
scrollHeight: { value: number },
|
|
26
28
|
}) {
|
|
27
29
|
const selectOptionDecoder = createSelectOptionDecoder();
|
|
28
30
|
renderNode = deepCloneRenderNode(renderNode);
|
|
@@ -40,7 +42,7 @@ export function decodeSelectRenderNode(
|
|
|
40
42
|
}
|
|
41
43
|
/*如果显示的选项大于6个,则使用Scroll滚动显示,否则直接显示*/
|
|
42
44
|
return (matchOptionPropsList.length > props.scrollNum ?
|
|
43
|
-
(<div style={{ height: unit(
|
|
45
|
+
(<div style={{ height: unit(scrollHeight.value)! }}>
|
|
44
46
|
<Scroll ref={onRefScroll}>
|
|
45
47
|
{renderNode}
|
|
46
48
|
</Scroll>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {designComponent, getComponentCls, reactive, useClasses} from "@peryl/react-compose";
|
|
1
|
+
import {computed, designComponent, getComponentCls, reactive, useClasses} from "@peryl/react-compose";
|
|
2
2
|
import {useWatchAutoClear} from "../../utils/watchEffectAutoClear";
|
|
3
3
|
import {createSingleSelectRender} from "./createSingleSelectRender";
|
|
4
4
|
import {createMultipleSelectRender} from "./createMultipleSelectRender";
|
|
@@ -10,6 +10,8 @@ import {createIsMatch} from "../../utils/isObjectCommonMatch";
|
|
|
10
10
|
import Input from "../Input";
|
|
11
11
|
import {createPopupAttrsGetter} from "../usePopup/utils/createPopperAttrsGetter";
|
|
12
12
|
import {useParentPopupId} from "../usePopup/utils/popup.utils";
|
|
13
|
+
import ApplicationConfigurationProvider from "../ApplicationConfigurationProvider";
|
|
14
|
+
import {removeUnit} from "@peryl/utils/removeUnit";
|
|
13
15
|
|
|
14
16
|
export const Select = designComponent({
|
|
15
17
|
name: '-select',
|
|
@@ -21,6 +23,7 @@ export const Select = designComponent({
|
|
|
21
23
|
setup({ props, slots, scopeSlots, event: { emit } }) {
|
|
22
24
|
|
|
23
25
|
const parentPopupId = useParentPopupId();
|
|
26
|
+
const configuration = ApplicationConfigurationProvider.inject();
|
|
24
27
|
|
|
25
28
|
const { editComputed } = useEdit();
|
|
26
29
|
const { styleComputed } = useStyle();
|
|
@@ -53,6 +56,14 @@ export const Select = designComponent({
|
|
|
53
56
|
}
|
|
54
57
|
]);
|
|
55
58
|
|
|
59
|
+
const scrollHeight = computed((): number => {
|
|
60
|
+
if (props.scrollHeight != null) {return props.scrollHeight;}
|
|
61
|
+
const fontSize = Number(removeUnit(configuration.value.theme.vars[`font-size-${styleComputed.value.size}`]));
|
|
62
|
+
const paddingY = Number(removeUnit(configuration.value.theme.vars[`dropdown-size-${styleComputed.value.size}-padding-y`]));
|
|
63
|
+
const itemHeight = fontSize + paddingY * 2 + 6 + 2;
|
|
64
|
+
return itemHeight * 6;
|
|
65
|
+
});
|
|
66
|
+
|
|
56
67
|
const selectCompositionParams: iSelectCompositionParams = {
|
|
57
68
|
props,
|
|
58
69
|
classes,
|
|
@@ -64,6 +75,7 @@ export const Select = designComponent({
|
|
|
64
75
|
styleComputed,
|
|
65
76
|
isMatch: createIsMatch(props),
|
|
66
77
|
getPublicPopperAttrs,
|
|
78
|
+
scrollHeight,
|
|
67
79
|
};
|
|
68
80
|
|
|
69
81
|
const methods = {
|
|
@@ -53,7 +53,7 @@ export const SelectPropOptions = {
|
|
|
53
53
|
handleFilterChange: { type: Function as PropType<(text: string) => void> },// 手动处理搜索值变化
|
|
54
54
|
|
|
55
55
|
scrollNum: { type: Number, default: 6 }, // 最多显示的下拉个数,超过这个数就会滚动展示
|
|
56
|
-
scrollHeight: { type: Number, default:
|
|
56
|
+
scrollHeight: { type: Number, default: null },// 滚动展示下拉选项的时候的高度
|
|
57
57
|
|
|
58
58
|
virtualData: { type: Array as PropType<iSelectOptionProps[]> },
|
|
59
59
|
virtualRowSize: { type: Number },// 虚拟滚动的时候的行高
|
|
@@ -135,7 +135,8 @@ export type iSelectCompositionParams = {
|
|
|
135
135
|
scopeSlots: tScopeSlotsType<typeof SelectScopeSlotsOption>,
|
|
136
136
|
editComputed: tEditComputed,
|
|
137
137
|
styleComputed: { value: { size: typeof ThemeSize.TYPE } },
|
|
138
|
-
classes: { value: any, }
|
|
138
|
+
classes: { value: any, },
|
|
139
|
+
scrollHeight: { value: number }
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
/**
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {computed, inject, provide} from "@peryl/react-compose";
|
|
2
|
+
import {Table} from "../../index";
|
|
3
|
+
|
|
4
|
+
export function useTableAutoSpan(getConfig: () => { data: Record<string, any>[] }) {
|
|
5
|
+
|
|
6
|
+
const table = Table.use.inject(null);
|
|
7
|
+
|
|
8
|
+
const spans = computed(() => {
|
|
9
|
+
const { data } = getConfig();
|
|
10
|
+
const bodyPlcList = table?.bodyPlcList.value;
|
|
11
|
+
if (!bodyPlcList) {return null;}
|
|
12
|
+
const rowSpanFields = Array.from(new Set(bodyPlcList.filter(i => i.props.autoRowSpan && !!i.props.field).map(i => i.props.field!)));
|
|
13
|
+
const colSpanFields = Array.from(new Set(bodyPlcList.filter(i => i.props.autoColSpan && !!i.props.field).map(i => i.props.field!)));
|
|
14
|
+
// console.log({ data, rowSpanFields, colSpanFields, });
|
|
15
|
+
const spans = calcSpans(data, { rowSpanFields, colSpanFields });
|
|
16
|
+
// console.log(spans);
|
|
17
|
+
return { spans, data };
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
provide('@@TABLE_AUTO_SPAN', spans);
|
|
21
|
+
|
|
22
|
+
return spans;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function injectTableAutoSpan() {
|
|
26
|
+
return inject('@@TABLE_AUTO_SPAN') as ReturnType<typeof useTableAutoSpan>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const calcRowSpans = (data: Record<string, any>[], fields: string[]) => {
|
|
30
|
+
|
|
31
|
+
/*结果数组,每行数据都记录下每个字段的span值*/
|
|
32
|
+
const resultSpanMap: Record<string, number>[] = [];
|
|
33
|
+
|
|
34
|
+
/*遍历每一行数据的时候,记录下要合并的字段,如果字段值变了则记录下这条数据的rowIndex到prevIndex[field],也就是 prevIndex[field] = rowIndex*/
|
|
35
|
+
const prevIndex: any = fields.reduce((prev, field) => (prev[field] = 0, prev), {} as Record<string, number>);
|
|
36
|
+
|
|
37
|
+
/*遍历每一行数据时,先初始化一个rowSpanMap,以这个为原始模板*/
|
|
38
|
+
const templateRowMap = fields.reduce((prev, field) => (prev[field] = 1, prev), {} as Record<string, number>);
|
|
39
|
+
|
|
40
|
+
data.forEach((row, rowIndex) => {
|
|
41
|
+
|
|
42
|
+
const rowSpanMap = { ...templateRowMap };
|
|
43
|
+
|
|
44
|
+
/*第一条数据任何字段的span都不可能为0,从第二条数据开始,字段值相同的field才会设置span为0实现合并单元格的功能*/
|
|
45
|
+
if (rowIndex === 0) {
|
|
46
|
+
resultSpanMap.push(rowSpanMap);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/*遍历每一个要合并的字段*/
|
|
51
|
+
fields.forEach((field, fieldIndex) => {
|
|
52
|
+
if (
|
|
53
|
+
/*字段值,与上一条数据字段的值相同,并且*/
|
|
54
|
+
row[field] === data[prevIndex[field]][field] && (
|
|
55
|
+
/*是第一个合并的字段,或者上一个合并的字段是合并状态*/
|
|
56
|
+
fieldIndex == 0 || (rowSpanMap[fields[fieldIndex - 1]] === 0)
|
|
57
|
+
)
|
|
58
|
+
) {
|
|
59
|
+
/*当前字段应该合并*/
|
|
60
|
+
resultSpanMap[prevIndex[field]][field]++;
|
|
61
|
+
rowSpanMap[field] = 0;
|
|
62
|
+
} else {
|
|
63
|
+
/*字段值不一样,标记新的记录下这个新的rowIndex,后续合并字段都操作这个rowIndex来实现*/
|
|
64
|
+
prevIndex[field] = rowIndex;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
resultSpanMap.push(rowSpanMap);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return data.map((_, rowIndex) => resultSpanMap[rowIndex]);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const calcColSpans = (data: Record<string, any>[], fields: string[]) => {
|
|
75
|
+
const resultSpanMap: Record<string, any>[] = [];
|
|
76
|
+
|
|
77
|
+
data.forEach((row) => {
|
|
78
|
+
const colSpanMap: Record<string, number> = {};
|
|
79
|
+
let prevField: any = null;
|
|
80
|
+
fields.forEach((field, fieldIndex) => {
|
|
81
|
+
|
|
82
|
+
/*第一个字段的colSpan不可能为0*/
|
|
83
|
+
if (fieldIndex === 0) {
|
|
84
|
+
prevField = field;
|
|
85
|
+
colSpanMap[field] = 1;
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (
|
|
90
|
+
/*当前字段的值与上一个字段的值相等,则当前字段应该合并*/
|
|
91
|
+
row[prevField] === row[field]
|
|
92
|
+
) {
|
|
93
|
+
colSpanMap[field] = 0;
|
|
94
|
+
colSpanMap[prevField]++;
|
|
95
|
+
} else {
|
|
96
|
+
/*当前字段与上一个字段值不相等,则标记当前字段为新的起始位置*/
|
|
97
|
+
colSpanMap[field] = 1;
|
|
98
|
+
prevField = field;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
});
|
|
102
|
+
resultSpanMap.push(colSpanMap);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return data.map((_, rowIndex) => resultSpanMap[rowIndex]);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export const calcSpans = (data: Record<string, any>[], config: { rowSpanFields?: string[], colSpanFields?: string[] }) => {
|
|
109
|
+
const rowSpans = !config.rowSpanFields?.length ? null : calcRowSpans(data, config.rowSpanFields);
|
|
110
|
+
const colSpans = !config.colSpanFields?.length ? null : calcColSpans(data, config.colSpanFields);
|
|
111
|
+
return data.map((_, rowIndex) => ({ row: rowSpans?.[rowIndex], col: colSpans?.[rowIndex] }));
|
|
112
|
+
};
|
|
@@ -36,6 +36,7 @@ export const PlcGroupPropsOptions = {
|
|
|
36
36
|
noPadding: { type: Boolean }, // 是否不兼容表格的虚拟滚动功能
|
|
37
37
|
colDraggable: { type: Boolean, default: null }, // 列是否可以拖拽排序
|
|
38
38
|
link: { type: Boolean }, // 超链接样式
|
|
39
|
+
tip: { type: [String, Function] as PropType<string | (() => any)> }, // 提示说明
|
|
39
40
|
|
|
40
41
|
hide: { type: Boolean }, // 是否隐藏
|
|
41
42
|
order: { type: [String, Number] }, // 列排序
|
|
@@ -71,6 +72,8 @@ export const PlcPropsOptions = {
|
|
|
71
72
|
hideInForm: { type: Boolean }, // 是否再表单编辑中显示
|
|
72
73
|
formLabel: { type: String }, // 在表单编辑中的label文本
|
|
73
74
|
overflowTooltip: { type: Boolean }, // 是否在内容文本溢出之后使用tooltip显示
|
|
75
|
+
autoRowSpan: { type: Boolean }, // 字段值相同则自动合并行
|
|
76
|
+
autoColSpan: { type: Boolean }, // 字段值相同则自动合并列
|
|
74
77
|
|
|
75
78
|
// 编辑相关
|
|
76
79
|
...PlcValidatePropsOption, // 校验属性
|
|
@@ -222,12 +222,12 @@ export const PlcOperation = designComponent({
|
|
|
222
222
|
}
|
|
223
223
|
});
|
|
224
224
|
const width = maxWidth + state.cellPaddingX * 2;
|
|
225
|
-
console.warn({ width });
|
|
225
|
+
// console.warn({ width });
|
|
226
226
|
if (!state.plcOperationWidth || width > state.plcOperationWidth) {
|
|
227
|
-
console.log({
|
|
227
|
+
/*console.log({
|
|
228
228
|
'plcOperationWidth.value': plcOperationWidth.value,
|
|
229
229
|
'width + 4': width + 4,
|
|
230
|
-
})
|
|
230
|
+
});*/
|
|
231
231
|
if (width + 4 > plcOperationWidth.value) {
|
|
232
232
|
state.plcOperationWidth = width + 4;
|
|
233
233
|
}
|