xt-element-ui 2.2.2 → 2.2.4

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 (153) hide show
  1. package/README.md +140 -192
  2. package/docs/README.md +162 -81
  3. package/docs/components/base/theme.md +248 -0
  4. package/docs/components/base/xt-button.md +11 -4
  5. package/docs/components/base/xt-card.md +5 -11
  6. package/docs/components/base/xt-config-provider.md +2 -0
  7. package/docs/components/base/xt-flow.md +404 -0
  8. package/docs/components/base/xt-list.md +1 -1
  9. package/docs/components/base/xt-multi.md +5 -5
  10. package/docs/components/base/xt-scroll-arrow.md +87 -1
  11. package/docs/components/base/xt-scroll.md +237 -0
  12. package/docs/components/business/xt-chart.md +1 -0
  13. package/docs/components/utils/config.md +18 -4
  14. package/docs/components/utils/theme.md +280 -183
  15. package/lib/index.common.1.js +4 -26
  16. package/lib/index.common.2.js +1 -1
  17. package/lib/index.common.js +4577 -109925
  18. package/lib/index.css +1 -1
  19. package/lib/index.umd.1.js +4 -26
  20. package/lib/index.umd.2.js +1 -1
  21. package/lib/index.umd.js +4583 -109930
  22. package/lib/index.umd.min.1.js +1 -1
  23. package/lib/index.umd.min.js +1 -1
  24. package/lib/theme/element-overrides.css +607 -0
  25. package/lib/theme/element-vars.css +280 -0
  26. package/lib/xt-badge/xt-badge.common.js +1 -1
  27. package/lib/xt-badge/xt-badge.css +1 -1
  28. package/lib/xt-badge/xt-badge.umd.js +1 -1
  29. package/lib/xt-button/xt-button.common.js +13 -8
  30. package/lib/xt-button/xt-button.css +1 -1
  31. package/lib/xt-button/xt-button.umd.js +13 -8
  32. package/lib/xt-button/xt-button.umd.min.js +1 -1
  33. package/lib/xt-card/xt-card.common.js +5 -5
  34. package/lib/xt-card/xt-card.umd.js +5 -5
  35. package/lib/xt-card/xt-card.umd.min.js +1 -1
  36. package/lib/xt-card-item/xt-card-item.common.js +4 -4
  37. package/lib/xt-card-item/xt-card-item.umd.js +4 -4
  38. package/lib/xt-card-item/xt-card-item.umd.min.js +1 -1
  39. package/lib/xt-chart/xt-chart.common.js +1969 -108924
  40. package/lib/xt-chart/xt-chart.css +1 -1
  41. package/lib/xt-chart/xt-chart.umd.js +1975 -108929
  42. package/lib/xt-chart/xt-chart.umd.min.js +1 -1
  43. package/lib/xt-config-provider/xt-config-provider.common.js +561 -107504
  44. package/lib/xt-config-provider/xt-config-provider.css +1 -1
  45. package/lib/xt-config-provider/xt-config-provider.umd.js +567 -107509
  46. package/lib/xt-config-provider/xt-config-provider.umd.min.js +1 -1
  47. package/lib/xt-date-picker/xt-date-picker.common.1.js +4 -26
  48. package/lib/xt-date-picker/xt-date-picker.common.2.js +1 -1
  49. package/lib/xt-date-picker/xt-date-picker.common.js +1 -47
  50. package/lib/xt-date-picker/xt-date-picker.css +1 -1
  51. package/lib/xt-date-picker/xt-date-picker.umd.1.js +4 -26
  52. package/lib/xt-date-picker/xt-date-picker.umd.2.js +1 -1
  53. package/lib/xt-date-picker/xt-date-picker.umd.js +1 -47
  54. package/lib/xt-date-picker/xt-date-picker.umd.min.1.js +1 -1
  55. package/lib/xt-date-picker/xt-date-picker.umd.min.js +1 -1
  56. package/lib/xt-flex-box/xt-flex-box.common.js +1 -1
  57. package/lib/xt-flex-box/xt-flex-box.umd.js +1 -1
  58. package/lib/xt-flow/demo.html +10 -0
  59. package/lib/xt-flow/index.js +1 -0
  60. package/lib/xt-flow/xt-flow.common.js +638 -0
  61. package/lib/xt-flow/xt-flow.css +1 -0
  62. package/lib/xt-flow/xt-flow.umd.js +648 -0
  63. package/lib/xt-flow/xt-flow.umd.min.js +1 -0
  64. package/lib/xt-form-schema/xt-form-schema.common.js +1 -1
  65. package/lib/xt-form-schema/xt-form-schema.umd.js +1 -1
  66. package/lib/xt-grid-box/xt-grid-box.common.js +1 -1
  67. package/lib/xt-grid-box/xt-grid-box.umd.js +1 -1
  68. package/lib/xt-grid-item/xt-grid-item.common.js +1 -1
  69. package/lib/xt-grid-item/xt-grid-item.umd.js +1 -1
  70. package/lib/xt-icon/xt-icon.common.js +1 -1
  71. package/lib/xt-icon/xt-icon.umd.js +1 -1
  72. package/lib/xt-input/xt-input.common.js +1 -1
  73. package/lib/xt-input/xt-input.umd.js +1 -1
  74. package/lib/xt-list/xt-list.common.js +457 -118
  75. package/lib/xt-list/xt-list.css +1 -1
  76. package/lib/xt-list/xt-list.umd.js +457 -118
  77. package/lib/xt-list/xt-list.umd.min.js +1 -1
  78. package/lib/xt-map/xt-map.common.js +1 -1
  79. package/lib/xt-map/xt-map.umd.js +1 -1
  80. package/lib/xt-map-provider/xt-map-provider.common.js +1 -1
  81. package/lib/xt-map-provider/xt-map-provider.umd.js +1 -1
  82. package/lib/xt-page/xt-page.common.js +1 -1
  83. package/lib/xt-page/xt-page.umd.js +1 -1
  84. package/lib/xt-progress/xt-progress.common.js +1 -1
  85. package/lib/xt-progress/xt-progress.umd.js +1 -1
  86. package/lib/xt-scroll/demo.html +10 -0
  87. package/lib/xt-scroll/index.js +1 -0
  88. package/lib/xt-scroll/xt-scroll.common.js +551 -0
  89. package/lib/xt-scroll/xt-scroll.css +1 -0
  90. package/lib/xt-scroll/xt-scroll.umd.js +561 -0
  91. package/lib/xt-scroll/xt-scroll.umd.min.js +1 -0
  92. package/lib/xt-scroll-arrow/xt-scroll-arrow.common.js +591 -170
  93. package/lib/xt-scroll-arrow/xt-scroll-arrow.css +1 -1
  94. package/lib/xt-scroll-arrow/xt-scroll-arrow.umd.js +591 -170
  95. package/lib/xt-scroll-arrow/xt-scroll-arrow.umd.min.js +1 -1
  96. package/lib/xt-select-tree/xt-select-tree.common.js +1 -1
  97. package/lib/xt-select-tree/xt-select-tree.umd.js +1 -1
  98. package/lib/xt-step-price/xt-step-price.common.js +2 -2
  99. package/lib/xt-step-price/xt-step-price.umd.js +2 -2
  100. package/lib/xt-step-price-item/xt-step-price-item.common.js +1 -1
  101. package/lib/xt-step-price-item/xt-step-price-item.umd.js +1 -1
  102. package/lib/xt-tab-pane/xt-tab-pane.common.js +1 -1
  103. package/lib/xt-tab-pane/xt-tab-pane.umd.js +1 -1
  104. package/lib/xt-table/xt-table.common.js +2 -2
  105. package/lib/xt-table/xt-table.umd.js +2 -2
  106. package/lib/xt-tabs/xt-tabs.common.js +1 -1
  107. package/lib/xt-tabs/xt-tabs.umd.js +1 -1
  108. package/lib/xt-text/xt-text.common.js +1 -1
  109. package/lib/xt-text/xt-text.css +1 -1
  110. package/lib/xt-text/xt-text.umd.js +1 -1
  111. package/lib/xt-time/xt-time.common.js +1 -1
  112. package/lib/xt-time/xt-time.umd.js +1 -1
  113. package/lib/xt-transfer-tree/xt-transfer-tree.common.js +1 -1
  114. package/lib/xt-transfer-tree/xt-transfer-tree.umd.js +1 -1
  115. package/lib/xt-upload/xt-upload.common.js +11 -11
  116. package/lib/xt-upload/xt-upload.umd.js +12 -12
  117. package/lib/xt-upload/xt-upload.umd.min.js +1 -1
  118. package/package.json +6 -5
  119. package/src/components/index.scss +7 -1
  120. package/src/components/theme/element-overrides.css +607 -0
  121. package/src/components/theme/element-vars.css +280 -0
  122. package/src/components/theme/iframe-injector.js +502 -0
  123. package/src/components/theme/index.js +64 -0
  124. package/src/components/xt-badge/style/index.scss +6 -6
  125. package/src/components/xt-button/index.vue +11 -6
  126. package/src/components/xt-button/style/index.scss +7 -5
  127. package/src/components/xt-card/index.vue +3 -3
  128. package/src/components/xt-card-item/index.vue +2 -2
  129. package/src/components/xt-chart/XtMulti.vue +8 -18
  130. package/src/components/xt-chart/XtPie.vue +1 -0
  131. package/src/components/xt-chart/utils.js +84 -50
  132. package/src/components/xt-config-provider/index.vue +56 -54
  133. package/src/components/xt-config-provider/style/index.scss +0 -11
  134. package/src/components/xt-date-picker/component/RangeDate.vue +1 -29
  135. package/src/components/xt-date-picker/style/index.scss +79 -54
  136. package/src/components/xt-flow/flowable-parser.js +244 -0
  137. package/src/components/xt-flow/index.js +8 -0
  138. package/src/components/xt-flow/index.vue +226 -0
  139. package/src/components/xt-flow/style/index.scss +359 -0
  140. package/src/components/xt-list/index.vue +23 -12
  141. package/src/components/xt-scroll/index.js +9 -0
  142. package/src/components/xt-scroll/index.vue +363 -0
  143. package/src/components/xt-scroll/style/index.scss +107 -0
  144. package/src/components/xt-scroll-arrow/index.vue +200 -83
  145. package/src/components/xt-scroll-arrow/style/index.scss +16 -5
  146. package/src/components/xt-text/style/index.scss +6 -6
  147. package/src/index.js +15 -13
  148. package/src/styles/css-variables.scss +73 -1
  149. package/src/utils/color.js +105 -0
  150. package/src/utils/index.js +456 -468
  151. package/src/utils/theme-vars.js +134 -0
  152. package/lib/css/1.87a493be.css +0 -1
  153. package/lib/xt-date-picker/css/1.87a493be.css +0 -1
