oxy-uni-ui 1.0.1 → 1.1.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 (54) hide show
  1. package/LICENSE +1 -1
  2. package/attributes.json +1 -1
  3. package/components/common/abstracts/variable.scss +32 -4
  4. package/components/common/util.ts +44 -0
  5. package/components/oxy-checkbox/index.scss +36 -6
  6. package/components/oxy-checkbox/oxy-checkbox.vue +5 -4
  7. package/components/oxy-checkbox/types.ts +2 -1
  8. package/components/oxy-col-picker/index.scss +18 -15
  9. package/components/oxy-col-picker/oxy-col-picker.vue +28 -3
  10. package/components/oxy-col-picker/types.ts +12 -0
  11. package/components/oxy-corner/index.scss +138 -0
  12. package/components/oxy-corner/oxy-corner.vue +66 -0
  13. package/components/oxy-corner/types.ts +43 -0
  14. package/components/oxy-drop-menu/index.scss +4 -0
  15. package/components/oxy-drop-menu/oxy-drop-menu.vue +5 -3
  16. package/components/oxy-drop-menu/types.ts +1 -1
  17. package/components/oxy-drop-menu-item/index.scss +4 -4
  18. package/components/oxy-drop-menu-item/oxy-drop-menu-item.vue +2 -0
  19. package/components/oxy-file-list/index.scss +83 -0
  20. package/components/oxy-file-list/oxy-file-list.vue +213 -0
  21. package/components/oxy-file-list/types.ts +54 -0
  22. package/components/oxy-list/index.scss +4 -0
  23. package/components/oxy-list/oxy-list.vue +125 -0
  24. package/components/oxy-list/types.ts +50 -0
  25. package/components/oxy-slider/index.scss +2 -2
  26. package/components/oxy-swiper/index.scss +1 -2
  27. package/components/oxy-textarea/oxy-textarea.vue +0 -4
  28. package/components/oxy-tree/components/tree-node-content.vue +72 -0
  29. package/components/oxy-tree/index.scss +61 -0
  30. package/components/oxy-tree/index.ts +51 -0
  31. package/components/oxy-tree/oxy-tree.vue +289 -0
  32. package/components/oxy-tree/types.ts +48 -0
  33. package/components/oxy-upload/images/audio.png +0 -0
  34. package/components/oxy-upload/images/excle.png +0 -0
  35. package/components/oxy-upload/images/other.png +0 -0
  36. package/components/oxy-upload/images/pdf.png +0 -0
  37. package/components/oxy-upload/images/pic.png +0 -0
  38. package/components/oxy-upload/images/txt.png +0 -0
  39. package/components/oxy-upload/images/video.png +0 -0
  40. package/components/oxy-upload/images/word.png +0 -0
  41. package/components/oxy-upload/index.scss +50 -0
  42. package/components/oxy-upload/oxy-upload.vue +93 -7
  43. package/components/oxy-upload/types.ts +22 -1
  44. package/components/oxy-virtual-scroll/index.scss +35 -0
  45. package/components/oxy-virtual-scroll/oxy-virtual-scroll.vue +184 -0
  46. package/components/oxy-virtual-scroll/types.ts +65 -0
  47. package/components/oxy-virtual-scroll/virtual-scroll.ts +81 -0
  48. package/global.d.ts +3 -0
  49. package/locale/lang/ar-SA.ts +2 -1
  50. package/locale/lang/en-US.ts +2 -1
  51. package/locale/lang/zh-CN.ts +2 -1
  52. package/package.json +1 -1
  53. package/tags.json +1 -1
  54. package/web-types.json +1 -1
