stk-table-vue 0.0.1-beta.2 → 0.0.1-beta.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.
package/README.md CHANGED
@@ -112,30 +112,106 @@ export type StkProps = Partial<{
112
112
  }>;
113
113
  ```
114
114
 
115
- #### StkTableColumn
115
+ ### StkTableColumn
116
116
  ``` ts
117
117
  type Sorter = boolean | Function;
118
-
118
+ /** 表格列配置 */
119
119
  export type StkTableColumn<T extends Record<string, any>> = {
120
- dataIndex: keyof T & string;
121
- title?: string;
122
- align?: 'right' | 'left' | 'center';
123
- headerAlign?: 'right' | 'left' | 'center';
124
- sorter?: Sorter;
125
- width?: string;
126
- minWidth?: string;
127
- maxWidth?: string;
128
- headerClassName?: string;
129
- className?: string;
130
- sortField?: keyof T;
131
- sortType?: 'number' | 'string';
132
- fixed?: 'left' | 'right' | null;
133
-
134
- /** private */ rowSpan?: number;
135
- /** private */ colSpan?: number;
136
- customCell?: Component | VNode;
137
- customHeaderCell?: Component | VNode;
138
- children?: StkTableColumn<T>[];
120
+ /** 取值id */
121
+ dataIndex: keyof T & string;
122
+ /** 表头文字 */
123
+ title?: string;
124
+ /** 列内容对齐方式 */
125
+ align?: 'right' | 'left' | 'center';
126
+ /** 表头内容对齐方式 */
127
+ headerAlign?: 'right' | 'left' | 'center';
128
+ /** 筛选 */
129
+ sorter?: Sorter;
130
+ /** 列宽。横向虚拟滚动时必须设置。 */
131
+ width?: string;
132
+ /** 最小列宽。非x虚拟滚动生效。 */
133
+ minWidth?: string;
134
+ /** 最大列宽。非x虚拟滚动生效。 */
135
+ maxWidth?: string;
136
+ /**th class */
137
+ headerClassName?: string;
138
+ /** td class */
139
+ className?: string;
140
+ /** 排序字段。default: dataIndex */
141
+ sortField?: keyof T;
142
+ /** 排序方式。按数字/字符串 */
143
+ sortType?: 'number' | 'string';
144
+ /** 固定列 */
145
+ fixed?: 'left' | 'right' | null;
146
+ /** private */ rowSpan?: number;
147
+ /** private */ colSpan?: number;
148
+ /**自定义 td 渲染内容 */
149
+ customCell?: Component | VNode | CustomCellFunc<T>;
150
+ /** 自定义 th 渲染内容 */
151
+ customHeaderCell?: Component | VNode | CustomHeaderCellFunc<T>;
152
+ /** 二级表头 */
153
+ children?: StkTableColumn<T>[];
139
154
  };
