vite-uni-dev-tool 1.1.0 → 1.2.1

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 (195) hide show
  1. package/README.md +21 -1
  2. package/dist/const.cjs +1 -1
  3. package/dist/const.d.ts +2 -1
  4. package/dist/const.js +1 -1
  5. package/dist/core-shared.d.ts +2 -3
  6. package/dist/core.d.ts +8 -8
  7. package/dist/core.js +2 -2
  8. package/dist/i18n/index.d.ts +0 -1
  9. package/dist/i18n/instance.d.ts +0 -1
  10. package/dist/i18n/locales/en.cjs +1 -1
  11. package/dist/i18n/locales/en.d.ts +6 -1
  12. package/dist/i18n/locales/en.js +1 -1
  13. package/dist/i18n/locales/zh-Hans.cjs +1 -1
  14. package/dist/i18n/locales/zh-Hans.d.ts +6 -1
  15. package/dist/i18n/locales/zh-Hans.js +1 -1
  16. package/dist/index.d.ts +0 -1
  17. package/dist/modules/devConsole/index.cjs +4 -4
  18. package/dist/modules/devConsole/index.d.ts +6 -107
  19. package/dist/modules/devConsole/index.js +4 -4
  20. package/dist/modules/devEvent/index.cjs +3 -3
  21. package/dist/modules/devEvent/index.d.ts +2 -3
  22. package/dist/modules/devEvent/index.js +3 -3
  23. package/dist/modules/devIntercept/index.cjs +14 -14
  24. package/dist/modules/devIntercept/index.d.ts +34 -6
  25. package/dist/modules/devIntercept/index.js +14 -14
  26. package/dist/modules/devStore/index.cjs +1 -1
  27. package/dist/modules/devStore/index.d.ts +48 -40
  28. package/dist/modules/devStore/index.js +1 -1
  29. package/dist/modules/devToolInfo/index.cjs +1 -1
  30. package/dist/modules/devToolInfo/index.d.ts +6 -25
  31. package/dist/modules/devToolInfo/index.js +1 -1
  32. package/dist/plugins/uniDevTool/transform/transformApp.d.ts +0 -1
  33. package/dist/plugins/uniDevTool/transform/transformMain.cjs +3 -3
  34. package/dist/plugins/uniDevTool/transform/transformMain.d.ts +2 -2
  35. package/dist/plugins/uniDevTool/transform/transformMain.js +3 -3
  36. package/dist/plugins/uniDevTool/transform/transformVue.cjs +31 -25
  37. package/dist/plugins/uniDevTool/transform/transformVue.d.ts +2 -2
  38. package/dist/plugins/uniDevTool/transform/transformVue.js +30 -24
  39. package/dist/plugins/uniDevTool/uniDevTool.cjs +3 -3
  40. package/dist/plugins/uniDevTool/uniDevTool.d.ts +3 -2
  41. package/dist/plugins/uniDevTool/uniDevTool.js +3 -3
  42. package/dist/plugins/uniGlobalComponents/uniGlobalComponents.d.ts +0 -1
  43. package/dist/plugins/utils/index.d.ts +0 -1
  44. package/dist/shims-uni.d.ts +26 -22
  45. package/dist/type.d.ts +47 -43
  46. package/dist/utils/array.d.ts +0 -1
  47. package/dist/utils/date.d.ts +0 -1
  48. package/dist/utils/file.d.ts +0 -1
  49. package/dist/utils/function.d.ts +0 -1
  50. package/dist/utils/index.d.ts +0 -1
  51. package/dist/utils/ip.d.ts +0 -1
  52. package/dist/utils/language.d.ts +14 -15
  53. package/dist/utils/object.cjs +1 -1
  54. package/dist/utils/object.d.ts +7 -8
  55. package/dist/utils/object.js +1 -1
  56. package/dist/utils/openLink.d.ts +0 -1
  57. package/dist/utils/page.d.ts +0 -1
  58. package/dist/utils/platform.d.ts +0 -1
  59. package/dist/utils/string.d.ts +0 -1
  60. package/dist/utils/utils.d.ts +0 -1
  61. package/dist/v3/DevTool/components/BluetoothList/BluetoothItem.vue +199 -199
  62. package/dist/v3/DevTool/components/BluetoothList/BluetoothTool.vue +730 -730
  63. package/dist/v3/DevTool/components/BluetoothList/index.vue +167 -167
  64. package/dist/v3/DevTool/components/CaptureScreen/index.vue +109 -109
  65. package/dist/v3/DevTool/components/ConsoleList/ConsoleItem.vue +230 -225
  66. package/dist/v3/DevTool/components/ConsoleList/RunJSInput.vue +247 -247
  67. package/dist/v3/DevTool/components/ConsoleList/index.vue +171 -171
  68. package/dist/v3/DevTool/components/ConsoleList/staticTips.ts +1145 -1145
  69. package/dist/v3/DevTool/components/DevToolButton/index.vue +42 -6
  70. package/dist/v3/DevTool/components/DevToolTitle/index.vue +24 -24
  71. package/dist/v3/DevTool/components/DevToolWindow/DevToolOverlay.vue +197 -197
  72. package/dist/v3/DevTool/components/DevToolWindow/hooks/dataUtils.ts +48 -48
  73. package/dist/v3/DevTool/components/DevToolWindow/hooks/useDevToolData.ts +411 -387
  74. package/dist/v3/DevTool/components/DevToolWindow/hooks/useDevToolHandlers.ts +644 -629
  75. package/dist/v3/DevTool/components/DevToolWindow/hooks/useDevToolOverlay.ts +201 -197
  76. package/dist/v3/DevTool/components/DevToolWindow/index.vue +27 -64
  77. package/dist/v3/DevTool/components/ElEvent/ElEventItem.vue +105 -105
  78. package/dist/v3/DevTool/components/ElEvent/index.vue +106 -106
  79. package/dist/v3/DevTool/components/Instance/components/InstanceTreeNode.vue +265 -265
  80. package/dist/v3/DevTool/components/Instance/flatten.ts +226 -226
  81. package/dist/v3/DevTool/components/Instance/index.vue +94 -94
  82. package/dist/v3/DevTool/components/Instance/registry.ts +49 -49
  83. package/dist/v3/DevTool/components/Instance/transformTree.ts +393 -375
  84. package/dist/v3/DevTool/components/Instance/transformTreeCtx.ts +268 -268
  85. package/dist/v3/DevTool/components/Instance/typing.d.ts +43 -43
  86. package/dist/v3/DevTool/components/InstanceDetail/index.vue +485 -485
  87. package/dist/v3/DevTool/components/JsonDetail/index.vue +70 -70
  88. package/dist/v3/DevTool/components/NFCList/NFCItem.vue +112 -112
  89. package/dist/v3/DevTool/components/NFCList/NFCTool.vue +454 -454
  90. package/dist/v3/DevTool/components/NFCList/const.ts +56 -56
  91. package/dist/v3/DevTool/components/NFCList/index.vue +94 -94
  92. package/dist/v3/DevTool/components/NetworkList/InterceptConfig.vue +624 -624
  93. package/dist/v3/DevTool/components/NetworkList/InterceptItem.vue +140 -140
  94. package/dist/v3/DevTool/components/NetworkList/NetworkDetail.vue +287 -287
  95. package/dist/v3/DevTool/components/NetworkList/NetworkIntercept.vue +88 -88
  96. package/dist/v3/DevTool/components/NetworkList/NetworkItem.vue +163 -163
  97. package/dist/v3/DevTool/components/NetworkList/NetworkSend.vue +589 -589
  98. package/dist/v3/DevTool/components/NetworkList/const.ts +4 -4
  99. package/dist/v3/DevTool/components/NetworkList/hooks/useNetworkForm.ts +86 -86
  100. package/dist/v3/DevTool/components/NetworkList/index.vue +160 -160
  101. package/dist/v3/DevTool/components/NetworkList/utils.ts +101 -101
  102. package/dist/v3/DevTool/components/Performance/index.vue +498 -498
  103. package/dist/v3/DevTool/components/Performance/modules/PerformanceMetrics.vue +153 -153
  104. package/dist/v3/DevTool/components/Performance/modules/usePerformanceChart.ts +460 -460
  105. package/dist/v3/DevTool/components/Performance/modules/usePerformanceData.ts +258 -258
  106. package/dist/v3/DevTool/components/PiniaList/index.vue +93 -93
  107. package/dist/v3/DevTool/components/RunJS/index.vue +148 -148
  108. package/dist/v3/DevTool/components/ScanCodeList/ScanCodeItem.vue +97 -97
  109. package/dist/v3/DevTool/components/ScanCodeList/index.vue +100 -100
  110. package/dist/v3/DevTool/components/SettingButton/index.vue +45 -45
  111. package/dist/v3/DevTool/components/SettingList/index.vue +226 -218
  112. package/dist/v3/DevTool/components/SettingList/modules/SettingBarrage.vue +320 -304
  113. package/dist/v3/DevTool/components/SettingList/modules/SettingDevTool.vue +212 -212
  114. package/dist/v3/DevTool/components/SettingList/modules/SettingInfo.vue +157 -157
  115. package/dist/v3/DevTool/components/SettingList/modules/SettingLanguage.vue +74 -74
  116. package/dist/v3/DevTool/components/SettingList/modules/SettingLog.vue +230 -230
  117. package/dist/v3/DevTool/components/SettingList/typing.d.ts +2 -2
  118. package/dist/v3/DevTool/components/SourceCode/Line.vue +127 -127
  119. package/dist/v3/DevTool/components/SourceCode/parseCode.ts +609 -609
  120. package/dist/v3/DevTool/components/StorageList/index.vue +174 -174
  121. package/dist/v3/DevTool/components/TransferList/TransferDetail.vue +268 -268
  122. package/dist/v3/DevTool/components/VuexList/index.vue +84 -84
  123. package/dist/v3/DevTool/index.vue +85 -138
  124. package/dist/v3/components/AppTransition/index.vue +156 -176
  125. package/dist/v3/components/AutoSizer/index.vue +192 -192
  126. package/dist/v3/components/AutoSizer/index1.vue +184 -184
  127. package/dist/v3/components/AutoSizer/utils.ts +49 -49
  128. package/dist/v3/components/Barrage/BarrageItem.vue +194 -137
  129. package/dist/v3/components/Barrage/index.vue +205 -202
  130. package/dist/v3/components/CircularButton/index.vue +84 -84
  131. package/dist/v3/components/CustomSwiper/CustomSwiperItem.vue +49 -49
  132. package/dist/v3/components/CustomSwiper/index.vue +104 -104
  133. package/dist/v3/components/DevErrorBoundary/index.vue +388 -0
  134. package/dist/v3/components/DraggableContainer/index.vue +186 -73
  135. package/dist/v3/components/Empty/index.vue +29 -29
  136. package/dist/v3/components/FilterSelect/index.vue +179 -179
  137. package/dist/v3/components/JsonPretty/components/Brackets/index.vue +27 -27
  138. package/dist/v3/components/JsonPretty/components/Carets/index.vue +59 -59
  139. package/dist/v3/components/JsonPretty/components/CheckController/index.vue +136 -136
  140. package/dist/v3/components/JsonPretty/components/TreeNode/index.vue +387 -387
  141. package/dist/v3/components/JsonPretty/hooks/useClipboard.ts +21 -21
  142. package/dist/v3/components/JsonPretty/hooks/useError.ts +21 -21
  143. package/dist/v3/components/JsonPretty/type.ts +127 -127
  144. package/dist/v3/components/JsonPretty/utils/index.ts +169 -169
  145. package/dist/v3/components/MovableContainer/index.vue +10 -4
  146. package/dist/v3/components/Pick/index.vue +321 -322
  147. package/dist/v3/components/Tag/index.vue +113 -113
  148. package/dist/v3/components/VirtualList/AutoSize.vue +40 -40
  149. package/dist/v3/components/VirtualList/index.vue +416 -416
  150. package/dist/v3/hooks/useBluetooth/index.ts +561 -561
  151. package/dist/v3/hooks/useContainerStyle.ts +95 -153
  152. package/dist/v3/hooks/useNFC/index.ts +107 -107
  153. package/dist/v3/hooks/useNFC/typing.d.ts +396 -396
  154. package/dist/v3/hooks/useNFC/useNFCAndroid.ts +966 -966
  155. package/dist/v3/hooks/useNFC/useNFCMpWeiXin.ts +812 -812
  156. package/dist/v3/hooks/useNFC/utils.ts +754 -754
  157. package/dist/v3/hooks/useRequest/index.ts +586 -586
  158. package/dist/v3/hooks/useRequest/utils.ts +267 -267
  159. package/dist/v3/hooks/useScanCode/index.ts +206 -206
  160. package/dist/v3/hooks/useWebsocket/index.ts +253 -253
  161. package/dist/v3/styles/theme.ts +12 -12
  162. package/package.json +70 -59
  163. package/dist/const.d.ts.map +0 -1
  164. package/dist/core-shared.d.ts.map +0 -1
  165. package/dist/core.d.ts.map +0 -1
  166. package/dist/i18n/index.d.ts.map +0 -1
  167. package/dist/i18n/instance.d.ts.map +0 -1
  168. package/dist/i18n/locales/en.d.ts.map +0 -1
  169. package/dist/i18n/locales/zh-Hans.d.ts.map +0 -1
  170. package/dist/index.d.ts.map +0 -1
  171. package/dist/modules/devConsole/index.d.ts.map +0 -1
  172. package/dist/modules/devEvent/index.d.ts.map +0 -1
  173. package/dist/modules/devIntercept/index.d.ts.map +0 -1
  174. package/dist/modules/devStore/index.d.ts.map +0 -1
  175. package/dist/modules/devToolInfo/index.d.ts.map +0 -1
  176. package/dist/plugins/uniDevTool/transform/transformApp.d.ts.map +0 -1
  177. package/dist/plugins/uniDevTool/transform/transformMain.d.ts.map +0 -1
  178. package/dist/plugins/uniDevTool/transform/transformVue.d.ts.map +0 -1
  179. package/dist/plugins/uniDevTool/uniDevTool.d.ts.map +0 -1
  180. package/dist/plugins/uniGlobalComponents/uniGlobalComponents.d.ts.map +0 -1
  181. package/dist/plugins/utils/index.d.ts.map +0 -1
  182. package/dist/type.d.ts.map +0 -1
  183. package/dist/utils/array.d.ts.map +0 -1
  184. package/dist/utils/date.d.ts.map +0 -1
  185. package/dist/utils/file.d.ts.map +0 -1
  186. package/dist/utils/function.d.ts.map +0 -1
  187. package/dist/utils/index.d.ts.map +0 -1
  188. package/dist/utils/ip.d.ts.map +0 -1
  189. package/dist/utils/language.d.ts.map +0 -1
  190. package/dist/utils/object.d.ts.map +0 -1
  191. package/dist/utils/openLink.d.ts.map +0 -1
  192. package/dist/utils/page.d.ts.map +0 -1
  193. package/dist/utils/platform.d.ts.map +0 -1
  194. package/dist/utils/string.d.ts.map +0 -1
  195. package/dist/utils/utils.d.ts.map +0 -1
