plain-design 1.0.0-beta.35 → 1.0.0-beta.37

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plain-design",
3
- "version": "1.0.0-beta.35",
3
+ "version": "1.0.0-beta.37",
4
4
  "description": "",
5
5
  "main": "dist/plain-design.min.js",
6
6
  "module": "dist/plain-design.commonjs.min.js",
@@ -20,7 +20,7 @@
20
20
  "peerDependencies": {
21
21
  "exceljs": "^4.2.1",
22
22
  "file-saver": "^2.0.5",
23
- "plain-design-composition": "^0.0.181",
23
+ "plain-design-composition": "^0.0.185",
24
24
  "react": "^18.0.1",
25
25
  "react-dom": "^18.0.1"
26
26
  },
@@ -34,7 +34,7 @@
34
34
  "color": "^4.2.3",
35
35
  "dayjs": "^1.10.4",
36
36
  "plain-icons": "0.0.7",
37
- "plain-utils": "^0.1.48",
37
+ "plain-utils": "0.1.56",
38
38
  "react-flip-move": "^3.0.4",
39
39
  "react-transition-group": "^4.4.1"
40
40
  },
@@ -69,7 +69,7 @@
69
69
  "fork-ts-checker-webpack-plugin": "^6.2.4",
70
70
  "mini-css-extract-plugin": "^1.4.1",
71
71
  "mockjs": "^1.1.0",
72
- "plain-design-composition": "^0.0.182",
72
+ "plain-design-composition": "^0.0.185",
73
73
  "postcss": "^8.2.13",
74
74
  "postcss-loader": "^4.2.0",
75
75
  "qs": "^6.10.1",
@@ -19,23 +19,27 @@ import {ClientZoom} from "../../utils/ClientZoom";
19
19
  export function createObjectService(defaultConfig: iObjectServiceDefaultConfig) {
20
20
 
21
21
  const publicDialogOption: iDialogServiceOption = {
22
+ headAlign: 'left',
22
23
  title: i18n('base.selectData').d('选择数据'),
23
24
  confirmButton: true,
24
25
  cancelButton: true,
25
26
  maxHeight: ' ',
26
- maxWidth: '60vw',
27
+ maxWidth: ' ',
28
+ width: '50vw'
27
29
  };
28
30
 
29
31
  function processShowRows(option: TableOptionSpace.iTableOption) {
30
- const { clientHeight } = ClientZoom.getClientSize();
31
- const availableHeight = clientHeight * 0.8 - 48 - 44 - 40 - 40 - 28;
32
- const { bodyRowHeight } = getTableRowHeight(option.config.size, option.config);
33
- const showRows = Math.floor(availableHeight / bodyRowHeight) - 1;
34
-
35
- option.config.showRows = showRows;
36
- option.pagination.state.size = option.config.showRows;
37
- option.pagination.state.pageSizeOptions.indexOf(showRows) === -1 && (option.pagination.state.pageSizeOptions.unshift(showRows));
38
- option.fill.state.showRows = showRows;
32
+ if (option.useConfig.showRows == null) {
33
+ const { clientHeight } = ClientZoom.getClientSize();
34
+ const availableHeight = clientHeight * 0.8 - 48 - 44 - 40 - 40 - 28;
35
+ const { bodyRowHeight } = getTableRowHeight(option.config.size, option.config);
36
+ const showRows = Math.floor(availableHeight / bodyRowHeight) - 1;
37
+
38
+ option.config.showRows = showRows;
39
+ option.pagination.state.size = option.config.showRows;
40
+ option.pagination.state.pageSizeOptions.indexOf(showRows) === -1 && (option.pagination.state.pageSizeOptions.unshift(showRows));
41
+ option.fill.state.showRows = showRows;
42
+ }
39
43
  }
40
44
 
41
45
  function processPermit(option: TableOptionSpace.iTableOption) {
@@ -92,7 +96,7 @@ export function createObjectService(defaultConfig: iObjectServiceDefaultConfig)
92
96
  },
93
97
  };
94
98
 
