xt-element-ui 2.2.3 → 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 (116) hide show
  1. package/README.md +140 -192
  2. package/docs/README.md +162 -88
  3. package/docs/components/base/theme.md +248 -0
  4. package/docs/components/base/xt-list.md +1 -1
  5. package/docs/components/base/xt-scroll-arrow.md +87 -1
  6. package/docs/components/base/xt-scroll.md +237 -0
  7. package/docs/components/utils/config.md +18 -4
  8. package/docs/components/utils/theme.md +280 -183
  9. package/lib/index.common.1.js +4 -26
  10. package/lib/index.common.2.js +1 -1
  11. package/lib/index.common.js +1871 -671
  12. package/lib/index.css +1 -1
  13. package/lib/index.umd.1.js +4 -26
  14. package/lib/index.umd.2.js +1 -1
  15. package/lib/index.umd.js +1871 -671
  16. package/lib/index.umd.min.1.js +1 -1
  17. package/lib/index.umd.min.js +1 -1
  18. package/lib/theme/element-overrides.css +607 -0
  19. package/lib/theme/element-vars.css +280 -0
  20. package/lib/xt-badge/xt-badge.common.js +1 -1
  21. package/lib/xt-badge/xt-badge.umd.js +1 -1
  22. package/lib/xt-button/xt-button.common.js +1 -1
  23. package/lib/xt-button/xt-button.umd.js +1 -1
  24. package/lib/xt-card/xt-card.common.js +1 -1
  25. package/lib/xt-card/xt-card.umd.js +1 -1
  26. package/lib/xt-card-item/xt-card-item.common.js +1 -1
  27. package/lib/xt-card-item/xt-card-item.umd.js +1 -1
  28. package/lib/xt-chart/xt-chart.common.js +5 -5
  29. package/lib/xt-chart/xt-chart.umd.js +5 -5
  30. package/lib/xt-config-provider/xt-config-provider.css +1 -1
  31. package/lib/xt-date-picker/xt-date-picker.common.1.js +4 -26
  32. package/lib/xt-date-picker/xt-date-picker.common.2.js +1 -1
  33. package/lib/xt-date-picker/xt-date-picker.common.js +1 -47
  34. package/lib/xt-date-picker/xt-date-picker.css +1 -1
  35. package/lib/xt-date-picker/xt-date-picker.umd.1.js +4 -26
  36. package/lib/xt-date-picker/xt-date-picker.umd.2.js +1 -1
  37. package/lib/xt-date-picker/xt-date-picker.umd.js +1 -47
  38. package/lib/xt-date-picker/xt-date-picker.umd.min.1.js +1 -1
  39. package/lib/xt-date-picker/xt-date-picker.umd.min.js +1 -1
  40. package/lib/xt-flex-box/xt-flex-box.common.js +1 -1
  41. package/lib/xt-flex-box/xt-flex-box.umd.js +1 -1
  42. package/lib/xt-flow/xt-flow.common.js +1 -1
  43. package/lib/xt-flow/xt-flow.umd.js +1 -1
  44. package/lib/xt-form-schema/xt-form-schema.common.js +1 -1
  45. package/lib/xt-form-schema/xt-form-schema.umd.js +1 -1
  46. package/lib/xt-grid-box/xt-grid-box.common.js +1 -1
  47. package/lib/xt-grid-box/xt-grid-box.umd.js +1 -1
  48. package/lib/xt-grid-item/xt-grid-item.common.js +1 -1
  49. package/lib/xt-grid-item/xt-grid-item.umd.js +1 -1
  50. package/lib/xt-icon/xt-icon.common.js +1 -1
  51. package/lib/xt-icon/xt-icon.umd.js +1 -1
  52. package/lib/xt-input/xt-input.common.js +1 -1
  53. package/lib/xt-input/xt-input.umd.js +1 -1
  54. package/lib/xt-list/xt-list.common.js +457 -118
  55. package/lib/xt-list/xt-list.css +1 -1
  56. package/lib/xt-list/xt-list.umd.js +457 -118
  57. package/lib/xt-list/xt-list.umd.min.js +1 -1
  58. package/lib/xt-map/xt-map.common.js +1 -1
  59. package/lib/xt-map/xt-map.umd.js +1 -1
  60. package/lib/xt-map-provider/xt-map-provider.common.js +1 -1
  61. package/lib/xt-map-provider/xt-map-provider.umd.js +1 -1
  62. package/lib/xt-page/xt-page.common.js +1 -1
  63. package/lib/xt-page/xt-page.umd.js +1 -1
  64. package/lib/xt-progress/xt-progress.common.js +1 -1
  65. package/lib/xt-progress/xt-progress.umd.js +1 -1
  66. package/lib/xt-scroll/demo.html +10 -0
  67. package/lib/xt-scroll/index.js +1 -0
  68. package/lib/xt-scroll/xt-scroll.common.js +551 -0
  69. package/lib/xt-scroll/xt-scroll.css +1 -0
  70. package/lib/xt-scroll/xt-scroll.umd.js +561 -0
  71. package/lib/xt-scroll/xt-scroll.umd.min.js +1 -0
  72. package/lib/xt-scroll-arrow/xt-scroll-arrow.common.js +591 -170
  73. package/lib/xt-scroll-arrow/xt-scroll-arrow.css +1 -1
  74. package/lib/xt-scroll-arrow/xt-scroll-arrow.umd.js +591 -170
  75. package/lib/xt-scroll-arrow/xt-scroll-arrow.umd.min.js +1 -1
  76. package/lib/xt-select-tree/xt-select-tree.common.js +1 -1
  77. package/lib/xt-select-tree/xt-select-tree.umd.js +1 -1
  78. package/lib/xt-step-price/xt-step-price.common.js +2 -2
  79. package/lib/xt-step-price/xt-step-price.umd.js +2 -2
  80. package/lib/xt-step-price-item/xt-step-price-item.common.js +1 -1
  81. package/lib/xt-step-price-item/xt-step-price-item.umd.js +1 -1
  82. package/lib/xt-tab-pane/xt-tab-pane.common.js +1 -1
  83. package/lib/xt-tab-pane/xt-tab-pane.umd.js +1 -1
  84. package/lib/xt-table/xt-table.common.js +2 -2
  85. package/lib/xt-table/xt-table.umd.js +2 -2
  86. package/lib/xt-tabs/xt-tabs.common.js +1 -1
  87. package/lib/xt-tabs/xt-tabs.umd.js +1 -1
  88. package/lib/xt-text/xt-text.common.js +1 -1
  89. package/lib/xt-text/xt-text.umd.js +1 -1
  90. package/lib/xt-time/xt-time.common.js +1 -1
  91. package/lib/xt-time/xt-time.umd.js +1 -1
  92. package/lib/xt-transfer-tree/xt-transfer-tree.common.js +1 -1
  93. package/lib/xt-transfer-tree/xt-transfer-tree.umd.js +1 -1
  94. package/lib/xt-upload/xt-upload.common.js +2 -2
  95. package/lib/xt-upload/xt-upload.umd.js +2 -2
  96. package/package.json +5 -3
  97. package/src/components/index.scss +3 -0
  98. package/src/components/theme/element-overrides.css +607 -0
  99. package/src/components/theme/element-vars.css +280 -0
  100. package/src/components/theme/iframe-injector.js +502 -0
  101. package/src/components/theme/index.js +64 -0
  102. package/src/components/xt-config-provider/style/index.scss +0 -11
  103. package/src/components/xt-date-picker/component/RangeDate.vue +1 -29
  104. package/src/components/xt-date-picker/style/index.scss +80 -53
  105. package/src/components/xt-list/index.vue +23 -12
  106. package/src/components/xt-scroll/index.js +9 -0
  107. package/src/components/xt-scroll/index.vue +363 -0
  108. package/src/components/xt-scroll/style/index.scss +107 -0
  109. package/src/components/xt-scroll-arrow/index.vue +200 -83
  110. package/src/components/xt-scroll-arrow/style/index.scss +16 -5
  111. package/src/index.js +9 -2
  112. package/src/utils/color.js +105 -0
  113. package/src/utils/index.js +456 -468
  114. package/src/utils/theme-vars.js +134 -0
  115. package/lib/css/1.87a493be.css +0 -1
  116. package/lib/xt-date-picker/css/1.87a493be.css +0 -1
