oxy-uni-ui 1.2.3 → 2.0.0

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 (235) hide show
  1. package/attributes.json +1 -1
  2. package/components/common/abstracts/variable.scss +353 -328
  3. package/components/common/util.ts +185 -32
  4. package/components/composables/index.ts +1 -0
  5. package/components/composables/usePopover.ts +24 -20
  6. package/components/composables/useVirtualScroll.ts +10 -9
  7. package/components/composables/useWindowResize.ts +35 -0
  8. package/components/oxy-action-sheet/index.scss +24 -11
  9. package/components/oxy-action-sheet/oxy-action-sheet.vue +27 -19
  10. package/components/oxy-action-sheet/types.ts +7 -0
  11. package/components/oxy-backtop/index.scss +3 -3
  12. package/components/oxy-backtop/oxy-backtop.vue +9 -6
  13. package/components/oxy-backtop/types.ts +7 -7
  14. package/components/oxy-badge/index.scss +4 -4
  15. package/components/oxy-badge/oxy-badge.vue +3 -3
  16. package/components/oxy-badge/types.ts +2 -2
  17. package/components/oxy-button/index.scss +5 -5
  18. package/components/oxy-button/oxy-button.vue +5 -1
  19. package/components/oxy-calendar/index.scss +11 -11
  20. package/components/oxy-calendar/oxy-calendar.vue +1 -0
  21. package/components/oxy-calendar/types.ts +5 -0
  22. package/components/oxy-calendar-view/month/index.scss +4 -4
  23. package/components/oxy-calendar-view/month/types.ts +36 -0
  24. package/components/oxy-calendar-view/monthPanel/index.scss +7 -7
  25. package/components/oxy-calendar-view/monthPanel/month-panel.vue +14 -8
  26. package/components/oxy-calendar-view/year/index.scss +4 -4
  27. package/components/oxy-calendar-view/yearPanel/index.scss +4 -4
  28. package/components/oxy-calendar-view/yearPanel/year-panel.vue +21 -5
  29. package/components/oxy-card/index.scss +2 -2
  30. package/components/oxy-cell/index.scss +8 -8
  31. package/components/oxy-checkbox/index.scss +7 -7
  32. package/components/oxy-checkbox-group/index.scss +2 -2
  33. package/components/oxy-circle/oxy-circle.vue +10 -7
  34. package/components/oxy-circle/types.ts +5 -5
  35. package/components/oxy-col/oxy-col.vue +2 -2
  36. package/components/oxy-col-picker/index.scss +4 -4
  37. package/components/oxy-col-picker/oxy-col-picker.vue +6 -5
  38. package/components/oxy-col-picker/types.ts +7 -2
  39. package/components/oxy-collapse/index.scss +2 -2
  40. package/components/oxy-collapse-item/oxy-collapse-item.vue +3 -3
  41. package/components/oxy-corner/index.scss +32 -32
  42. package/components/oxy-count-to/oxy-count-to.vue +3 -3
  43. package/components/oxy-curtain/index.scss +15 -15
  44. package/components/oxy-curtain/oxy-curtain.vue +4 -2
  45. package/components/oxy-curtain/types.ts +6 -1
  46. package/components/oxy-date-strip/oxy-date-strip.vue +2 -2
  47. package/components/oxy-date-strip/types.ts +1 -1
  48. package/components/oxy-date-strip-item/index.scss +3 -3
  49. package/components/oxy-datetime-picker/index.scss +11 -11
  50. package/components/oxy-datetime-picker/oxy-datetime-picker.vue +1 -0
  51. package/components/oxy-datetime-picker/types.ts +5 -0
  52. package/components/oxy-drop-menu/index.scss +3 -3
  53. package/components/oxy-drop-menu/oxy-drop-menu.vue +3 -3
  54. package/components/oxy-drop-menu-item/index.scss +1 -1
  55. package/components/oxy-drop-menu-item/oxy-drop-menu-item.vue +4 -3
  56. package/components/oxy-drop-menu-item/types.ts +5 -0
  57. package/components/oxy-echarts/types.ts +6 -0
  58. package/components/oxy-fab/index.scss +8 -8
  59. package/components/oxy-fab/oxy-fab.vue +22 -3
  60. package/components/oxy-file-list/index.scss +24 -23
  61. package/components/oxy-file-list/oxy-file-list.vue +2 -2
  62. package/components/oxy-floating-panel/oxy-floating-panel.vue +13 -9
  63. package/components/oxy-floating-panel/{type.ts → types.ts} +8 -8
  64. package/components/oxy-footer/index.scss +19 -0
  65. package/components/oxy-footer/oxy-footer.vue +78 -0
  66. package/components/oxy-footer/types.ts +17 -0
  67. package/components/oxy-form-item/types.ts +22 -1
  68. package/components/oxy-gap/oxy-gap.vue +2 -2
  69. package/components/oxy-gap/types.ts +2 -2
  70. package/components/oxy-grid/oxy-grid.vue +1 -1
  71. package/components/oxy-grid/types.ts +1 -1
  72. package/components/oxy-grid-item/index.scss +1 -1
  73. package/components/oxy-grid-item/oxy-grid-item.vue +7 -5
  74. package/components/oxy-grid-item/types.ts +1 -1
  75. package/components/oxy-guidance/index.scss +75 -0
  76. package/components/oxy-guidance/oxy-guidance.vue +201 -0
  77. package/components/oxy-guidance/types.ts +33 -0
  78. package/components/oxy-icon/oxy-icon.vue +2 -2
  79. package/components/oxy-icon/types.ts +1 -1
  80. package/components/oxy-img/oxy-img.vue +4 -4
  81. package/components/oxy-img/types.ts +3 -3
  82. package/components/oxy-img-cropper/index.scss +12 -12
  83. package/components/oxy-img-cropper/oxy-img-cropper.vue +97 -52
  84. package/components/oxy-img-cropper/types.ts +2 -2
  85. package/components/oxy-img-lazy/oxy-img-lazy.vue +3 -3
  86. package/components/oxy-img-lazy/types.ts +3 -3
  87. package/components/oxy-index-anchor/index.scss +2 -2
  88. package/components/oxy-index-anchor/oxy-index-anchor.vue +2 -2
  89. package/components/oxy-index-anchor/{type.ts → types.ts} +3 -0
  90. package/components/oxy-index-bar/index.scss +3 -3
  91. package/components/oxy-index-bar/oxy-index-bar.vue +3 -3
  92. package/components/oxy-index-bar/{type.ts → types.ts} +2 -2
  93. package/components/oxy-input/index.scss +1 -1
  94. package/components/oxy-input-number/index.scss +5 -5
  95. package/components/oxy-input-number/oxy-input-number.vue +2 -2
  96. package/components/oxy-input-number/types.ts +3 -2
  97. package/components/oxy-keyboard/index.scss +5 -5
  98. package/components/oxy-keyboard/key/index.scss +3 -3
  99. package/components/oxy-keyboard/key/index.vue +2 -2
  100. package/components/oxy-keyboard/key/types.ts +15 -0
  101. package/components/oxy-keyboard/oxy-keyboard.vue +1 -0
  102. package/components/oxy-keyboard/types.ts +5 -0
  103. package/components/oxy-link/index.scss +2 -2
  104. package/components/oxy-list/oxy-list.vue +4 -3
  105. package/components/oxy-loading/oxy-loading.vue +8 -4
  106. package/components/oxy-loading/types.ts +1 -1
  107. package/components/oxy-loadmore/index.scss +3 -3
  108. package/components/oxy-long-press-menu/index.scss +93 -0
  109. package/components/oxy-long-press-menu/oxy-long-press-menu.vue +338 -0
  110. package/components/oxy-long-press-menu/types.ts +34 -0
  111. package/components/oxy-message-box/index.scss +12 -11
  112. package/components/oxy-message-box/oxy-message-box.vue +11 -3
  113. package/components/oxy-message-box/types.ts +14 -0
  114. package/components/oxy-navbar/index.scss +2 -2
  115. package/components/oxy-navbar/oxy-navbar.vue +58 -13
  116. package/components/oxy-navbar/types.ts +8 -1
  117. package/components/oxy-navbar-capsule/types.ts +3 -0
  118. package/components/oxy-notice-bar/index.scss +3 -3
  119. package/components/oxy-notice-bar/oxy-notice-bar.vue +9 -5
  120. package/components/oxy-notice-bar/types.ts +3 -3
  121. package/components/oxy-notify/index.ts +1 -0
  122. package/components/oxy-notify/oxy-notify.vue +3 -2
  123. package/components/oxy-notify/types.ts +7 -0
  124. package/components/oxy-pagination/index.scss +1 -1
  125. package/components/oxy-password-input/oxy-password-input.vue +2 -2
  126. package/components/oxy-password-input/types.ts +1 -1
  127. package/components/oxy-picker/index.scss +45 -2
  128. package/components/oxy-picker/oxy-picker.vue +100 -14
  129. package/components/oxy-picker/types.ts +29 -1
  130. package/components/oxy-picker-view/index.scss +3 -3
  131. package/components/oxy-picker-view/oxy-picker-view.vue +4 -4
  132. package/components/oxy-popover/index.scss +9 -9
  133. package/components/oxy-popup/index.scss +2 -2
  134. package/components/oxy-popup/oxy-popup.vue +35 -2
  135. package/components/oxy-popup/types.ts +8 -1
  136. package/components/oxy-progress/index.scss +3 -3
  137. package/components/oxy-qrcode/draw.ts +398 -0
  138. package/components/oxy-qrcode/index.scss +2 -0
  139. package/components/oxy-qrcode/oxy-qrcode.vue +124 -0
  140. package/components/oxy-qrcode/qrcode.ts +936 -0
  141. package/components/oxy-qrcode/types.ts +42 -0
  142. package/components/oxy-radio/index.scss +10 -10
  143. package/components/oxy-radio-group/index.scss +2 -2
  144. package/components/oxy-rate/types.ts +4 -4
  145. package/components/oxy-resize/index.scss +2 -2
  146. package/components/oxy-resize/oxy-resize.vue +4 -4
  147. package/components/oxy-resize/types.ts +3 -0
  148. package/components/oxy-rich-text/index.scss +30 -29
  149. package/components/oxy-rich-text/mp-html/mp-html.vue +33 -24
  150. package/components/oxy-rich-text/mp-html/node/node.vue +30 -19
  151. package/components/oxy-rich-text/oxy-rich-text.vue +31 -31
  152. package/components/oxy-rich-text/types.ts +6 -1
  153. package/components/oxy-row/oxy-row.vue +3 -3
  154. package/components/oxy-row/types.ts +1 -1
  155. package/components/oxy-search/index.scss +3 -3
  156. package/components/oxy-segmented/index.scss +16 -16
  157. package/components/oxy-segmented/oxy-segmented.vue +23 -3
  158. package/components/oxy-select/index.scss +144 -68
  159. package/components/oxy-select/oxy-select.vue +85 -50
  160. package/components/oxy-select/types.ts +13 -1
  161. package/components/oxy-select-picker/index.scss +7 -7
  162. package/components/oxy-select-picker/oxy-select-picker.vue +1 -0
  163. package/components/oxy-select-picker/types.ts +2 -0
  164. package/components/oxy-sidebar-item/index.scss +1 -1
  165. package/components/oxy-signature/oxy-signature.vue +18 -10
  166. package/components/oxy-signature/types.ts +106 -13
  167. package/components/oxy-skeleton/oxy-skeleton.vue +6 -6
  168. package/components/oxy-skeleton/types.ts +1 -1
  169. package/components/oxy-slider/index.scss +3 -3
  170. package/components/oxy-sort-button/index.scss +8 -8
  171. package/components/oxy-status-tip/index.scss +4 -4
  172. package/components/oxy-status-tip/oxy-status-tip.vue +5 -5
  173. package/components/oxy-status-tip/types.ts +3 -3
  174. package/components/oxy-step/index.scss +14 -14
  175. package/components/oxy-sticky/oxy-sticky.vue +6 -6
  176. package/components/oxy-stream-render/types.ts +4 -1
  177. package/components/oxy-swipe-action/oxy-swipe-action.vue +27 -2
  178. package/components/oxy-swiper/oxy-swiper.vue +6 -6
  179. package/components/oxy-swiper/types.ts +5 -5
  180. package/components/oxy-switch/index.scss +8 -8
  181. package/components/oxy-switch/oxy-switch.vue +2 -2
  182. package/components/oxy-switch/types.ts +1 -1
  183. package/components/oxy-tab/index.scss +11 -1
  184. package/components/oxy-tabbar/index.scss +1 -1
  185. package/components/oxy-tabbar/oxy-tabbar.vue +39 -10
  186. package/components/oxy-table/index.scss +5 -5
  187. package/components/oxy-table/oxy-table.vue +8 -6
  188. package/components/oxy-table/types.ts +2 -2
  189. package/components/oxy-table-col/oxy-table-col.vue +3 -3
  190. package/components/oxy-table-col/types.ts +2 -2
  191. package/components/oxy-tabs/index.scss +43 -15
  192. package/components/oxy-tabs/oxy-tabs.vue +53 -19
  193. package/components/oxy-tabs/types.ts +15 -3
  194. package/components/oxy-tag/index.scss +15 -15
  195. package/components/oxy-text/index.scss +5 -1
  196. package/components/oxy-text/oxy-text.vue +76 -7
  197. package/components/oxy-text/types.ts +12 -0
  198. package/components/oxy-textarea/index.scss +6 -6
  199. package/components/oxy-toast/oxy-toast.vue +24 -8
  200. package/components/oxy-tooltip/index.scss +9 -9
  201. package/components/oxy-tree/index.scss +51 -15
  202. package/components/oxy-tree/oxy-tree.vue +13 -9
  203. package/components/oxy-tree/types.ts +12 -9
  204. package/components/oxy-upload/index.scss +21 -21
  205. package/components/oxy-upload/types.ts +2 -2
  206. package/components/oxy-verification-code/index.scss +6 -0
  207. package/components/oxy-verification-code/oxy-verification-code.vue +187 -0
  208. package/components/oxy-verification-code/types.ts +82 -0
  209. package/components/oxy-video-preview/index.scss +4 -4
  210. package/components/oxy-virtual-scroll/index.scss +4 -4
  211. package/components/oxy-virtual-scroll/oxy-virtual-scroll.vue +11 -7
  212. package/components/oxy-virtual-scroll/types.ts +14 -14
  213. package/components/oxy-voice-player/index.scss +908 -0
  214. package/components/oxy-voice-player/oxy-voice-player.vue +821 -0
  215. package/components/oxy-voice-player/types.ts +567 -0
  216. package/components/oxy-waterfall/oxy-waterfall.vue +6 -6
  217. package/components/oxy-waterfall/types.ts +6 -6
  218. package/components/oxy-watermark/oxy-watermark.vue +35 -13
  219. package/components/oxy-watermark/types.ts +14 -14
  220. package/global.d.ts +2 -0
  221. package/locale/lang/ar-SA.ts +3 -0
  222. package/locale/lang/en-US.ts +3 -0
  223. package/locale/lang/zh-CN.ts +3 -0
  224. package/package.json +97 -1
  225. package/tags.json +1 -1
  226. package/web-types.json +1 -1
  227. package/components/oxy-number-keyboard/index.scss +0 -78
  228. package/components/oxy-number-keyboard/key/index.scss +0 -81
  229. package/components/oxy-number-keyboard/key/index.vue +0 -78
  230. package/components/oxy-number-keyboard/key/types.ts +0 -11
  231. package/components/oxy-number-keyboard/oxy-number-keyboard.vue +0 -151
  232. package/components/oxy-number-keyboard/types.ts +0 -83
  233. package/components/oxy-tree/components/tree-node-content.vue +0 -72
  234. package/components/oxy-tree/index.ts +0 -51
  235. package/oxy-uni-ui.zip +0 -0
