@teamias/rex-design 0.1.25 → 0.1.26

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.
@@ -230,26 +230,30 @@ export var BaseTable = function BaseTable(_ref) {
230
230
  if (loading) return;
231
231
  var timer = null;
232
232
  var fn = function fn() {
233
- var contentBodyEl = document.querySelector(".".concat(state.tableKey));
234
- var bodyEl = contentBodyEl === null || contentBodyEl === void 0 ? void 0 : contentBodyEl.querySelector('tbody');
235
- // console.log(bodyEl);
236
-
237
- if (!bodyEl) return;
238
233
  if (timer) clearTimeout(timer);
239
234
  timer = setTimeout(function () {
240
235
  timer = null;
241
- var bodyRect = bodyEl.getBoundingClientRect();
236
+ // 重新查询,避免使用过期的 DOM 引用
237
+ var el = document.querySelector(".".concat(state.tableKey));
238
+ var tbody = (el === null || el === void 0 ? void 0 : el.querySelector('tbody')) || (el === null || el === void 0 ? void 0 : el.querySelector('.ant-table-tbody'));
239
+ if (!tbody || !el) return;
240
+ var bodyRect = tbody.getBoundingClientRect();
242
241
  // 54: 底部padding + 分页高度 + 分页padding
243
- state.scrollHeight = Math.max(window.innerHeight - bodyRect.top - 54, 300);
244
- state.tableWidth = contentBodyEl.offsetWidth;
245
- // console.log(state.scrollHeight);
242
+ var nextScrollHeight = Math.max(window.innerHeight - bodyRect.top - 54, 300);
243
+ var nextTableWidth = el.offsetWidth;
244
+ if (nextScrollHeight === state.scrollHeight && nextTableWidth === state.tableWidth) return;
245
+ state.scrollHeight = nextScrollHeight;
246
+ state.tableWidth = nextTableWidth;
246
247
  update();
247
248
  }, 0);
248
249
  };
249
250
  fn();
250
- window.addEventListener('resize', fn);
251
+ var el = document.querySelector(".".concat(state.tableKey));
252
+ var observer = el ? new ResizeObserver(fn) : null;
253
+ observer === null || observer === void 0 || observer.observe(el);
251
254
  return function () {
252
- window.removeEventListener('resize', fn);
255
+ observer === null || observer === void 0 || observer.disconnect();
256
+ if (timer) clearTimeout(timer);
253
257
  };
254
258
  }, [loading], {
255
259
  wait: 0
@@ -0,0 +1,2 @@
1
+ declare const _default: () => import("react/jsx-runtime").JSX.Element;
2
+ export default _default;
@@ -0,0 +1,177 @@
1
+ import { BaseTable } from "../../..";
2
+ import { useMemo } from 'react';
3
+
4
+ /**
5
+ * title: 虚拟滚动 + onCell 行列合并
6
+ * description: 开启 `virtual` 虚拟滚动渲染海量数据,同时通过 `fieldPropsFn` 为列提供 `onCell`,可实现行合并(rowSpan)和列合并(colSpan)。
7
+ */
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ var DEPARTMENTS = ['市场部', '技术部', '人事部', '财务部', '运营部'];
10
+ var ROLES = ['销售', '运营', '前端', '后端', '全栈', 'HRBP', '招聘', '财务', '会计', '审计'];
11
+ var CITIES = ['北京', '上海', '广州', '深圳', '杭州', '成都', '武汉', '南京', '天津', '重庆'];
12
+ var STATUSES = ['在职', '离职', '试用期', '待入职'];
13
+ var TOTAL = 10000;
14
+ export default (function () {
15
+ var dataSource = useMemo(function () {
16
+ var deptSize = Math.floor(TOTAL / DEPARTMENTS.length);
17
+ var data = [];
18
+ DEPARTMENTS.forEach(function (dept, di) {
19
+ var count = di === DEPARTMENTS.length - 1 ? TOTAL - data.length - 1 : deptSize;
20
+ for (var n = 0; n < count; n++) {
21
+ var idx = data.length + 1;
22
+ data.push({
23
+ key: "row-".concat(idx),
24
+ category: dept,
25
+ name: "\u5458\u5DE5 ".concat(idx),
26
+ age: 20 + idx % 30,
27
+ department: "".concat(dept).concat(Math.floor(n / 100) + 1, "\u7EC4"),
28
+ role: ROLES[idx % ROLES.length],
29
+ score: 60 + idx % 40,
30
+ city: CITIES[idx % CITIES.length],
31
+ phone: "138".concat(String(idx).padStart(8, '0')),
32
+ email: "user".concat(idx, "@example.com"),
33
+ status: STATUSES[idx % STATUSES.length],
34
+ remark: ''
35
+ });
36
+ }
37
+ });
38
+
39
+ // 汇总行
40
+ data.push({
41
+ key: 'summary',
42
+ category: '汇总',
43
+ name: '合计',
44
+ age: 0,
45
+ department: '—',
46
+ role: '—',
47
+ score: 0,
48
+ city: '',
49
+ phone: '',
50
+ email: '',
51
+ status: '',
52
+ remark: "\u5171 ".concat(TOTAL, " \u4EBA")
53
+ });
54
+
55
+ // 计算 category 列 rowSpan:相邻相同部门合并
56
+ var i = 0;
57
+ while (i < data.length) {
58
+ var cat = data[i].category;
59
+ var j = i + 1;
60
+ while (j < data.length && data[j].category === cat) j++;
61
+ data[i]._categoryRowSpan = j - i;
62
+ for (var k = i + 1; k < j; k++) data[k]._categoryRowSpan = 0;
63
+ i = j;
64
+ }
65
+ return data;
66
+ }, []);
67
+ return /*#__PURE__*/_jsx(BaseTable, {
68
+ useDataCellRender: false,
69
+ virtual: true,
70
+ fieldsConfig: [{
71
+ title: '部门',
72
+ dataIndex: 'category',
73
+ width: 100,
74
+ align: 'center'
75
+ }, {
76
+ title: '姓名',
77
+ dataIndex: 'name',
78
+ width: 100
79
+ }, {
80
+ title: '年龄',
81
+ dataIndex: 'age',
82
+ width: 80,
83
+ align: 'center'
84
+ }, {
85
+ title: '区域',
86
+ dataIndex: 'department',
87
+ width: 120
88
+ }, {
89
+ title: '岗位',
90
+ dataIndex: 'role',
91
+ width: 100
92
+ }, {
93
+ title: '评分',
94
+ dataIndex: 'score',
95
+ width: 80,
96
+ align: 'center'
97
+ }, {
98
+ title: '城市',
99
+ dataIndex: 'city',
100
+ width: 100
101
+ }, {
102
+ title: '手机号',
103
+ dataIndex: 'phone',
104
+ width: 140
105
+ }, {
106
+ title: '邮箱',
107
+ dataIndex: 'email',
108
+ width: 200
109
+ }, {
110
+ title: '状态',
111
+ dataIndex: 'status',
112
+ width: 100,
113
+ align: 'center'
114
+ }, {
115
+ title: '备注',
116
+ dataIndex: 'remark',
117
+ width: 220
118
+ }],
119
+ fieldPropsFn: function fieldPropsFn() {
120
+ return {
121
+ // 行合并:相同部门的行合并为一个单元格
122
+ category: {
123
+ onCell: function onCell(record) {
124
+ var _record$_categoryRowS;
125
+ return {
126
+ rowSpan: (_record$_categoryRowS = record._categoryRowSpan) !== null && _record$_categoryRowS !== void 0 ? _record$_categoryRowS : 1
127
+ };
128
+ }
129
+ },
130
+ // 列合并:汇总行的 city/phone/email/status 设为 colSpan=0,由 remark 列占据
131
+ city: {
132
+ onCell: function onCell(record) {
133
+ return record.category === '汇总' ? {
134
+ colSpan: 0
135
+ } : {};
136
+ }
137
+ },
138
+ phone: {
139
+ onCell: function onCell(record) {
140
+ return record.category === '汇总' ? {
141
+ colSpan: 0
142
+ } : {};
143
+ }
144
+ },
145
+ email: {
146
+ onCell: function onCell(record) {
147
+ return record.category === '汇总' ? {
148
+ colSpan: 0
149
+ } : {};
150
+ }
151
+ },
152
+ status: {
153
+ onCell: function onCell(record) {
154
+ return record.category === '汇总' ? {
155
+ colSpan: 0
156
+ } : {};
157
+ }
158
+ },
159
+ // 备注列:汇总行横跨 city/phone/email/status/remark 共 5 列
160
+ remark: {
161
+ onCell: function onCell(record) {
162
+ return record.category === '汇总' ? {
163
+ colSpan: 5
164
+ } : {};
165
+ }
166
+ }
167
+ };
168
+ },
169
+ dataSource: dataSource,
170
+ scroll: function scroll(h) {
171
+ return {
172
+ y: h
173
+ };
174
+ },
175
+ pagination: false
176
+ });
177
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: () => import("react/jsx-runtime").JSX.Element;
2
+ export default _default;
@@ -0,0 +1,196 @@
1
+ import { BaseTable } from "../../..";
2
+ import { useMemo } from 'react';
3
+
4
+ /**
5
+ * title: 虚拟滚动 + DataCell 渲染 + 区域行合并
6
+ * description: 启用 `virtual` 虚拟滚动,同时使用默认的 DataCell 方式渲染单元格,并通过 `fieldPropsFn` 为 `department` 列提供 `onCell`,实现相同区域的行合并(rowSpan)。
7
+ */
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ var DEPARTMENTS = ['市场部', '技术部', '人事部', '财务部', '运营部'];
10
+ var ROLES = ['销售', '运营', '前端', '后端', '全栈', 'HRBP', '招聘', '财务', '会计', '审计'];
11
+ var CITIES = ['北京', '上海', '广州', '深圳', '杭州', '成都', '武汉', '南京', '天津', '重庆'];
12
+ var STATUSES = ['在职', '离职', '试用期', '待入职'];
13
+ var TOTAL = 10000;
14
+
15
+ /** DataCell 文本单元格格式 */
16
+ var textCell = function textCell(value) {
17
+ return [{
18
+ type: 'text',
19
+ props: {
20
+ value: String(value)
21
+ }
22
+ }];
23
+ };
24
+
25
+ /** DataCell 头像单元格格式 */
26
+ var avatarCell = function avatarCell(idx) {
27
+ return [{
28
+ type: 'img',
29
+ props: {
30
+ value: "https://api.dicebear.com/7.x/miniavs/svg?seed=".concat(idx),
31
+ label: "\u5458\u5DE5 ".concat(idx),
32
+ width: 32,
33
+ height: 32,
34
+ style: {
35
+ borderRadius: '50%'
36
+ }
37
+ }
38
+ }];
39
+ };
40
+
41
+ /** DataCell 多维度评分单元格格式 */
42
+ var scoreCell = function scoreCell(base) {
43
+ return [{
44
+ type: 'group-v2',
45
+ props: {
46
+ itemsDirection: 'column',
47
+ itemsGap: 2,
48
+ items: [{
49
+ type: 'text',
50
+ value: "\u7EE9\u6548\u5206\uFF1A".concat(base),
51
+ style: {
52
+ color: '#1677ff'
53
+ }
54
+ }, {
55
+ type: 'text',
56
+ value: "\u6280\u672F\u5206\uFF1A".concat(Math.min(base + 5, 100)),
57
+ style: {
58
+ color: '#52c41a'
59
+ }
60
+ }, {
61
+ type: 'text',
62
+ value: "\u7EFC\u5408\u5206\uFF1A".concat(Math.round((base + Math.min(base + 5, 100)) / 2)),
63
+ style: {
64
+ color: '#faad14'
65
+ }
66
+ }]
67
+ }
68
+ }];
69
+ };
70
+
71
+ /** DataCell 标签单元格格式 */
72
+ var tagCell = function tagCell(value) {
73
+ return [{
74
+ type: 'tag',
75
+ props: {
76
+ value: value,
77
+ color: value === '在职' ? 'green' : value === '离职' ? 'red' : value === '试用期' ? 'blue' : 'orange'
78
+ }
79
+ }];
80
+ };
81
+ export default (function () {
82
+ var dataSource = useMemo(function () {
83
+ var deptSize = Math.floor(TOTAL / DEPARTMENTS.length);
84
+ var data = [];
85
+ DEPARTMENTS.forEach(function (dept, di) {
86
+ var count = di === DEPARTMENTS.length - 1 ? TOTAL - data.length : deptSize;
87
+ for (var n = 0; n < count; n++) {
88
+ var idx = data.length + 1;
89
+ var deptGroup = "".concat(dept).concat(Math.floor(n / 100) + 1, "\u7EC4");
90
+ data.push({
91
+ key: "row-".concat(idx),
92
+ _deptGroup: deptGroup,
93
+ avatar: avatarCell(idx),
94
+ name: textCell("\u5458\u5DE5 ".concat(idx)),
95
+ age: textCell(20 + idx % 30),
96
+ category: textCell(dept),
97
+ department: textCell(deptGroup),
98
+ role: textCell(ROLES[idx % ROLES.length]),
99
+ score: scoreCell(60 + idx % 40),
100
+ city: textCell(CITIES[idx % CITIES.length]),
101
+ phone: textCell("138".concat(String(idx).padStart(8, '0'))),
102
+ email: textCell("user".concat(idx, "@example.com")),
103
+ status: tagCell(STATUSES[idx % STATUSES.length]),
104
+ remark: textCell('')
105
+ });
106
+ }
107
+ });
108
+
109
+ // 计算 department 列 rowSpan:相邻相同区域合并
110
+ var i = 0;
111
+ while (i < data.length) {
112
+ var grp = data[i]._deptGroup;
113
+ var j = i + 1;
114
+ while (j < data.length && data[j]._deptGroup === grp) j++;
115
+ data[i]._departmentRowSpan = j - i;
116
+ for (var k = i + 1; k < j; k++) data[k]._departmentRowSpan = 0;
117
+ i = j;
118
+ }
119
+ return data;
120
+ }, []);
121
+ return /*#__PURE__*/_jsx(BaseTable, {
122
+ virtual: true,
123
+ fieldsConfig: [{
124
+ title: '头像',
125
+ dataIndex: 'avatar',
126
+ width: 64,
127
+ align: 'center'
128
+ }, {
129
+ title: '姓名',
130
+ dataIndex: 'name',
131
+ width: 100
132
+ }, {
133
+ title: '年龄',
134
+ dataIndex: 'age',
135
+ width: 80,
136
+ align: 'center'
137
+ }, {
138
+ title: '部门',
139
+ dataIndex: 'category',
140
+ width: 100,
141
+ align: 'center'
142
+ }, {
143
+ title: '区域',
144
+ dataIndex: 'department',
145
+ width: 120
146
+ }, {
147
+ title: '岗位',
148
+ dataIndex: 'role',
149
+ width: 100
150
+ }, {
151
+ title: '评分',
152
+ dataIndex: 'score',
153
+ width: 160
154
+ }, {
155
+ title: '城市',
156
+ dataIndex: 'city',
157
+ width: 100
158
+ }, {
159
+ title: '手机号',
160
+ dataIndex: 'phone',
161
+ width: 140
162
+ }, {
163
+ title: '邮箱',
164
+ dataIndex: 'email',
165
+ width: 200
166
+ }, {
167
+ title: '状态',
168
+ dataIndex: 'status',
169
+ width: 100,
170
+ align: 'center'
171
+ }, {
172
+ title: '备注',
173
+ dataIndex: 'remark',
174
+ width: 220
175
+ }],
176
+ fieldPropsFn: function fieldPropsFn() {
177
+ return {
178
+ department: {
179
+ onCell: function onCell(record) {
180
+ var _ref;
181
+ return {
182
+ rowSpan: (_ref = record._departmentRowSpan) !== null && _ref !== void 0 ? _ref : 1
183
+ };
184
+ }
185
+ }
186
+ };
187
+ },
188
+ dataSource: dataSource,
189
+ scroll: function scroll(h) {
190
+ return {
191
+ y: h
192
+ };
193
+ },
194
+ pagination: false
195
+ });
196
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamias/rex-design",
3
- "version": "0.1.25",
3
+ "version": "0.1.26",
4
4
  "description": "A react library developed with dumi",
5
5
  "license": "MIT",
6
6
  "module": "dist/index.js",