@@ -0,0 +1,363 @@
1
+ <template>
2
+ <div class="xt-scroll" :class="[`xt-scroll--${scrollDirection}`]" :style="containerStyle">
3
+ <!-- 原生滚动容器 -->
4
+ <div
5
+ ref="scrollWrap"
6
+ class="xt-scroll__wrap"
7
+ :class="[`xt-scroll__wrap--${scrollDirection}`]"
8
+ @scroll="onScroll"
9
+ >
10
+ <!-- 虚拟滚动模式 -->
11
+ <div v-if="vScroll" class="xt-scroll__virtual" :style="virtualWrapperStyle">
12
+ <!-- 虚拟滚动 phantom -->
13
+ <div
14
+ v-if="scrollDirection === 'vertical'"
15
+ class="xt-scroll__phantom"
16
+ :style="{ height: totalSize + 'px' }"
17
+ >
18
+ <div :style="{ transform: `translateY(${offsetStart}px)` }">
19
+ <template v-for="(item, index) in visibleData">
20
+ <div
21
+ :key="getItemKey(item, index)"
22
+ class="xt-scroll__item"
23
+ :style="itemStyle"
24
+ :class="itemClassName"
25
+ >
26
+ <slot name="item" :item="item" :index="getOriginalIndex(index)">
27
+ {{ item }}
28
+ </slot>
29
+ </div>
30
+ </template>
31
+ </div>
32
+ </div>
33
+
34
+ <!-- 横向虚拟滚动 phantom -->
35
+ <div
36
+ v-else-if="scrollDirection === 'horizontal'"
37
+ class="xt-scroll__phantom"
38
+ :style="{ width: totalSize + 'px' }"
39
+ >
40
+ <div :style="{ transform: `translateX(${offsetStart}px)` }">
41
+ <template v-for="(item, index) in visibleData">
42
+ <div
43
+ :key="getItemKey(item, index)"
44
+ class="xt-scroll__item"
45
+ :style="itemStyle"
46
+ :class="itemClassName"
47
+ >
48
+ <slot name="item" :item="item" :index="getOriginalIndex(index)">
49
+ {{ item }}
50
+ </slot>
51
+ </div>
52
+ </template>
53
+ </div>
54
+ </div>
55
+ </div>
56
+
57
+ <!-- 空状态 -->
58
+ <div v-if="vScroll && (!data || !data.length) && !loading" class="xt-scroll__empty">
59
+ <slot name="empty">
60
+ <span>{{ emptyText }}</span>
61
+ </slot>
62
+ </div>
63
+
64
+ <!-- 加载状态 -->
65
+ <div v-if="loading" class="xt-scroll__loading">
66
+ <slot name="loading">
67
+ <i class="el-icon-loading"></i>
68
+ <span>加载中...</span>
69
+ </slot>
70
+ </div>
71
+
72
+ <!-- 非虚拟滚动模式:默认插槽 -->
73
+ <div v-if="!vScroll" class="xt-scroll__default">
74
+ <slot></slot>
75
+ </div>
76
+
77
+ <!-- 触底/触顶加载更多 -->
78
+ <div v-if="vScroll && showLoadMore && !loading" class="xt-scroll__loadmore" @click="onLoadMore">
79
+ <el-button type="text" :loading="loadMoreLoading">
80
+ {{ loadMoreText }}
81
+ </el-button>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </template>
86
+
87
+ <script>
88
+ export default {
89
+ name: 'XtScroll',
90
+
91
+ props: {
92
+ // ========== 虚拟滚动配置 ==========
93
+ /** 是否启用虚拟滚动 */
94
+ vScroll: { type: Boolean, default: false },
95
+ /** 数据源 */
96
+ data: { type: Array, default: () => [] },
97
+ /** 每个 item 的固定尺寸(px),纵向为高度,横向为宽度 */
98
+ itemSize: { type: Number, default: 50 },
99
+ /** item 的唯一键字段名 */
100
+ keyField: { type: String, default: 'id' },
101
+ /** 预渲染缓冲区大小(item 数量) */
102
+ bufferSize: { type: Number, default: 5 },
103
+ /** 虚拟滚动方向 */
104
+ scrollDirection: {
105
+ type: String,
106
+ default: 'vertical',
107
+ validator: (v) => ['vertical', 'horizontal'].includes(v)
108
+ },
109
+ /** item 的自定义 CSS 类名 */
110
+ itemClassName: { type: String, default: '' },
111
+
112
+ // ========== 容器尺寸 ==========
113
+ height: { type: [Number, String], default: '' },
114
+ maxHeight: { type: [Number, String], default: '' },
115
+ width: { type: [Number, String], default: '' },
116
+ maxWidth: { type: [Number, String], default: '' },
117
+
118
+ // ========== 状态 ==========
119
+ loading: { type: Boolean, default: false },
120
+ emptyText: { type: String, default: '暂无数据' },
121
+
122
+ // ========== 加载更多 ==========
123
+ loadMore: { type: Boolean, default: false },
124
+ loadMoreText: { type: String, default: '加载更多' },
125
+ loadMoreLoading: { type: Boolean, default: false }
126
+ },
127
+
128
+ data() {
129
+ return {
130
+ scrollPos: 0,
131
+ containerSize: 0,
132
+ resizeObserver: null,
133
+ rafId: null
134
+ }
135
+ },
136
+
137
+ computed: {
138
+ containerStyle() {
139
+ const style = {}
140
+ if (this.height) {
141
+ style.height = typeof this.height === 'number' ? this.height + 'px' : this.height
142
+ }
143
+ if (this.maxHeight) {
144
+ style.maxHeight = typeof this.maxHeight === 'number' ? this.maxHeight + 'px' : this.maxHeight
145
+ }
146
+ if (this.width) {
147
+ style.width = typeof this.width === 'number' ? this.width + 'px' : this.width
148
+ }
149
+ if (this.maxWidth) {
150
+ style.maxWidth = typeof this.maxWidth === 'number' ? this.maxWidth + 'px' : this.maxWidth
151
+ }
152
+ return style
153
+ },
154
+
155
+ virtualWrapperStyle() {
156
+ const style = {}
157
+ if (this.scrollDirection === 'horizontal') {
158
+ style.height = '100%'
159
+ }
160
+ return style
161
+ },
162
+
163
+ itemStyle() {
164
+ return this.scrollDirection === 'vertical'
165
+ ? { height: this.itemSize + 'px' }
166
+ : { width: this.itemSize + 'px', display: 'inline-block' }
167
+ },
168
+
169
+ /** 数据总条数 */
170
+ dataCount() {
171
+ return (this.data && this.data.length) || 0
172
+ },
173
+
174
+ /** 总滚动尺寸 */
175
+ totalSize() {
176
+ return this.dataCount * this.itemSize
177
+ },
178
+
179
+ /** 虚拟滚动:可见范围起始索引 */
180
+ visibleStartIndex() {
181
+ if (!this.vScroll) return 0
182
+ const start = Math.floor(this.scrollPos / this.itemSize)
183
+ return Math.max(0, start - this.bufferSize)
184
+ },
185
+
186
+ /** 虚拟滚动:可见范围结束索引 */
187
+ visibleEndIndex() {
188
+ if (!this.vScroll) return this.dataCount
189
+ const visibleCount = Math.ceil(this.containerSize / this.itemSize)
190
+ const end = Math.ceil(this.scrollPos / this.itemSize) + visibleCount
191
+ return Math.min(this.dataCount, end + this.bufferSize)
192
+ },
193
+
194
+ /** 可见数据 */
195
+ visibleData() {
196
+ if (!this.vScroll || !this.data) return this.data || []
197
+ return this.data.slice(this.visibleStartIndex, this.visibleEndIndex)
198
+ },
199
+
200
+ /** 偏移量(px) */
201
+ offsetStart() {
202
+ return this.visibleStartIndex * this.itemSize
203
+ },
204
+
205
+ /** 是否显示加载更多 */
206
+ showLoadMore() {
207
+ if (!this.loadMore || !this.dataCount) return false
208
+ if (this.scrollDirection === 'vertical') {
209
+ return this.scrollPos + this.containerSize >= this.totalSize - this.itemSize * 2
210
+ }
211
+ return false
212
+ }
213
+ },
214
+
215
+ watch: {
216
+ data: {
217
+ handler() {
218
+ this.$nextTick(() => {
219
+ this.updateContainerSize()
220
+ })
221
+ }
222
+ },
223
+ vScroll(val) {
224
+ if (val) {
225
+ this.$nextTick(() => {
226
+ this.updateContainerSize()
227
+ this.bindResizeObserver()
228
+ })
229
+ }
230
+ }
231
+ },
232
+
233
+ mounted() {
234
+ this.$nextTick(() => {
235
+ this.updateContainerSize()
236
+ if (this.vScroll) {
237
+ this.bindResizeObserver()
238
+ }
239
+ })
240
+ },
241
+
242
+ beforeDestroy() {
243
+ this.unbindResizeObserver()
244
+ if (this.rafId && typeof cancelAnimationFrame !== 'undefined') {
245
+ cancelAnimationFrame(this.rafId)
246
+ this.rafId = null
247
+ }
248
+ },
249
+
250
+ methods: {
251
+ // ========== 虚拟滚动 ==========
252
+ onScroll() {
253
+ const wrap = this.$refs.scrollWrap
254
+ if (!wrap) return
255
+
256
+ const pos = this.scrollDirection === 'vertical' ? wrap.scrollTop : wrap.scrollLeft
257
+ this.scrollPos = pos
258
+
259
+ // 对外 emit scroll 事件,传递 scrollTop/scrollLeft 方便父组件使用
260
+ this.$emit('scroll', {
261
+ scrollTop: wrap.scrollTop,
262
+ scrollLeft: wrap.scrollLeft
263
+ })
264
+
265
+ if (this.rafId) return
266
+ if (typeof requestAnimationFrame === 'undefined') return
267
+ this.rafId = requestAnimationFrame(() => {
268
+ this.$forceUpdate()
269
+ this.rafId = null
270
+ })
271
+ },
272
+
273
+ getItemKey(item, index) {
274
+ if (item && typeof item === 'object' && this.keyField && item[this.keyField] != null) {
275
+ return item[this.keyField]
276
+ }
277
+ return `vitem_${this.visibleStartIndex + index}`
278
+ },
279
+
280
+ getOriginalIndex(index) {
281
+ return this.visibleStartIndex + index
282
+ },
283
+
284
+ // ========== 容器尺寸 ==========
285
+ updateContainerSize() {
286
+ const wrap = this.$refs.scrollWrap
287
+ if (!wrap) return
288
+
289
+ this.containerSize = this.scrollDirection === 'vertical'
290
+ ? wrap.clientHeight
291
+ : wrap.clientWidth
292
+ },
293
+
294
+ bindResizeObserver() {
295
+ if (typeof ResizeObserver === 'undefined') return
296
+ this.unbindResizeObserver()
297
+
298
+ const wrap = this.$refs.scrollWrap
299
+ if (!wrap) return
300
+
301
+ this.resizeObserver = new ResizeObserver(() => {
302
+ this.updateContainerSize()
303
+ })
304
+ this.resizeObserver.observe(wrap)
305
+ },
306
+
307
+ unbindResizeObserver() {
308
+ if (this.resizeObserver) {
309
+ this.resizeObserver.disconnect()
310
+ this.resizeObserver = null
311
+ }
312
+ },
313
+
314
+ // ========== 加载更多 ==========
315
+ onLoadMore() {
316
+ this.$emit('load-more')
317
+ },
318
+
319
+ // ========== 对外暴露方法 ==========
320
+ /** 获取原生滚动容器 DOM 元素 */
321
+ getScrollContainer() {
322
+ return this.$refs.scrollWrap
323
+ },
324
+
325
+ /** 滚动到指定位置 */
326
+ scrollTo(pos, behavior) {
327
+ const wrap = this.$refs.scrollWrap
328
+ if (!wrap) return
329
+
330
+ const opts = behavior && typeof behavior === 'string'
331
+ ? { behavior }
332
+ : { behavior: 'smooth' }
333
+
334
+ if (this.scrollDirection === 'vertical') {
335
+ wrap.scrollTo({ top: pos, ...opts })
336
+ } else {
337
+ wrap.scrollTo({ left: pos, ...opts })
338
+ }
339
+ },
340
+
341
+ /** 滚动到指定索引的 item */
342
+ scrollToItem(index) {
343
+ const pos = index * this.itemSize
344
+ this.scrollTo(pos)
345
+ },
346
+
347
+ /** 滚动到顶部/左侧 */
348
+ scrollToStart() {
349
+ this.scrollTo(0)
350
+ },
351
+
352
+ /** 滚动到底部/右侧 */
353
+ scrollToEnd() {
354
+ this.scrollTo(this.totalSize)
355
+ },
356
+
357
+ /** 获取当前滚动位置 */
358
+ getScrollPos() {
359
+ return this.scrollPos
360
+ }
361
+ }
362
+ }
363
+ </script>
@@ -0,0 +1,107 @@
1
+ @import '../../../styles/variables.scss';
2
+
3
+ .xt-scroll {
4
+ width: 100%;
5
+ height: 100%;
6
+
7
+ // 原生滚动容器
8
+ &__wrap {
9
+ width: 100%;
10
+ height: 100%;
11
+ overflow: auto;
12
+
13
+ // 纵向滚动
14
+ &--vertical {
15
+ overflow-x: hidden;
16
+ overflow-y: auto;
17
+ }
18
+
19
+ // 横向滚动
20
+ &--horizontal {
21
+ overflow-x: auto;
22
+ overflow-y: hidden;
23
+ }
24
+ }
25
+
26
+ // 虚拟滚动容器
27
+ &__virtual {
28
+ width: 100%;
29
+ position: relative;
30
+ }
31
+
32
+ &__phantom {
33
+ position: relative;
34
+ box-sizing: border-box;
35
+ }
36
+
37
+ &__item {
38
+ box-sizing: border-box;
39
+ overflow: hidden;
40
+ }
41
+
42
+ // 默认内容区
43
+ &__default {
44
+ width: 100%;
45
+ }
46
+
47
+ // 空状态
48
+ &__empty {
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+ padding: 48px 0;
53
+ color: #909399;
54
+ font-size: 14px;
55
+ }
56
+
57
+ // 加载状态
58
+ &__loading {
59
+ display: flex;
60
+ align-items: center;
61
+ justify-content: center;
62
+ gap: 8px;
63
+ padding: 48px 0;
64
+ color: #909399;
65
+ font-size: 14px;
66
+
67
+ .el-icon-loading {
68
+ font-size: 20px;
69
+ animation: xt-scroll-rotating 2s linear infinite;
70
+ }
71
+ }
72
+
73
+ // 加载更多
74
+ &__loadmore {
75
+ display: flex;
76
+ justify-content: center;
77
+ padding: 16px 0;
78
+ }
79
+
80
+ // 横向模式
81
+ &--horizontal {
82
+ .xt-scroll__virtual {
83
+ height: 100%;
84
+ }
85
+
86
+ .xt-scroll__phantom {
87
+ white-space: nowrap;
88
+ }
89
+
90
+ .xt-scroll__item {
91
+ display: inline-block;
92
+ vertical-align: top;
93
+ }
94
+ }
95
+
96
+ // 纵向模式
97
+ &--vertical {
98
+ .xt-scroll__item {
99
+ width: 100%;
100
+ }
101
+ }
102
+ }
103
+
104
+ @keyframes xt-scroll-rotating {
105
+ from { transform: rotate(0deg); }
106
+ to { transform: rotate(360deg); }
107
+ }