95
- effects.push(
99
+ !serviceConfig.readonly && effects.push(
96
100
  config.option.hooks.onRenderColumns.use({
97
101
  processor: ({ list, render }) => {list.push({ render, key: 'object-check', seq: 0 });},
98
102
  render: () => (
@@ -101,16 +105,11 @@ export function createObjectService(defaultConfig: iObjectServiceDefaultConfig)
101
105
  })
102
106
  );
103
107
 
104
- (!config.option.permission.permit.value.show.update || config.option.permission.permit.value.disabled.update) &&
105
- effects.push(
106
- config.option.hooks.onDblclickRow.use(async () => {
107
- await delay();
108
- handler.handleConfirm();
109
- })
110
- );
111
-
112
108
  const close = $dialog({
113
109
  ...publicDialogOption,
110
+ ...serviceConfig.dialogProps,
111
+ ...serviceConfig.readonly ? { confirmButton: false, cancelButton: false } : {},
112
+ title: serviceConfig.option.config.title || publicDialogOption.title,
114
113
  onClose: () => {effects.clear();},
115
114
  onOpen: () => config.option.methods.pageMethods.reload(),
116
115
  handleConfirm: handler.handleConfirm,
@@ -124,6 +123,14 @@ export function createObjectService(defaultConfig: iObjectServiceDefaultConfig)
124
123
  }
125
124
  });
126
125
 
126
+ !serviceConfig.readonly && (!config.option.permission.permit.value.show.update || config.option.permission.permit.value.disabled.update) &&
127
+ effects.push(
128
+ config.option.hooks.onDblclickRow.use(async () => {
129
+ await delay();
130
+ handler.handleConfirm();
131
+ })
132
+ );
133
+
127
134
  return dfd.promise;
128
135
  }
129
136
 
@@ -145,7 +152,7 @@ export function createObjectService(defaultConfig: iObjectServiceDefaultConfig)
145
152
  selected: (!config.selected ? undefined : deepcopy(convertRowToSelected(config.selected, config.map))) as undefined | PlainObject[]
146
153
  });
147
154
 