@@ -44,6 +44,7 @@
44
44
  :hide-when-close="false"
45
45
  :close-on-click-modal="closeOnClickModal"
46
46
  :z-index="zIndex"
47
+ :max-width="popupMaxWidth"
47
48
  :safe-area-inset-bottom="safeAreaInsetBottom"
48
49
  :root-portal="rootPortal"
49
50
  @close="onCancel"
@@ -59,6 +60,15 @@
59
60
  {{ confirmButtonText || translate('done') }}
60
61
  </view>
61
62
  </view>
63
+ <view v-if="searchable" class="oxy-picker__search">
64
+ <view class="oxy-picker__search-input">
65
+ <oxy-icon name="search" custom-class="oxy-picker__search-icon" />
66
+ <input v-model="searchKeyword" :placeholder="searchPlaceholder" @input="handleSearch" />
67
+ <view v-if="searchKeyword" class="oxy-picker__search-clear" @click="clearSearch">
68
+ <oxy-icon name="error-fill" custom-class="oxy-picker__search-clear-icon" />
69
+ </view>
70
+ </view>
71
+ </view>
62
72
  <oxy-picker-view
63
73
  ref="pickerViewOxy"
64
74
  :custom-class="customViewClass"
@@ -97,16 +107,14 @@ import OxyPopup from '../oxy-popup/oxy-popup.vue'
97
107
  import OxyPickerView from '../oxy-picker-view/oxy-picker-view.vue'