@@ -1,35 +1,59 @@
1
1
  <template>
2
2
  <div class="xt-scroll-arrow" :class="[`xt-scroll-arrow--${direction}`]" :style="containerStyle">
3
- <div
4
- v-if="showLeftArrow"
3
+ <div
4
+ v-if="showLeftArrow"
5
5
  class="xt-scroll-arrow__btn xt-scroll-arrow__btn--left"
6
6
  @click="scrollLeft"
7
7
  >
8
8
  <i class="el-icon-arrow-left"></i>
9
9
  </div>
10
10
 
11
- <div ref="scrollContainer" class="xt-scroll-arrow__content" @scroll="handleScroll" @click="handleClick">
12
- <slot></slot>
11
+ <div
12
+ v-if="showTopArrow && direction === 'vertical'"
13
+ class="xt-scroll-arrow__btn xt-scroll-arrow__btn--top"
14
+ @click="scrollTop"
15
+ >
16
+ <i class="el-icon-arrow-up"></i>
13
17
  </div>
14
18
 
15
- <div
16
- v-if="showRightArrow"
19
+ <!-- 使用 xt-scroll 作为滚动容器 -->
20
+ <xt-scroll
21
+ ref="scrollRef"
22
+ :class="['xt-scroll-arrow__content', scrollClass]"
23
+ :v-scroll="vScroll"
24
+ :data="vScrollData"
25
+ :item-size="itemSize"
26
+ :key-field="keyField"
27
+ :buffer-size="bufferSize"
28
+ :scroll-direction="direction"
29
+ :loading="vScrollLoading"
30
+ :load-more="loadMore"
31
+ :load-more-text="loadMoreText"
32
+ :load-more-loading="loadMoreLoading"
33
+ @scroll="onScroll"
34
+ @load-more="$emit('load-more')"
35
+ >
36
+ <!-- 虚拟滚动模式:使用 item 插槽 -->
37
+ <template v-if="vScroll" #item="{ item, index }">
38
+ <slot name="vitem" :item="item" :index="index">
39
+ <div class="xt-scroll-arrow__vitem">{{ item }}</div>
40
+ </slot>
41
+ </template>
42
+
43
+ <!-- 非虚拟滚动模式:默认插槽 -->
44
+ <slot v-else></slot>
45
+ </xt-scroll>
46
+
47
+ <div
48
+ v-if="showRightArrow"
17
49
  class="xt-scroll-arrow__btn xt-scroll-arrow__btn--right"
