stellar-ui-plus 1.25.0 → 1.25.2

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 (248) hide show
  1. package/components/ste-animate/ATTRIBUTES.md +13 -5
  2. package/components/ste-animate/README.md +4 -28
  3. package/components/ste-animate/ste-animate.easycom.json +31 -9
  4. package/components/ste-app-update/ATTRIBUTES.md +11 -5
  5. package/components/ste-app-update/README.md +1 -3
  6. package/components/ste-app-update/method.ts +44 -1
  7. package/components/ste-app-update/props.ts +17 -2
  8. package/components/ste-app-update/ste-app-update.easycom.json +18 -8
  9. package/components/ste-app-update/ste-app-update.vue +93 -18
  10. package/components/ste-area-chart/ATTRIBUTES.md +3 -1
  11. package/components/ste-area-chart/README.md +4 -4
  12. package/components/ste-badge/ATTRIBUTES.md +10 -1
  13. package/components/ste-badge/README.md +9 -18
  14. package/components/ste-badge/ste-badge.easycom.json +8 -0
  15. package/components/ste-bar-chart/ATTRIBUTES.md +3 -1
  16. package/components/ste-bar-chart/README.md +3 -5
  17. package/components/ste-barcode/ATTRIBUTES.md +6 -2
  18. package/components/ste-barcode/README.md +3 -5
  19. package/components/ste-barcode/ste-barcode.easycom.json +1 -2
  20. package/components/ste-button/ATTRIBUTES.md +24 -14
  21. package/components/ste-button/README.md +11 -19
  22. package/components/ste-button/ste-button.easycom.json +76 -12
  23. package/components/ste-calendar/ATTRIBUTES.md +12 -2
  24. package/components/ste-calendar/README.md +16 -24
  25. package/components/ste-calendar/ste-calendar.easycom.json +4 -3
  26. package/components/ste-category/ATTRIBUTES.md +6 -2
  27. package/components/ste-category/README.md +2 -4
  28. package/components/ste-category/ste-category.easycom.json +1 -2
  29. package/components/ste-checkbox/ATTRIBUTES.md +6 -2
  30. package/components/ste-checkbox/README.md +18 -20
  31. package/components/ste-checkbox/ste-checkbox.easycom.json +1 -3
  32. package/components/ste-checkbox/ste-checkbox.vue +71 -80
  33. package/components/ste-code-input/ATTRIBUTES.md +8 -4
  34. package/components/ste-code-input/README.md +7 -9
  35. package/components/ste-code-input/ste-code-input.easycom.json +13 -4
  36. package/components/ste-column-chart/ATTRIBUTES.md +3 -1
  37. package/components/ste-column-chart/README.md +5 -7
  38. package/components/ste-comment/ATTRIBUTES.md +3 -1
  39. package/components/ste-comment/README.md +2 -4
  40. package/components/ste-coupon-list/ATTRIBUTES.md +15 -5
  41. package/components/ste-coupon-list/README.md +6 -14
  42. package/components/ste-coupon-list/ste-coupon-list.easycom.json +22 -3
  43. package/components/ste-custom-keyboard/ATTRIBUTES.md +16 -7
  44. package/components/ste-custom-keyboard/README.md +10 -18
  45. package/components/ste-custom-keyboard/ste-custom-keyboard.easycom.json +28 -10
  46. package/components/ste-date-picker/ATTRIBUTES.md +9 -5
  47. package/components/ste-date-picker/README.md +9 -11
  48. package/components/ste-date-picker/ste-date-picker.easycom.json +19 -4
  49. package/components/ste-date-user/ATTRIBUTES.md +9 -1
  50. package/components/ste-date-user/README.md +3 -11
  51. package/components/ste-date-user/ste-date-user.easycom.json +4 -0
  52. package/components/ste-drag/ATTRIBUTES.md +13 -3
  53. package/components/ste-drag/README.md +5 -13
  54. package/components/ste-drag/ste-drag.easycom.json +10 -2
  55. package/components/ste-drag-sort/ATTRIBUTES.md +25 -0
  56. package/components/ste-drag-sort/README.md +116 -0
  57. package/components/ste-drag-sort/config.json +5 -0
  58. package/components/ste-drag-sort/props.ts +16 -0
  59. package/components/ste-drag-sort/ste-drag-sort.easycom.json +88 -0
  60. package/components/ste-drag-sort/ste-drag-sort.vue +589 -0
  61. package/components/ste-dropdown-menu/ATTRIBUTES.md +8 -4
  62. package/components/ste-dropdown-menu/README.md +14 -16
  63. package/components/ste-dropdown-menu/ste-dropdown-menu.easycom.json +13 -4
  64. package/components/ste-filter-tool/ATTRIBUTES.md +6 -2
  65. package/components/ste-filter-tool/README.md +4 -6
  66. package/components/ste-filter-tool/ste-filter-tool.easycom.json +1 -5
  67. package/components/ste-function-list/ATTRIBUTES.md +13 -2
  68. package/components/ste-function-list/README.md +3 -12
  69. package/components/ste-function-list/ste-function-list.easycom.json +8 -3
  70. package/components/ste-funnel-chart/ATTRIBUTES.md +3 -1
  71. package/components/ste-funnel-chart/README.md +4 -6
  72. package/components/ste-goods-info/ATTRIBUTES.md +15 -4
  73. package/components/ste-goods-info/README.md +8 -17
  74. package/components/ste-goods-info/ste-goods-info.easycom.json +40 -13
  75. package/components/ste-goods-list/ATTRIBUTES.md +9 -1
  76. package/components/ste-goods-list/README.md +4 -12
  77. package/components/ste-goods-list/ste-goods-list.easycom.json +4 -0
  78. package/components/ste-guide-qa/ATTRIBUTES.md +15 -4
  79. package/components/ste-guide-qa/README.md +6 -15
  80. package/components/ste-guide-qa/ste-guide-qa.easycom.json +20 -2
  81. package/components/ste-icon/ATTRIBUTES.md +7 -3
  82. package/components/ste-icon/README.md +5 -7
  83. package/components/ste-icon/ste-icon.easycom.json +7 -2
  84. package/components/ste-image/ATTRIBUTES.md +13 -2
  85. package/components/ste-image/README.md +6 -15
  86. package/components/ste-image/ste-image.easycom.json +8 -3
  87. package/components/ste-index-list/ATTRIBUTES.md +8 -4
  88. package/components/ste-index-list/README.md +6 -8
  89. package/components/ste-index-list/ste-index-list.easycom.json +13 -3
  90. package/components/ste-input/ATTRIBUTES.md +14 -3
  91. package/components/ste-input/README.md +16 -25
  92. package/components/ste-input/ste-input.easycom.json +14 -5
  93. package/components/ste-line-chart/ATTRIBUTES.md +3 -1
  94. package/components/ste-line-chart/README.md +5 -7
  95. package/components/ste-loading/ATTRIBUTES.md +3 -1
  96. package/components/ste-loading/README.md +6 -8
  97. package/components/ste-login/ATTRIBUTES.md +12 -2
  98. package/components/ste-login/README.md +7 -15
  99. package/components/ste-login/ste-login.easycom.json +4 -7
  100. package/components/ste-login-info/ATTRIBUTES.md +6 -2
  101. package/components/ste-login-info/README.md +2 -4
  102. package/components/ste-login-info/ste-login-info.easycom.json +1 -4
  103. package/components/ste-marquee/ATTRIBUTES.md +44 -0
  104. package/components/ste-marquee/README.md +123 -0
  105. package/components/ste-marquee/config.json +5 -0
  106. package/components/ste-marquee/props.ts +106 -0
  107. package/components/ste-marquee/ste-marquee.easycom.json +132 -0
  108. package/components/ste-marquee/ste-marquee.vue +249 -0
  109. package/components/ste-media-preview/ATTRIBUTES.md +14 -4
  110. package/components/ste-media-preview/README.md +23 -32
  111. package/components/ste-media-preview/ste-media-preview.easycom.json +16 -4
  112. package/components/ste-message-box/ATTRIBUTES.md +3 -1
  113. package/components/ste-message-box/README.md +11 -13
  114. package/components/ste-navbar/ATTRIBUTES.md +13 -3
  115. package/components/ste-navbar/README.md +5 -13
  116. package/components/ste-navbar/ste-navbar.easycom.json +10 -1
  117. package/components/ste-notice-bar/ATTRIBUTES.md +16 -5
  118. package/components/ste-notice-bar/README.md +11 -20
  119. package/components/ste-notice-bar/ste-notice-bar.easycom.json +26 -3
  120. package/components/ste-number-keyboard/ATTRIBUTES.md +17 -7
  121. package/components/ste-number-keyboard/README.md +9 -18
  122. package/components/ste-number-keyboard/ste-number-keyboard.easycom.json +32 -9
  123. package/components/ste-order-card/ATTRIBUTES.md +6 -2
  124. package/components/ste-order-card/README.md +4 -6
  125. package/components/ste-order-card/ste-order-card.easycom.json +1 -4
  126. package/components/ste-pie-chart/ATTRIBUTES.md +3 -1
  127. package/components/ste-pie-chart/README.md +4 -6
  128. package/components/ste-popup/ATTRIBUTES.md +15 -5
  129. package/components/ste-popup/README.md +10 -18
  130. package/components/ste-popup/ste-popup.easycom.json +22 -4
  131. package/components/ste-price/ATTRIBUTES.md +7 -3
  132. package/components/ste-price/README.md +10 -12
  133. package/components/ste-price/ste-price.easycom.json +7 -2
  134. package/components/ste-progress/ATTRIBUTES.md +9 -1
  135. package/components/ste-progress/README.md +9 -17
  136. package/components/ste-progress/ste-progress.easycom.json +4 -0
  137. package/components/ste-qrcode/ATTRIBUTES.md +6 -2
  138. package/components/ste-qrcode/README.md +4 -6
  139. package/components/ste-qrcode/ste-qrcode.easycom.json +1 -2
  140. package/components/ste-radio/ATTRIBUTES.md +6 -2
  141. package/components/ste-radio/README.md +17 -19
  142. package/components/ste-radio/ste-radio.easycom.json +1 -3
  143. package/components/ste-radio/ste-radio.vue +109 -85
  144. package/components/ste-rate/ATTRIBUTES.md +7 -3
  145. package/components/ste-rate/README.md +8 -10
  146. package/components/ste-rate/ste-rate.easycom.json +7 -2
  147. package/components/ste-read-more/ATTRIBUTES.md +20 -4
  148. package/components/ste-read-more/README.md +5 -19
  149. package/components/ste-read-more/ste-read-more.easycom.json +20 -2
  150. package/components/ste-rich-text/ATTRIBUTES.md +3 -1
  151. package/components/ste-rich-text/README.md +2 -4
  152. package/components/ste-ring-chart/ATTRIBUTES.md +3 -1
  153. package/components/ste-ring-chart/README.md +22 -5
  154. package/components/ste-ring-chart/ste-ring-chart.vue +40 -1
  155. package/components/ste-scroll-to/ATTRIBUTES.md +7 -3
  156. package/components/ste-scroll-to/README.md +2 -4
  157. package/components/ste-scroll-to/ste-scroll-to.easycom.json +7 -2
  158. package/components/ste-search/ATTRIBUTES.md +14 -3
  159. package/components/ste-search/README.md +12 -21
  160. package/components/ste-search/ste-search.easycom.json +14 -7
  161. package/components/ste-search-box/ATTRIBUTES.md +6 -2
  162. package/components/ste-search-box/README.md +3 -5
  163. package/components/ste-search-box/ste-search-box.easycom.json +1 -3
  164. package/components/ste-select/ATTRIBUTES.md +9 -5
  165. package/components/ste-select/README.md +11 -11
  166. package/components/ste-select/ste-select.easycom.json +19 -6
  167. package/components/ste-select-seat/ATTRIBUTES.md +8 -4
  168. package/components/ste-select-seat/README.md +7 -21
  169. package/components/ste-select-seat/ste-select-seat.easycom.json +13 -3
  170. package/components/ste-signature/ATTRIBUTES.md +18 -5
  171. package/components/ste-signature/README.md +3 -14
  172. package/components/ste-signature/ste-signature.easycom.json +50 -3
  173. package/components/ste-simple-calendar/ATTRIBUTES.md +16 -4
  174. package/components/ste-simple-calendar/README.md +8 -18
  175. package/components/ste-simple-calendar/ste-simple-calendar.easycom.json +30 -2
  176. package/components/ste-skeleton/ATTRIBUTES.md +9 -1
  177. package/components/ste-skeleton/README.md +5 -13
  178. package/components/ste-skeleton/ste-skeleton.easycom.json +4 -0
  179. package/components/ste-slide-verify/ATTRIBUTES.md +16 -5
  180. package/components/ste-slide-verify/README.md +7 -16
  181. package/components/ste-slide-verify/ste-slide-verify.easycom.json +26 -3
  182. package/components/ste-slider/ATTRIBUTES.md +14 -2
  183. package/components/ste-slider/README.md +12 -21
  184. package/components/ste-slider/ste-slider.easycom.json +12 -4
  185. package/components/ste-slider/ste-slider.vue +5 -3
  186. package/components/ste-stepper/ATTRIBUTES.md +9 -5
  187. package/components/ste-stepper/README.md +9 -13
  188. package/components/ste-stepper/ste-stepper.easycom.json +19 -6
  189. package/components/ste-steps/ATTRIBUTES.md +6 -2
  190. package/components/ste-steps/README.md +9 -11
  191. package/components/ste-steps/ste-steps.easycom.json +1 -2
  192. package/components/ste-sticky/ATTRIBUTES.md +8 -4
  193. package/components/ste-sticky/README.md +2 -4
  194. package/components/ste-sticky/ste-sticky.easycom.json +13 -3
  195. package/components/ste-swipe-action/ATTRIBUTES.md +14 -3
  196. package/components/ste-swipe-action/README.md +9 -18
  197. package/components/ste-swipe-action/ste-swipe-action.easycom.json +20 -2
  198. package/components/ste-swipe-action/useData.ts +15 -8
  199. package/components/ste-swipe-action-group/ATTRIBUTES.md +6 -2
  200. package/components/ste-swipe-action-group/ste-swipe-action-group.easycom.json +1 -3
  201. package/components/ste-swiper/ATTRIBUTES.md +6 -2
  202. package/components/ste-swiper/README.md +12 -14
  203. package/components/ste-swiper/ste-swiper.easycom.json +1 -3
  204. package/components/ste-switch/ATTRIBUTES.md +8 -4
  205. package/components/ste-switch/README.md +7 -9
  206. package/components/ste-switch/ste-switch.easycom.json +13 -3
  207. package/components/ste-tab/ATTRIBUTES.md +3 -1
  208. package/components/ste-table/ATTRIBUTES.md +12 -8
  209. package/components/ste-table/README.md +23 -23
  210. package/components/ste-table/ste-table.easycom.json +38 -9
  211. package/components/ste-tabs/ATTRIBUTES.md +9 -4
  212. package/components/ste-tabs/README.md +4 -6
  213. package/components/ste-tabs/props.ts +3 -0
  214. package/components/ste-tabs/ste-tabs.easycom.json +18 -2
  215. package/components/ste-tabs/useData.ts +1 -1
  216. package/components/ste-text/ATTRIBUTES.md +9 -1
  217. package/components/ste-text/README.md +4 -12
  218. package/components/ste-text/ste-text.easycom.json +4 -0
  219. package/components/ste-toast/ATTRIBUTES.md +10 -1
  220. package/components/ste-toast/README.md +9 -18
  221. package/components/ste-toast/ste-toast.easycom.json +14 -0
  222. package/components/ste-touch-swipe/ATTRIBUTES.md +6 -2
  223. package/components/ste-touch-swipe/README.md +4 -6
  224. package/components/ste-touch-swipe/ste-touch-swipe.easycom.json +1 -2
  225. package/components/ste-tour/ATTRIBUTES.md +7 -3
  226. package/components/ste-tour/README.md +5 -7
  227. package/components/ste-tour/ste-tour.easycom.json +11 -4
  228. package/components/ste-tree/ATTRIBUTES.md +15 -2
  229. package/components/ste-tree/README.md +6 -17
  230. package/components/ste-tree/ste-tree.easycom.json +16 -4
  231. package/components/ste-upload/ATTRIBUTES.md +17 -5
  232. package/components/ste-upload/README.md +9 -20
  233. package/components/ste-upload/ste-upload.easycom.json +36 -9
  234. package/components/ste-user-info/ATTRIBUTES.md +15 -5
  235. package/components/ste-user-info/README.md +5 -13
  236. package/components/ste-user-info/ste-user-info.easycom.json +22 -4
  237. package/components/ste-video/ATTRIBUTES.md +3 -1
  238. package/components/ste-video/README.md +4 -8
  239. package/components/ste-watermark/ATTRIBUTES.md +3 -1
  240. package/components/ste-watermark/README.md +5 -7
  241. package/config/font-size.ts +3 -0
  242. package/config/index.ts +5 -0
  243. package/index.ts +4 -0
  244. package/package.json +1 -1
  245. package/types/components.d.ts +4 -0
  246. package/types/refComponents.d.ts +4 -0
  247. package/utils/System.ts +50 -15
  248. package/utils/mixin.ts +4 -3