148
- effects.push(
155
+ !serviceConfig.readonly && effects.push(
149
156
  config.option.hooks.onRenderColumns.use({
150
157
  processor: ({ list, render }) => {list.push({ render, key: 'object-check', seq: 0 });},
151
158
  render: () => (
@@ -155,7 +162,11 @@ export function createObjectService(defaultConfig: iObjectServiceDefaultConfig)
155
162
  );
156
163
 
157
164
  $dialog({
165
+ headAlign: 'left',
158
166
  ...publicDialogOption,
167
+ ...serviceConfig.dialogProps,
168
+ ...serviceConfig.readonly ? { confirmButton: false, cancelButton: false } : {},
169
+ title: serviceConfig.option.config.title || publicDialogOption.title,
159
170
  onClose: () => {effects.clear();},
160
171
  onOpen: () => config.option.methods.pageMethods.reload(),
161
172
  handleConfirm: async () => {
@@ -1,6 +1,8 @@
1
1
  import {PlainObject} from "plain-utils/utils/event";
2
2
  import {iObjectConverter} from "./object.conver";
3
3
  import {TableOptionSpace} from "../AutoTable/utils/TableOption.space";
4
+ import {ComponentPropsType} from "plain-design-composition";
5
+ import {Dialog} from "../Dialog";
4
6
 
5
7
  /**
6
8
  * 创建Object服务需要的默认的配置参数
@@ -17,9 +19,11 @@ export interface iObjectServiceDefaultConfig {
17
19
  * @date 2023.1.24 20:14
18
20
  */
19
21
  export interface iObjectServicePickPublicConfig extends Partial<iObjectServiceDefaultConfig> {
20
- option: TableOptionSpace.iTableOption, // TableOption对象
21
- map?: Record<string, string> | [iObjectConverter, iObjectConverter], // 用来转化选中行与目标行对象的规则
22
- beforeCancel?: () => void | boolean | Promise<void | boolean>, // 取消之前的动作
22
+ option: TableOptionSpace.iTableOption, // TableOption对象
23
+ map?: Record<string, string> | [iObjectConverter, iObjectConverter], // 用来转化选中行与目标行对象的规则
24
+ beforeCancel?: () => void | boolean | Promise<void | boolean>, // 取消之前的动作
25
+ readonly?: boolean, // 只读,不需要选择数据,只需要关闭
26
+ dialogProps?: Partial<ComponentPropsType<typeof Dialog>> // dialog属性
23
27
  }
24
28
 
25
29
  /**
@@ -97,6 +97,7 @@ export const ImagePreviewerFixedContainer = designComponent({
97
97
  <div className={classes.value} ref={onRef.el}>
98
98
  {state.ready && (
99
99
  <ImagePreviewer
100
+ closable
100
101
  option={props.option}
101
102
  style={styles.value}
102
103
  />
@@ -5,7 +5,7 @@ import {PlainObject} from "plain-utils/utils/event";
5
5
  import '../utils/TableOption.space';
6
6
  import {PlcIndex} from "../../Table/standard/PlcIndex";
7
7
  import {AutoModule} from "../utils/AutoModule";
8
- import {iMouseEvent} from "plain-design-composition";
8
+ import {Fragment, iMouseEvent} from "plain-design-composition";
9
9
 
10
10
  declare module '../utils/TableOption.space' {
11
11
  namespace TableOptionSpace {
@@ -46,8 +46,8 @@ export const useTableOptionTable = AutoModule.createRegistration((
46
46
  hooks.onRenderColumns.use({
47
47
  processor: ({ list, render }) => {list.push({ key: 'index', seq: 0, render });},
48
48
  render: () => <>
49
- {config.indexing != false && <PlcIndex start={(pagination.state.page - 1) * pagination.state.size}/>}
50
- {render.default()}
49
+ {config.indexing != false && <PlcIndex start={(pagination.state.page - 1) * pagination.state.size} key="key_standard_index"/>}
50
+ <Fragment key="key_option_render">{render.default()}</Fragment>
51
51
  </>
52
52
  });
53
53
 
@@ -50,6 +50,7 @@ export namespace TableOptionSpace {
50
50
  * @date 2022.12.20 10:47
51
51
  */
52
52
  export interface iTableOptionCustomConfig {
53
+ title?: string, // 表格标题
53
54
  url?: iUrl, // 请求配置
54
55
  data?: any[], // 默认数据
55
56
  fill?: boolean, // 是否自动计算高度
@@ -161,6 +162,8 @@ export namespace TableOptionSpace {
161
162
  */
162
163
  export interface iTableOption {
163
164
  config: iTableOptionConfig;
165
+ useConfig: iTableOptionUseConfig,
166
+ defaultConfig: iTableOptionDefaultConfig,
164
167
  clone: iTableOptionClone;
165
168
  }
166
169
 
@@ -13,6 +13,7 @@ import {delay} from "plain-utils/utils/delay";
13
13
  import {Tooltip} from "../Tooltip";
14
14
  import {buildCycleIndexList} from "../../utils/buildCycleIndexList";
15
15
  import {ComponentUtils} from "../../utils/ComponentUtils";
16
+ import {addWindowListener} from "plain-utils/dom/addWindowListener";
16
17
 
17
18
  export const Carousel = designComponent({
18
19
  name: 'carousel',
@@ -294,11 +295,10 @@ export const Carousel = designComponent({
294
295
  reset();
295
296
  };
296
297
 
297
- draggierEffects.push(addElementListener(document.body, 'mousemove', touchmove));
298
- draggierEffects.push(addElementListener(document.body, 'touchmove', touchmove));
299
-
300
- draggierEffects.push(addElementListener(document.body, 'mouseup', draggierEffects.clear));
301
- draggierEffects.push(addElementListener(document.body, 'touchend', draggierEffects.clear));
298
+ draggierEffects.push(addWindowListener('mousemove', touchmove));
299
+ draggierEffects.push(addWindowListener('touchmove', touchmove));
300
+ draggierEffects.push(addWindowListener('mouseup', draggierEffects.clear));
301
+ draggierEffects.push(addWindowListener('touchend', draggierEffects.clear));
302
302
  };
303
303
 
304
304
  const reset = () => {
@@ -1,4 +1,4 @@
1
- import {computed, designComponent, iHTMLDivElement, onBeforeUnmount, onMounted, PropType, reactive, useClasses, useRefs, useStyles} from "plain-design-composition";
1
+ import {computed, designComponent, iHTMLDivElement, onBeforeUnmount, onMounted, PropType, reactive, useClasses, useRefs, useStyles, watch} from "plain-design-composition";
2
2
  import {getCenterRect, iImagePreviewerOption, ImagePreviewerHooks} from "./image-previewer.utils";
3
3
  import {createEffects} from "plain-utils/utils/createEffects";
4
4
  import {getRectAutoFormat} from "../../utils/getRectAutoFormat";
@@ -18,7 +18,8 @@ import {getDeviceInfo} from "../../utils/getDeviceInfo";
18
18
  export const ImagePreviewer = designComponent({
19
19
  name: 'image-preview-component',
20
20
  props: {
21
- option: { type: Object as PropType<iImagePreviewerOption>, required: true }
21
+ option: { type: Object as PropType<iImagePreviewerOption>, required: true },
22
+ closable: { type: Boolean }
22
23
  },
23
24
  inheritPropsType: iHTMLDivElement,
24
25
  setup({ props }) {
@@ -71,7 +72,8 @@ export const ImagePreviewer = designComponent({
71
72
  }
72
73
 
73
74
  /*当前正在显示的图片元素,关闭时让这个元素显示一个缩小动画*/
74
- const sourceImgElement = props.option.imageElement;
75
+ const currentUrl = props.option.urls[state.current!].url;
76
+ const sourceImgElement = props.option.imageElement?.getAttribute('src') === currentUrl ? props.option.imageElement : (Array.from(document.querySelectorAll('img')) as HTMLImageElement[]).find(i => i.getAttribute('src') === currentUrl && i !== currentImgElement && !i.hasAttribute('data-ignore'));
75
77
 
76
78
  const currentRect = getCenterRect({ imageElement: currentImgElement, containerElement: refs.carousel!.refs.el! });
77
79
 
@@ -129,17 +131,18 @@ export const ImagePreviewer = designComponent({
129
131
 
130
132
  const handler = {
131
133
  onDoubleClickImage: () => {
132
- methods.close();
134
+ props.closable && methods.close();
133
135
  },
134
- onChangeCurrent: () => {
135
- transformHandler.transformMethods.reset();
136
- if (!!props.option.imageElement) {
137
- if (props.option.imageElement.style.opacity != props.option.oldSourceImageOpacity) {
138
- props.option.imageElement.style.opacity = props.option.oldSourceImageOpacity || "";
139
- }
136
+ };
137
+
138
+ watch(() => state.current, () => {
139
+ transformHandler.transformMethods.reset();
140
+ if (!!props.option.imageElement) {
141
+ if (props.option.imageElement.style.opacity != props.option.oldSourceImageOpacity) {
142
+ props.option.imageElement.style.opacity = props.option.oldSourceImageOpacity || "";
140
143
  }
141
144
  }
142
- };
145
+ });
143
146
 
144
147
  const transformHandler = (() => {
145
148
  const transformState = reactive({
@@ -191,7 +194,7 @@ export const ImagePreviewer = designComponent({
191
194
  if (!!transformState.previousTouchstartTimestamp) {
192
195
  if (currentTouchstartTimestamp - transformState.previousTouchstartTimestamp < 200) {
193
196
  /*100ms内点击了两次,自动关闭*/
194
- methods.close();
197
+ props.closable && methods.close();
195
198
  return;
196
199
  }
197
200
  }
@@ -244,70 +247,71 @@ export const ImagePreviewer = designComponent({
244
247
  transformState.transformData.top = Number((touchState.startTop + (moveY - touchState.startY)).toFixed(2));
245
248
  transformState.transformData.left = Number((touchState.startLeft + (moveX - touchState.startX)).toFixed(2));
246
249
  };
247
- touchEffects.push(addElementListener(document.body, 'touchmove', touchmove, { passive: false }));
248
- touchEffects.push(addElementListener(document.body, 'touchend', touchEffects.clear, { passive: false }));
249
- touchEffects.push(addElementListener(document.body, 'mousemove', touchmove, { passive: false }));
250
- touchEffects.push(addElementListener(document.body, 'mouseup', touchEffects.clear, { passive: false }));
250
+ touchEffects.push(addWindowListener('touchmove', touchmove, { passive: false }));
251
+ touchEffects.push(addWindowListener('touchend', touchEffects.clear, { passive: false }));
252
+ touchEffects.push(addWindowListener('mousemove', touchmove, { passive: false }));
253
+ touchEffects.push(addWindowListener('mouseup', touchEffects.clear, { passive: false }));
251
254
  } else {
252
255
  if (getDeviceInfo().deviceType === 'mobile' && 'touches' in e && e.touches.length === 1) {
253
256
 
254
257
  /*---------------------------------------单指拖拽关闭-------------------------------------------*/
255
-
256
- /*移动端的情况下,如果纵向移动超过一定距离,则一边移动一边缩小,缩小到一定程度关闭预览*/
257
- let imageElement = (e.currentTarget as HTMLDivElement).querySelector('img') as HTMLImageElement;
258
- let mobileTouchState = {
259
- startX: e.touches[0].clientX,
260
- startY: e.touches[0].clientY,
261
- touching: null as null | { scale: number },
262
- };
263
- const touchmove = (e: TouchEvent) => {
264
- if (autoClearIfDoubleTouching(e)) {return;}
265
- e.stopPropagation();
266
- e.preventDefault();
267
- let durX = e.touches[0].clientX - mobileTouchState.startX;
268
- let durY = e.touches[0].clientY - mobileTouchState.startY;
269
- if (!mobileTouchState.touching) {
270
- if (durY > durX && durY > 10) {
271
- transformState.mobileClosing = true;
272
- mobileTouchState.touching = { scale: 1 };
273
- /*拖拽结束时的处理动作*/
274
- touchEffects.push(async () => {
275
- transformState.mobileClosing = false;
276
-
277
- if (mobileTouchState.touching!.scale < 0.9) {
278
- /*取消缩放,改为实际设置大小,是的关闭动画合理*/
279
- methods.close();
280
- } else {
281
- /*取消缩放,还原原来的状态*/
282
- imageElement.style.transition = "all ease 300ms";
283
- imageElement.style.transform = "translate3d(0,0,0) scale(1)";
284
- delay(300).then(() => {
285
- imageElement.style.transition = "";
286
- imageElement.style.transform = "";
287
- });
288
- }
289
-
290
- mobileTouchState.touching = null;
291
- });
258
+ if (props.closable) {
259
+ /*移动端的情况下,如果纵向移动超过一定距离,则一边移动一边缩小,缩小到一定程度关闭预览*/
260
+ let imageElement = (e.currentTarget as HTMLDivElement).querySelector('img') as HTMLImageElement;
261
+ let mobileTouchState = {
262
+ startX: e.touches[0].clientX,
263
+ startY: e.touches[0].clientY,
264
+ touching: null as null | { scale: number },
265
+ };
266
+ const touchmove = (e: TouchEvent) => {
267
+ if (autoClearIfDoubleTouching(e)) {return;}
268
+ e.stopPropagation();
269
+ e.preventDefault();
270
+ let durX = e.touches[0].clientX - mobileTouchState.startX;
271
+ let durY = e.touches[0].clientY - mobileTouchState.startY;
272
+ if (!mobileTouchState.touching) {
273
+ if (durY > durX && durY > 10) {
274
+ transformState.mobileClosing = true;
275
+ mobileTouchState.touching = { scale: 1 };
276
+ /*拖拽结束时的处理动作*/
277
+ touchEffects.push(async () => {
278
+ transformState.mobileClosing = false;
279
+
280
+ if (mobileTouchState.touching!.scale < 0.9) {
281
+ /*取消缩放,改为实际设置大小,是的关闭动画合理*/
282
+ methods.close();
283
+ } else {
284
+ /*取消缩放,还原原来的状态*/
285
+ imageElement.style.transition = "all ease 300ms";
286
+ imageElement.style.transform = "translate3d(0,0,0) scale(1)";
287
+ delay(300).then(() => {
288
+ imageElement.style.transition = "";
289
+ imageElement.style.transform = "";
290
+ });
291
+ }
292
+
293
+ mobileTouchState.touching = null;
294
+ });
295
+ }
296
+ }
297
+ if (!mobileTouchState.touching) {
298
+ return;
299
+ }
300
+ if (durY < 0) {durY = 0;}
301
+ if (durY === 0) {
302
+ /*移动距离为0,不做缩放移动*/
303
+ imageElement.style.transform = '';
304
+ } else {
305
+ /*按照移动距离进行缩放移动*/
306
+ const height = Math.ceil(document.body.clientHeight / 3);
307
+ const scale = Number((1 - durY / height).toFixed(2));
308
+ mobileTouchState.touching.scale = scale;
309
+ imageElement.style.transform = `translate3d(0,${durY}px,0) scale(${scale})`;
292
310
  }
293
- }
294
- if (!mobileTouchState.touching) {
295
- return;
296
- }
297
- if (durY < 0) {durY = 0;}
298
- if (durY === 0) {
299
- /*移动距离为0,不做缩放移动*/
300
- imageElement.style.transform = '';
301
- } else {
302
- /*按照移动距离进行缩放移动*/
303
- const height = Math.ceil(document.body.clientHeight / 3);
304
- const scale = Number((1 - durY / height).toFixed(2));
305
- mobileTouchState.touching.scale = scale;
306
- imageElement.style.transform = `translate3d(0,${durY}px,0) scale(${scale})`;
307
- }
308
- };
309
- touchEffects.push(addElementListener(document.body, 'touchmove', touchmove, { passive: false }));
310
- touchEffects.push(addElementListener(document.body, 'touchend', touchEffects.clear, { passive: false }));
311
+ };
312
+ touchEffects.push(addWindowListener('touchmove', touchmove, { passive: false }));
313
+ touchEffects.push(addWindowListener('touchend', touchEffects.clear, { passive: false }));
314
+ }
311
315
  }
312
316
  }
313
317
 
@@ -338,8 +342,8 @@ export const ImagePreviewer = designComponent({
338
342
  transformState.mobileScaling = null;
339
343
  });
340
344
 
341
- touchEffects.push(addElementListener(document.body, 'touchmove', touchmove, { passive: false, }));
342
- touchEffects.push(addElementListener(document.body, 'touchend', touchEffects.clear, { passive: false }));
345
+ touchEffects.push(addWindowListener('touchmove', touchmove, { passive: false, }));
346
+ touchEffects.push(addWindowListener('touchend', touchEffects.clear, { passive: false }));
343
347
  }
344
348
  },
345
349
  };
@@ -510,7 +514,6 @@ export const ImagePreviewer = designComponent({
510
514
  v-model={state.current}
511
515
  height={props.option.autoHeight ? undefined : `calc(100% - ${props.option.galleryHeight}px)`}
512
516
  style={{ paddingBottom: `${props.option.separatorHeight}px` }}
513
- onChange={handler.onChangeCurrent}
514
517
  disableSwiper={transformHandler.isTransforming.value}
515
518
  largeSwitchButton
516
519
  switchButton={props.option.swipeButton == false ? false : undefined}
@@ -548,7 +551,6 @@ export const ImagePreviewer = designComponent({
548
551
  <ImagePreviewerGallery
549
552
  option={props.option}
550
553
  v-model={state.current}
551
- onChange={handler.onChangeCurrent}
552
554
  style={galleryStyles.value}
553
555
  />
554
556
  )}
@@ -48,7 +48,7 @@ export const ImagePreviewerCarouselImage = designComponent({
48
48
  const preventDefaultDraggier = (e: iMouseEvent) => {e.preventDefault();};
49
49
 
50
50
  return () => (
51
- <img ref={onRef.img} style={styles.value} src={props.src} data-direction={state.direction} onLoad={onLoad} onError={onError} onDragStart={preventDefaultDraggier}/>
51
+ <img data-ignore="true" ref={onRef.img} style={styles.value} src={props.src} data-direction={state.direction} onLoad={onLoad} onError={onError} onDragStart={preventDefaultDraggier}/>
52
52
  );
53
53
  },
54
54
  });
@@ -188,7 +188,7 @@ export const ImagePreviewerGallery = designComponent({
188
188
  onMouseUp={(e) => handler.onMouseupItem(e, index)}
189
189
  data-active={String(model.value == index)}
190
190
  >
191
- <img src={item.thumbUrl} onMouseDown={handler.preventDragImage} onLoad={() => handler.onImageLoad(item.thumbUrl)} onError={() => handler.onImageLoad(item.thumbUrl)}/>
191
+ <img data-ignore="true" src={item.thumbUrl} onMouseDown={handler.preventDragImage} onLoad={() => handler.onImageLoad(item.thumbUrl)} onError={() => handler.onImageLoad(item.thumbUrl)}/>
192
192
  {/*{<PreviewerLoading/>}*/}
193
193
  {state.readyMap[item.thumbUrl] !== true && <PreviewerLoading/>}
194
194
  </div>
@@ -3,17 +3,27 @@ import {OvPropsOption} from "../Ov/ov.utils";
3
3
  import {usePublicOv} from "../Ov/usePublicOv";
4
4
  import {PlcSelect} from "../Table/editor/PlcSelect";
5
5
  import {SelectOption} from "../SelectOption";
6
+ import {PlcScopeSlotsOptions} from "../Table/plc/utils/plc.scope-slots";
7
+ import {inheritSlots} from "../../utils/inheritSlots";
6
8
 
7
9
  export const PlcOv = designComponent({
8
10
  name: 'plc-ov',
9
11
  inheritPropsType: PlcSelect,
10
12
  props: OvPropsOption,
11
- setup({ props }) {
13
+ scopeSlots: PlcScopeSlotsOptions,
14
+ slots: ['default'],
15
+ setup({ props, slots, scopeSlots }) {
12
16
  const { state } = usePublicOv({ props });
13
17
  return () => (
14
- <PlcSelect>
15
- {state.ovMetas.map(meta => (<SelectOption label={meta.name} val={meta.code} key={meta.code}/>))}
16
- </PlcSelect>
18
+ <PlcSelect
19
+ v-slots={inheritSlots({
20
+ slots,
21
+ scopeSlots,
22
+ defaultSlots: {
23
+ default: () => state.ovMetas.map(meta => (<SelectOption label={meta.name} val={meta.code} key={meta.code}/>))
24
+ }
25
+ })}
26
+ />
17
27
  );
18
28
  },
19
29
  });
@@ -3,8 +3,8 @@ import './stack-card.scss';
3
3
  import {findReactElement} from "../../utils/findReactElement";
4
4
  import StackCardItem from "../StackCardItem";
5
5
  import {createEffects} from "plain-utils/utils/createEffects";
6
- import {addElementListener} from "plain-utils/dom/addElementListener";
7
6
  import {delay} from "plain-utils/utils/delay";
7
+ import {addWindowListener} from "plain-utils/dom/addWindowListener";
8
8
 
9
9
  export const StackCard = designComponent({
10
10
  name: 'stack-card',
@@ -78,10 +78,10 @@ export const StackCard = designComponent({
78
78
  draggierState.left = -durX + staticState.startLeft;
79
79
  };
80
80
 
81
- draggierEffects.push(addElementListener(document.body, 'mousemove', touchmove));
82
- draggierEffects.push(addElementListener(document.body, 'mouseup', draggierEffects.clear));
83
- draggierEffects.push(addElementListener(document.body, 'touchmove', touchmove));
84
- draggierEffects.push(addElementListener(document.body, 'touchend', draggierEffects.clear));
81
+ draggierEffects.push(addWindowListener('mousemove', touchmove));
82
+ draggierEffects.push(addWindowListener('mouseup', draggierEffects.clear));
83
+ draggierEffects.push(addWindowListener('touchmove', touchmove));
84
+ draggierEffects.push(addWindowListener('touchend', draggierEffects.clear));
85
85
  };
86
86
 
87
87
  return { draggierState, touchstart };
@@ -19,6 +19,8 @@
19
19
  margin-bottom: $margin;
20
20
 
21
21
  .table-operation-bar-right {
22
+ margin-left: 12px;
23
+
22
24
  & > * + * {
23
25
  margin-left: calc(#{$margin} - 8px);
24
26
  }
@@ -128,12 +128,12 @@ export function useTableFormEditor(
128
128
  const validateAttrs = pick(plc.props, Object.keys(PlcValidatePropsOption) as (keyof typeof PlcValidatePropsOption)[]);
129
129
  return (
130
130
  <FormItem
131
+ key={index}
131
132
  label={plc.props.formLabel || plc.props.title}
132
133
  field={plc.props.field}
133
134
  required={plc.props.required}
134
135
  rules={plc.props.rules}
135
136
  validator={plc.props.validator}
136
- key={index}
137
137
  disabled={!editable}
138
138
  {...validateAttrs}
139
139
  >
@@ -118,12 +118,12 @@ export function useTableModifyEditor(
118
118
  const validateAttrs = pick(plc.props, Object.keys(PlcValidatePropsOption) as (keyof typeof PlcValidatePropsOption)[]);
119
119
  return (
120
120
  <FormItem
121
+ key={index}
121
122
  label={plc.props.formLabel || plc.props.title}
122
123
  field={plc.props.field}
123
124
  required={plc.props.required}
124
125
  rules={plc.props.rules}
125
126
  validator={plc.props.validator}
126
- key={index}
127
127
  disabled={!editable}
128
128
  {...validateAttrs}
129
129
  >
@@ -93,10 +93,9 @@ $scrollbarSize: 12px;
93
93
  }
94
94
 
95
95
  &.plt-row-checked {
96
- border-bottom-color: plv(primary-light-2);
97
-
98
96
  td {
99
97
  background-color: plv(primary-light-1);
98
+ border-bottom-color: plv(primary-light-2);
100
99
  }
101
100
  }
102
101
  }
@@ -15,7 +15,7 @@ export const useDialog = createApplicationService(
15
15
  const service = (sourceOption: string | iDialogServiceOption, externalOption?: iDialogServiceOption): () => void => {
16
16
  const option = formatOptions(sourceOption, externalOption);
17
17
  !option.id && (option.id = nextDialogId());
18
- option.minWidth !== null && (option.minWidth = '325px');
18
+ option.minWidth === null && (option.minWidth = '325px');
19
19
 
20
20
  getManager().then(async manager => {await manager.service(option);});
21
21
 
@@ -0,0 +1,28 @@
1
+ import {RenderNode} from "plain-design-composition";
2
+
3
+ export function inheritSlots<
4
+ Slots extends Record<string, (() => RenderNode) & { isExist: () => boolean }>,
5
+ ScopeSlots extends Record<string, ((...args: any[]) => RenderNode) & { isExist: () => boolean }>,
6
+ >(
7
+ {
8
+ slots,
9
+ scopeSlots,
10
+ defaultSlots,
11
+ defaultScopeSlots,
12
+ }: {
13
+ slots?: Slots,
14
+ scopeSlots?: ScopeSlots,
15
+ defaultSlots?: { [k in keyof Slots]: Omit<Slots[k], 'isExist'> },
16
+ defaultScopeSlots?: { [k in keyof ScopeSlots]: Omit<ScopeSlots[k], 'isExist'> },
17
+ }
18
+ ) {
19
+ const ret = {} as any;
20
+
21
+ !!defaultSlots && Object.entries(defaultSlots).forEach(([key, val]) => {ret[key] = val;});
22
+ !!defaultScopeSlots && Object.entries(defaultScopeSlots).forEach(([key, val]) => {ret[key] = val;});
23
+
24
+ !!slots && Object.keys(slots).forEach((k: keyof Slots) => {if (slots[k].isExist()) {ret[k] = () => slots[k]();}});
25
+ !!scopeSlots && Object.keys(scopeSlots).forEach((k: keyof ScopeSlots) => {if (scopeSlots[k].isExist()) {ret[k] = (...args: any[]) => scopeSlots[k](...args);}});
26
+
27
+ return ret;
28
+ }