18
50
  @click="scrollRight"
19
51
  >
20
52
  <i class="el-icon-arrow-right"></i>
21
53
  </div>
22
54
 
23
- <div
24
- v-if="showTopArrow && direction === 'vertical'"
25
- class="xt-scroll-arrow__btn xt-scroll-arrow__btn--top"
26
- @click="scrollTop"
27
- >
28
- <i class="el-icon-arrow-up"></i>
29
- </div>
30
-
31
- <div
32
- v-if="showBottomArrow && direction === 'vertical'"
55
+ <div
56
+ v-if="showBottomArrow && direction === 'vertical'"
33
57
  class="xt-scroll-arrow__btn xt-scroll-arrow__btn--bottom"
34
58
  @click="scrollBottom"
35
59
  >
@@ -39,22 +63,36 @@
39
63
  </template>
40
64
 
41
65
  <script>
66
+ import XtScroll from '../xt-scroll'
67
+
42
68
  export default {
43
69
  name: 'XtScrollArrow',
70
+
71
+ components: {
72
+ XtScroll
73
+ },
74
+
44
75
  props: {
76
+ // ========== 滚动方向 ==========
45
77
  direction: {
46
78
  type: String,
47
79
  default: 'horizontal',
48
80
  validator: (val) => ['horizontal', 'vertical'].includes(val)
49
81
  },
82
+
83
+ // ========== 滚动步长 ==========
50
84
  scrollStep: {
51
85
  type: Number,
52
86
  default: 100
53
87
  },
88
+
89
+ // ========== 箭头显示 ==========
54
90
  autoHide: {
55
91
  type: Boolean,
56
92
  default: true
57
93
  },
94
+
95
+ // ========== 容器尺寸 ==========
58
96
  height: {
59
97
  type: [String, Number],
60
98
  default: ''
@@ -63,6 +101,8 @@ export default {
63
101
  type: [String, Number],
64
102
  default: ''
65
103
  },
104
+
105
+ // ========== 模式 ==========
66
106
  appendMode: {
67
107
  type: Boolean,
68
108
  default: false
@@ -70,16 +110,65 @@ export default {
70
110
  clickMode: {
71
111
  type: Boolean,
72
112
  default: false
113
+ },
114
+
115
+ // ========== 虚拟滚动配置 ==========
116
+ /** 是否启用虚拟滚动 */
117
+ vScroll: {
118
+ type: Boolean,
119
+ default: false
120
+ },
121
+ /** 虚拟滚动数据源 */
122
+ vScrollData: {
123
+ type: Array,
124
+ default: () => []
125
+ },
126
+ /** 每个 item 的固定尺寸(px) */
127
+ itemSize: {
128
+ type: Number,
129
+ default: 50
130
+ },
131
+ /** item 的唯一键字段名 */
132
+ keyField: {
133
+ type: String,
134
+ default: 'id'
135
+ },
136
+ /** 预渲染缓冲区大小 */
137
+ bufferSize: {
138
+ type: Number,
139
+ default: 5
140
+ },
141
+ /** 虚拟滚动加载状态 */
142
+ vScrollLoading: {
143
+ type: Boolean,
144
+ default: false
145
+ },
146
+
147
+ // ========== 加载更多 ==========
148
+ loadMore: {
149
+ type: Boolean,
150
+ default: false
151
+ },
152
+ loadMoreText: {
153
+ type: String,
154
+ default: '加载更多'
155
+ },
156
+ loadMoreLoading: {
157
+ type: Boolean,
158
+ default: false
73
159
  }
74
160
  },
161
+
75
162
  data() {
76
163
  return {
77
164
  showLeftArrow: false,
78
165
  showRightArrow: false,
79
166
  showTopArrow: false,
80
- showBottomArrow: false
167
+ showBottomArrow: false,
168
+ mutationObserver: null
81
169
  }
82
170
  },
171
+
83
172
  computed: {
84
173
  containerStyle() {
85
174
  const style = {}
@@ -90,27 +179,44 @@ export default {
90
179
  style.width = typeof this.width === 'number' ? `${this.width}px` : this.width
91
180
  }
92
181
  return style
182
+ },
183
+ scrollClass() {
184
+ return this.vScroll ? 'xt-scroll-arrow__content--virtual' : ''
93
185
  }
94
186
  },
187
+
95
188
  watch: {
96
189
  direction() {
97
190
  this.$nextTick(() => {
98
191
  this.checkScroll()
99
192
  })
193
+ },
194
+ vScrollData: {
195
+ handler() {
196
+ this.$nextTick(() => {
197
+ this.checkScroll()
198
+ })
199
+ }
100
200
  }
101
201
  },
202
+
102
203
  mounted() {
103
204
  this.$nextTick(() => {
104
205
  this.checkScroll()
105
206
  })
106
207
  this.addResizeObserver()
107
- this.addMutationObserver()
208
+ if (!this.vScroll) {
209
+ this.addMutationObserver()
210
+ }
108
211
  },
212
+
109
213
  beforeDestroy() {
110
214
  this.removeResizeObserver()
111
215
  this.removeMutationObserver()
112
216
  },
217
+
113
218
  methods: {
219
+ // ========== 尺寸监听 ==========
114
220
  addResizeObserver() {
115
221
  if (typeof ResizeObserver !== 'undefined') {
116
222
  this.resizeObserver = new ResizeObserver(() => {
@@ -118,17 +224,19 @@ export default {
118
224
  this.checkScroll()
119
225
  })
120
226
  })
121
- const container = this.$refs.scrollContainer
227
+ const container = this.$el
122
228
  if (container) {
123
229
  this.resizeObserver.observe(container)
124
230
  }
125
231
  }
126
232
  },
233
+
127
234
  removeResizeObserver() {
128
235
  if (this.resizeObserver) {
129
236
  this.resizeObserver.disconnect()
130
237
  }
131
238
  },
239
+
132
240
  addMutationObserver() {
133
241
  if (typeof MutationObserver !== 'undefined') {
134
242
  this.mutationObserver = new MutationObserver(() => {
@@ -139,28 +247,37 @@ export default {
139
247
  }
140
248
  })
141
249
  })
142
- const container = this.$refs.scrollContainer
250
+ const container = this.$refs.scrollRef
143
251
  if (container) {
144
- this.mutationObserver.observe(container, {
145
- childList: true,
146
- subtree: true
147
- })
252
+ const wrap = container.getScrollContainer && container.getScrollContainer()
253
+ if (wrap) {
254
+ this.mutationObserver.observe(wrap, {
255
+ childList: true,
256
+ subtree: true
257
+ })
258
+ }
148
259
  }
149
260
  }
150
261
  },
262
+
151
263
  removeMutationObserver() {
152
264
  if (this.mutationObserver) {
153
265
  this.mutationObserver.disconnect()
154
266
  }
155
267
  },
268
+
269
+ // ========== 滚动检测 ==========
156
270
  checkScroll() {
157
- const container = this.$refs.scrollContainer
158
- if (!container) return
271
+ const scrollRef = this.$refs.scrollRef
272
+ if (!scrollRef) return
273
+
274
+ const wrap = scrollRef.getScrollContainer && scrollRef.getScrollContainer()
275
+ if (!wrap) return
159
276
 
160
277
  if (this.direction === 'horizontal') {
161
- const scrollLeft = container.scrollLeft
162
- const scrollWidth = container.scrollWidth
163
- const clientWidth = container.clientWidth
278
+ const scrollLeft = wrap.scrollLeft
279
+ const scrollWidth = wrap.scrollWidth
280
+ const clientWidth = wrap.clientWidth
164
281
  const maxScroll = scrollWidth - clientWidth
165
282
 
166
283
  this.showTopArrow = false
@@ -168,15 +285,15 @@ export default {
168
285
 
169
286
  if (this.autoHide) {
170
287
  this.showLeftArrow = scrollLeft > 0
171
- this.showRightArrow = maxScroll > 0 && scrollLeft < maxScroll
288
+ this.showRightArrow = maxScroll > 0 && scrollLeft < maxScroll - 1
172
289
  } else {
173
290
  this.showLeftArrow = maxScroll > 0
174
291
  this.showRightArrow = maxScroll > 0
175
292
  }
176
293
  } else {
177
- const scrollTop = container.scrollTop
178
- const scrollHeight = container.scrollHeight
179
- const clientHeight = container.clientHeight
294
+ const scrollTop = wrap.scrollTop
295
+ const scrollHeight = wrap.scrollHeight
296
+ const clientHeight = wrap.clientHeight
180
297
  const maxScroll = scrollHeight - clientHeight
181
298
 
182
299
  this.showLeftArrow = false
@@ -184,77 +301,77 @@ export default {
184
301
 
185
302
  if (this.autoHide) {
186
303
  this.showTopArrow = scrollTop > 0
187
- this.showBottomArrow = maxScroll > 0 && scrollTop < maxScroll
304
+ this.showBottomArrow = maxScroll > 0 && scrollTop < maxScroll - 1
188
305
  } else {
189
306
  this.showTopArrow = maxScroll > 0
190
307
  this.showBottomArrow = maxScroll > 0
191
308
  }
192
309
  }
193
310
  },
194
- handleScroll() {
311
+
312
+ onScroll() {
195
313
  this.checkScroll()
196
- this.$emit('scroll', this.$refs.scrollContainer)
197
- },
198
- handleClick(e) {
199
- if (!this.clickMode) return
200
- const container = this.$refs.scrollContainer
201
- if (!container) return
202
-
203
- const target = e.target
204
- if (!target || target === container) return
205
-
206
- const containerRect = container.getBoundingClientRect()
207
- const targetRect = target.getBoundingClientRect()
208
-
209
- const isVisible = (
210
- targetRect.left >= containerRect.left &&
211
- targetRect.right <= containerRect.right &&
212
- targetRect.top >= containerRect.top &&
213
- targetRect.bottom <= containerRect.bottom
214
- )
215
-
216
- if (!isVisible) {
217
- if (this.direction === 'horizontal') {
218
- const scrollLeft = target.offsetLeft - (container.clientWidth - targetRect.width) / 2
219
- container.scrollTo({ left: scrollLeft, behavior: 'smooth' })
220
- } else {
221
- const scrollTop = target.offsetTop - (container.clientHeight - targetRect.height) / 2
222
- container.scrollTo({ top: scrollTop, behavior: 'smooth' })
223
- }
224
- }
314
+ this.$emit('scroll', this.$refs.scrollRef)
225
315
  },
316
+
317
+ // ========== 滚动操作 ==========
226
318
  scrollLeft() {
227
- const container = this.$refs.scrollContainer
228
- if (container) {
229
- container.scrollBy({ left: -this.scrollStep, behavior: 'smooth' })
230
- }
319
+ this._scrollBy(-this.scrollStep)
231
320
  },
321
+
232
322
  scrollRight() {
233
- const container = this.$refs.scrollContainer
234
- if (container) {
235
- container.scrollBy({ left: this.scrollStep, behavior: 'smooth' })
236
- }
323
+ this._scrollBy(this.scrollStep)
237
324
  },
325
+
238
326
  scrollTop() {
239
- const container = this.$refs.scrollContainer
240
- if (container) {
241
- container.scrollBy({ top: -this.scrollStep, behavior: 'smooth' })
242
- }
327
+ this._scrollBy(-this.scrollStep, 'vertical')
243
328
  },
329
+
244
330
  scrollBottom() {
245
- const container = this.$refs.scrollContainer
246
- if (container) {
247
- container.scrollBy({ top: this.scrollStep, behavior: 'smooth' })
331
+ this._scrollBy(this.scrollStep, 'vertical')
332
+ },
333
+
334
+ _scrollBy(delta, dir) {
335
+ const direction = dir || this.direction
336
+ const scrollRef = this.$refs.scrollRef
337
+ if (!scrollRef) return
338
+
339
+ const wrap = scrollRef.getScrollContainer && scrollRef.getScrollContainer()
340
+ if (!wrap) return
341
+
342
+ if (direction === 'horizontal') {
343
+ wrap.scrollBy({ left: delta, behavior: 'smooth' })
344
+ } else {
345
+ wrap.scrollBy({ top: delta, behavior: 'smooth' })
248
346
  }
249
347
  },
348
+
250
349
  scrollToEnd() {
251
- const container = this.$refs.scrollContainer
252
- if (!container) return
350
+ const scrollRef = this.$refs.scrollRef
351
+ if (!scrollRef) return
352
+ const wrap = scrollRef.getScrollContainer && scrollRef.getScrollContainer()
353
+ if (!wrap) return
354
+
253
355
  if (this.direction === 'horizontal') {
254
- container.scrollTo({ left: container.scrollWidth, behavior: 'smooth' })
356
+ wrap.scrollTo({ left: wrap.scrollWidth, behavior: 'smooth' })
255
357
  } else {
256
- container.scrollTo({ top: container.scrollHeight, behavior: 'smooth' })
358
+ wrap.scrollTo({ top: wrap.scrollHeight, behavior: 'smooth' })
257
359
  }
360
+ },
361
+
362
+ // ========== 对外暴露方法 ==========
363
+ /** 获取滚动位置 */
364
+ getScrollPos() {
365
+ const scrollRef = this.$refs.scrollRef
366
+ if (!scrollRef) return 0
367
+ const wrap = scrollRef.getScrollContainer && scrollRef.getScrollContainer()
368
+ if (!wrap) return 0
369
+ return this.direction === 'horizontal' ? wrap.scrollLeft : wrap.scrollTop
370
+ },
371
+
372
+ /** 获取 xt-scroll 组件实例 */
373
+ getScrollInstance() {
374
+ return this.$refs.scrollRef
258
375
  }
259
376
  }
260
377
  }
@@ -16,15 +16,26 @@
16
16
 
17
17
  &__content {
18
18
  flex: 1;
19
- overflow: auto;
20
- scrollbar-width: none;
21
- -ms-overflow-style: none;
19
+ overflow: hidden;
22
20
 
23
- &::-webkit-scrollbar {
24
- display: none;
21
+ // 虚拟滚动模式下的内容容器
22
+ &--virtual {
23
+ width: 100%;
25
24
  }
26
25
  }
27
26
 
27
+ // 虚拟滚动 item
28
+ &__vitem {
29
+ display: flex;
30
+ align-items: center;
31
+ height: 100%;
32
+ padding: 0 8px;
33
+ box-sizing: border-box;
34
+ overflow: hidden;
35
+ white-space: nowrap;
36
+ text-overflow: ellipsis;
37
+ }
38
+
28
39
  &__btn {
29
40
  position: absolute;
30
41
  z-index: 10;
package/src/index.js CHANGED
@@ -37,6 +37,7 @@ import XtIcon from './components/xt-icon' // XtIcon 组件(支持 el-icon /
37
37
  import XtTable from './components/xt-table' // XtTable 组件(基于 ElementUI Table 封装)
38
38
  import XtList from './components/xt-list' // XtList 组件(卡片列表)
39
39
  import XtScrollArrow from './components/xt-scroll-arrow'
40
+ import XtScroll from './components/xt-scroll' // XtScroll 组件(虚拟滚动容器)
40
41
  import XtBar from './components/xt-chart/XtBar.vue'
41
42
  import XtLine from './components/xt-chart/XtLine.vue'
42
43
  import XtPie from './components/xt-chart/XtPie.vue'
@@ -47,6 +48,7 @@ import XtUpload from './components/xt-upload'
47
48
  import XtTransferTree from './components/xt-transfer-tree' // XtTransferTree 组件(树形穿梭框)
48
49
  import XtFormSchema from './components/xt-form-schema' // XtFormSchema 组件(表单配置化搜索)
49
50
  import XtFlow from './components/xt-flow' // XtFlow 组件(审批流程轨迹)
51
+ import Theme from './components/theme' // Theme 模块(iframe 主题注入工具)
50
52
 
51
53
 
52
54
  const components = [
@@ -74,6 +76,7 @@ const components = [
74
76
  XtTable,
75
77
  XtList,
76
78
  XtScrollArrow,
79
+ XtScroll,
77
80
  XtBar,
78
81
  XtLine,
79
82
  XtPie,
@@ -154,6 +157,7 @@ export default {
154
157
  XtTable,
155
158
  XtList,
156
159
  XtScrollArrow,
160
+ XtScroll,
157
161
  XtBar,
158
162
  XtLine,
159
163
  XtPie,
@@ -163,7 +167,8 @@ export default {
163
167
  XtUpload,
164
168
  XtTransferTree,
165
169
  XtFormSchema,
166
- XtFlow
170
+ XtFlow,
171
+ Theme
167
172
  }
168
173
 
169
174
  // 导出工具函数和变量
@@ -202,6 +207,7 @@ export {
202
207
  XtTable,
203
208
  XtList,
204
209
  XtScrollArrow,
210
+ XtScroll,
205
211
  XtBar,
206
212
  XtLine,
207
213
  XtChart,
@@ -212,5 +218,6 @@ export {
212
218
  XtUpload,
213
219
  XtTransferTree,
214
220
  XtFormSchema,
215
- XtFlow
221
+ XtFlow,
222
+ Theme
216
223
  }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * 颜色工具函数
3
+ * 供 utils/index.js 和 theme/iframe-injector.js 共同使用
4
+ */
5
+
6
+ /**
7
+ * 十六进制颜色转 RGB 字符串 "r, g, b"
8
+ */
9
+ export function hexToRgb(hex) {
10
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
11
+ return result
12
+ ? `${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}`
13
+ : '24, 144, 255'
14
+ }
15
+
16
+ /**
17
+ * 十六进制颜色转 RGB 对象 { r, g, b }
18
+ */
19
+ export function hexToRgbObject(hex) {
20
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
21
+ return result ? {
22
+ r: parseInt(result[1], 16),
23
+ g: parseInt(result[2], 16),
24
+ b: parseInt(result[3], 16)
25
+ } : null
26
+ }
27
+
28
+ /**
29
+ * RGB 对象转十六进制
30
+ */
31
+ export function rgbToHex(r, g, b) {
32
+ return '#' + [r, g, b].map(x => {
33
+ const hex = x.toString(16)
34
+ return hex.length === 1 ? '0' + hex : hex
35
+ }).join('')
36
+ }
37
+
38
+ /**
39
+ * 加深颜色(amount 范围 0-100,表示减少的量)
40
+ */
41
+ export function darkenColor(hex, amount) {
42
+ const obj = hexToRgbObject(hex)
43
+ if (!obj) return hex
44
+ const r = Math.max(0, obj.r - amount)
45
+ const g = Math.max(0, obj.g - amount)
46
+ const b = Math.max(0, obj.b - amount)
47
+ return rgbToHex(r, g, b)
48
+ }
49
+
50
+ /**
51
+ * 减淡/变亮颜色(percent 范围 0-100,表示增加的百分比)
52
+ */
53
+ export function lightenColor(hex, percent) {
54
+ const obj = hexToRgbObject(hex)
55
+ if (!obj) return hex
56
+ const amount = Math.round(2.55 * percent)
57
+ const r = Math.min(255, obj.r + amount)
58
+ const g = Math.min(255, obj.g + amount)
59
+ const b = Math.min(255, obj.b + amount)
60
+ return rgbToHex(r, g, b)
61
+ }
62
+
63
+ /**
64
+ * 根据主色调生成 Element UI 主色 CSS 变量
65
+ * 返回 { '--el-color-primary': hex, '--el-color-primary-light-3': hex, ... }
66
+ */
67
+ export function generatePrimaryColorVars(primaryColor) {
68
+ const prefix = '--el-color-primary'
69
+ return {
70
+ [prefix]: primaryColor,
71
+ [`${prefix}-light-3`]: lightenColor(primaryColor, 30),
72
+ [`${prefix}-light-5`]: lightenColor(primaryColor, 50),
73
+ [`${prefix}-light-7`]: lightenColor(primaryColor, 70),
74
+ [`${prefix}-light-8`]: lightenColor(primaryColor, 80),
75
+ [`${prefix}-light-9`]: lightenColor(primaryColor, 90),
76
+ [`${prefix}-dark-2`]: darkenColor(primaryColor, 20),
77
+ [`${prefix}-rgb`]: hexToRgb(primaryColor)
78
+ }
79
+ }
80
+
81
+ /**
82
+ * 根据主色调生成 xt 组件主色 CSS 变量
83
+ * 返回 { '--xt-color-primary': hex, ... }
84
+ */
85
+ export function generateXtPrimaryColorVars(primaryColor) {
86
+ const prefix = '--xt-color-primary'
87
+ return {
88
+ [prefix]: primaryColor,
89
+ [`${prefix}-light-3`]: lightenColor(primaryColor, 30),
90
+ [`${prefix}-light-5`]: lightenColor(primaryColor, 50),
91
+ [`${prefix}-light-7`]: lightenColor(primaryColor, 70),
92
+ [`${prefix}-light-8`]: lightenColor(primaryColor, 80),
93
+ [`${prefix}-light-9`]: lightenColor(primaryColor, 90)
94
+ }
95
+ }
96
+
97
+ export default {
98
+ hexToRgb,
99
+ hexToRgbObject,
100
+ rgbToHex,
101
+ darkenColor,
102
+ lightenColor,
103
+ generatePrimaryColorVars,
104
+ generateXtPrimaryColorVars
105
+ }