plain-design 1.0.0-beta.130 → 1.0.0-beta.132

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.
Files changed (51) hide show
  1. package/dist/plain-design.commonjs.min.js +2 -2
  2. package/dist/plain-design.min.css +5 -4
  3. package/dist/plain-design.min.js +2 -2
  4. package/dist/report.html +2 -2
  5. package/package.json +2 -2
  6. package/src/packages/components/AutoTable/auto-table.scss +21 -0
  7. package/src/packages/components/AutoTable/filter/useTableOption.filter.state.ts +3 -2
  8. package/src/packages/components/AutoTable/use/useTableOption.column.popper.tsx +1 -1
  9. package/src/packages/components/AutoTable/use/useTableOption.fill.tsx +2 -2
  10. package/src/packages/components/AutoTable/use/useTableOption.hooks.tsx +4 -2
  11. package/src/packages/components/AutoTable/use/useTableOption.pagination.tsx +1 -1
  12. package/src/packages/components/AutoTable/use/useTableOption.table.tsx +5 -3
  13. package/src/packages/components/AutoTable/use/useTableOption.tips.tsx +2 -2
  14. package/src/packages/components/AutoTable/utils/TableOption.space.tsx +5 -2
  15. package/src/packages/components/Button/index.tsx +9 -2
  16. package/src/packages/components/Cascade/createSingleCascadeRender.tsx +1 -0
  17. package/src/packages/components/Dialog/index.tsx +6 -2
  18. package/src/packages/components/Dropdown/index.tsx +14 -1
  19. package/src/packages/components/Form/form.scss +4 -0
  20. package/src/packages/components/Form/layout/useFormLayout.tsx +1 -0
  21. package/src/packages/components/FormItem/index.tsx +7 -0
  22. package/src/packages/components/Input/useSuggestionInput.tsx +2 -1
  23. package/src/packages/components/Input/uses/useInputEnterHandler.tsx +9 -2
  24. package/src/packages/components/ListOption/index.tsx +20 -0
  25. package/src/packages/components/ListPanel/index.tsx +30 -0
  26. package/src/packages/components/ListPanel/list-panel.scss +20 -0
  27. package/src/packages/components/Scroll/index.tsx +1 -0
  28. package/src/packages/components/Select/createPublicSelectRender.tsx +4 -2
  29. package/src/packages/components/Select/decodeSelectRenderNode.tsx +4 -2
  30. package/src/packages/components/Select/index.tsx +13 -1
  31. package/src/packages/components/Select/select.utils.tsx +3 -2
  32. package/src/packages/components/Table/plc/use/useTableAutoSpan.tsx +112 -0
  33. package/src/packages/components/Table/plc/useTablePlc.tsx +2 -1
  34. package/src/packages/components/Table/plc/utils/plc.utils.ts +3 -0
  35. package/src/packages/components/Table/standard/PlcOperation/PlcOperation.tsx +3 -3
  36. package/src/packages/components/Table/table/Table.tsx +10 -6
  37. package/src/packages/components/Table/table/body/cell.tsx +34 -3
  38. package/src/packages/components/Table/table/body/useCellValue.tsx +14 -5
  39. package/src/packages/components/Table/table/head/head-cell.tsx +6 -0
  40. package/src/packages/components/Table/table/table.scss +4 -0
  41. package/src/packages/components/Table/table/use/useTableFormEditor.tsx +5 -1
  42. package/src/packages/components/Table/table/use/useTableModifyEditor.tsx +8 -2
  43. package/src/packages/components/Table/table/utils/createTableHooks.ts +5 -3
  44. package/src/packages/components/Table/table/utils/table.utils.ts +3 -2
  45. package/src/packages/components/VirtualTable/index.tsx +6 -0
  46. package/src/packages/components/VirtualTable/virtual-table.scss +3 -3
  47. package/src/packages/components/createSimpleDate/index.ts +49 -0
  48. package/src/packages/components/useContextmenuOptions/index.tsx +40 -0
  49. package/src/packages/components/usePopup/trigger/useManagerTrigger.clickOutside.tsx +18 -23
  50. package/src/packages/components/useTableFilter/index.ts +73 -0
  51. package/src/packages/entry.tsx +6 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plain-design",