@@ -1,322 +1,321 @@
1
- <template>
2
- <view class="pick-wrapper" :style="customStyle">
3
- <!-- Trigger Area -->
4
- <view
5
- :class="`pick-trigger ${!modelValue ? 'pick-trigger-placeholder' : ''}`"
6
- @click="onOpenPick">
7
- <text class="pick-trigger-text">
8
- {{ label || placeholder || '请选择' }}
9
- </text>
10
- <view class="pick-handle">
11
- <view
12
- v-if="allowClear && modelValue"
13
- class="pick-clear"
14
- @click.stop="onClear">
15
- ×
16
- </view>
17
- <view :class="['pick-arrow', isActive ? 'pick-arrow-active' : '']">
18
- >
19
- </view>
20
- </view>
21
- </view>
22
-
23
- <!-- Popup Modal -->
24
- <view class="pick-mask" v-if="isActive" @click="onClosePick">
25
- <view class="pick-modal" @click.stop>
26
- <!-- Header -->
27
- <view class="pick-header">
28
- <text class="pick-title">{{ placeholder || '请选择' }}</text>
29
- <view class="pick-close" @click="onClosePick">×</view>
30
- </view>
31
-
32
- <!-- Search -->
33
- <view class="pick-search" v-if="!readonly">
34
- <input
35
- class="pick-search-input"
36
- :value="searchText"
37
- placeholder="搜索..."
38
- @input="debounceInput"
39
- :focus="isActive" />
40
- </view>
41
-
42
- <!-- List -->
43
- <scroll-view scroll-y class="pick-list">
44
- <view
45
- v-for="item in filteredOptions"
46
- :key="item.value"
47
- :class="[
48
- 'pick-item',
49
- item.value === modelValue ? 'pick-item-active' : '',
50
- ]"
51
- @click="onSelect(item)">
52
- <text class="pick-item-text">{{ item.label }}</text>
53
- <text v-if="item.value === modelValue" class="pick-item-check">
54
-
55
- </text>
56
- </view>
57
- <view v-if="filteredOptions.length === 0" class="pick-empty">
58
- 暂无数据
59
- </view>
60
- </scroll-view>
61
- </view>
62
- </view>
63
- </view>
64
- </template>
65
-
66
- <script lang="ts" setup>
67
- import { debounce } from '../../../utils';
68
- import { ref, computed } from 'vue';
69
-
70
- const props = defineProps<{
71
- placeholder?: string;
72
- readonly?: boolean;
73
- allowClear?: boolean;
74
- options?: { label: string; value: any }[];
75
- customStyle?: Record<string, any> | string;
76
- }>();
77
-
78
- const modelValue = defineModel<string>('modelValue');
79
-
80
- const emit = defineEmits<{
81
- (e: 'search', value: string): void;
82
- (e: 'openSearch', value: boolean): void;
83
- (e: 'change', value: { label: string; value: any }): void;
84
- }>();
85
-
86
- const isActive = ref(false);
87
- const searchText = ref('');
88
-
89
- // Computed label for the trigger
90
- const label = computed(() => {
91
- return (
92
- props.options?.find((item) => item.value === modelValue.value)?.label ??
93
- modelValue.value
94
- );
95
- });
96
-
97
- const filteredOptions = computed(() => {
98
- if (!searchText.value) return props.options || [];
99
- const lowerSearch = searchText.value.toLowerCase();
100
- return (props.options || []).filter(
101
- (item) => item.label && item.label.toLowerCase().includes(lowerSearch),
102
- );
103
- });
104
-
105
- function onOpenPick() {
106
- isActive.value = true;
107
- searchText.value = '';
108
- emit('openSearch', true);
109
- }
110
-
111
- function onClosePick() {
112
- isActive.value = false;
113
- emit('openSearch', false);
114
- }
115
-
116
- function onInput(e: any) {
117
- const value = e.detail?.value ?? e.target?.value;
118
- searchText.value = value;
119
- emit('search', value);
120
- }
121
-
122
- const debounceInput = debounce(onInput, 300);
123
-
124
- function onSelect(item: { label: string; value: any }) {
125
- modelValue.value = item.value;
126
- emit('change', item);
127
- onClosePick();
128
- }
129
-
130
- function onClear() {
131
- modelValue.value = '';
132
- emit('search', '');
133
- emit('change', { label: '', value: '' });
134
- }
135
- </script>
136
-
137
- <style scoped>
138
- .pick-wrapper {
139
- position: relative;
140
- width: 100%;
141
- }
142
-
143
- .pick-trigger {
144
- display: flex;
145
- align-items: center;
146
- justify-content: space-between;
147
- width: 100%;
148
- min-width: 0;
149
- height: 24px; /* Slightly taller for easier click */
150
- padding: 0 10px;
151
- border-radius: 4px;
152
- border: 1px solid var(--dev-tool-border-color);
153
- background-color: var(--dev-tool-bg-color);
154
- transition: all 0.3s;
155
- box-sizing: border-box;
156
- cursor: pointer;
157
- }
158
-
159
- .pick-trigger:hover {
160
- border-color: var(--dev-tool-active-color, #409eff);
161
- }
162
-
163
- .pick-trigger-placeholder .pick-trigger-text {
164
- color: var(--dev-tool-text-color-placeholder, #999);
165
- }
166
-
167
- .pick-trigger-text {
168
- flex: 1;
169
- overflow: hidden;
170
- text-overflow: ellipsis;
171
- white-space: nowrap;
172
- color: var(--dev-tool-text-color);
173
- }
174
-
175
- .pick-handle {
176
- display: flex;
177
- align-items: center;
178
- }
179
-
180
- .pick-arrow {
181
- padding-left: 4px;
182
- color: #999;
183
- font-family: monospace;
184
- font-weight: bold;
185
- transform: rotate(90deg);
186
- transition: transform 0.3s;
187
- position: relative;
188
- top: -1px;
189
- }
190
-
191
- .pick-arrow-active {
192
- transform: rotate(-90deg);
193
- }
194
-
195
- .pick-clear {
196
- padding-left: 8px;
197
- font-size: 16px;
198
- color: #999;
199
- }
200
-
201
- .pick-mask {
202
- position: fixed;
203
- inset: 0;
204
- background-color: rgb(0 0 0 / 40%);
205
- z-index: 10000;
206
- display: flex;
207
- align-items: center;
208
- justify-content: center;
209
- backdrop-filter: blur(2px);
210
- }
211
-
212
- .pick-modal {
213
- width: 80%;
214
- max-width: 400px;
215
- height: 60vh;
216
- max-height: 500px;
217
- background-color: var(--dev-tool-bg-color);
218
- border-radius: 12px;
219
- box-shadow: 0 8px 24px rgb(0 0 0 / 15%);
220
- display: flex;
221
- flex-direction: column;
222
- overflow: hidden;
223
- animation: pick-pop-in 0.2s ease-out;
224
- }
225
-
226
- @keyframes pick-pop-in {
227
- from {
228
- opacity: 0;
229
- transform: scale(0.95);
230
- }
231
-
232
- to {
233
- opacity: 1;
234
- transform: scale(1);
235
- }
236
- }
237
-
238
- .pick-header {
239
- display: flex;
240
- align-items: center;
241
- justify-content: space-between;
242
- padding: 12px 16px;
243
- border-bottom: 1px solid var(--dev-tool-border-color);
244
- }
245
-
246
- .pick-title {
247
- font-weight: 600;
248
- color: var(--dev-tool-text-color);
249
- }
250
-
251
- .pick-close {
252
- font-size: 20px;
253
- color: #999;
254
- padding: 4px;
255
- cursor: pointer;
256
- }
257
-
258
- .pick-search {
259
- padding: 10px 16px;
260
- border-bottom: 1px solid var(--dev-tool-border-color);
261
- }
262
-
263
- .pick-search-input {
264
- width: 100%;
265
- height: 36px;
266
- padding: 0 12px;
267
- border-radius: 6px;
268
- background-color: var(--dev-tool-bg2-color, #f5f5f5);
269
- border: 1px solid transparent;
270
- box-sizing: border-box;
271
- color: var(--dev-tool-text-color);
272
- }
273
-
274
- .pick-search-input:focus {
275
- border-color: var(--dev-tool-active-color, #409eff);
276
- background-color: var(--dev-tool-bg-color);
277
- }
278
-
279
- .pick-list {
280
- flex: 1;
281
- overflow-y: auto;
282
- padding: 8px 0;
283
- }
284
-
285
- .pick-item {
286
- display: flex;
287
- align-items: center;
288
- justify-content: space-between;
289
- padding: 12px 16px;
290
- cursor: pointer;
291
- transition: background-color 0.2s;
292
- }
293
-
294
- .pick-item:hover,
295
- .pick-item:active {
296
- background-color: var(--dev-tool-hover-bg-color, rgb(0 0 0 / 5%));
297
- }
298
-
299
- .pick-item-active {
300
- background-color: var(--dev-tool-active-bg-color, rgb(64 158 255 / 10%));
301
- }
302
-
303
- .pick-item-active .pick-item-text {
304
- color: var(--dev-tool-active-color, #409eff);
305
- font-weight: 500;
306
- }
307
-
308
- .pick-item-text {
309
- color: var(--dev-tool-text-color);
310
- }
311
-
312
- .pick-item-check {
313
- color: var(--dev-tool-active-color, #409eff);
314
- font-weight: bold;
315
- }
316
-
317
- .pick-empty {
318
- padding: 24px;
319
- text-align: center;
320
- color: #999;
321
- }
322
- </style>
1
+ <template>
2
+ <view class="pick-wrapper" :style="customStyle">
3
+ <!-- Trigger Area -->
4
+ <view
5
+ :class="`pick-trigger ${!modelValue ? 'pick-trigger-placeholder' : ''}`"
6
+ @click="onOpenPick">
7
+ <text class="pick-trigger-text">
8
+ {{ label || placeholder || '请选择' }}
9
+ </text>
10
+ <view class="pick-handle">
11
+ <view
12
+ v-if="allowClear && modelValue"
13
+ class="pick-clear"
14
+ @click.stop="onClear">
15
+ ×
16
+ </view>
17
+ <view :class="['pick-arrow', isActive ? 'pick-arrow-active' : '']">
18
+ >
19
+ </view>
20
+ </view>
21
+ </view>
22
+
23
+ <!-- Popup Modal -->
24
+ <view class="pick-mask" v-if="isActive" @click="onClosePick">
25
+ <view class="pick-modal" @click.stop>
26
+ <!-- Header -->
27
+ <view class="pick-header">
28
+ <text class="pick-title">{{ placeholder || '请选择' }}</text>
29
+ <view class="pick-close" @click="onClosePick">×</view>
30
+ </view>
31
+
32
+ <!-- Search -->
33
+ <view class="pick-search" v-if="!readonly">
34
+ <input
35
+ class="pick-search-input"
36
+ :value="searchText"
37
+ placeholder="搜索..."
38
+ @input="debounceInput"
39
+ :focus="isActive" />
40
+ </view>
41
+
42
+ <!-- List -->
43
+ <scroll-view scroll-y class="pick-list">
44
+ <view
45
+ v-for="item in filteredOptions"
46
+ :key="item.value"
47
+ :class="[
48
+ 'pick-item',
49
+ item.value === modelValue ? 'pick-item-active' : '',
50
+ ]"
51
+ @click="onSelect(item)">
52
+ <text class="pick-item-text">{{ item.label }}</text>
53
+ <text v-if="item.value === modelValue" class="pick-item-check">
54
+
55
+ </text>
56
+ </view>
57
+ <view v-if="filteredOptions.length === 0" class="pick-empty">
58
+ 暂无数据
59
+ </view>
60
+ </scroll-view>
61
+ </view>
62
+ </view>
63
+ </view>
64
+ </template>
65
+
66
+ <script lang="ts" setup>
67
+ import { debounce } from '../../../utils';
68
+ import { ref, computed } from 'vue';
69
+
70
+ interface Option {
71
+ label: string;
72
+ value: any;
73
+ }
74
+
75
+ const props = defineProps<{
76
+ placeholder?: string;
77
+ readonly?: boolean;
78
+ allowClear?: boolean;
79
+ options?: Option[];
80
+ customStyle?: Record<string, any> | string;
81
+ }>();
82
+
83
+ const modelValue = defineModel<string>('modelValue');
84
+ const emit = defineEmits<{
85
+ (e: 'search', value: string): void;
86
+ (e: 'openSearch', value: boolean): void;
87
+ (e: 'change', value: Option): void;
88
+ }>();
89
+
90
+ const isActive = ref(false);
91
+ const searchText = ref('');
92
+
93
+ const label = computed(
94
+ () =>
95
+ props.options?.find((i) => i.value === modelValue.value)?.label ??
96
+ modelValue.value,
97
+ );
98
+
99
+ const filteredOptions = computed(() => {
100
+ const list = props.options || [];
101
+ if (!searchText.value) return list;
102
+ const s = searchText.value.toLowerCase();
103
+ return list.filter((i) => i.label?.toLowerCase().includes(s));
104
+ });
105
+
106
+ const onOpenPick = () => {
107
+ isActive.value = true;
108
+ searchText.value = '';
109
+ emit('openSearch', true);
110
+ };
111
+
112
+ const onClosePick = () => {
113
+ isActive.value = false;
114
+ emit('openSearch', false);
115
+ };
116
+
117
+ const debounceInput = debounce((e: any) => {
118
+ const val = e.detail?.value ?? e.target?.value;
119
+ searchText.value = val;
120
+ emit('search', val);
121
+ }, 300);
122
+
123
+ const onSelect = (item: Option) => {
124
+ modelValue.value = item.value;
125
+ emit('change', item);
126
+ onClosePick();
127
+ };
128
+
129
+ const onClear = () => {
130
+ modelValue.value = '';
131
+ emit('search', '');
132
+ emit('change', { label: '', value: '' });
133
+ };
134
+ </script>
135
+
136
+ <style scoped>
137
+ .pick-wrapper {
138
+ position: relative;
139
+ width: 100%;
140
+ }
141
+
142
+ .pick-trigger {
143
+ display: flex;
144
+ align-items: center;
145
+ justify-content: space-between;
146
+ width: 100%;
147
+ min-width: 0;
148
+ height: 24px; /* Slightly taller for easier click */
149
+ padding: 0 10px;
150
+ border-radius: 4px;
151
+ border: 1px solid var(--dev-tool-border-color);
152
+ background-color: var(--dev-tool-bg-color);
153
+ transition: all 0.3s;
154
+ box-sizing: border-box;
155
+ cursor: pointer;
156
+ }
157
+
158
+ .pick-trigger:hover {
159
+ border-color: var(--dev-tool-active-color, #409eff);
160
+ }
161
+
162
+ .pick-trigger-placeholder .pick-trigger-text {
163
+ color: var(--dev-tool-text-color-placeholder, #999);
164
+ }
165
+
166
+ .pick-trigger-text {
167
+ flex: 1;
168
+ overflow: hidden;
169
+ text-overflow: ellipsis;
170
+ white-space: nowrap;
171
+ color: var(--dev-tool-text-color);
172
+ }
173
+
174
+ .pick-handle {
175
+ display: flex;
176
+ align-items: center;
177
+ }
178
+
179
+ .pick-arrow {
180
+ padding-left: 4px;
181
+ color: #999;
182
+ font-family: monospace;
183
+ font-weight: bold;
184
+ transform: rotate(90deg);
185
+ transition: transform 0.3s;
186
+ position: relative;
187
+ top: -1px;
188
+ }
189
+
190
+ .pick-arrow-active {
191
+ transform: rotate(-90deg);
192
+ }
193
+
194
+ .pick-clear {
195
+ padding-left: 8px;
196
+ font-size: 16px;
197
+ color: #999;
198
+ }
199
+
200
+ .pick-mask {
201
+ position: fixed;
202
+ inset: 0;
203
+ background-color: rgb(0 0 0 / 40%);
204
+ z-index: 10000;
205
+ display: flex;
206
+ align-items: center;
207
+ justify-content: center;
208
+ backdrop-filter: blur(2px);
209
+ }
210
+
211
+ .pick-modal {
212
+ width: 80%;
213
+ max-width: 400px;
214
+ height: 60vh;
215
+ max-height: 500px;
216
+ background-color: var(--dev-tool-bg-color);
217
+ border-radius: 12px;
218
+ box-shadow: 0 8px 24px rgb(0 0 0 / 15%);
219
+ display: flex;
220
+ flex-direction: column;
221
+ overflow: hidden;
222
+ animation: pick-pop-in 0.2s ease-out;
223
+ }
224
+
225
+ @keyframes pick-pop-in {
226
+ from {
227
+ opacity: 0;
228
+ transform: scale(0.95);
229
+ }
230
+
231
+ to {
232
+ opacity: 1;
233
+ transform: scale(1);
234
+ }
235
+ }
236
+
237
+ .pick-header {
238
+ display: flex;
239
+ align-items: center;
240
+ justify-content: space-between;
241
+ padding: 12px 16px;
242
+ border-bottom: 1px solid var(--dev-tool-border-color);
243
+ }
244
+
245
+ .pick-title {
246
+ font-weight: 600;
247
+ color: var(--dev-tool-text-color);
248
+ }
249
+
250
+ .pick-close {
251
+ font-size: 20px;
252
+ color: #999;
253
+ padding: 4px;
254
+ cursor: pointer;
255
+ }
256
+
257
+ .pick-search {
258
+ padding: 10px 16px;
259
+ border-bottom: 1px solid var(--dev-tool-border-color);
260
+ }
261
+
262
+ .pick-search-input {
263
+ width: 100%;
264
+ height: 36px;
265
+ padding: 0 12px;
266
+ border-radius: 6px;
267
+ background-color: var(--dev-tool-bg2-color, #f5f5f5);
268
+ border: 1px solid transparent;
269
+ box-sizing: border-box;
270
+ color: var(--dev-tool-text-color);
271
+ }
272
+
273
+ .pick-search-input:focus {
274
+ border-color: var(--dev-tool-active-color, #409eff);
275
+ background-color: var(--dev-tool-bg-color);
276
+ }
277
+
278
+ .pick-list {
279
+ flex: 1;
280
+ overflow-y: auto;
281
+ padding: 8px 0;
282
+ }
283
+
284
+ .pick-item {
285
+ display: flex;
286
+ align-items: center;
287
+ justify-content: space-between;
288
+ padding: 12px 16px;
289
+ cursor: pointer;
290
+ transition: background-color 0.2s;
291
+ }
292
+
293
+ .pick-item:hover,
294
+ .pick-item:active {
295
+ background-color: var(--dev-tool-hover-bg-color, rgb(0 0 0 / 5%));
296
+ }
297
+
298
+ .pick-item-active {
299
+ background-color: var(--dev-tool-active-bg-color, rgb(64 158 255 / 10%));
300
+ }
301
+
302
+ .pick-item-active .pick-item-text {
303
+ color: var(--dev-tool-active-color, #409eff);
304
+ font-weight: 500;
305
+ }
306
+
307
+ .pick-item-text {
308
+ color: var(--dev-tool-text-color);
309
+ }
310
+
311
+ .pick-item-check {
312
+ color: var(--dev-tool-active-color, #409eff);
313
+ font-weight: bold;
314
+ }
315
+
316
+ .pick-empty {
317
+ padding: 24px;
318
+ text-align: center;
319
+ color: #999;
320
+ }
321
+ </style>