@@ -4,6 +4,7 @@
4
4
  .oxy-theme-dark {
5
5
  @include b(drop-menu) {
6
6
  color: $-dark-color;
7
+
7
8
  @include e(list) {
8
9
  background-color: $-dark-background2;
9
10
  }
@@ -27,6 +28,7 @@
27
28
  text-align: center;
28
29
  background-color: #fff;
29
30
  }
31
+
30
32
  @include e(item) {
31
33
  flex: 1;
32
34
  min-width: 0;
@@ -40,11 +42,13 @@
40
42
  .oxy-drop-menu__item-title::after {
41
43
  opacity: 1;
42
44
  }
45
+
43
46
  :deep(.oxy-drop-menu__arrow) {
44
47
  transform: rotate(-180deg);
45
48
  transform-origin: center center;
46
49
  }
47
50
  }
51
+
48
52
  @include when(disabled) {
49
53
  color: $-drop-menu-disabled-color;
50
54
  }
@@ -18,7 +18,7 @@
18
18
  v-for="(child, index) in children"
19
19
  :key="index"
20
20
  @click="toggle(child)"
21
- :class="`oxy-drop-menu__item ${child.disabled ? 'is-disabled' : ''} ${child.$.exposed!.getShowPop() ? 'is-active' : ''}`"
21
+ :class="`oxy-drop-menu__item ${child.disabled ? 'is-disabled' : ''} ${child.$.exposed?.getShowPop() ? 'is-active' : ''}`"
22
22
  >
23
23
  <view class="oxy-drop-menu__item-title">
24
24
  <view class="oxy-drop-menu__item-title-text">{{ getDisplayTitle(child) }}</view>
@@ -60,6 +60,8 @@ const windowHeight = ref<number>(0)
60
60
  const modalStyle = computed(() => {
61
61
  return props.direction === 'down'
62
62
  ? `top: calc(var(--window-top) + ${offset.value}px); bottom: 0;`
63
+ : props.direction === 'bottom'
64
+ ? 'top: var(--window-top); bottom: 0;'
63
65
  : `top: 0; bottom: calc(var(--window-bottom) + ${offset.value}px)`
64
66
  })
65
67
 
@@ -95,7 +97,7 @@ linkChildren({ props, fold, offset })
95
97
  watch(
96
98
  () => props.direction,
97
99
  (newValue) => {
98
- if (!['up', 'down'].includes(newValue)) {
100
+ if (!['up', 'down', 'bottom'].includes(newValue)) {
99
101
  // eslint-disable-next-line quotes
100
102
  console.error("[Oxy ui] warning(oxy-drop-menu): direction must be 'up' or 'down'")
101
103
  }
@@ -142,7 +144,7 @@ function fold(child: any) {
142
144
  getRect(`#${dropMenuId.value}`, false, proxy).then((rect) => {
143
145
  if (!rect) return
144
146
  const { top, bottom } = rect
145
- if (props.direction === 'down') {
147
+ if (props.direction === 'down' || props.direction === 'bottom') {
146
148
  offset.value = Number(bottom)
147
149
  } else {
148
150
  offset.value = windowHeight.value - Number(top)
@@ -1,7 +1,7 @@
1
1
  import { type ExtractPropTypes, type InjectionKey, type Ref } from 'vue'
2
2
  import { baseProps, makeBooleanProp, makeNumberProp, makeStringProp } from '../common/props'
3
3
 
4
- export type DropDirection = 'up' | 'down'
4
+ export type DropDirection = 'up' | 'down' | 'bottom'
5
5
 
6
6
  export type DropMenuProvide = {
7
7
  props: Partial<DropMenuProps>
@@ -20,8 +20,8 @@
20
20
  color: $-drop-menu-item-color;
21
21
  width: 100%;
22
22
  z-index: 101;
23
-
24
- @include e(popup){
23
+
24
+ @include e(popup) {
25
25
  position: absolute;
26
26
  max-height: 80%;
27
27
  }
@@ -40,7 +40,7 @@
40
40
  }
41
41
  }
42
42
 
43
- @include e(title){
43
+ @include e(title) {
44
44
  display: block;
45
45
  }
46
46
 
@@ -51,7 +51,7 @@
51
51
  margin-left: 2px;
52
52
  }
53
53
 
54
- @include edeep(icon){
54
+ @include edeep(icon) {
55
55
  display: block;
56
56
  font-size: $-drop-menu-option-check-size;
57
57
  }
@@ -91,6 +91,8 @@ const positionStyle = computed(() => {
91
91
  style =
92
92
  dropMenu.props.direction === 'down'
93
93
  ? `top: calc(var(--window-top) + ${dropMenu.offset.value}px); bottom: 0;`
94
+ : dropMenu.props.direction === 'bottom'
95
+ ? 'top: calc(var(--window-top); bottom: 0;'
94
96
  : `top: 0; bottom: calc(var(--window-bottom) + ${dropMenu.offset.value}px)`
95
97
  } else {
96
98
  style = ''
@@ -0,0 +1,83 @@
1
+ @import '../common/abstracts/variable';
2
+ @import '../common/abstracts/mixin';
3
+
4
+ @include b(file-list) {
5
+ position: relative;
6
+ display: flex;
7
+ flex-wrap: wrap;
8
+ margin: 0 -8px;
9
+ @include e(item) {
10
+ position: relative;
11
+ width: calc(33.33% - 16px);
12
+ height: $-file-list-height;
13
+ margin: 0 8px 32px;
14
+ }
15
+ @include e(content) {
16
+ display: flex;
17
+ flex-direction: column;
18
+ justify-content: center;
19
+ align-items: center;
20
+ width: 100%;
21
+ height: 100%;
22
+ border: 1px solid $-color-border;
23
+ border-radius: 8px;
24
+ }
25
+ @include e(picture) {
26
+ position: relative;
27
+ display: block;
28
+ width: 100%;
29
+ height: 100%;
30
+ border-radius: 8px;
31
+ }
32
+ @include e(icon) {
33
+ width: 32px;
34
+ height: 32px;
35
+ }
36
+ @include e(name) {
37
+ display: block;
38
+ width: 100%;
39
+ font-size: $-upload-file-fs;
40
+ color: $-upload-file-color;
41
+ padding: 0 4px;
42
+ text-align: center;
43
+ margin-top: 8px;
44
+ white-space: nowrap;
45
+ overflow: hidden;
46
+ text-overflow: ellipsis;
47
+ }
48
+ :deep(.oxy-tooltip) {
49
+ width: 100%;
50
+ .oxy-tooltip__inner {
51
+ width: fit-content;
52
+ white-space: pre-wrap;
53
+ word-break: break-all;
54
+ }
55
+ }
56
+ &.oxy-file-list__list {
57
+ display: block;
58
+ margin: 0;
59
+ .oxy-file-list__list--item {
60
+ width: 100%;
61
+ background: #f8f9ff;
62
+ padding: 8px 12px;
63
+ border-radius: 4px;
64
+ display: flex;
65
+ flex-direction: row;
66
+ align-items: center;
67
+ .oxy-file-list__icon {
68
+ width: 24px;
69
+ height: 24px;
70
+ margin-right: 8px;
71
+ }
72
+ .oxy-file-list__name {
73
+ flex: 1;
74
+ text-align: left;
75
+ margin: 0;
76
+ padding: 0;
77
+ }
78
+ & + .oxy-file-list__list--item {
79
+ margin-top: 8px;
80
+ }
81
+ }
82
+ }
83
+ }
@@ -0,0 +1,213 @@
1
+ <template>
2
+ <view :class="['oxy-file-list', { 'oxy-file-list__list': props.type === 'list' }, customClass]">
3
+ <block v-if="props.type === 'list'">
4
+ <view v-for="(file, index) in props.data" :key="index" class="oxy-file-list__list--item" @click="onPreview(file)">
5
+ <image :src="getUploadImage(file)" mode="aspectFill" class="oxy-file-list__icon" />
6
+ <text class="oxy-file-list__name">{{ file.name }}</text>
7
+ </view>
8
+ </block>
9
+ <block v-else>
10
+ <view v-for="(file, index) in props.data" :key="index" class="oxy-file-list__item">
11
+ <view class="oxy-file-list__content">
12
+ <image v-if="isImage(file)" :src="file.url" mode="aspectFill" class="oxy-file-list__picture" @click="onPreview(file)" />
13
+ <image v-else :src="getUploadImage(file)" mode="aspectFill" class="oxy-file-list__icon" @click="onPreview(file)" />
14
+ </view>
15
+ <oxy-tooltip placement="top" :content="file.name">
16
+ <text class="oxy-file-list__name">{{ file.name }}</text>
17
+ </oxy-tooltip>
18
+ </view>
19
+ </block>
20
+ </view>
21
+ <oxy-video-preview ref="videoPreview"></oxy-video-preview>
22
+ </template>
23
+
24
+ <script lang="ts">
25
+ export default {
26
+ name: 'oxy-file-list',
27
+ options: {
28
+ addGlobalClass: true,
29
+ virtualHost: true,
30
+ styleIsolation: 'shared'
31
+ }
32
+ }
33
+ </script>
34
+ <script lang="ts" setup>
35
+ import ImgPdf from '../oxy-upload/images/pdf.png'
36
+ import ImgWord from '../oxy-upload/images/word.png'
37
+ import ImgAudio from '../oxy-upload/images/audio.png'
38
+ import ImgVideo from '../oxy-upload/images/video.png'
39
+ import ImgPic from '../oxy-upload/images/pic.png'
40
+ import ImgOther from '../oxy-upload/images/other.png'
41
+ import OxyVideoPreview from '../oxy-video-preview/oxy-video-preview.vue'
42
+ import { ref } from 'vue'
43
+ import { isImageUrl, isVideoUrl, isAudioUrl, isPdfUrl, isDocUrl } from '../common/util'
44
+ import { type FileListItem, fileListProps } from './types'
45
+ import type { VideoPreviewInstance } from '../oxy-video-preview/types'
46
+
47
+ const imgs: AnyObject = {
48
+ pdf: ImgPdf,
49
+ word: ImgWord,
50
+ audio: ImgAudio,
51
+ video: ImgVideo,
52
+ pic: ImgPic,
53
+ other: ImgOther
54
+ }
55
+
56
+ const props = defineProps(fileListProps)
57
+
58
+ const videoPreview = ref<VideoPreviewInstance>()
59
+ /**
60
+ * 预览图片
61
+ * @param file
62
+ */
63
+ function handlePreviewImage(file: FileListItem) {
64
+ const { onPreviewFail } = props
65
+ uni.previewImage({
66
+ urls: [file.url],
67
+ current: 0,
68
+ fail() {
69
+ if (onPreviewFail) {
70
+ onPreviewFail({
71
+ file
72
+ })
73
+ } else {
74
+ uni.showToast({ title: '预览图片失败', icon: 'none' })
75
+ }
76
+ }
77
+ })
78
+ }
79
+
80
+ /**
81
+ * 预览视频
82
+ * @param file
83
+ */
84
+ function handlePreviewVieo(file: FileListItem) {
85
+ const { onPreviewFail } = props
86
+ // #ifdef MP-WEIXIN
87
+ uni.previewMedia({
88
+ current: 0,
89
+ sources: [
90
+ {
91
+ url: file.url,
92
+ type: 'video',
93
+ poster: file.thumb
94
+ }
95
+ ],
96
+ fail() {
97
+ if (onPreviewFail) {
98
+ onPreviewFail({
99
+ file
100
+ })
101
+ } else {
102
+ uni.showToast({ title: '预览视频失败', icon: 'none' })
103
+ }
104
+ }
105
+ })
106
+ // #endif
107
+ // #ifndef MP-WEIXIN
108
+ videoPreview.value?.open({ url: file.url, poster: file.thumb, title: file.name })
109
+ // #endif
110
+ }
111
+
112
+ /**
113
+ * 预览文件
114
+ * @param file
115
+ */
116
+ function handlePreviewFile(file: FileListItem) {
117
+ uni.openDocument({
118
+ filePath: file.url,
119
+ showMenu: true
120
+ })
121
+ }
122
+
123
+ function onPreviewImage(file: FileListItem) {
124
+ const { beforePreview } = props
125
+ if (beforePreview) {
126
+ beforePreview({
127
+ file,
128
+ resolve: (isPass: boolean) => {
129
+ isPass && handlePreviewImage(file)
130
+ }
131
+ })
132
+ } else {
133
+ handlePreviewImage(file)
134
+ }
135
+ }
136
+
137
+ function onPreviewVideo(file: FileListItem) {
138
+ const { beforePreview } = props
139
+ if (beforePreview) {
140
+ beforePreview({
141
+ file,
142
+ resolve: (isPass: boolean) => {
143
+ isPass && handlePreviewVieo(file)
144
+ }
145
+ })
146
+ } else {
147
+ handlePreviewVieo(file)
148
+ }
149
+ }
150
+
151
+ function onPreviewFile(file: FileListItem) {
152
+ const { beforePreview } = props
153
+ if (beforePreview) {
154
+ beforePreview({
155
+ file,
156
+ resolve: (isPass: boolean) => {
157
+ isPass && handlePreviewFile(file)
158
+ }
159
+ })
160
+ } else {
161
+ handlePreviewFile(file)
162
+ }
163
+ }
164
+
165
+ function onPreview(file: FileListItem) {
166
+ if (isImage(file)) {
167
+ onPreviewImage(file)
168
+ } else if (isVideo(file)) {
169
+ onPreviewVideo(file)
170
+ } else {
171
+ onPreviewFile(file)
172
+ }
173
+ }
174
+
175
+ function isVideo(file: FileListItem) {
176
+ return (file.name && isVideoUrl(file.name)) || isVideoUrl(file.url)
177
+ }
178
+
179
+ function isImage(file: FileListItem) {
180
+ return (file.name && isImageUrl(file.name)) || isImageUrl(file.url)
181
+ }
182
+
183
+ function isAudio(file: FileListItem) {
184
+ return (file.name && isAudioUrl(file.name)) || isAudioUrl(file.url)
185
+ }
186
+
187
+ function isPdf(file: FileListItem) {
188
+ return (file.name && isPdfUrl(file.name)) || isPdfUrl(file.url)
189
+ }
190
+
191
+ function isDoc(file: FileListItem) {
192
+ return (file.name && isDocUrl(file.name)) || isDocUrl(file.url)
193
+ }
194
+
195
+ function getUploadImage(file: FileListItem) {
196
+ if (isPdf(file)) {
197
+ return imgs.pdf
198
+ } else if (isDoc(file)) {
199
+ return imgs.word
200
+ } else if (isAudio(file)) {
201
+ return imgs.audio
202
+ } else if (isVideo(file)) {
203
+ return imgs.video
204
+ } else if (isImage(file)) {
205
+ return imgs.pic
206
+ } else {
207
+ return imgs.other
208
+ }
209
+ }
210
+ </script>
211
+ <style lang="scss" scoped>
212
+ @import './index.scss';
213
+ </style>
@@ -0,0 +1,54 @@
1
+ import type { ExtractPropTypes, PropType } from 'vue'
2
+ import { baseProps, makeArrayProp, makeStringProp } from '../common/props'
3
+
4
+ export type FileListItem = {
5
+ [key: string]: any
6
+ // 文件名称
7
+ name?: string
8
+ // 文件地址
9
+ url: string
10
+ }
11
+
12
+ export type FileListType = 'card' | 'list'
13
+
14
+ export type FileListBeforePreviewOption = {
15
+ file: FileListItem
16
+ resolve: (isPass: boolean) => void
17
+ }
18
+ export type FileListBeforePreview = (option: FileListBeforePreviewOption) => void
19
+
20
+ export type FileListOnPreviewFailOption = {
21
+ file: FileListItem
22
+ }
23
+ export type FileListOnPreviewFail = (option: FileListOnPreviewFailOption) => void
24
+
25
+ export const fileListProps = {
26
+ ...baseProps,
27
+
28
+ /**
29
+ * 文件列表
30
+ * 类型:array
31
+ * 默认值:[]
32
+ */
33
+ data: makeArrayProp<FileListItem>(),
34
+ /**
35
+ * 文件列表类型
36
+ * 类型:string
37
+ * 默认值:'card'
38
+ */
39
+ type: makeStringProp<FileListType>('list'),
40
+ /**
41
+ * 文件预览前的钩子,参数为预览的文件,若返回false或者返回Promise且被reject,则停止预览。
42
+ * 类型:function({file,resolve})
43
+ * 默认值:-
44
+ */
45
+ beforePreview: Function as PropType<FileListBeforePreview>,
46
+ /**
47
+ * 预览失败执行操作
48
+ * 类型:function({file})
49
+ * 默认值:-
50
+ */
51
+ onPreviewFail: Function as PropType<FileListOnPreviewFail>
52
+ }
53
+
54
+ export type CornerProps = ExtractPropTypes<typeof fileListProps>
@@ -0,0 +1,4 @@
1
+ @import './../common/abstracts/_mixin.scss';
2
+ @import './../common/abstracts/variable.scss';
3
+ @include b(list) {
4
+ }
@@ -0,0 +1,125 @@
1
+ <template>
2
+ <view :class="['oxy-list', customClass]" :style="customStyle">
3
+ <oxy-virtual-scroll
4
+ ref="virtualScrollRef"
5
+ :is-virtual="virtual"
6
+ :data="data"
7
+ :height="height"
8
+ :item-height="itemHeight"
9
+ :id-key="idKey"
10
+ :show-back-to-top="showBackToTop"
11
+ :back-to-top-threshold="backToTopThreshold"
12
+ :refresher-triggered="triggered"
13
+ v-bind="{ ...defaultscrollConfig, ...scrollConfig }"
14
+ @scroll-to-upper="onScrollToUpper"
15
+ @scroll-to-lower="onScrollToLower"
16
+ @scroll="onScroll"
17
+ @refresherrefresh="onRefresh"
18
+ @refresherrestore="onRestore"
19
+ @refresherabort="onAbort"
20
+ >
21
+ <template #item="{ item }">
22
+ <slot name="item" :item="item"></slot>
23
+ </template>
24
+ <template #bottom>
25
+ <oxy-loadmore
26
+ v-if="loadmoreState"
27
+ :state="loadmoreState"
28
+ :loading-text="loadingText"
29
+ :finished-text="finishedText"
30
+ :error-text="errorText"
31
+ :loading-props="loadingProps"
32
+ @reload="onReload"
33
+ />
34
+ </template>
35
+ </oxy-virtual-scroll>
36
+ </view>
37
+ </template>
38
+
39
+ <script lang="ts">
40
+ export default {
41
+ name: 'oxy-list',
42
+ options: {
43
+ addGlobalClass: true,
44
+ virtualHost: true,
45
+ styleIsolation: 'shared'
46
+ }
47
+ }
48
+ </script>
49
+
50
+ <script lang="ts" setup>
51
+ import { computed, ref } from 'vue'
52
+ import { type ListExpose, listProps } from './types'
53
+ import type {
54
+ ScrollViewOnRefresherabortEvent,
55
+ ScrollViewOnRefresherrefreshEvent,
56
+ ScrollViewOnRefresherrestoreEvent,
57
+ ScrollViewOnScrollEvent
58
+ } from '@uni-helper/uni-app-types/index'
59
+ import type { VirtualScrollInstance } from '../oxy-virtual-scroll/types'
60
+
61
+ const props = defineProps(listProps)
62
+
63
+ const emit = defineEmits(['scroll-to-lower', 'reload', 'scroll-to-upper', 'scroll', 'refresh', 'restore', 'abort'])
64
+ const virtualScrollRef = ref<VirtualScrollInstance | null>(null)
65
+
66
+ const defaultscrollConfig = {
67
+ refresherEnabled: true,
68
+ refresherThreshold: 60,
69
+ scrollWithAnimation: false
70
+ }
71
+
72
+ const onScrollToLower = async () => {
73
+ emit('scroll-to-lower')
74
+ }
75
+ const onScrollToUpper = async () => {
76
+ emit('scroll-to-upper')
77
+ }
78
+ const onReload = async () => {
79
+ emit('reload')
80
+ }
81
+ const onScroll = async (event: ScrollViewOnScrollEvent) => {
82
+ emit('scroll', event)
83
+ }
84
+
85
+ // 下拉刷新
86
+ const onRefresh = (e: ScrollViewOnRefresherrefreshEvent) => {
87
+ emit('refresh', e)
88
+ }
89
+
90
+ // 下拉刷新被复位
91
+ const onRestore = (e: ScrollViewOnRefresherrestoreEvent) => {
92
+ emit('restore', e)
93
+ }
94
+
95
+ // 下拉刷新被中止
96
+ const onAbort = (e: ScrollViewOnRefresherabortEvent) => {
97
+ emit('abort', e)
98
+ }
99
+ const scrollToTop = () => {
100
+ virtualScrollRef.value?.scrollToTop()
101
+ }
102
+ const scrollToBottom = () => {
103
+ virtualScrollRef.value?.scrollToBottom()
104
+ }
105
+ const scrollToPosition = (position: number | string) => {
106
+ virtualScrollRef.value?.scrollToPosition(position)
107
+ }
108
+ const scrollToElement = (item: any) => {
109
+ virtualScrollRef.value?.scrollToElement(item)
110
+ }
111
+ const scrollToElementById = (id: string | number) => {
112
+ virtualScrollRef.value?.scrollToElementById(id)
113
+ }
114
+ defineExpose<ListExpose>({
115
+ scrollToTop,
116
+ scrollToBottom,
117
+ scrollToPosition,
118
+ scrollToElement,
119
+ scrollToElementById
120
+ })
121
+ </script>
122
+
123
+ <style lang="scss" scoped>
124
+ @import './index.scss';
125
+ </style>
@@ -0,0 +1,50 @@
1
+ import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'
2
+ import { makeBooleanProp } from '../common/props'
3
+ import { type LoadMoreState } from '../oxy-loadmore/types'
4
+ import { type LoadingProps } from '../oxy-loading/types'
5
+ import { virtualScrollProps } from '../oxy-virtual-scroll/types'
6
+
7
+ export const listProps = {
8
+ ...virtualScrollProps,
9
+
10
+ loadmoreState: String as PropType<LoadMoreState>,
11
+
12
+ /**
13
+ * 加载提示文案
14
+ */
15
+ loadingText: String,
16
+ /**
17
+ * 全部加载完的提示文案
18
+ */
19
+ finishedText: String,
20
+ /**
21
+ * 加载失败的提示文案
22
+ */
23
+ errorText: String,
24
+ /**
25
+ * 加载中loading组件的属性
26
+ * 参考loading组件
27
+ */
28
+ loadingProps: Object as PropType<Partial<LoadingProps>>,
29
+ triggered: makeBooleanProp(false),
30
+ scrollConfig: {
31
+ type: Object as PropType<ScrollConfig>,
32
+ default: () => ({})
33
+ }
34
+ }
35
+ export type ScrollConfig = {
36
+ refresherEnabled: boolean
37
+ refresherThreshold: number
38
+ refresherBackground: string
39
+ animation: boolean
40
+ [key: string]: any
41
+ }
42
+ export type ListExpose = {
43
+ scrollToTop: () => void
44
+ scrollToBottom: () => void
45
+ scrollToPosition: (position: number | string) => void
46
+ scrollToElement: (item: any) => void
47
+ scrollToElementById: (id: string | number) => void
48
+ }
49
+ export type ListProps = ExtractPropTypes<typeof listProps>
50
+ export type ListInstance = ComponentPublicInstance<ListProps, ListExpose>
@@ -25,7 +25,7 @@
25
25
  display: flex;
26
26
  flex-flow: row nowrap;
27
27
  align-items: center;
28
- height: calc($-slider-handle-radius * 3);
28
+ // height: calc($-slider-handle-radius * 3);
29
29
 
30
30
  @include e(label-min, label-max) {
31
31
  font-size: $-slider-fs;
@@ -95,4 +95,4 @@
95
95
  color: $-slider-disabled-color;
96
96
  }
97
97
  }
98
- }
98
+ }
@@ -17,7 +17,6 @@
17
17
  padding: $-swiper-item-padding;
18
18
 
19
19
  @include m(slot) {
20
- // 问题来自 https://github.com/dcloudio/uni-app/issues/4629,支付宝小程序不支持属性选择器
21
20
  /* #ifdef MP */
22
21
  :deep() {
23
22
  /* #ifdef MP-WEIXIN */
@@ -50,4 +49,4 @@
50
49
  color: $-swiper-item-text-color;
51
50
  font-size: $-swiper-item-text-fs;
52
51
  }
53
- }
52
+ }
@@ -179,10 +179,6 @@ const isRequired = computed(() => {
179
179
 
180
180
  // 当前文本域文字长度
181
181
  const currentLength = computed(() => {
182
- /**
183
- * 使用Array.from处理多码元字符以获取正确的长度
184
- * @link https://github.com/Moonofweisheng/oxy-uni-ui/issues/933
185
- */
186
182
  return Array.from(String(formatValue(props.modelValue))).length
187
183
  })
188
184