stk-table-vue 0.6.2 → 0.6.3

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.
@@ -147,14 +147,14 @@ export function useHighlight({ props, stkTableId, tableContainerRef }: Params) {
147
147
  /**
148
148
  * 高亮一个单元格。暂不支持虚拟滚动高亮状态记忆。
149
149
  * @param rowKeyValue 一行的key
150
- * @param dataIndex 列key
150
+ * @param colKeyValue 列key
151
151
  * @param options.method css-使用css渲染,animation-使用animation api。默认animation;
152
152
  * @param option.className 自定义css动画的class。
153
153
  * @param option.keyframe 同Keyframe https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Animations_API/Keyframe_Formats
154
154
  * @param option.duration 动画时长。method='css'状态下,用于移除class,如果传入了className则需要与自定义的动画时间一致。
155
155
  */
156
- function setHighlightDimCell(rowKeyValue: UniqKey, dataIndex: string, option: HighlightDimCellOption = {}) {
157
- const cellEl = tableContainerRef.value?.querySelector<HTMLElement>(`[data-row-key="${rowKeyValue}"]>[data-index="${dataIndex}"]`);
156
+ function setHighlightDimCell(rowKeyValue: UniqKey, colKeyValue: string, option: HighlightDimCellOption = {}) {
157
+ const cellEl = tableContainerRef.value?.querySelector<HTMLElement>(`[data-cell-key="${rowKeyValue}--${colKeyValue}"]`);
158
158
  const { className, method, duration, keyframe } = {
159
159
  className: HIGHLIGHT_CELL_CLASS,
160
160
  method: 'animation',
@@ -15,7 +15,7 @@ export function useThDrag<DT extends Record<string, any>>({ props, emits, colKey
15
15
 
16
16
  const dragConfig = computed(() => {
17
17
  const headerDrag = props.headerDrag;
18
- const draggable = headerDrag !== false;
18
+ const draggable = headerDrag !== false; // true or object
19
19
  return {
20
20
  draggable,
21
21
  mode: 'insert',
@@ -97,6 +97,6 @@ export function useThDrag<DT extends Record<string, any>>({ props, emits, colKey
97
97
  onThDragOver,
98
98
  onThDrop,
99
99
  /** 是否可拖拽 */
100
- isHeaderDraggable: (col: StkTableColumn<DT>) => !dragConfig.value.disabled(col),
100
+ isHeaderDraggable: (col: StkTableColumn<DT>) => dragConfig.value.draggable && !dragConfig.value.disabled(col),
101
101
  };
102
102
  }
@@ -14,7 +14,7 @@ function isEmptyValue(val: any, isNumber?: boolean) {
14
14
  *
15
15
  * 注意:不会改变原数组,返回新数组
16
16
  * @param sortState
17
- * @param sortState.dataIndex 排序的列
17
+ * @param sortState.dataIndex 排序的字段
18
18
  * @param sortState.order 排序顺序
19
19
  * @param sortState.sortType 排序方式
20
20
  * @param newItem 要插入的数据
@@ -169,8 +169,8 @@ export function tableSort<T extends Record<string, any>>(
169
169
  return targetDataSource;
170
170
  }
171
171
 
172
- /** 表头column配置的层级 */
173
- export function howDeepTheHeader(arr: StkTableColumn<any>[], level = 1) {
172
+ /** 多级表头深度 从0开始为一级*/
173
+ export function howDeepTheHeader(arr: StkTableColumn<any>[], level = 0) {
174
174
  const levels = [level];
175
175
  arr.forEach(item => {
176
176
  if (item.children?.length) {
@@ -7,17 +7,19 @@
7
7
  </div>
8
8
  <div class="tree-select-main-arrow"></div>
9
9
  </div>
10
- <!-- 下拉框 -->
11
- <div v-if="vIfLoadComponent" v-show="!disabled && showDropdown" class="dropdown-menu" :style="dropdownMenuStyle">
12
- <VirtualTree
13
- ref="virtualTree"
14
- v-bind="vsTreeProps"
15
- height="100%"
16
- :replace-fields="assignedFields"
17
- :tree-data="treeDataClone"
18
- @item-click="onTreeItemClick"
19
- />
20
- </div>
10
+ <Teleport :to="renderDropdownToBody ? body : void 0" :disabled="!renderDropdownToBody">
11
+ <!-- VirtualTreeSelect下拉框 -->
12
+ <div v-if="vIfLoadComponent" v-show="!disabled && showDropdown" class="dropdown-menu" :style="dropdownMenuStyle">
13
+ <VirtualTree
14
+ ref="virtualTree"
15
+ v-bind="vsTreeProps"
16
+ height="100%"
17
+ :replace-fields="assignedFields"
18
+ :tree-data="treeDataClone"
19
+ @item-click="onTreeItemClick"
20
+ />
21
+ </div>
22
+ </Teleport>
21
23
  <!-- 遮罩:用于点击区域外关闭 -->
22
24
  <div v-if="!disabled && showDropdown" class="dropdown-mask" :style="{ zIndex: zIndex }" @click="showDropdown = false"></div>
23
25
  </div>
@@ -83,6 +85,11 @@ export default {
83
85
  type: Object,
84
86
  default: () => ({}),
85
87
  },
88
+ /** 是否把dropdown挂载在body */
89
+ renderDropdownToBody: {
90
+ type: Boolean,
91
+ default: false,
92
+ },
86
93
  },
87
94
  data() {
88
95
  return {
@@ -155,9 +162,10 @@ export default {
155
162
  * 设置下拉框从上方弹出还是下方
156
163
  */
157
164
  setDropdownMenuStyle() {
165
+ const { innerWidth, innerHeight } = window;
158
166
  /** @type {DOMRect} */
159
167
  const rect = this.$el.getBoundingClientRect();
160
- const bottom = window.innerHeight - rect.top - rect.height;
168
+ const bottom = innerHeight - rect.top - rect.height;
161
169
  const dropdownWidth = this.dropdownWidth ? this.dropdownWidth : rect.width;
162
170
  // reset style
163
171
  this.dropdownMenuStyle = {
@@ -166,28 +174,40 @@ export default {
166
174
  height: this.dropdownHeight + 'px',
167
175
  zIndex: this.zIndex + 1,
168
176
  };
169
-
170
- if (window.innerWidth - rect.left >= dropdownWidth) {
171
- // 右边有空间
172
- this.dropdownMenuStyle.right = null;
173
- } else if (rect.right >= dropdownWidth) {
174
- // 左边有空间
175
- this.dropdownMenuStyle.right = 0;
177
+ if (this.renderDropdownToBody) {
178
+ this.dropdownMenuStyle.top = rect.bottom + this.dropdownSpace + 'px';
179
+ this.dropdownMenuStyle.left = rect.left + 'px';
180
+ if (innerWidth - rect.left < dropdownWidth) {
181
+ // 右边没有空间放左边
182
+ this.dropdownMenuStyle.left = rect.right - this.dropdownWidth + 'px';
183
+ }
184
+ if (innerHeight - rect.bottom < this.dropdownHeight) {
185
+ // 下面没有空间放上面
186
+ this.dropdownMenuStyle.top = rect.top - this.dropdownHeight - this.dropdownSpace + 'px';
187
+ }
176
188
  } else {
177
- this.dropdownMenuStyle.width = '96vw';
178
- this.dropdownMenuStyle.right = -1 * (window.innerWidth - rect.right) + 'px';
179
- }
189
+ if (innerWidth - rect.left >= dropdownWidth) {
190
+ // 右边有空间
191
+ this.dropdownMenuStyle.right = null;
192
+ } else if (rect.right >= dropdownWidth) {
193
+ // 左边有空间
194
+ this.dropdownMenuStyle.right = 0;
195
+ } else {
196
+ this.dropdownMenuStyle.width = '96vw';
197
+ this.dropdownMenuStyle.right = -1 * (innerWidth - rect.right) + 'px';
198
+ }
180
199
 
181
- if (bottom >= this.dropdownHeight) {
182
- // 下方有充足空间
183
- this.dropdownMenuStyle.top = rect.height + this.dropdownSpace + 'px';
184
- } else if (rect.top >= this.dropdownHeight) {
185
- // 上方有充足空间
186
- this.dropdownMenuStyle.top = -1 * this.dropdownHeight - this.dropdownSpace + 'px';
187
- } else {
188
- this.dropdownMenuStyle.top = 0;
189
- this.dropdownMenuStyle.position = 'fixed';
190
- this.dropdownMenuStyle.height = window.innerHeight + 'px';
200
+ if (bottom >= this.dropdownHeight) {
201
+ // 下方有充足空间
202
+ this.dropdownMenuStyle.top = rect.height + this.dropdownSpace + 'px';
203
+ } else if (rect.top >= this.dropdownHeight) {
204
+ // 上方有充足空间
205
+ this.dropdownMenuStyle.top = -1 * this.dropdownHeight - this.dropdownSpace + 'px';
206
+ } else {
207
+ this.dropdownMenuStyle.top = 0;
208
+ this.dropdownMenuStyle.position = 'fixed';
209
+ this.dropdownMenuStyle.height = innerHeight + 'px';
210
+ }
191
211
  }
192
212
  },
193
213
  /** 通过key值查找一项 */
@@ -228,7 +248,7 @@ export default {
228
248
  };
229
249
  </script>
230
250
  <style lang="less" scoped>
231
- :v-deep(.vtScroll-tree ul li .list-item:hover:not(.item-highlight)) {
251
+ :deep(.vtScroll-tree ul li .list-item:hover:not(.item-highlight)) {
232
252
  background-color: #f7f7fc;
233
253
  }
234
254
 
@@ -237,29 +257,35 @@ export default {
237
257
  border: 1px solid #cbcbe1;
238
258
  background-color: rgb(246, 246, 246);
239
259
  cursor: not-allowed;
260
+
240
261
  .tree-select-main-label {
241
262
  color: #ccc;
242
263
  }
264
+
243
265
  .tree-select-main-arrow {
244
266
  border-top: 5px solid #ccc;
245
267
  }
246
268
  }
247
269
  }
270
+
248
271
  .v-tree-select-wrapper {
249
272
  position: relative;
250
273
  width: 200px;
251
274
  height: 25px;
252
275
  transition: border 0.3s;
276
+
253
277
  &.disabled {
254
278
  .tree-select-main {
255
279
  border: 1px solid #cccccc;
256
280
  }
257
281
  }
282
+
258
283
  &:hover:not(.disabled) {
259
284
  .tree-select-main {
260
285
  border: 1px solid #8f90b5;
261
286
  }
262
287
  }
288
+
263
289
  .tree-select-main {
264
290
  display: flex;
265
291
  justify-content: space-between;
@@ -273,21 +299,26 @@ export default {
273
299
  box-sizing: border-box;
274
300
  padding: 0 10px;
275
301
  transition: all 0.3s;
302
+
276
303
  &.expand {
277
304
  border: 1px solid #8f90b5;
305
+
278
306
  .tree-select-main-arrow {
279
307
  border-top: 5px solid #4a4b72;
280
308
  transform: rotate(180deg);
281
309
  }
282
310
  }
311
+
283
312
  .tree-select-main-label {
284
313
  width: 100%;
285
314
  overflow: hidden;
286
315
  text-overflow: ellipsis;
316
+
287
317
  &.placeholder {
288
318
  color: #7d7d94;
289
319
  }
290
320
  }
321
+
291
322
  .tree-select-main-arrow {
292
323
  margin-left: 10px;
293
324
  align-self: center;
@@ -298,11 +329,13 @@ export default {
298
329
  border-right: 4px solid transparent;
299
330
  border-bottom: 0px;
300
331
  transition: transform 0.2s ease;
332
+
301
333
  &.expand {
302
334
  transform: rotate(180deg);
303
335
  }
304
336
  }
305
337
  }
338
+
306
339
  .dropdown-menu {
307
340
  overflow: hidden;
308
341
  border: 1px solid #ddd;
@@ -319,6 +352,7 @@ export default {
319
352
  // min-width: max-content;
320
353
  // }
321
354
  }
355
+
322
356
  /**遮罩 */
323
357
  .dropdown-mask {
324
358
  position: fixed;