140
155
  ```
141
156
 
157
+
158
+ ### Example
159
+ ```vue
160
+ <template>
161
+ <StkTable
162
+ ref="stkTable"
163
+ row-key="name"
164
+ v-model:columns="columns"
165
+ :style="{height:props.height}"
166
+ theme='dark'
167
+ height='200px'
168
+ :show-overflow="false"
169
+ :show-header-overflow="false"
170
+ :sort-remote="false"
171
+ col-resizable
172
+ header-drag
173
+ virtual
174
+ virtual-x
175
+ no-data-full
176
+ :headless="false"
177
+ :data-source="dataSource"
178
+ @current-change="onCurrentChange"
179
+ @row-menu="onRowMenu"
180
+ @header-row-menu="onHeaderRowMenu"
181
+ @row-click="onRowClick"
182
+ @row-dblclick="onRowDblclick"
183
+ @sort-change="handleSortChange"
184
+ @cell-click="onCellClick"
185
+ @header-cell-click="onHeaderCellClick"
186
+ @scroll="onTableScroll"
187
+ @col-order-change="onColOrderChange"
188
+ />
189
+ </template>
190
+ <script setup>
191
+ import { h, defineComponent } from 'vue';
192
+ const columns = [
193
+ {
194
+ title: 'Name',
195
+ dataIndex: 'name',
196
+ fixed: 'left',
197
+ width: '200px',
198
+ headerClassName: 'my-th',
199
+ className: 'my-td',
200
+ sorter: true,
201
+ customHeaderCell: function FunctionalComponent(props){
202
+ return h(
203
+ 'span',
204
+ { style: 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap' },
205
+ props.col.title + '(render) text-overflow,',
206
+ );
207
+ },
208
+ customCell: defineComponent({
209
+ setup(){
210
+ //...
211
+ return () => <div></div>
212
+ }
213
+ })
214
+ },
215
+ ]
216
+ </script>
217
+ ```
@@ -30,8 +30,12 @@ declare function setSorter(dataIndex: string, order: null | 'asc' | 'desc', opti
30
30
  }): any[];
31
31
  /** 重置排序 */
32
32
  declare function resetSorter(): void;
33
- /** 滚动 */
34
- declare function scrollTo(top?: number, left?: number): void;
33
+ /**
34
+ * 设置滚动条位置
35
+ * @param top 传null 则不变动位置
36
+ * @param left 传null 则不变动位置
37
+ */
38
+ declare function scrollTo(top?: number | null, left?: number | null): void;
35
39
  /** 获取当前状态的表格数据 */
36
40
  declare function getTableData(): any[];
37
41
  declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<Partial<{
@@ -56,9 +60,9 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
56
60
  showTrHoverClass: boolean;
57
61
  headerDrag: boolean;
58
62
  rowClassName: (row: any, i: number) => string;
59
- /** rowKey缓存 */
60
63
  colResizable: boolean;
61
64
  colMinWidth: number;
65
+ border: boolean | "horizontal";
62
66
  }>>, {
63
67
  width: string;
64
68
  fixedMode: boolean;
@@ -83,6 +87,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
83
87
  rowClassName: () => "";
84
88
  colResizable: boolean;
85
89
  colMinWidth: number;
90
+ border: boolean;
86
91
  }>, {
87
92
  setCurrentRow: typeof setCurrentRow;
88
93
  setHighlightDimCell: (rowKeyValue: string, dataIndex: string) => void;
@@ -127,9 +132,9 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
127
132
  showTrHoverClass: boolean;
128
133
  headerDrag: boolean;
129
134
  rowClassName: (row: any, i: number) => string;
130
- /** rowKey缓存 */
131
135
  colResizable: boolean;
132
136
  colMinWidth: number;
137
+ border: boolean | "horizontal";
133
138
  }>>, {
134
139
  width: string;
135
140
  fixedMode: boolean;
@@ -154,6 +159,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
154
159
  rowClassName: () => "";
155
160
  colResizable: boolean;
156
161
  colMinWidth: number;
162
+ border: boolean;
157
163
  }>>> & {
158
164
  onScroll?: ((...args: any[]) => any) | undefined;
159
165
  "onTh-drag-start"?: ((...args: any[]) => any) | undefined;
@@ -192,6 +198,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
192
198
  rowClassName: (row: any, i: number) => string;
193
199
  colResizable: boolean;
194
200
  colMinWidth: number;
201
+ border: boolean | "horizontal";
195
202
  }, {}>, {
196
203
  tableHeader?(_: {
197
204
  column: StkTableColumn<any>;
@@ -1,5 +1,10 @@
1
1
  import { Component, VNode } from 'vue';
2
- type Sorter = boolean | Function;
2
+ /** 排序方式,asc-正序,desc-倒序,null-默认顺序 */
3
+ export type Order = null | 'asc' | 'desc';
4
+ type Sorter = boolean | ((data: any[], option: {
5
+ order: Order;
6
+ column: any;
7
+ }) => any[]);
3
8
  export type CustomCellFunc<T extends Record<string, any>> = (props: {
4
9
  row: T;
5
10
  col: StkTableColumn<T>;
@@ -8,29 +13,46 @@ export type CustomCellFunc<T extends Record<string, any>> = (props: {
8
13
  export type CustomHeaderCellFunc<T extends Record<string, any>> = (props: {
9
14
  col: StkTableColumn<T>;
10
15
  }) => VNode;
16
+ /** 表格列配置 */
11
17
  export type StkTableColumn<T extends Record<string, any>> = {
18
+ /** 取值id */
12
19
  dataIndex: keyof T & string;
20
+ /** 表头文字 */
13
21
  title?: string;
22
+ /** 列内容对齐方式 */
14
23
  align?: 'right' | 'left' | 'center';
24
+ /** 表头内容对齐方式 */
15
25
  headerAlign?: 'right' | 'left' | 'center';
26
+ /** 筛选 */
16
27
  sorter?: Sorter;
28
+ /** 列宽。横向虚拟滚动时必须设置。 */
17
29
  width?: string;
30
+ /** 最小列宽。非x虚拟滚动生效。 */
18
31
  minWidth?: string;
32
+ /** 最大列宽。非x虚拟滚动生效。 */
19
33
  maxWidth?: string;
34
+ /**th class */
20
35
  headerClassName?: string;
36
+ /** td class */
21
37
  className?: string;
38
+ /** 排序字段。default: dataIndex */
22
39
  sortField?: keyof T;
40
+ /** 排序方式。按数字/字符串 */
23
41
  sortType?: 'number' | 'string';
42
+ /** 固定列 */
24
43
  fixed?: 'left' | 'right' | null;
25
44
  /** private */ rowSpan?: number;
26
45
  /** private */ colSpan?: number;
46
+ /**自定义 td 渲染内容 */
27
47
  customCell?: Component | VNode | CustomCellFunc<T>;
48
+ /** 自定义 th 渲染内容 */
28
49
  customHeaderCell?: Component | VNode | CustomHeaderCellFunc<T>;
50
+ /** 二级表头 */
29
51
  children?: StkTableColumn<T>[];
30
52
  };
31
53
  export type SortOption = Pick<StkTableColumn<any>, 'sorter' | 'dataIndex' | 'sortField' | 'sortType'>;
32
- export type SortState = {
33
- dataIndex: string;
54
+ export type SortState<T> = {
55
+ dataIndex: T;
34
56
  order: null | 'asc' | 'desc';
35
57
  sortType?: 'number' | 'string';
36
58
  };
@@ -88,5 +110,11 @@ export type StkProps = Partial<{
88
110
  colResizable: boolean;
89
111
  /** 可拖动至最小的列宽 */
90
112
  colMinWidth: number;
113
+ /**
114
+ * 单元格分割线。
115
+ * 默认横竖都有
116
+ * horizontal - 仅展示横线
117
+ */
118
+ border: boolean | 'horizontal';
91
119
  }>;
92
120
  export {};
@@ -0,0 +1,23 @@
1
+ import { Order, SortOption, SortState, StkTableColumn } from './types';
2
+ /**
3
+ * 对有序数组插入新数据
4
+ * @param sortState
5
+ * @param sortState.dataIndex 排序的列
6
+ * @param sortState.order 排序顺序
7
+ * @param sortState.sortType 排序方式
8
+ * @param newItem 要插入的数据
9
+ * @param targetArray 表格数据
10
+ */
11
+ export declare function insertToOrderedArray<T extends object>(sortState: SortState<keyof T>, newItem: any, targetArray: T[]): T[];
12
+ /**
13
+ * 表格排序抽离
14
+ * 可以在组件外部自己实现表格排序,组件配置remote,使表格不排序。
15
+ * 使用者在@sort-change事件中自行更改table props 'dataSource'完成排序。
16
+ * TODO: key 唯一值,排序字段相同时,根据唯一值排序。
17
+ * @param sortOption 列配置
18
+ * @param order 排序方式
19
+ * @param dataSource 排序的数组
20
+ */
21
+ export declare function tableSort(sortOption: SortOption, order: Order, dataSource: any[]): any[];
22
+ /** column 的层级 */
23
+ export declare function howDeepTheColumn(arr: StkTableColumn<any>[], level?: number): number;
@@ -435,9 +435,9 @@ function strCompare(a, b, type) {
435
435
  if (type === "number") {
436
436
  if (+a > +b)
437
437
  return 1;
438
- if (+a === +b)
438
+ else if (+a === +b)
439
439
  return 0;
440
- if (+a < +b)
440
+ else
441
441
  return -1;
442
442
  } else {
443
443
  return String(a).localeCompare(b);
@@ -492,7 +492,7 @@ function howDeepTheColumn(arr, level = 1) {
492
492
  });
493
493
  return Math.max(...levels);
494
494
  }
495
- const _withScopeId = (n) => (pushScopeId("data-v-646b1c00"), n = n(), popScopeId(), n);
495
+ const _withScopeId = (n) => (pushScopeId("data-v-a99d823a"), n = n(), popScopeId(), n);
496
496
  const _hoisted_1 = { key: 0 };
497
497
  const _hoisted_2 = ["data-col-key", "draggable", "rowspan", "colspan", "title", "onClick"];
498
498
  const _hoisted_3 = { class: "table-header-cell-wrapper" };
@@ -563,7 +563,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
563
563
  headerDrag: { type: Boolean, default: false },
564
564
  rowClassName: { type: Function, default: () => "" },
565
565
  colResizable: { type: Boolean, default: false },
566
- colMinWidth: { default: 10 }
566
+ colMinWidth: { default: 10 },
567
+ border: { type: [Boolean, String], default: true }
567
568
  },
568
569
  emits: [
569
570
  "sort-change",
@@ -920,7 +921,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
920
921
  "virtual-x": _ctx.virtualX,
921
922
  dark: _ctx.theme === "dark",
922
923
  headless: _ctx.headless,
923
- "is-col-resizing": unref(isColResizing)
924
+ "is-col-resizing": unref(isColResizing),
925
+ border: props.border,
926
+ "border-horizontal": props.border === "horizontal"
924
927
  }]),
925
928
  style: normalizeStyle(_ctx.virtual && { "--row-height": unref(virtualScroll).rowHeight + "px" }),
926
929
  onScroll: onTableScroll,
@@ -1093,7 +1096,7 @@ const _export_sfc = (sfc, props) => {
1093
1096
  }
1094
1097
  return target;
1095
1098
  };
1096
- const StkTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-646b1c00"]]);
1099
+ const StkTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-a99d823a"]]);
1097
1100
  export {
1098
1101
  StkTable,
1099
1102
  insertToOrderedArray,
package/lib/style.css CHANGED
@@ -1,4 +1,4 @@
1
- .stk-table[data-v-646b1c00] {
1
+ .stk-table[data-v-a99d823a] {
2
2
  --row-height: 28px;
3
3
  --cell-padding-x: 8px;
4
4
  --resize-handle-width: 4px;
@@ -28,7 +28,7 @@
28
28
  /** 列宽调整指示器 */
29
29
  /**虚拟滚动模式 */
30
30
  }
31
- .stk-table.dark[data-v-646b1c00] {
31
+ .stk-table.dark[data-v-a99d823a] {
32
32
  --th-bgc: #181c21;
33
33
  --td-bgc: #181c21;
34
34
  --border-color: #26292e;
@@ -43,13 +43,39 @@
43
43
  --col-resize-indicator-color: #5d6064;
44
44
  color: #d0d1d2;
45
45
  }
46
- .stk-table.headless[data-v-646b1c00] {
46
+ .stk-table.headless[data-v-a99d823a] {
47
47
  border-top: 1px solid var(--border-color);
48
48
  }
49
- .stk-table.is-col-resizing th[data-v-646b1c00] {
49
+ .stk-table.is-col-resizing th[data-v-a99d823a] {
50
50
  pointer-events: none;
51
51
  }
52
- .stk-table .column-resize-indicator[data-v-646b1c00] {
52
+ .stk-table.border-horizontal[data-v-a99d823a] {
53
+ --bg-border-right: linear-gradient(transparent, transparent);
54
+ --bg-border-left: linear-gradient(transparent, transparent);
55
+ }
56
+ .stk-table.border .stk-table-main th[data-v-a99d823a],
57
+ .stk-table.border .stk-table-main td[data-v-a99d823a] {
58
+ background-image: var(--bg-border-right), var(--bg-border-bottom);
59
+ }
60
+ .stk-table.border .stk-table-main thead tr:first-child th[data-v-a99d823a] {
61
+ background-image: var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom);
62
+ }
63
+ .stk-table.border .stk-table-main thead tr:first-child th[data-v-a99d823a]:first-child {
64
+ background-image: var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
65
+ }
66
+ .stk-table.border .stk-table-main thead tr th[data-v-a99d823a]:first-child {
67
+ background-image: var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
68
+ }
69
+ .stk-table.border .stk-table-main tbody td[data-v-a99d823a]:first-child {
70
+ background-image: var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
71
+ }
72
+ .stk-table.border.virtual-x .stk-table-main thead tr:first-child .virtual-x-left + th[data-v-a99d823a] {
73
+ background-image: var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
74
+ }
75
+ .stk-table.border.virtual-x .stk-table-main tr .virtual-x-left + th[data-v-a99d823a] {
76
+ background-image: var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
77
+ }
78
+ .stk-table .column-resize-indicator[data-v-a99d823a] {
53
79
  width: 0;
54
80
  height: 100%;
55
81
  border-left: 1px dashed var(--col-resize-indicator-color);
@@ -58,133 +84,122 @@
58
84
  display: none;
59
85
  pointer-events: none;
60
86
  }
61
- .stk-table .stk-table-main[data-v-646b1c00] {
87
+ .stk-table .stk-table-main[data-v-a99d823a] {
62
88
  border-spacing: 0;
63
89
  border-collapse: separate;
64
90
  }
65
- .stk-table .stk-table-main.fixed-mode[data-v-646b1c00] {
91
+ .stk-table .stk-table-main.fixed-mode[data-v-a99d823a] {
66
92
  table-layout: fixed;
67
93
  }
68
- .stk-table .stk-table-main th[data-v-646b1c00],
69
- .stk-table .stk-table-main td[data-v-646b1c00] {
94
+ .stk-table .stk-table-main th[data-v-a99d823a],
95
+ .stk-table .stk-table-main td[data-v-a99d823a] {
70
96
  z-index: 1;
71
97
  height: var(--row-height);
72
98
  font-size: 14px;
73
99
  box-sizing: border-box;
74
100
  padding: 0 var(--cell-padding-x);
75
- background-image: var(--bg-border-right), var(--bg-border-bottom);
76
101
  }
77
- .stk-table .stk-table-main thead tr:first-child th[data-v-646b1c00] {
102
+ .stk-table .stk-table-main thead tr:first-child th[data-v-a99d823a] {
78
103
  position: sticky;
79
104
  top: 0;
80
- background-image: var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom);
81
105
  }
82
- .stk-table .stk-table-main thead tr:first-child th[data-v-646b1c00]:first-child {
83
- background-image: var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
84
- }
85
- .stk-table .stk-table-main thead tr th[data-v-646b1c00] {
106
+ .stk-table .stk-table-main thead tr th[data-v-a99d823a] {
86
107
  background-color: var(--th-bgc);
87
108
  }
88
- .stk-table .stk-table-main thead tr th.sortable[data-v-646b1c00] {
109
+ .stk-table .stk-table-main thead tr th.sortable[data-v-a99d823a] {
89
110
  cursor: pointer;
90
111
  }
91
- .stk-table .stk-table-main thead tr th[data-v-646b1c00]:first-child {
92
- background-image: var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
93
- }
94
- .stk-table .stk-table-main thead tr th.text-overflow .table-header-cell-wrapper[data-v-646b1c00] {
112
+ .stk-table .stk-table-main thead tr th.text-overflow .table-header-cell-wrapper[data-v-a99d823a] {
95
113
  white-space: nowrap;
96
114
  overflow: hidden;
97
115
  }
98
- .stk-table .stk-table-main thead tr th.text-overflow .table-header-cell-wrapper .table-header-title[data-v-646b1c00] {
116
+ .stk-table .stk-table-main thead tr th.text-overflow .table-header-cell-wrapper .table-header-title[data-v-a99d823a] {
99
117
  text-overflow: ellipsis;
100
118
  overflow: hidden;
101
119
  }
102
- .stk-table .stk-table-main thead tr th:not(.sorter-desc):not(.sorter-asc):hover .table-header-cell-wrapper .table-header-sorter #arrow-up[data-v-646b1c00] {
120
+ .stk-table .stk-table-main thead tr th:not(.sorter-desc):not(.sorter-asc):hover .table-header-cell-wrapper .table-header-sorter #arrow-up[data-v-a99d823a] {
103
121
  fill: var(--sort-arrow-hover-color);
104
122
  }
105
- .stk-table .stk-table-main thead tr th:not(.sorter-desc):not(.sorter-asc):hover .table-header-cell-wrapper .table-header-sorter #arrow-down[data-v-646b1c00] {
123
+ .stk-table .stk-table-main thead tr th:not(.sorter-desc):not(.sorter-asc):hover .table-header-cell-wrapper .table-header-sorter #arrow-down[data-v-a99d823a] {
106
124
  fill: var(--sort-arrow-hover-color);
107
125
  }
108
- .stk-table .stk-table-main thead tr th.sorter-desc .table-header-cell-wrapper .table-header-sorter #arrow-up[data-v-646b1c00] {
126
+ .stk-table .stk-table-main thead tr th.sorter-desc .table-header-cell-wrapper .table-header-sorter #arrow-up[data-v-a99d823a] {
109
127
  fill: var(--sort-arrow-active-sub-color);
110
128
  }
111
- .stk-table .stk-table-main thead tr th.sorter-desc .table-header-cell-wrapper .table-header-sorter #arrow-down[data-v-646b1c00] {
129
+ .stk-table .stk-table-main thead tr th.sorter-desc .table-header-cell-wrapper .table-header-sorter #arrow-down[data-v-a99d823a] {
112
130
  fill: var(--sort-arrow-active-color);
113
131
  }
114
- .stk-table .stk-table-main thead tr th.sorter-asc .table-header-cell-wrapper .table-header-sorter #arrow-up[data-v-646b1c00] {
132
+ .stk-table .stk-table-main thead tr th.sorter-asc .table-header-cell-wrapper .table-header-sorter #arrow-up[data-v-a99d823a] {
115
133
  fill: var(--sort-arrow-active-color);
116
134
  }
117
- .stk-table .stk-table-main thead tr th.sorter-asc .table-header-cell-wrapper .table-header-sorter #arrow-down[data-v-646b1c00] {
135
+ .stk-table .stk-table-main thead tr th.sorter-asc .table-header-cell-wrapper .table-header-sorter #arrow-down[data-v-a99d823a] {
118
136
  fill: var(--sort-arrow-active-sub-color);
119
137
  }
120
- .stk-table .stk-table-main thead tr th .table-header-cell-wrapper[data-v-646b1c00] {
138
+ .stk-table .stk-table-main thead tr th .table-header-cell-wrapper[data-v-a99d823a] {
121
139
  max-width: 100%;
122
140
  display: inline-flex;
123
141
  align-items: center;
124
142
  }
125
- .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-title[data-v-646b1c00] {
143
+ .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-title[data-v-a99d823a] {
126
144
  overflow: hidden;
127
145
  align-self: flex-start;
128
146
  }
129
- .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-sorter[data-v-646b1c00] {
147
+ .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-sorter[data-v-a99d823a] {
130
148
  flex-shrink: 0;
131
149
  margin-left: 4px;
132
150
  width: 16px;
133
151
  height: 16px;
134
152
  }
135
- .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-sorter #arrow-up[data-v-646b1c00],
136
- .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-sorter #arrow-down[data-v-646b1c00] {
153
+ .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-sorter #arrow-up[data-v-a99d823a],
154
+ .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-sorter #arrow-down[data-v-a99d823a] {
137
155
  fill: var(--sort-arrow-color);
138
156
  }
139
- .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-resizer[data-v-646b1c00] {
157
+ .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-resizer[data-v-a99d823a] {
140
158
  position: absolute;
141
159
  top: 0;
142
160
  bottom: 0;
143
161
  cursor: col-resize;
144
162
  width: var(--resize-handle-width);
145
163
  }
146
- .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-resizer.left[data-v-646b1c00] {
164
+ .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-resizer.left[data-v-a99d823a] {
147
165
  left: 0;
148
166
  }
149
- .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-resizer.right[data-v-646b1c00] {
167
+ .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-resizer.right[data-v-a99d823a] {
150
168
  right: 0;
151
169
  }
152
- .stk-table .stk-table-main tbody[data-v-646b1c00] {
170
+ .stk-table .stk-table-main tbody[data-v-a99d823a] {
153
171
  /**高亮渐暗 */
154
172
  }
155
- @keyframes dim-646b1c00 {
173
+ @keyframes dim-a99d823a {
156
174
  from {
157
175
  background-color: var(--highlight-color);
158
176
  }
159
177
  }
160
- .stk-table .stk-table-main tbody tr[data-v-646b1c00] {
178
+ .stk-table .stk-table-main tbody tr[data-v-a99d823a] {
161
179
  background-color: var(--td-bgc);
162
180
  }
163
- .stk-table .stk-table-main tbody tr.highlight-row[data-v-646b1c00] {
164
- animation: dim-646b1c00 2s linear;
181
+ .stk-table .stk-table-main tbody tr.highlight-row[data-v-a99d823a] {
182
+ animation: dim-a99d823a 2s linear;
165
183
  }
166
- .stk-table .stk-table-main tbody tr.hover[data-v-646b1c00],
167
- .stk-table .stk-table-main tbody tr[data-v-646b1c00]:hover {
184
+ .stk-table .stk-table-main tbody tr.hover[data-v-a99d823a],
185
+ .stk-table .stk-table-main tbody tr[data-v-a99d823a]:hover {
168
186
  background-color: var(--tr-hover-bgc);
169
187
  }
170
- .stk-table .stk-table-main tbody tr.active[data-v-646b1c00] {
188
+ .stk-table .stk-table-main tbody tr.active[data-v-a99d823a] {
171
189
  background-color: var(--tr-active-bgc);
172
190
  }
173
- .stk-table .stk-table-main tbody tr td.fixed-cell[data-v-646b1c00] {
191
+ .stk-table .stk-table-main tbody tr td.fixed-cell[data-v-a99d823a] {
174
192
  background-color: inherit;
175
193
  }
176
- .stk-table .stk-table-main tbody tr td[data-v-646b1c00]:first-child {
177
- background-image: var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
178
- }
179
- .stk-table .stk-table-main tbody tr td.highlight-cell[data-v-646b1c00] {
180
- animation: dim-646b1c00 2s linear;
194
+ .stk-table .stk-table-main tbody tr td.highlight-cell[data-v-a99d823a] {
195
+ animation: dim-a99d823a 2s linear;
181
196
  }
182
- .stk-table .stk-table-main tbody tr td.text-overflow .table-cell-wrapper[data-v-646b1c00] {
197
+ .stk-table .stk-table-main tbody tr td.text-overflow .table-cell-wrapper[data-v-a99d823a] {
183
198
  white-space: nowrap;
184
199
  overflow: hidden;
185
200
  text-overflow: ellipsis;
186
201
  }
187
- .stk-table .stk-table-no-data[data-v-646b1c00] {
202
+ .stk-table .stk-table-no-data[data-v-a99d823a] {
188
203
  background-color: var(--table-bgc);
189
204
  line-height: var(--row-height);
190
205
  text-align: center;
@@ -199,33 +214,27 @@ from {
199
214
  align-items: center;
200
215
  justify-content: center;
201
216
  }
202
- .stk-table .stk-table-no-data.no-data-full[data-v-646b1c00] {
217
+ .stk-table .stk-table-no-data.no-data-full[data-v-a99d823a] {
203
218
  flex: 1;
204
219
  }
205
- .stk-table.virtual .stk-table-main thead tr th .table-header-cell-wrapper[data-v-646b1c00] {
220
+ .stk-table.virtual .stk-table-main thead tr th .table-header-cell-wrapper[data-v-a99d823a] {
206
221
  overflow: hidden;
207
222
  max-height: var(--row-height);
208
223
  }
209
- .stk-table.virtual .stk-table-main tbody[data-v-646b1c00] {
224
+ .stk-table.virtual .stk-table-main tbody[data-v-a99d823a] {
210
225
  position: relative;
211
226
  }
212
- .stk-table.virtual .stk-table-main tbody tr.padding-top-tr td[data-v-646b1c00] {
227
+ .stk-table.virtual .stk-table-main tbody tr.padding-top-tr td[data-v-a99d823a] {
213
228
  height: 0;
214
229
  }
215
- .stk-table.virtual .stk-table-main tbody tr td[data-v-646b1c00] {
230
+ .stk-table.virtual .stk-table-main tbody tr td[data-v-a99d823a] {
216
231
  height: var(--row-height);
217
232
  line-height: 1;
218
233
  }
219
- .stk-table.virtual .stk-table-main tbody tr td .table-cell-wrapper[data-v-646b1c00] {
234
+ .stk-table.virtual .stk-table-main tbody tr td .table-cell-wrapper[data-v-a99d823a] {
220
235
  max-height: var(--row-height);
221
236
  overflow: hidden;
222
237
  }
223
- .stk-table.virtual-x .stk-table-main .virtual-x-left[data-v-646b1c00] {
238
+ .stk-table.virtual-x .stk-table-main .virtual-x-left[data-v-a99d823a] {
224
239
  padding: 0;
225
240
  }
226
- .stk-table.virtual-x .stk-table-main thead tr:first-child .virtual-x-left + th[data-v-646b1c00] {
227
- background-image: var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
228
- }
229
- .stk-table.virtual-x .stk-table-main tr .virtual-x-left + th[data-v-646b1c00] {
230
- background-image: var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
231
- }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,58 +1,60 @@
1
- {
2
- "name": "stk-table-vue",
3
- "version": "0.0.1-beta.2",
4
- "description": "simple realtime virtual table for vue3",
5
- "main": "./lib/stk-table-vue.js",
6
- "types": "./lib/StkTable/index.d.ts",
7
- "packageManager": "pnpm@8.11.0",
8
- "directories": {
9
- "test": "test"
10
- },
11
- "type": "module",
12
- "scripts": {
13
- "dev": "vite",
14
- "build": "vite build",
15
- "test": "vitest"
16
- },
17
- "keywords": [
18
- "virtual table",
19
- "vue",
20
- "highlight",
21
- "sticky"
22
- ],
23
- "files": [
24
- "lib",
25
- "src"
26
- ],
27
- "author": "japlus",
28
- "repository": {
29
- "type": "git",
30
- "url": "https://gitee.com/japlus/stk-table-vue"
31
- },
32
- "license": "MIT",
33
- "devDependencies": {
34
- "@types/d3-interpolate": "^3.0.4",
35
- "@typescript-eslint/eslint-plugin": "^6.14.0",
36
- "@typescript-eslint/parser": "^6.14.0",
37
- "@vitejs/plugin-vue": "^4.5.0",
38
- "@vitejs/plugin-vue-jsx": "^3.1.0",
39
- "eslint": "^8.55.0",
40
- "eslint-config-prettier": "^9.1.0",
41
- "eslint-plugin-html": "^7.1.0",
42
- "eslint-plugin-prettier": "^5.0.1",
43
- "eslint-plugin-vue": "^9.19.2",
44
- "less": "^4.2.0",
45
- "prettier": "^3.1.1",
46
- "pug": "^3.0.2",
47
- "typescript": "^5.3.3",
48
- "vite": "^5.0.6",
49
- "vite-plugin-dts": "^3.6.4",
50
- "vue": "^3.3.9",
51
- "vue-eslint-parser": "^9.3.2",
52
- "vue-loader": "^17.2.2"
53
- },
54
- "dependencies": {
55
- "d3-interpolate": "^3.0.1",
56
- "vitest": "^1.1.0"
57
- }
1
+ {
2
+ "name": "stk-table-vue",
3
+ "version": "0.0.1-beta.3",
4
+ "description": "simple realtime virtual table for vue3",
5
+ "main": "./lib/stk-table-vue.js",
6
+ "types": "./lib/StkTable/index.d.ts",
7
+ "packageManager": "pnpm@8.11.0",
8
+ "directories": {
9
+ "test": "test"
10
+ },
11
+ "type": "module",
12
+ "scripts": {
13
+ "dev": "vite",
14
+ "build": "vite build",
15
+ "test": "vitest"
16
+ },
17
+ "keywords": [
18
+ "virtual table",
19
+ "vue",
20
+ "highlight",
21
+ "sticky"
22
+ ],
23
+ "files": [
24
+ "lib",
25
+ "src"
26
+ ],
27
+ "author": "japlus",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://gitee.com/japlus/stk-table-vue"
31
+ },
32
+ "license": "MIT",
33
+ "devDependencies": {
34
+ "@types/d3-interpolate": "^3.0.4",
35
+ "@typescript-eslint/eslint-plugin": "^6.14.0",
36
+ "@typescript-eslint/parser": "^6.14.0",
37
+ "@vitejs/plugin-vue": "^4.5.0",
38
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
39
+ "@vue/test-utils": "2.4.0-alpha.2",
40
+ "eslint": "^8.55.0",
41
+ "eslint-config-prettier": "^9.1.0",
42
+ "eslint-plugin-html": "^7.1.0",
43
+ "eslint-plugin-prettier": "^5.0.1",
44
+ "eslint-plugin-vue": "^9.19.2",
45
+ "happy-dom": "^12.10.3",
46
+ "less": "^4.2.0",
47
+ "prettier": "^3.1.1",
48
+ "pug": "^3.0.2",
49
+ "typescript": "^5.3.3",
50
+ "vite": "^5.0.6",
51
+ "vite-plugin-dts": "^3.6.4",
52
+ "vitest": "^1.1.0",
53
+ "vue": "^3.3.9",
54
+ "vue-eslint-parser": "^9.3.2",
55
+ "vue-loader": "^17.2.2"
56
+ },
57
+ "dependencies": {
58
+ "d3-interpolate": "^3.0.1"
59
+ }
58
60
  }
@@ -8,6 +8,8 @@
8
8
  dark: theme === 'dark',
9
9
  headless,
10
10
  'is-col-resizing': isColResizing,
11
+ border: props.border,
12
+ 'border-horizontal': props.border === 'horizontal',
11
13
  }"
12
14
  :style="virtual && { '--row-height': virtualScroll.rowHeight + 'px' }"
13
15
  @scroll="onTableScroll"
@@ -185,7 +187,7 @@
185
187
  * [] 计算的高亮颜色,挂在数据源上对象上,若多个表格使用同一个数据源对象会有问题。需要深拷贝。(解决方案:获取组件uid)
186
188
  * [] highlight-row 颜色不能恢复到active的颜色
187
189
  */
188
- import { SortOption, StkProps, StkTableColumn } from '@/StkTable/types/index';
190
+ import { Order, SortOption, StkProps, StkTableColumn } from '@/StkTable/types/index';
189
191
  import { CSSProperties, computed, onMounted, ref, shallowRef, toRaw, watch } from 'vue';
190
192
  import { Default_Col_Width, Is_Legacy_Mode } from './const';
191
193
  import { useColResize } from './useColResize';
@@ -218,6 +220,7 @@ const props = withDefaults(defineProps<StkProps>(), {
218
220
  rowClassName: () => '',
219
221
  colResizable: false,
220
222
  colMinWidth: 10,
223
+ border: true,
221
224
  });
222
225
 
223
226
  const emit = defineEmits([
@@ -248,7 +251,7 @@ let sortCol = ref<string | null>();
248
251
  let sortOrderIndex = ref(0);
249
252
 
250
253
  /** 排序切换顺序 */
251
- const sortSwitchOrder = [null, 'desc', 'asc'];
254
+ const sortSwitchOrder: Order[] = [null, 'desc', 'asc'];
252
255
 
253
256
  /** 表头.内容是 props.columns 的引用集合 */
254
257
  const tableHeaders = ref<StkTableColumn<any>[][]>([]);
@@ -767,6 +770,55 @@ defineExpose({
767
770
  &.is-col-resizing th {
768
771
  pointer-events: none;
769
772
  }
773
+ &.border-horizontal {
774
+ --bg-border-right: linear-gradient(transparent, transparent);
775
+ --bg-border-left: linear-gradient(transparent, transparent);
776
+ }
777
+
778
+ &.border {
779
+ .stk-table-main {
780
+ th,
781
+ td {
782
+ background-image: var(--bg-border-right), var(--bg-border-bottom);
783
+ }
784
+ thead {
785
+ tr {
786
+ &:first-child th {
787
+ background-image: var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom);
788
+
789
+ &:first-child {
790
+ background-image: var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
791
+ }
792
+ }
793
+ th {
794
+ &:first-child {
795
+ background-image: var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
796
+ }
797
+ }
798
+ }
799
+ }
800
+ tbody {
801
+ td {
802
+ &:first-child {
803
+ background-image: var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
804
+ }
805
+ }
806
+ }
807
+ }
808
+
809
+ &.virtual-x {
810
+ .stk-table-main {
811
+ thead tr:first-child .virtual-x-left + th {
812
+ // 横向虚拟滚动时,左侧第一个单元格加上border-left
813
+ background-image: var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
814
+ }
815
+
816
+ tr .virtual-x-left + th {
817
+ background-image: var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
818
+ }
819
+ }
820
+ }
821
+ }
770
822
 
771
823
  /** 列宽调整指示器 */
772
824
  .column-resize-indicator {
@@ -793,7 +845,6 @@ defineExpose({
793
845
  font-size: 14px;
794
846
  box-sizing: border-box;
795
847
  padding: 0 var(--cell-padding-x);
796
- background-image: var(--bg-border-right), var(--bg-border-bottom);
797
848
  }
798
849
 
799
850
  thead {
@@ -801,12 +852,6 @@ defineExpose({
801
852
  &:first-child th {
802
853
  position: sticky;
803
854
  top: 0;
804
- // border-top: 1px solid var(--border-color);
805
- background-image: var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom);
806
-
807
- &:first-child {
808
- background-image: var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
809
- }
810
855
  }
811
856
 
812
857
  th {
@@ -816,15 +861,6 @@ defineExpose({
816
861
  cursor: pointer;
817
862
  }
818
863
 
819
- &:first-child {
820
- // border-left: 1px solid var(--border-color);
821
- background-image: var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
822
- // padding-left: 12px;
823
- }
824
-
825
- // &:last-child {
826
- // padding-right: 12px;
827
- // }
828
864
  &.text-overflow {
829
865
  .table-header-cell-wrapper {
830
866
  white-space: nowrap;
@@ -945,10 +981,6 @@ defineExpose({
945
981
  background-color: inherit; // 防止横向滚动后透明
946
982
  }
947
983
 
948
- &:first-child {
949
- background-image: var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
950
- }
951
-
952
984
  &.highlight-cell {
953
985
  animation: dim 2s linear;
954
986
  }
@@ -1059,15 +1091,6 @@ defineExpose({
1059
1091
  .virtual-x-left {
1060
1092
  padding: 0;
1061
1093
  }
1062
-
1063
- thead tr:first-child .virtual-x-left + th {
1064
- // 横向虚拟滚动时,左侧第一个单元格加上border-left
1065
- background-image: var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
1066
- }
1067
-
1068
- tr .virtual-x-left + th {
1069
- background-image: var(--bg-border-right), var(--bg-border-bottom), var(--bg-border-left);
1070
- }
1071
1094
  }
1072
1095
  }
1073
1096
  }
@@ -1,29 +1,48 @@
1
1
  import { Component, VNode } from 'vue';
2
2
 
3
- type Sorter = boolean | Function;
3
+ /** 排序方式,asc-正序,desc-倒序,null-默认顺序 */
4
+ export type Order = null | 'asc' | 'desc';
5
+
6
+ type Sorter = boolean | ((data: any[], option: { order: Order; column: any }) => any[]);
4
7
 
5
8
  export type CustomCellFunc<T extends Record<string, any>> = (props: { row: T; col: StkTableColumn<T>; cellValue: any }) => VNode;
6
9
  export type CustomHeaderCellFunc<T extends Record<string, any>> = (props: { col: StkTableColumn<T> }) => VNode;
7
10
 
11
+ /** 表格列配置 */
8
12
  export type StkTableColumn<T extends Record<string, any>> = {
13
+ /** 取值id */
9
14
  dataIndex: keyof T & string;
15
+ /** 表头文字 */
10
16
  title?: string;
17
+ /** 列内容对齐方式 */
11
18
  align?: 'right' | 'left' | 'center';
19
+ /** 表头内容对齐方式 */
12
20
  headerAlign?: 'right' | 'left' | 'center';
21
+ /** 筛选 */
13
22
  sorter?: Sorter;
23
+ /** 列宽。横向虚拟滚动时必须设置。 */
14
24
  width?: string;
25
+ /** 最小列宽。非x虚拟滚动生效。 */
15
26
  minWidth?: string;
27
+ /** 最大列宽。非x虚拟滚动生效。 */
16
28
  maxWidth?: string;
29
+ /**th class */
17
30
  headerClassName?: string;
31
+ /** td class */
18
32
  className?: string;
33
+ /** 排序字段。default: dataIndex */
19
34
  sortField?: keyof T;
35
+ /** 排序方式。按数字/字符串 */
20
36
  sortType?: 'number' | 'string';
37
+ /** 固定列 */
21
38
  fixed?: 'left' | 'right' | null;
22
-
23
39
  /** private */ rowSpan?: number;
24
40
  /** private */ colSpan?: number;
41
+ /**自定义 td 渲染内容 */
25
42
  customCell?: Component | VNode | CustomCellFunc<T>;
43
+ /** 自定义 th 渲染内容 */
26
44
  customHeaderCell?: Component | VNode | CustomHeaderCellFunc<T>;
45
+ /** 二级表头 */
27
46
  children?: StkTableColumn<T>[];
28
47
  };
29
48
 
@@ -112,4 +131,11 @@ export type StkProps = Partial<{
112
131
 
113
132
  /** 可拖动至最小的列宽 */
114
133
  colMinWidth: number;
134
+
135
+ /**
136
+ * 单元格分割线。
137
+ * 默认横竖都有
138
+ * horizontal - 仅展示横线
139
+ */
140
+ border: boolean | 'horizontal';
115
141
  }>;
@@ -1,4 +1,4 @@
1
- import { SortOption, SortState, StkTableColumn } from './types';
1
+ import { Order, SortOption, SortState, StkTableColumn } from './types';
2
2
 
3
3
  /**
4
4
  * 对有序数组插入新数据
@@ -67,11 +67,11 @@ function strCompare(a: string, b: string, type: 'number' | 'string'): number {
67
67
  * 可以在组件外部自己实现表格排序,组件配置remote,使表格不排序。
68
68
  * 使用者在@sort-change事件中自行更改table props 'dataSource'完成排序。
69
69
  * TODO: key 唯一值,排序字段相同时,根据唯一值排序。
70
- * @param {SortOption} sortOption 列配置
71
- * @param {string|null} order 排序方式
72
- * @param {any} dataSource 排序的数组
70
+ * @param sortOption 列配置
71
+ * @param order 排序方式
72
+ * @param dataSource 排序的数组
73
73
  */
74
- export function tableSort(sortOption: SortOption, order: string | null, dataSource: any[]) {
74
+ export function tableSort(sortOption: SortOption, order: Order, dataSource: any[]): any[] {
75
75
  let targetDataSource = [...dataSource];
76
76
  if (typeof sortOption.sorter === 'function') {
77
77
  const customSorterData = sortOption.sorter(targetDataSource, { order, column: sortOption });
@@ -1,23 +0,0 @@
1
- import { SortOption, SortState, StkTableColumn } from './types';
2
- /**
3
- * 对有序数组插入新数据
4
- * @param {object} sortState
5
- * @param {string} sortState.dataIndex 排序的列
6
- * @param {null|'asc'|'desc'} sortState.order 排序顺序
7
- * @param {'number'|'string'} [sortState.sortType] 排序方式
8
- * @param {object} newItem 要插入的数据
9
- * @param {Array} targetArray 表格数据
10
- */
11
- export declare function insertToOrderedArray(sortState: SortState, newItem: any, targetArray: any[]): any[];
12
- /**
13
- * 表格排序抽离
14
- * 可以在组件外部自己实现表格排序,组件配置remote,使表格不排序。
15
- * 使用者在@sort-change事件中自行更改table props 'dataSource'完成排序。
16
- * TODO: key 唯一值,排序字段相同时,根据唯一值排序。
17
- * @param {SortOption} sortOption 列配置
18
- * @param {string|null} order 排序方式
19
- * @param {any} dataSource 排序的数组
20
- */
21
- export declare function tableSort(sortOption: SortOption, order: string | null, dataSource: any[]): any[];
22
- /** column 的层级 */
23
- export declare function howDeepTheColumn(arr: StkTableColumn<any>[], level?: number): number;
File without changes
File without changes
File without changes