@@ -0,0 +1,589 @@
1
+ <script setup lang="ts">
2
+ import { computed, getCurrentInstance, onBeforeUnmount, ref, watch, type ComponentPublicInstance, type CSSProperties } from 'vue';
3
+ import { getTouchX, getTouchY, toTouchArray } from '../ste-select-seat/useTouchCompat';
4
+ import utils from '../../utils/utils';
5
+ import propsData, { type SteDragSortItem } from './props';
6
+
7
+ const componentName = 'ste-drag-sort';
8
+
9
+ defineOptions({
10
+ name: componentName,
11
+ options: {
12
+ virtualHost: true,
13
+ },
14
+ });
15
+
16
+ type InternalItem = {
17
+ uid: string;
18
+ raw: SteDragSortItem;
19
+ };
20
+
21
+ type ItemPosition = {
22
+ top: number;
23
+ left: number;
24
+ width: number;
25
+ height: number;
26
+ };
27
+
28
+ type TranslateOffset = {
29
+ x: number;
30
+ y: number;
31
+ };
32
+
33
+ const props = defineProps(propsData);
34
+ const emits = defineEmits<{
35
+ (e: 'update:modelValue', value: SteDragSortItem[]): void;
36
+ (e: 'change', value: SteDragSortItem[]): void;
37
+ (e: 'start', index: number): void;
38
+ (e: 'end', index: number): void;
39
+ }>();
40
+
41
+ const instance = getCurrentInstance() as unknown as ComponentPublicInstance;
42
+
43
+ const list = ref<InternalItem[]>([]);
44
+ const dragging = ref(false);
45
+ const dragIndex = ref(-1);
46
+ const insertIndex = ref(-1);
47
+ const startX = ref(0);
48
+ const startY = ref(0);
49
+ const offsetX = ref(0);
50
+ const offsetY = ref(0);
51
+ const itemPositions = ref<ItemPosition[]>([]);
52
+ const itemWidth = ref(0);
53
+ const itemHeight = ref(0);
54
+ const sortingStarted = ref(false);
55
+
56
+ let mouseLongPressTimer: ReturnType<typeof setTimeout> | null = null;
57
+ let mousePressing = false;
58
+ let mousePendingIndex = -1;
59
+ let mousePendingX = 0;
60
+ let mousePendingY = 0;
61
+ let dragSessionId = 0;
62
+
63
+ const columns = computed(() => {
64
+ const value = Math.floor(Number(props.columns) || 1);
65
+ return value > 0 ? value : 1;
66
+ });
67
+
68
+ const rootClass = computed(() => {
69
+ return {
70
+ 'ste-drag-sort-columns': columns.value > 1,
71
+ };
72
+ });
73
+
74
+ function getUidPools(items: InternalItem[]) {
75
+ const pools = new Map<SteDragSortItem, string[]>();
76
+
77
+ items.forEach(item => {
78
+ const pool = pools.get(item.raw) || [];
79
+ pool.push(item.uid);
80
+ pools.set(item.raw, pool);
81
+ });
82
+
83
+ return pools;
84
+ }
85
+
86
+ function syncList(value: SteDragSortItem[]) {
87
+ const pools = getUidPools(list.value);
88
+
89
+ list.value = (value || []).map(item => {
90
+ const pool = pools.get(item);
91
+ const uid = pool?.shift() || utils.guid(12);
92
+ return { uid, raw: item };
93
+ });
94
+ }
95
+
96
+ function resetDragState() {
97
+ dragSessionId += 1;
98
+ dragging.value = false;
99
+ dragIndex.value = -1;
100
+ insertIndex.value = -1;
101
+ startX.value = 0;
102
+ startY.value = 0;
103
+ offsetX.value = 0;
104
+ offsetY.value = 0;
105
+ itemPositions.value = [];
106
+ itemWidth.value = 0;
107
+ itemHeight.value = 0;
108
+ sortingStarted.value = false;
109
+ }
110
+
111
+ function clearMouseLongPress() {
112
+ if (mouseLongPressTimer) {
113
+ clearTimeout(mouseLongPressTimer);
114
+ mouseLongPressTimer = null;
115
+ }
116
+ mousePressing = false;
117
+ mousePendingIndex = -1;
118
+ mousePendingX = 0;
119
+ mousePendingY = 0;
120
+ }
121
+
122
+ function removeMouseListeners() {
123
+ if (typeof window === 'undefined') return;
124
+ window.removeEventListener('mousemove', onMouseMove);
125
+ window.removeEventListener('mouseup', onMouseUp);
126
+ }
127
+
128
+ function getItemDisabled(index: number) {
129
+ return !!list.value[index]?.raw?.disabled;
130
+ }
131
+
132
+ function getEnabledIndices() {
133
+ return list.value.reduce<number[]>((indices, item, index) => {
134
+ if (!item.raw?.disabled) {
135
+ indices.push(index);
136
+ }
137
+ return indices;
138
+ }, []);
139
+ }
140
+
141
+ function getReorderPreview(dragIdx: number, targetIdx: number) {
142
+ const enabledIndices = getEnabledIndices();
143
+ const dragEnabledIndex = enabledIndices.indexOf(dragIdx);
144
+ const targetEnabledIndex = enabledIndices.indexOf(targetIdx);
145
+
146
+ if (dragEnabledIndex < 0 || targetEnabledIndex < 0) return null;
147
+
148
+ const nextEnabledSourceIndices = [...enabledIndices];
149
+ const [draggedSourceIndex] = nextEnabledSourceIndices.splice(dragEnabledIndex, 1);
150
+ nextEnabledSourceIndices.splice(targetEnabledIndex, 0, draggedSourceIndex);
151
+
152
+ const finalIndexMap = new Map<number, number>();
153
+ list.value.forEach((_, index) => finalIndexMap.set(index, index));
154
+ enabledIndices.forEach((slotIndex, orderIndex) => {
155
+ finalIndexMap.set(nextEnabledSourceIndices[orderIndex], slotIndex);
156
+ });
157
+
158
+ return {
159
+ enabledIndices,
160
+ nextEnabledSourceIndices,
161
+ finalIndexMap,
162
+ };
163
+ }
164
+
165
+ function getFirstTouch(event: TouchEvent) {
166
+ return toTouchArray(event.touches)[0] || toTouchArray(event.changedTouches)[0];
167
+ }
168
+
169
+ async function measureItemPositions() {
170
+ const rootRect = await utils.querySelector<false>('.ste-drag-sort-root', instance);
171
+ const rects = await utils.querySelector('.ste-drag-sort-item', instance, true);
172
+ const items = Array.isArray(rects) ? rects : [];
173
+
174
+ itemWidth.value = columns.value > 1 ? (rootRect?.width || 0) / columns.value : items[0]?.width || 0;
175
+ itemHeight.value = items[0]?.height || 0;
176
+ itemPositions.value = items.map(rect => ({
177
+ top: rect.top || 0,
178
+ left: rect.left || 0,
179
+ width: rect.width || itemWidth.value,
180
+ height: rect.height || itemHeight.value,
181
+ }));
182
+ }
183
+
184
+ function calculateGridInsertIndex(centerX: number, centerY: number) {
185
+ if (!itemPositions.value.length) return dragIndex.value;
186
+
187
+ let closestIndex = dragIndex.value;
188
+ let minDistance = Infinity;
189
+
190
+ itemPositions.value.forEach((position, index) => {
191
+ if (getItemDisabled(index)) return;
192
+
193
+ const itemCenterX = position.left + position.width / 2;
194
+ const itemCenterY = position.top + position.height / 2;
195
+ const distance = Math.sqrt(Math.pow(centerX - itemCenterX, 2) + Math.pow(centerY - itemCenterY, 2));
196
+
197
+ if (distance < minDistance) {
198
+ minDistance = distance;
199
+ closestIndex = index;
200
+ }
201
+ });
202
+
203
+ return closestIndex;
204
+ }
205
+
206
+ function calculateSingleColumnInsertIndex(centerY: number) {
207
+ let closestIndex = dragIndex.value;
208
+ let minDistance = Infinity;
209
+
210
+ itemPositions.value.forEach((position, index) => {
211
+ if (getItemDisabled(index)) return;
212
+
213
+ const itemCenterY = position.top + position.height / 2;
214
+ const distance = Math.abs(centerY - itemCenterY);
215
+
216
+ if (distance < minDistance) {
217
+ minDistance = distance;
218
+ closestIndex = index;
219
+ }
220
+ });
221
+
222
+ return closestIndex;
223
+ }
224
+
225
+ function calculateInsertIndex() {
226
+ if (!itemPositions.value.length || dragIndex.value < 0) return dragIndex.value;
227
+
228
+ const dragPosition = itemPositions.value[dragIndex.value];
229
+ const centerX = dragPosition.left + dragPosition.width / 2 + offsetX.value;
230
+ const centerY = dragPosition.top + dragPosition.height / 2 + offsetY.value;
231
+
232
+ if (columns.value > 1) {
233
+ return calculateGridInsertIndex(centerX, centerY);
234
+ }
235
+
236
+ return calculateSingleColumnInsertIndex(centerY);
237
+ }
238
+
239
+ function getItemTranslateOffset(index: number): TranslateOffset {
240
+ if (!dragging.value || !sortingStarted.value) return { x: 0, y: 0 };
241
+ if (getItemDisabled(index)) return { x: 0, y: 0 };
242
+ if (index === dragIndex.value || dragIndex.value === insertIndex.value) return { x: 0, y: 0 };
243
+
244
+ const reorderPreview = getReorderPreview(dragIndex.value, insertIndex.value);
245
+ const nextIndex = reorderPreview?.finalIndexMap.get(index);
246
+
247
+ if (typeof nextIndex !== 'number' || nextIndex === index) return { x: 0, y: 0 };
248
+
249
+ if (columns.value > 1) {
250
+ const cols = columns.value;
251
+ const currentRow = Math.floor(index / cols);
252
+ const currentCol = index % cols;
253
+ const nextRow = Math.floor(nextIndex / cols);
254
+ const nextCol = nextIndex % cols;
255
+
256
+ return {
257
+ x: (nextCol - currentCol) * itemWidth.value,
258
+ y: (nextRow - currentRow) * itemHeight.value,
259
+ };
260
+ }
261
+
262
+ return {
263
+ x: 0,
264
+ y: (nextIndex - index) * itemHeight.value,
265
+ };
266
+ }
267
+
268
+ function getItemStyle(index: number): CSSProperties {
269
+ const style: CSSProperties = {};
270
+
271
+ if (columns.value > 1) {
272
+ const width = `${100 / columns.value}%`;
273
+ style.flexBasis = width;
274
+ style.width = width;
275
+ style.boxSizing = 'border-box';
276
+ }
277
+
278
+ if (!dragging.value) return style;
279
+
280
+ if (index === dragIndex.value) {
281
+ const dragScale = sortingStarted.value ? 1.03 : 1.02;
282
+ style.transform = `translate(${offsetX.value}px, ${offsetY.value}px) scale(${dragScale})`;
283
+ style.zIndex = 100;
284
+ return style;
285
+ }
286
+
287
+ const offset = getItemTranslateOffset(index);
288
+ if (offset.x || offset.y) {
289
+ style.transform = `translate(${offset.x}px, ${offset.y}px)`;
290
+ }
291
+
292
+ return style;
293
+ }
294
+
295
+ function getItemClass(index: number) {
296
+ return {
297
+ 'ste-drag-sort-item-disabled': props.disabled || !!list.value[index]?.raw?.disabled,
298
+ 'ste-drag-sort-item-ready': dragging.value && dragIndex.value === index && !sortingStarted.value,
299
+ 'ste-drag-sort-item-dragging': dragging.value && dragIndex.value === index,
300
+ 'ste-drag-sort-item-animating': dragging.value && dragIndex.value !== index,
301
+ };
302
+ }
303
+
304
+ function triggerReadyHaptic() {
305
+ if (!props.longPress) return;
306
+
307
+ try {
308
+ if (typeof uni === 'undefined' || typeof uni.vibrateShort !== 'function') return;
309
+ uni.vibrateShort({
310
+ type: 'light',
311
+ fail: () => {},
312
+ });
313
+ } catch {
314
+ // Ignore unsupported platforms so drag flow can proceed.
315
+ }
316
+ }
317
+
318
+ function checkMovedToOtherElement() {
319
+ if (!itemPositions.value.length || dragIndex.value < 0) return false;
320
+
321
+ const dragPosition = itemPositions.value[dragIndex.value];
322
+ const centerX = dragPosition.left + dragPosition.width / 2 + offsetX.value;
323
+ const centerY = dragPosition.top + dragPosition.height / 2 + offsetY.value;
324
+
325
+ if (columns.value > 1) {
326
+ return itemPositions.value.some((position, index) => {
327
+ if (index === dragIndex.value) return false;
328
+
329
+ return centerX >= position.left && centerX <= position.left + position.width && centerY >= position.top && centerY <= position.top + position.height;
330
+ });
331
+ }
332
+
333
+ if (dragIndex.value > 0) {
334
+ const prev = itemPositions.value[dragIndex.value - 1];
335
+ if (centerY <= prev.top + prev.height / 2) return true;
336
+ }
337
+
338
+ if (dragIndex.value < itemPositions.value.length - 1) {
339
+ const next = itemPositions.value[dragIndex.value + 1];
340
+ if (centerY >= next.top + next.height / 2) return true;
341
+ }
342
+
343
+ return false;
344
+ }
345
+
346
+ async function startDrag(index: number, clientX: number, clientY: number) {
347
+ if (props.disabled) return false;
348
+ if (dragging.value) return false;
349
+ if (index < 0 || index >= list.value.length) return false;
350
+ if (getItemDisabled(index)) return false;
351
+
352
+ const sessionId = ++dragSessionId;
353
+ dragging.value = true;
354
+ dragIndex.value = index;
355
+ insertIndex.value = index;
356
+ startX.value = clientX;
357
+ startY.value = clientY;
358
+ offsetX.value = 0;
359
+ offsetY.value = 0;
360
+ sortingStarted.value = false;
361
+
362
+ triggerReadyHaptic();
363
+ emits('start', index);
364
+ await measureItemPositions();
365
+
366
+ return dragging.value && dragSessionId === sessionId && dragIndex.value === index;
367
+ }
368
+
369
+ function moveDrag(clientX: number, clientY: number) {
370
+ if (!dragging.value) return;
371
+
372
+ offsetX.value = clientX - startX.value;
373
+ offsetY.value = clientY - startY.value;
374
+
375
+ if (!sortingStarted.value && checkMovedToOtherElement()) {
376
+ sortingStarted.value = true;
377
+ }
378
+
379
+ if (sortingStarted.value) {
380
+ insertIndex.value = calculateInsertIndex();
381
+ }
382
+ }
383
+
384
+ function finishDrag() {
385
+ if (!dragging.value) return;
386
+
387
+ const oldIndex = dragIndex.value;
388
+ const reorderPreview = getReorderPreview(oldIndex, insertIndex.value >= 0 ? insertIndex.value : oldIndex);
389
+ const newIndex = reorderPreview?.finalIndexMap.get(oldIndex) ?? oldIndex;
390
+
391
+ if (oldIndex !== newIndex && oldIndex >= 0) {
392
+ const nextList = Array.from({ length: list.value.length }) as InternalItem[];
393
+
394
+ list.value.forEach((item, index) => {
395
+ if (getItemDisabled(index)) {
396
+ nextList[index] = item;
397
+ }
398
+ });
399
+
400
+ reorderPreview?.enabledIndices.forEach((slotIndex, orderIndex) => {
401
+ nextList[slotIndex] = list.value[reorderPreview.nextEnabledSourceIndices[orderIndex]];
402
+ });
403
+
404
+ list.value = nextList;
405
+
406
+ const result = nextList.map(item => item.raw);
407
+ emits('update:modelValue', result);
408
+ emits('change', result);
409
+ }
410
+
411
+ resetDragState();
412
+ emits('end', newIndex);
413
+ }
414
+
415
+ async function onTouchStart(event: TouchEvent, index: number, type: 'touch' | 'longpress') {
416
+ if (type === 'longpress' && !props.longPress) return;
417
+ if (type === 'touch' && props.longPress) return;
418
+
419
+ const touch = getFirstTouch(event);
420
+ if (!touch) return;
421
+
422
+ const started = await startDrag(index, getTouchX(touch), getTouchY(touch));
423
+ if (!started) return;
424
+
425
+ event.stopPropagation();
426
+ event.preventDefault();
427
+ }
428
+
429
+ function onTouchMove(event: TouchEvent) {
430
+ if (!dragging.value) return;
431
+
432
+ const touch = getFirstTouch(event);
433
+ if (!touch) return;
434
+
435
+ moveDrag(getTouchX(touch), getTouchY(touch));
436
+ event.preventDefault();
437
+ }
438
+
439
+ function onTouchEnd() {
440
+ finishDrag();
441
+ }
442
+
443
+ function mouseDown(event: MouseEvent, index: number) {
444
+ if (typeof window === 'undefined') return;
445
+ if (props.disabled || getItemDisabled(index)) return;
446
+
447
+ mousePressing = true;
448
+ mousePendingIndex = index;
449
+ mousePendingX = event.clientX;
450
+ mousePendingY = event.clientY;
451
+
452
+ window.addEventListener('mousemove', onMouseMove);
453
+ window.addEventListener('mouseup', onMouseUp);
454
+
455
+ if (!props.longPress) {
456
+ startDrag(index, event.clientX, event.clientY);
457
+ return;
458
+ }
459
+
460
+ mouseLongPressTimer = setTimeout(() => {
461
+ if (!mousePressing || mousePendingIndex < 0) return;
462
+ startDrag(mousePendingIndex, mousePendingX, mousePendingY);
463
+ }, 350);
464
+ }
465
+
466
+ function onMouseMove(event: MouseEvent) {
467
+ if (dragging.value) {
468
+ moveDrag(event.clientX, event.clientY);
469
+ event.preventDefault();
470
+ return;
471
+ }
472
+
473
+ if (!mousePressing || !mouseLongPressTimer) return;
474
+
475
+ const deltaX = Math.abs(event.clientX - mousePendingX);
476
+ const deltaY = Math.abs(event.clientY - mousePendingY);
477
+
478
+ if (deltaX > 5 || deltaY > 5) {
479
+ clearMouseLongPress();
480
+ removeMouseListeners();
481
+ }
482
+ }
483
+
484
+ function onMouseUp() {
485
+ if (dragging.value) {
486
+ finishDrag();
487
+ }
488
+
489
+ clearMouseLongPress();
490
+ removeMouseListeners();
491
+ }
492
+
493
+ watch(
494
+ () => props.modelValue,
495
+ value => {
496
+ syncList(value || []);
497
+ },
498
+ {
499
+ immediate: true,
500
+ deep: true,
501
+ }
502
+ );
503
+
504
+ onBeforeUnmount(() => {
505
+ clearMouseLongPress();
506
+ removeMouseListeners();
507
+ });
508
+ </script>
509
+
510
+ <template>
511
+ <view class="ste-drag-sort-root" :class="[rootClass, { 'ste-drag-sort-root-dragging': dragging }]" data-test="drag-sort">
512
+ <template v-if="dragging">
513
+ <view
514
+ v-for="(current, index) in list"
515
+ :key="current.uid"
516
+ class="ste-drag-sort-item"
517
+ :class="getItemClass(index)"
518
+ :style="getItemStyle(index)"
519
+ @touchstart="(event: TouchEvent) => onTouchStart(event, index, 'touch')"
520
+ @longpress="(event: TouchEvent) => onTouchStart(event, index, 'longpress')"
521
+ @touchmove.stop.prevent="onTouchMove"
522
+ @touchend="onTouchEnd"
523
+ @touchcancel="onTouchEnd"
524
+ @mousedown.prevent="mouseDown($event, index)"
525
+ >
526
+ <slot name="item" :item="current.raw" :index="index" :dragging="dragging" :dragIndex="dragIndex" :insertIndex="insertIndex"></slot>
527
+ </view>
528
+ </template>
529
+ <template v-else>
530
+ <view
531
+ v-for="(current, index) in list"
532
+ :key="current.uid"
533
+ class="ste-drag-sort-item"
534
+ :class="getItemClass(index)"
535
+ :style="getItemStyle(index)"
536
+ @touchstart="(event: TouchEvent) => onTouchStart(event, index, 'touch')"
537
+ @longpress="(event: TouchEvent) => onTouchStart(event, index, 'longpress')"
538
+ @touchmove="onTouchMove"
539
+ @touchend="onTouchEnd"
540
+ @touchcancel="onTouchEnd"
541
+ @mousedown.prevent="mouseDown($event, index)"
542
+ >
543
+ <slot name="item" :item="current.raw" :index="index" :dragging="dragging" :dragIndex="dragIndex" :insertIndex="insertIndex"></slot>
544
+ </view>
545
+ </template>
546
+ </view>
547
+ </template>
548
+
549
+ <style lang="scss" scoped>
550
+ .ste-drag-sort-root {
551
+ position: relative;
552
+ display: flex;
553
+ flex-direction: column;
554
+ overflow: visible;
555
+ user-select: none;
556
+
557
+ &.ste-drag-sort-columns {
558
+ flex-direction: row;
559
+ flex-wrap: wrap;
560
+ }
561
+
562
+ &.ste-drag-sort-root-dragging {
563
+ touch-action: none;
564
+ }
565
+ }
566
+
567
+ .ste-drag-sort-item {
568
+ position: relative;
569
+ z-index: 10;
570
+ transition: opacity 0.12s ease;
571
+
572
+ &.ste-drag-sort-item-dragging {
573
+ opacity: 0.95;
574
+ z-index: 20;
575
+ }
576
+
577
+ &.ste-drag-sort-item-ready {
578
+ opacity: 0.98;
579
+ }
580
+
581
+ &.ste-drag-sort-item-disabled {
582
+ opacity: 0.6;
583
+ }
584
+
585
+ &.ste-drag-sort-item-animating {
586
+ transition: transform 0.2s ease;
587
+ }
588
+ }
589
+ </style>
@@ -1,4 +1,6 @@
1
- #### Props
1
+ ## API
2
+
3
+ ### Props
2
4
  | 属性名 | 说明 | 类型 | 默认值 | 可选值 | 支持版本 |
3
5
  | ----- | ----- | --- | ------- | ------ | -------- |
4
6
  | `title` | 菜单标题,未设置时会显示选中项的值 | `string` | - | - | - |
@@ -15,9 +17,11 @@
15
17
  | `showPopup` | 是否显示菜单弹窗 | `boolean` | `false` | - | `1.21.0` |
16
18
 
17
19
 
18
- #### Events
20
+ ### Events
19
21
  | 事件名 | 说明 | 事件参数 | 支持版本 |
20
22
  | ----- | ----- | ------- | -------- |
21
23
  | `change` | 选项改变时触发 | `value`:选中的值 | - |
22
- | `open` | 菜单打开 | - | - |
23
- | `close` | 菜单收起 | - | - |
24
+ | `open` | 菜单打开 | `data`:() => void | - |
25
+ | `close` | 菜单收起 | `data`:() => void | - |
26
+
27
+