3
- "version": "1.0.0-beta.130",
3
+ "version": "1.0.0-beta.132",
4
4
  "description": "",
5
5
  "main": "dist/plain-design.min.js",
6
6
  "module": "dist/plain-design.commonjs.min.js",
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@peryl/icon": "0.0.8",
34
- "@peryl/utils": "^0.1.72",
34
+ "@peryl/utils": "^0.1.73",
35
35
  "@types/color": "3.0.6",
36
36
  "@types/react-transition-group": "4.4.10",
37
37
  "color": "4.2.3",
@@ -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: '400px' };
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, // BaseTable的minShowRows
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
  /**
@@ -1,5 +1,5 @@
1
1
  import './button.scss';
2
- import {computed, designComponent, getComponentCls, iHTMLButtonElement, mergeAttrs, PropType, reactive, StyleProperties, useClasses, useNumber, useRefs, useStyles, watch} from "@peryl/react-compose";
2
+ import {computed, designComponent, getComponentCls, iHTMLButtonElement, mergeAttrs, onBeforeUnmount, PropType, reactive, StyleProperties, useClasses, useNumber, useRefs, useStyles, watch} from "@peryl/react-compose";
3
3
  import {EditProps, useEdit} from "../../uses/useEdit";
4
4
  import {StyleProps, ThemeMode, ThemeStatus, useStyle} from "../../uses/useStyle";
5
5
  import {throttle} from "@peryl/utils/throttle";
@@ -10,6 +10,7 @@ import {Loading} from "../Loading";
10
10
  import {ButtonGroup} from "../ButtonGroup";
11
11
  import {AutoLoadingObserver} from "../AutoLoadingObserver";
12
12
  import {useCollapseStyles} from "../../uses/useCollapseStyles";
13
+ import {createEffects} from "@peryl/utils/createEffects";
13
14
 
14
15
  export const Button = designComponent({
15
16
  name: '-button',
@@ -82,16 +83,22 @@ export const Button = designComponent({
82
83
  },
83
84
  });
84
85
 
86
+ const { effects: throttleClickEffects } = createEffects();
87
+ onBeforeUnmount(() => {throttleClickEffects.clear();});
88
+
85
89
  watch(
86
90
  () => props.throttleClick,
87
91
  (val) => {
92
+ throttleClickEffects.clear();
88
93
  if (!val) {
89
94
  return state.handleClick = state.handleClickInner;
90
95
  }
91
96
  if (val === true) {
92
97
  val = 1000;
93
98
  }
94
- state.handleClick = throttle(state.handleClickInner, val, { trailing: false });
99
+ const throttleClickHandler = throttle(state.handleClickInner, val, { trailing: false });
100
+ throttleClickEffects.push(() => throttleClickHandler.dispose());
101
+ state.handleClick = throttleClickHandler;
95
102
  },
96
103
  { immediate: true }
97
104
  );
@@ -63,6 +63,7 @@ export function createSingleCascadeRender(
63
63
  state.inputValue = null;
64
64
  },
65
65
  onBlur: (e: FocusEvent) => {
66
+ if (!event.emit) {return;}
66
67
  event.emit.onBlur(e);
67
68
  props.inputAttrs?.onBlur?.(e);
68
69
  state.isFocus = false;
@@ -1,4 +1,4 @@
1
- import {computed, createHooks, designComponent, getComponentCls, iMouseEvent, mergeAttrs, nextIndex, nextTick, Portal, PropType, reactive, useClasses, useModel, useRefs, useStyles, watch} from "@peryl/react-compose";
1
+ import {computed, createHooks, designComponent, getComponentCls, iMouseEvent, mergeAttrs, nextIndex, nextTick, onBeforeUnmount, Portal, PropType, reactive, useClasses, useModel, useRefs, useStyles, watch} from "@peryl/react-compose";
2
2
  import {DialogAlign, DialogAnimations, DialogCloseType, DialogPositions} from "./utils/dialog.utils";
3
3
  import {APPLICATION_SERVICE_CONTAINER_CLASS} from "../Application/utils/application.utils";
4
4
  import {unit} from "@peryl/utils/unit";
@@ -81,7 +81,6 @@ export const Dialog = designComponent({
81
81
  const { styleComputed } = useStyle();
82
82
 
83
83
  const { emit } = event;
84
-
85
84
  const model = useModel(() => props.modelValue, emit.onUpdateModelValue);
86
85
  const open = useModel(() => props.open, emit.onUpdateOpen);
87
86
 
@@ -320,6 +319,11 @@ export const Dialog = designComponent({
320
319
  }, 300, { trailing: false }),
321
320
  };
322
321
 
322
+ onBeforeUnmount(() => {
323
+ methods.confirm.dispose();
324
+ methods.cancel.dispose();
325
+ });
326
+
323
327
  watch(() => model.value, async show => {
324
328
  await nextTick();
325
329
  await (show ? methods.show() : methods.hide());
@@ -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: '200px', width: dropdownContentWidth.value, }, key },
126
+ attrs: { style: { height: scrollHeight.value + 'px', width: dropdownContentWidth.value, }, key },
114
127
  content: <>
115
128
  <Scroll>
116
129
  {children}
@@ -33,6 +33,10 @@
33
33
  box-sizing: border-box;
34
34
  position: relative;
35
35
  vertical-align: top;
36
+ .form-item-cell-tip {
37
+ color: plv(text-3);
38
+ vertical-align: -0.15em;
39
+ }
36
40
  .form-item-label {
37
41
  vertical-align: top;
38
42
  display: inline-block;
@@ -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: 150,
139
+ scrollHeight: 200,
140
140
  },
141
141
  onRefScroll: innerOnRef.scroll,
142
+ scrollHeight: { value: 200 }
142
143
  });
143
144
  matchOptionPropsList = _matchOptionPropsList;
144
145
  return (
@@ -40,15 +40,19 @@ export function useInputEnterHandler(
40
40
  };
41
41
 
42
42
  const enterHandler = reactive({ value: doNothing, });
43
+ const { effects: throttleEffects } = createEffects();
43
44
 
44
45
  watch(() => props.throttleEnter, (val) => {
46
+ throttleEffects.clear();
45
47
  if (!val) {
46
48
  enterHandler.value = innerHandler;
47
49
  }
48
50
  if (val === true) {
49
51
  val = 1000;
50
52
  }
51
- enterHandler.value = throttle(innerHandler, val as number, { trailing: true });
53
+ const throttleHandler = throttle(innerHandler, val as number, { trailing: true });
54
+ throttleEffects.push(() => throttleHandler.dispose());
55
+ enterHandler.value = throttleHandler;
52
56
  }, { immediate: true });
53
57
 
54
58
  const handler = {
@@ -72,5 +76,8 @@ export function useInputEnterHandler(
72
76
  effects.push(() => {input.removeEventListener('keydown', handler.onKeydown);});
73
77
  });
74
78
 
75
- onBeforeUnmount(() => effects.clear());
79
+ onBeforeUnmount(() => {
80
+ effects.clear();
81
+ throttleEffects.clear();
82
+ });
76
83
  }
@@ -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
+ }
@@ -354,6 +354,7 @@ export const Scroll = designComponent({
354
354
  popper.event.off.onOpen(handler.popperOpen)
355
355
  popper.event.off.onShow(handler.popperShow)
356
356
  }*/
357
+ handler.windowResize.dispose();
357
358
  });
358
359
 
359
360
  watch(() => props.refreshState, methods.refresh);
@@ -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: () => props.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(props.scrollHeight)! }}>
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(props.scrollHeight)! }}>
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: 150 },// 滚动展示下拉选项的时候的高度
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
  /**