98
108
  import OxyCell from '../oxy-cell/oxy-cell.vue'
99
109
  import { getCurrentInstance, onBeforeMount, ref, watch, computed, onMounted, nextTick } from 'vue'
100
- import { deepClone, defaultDisplayFormat, getType, isArray, isDef, isFunction } from '../common/util'
110
+ import { deepClone, defaultDisplayFormat, getType, isArray, isDef, isFunction, debounce } from '../common/util'
101
111
  import { type ColumnItem, formatArray, type PickerViewInstance } from '../oxy-picker-view/types'
102
- import { FORM_KEY, type FormItemRule } from '../oxy-form/types'
103
- import { useParent } from '../composables/useParent'
104
112
  import { useTranslate } from '../composables/useTranslate'
105
- import { pickerProps, type PickerExpose } from './types'
113
+ import { pickerProps, type PickerExpose, type PickerSearchEvent } from './types'
106
114
  const { translate } = useTranslate('picker')
107
115
 
108
116
  const props = defineProps(pickerProps)
109
- const emit = defineEmits(['confirm', 'open', 'cancel', 'clear', 'update:modelValue'])
117
+ const emit = defineEmits(['confirm', 'open', 'cancel', 'clear', 'update:modelValue', 'search'])
110
118
 
111
119
  const pickerViewOxy = ref<PickerViewInstance | null>(null)
