plain-design 1.0.0-beta.31 → 1.0.0-beta.33

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. package/dist/plain-design.commonjs.min.js +18 -18
  2. package/dist/plain-design.min.css +11 -6
  3. package/dist/plain-design.min.js +18 -18
  4. package/dist/report.html +38 -38
  5. package/package.json +3 -3
  6. package/src/packages/components/$previewer/ImagePreviewerFixedContainer.tsx +107 -0
  7. package/src/packages/components/$previewer/image-previewer-fixed-container.scss +18 -0
  8. package/src/packages/components/$previewer/index.tsx +52 -0
  9. package/src/packages/components/Application/service/useApplicationService.tsx +2 -0
  10. package/src/packages/components/Carousel/carousel.scss +391 -0
  11. package/src/packages/components/Carousel/index.tsx +569 -22
  12. package/src/packages/components/CarouselItem/index.tsx +77 -0
  13. package/src/packages/components/ImagePreviewer/ImagePreviewer.tsx +572 -0
  14. package/src/packages/components/ImagePreviewer/ImagePreviewerButtonBar.tsx +140 -0
  15. package/src/packages/components/ImagePreviewer/ImagePreviewerCarouselImage.tsx +54 -0
  16. package/src/packages/components/ImagePreviewer/ImagePreviewerGallery.tsx +202 -0
  17. package/src/packages/components/ImagePreviewer/PreviewerLoading.tsx +26 -0
  18. package/src/packages/components/ImagePreviewer/image-previewer.scss +244 -0
  19. package/src/packages/components/ImagePreviewer/image-previewer.utils.tsx +135 -0
  20. package/src/packages/components/ImagePreviewer/index.tsx +5 -0
  21. package/src/packages/components/ImagePreviewer/previewer-loading.scss +52 -0
  22. package/src/packages/components/Input/useMultipleInput.tsx +2 -79
  23. package/src/packages/components/Scroll/index.tsx +6 -6
  24. package/src/packages/components/SortList/index.tsx +191 -0
  25. package/src/packages/components/SortList/sort-list.scss +11 -0
  26. package/src/packages/components/StackCard/index.tsx +260 -0
  27. package/src/packages/components/StackCard/stack-card.scss +28 -0
  28. package/src/packages/components/StackCardItem/index.tsx +23 -0
  29. package/src/packages/components/Table/standard/PlcOperation/PlcOperation.tsx +1 -1
  30. package/src/packages/components/Table/standard/PlcTree/RenderPlcTreeNode.tsx +2 -1
  31. package/src/packages/components/Table/table/body/row.tsx +1 -1
  32. package/src/packages/components/Table/table/use/useTableDraggier.row.tsx +1 -1
  33. package/src/packages/components/Table/table/utils/createTableHooks.ts +1 -1
  34. package/src/packages/components/ThemeEditor/index.tsx +25 -24
  35. package/src/packages/components/Tree/RenderTreeNode.tsx +2 -1
  36. package/src/packages/components/Tree/index.tsx +2 -1
  37. package/src/packages/components/VirtualList/index.tsx +12 -3
  38. package/src/packages/components/VirtualList/useVirtualList.tsx +129 -86
  39. package/src/packages/components/VirtualList/virtual-list.scss +31 -17
  40. package/src/packages/components/VirtualTable/index.tsx +1 -1
  41. package/src/packages/entry.tsx +5 -1
  42. package/src/packages/i18n/lang/en-us.ts +36 -0
  43. package/src/packages/i18n/lang/zh-cn.ts +36 -0
  44. package/src/packages/uses/useDragHorizontalScroll.ts +82 -0
  45. package/src/packages/utils/ComponentUtils.ts +10 -0
  46. package/src/packages/utils/buildCycleIndexList.ts +31 -0
  47. package/src/packages/utils/getDeviceInfo.ts +44 -44
  48. package/src/packages/utils/getRectAutoFormat.ts +9 -0
  49. package/src/packages/utils/notNull.ts +9 -0
  50. package/src/pages/index/app.scss +1 -1
  51. package/src/pages/index/components/normal/DemoCarousel.tsx +178 -73
  52. package/src/pages/index/components/normal/DemoKeepAlive.tsx +25 -25
  53. package/src/pages/index/components/normal/DemoSortList.tsx +70 -0
  54. package/src/pages/index/components/normal/DemoStackCard.tsx +356 -0
  55. package/src/pages/index/components/normal/DemoVirtualList.tsx +89 -3
  56. package/src/pages/index/components/service/DemoImagePreviewer.tsx +185 -0
  57. package/src/pages/index/home/AppHome.tsx +18 -3
  58. package/src/pages/index/home/menus.tsx +3 -1
  59. package/src/packages/components/CarouselGroup/carousel.scss +0 -143
  60. package/src/packages/components/CarouselGroup/index.tsx +0 -274