112
120
 
@@ -121,6 +129,8 @@ const displayColumns = ref<Array<string | number | ColumnItem | Array<string | n
121
129
  const resetColumns = ref<Array<string | number | ColumnItem | Array<string | number | ColumnItem>>>([]) // 保存之前的 columns,当取消时,将数据源回滚,避免多级联动数据源不正确的情况
122
130
  const isPicking = ref<boolean>(false) // 判断pickview是否还在滑动中
123
131
  const hasConfirmed = ref<boolean>(false) // 判断用户是否点击了确认按钮
132
+ const searchKeyword = ref<string>('')
133
+ const filteredDisplayColumns = ref<Array<string | number | ColumnItem | Array<string | number | ColumnItem>>>([]) // 保存过滤后的显示列
124
134
 
125
135
  const isLoading = computed(() => {
126
136
  return props.loading || innerLoading.value
@@ -188,6 +198,9 @@ watch(
188
198
  }
189
199
  )
190
200
 
201
+ const isMultiColumn = computed(() => {
202
+ return props.columns.length > 0 && isArray(props.columns[0])
203
+ })
191
204
  // 是否展示清除按钮
192
205
  const showClear = computed(() => {
193
206
  return props.clearable && !props.disabled && !props.readonly && showValue.value.length > 0
@@ -266,7 +279,7 @@ function getSelects(value: string | number | Array<string | number | Array<any>>
266
279
  let selected: number[] = []
267
280
  value.forEach((target, col) => {
268
281
  let row = formatColumns[col].findIndex((row) => {
269
- return row[props.valueKey].toString() === target.toString()
282
+ return (row as any)[props.valueKey].toString() === target.toString()
270
283
  })
271
284
  row = row === -1 ? 0 : row
272
285
  selected.push(row)
@@ -300,7 +313,9 @@ function showPopup() {
300
313
  emit('open')
301
314
  popupShow.value = true
302
315
  pickerValue.value = props.modelValue
303
- displayColumns.value = resetColumns.value
316
+ if (isMultiColumn.value) {
317
+ displayColumns.value = resetColumns.value
318
+ }
304
319
  }
305
320
 
306
321
  /**
@@ -309,10 +324,13 @@ function showPopup() {
309
324
  function onCancel() {
310
325
  popupShow.value = false
311
326
  emit('cancel')
312
- let timmer = setTimeout(() => {
313
- clearTimeout(timmer)
314
- isDef(pickerViewOxy.value) && pickerViewOxy.value.resetColumns(resetColumns.value)
315
- }, 300)
327
+ if (isMultiColumn.value) {
328
+ resetColumns.value = displayColumns.value
329
+ let timmer = setTimeout(() => {
330
+ clearTimeout(timmer)
331
+ isDef(pickerViewOxy.value) && pickerViewOxy.value.resetColumns(resetColumns.value)
332
+ }, 300)
333
+ }
316
334
  }
317
335
  /**
318
336
  * 点击确定按钮触发。展示选中值,触发cancel事件。
@@ -347,10 +365,25 @@ function handleConfirm() {
347
365
 
348
366
  const selects = pickerViewOxy.value!.getSelects()
349
367
  const values = pickerViewOxy.value!.getValues()
350
- // 获取当前的数据源,并设置给 resetColumns,用于取消时可以回退数据源
351
- const columns = pickerViewOxy.value!.getColumnsData()
368
+
369
+ let isSearchResultEmpty = false
370
+
371
+ if (isMultiColumn.value) {
372
+ isSearchResultEmpty = displayColumns.value.every((column) => {
373
+ return isArray(column) && column.length === 0
374
+ })
375
+ const columns = pickerViewOxy.value!.getColumnsData()
376
+ resetColumns.value = deepClone(columns)
377
+ } else {
378
+ isSearchResultEmpty = displayColumns.value.length === 0
379
+ }
380
+
381
+ if (isSearchResultEmpty) {
382
+ popupShow.value = false
383
+ return
384
+ }
385
+
352
386
  popupShow.value = false
353
- resetColumns.value = deepClone(columns)
354
387
  emit('update:modelValue', values)
355
388
 
356
389
  setShowValue(selects)
@@ -400,10 +433,63 @@ function setLoading(loading: boolean) {
400
433
 
401
434
  function handleClear() {
402
435
  const clearValue = isArray(pickerValue.value) ? [] : ''
436
+ resetColumns.value = props.columns
437
+
403
438
  emit('update:modelValue', clearValue)
404
439
  emit('clear')
405
440
  }
406
441
 
442
+ function handleSearch() {
443
+ debouncedFilterColumns()
444
+ }
445
+
446
+ function clearSearch() {
447
+ searchKeyword.value = ''
448
+ // filteredDisplayColumns.value = []
449
+ // displayColumns.value = resetColumns.value
450
+ debouncedFilterColumns()
451
+ }
452
+
453
+ function filterColumns() {
454
+ const keyword = searchKeyword.value.trim().toLowerCase()
455
+ emit('search', { keyword } as PickerSearchEvent)
456
+
457
+ if (props.filterMethod && isFunction(props.filterMethod)) {
458
+ filteredDisplayColumns.value = props.filterMethod({ keyword } as PickerSearchEvent)
459
+ displayColumns.value = filteredDisplayColumns.value
460
+ if (!keyword) {
461
+ resetColumns.value = filteredDisplayColumns.value
462
+ }
463
+ return
464
+ }
465
+ if (isMultiColumn.value) {
466
+ return
467
+ }
468
+ if (!keyword) {
469
+ filteredDisplayColumns.value = []
470
+ displayColumns.value = resetColumns.value
471
+ return
472
+ }
473
+
474
+ const searchKey = props.searchKey || props.labelKey
475
+
476
+ const filteredItems = resetColumns.value.filter((item) => {
477
+ if (typeof item === 'string' || typeof item === 'number') {
478
+ return item.toString().toLowerCase().includes(keyword)
479
+ }
480
+ if (typeof item === 'object' && item !== null) {
481
+ const value = (item as any)[searchKey] || (item as any)[props.labelKey]
482
+ return value != null && value.toString().toLowerCase().includes(keyword)
483
+ }
484
+ return false
485
+ })
486
+
487
+ filteredDisplayColumns.value = filteredItems
488
+ displayColumns.value = filteredItems
489
+ }
490
+
491
+ const debouncedFilterColumns = debounce(filterColumns, 300)
492
+
407
493
  defineExpose<PickerExpose>({
408
494
  close,
409
495
  open,
@@ -138,6 +138,10 @@ export const pickerProps = {
138
138
  * 自定义层级
139
139
  */
140
140
  zIndex: makeNumberProp(15),
141
+ /**
142
+ * popup 最大宽度,支持 `rpx`、`px`、`%` 等单位
143
+ */
144
+ popupMaxWidth: makeStringProp('1200rpx'),
141
145
  /**
142
146
  * 表单域 model 字段名,在使用表单校验功能的情况下,该属性是必填的
143
147
  */
@@ -165,7 +169,27 @@ export const pickerProps = {
165
169
  /**
166
170
  * 打开pop之前的校验
167
171
  */
168
- beforeOpen: Function as PropType<() => boolean>
172
+ beforeOpen: Function as PropType<() => boolean>,
173
+ /**
174
+ * 是否启用搜索功能
175
+ */
176
+ searchable: makeBooleanProp(false),
177
+ /**
178
+ * 搜索框占位符
179
+ */
180
+ searchPlaceholder: makeStringProp('请输入搜索关键词'),
181
+ /**
182
+ * 搜索时过滤的键名,默认使用 labelKey
183
+ */
184
+ searchKey: String,
185
+ /**
186
+ * 搜索时触发的事件
187
+ */
188
+ onSearch: Function as PropType<(event: PickerSearchEvent) => void>,
189
+ /**
190
+ * 筛选方法,用于多列或级联选择器的自定义筛选逻辑
191
+ */
192
+ filterMethod: Function as PropType<(event: PickerSearchEvent) => any>
169
193
  }
170
194
 
171
195
  export type PickerProps = ExtractPropTypes<typeof pickerProps>
@@ -190,4 +214,8 @@ export type PickerExpose = {
190
214
  setLoading: (loading: boolean) => void
191
215
  }
192
216
 
217
+ export type PickerSearchEvent = {
218
+ keyword: string
219
+ }
220
+
193
221
  export type PickerInstance = ComponentPublicInstance<PickerExpose, PickerProps>
@@ -26,7 +26,7 @@
26
26
 
27
27
  @include b(picker-view) {
28
28
  position: relative;
29
- padding: 10px 0;
29
+ padding: 20rpx 0;
30
30
 
31
31
  @include e(columns) {
32
32
  position: relative;
@@ -47,7 +47,7 @@
47
47
  background-repeat: no-repeat;
48
48
  z-index: 2;
49
49
  pointer-events: none;
50
- filter: blur(4px);
50
+ filter: blur(8rpx);
51
51
  }
52
52
 
53
53
  @include e(loading) {
@@ -89,4 +89,4 @@
89
89
  color: $-picker-column-disabled-color;
90
90
  }
91
91
  }
92
- }
92
+ }
@@ -3,12 +3,12 @@
3
3
  <view class="oxy-picker-view__loading" v-if="loading">
4
4
  <oxy-loading :color="loadingColor" />
5
5
  </view>
6
- <view :style="`height: ${columnsHeight - 20}px;`">
6
+ <view :style="`height: ${(columnsHeight - 20) * 2}rpx;`">
7
7
  <picker-view
8
8
  mask-class="oxy-picker-view__mask"
9
9
  indicator-class="oxy-picker-view__roller"
10
- :indicator-style="`height: ${itemHeight}px;`"
11
- :style="`height: ${columnsHeight - 20}px;`"
10
+ :indicator-style="`height: ${itemHeight * 2}rpx;`"
11
+ :style="`height: ${(columnsHeight - 20) * 2}rpx;`"
12
12
  :value="selectedIndex"
13
13
  :immediate-change="immediateChange"
14
14
  @change="onChange"
@@ -22,7 +22,7 @@
22
22
  :class="`oxy-picker-view-column__item ${row['disabled'] ? 'oxy-picker-view-column__item--disabled' : ''} ${
23
23
  selectedIndex[colIndex] == rowIndex ? 'oxy-picker-view-column__item--active' : ''
24
24
  }`"
25
- :style="`line-height: ${itemHeight}px;`"
25
+ :style="`line-height: ${itemHeight * 2}rpx;`"
26
26
  >
27
27
  {{ row[labelKey] }}
28
28
  </view>
@@ -7,7 +7,7 @@
7
7
  @include e(pos) {
8
8
  background: rgb(75, 76, 77);
9
9
  color: $-dark-color;
10
- box-shadow: 0px 2px 10px 0px rgba(75, 76, 77, 0.1);
10
+ box-shadow: 0 4rpx 20rpx 0 rgba(75, 76, 77, 0.1);
11
11
  }
12
12
 
13
13
  @include e(menu) {
@@ -34,8 +34,8 @@
34
34
 
35
35
  @include edeep(icon) {
36
36
  vertical-align: middle;
37
- font-size: 18px;
38
- margin-right: 5px;
37
+ font-size: 36rpx;
38
+ margin-right: 10rpx;
39
39
  }
40
40
 
41
41
  @include e(menu-inner) {
@@ -66,7 +66,7 @@
66
66
  box-sizing: border-box;
67
67
  background-clip: padding-box;
68
68
  text-align: center;
69
- min-height: 36px;
69
+ min-height: 72rpx;
70
70
  z-index: $-popover-z-index;
71
71
  line-height: $-popover-line-height;
72
72
  font-size: $-popover-fs;
@@ -104,13 +104,13 @@
104
104
  }
105
105
 
106
106
  @include edeep(close-icon) {
107
- font-size: 12px;
107
+ font-size: 24rpx;
108
108
  position: absolute;
109
- right: -8px;
110
- top: -10px;
109
+ right: -16rpx;
110
+ top: -20rpx;
111
111
  transform: scale(0.5);
112
- padding: 10px;
112
+ padding: 20rpx;
113
113
  }
114
114
 
115
115
  @include squareArrow($-popover-arrow-size, $-popover-bg, $-popover-z-index - 1, $-popover-arrow-box-shadow);
116
- }
116
+ }
@@ -30,8 +30,8 @@
30
30
  @include b(popup) {
31
31
  @include edeep(close) {
32
32
  position: absolute;
33
- top: 10px;
34
- right: 10px;
33
+ top: 20rpx;
34
+ right: 20rpx;
35
35
  color: $-popup-close-color;
36
36
  font-size: $-popup-close-size;
37
37
  transform: rotate(-45deg);
@@ -77,11 +77,12 @@ export default {
77
77
  </script>
78
78
 
79
79
  <script lang="ts" setup>
80
- import { computed, onBeforeMount, ref } from 'vue'
80
+ import { computed, onBeforeMount, ref, watch } from 'vue'
81
81
  import OxyIcon from '../oxy-icon/oxy-icon.vue'
82
82
  import OxyOverlay from '../oxy-overlay/oxy-overlay.vue'
83
83
  import OxyTransition from '../oxy-transition/oxy-transition.vue'
84
84
  import OxyRootPortal from '../oxy-root-portal/oxy-root-portal.vue'
85
+ import { resolveSizeWithScreenWidth, unitConvert } from '../common/util'
85
86
  import { popupProps } from './types'
86
87
  import type { TransitionName } from '../oxy-transition/types'
87
88
 
@@ -124,9 +125,41 @@ const transitionName = computed<TransitionName | TransitionName[]>(() => {
124
125
  })
125
126
 
126
127
  const safeBottom = ref<number>(0)
128
+ const maxWidthStyleWhenOpen = ref<string>('')
129
+
130
+ function getMaxWidthStyle() {
131
+ if (props.maxWidth === '' || props.maxWidth === undefined || props.maxWidth === null) {
132
+ return ''
133
+ }
134
+ const maxWidthValue = resolveSizeWithScreenWidth(props.maxWidth, { defaultUnit: 'rpx' })
135
+ const widthStyle = props.position === 'center' ? 'width:100%;' : ''
136
+ return `${widthStyle}max-width:${maxWidthValue};margin-left:auto;margin-right:auto;`
137
+ }
138
+
139
+ watch(
140
+ () => props.modelValue,
141
+ (newValue) => {
142
+ if (newValue) {
143
+ maxWidthStyleWhenOpen.value = getMaxWidthStyle()
144
+ }
145
+ },
146
+ { immediate: true }
147
+ )
148
+
149
+ watch(
150
+ [() => props.maxWidth, () => props.position],
151
+ () => {
152
+ if (props.modelValue) {
153
+ maxWidthStyleWhenOpen.value = getMaxWidthStyle()
154
+ }
155
+ },
156
+ { deep: true }
157
+ )
127
158
 
128
159
  const style = computed(() => {
129
- return `z-index:${props.zIndex}; padding-bottom: ${safeBottom.value}px;${props.customStyle}`
160
+ return `z-index:${props.zIndex};padding-bottom:${unitConvert(safeBottom.value, 0, { output: 'px' })};${maxWidthStyleWhenOpen.value}${
161
+ props.customStyle
162
+ }`
130
163
  })
131
164
 
132
165
  const rootClass = computed(() => {
@@ -1,5 +1,5 @@
1
1
  import type { PropType } from 'vue'
2
- import { baseProps, makeBooleanProp, makeNumberProp, makeStringProp } from '../common/props'
2
+ import { baseProps, makeBooleanProp, makeNumberProp, makeNumericProp, makeStringProp } from '../common/props'
3
3
  import type { TransitionName } from '../oxy-transition/types'
4
4
 
5
5
  export type PopupType = 'center' | 'top' | 'right' | 'bottom' | 'left'
@@ -52,6 +52,13 @@ export const popupProps = {
52
52
  * 默认值:10
53
53
  */
54
54
  zIndex: makeNumberProp(10),
55
+ /**
56
+ * 弹出层最大宽度,支持 `rpx`、`px`、`%` 等单位;
57
+ * 数值和纯数字字符串按 `rpx` 处理,`%` 在打开时按屏幕宽度换算为 `rpx`
58
+ * 类型:number | string
59
+ * 默认值:''
60
+ */
61
+ maxWidth: makeNumericProp(''),
55
62
  /**
56
63
  * 是否当关闭时将弹出层隐藏(display: none)
57
64
  * 类型:boolean
@@ -47,8 +47,8 @@
47
47
  }
48
48
  }
49
49
  @include edeep(label) {
50
- width: 30px;
51
- margin-left: 9px;
50
+ width: 60rpx;
51
+ margin-left: 18rpx;
52
52
  color: $-progress-label-color;
53
53
  font-size: $-progress-label-fs;
54
54
  }
@@ -65,4 +65,4 @@
65
65
  color: $-progress-warning-color;
66
66
  }
67
67
  }
68
- }
68
+ }