@@ -0,0 +1,135 @@
1
+ import {PartialFields} from "../../utils/type";
2
+ import {createCounter, createHooks} from "plain-design-composition";
3
+ import {notNull} from "../../utils/notNull";
4
+
5
+ export const ImagePreviewerConstants = {
6
+ /*画廊高度,默认70px*/
7
+ DEFAULT_GALLERY_HEIGHT: 70,
8
+ /*画廊与大图之间的距离,默认24px*/
9
+ DEFAULT_SEPARATOR_HEIGHT: 0,
10
+ };
11
+
12
+ export interface iImagePreviewerOptionPartialFields {
13
+ imageElement?: null | HTMLImageElement, // 点击的图片原始dom对象,如果有传这个属性对象的话会有一个显示放大动画
14
+ galleryHeight: number, // 底部画廊的高度
15
+ separatorHeight: number, // 底部画廊距离图片显示区域的距离
16
+ autoHeight: boolean, // 自动高度,默认是true。这样设置之后图片会撑满宽度,高度自动;关闭的时候会设置高度100%,图片宽度自动
17
+ mask: boolean, // 显示背部遮罩
18
+ button?: boolean | { // 顶部按钮栏控制,button为false则禁用所有按钮;为对象则单独禁用某个按钮
19
+ zoomIn?: boolean, // 放大按钮
20
+ zoomOut?: boolean, // 缩小按钮
21
+ clockwise?: boolean, // 顺时针旋转按钮
22
+ anticlockwise?: boolean, // 逆时针旋转按钮
23
+ reset?: boolean, // 重置按钮
24
+ close?: boolean, // 关闭按钮
25
+ },
26
+ swipeButton?: boolean // 左右切换按钮控制,swipeButton为false则禁用前后按钮
27
+ gallery?: boolean, // 底部画廊控制,为false则禁用底部画廊
28
+ globalKeyboardEvent?: boolean // 监听全局的键盘事件,默认不监听全局键盘按键事件,而是等鼠标移入的时候才监听
29
+ maskColor?: string, // 遮罩颜色
30
+ disableZoomOnWheel?: boolean, // 禁用滚轮缩放
31
+ /*---------------------------------------以下为不可配置属性-------------------------------------------*/
32
+ id: string, // option唯一标识
33
+ oldSourceImageOpacity?: string // 原始的img对象的opacity属性值
34
+ }
35
+
36
+ export interface iImagePreviewerOption extends iImagePreviewerOptionPartialFields {
37
+ current: number; // 当前显示的元素索引
38
+ urls: { url: string, thumbUrl: string }[]; // 所有展示的图片,url为大图地址,thumbUrl为底部画廊图片预览地址
39
+ }
40
+
41
+ export type iImagePreviewerParamOption = string | string[] | iImagePreviewerOption['urls'] | Omit<PartialFields<iImagePreviewerOption, keyof iImagePreviewerOptionPartialFields>, 'urls'> & { urls: string[] | iImagePreviewerOption['urls'] }
42
+
43
+ export const ImagePreviewerHooks = {
44
+ /*PreviewerComponent挂载完毕事件*/
45
+ onImagePreviewerReady: createHooks<(data: { option: iImagePreviewerOption }) => void>()
46
+ };
47
+
48
+ const nextOptionId = createCounter('image_previewer');
49
+
50
+ export function createImagePreviewerOption(
51
+ param: iImagePreviewerParamOption,
52
+ imageElement?: HTMLImageElement,
53
+ defaultParam?: Partial<iImagePreviewerOption>
54
+ ): iImagePreviewerOption {
55
+ if (typeof param === "string") {
56
+ return {
57
+ id: nextOptionId(),
58
+ current: 0,
59
+ imageElement,
60
+ autoHeight: true,
61
+ mask: false,
62
+ urls: [{ url: param, thumbUrl: param }],
63
+ galleryHeight: ImagePreviewerConstants.DEFAULT_GALLERY_HEIGHT,
64
+ separatorHeight: ImagePreviewerConstants.DEFAULT_SEPARATOR_HEIGHT,
65
+ ...defaultParam,
66
+ };
67
+ }
68
+ if (Array.isArray(param)) {
69
+ return {
70
+ id: nextOptionId(),
71
+ current: 0,
72
+ imageElement,
73
+ autoHeight: true,
74
+ mask: false,
75
+ urls: param.map(p => typeof p === "string" ? { url: p, thumbUrl: p } : p),
76
+ galleryHeight: ImagePreviewerConstants.DEFAULT_GALLERY_HEIGHT,
77
+ separatorHeight: ImagePreviewerConstants.DEFAULT_SEPARATOR_HEIGHT,
78
+ ...defaultParam,
79
+ };
80
+ }
81
+ if (!!imageElement) {
82
+ param.imageElement = imageElement;
83
+ }
84
+ return {
85
+ autoHeight: true,
86
+ mask: false,
87
+ galleryHeight: notNull(param.galleryHeight, ImagePreviewerConstants.DEFAULT_GALLERY_HEIGHT),
88
+ separatorHeight: notNull(param.separatorHeight, ImagePreviewerConstants.DEFAULT_SEPARATOR_HEIGHT),
89
+ ...defaultParam,
90
+ ...param,
91
+ id: nextOptionId(),
92
+ urls: param.urls.map(p => typeof p === "string" ? { url: p, thumbUrl: p } : p),
93
+ };
94
+ }
95
+
96
+ /**
97
+ * 获取imageElement在containerElement容器中居中铺满的位置信息
98
+ * @author 韦胜健
99
+ * @date 2024/1/10 18:50
100
+ */
101
+ export const getCenterRect = (
102
+ {
103
+ imageElement, containerElement
104
+ }: {
105
+ imageElement: HTMLDivElement,
106
+ containerElement: HTMLDivElement | { containerRatio: number, containerHeight: number, containerWidth: number },
107
+ }
108
+ ) => {
109
+ const imageRatio = Number((imageElement.offsetWidth / imageElement.offsetHeight).toFixed(2));
110
+ const { containerRatio, containerHeight, containerWidth } = 'tagName' in containerElement ? (() => {
111
+ const containerRatio = Number((containerElement.offsetWidth / containerElement.offsetHeight).toFixed(2));
112
+ return {
113
+ containerRatio,
114
+ containerHeight: containerElement.offsetHeight,
115
+ containerWidth: containerElement.offsetWidth,
116
+ };
117
+ })() : containerElement;
118
+
119
+
120
+ if (imageRatio > containerRatio) {
121
+ /*宽度更宽,固定宽度为屏幕宽度缩放*/
122
+ const left = 0;
123
+ const width = containerWidth;
124
+ const height = Number((imageElement.offsetHeight / imageElement.offsetWidth * width).toFixed(0));
125
+ const top = Number(((containerHeight - height) / 2).toFixed(0));
126
+ return { top, left, width, height };
127
+ } else {
128
+ /*高度更高,固定高度将宽度缩放*/
129
+ const top = 0;
130
+ const height = containerHeight;
131
+ const width = Number((imageElement.offsetWidth / imageElement.offsetHeight * height).toFixed(0));
132
+ const left = Number(((containerWidth - width) / 2).toFixed(0));
133
+ return { top, left, width, height };
134
+ }
135
+ };
@@ -0,0 +1,5 @@
1
+ import {ImagePreviewer} from "./ImagePreviewer";
2
+
3
+ export default ImagePreviewer;
4
+
5
+ export {ImagePreviewer};
@@ -0,0 +1,52 @@
1
+ .previewer-loading {
2
+
3
+ $size: 1em;
4
+
5
+ height: $size;
6
+ width: $size;
7
+
8
+ .plain-loading-tag {
9
+ $centerRadius: (0.5*$size)/1.2;
10
+ $itemWidth: (0.35*$size)/1.2;
11
+ $itemHeight: (0.1*$size)/1.2;
12
+ $width: $centerRadius + $itemWidth * 2;
13
+ $height: $width;
14
+
15
+ width: $width;
16
+ height: $height;
17
+ position: relative;
18
+ display: block;
19
+
20
+ .plain-loading-inner {
21
+ background-color: currentColor;
22
+ display: inline-block;
23
+ width: $itemWidth;
24
+ height: $itemHeight;
25
+ margin-top: $itemHeight / 2 * -1;
26
+ margin-left: $centerRadius / 2;
27
+ top: 50%;
28
+ left: 50%;
29
+ position: absolute;
30
+ transform-origin: ($centerRadius / 2 * -1) ($itemHeight / 2);
31
+ @for $i from 1 through 12 {
32
+ &:nth-child(#{$i}) {
33
+ transform: rotate(($i - 1) * 30deg);
34
+ animation: plain-loading-tag 1s linear infinite #{-1 + $i / 12}s;
35
+ }
36
+ }
37
+ @keyframes plain-loading-tag {
38
+ 0% {
39
+ opacity: 1;
40
+ }
41
+ @for $i from 1 through 11 {
42
+ #{$i / 12 * 100}% {
43
+ opacity: 1 - $i / 12;
44
+ }
45
+ }
46
+ 100% {
47
+ opacity: 1;
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
@@ -1,12 +1,12 @@
1
1
  import {AutoWidthInput} from "../AutoWidthInput";
2
2
  import {iInputCompositionData, inputScrollEnd} from "./input.utils";
3
3
  import Icon from "../Icon";
4
- import {iHTMLElement, useClasses, useModel, useRefs, watch} from "plain-design-composition";
4
+ import {iHTMLElement, useClasses, useModel, useRefs} from "plain-design-composition";
5
5
  import {getKey, KEY} from "../KeyboardService";
6
6
  import {delay} from "plain-utils/utils/delay";
7
7
  import {createEffectiveHandler} from "../../utils/createEffectiveHandler";
8
8
  import {createEffects} from "plain-utils/utils/createEffects";
9
- import {ClientZoom} from "../..";
9
+ import {useDragHorizontalScroll} from "../../uses/useDragHorizontalScroll";
10
10
 
11
11
  /**
12
12
  * 渲染多值输入框
@@ -121,80 +121,3 @@ export const useMultipleInput = createEffectiveHandler(({ hooks, props, model, r
121
121
 
122
122
  return effects.clear;
123
123
  });
124
-
125
- function useDragHorizontalScroll(getEl: () => HTMLElement | null | undefined) {
126
-
127
- const staticState = {
128
- isDragging: false,
129
- el: null as null | undefined | HTMLElement,
130
- start: {
131
- x: 0,
132
- left: 0,
133
- width: 0,
134
- },
135
- move: {
136
- x: 0
137
- }
138
- };
139
-
140
- const { effects } = createEffects();
141
-
142
- const handler = {
143
- mousedown: (e: MouseEvent) => {
144
- const { clientX } = ClientZoom.getClientPosition(e);
145
- staticState.isDragging = false;
146
- staticState.start = {
147
- x: clientX,
148
- left: staticState.el!.scrollLeft,
149
- width: staticState.el!.scrollWidth,
150
- };
151
- document.documentElement.addEventListener('mousemove', handler.mousemove, true);
152
- document.documentElement.addEventListener('mouseup', handler.mouseup, true);
153
- },
154
- mousemove: (e: MouseEvent) => {
155
- const { clientX } = ClientZoom.getClientPosition(e);
156
- staticState.move.x = clientX;
157
- const durX = staticState.move.x - staticState.start.x;
158
- if (!staticState.isDragging) {
159
- if (Math.abs(durX) > 5) {
160
- staticState.isDragging = true;
161
- }
162
- }
163
- if (!staticState.isDragging) {
164
- return;
165
- }
166
- staticState.el!.scrollLeft = staticState.start.left - durX;
167
- },
168
- mouseup: () => {
169
- document.documentElement.removeEventListener('mousemove', handler.mousemove, true);
170
- document.documentElement.removeEventListener('mouseup', handler.mouseup, true);
171
- },
172
- onWheel: (e: WheelEvent) => {
173
- e.stopPropagation();
174
- e.preventDefault();
175
- const el = e.currentTarget as HTMLElement;
176
- const delta = e.deltaX + e.deltaY;
177
- el.scrollLeft += delta;
178
- },
179
- };
180
-
181
- effects.push(watch(() => getEl(), el => {
182
- if (!!staticState.el) {
183
- staticState.el.removeEventListener('mousedown', handler.mousedown);
184
- staticState.el.removeEventListener('wheel', handler.onWheel);
185
- }
186
- staticState.el = el;
187
- if (!staticState.el) {return;}
188
- staticState.el.addEventListener('mousedown', handler.mousedown);
189
- staticState.el.addEventListener('wheel', handler.onWheel);
190
- }));
191
-
192
- effects.push(() => {
193
- if (!!staticState.el) {
194
- staticState.el.removeEventListener('mousedown', handler.mousedown);
195
- staticState.el.removeEventListener('wheel', handler.onWheel);
196
- }
197
- });
198
-
199
- return effects.clear;
200
- }
@@ -78,9 +78,9 @@ export const Scroll = designComponent({
78
78
  set isDragging(val: boolean) {
79
79
  this._isDragging = val;
80
80
  if (val) {
81
- refs.host!.setAttribute('is-dragging', '');
81
+ refs.host?.setAttribute('is-dragging', '');
82
82
  } else {
83
- refs.host!.removeAttribute('is-dragging');
83
+ refs.host?.removeAttribute('is-dragging');
84
84
  }
85
85
  },
86
86
  };
@@ -215,9 +215,9 @@ export const Scroll = designComponent({
215
215
  * @date 2020/12/15 10:16
216
216
  */
217
217
  disableListTransition: (() => {
218
- const disabledQueueAnimation = debounce(() => refs.host!.removeAttribute('virtual-scrolling'), 300, true);
218
+ const disabledQueueAnimation = debounce(() => refs.host?.removeAttribute('virtual-scrolling'), 300, true);
219
219
  return () => {
220
- refs.host!.setAttribute('virtual-scrolling', '');
220
+ refs.host?.setAttribute('virtual-scrolling', '');
221
221
  disabledQueueAnimation();
222
222
  };
223
223
  })(),
@@ -227,9 +227,9 @@ export const Scroll = designComponent({
227
227
  * @date 2022.10.28 21:34
228
228
  */
229
229
  disableInnerTransition: (() => {
230
- const disabledQueueAnimation = debounce(() => refs.host!.removeAttribute('disable-all-transition'), 300, true);
230
+ const disabledQueueAnimation = debounce(() => refs.host?.removeAttribute('disable-all-transition'), 300, true);
231
231
  return () => {
232
- refs.host!.setAttribute('disable-all-transition', '');
232
+ refs.host?.setAttribute('disable-all-transition', '');
233
233
  disabledQueueAnimation();
234
234
  };
235
235
  })()
@@ -0,0 +1,191 @@
1
+ import {computed, CSSProperties, designComponent, getComponentCls, iHTMLDivElement, iMouseEvent, PropType, reactive, useClasses, useModel, useRefs} from "plain-design-composition";
2
+ import './sort-list.scss';
3
+ import {createEffects} from "plain-utils/utils/createEffects";
4
+ import {addWindowListener} from "plain-utils/dom/addWindowListener";
5
+ import {getRectAutoFormat} from "../../utils/getRectAutoFormat";
6
+ import {iElementRect} from "../../utils/getRowEl";
7
+
8
+ export const SortList = designComponent({
9
+ name: 'sort-list',
10
+ props: {
11
+ modelValue: { type: Array as PropType<any[]> },
12
+ col: { type: Number, default: 1 },
13
+ space: { type: Number, default: 0 },
14
+ },
15
+ emits: {
16
+ onUpdateModelValue: (val: any[]) => true,
17
+ onDragStart: (data: { item: any, index: number, e: iMouseEvent }) => true,
18
+ },
19
+ scopeSlots: {
20
+ default: (data: { item: any, index: number }) => true,
21
+ },
22
+ setup({ props, scopeSlots, event: { emit } }) {
23
+
24
+ const { refs, onRef } = useRefs({ el: iHTMLDivElement });
25
+
26
+ const model = useModel(() => props.modelValue || [], emit.onUpdateModelValue);
27
+
28
+ const isHorizontal = computed(() => props.col > 1);
29
+
30
+ const classes = useClasses(() => [
31
+ getComponentCls('sort-list'),
32
+ ]);
33
+
34
+ const draggier = (() => {
35
+
36
+ const draggierState = reactive({
37
+ isDragging: false,
38
+ });
39
+
40
+ const mousedown = (e: iMouseEvent, item: any, index: number) => {
41
+ emit.onDragStart({ item, index, e });
42
+
43
+ const { effects: draggierEffects } = createEffects();
44
+ const staticState = {
45
+ start: {
46
+ x: e.clientX,
47
+ y: e.clientY,
48
+ left: 0,
49
+ top: 0,
50
+ },
51
+ siblingRects: (() => {
52
+ const sortItemElements = Array.from(refs.el!.querySelectorAll('.sort-item')) as HTMLElement[];
53
+ return sortItemElements.map((el, index) => {
54
+ return {
55
+ index,
56
+ rects: getRectAutoFormat(el)
57
+ };
58
+ });
59
+ })(),
60
+ dropData: null as null | {
61
+ itemRect: { index: number, rects: Omit<iElementRect, 'right' | 'bottom'> },
62
+ pos: 'prev' | 'next'
63
+ }
64
+ };
65
+ const sourceElement = (e.currentTarget as HTMLElement);
66
+ const sourceRect = getRectAutoFormat(sourceElement);
67
+ staticState.start.left = sourceRect.left;
68
+ staticState.start.top = sourceRect.top;
69
+ let shadowElement: HTMLElement | null = null;
70
+ let indicator: HTMLDivElement | null = null;
71
+ const indicatorSize = 2;
72
+
73
+ draggierEffects.push(addWindowListener('mouseup', draggierEffects.clear));
74
+ draggierEffects.push(addWindowListener('mousemove', (e) => {
75
+ const durX = e.clientX - staticState.start.x;
76
+ const durY = e.clientY - staticState.start.y;
77
+
78
+ if (!draggierState.isDragging) {
79
+ if (Math.abs(durX) > 5 || Math.abs(durY) > 5) {
80
+ draggierState.isDragging = true;
81
+ draggierEffects.push(() => {draggierState.isDragging = false;});
82
+
83
+ shadowElement = sourceElement.cloneNode(true) as HTMLElement;
84
+ shadowElement.style.boxSizing = 'border-box';
85
+ shadowElement.style.position = 'fixed';
86
+ shadowElement.style.top = sourceRect.top + 'px';
87
+ shadowElement.style.left = sourceRect.left + 'px';
88
+ shadowElement.style.height = sourceRect.height + 'px';
89
+ shadowElement.style.width = sourceRect.width + 'px';
90
+ shadowElement.style.opacity = '0.5';
91
+ shadowElement.style.zIndex = '2';
92
+ refs.el!.appendChild(shadowElement);
93
+ draggierEffects.push(() => {refs.el!.removeChild(shadowElement!);});
94
+
95
+ sourceElement.style.opacity = "0";
96
+ draggierEffects.push(() => sourceElement.style.opacity = "");
97
+
98
+ indicator = document.createElement('div') as HTMLDivElement;
99
+ indicator.style.position = 'fixed';
100
+ indicator.style.zIndex = '3';
101
+ refs.el!.appendChild(indicator);
102
+ draggierEffects.push(() => {refs.el!.removeChild(indicator!);});
103
+
104
+ draggierEffects.push(() => {
105
+ if (!staticState.dropData) {return;}
106
+ if (staticState.dropData.itemRect.index === index) {return;}
107
+ let currentIndex = index;
108
+ let targetIndex = staticState.dropData.itemRect.index + (staticState.dropData.pos === 'prev' ? 0 : 1);
109
+ const newData = [...model.value];
110
+ const removeData = newData.splice(currentIndex, 1);
111
+ newData.splice(targetIndex > currentIndex ? targetIndex - 1 : targetIndex, 0, ...removeData);
112
+ model.value = newData;
113
+ });
114
+ }
115
+ }
116
+ if (!draggierState.isDragging || !shadowElement || !indicator) {
117
+ return;
118
+ }
119
+
120
+ shadowElement.style.top = `${Math.ceil(staticState.start.top + durY)}px`;
121
+ shadowElement.style.left = `${Math.ceil(staticState.start.left + durX)}px`;
122
+
123
+ const matchItemRect = staticState.siblingRects.find(i => {
124
+ return e.clientY > i.rects.top && e.clientY < i.rects.top + i.rects.height && e.clientX > i.rects.left && e.clientX < i.rects.left + i.rects.width;
125
+ });
126
+ if (!matchItemRect) {
127
+ staticState.dropData = null;
128
+ indicator.style.display = 'none';
129
+ } else {
130
+ staticState.dropData = {
131
+ itemRect: matchItemRect,
132
+ pos: (() => {
133
+ if (isHorizontal.value) {
134
+ return e.clientX > matchItemRect.rects.left + matchItemRect.rects.width / 2 ? 'next' : 'prev';
135
+ } else {
136
+ return e.clientY > matchItemRect.rects.top + matchItemRect.rects.height / 2 ? 'next' : 'prev';
137
+ }
138
+ })()
139
+ };
140
+ indicator.style.display = 'block';
141
+ indicator.style.backgroundColor = 'black';
142
+ if (isHorizontal.value) {
143
+ indicator.style.top = matchItemRect.rects.top + 'px';
144
+ indicator.style.height = matchItemRect.rects.height + 'px';
145
+ indicator.style.left = matchItemRect.rects.left + (staticState.dropData.pos === 'prev' ? (-indicatorSize / 2 - props.space / 2) : (matchItemRect.rects.width + props.space / 2 - indicatorSize / 2)) + 'px';
146
+ indicator.style.width = indicatorSize + 'px';
147
+ } else {
148
+ indicator.style.left = matchItemRect.rects.left + 'px';
149
+ indicator.style.width = matchItemRect.rects.width + 'px';
150
+ indicator.style.top = matchItemRect.rects.top + (staticState.dropData.pos === 'prev' ? (-indicatorSize / 2 - props.space / 2) : (matchItemRect.rects.height + props.space / 2 - indicatorSize / 2)) + 'px';
151
+ indicator.style.height = indicatorSize + 'px';
152
+ }
153
+ }
154
+ }));
155
+ };
156
+
157
+ return { mousedown };
158
+ })();
159
+
160
+ return () => (
161
+ <div
162
+ className={classes.value}
163
+ data-direction={isHorizontal.value ? 'horizontal' : 'vertical'}
164
+ ref={onRef.el}
165
+ >
166
+ {model.value.map((item, index) => {
167
+ const styles = {} as CSSProperties;
168
+ if (props.col !== 1) {
169
+ styles.width = `calc((100% - ${(props.col - 1) * props.space}px) / ${props.col})`;
170
+ if ((index + 1) % props.col !== 0) {
171
+ styles.marginRight = props.space + 'px';
172
+ }
173
+ } else {
174
+ styles.width = '100%';
175
+ }
176
+ styles.marginBottom = props.space + 'px';
177
+ return (
178
+ <div
179
+ className="sort-item"
180
+ style={styles}
181
+ key={index}
182
+ onMouseDown={e => draggier.mousedown(e, item, index)}
183
+ >
184
+ {scopeSlots.default({ item, index }, null)}
185
+ </div>
186
+ );
187
+ })}
188
+ </div>
189
+ );
190
+ },
191
+ });
@@ -0,0 +1,11 @@
1
+ @include comp(sort-list) {
2
+ user-select: none;
3
+ &[data-direction=horizontal] {
4
+ display: flex;
5
+ flex-wrap: wrap;
6
+ }
7
+ &[data-direction=vertical] {
8
+ display: flex;
9
+ flex-direction: column;
10
+ }
11
+ }