@rainbow-oh/yee-c 0.7.0 → 0.8.0
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/dist/cjs/Form/form-store.d.ts +2 -1
- package/dist/cjs/Form/form-store.js +32 -17
- package/dist/cjs/Table/hooks/useColumns.js +1 -1
- package/dist/cjs/Table/style/index.less +35 -11
- package/dist/cjs/Table/table.js +57 -7
- package/dist/cjs/Table/tbody/cell.js +1 -1
- package/dist/cjs/Table/util/header.d.ts +3 -1
- package/dist/cjs/Table/util/header.js +30 -3
- package/dist/cjs/style/color.css +2 -0
- package/dist/cjs/style/themes.css +1 -1
- package/dist/cjs/style/variables.css +3 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/Form/form-store.d.ts +2 -1
- package/dist/esm/Form/form-store.js +40 -19
- package/dist/esm/Table/hooks/useColumns.js +1 -1
- package/dist/esm/Table/style/index.less +35 -11
- package/dist/esm/Table/table.js +54 -2
- package/dist/esm/Table/tbody/cell.js +1 -1
- package/dist/esm/Table/util/header.d.ts +3 -1
- package/dist/esm/Table/util/header.js +30 -2
- package/dist/esm/style/color.css +2 -0
- package/dist/esm/style/themes.css +1 -1
- package/dist/esm/style/variables.css +3 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/umd/yee-c.min.css +3 -3
- package/dist/umd/yee-c.min.js +1 -1
- package/package.json +1 -1
- package/src/Form/form-store.ts +42 -15
- package/src/Table/hooks/useColumns.ts +1 -1
- package/src/Table/style/index.less +35 -11
- package/src/Table/table.tsx +60 -1
- package/src/Table/tbody/cell.tsx +1 -1
- package/src/Table/util/header.ts +48 -2
- package/src/style/color.css +2 -0
- package/src/version.ts +1 -1
package/package.json
CHANGED
package/src/Form/form-store.ts
CHANGED
|
@@ -32,6 +32,11 @@ function move<T>(array: T[], from: number, to: number): T[] {
|
|
|
32
32
|
|
|
33
33
|
const GLOBAL_WATCH_KEY = '__ALL__';
|
|
34
34
|
|
|
35
|
+
const isRelatedNamePath = (first: string, second: string): boolean =>
|
|
36
|
+
first === second ||
|
|
37
|
+
first.startsWith(`${second}.`) ||
|
|
38
|
+
second.startsWith(`${first}.`);
|
|
39
|
+
|
|
35
40
|
export class FormStore {
|
|
36
41
|
private store: Store = {};
|
|
37
42
|
private callbacks: Callbacks = {};
|
|
@@ -145,6 +150,9 @@ export class FormStore {
|
|
|
145
150
|
});
|
|
146
151
|
}
|
|
147
152
|
|
|
153
|
+
const changedKeys = Object.keys(newStore);
|
|
154
|
+
const relatedFieldNames = this.getRelatedFieldNames(changedKeys);
|
|
155
|
+
|
|
148
156
|
// Validate on onChange and onBlur (async — fire-and-forget so setFieldsValue
|
|
149
157
|
// stays synchronous for its callers; results surface via onStoreChange).
|
|
150
158
|
if (
|
|
@@ -152,10 +160,10 @@ export class FormStore {
|
|
|
152
160
|
trigger === 'onBlur' ||
|
|
153
161
|
trigger === 'onSubmit'
|
|
154
162
|
) {
|
|
155
|
-
void this.validateFields(
|
|
163
|
+
void this.validateFields(relatedFieldNames, trigger);
|
|
156
164
|
}
|
|
157
165
|
|
|
158
|
-
this.refreshField(newStore);
|
|
166
|
+
this.refreshField(newStore, relatedFieldNames);
|
|
159
167
|
};
|
|
160
168
|
|
|
161
169
|
resetFields = (name?: Name[]) => {
|
|
@@ -279,16 +287,22 @@ export class FormStore {
|
|
|
279
287
|
return err;
|
|
280
288
|
};
|
|
281
289
|
|
|
282
|
-
|
|
290
|
+
private getRelatedFieldNames = (changedKeys: string[]): Name[] =>
|
|
291
|
+
Array.from(this.fieldMap.keys()).filter((fieldName) =>
|
|
292
|
+
changedKeys.some((changedKey) =>
|
|
293
|
+
isRelatedNamePath(String(fieldName), changedKey),
|
|
294
|
+
),
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
refreshField = (newStore?: Store, relatedFieldNames?: Name[]) => {
|
|
283
298
|
if (newStore) {
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
290
|
-
this.notifyWatchers(key);
|
|
299
|
+
const changedKeys = Object.keys(newStore);
|
|
300
|
+
const fieldNames =
|
|
301
|
+
relatedFieldNames ?? this.getRelatedFieldNames(changedKeys);
|
|
302
|
+
fieldNames.forEach((fieldName) => {
|
|
303
|
+
this.fieldMap.get(fieldName)?.onStoreChange();
|
|
291
304
|
});
|
|
305
|
+
this.notifyWatchers(changedKeys);
|
|
292
306
|
} else {
|
|
293
307
|
this.fieldEntities.forEach((entity) => {
|
|
294
308
|
entity?.onStoreChange();
|
|
@@ -308,14 +322,27 @@ export class FormStore {
|
|
|
308
322
|
}
|
|
309
323
|
this.watchers.get(key)!.add(callback);
|
|
310
324
|
return () => {
|
|
311
|
-
this.watchers.get(key)
|
|
325
|
+
const watchers = this.watchers.get(key);
|
|
326
|
+
watchers?.delete(callback);
|
|
327
|
+
if (watchers?.size === 0) {
|
|
328
|
+
this.watchers.delete(key);
|
|
329
|
+
}
|
|
312
330
|
};
|
|
313
331
|
};
|
|
314
332
|
|
|
315
|
-
private notifyWatchers = (
|
|
316
|
-
if (
|
|
317
|
-
|
|
318
|
-
|
|
333
|
+
private notifyWatchers = (changedKeys?: string | string[]) => {
|
|
334
|
+
if (changedKeys) {
|
|
335
|
+
const keys = Array.isArray(changedKeys) ? changedKeys : [changedKeys];
|
|
336
|
+
const callbacks = new Set<() => void>();
|
|
337
|
+
this.watchers.forEach((watchers, watchedKey) => {
|
|
338
|
+
if (
|
|
339
|
+
watchedKey === GLOBAL_WATCH_KEY ||
|
|
340
|
+
keys.some((changedKey) => isRelatedNamePath(watchedKey, changedKey))
|
|
341
|
+
) {
|
|
342
|
+
watchers.forEach((callback) => callbacks.add(callback));
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
callbacks.forEach((callback) => callback());
|
|
319
346
|
} else {
|
|
320
347
|
this.watchers.forEach((set) => set.forEach((cb) => cb()));
|
|
321
348
|
}
|
|
@@ -58,7 +58,7 @@ export default function useColumns({
|
|
|
58
58
|
const tree = injectSelectionExpand(base, rowSelection, expandable);
|
|
59
59
|
const leaves = flattenLeafColumns(tree);
|
|
60
60
|
const wraped = handleColumns(leaves);
|
|
61
|
-
const rows = parseHeaderRows(tree);
|
|
61
|
+
const rows = parseHeaderRows(tree, wraped);
|
|
62
62
|
return { wrapedColumns: wraped, headerRows: rows };
|
|
63
63
|
}, [childColumns, columns, shouldRenderSelection, shouldRenderExpand]);
|
|
64
64
|
|
|
@@ -49,6 +49,12 @@
|
|
|
49
49
|
background-color: var(--yee-table-head-cell-split-line-color, #eee);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
+
|
|
53
|
+
&-fixed-left,
|
|
54
|
+
&-fixed-right {
|
|
55
|
+
position: sticky;
|
|
56
|
+
z-index: 1;
|
|
57
|
+
}
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
&-cell {
|
|
@@ -84,6 +90,16 @@
|
|
|
84
90
|
&-wrapper {
|
|
85
91
|
overflow: auto;
|
|
86
92
|
width: 100%;
|
|
93
|
+
|
|
94
|
+
&-scroll-left @{pls}-cell-fixed-left-last {
|
|
95
|
+
box-shadow: 6px 0 6px -4px
|
|
96
|
+
var(--yee-table-fixed-left-after-bs-color);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
&-scroll-right @{pls}-cell-fixed-right-first {
|
|
100
|
+
box-shadow: -6px 0 6px -4px
|
|
101
|
+
var(--yee-table-fixed-right-after-bs-color);
|
|
102
|
+
}
|
|
87
103
|
}
|
|
88
104
|
|
|
89
105
|
> table {
|
|
@@ -101,10 +117,18 @@
|
|
|
101
117
|
}
|
|
102
118
|
}
|
|
103
119
|
|
|
120
|
+
&-row {
|
|
121
|
+
background-color: var(--yee-table-row-bg-color);
|
|
122
|
+
}
|
|
123
|
+
|
|
104
124
|
&-even-row {
|
|
105
125
|
background-color: var(--yee-table-even-row-bg-color);
|
|
106
126
|
}
|
|
107
127
|
|
|
128
|
+
&-odd-row {
|
|
129
|
+
background-color: var(--yee-table-odd-row-bg-color);
|
|
130
|
+
}
|
|
131
|
+
|
|
108
132
|
&-column-sorters {
|
|
109
133
|
display: inline-flex;
|
|
110
134
|
align-items: center;
|
|
@@ -137,7 +161,7 @@
|
|
|
137
161
|
&-fixed-left,
|
|
138
162
|
&-fixed-right {
|
|
139
163
|
position: sticky;
|
|
140
|
-
background-color:
|
|
164
|
+
background-color: var(--yee-table-fixed-column-bg-color);
|
|
141
165
|
}
|
|
142
166
|
}
|
|
143
167
|
|
|
@@ -163,17 +187,17 @@
|
|
|
163
187
|
}
|
|
164
188
|
}
|
|
165
189
|
|
|
166
|
-
&-odd-row {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
190
|
+
// &-odd-row {
|
|
191
|
+
// > @{pls}-cell {
|
|
192
|
+
// background-color: var(--yee-table-odd-row-bg-color);
|
|
193
|
+
// }
|
|
194
|
+
// }
|
|
171
195
|
|
|
172
|
-
&-even-row {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
196
|
+
// &-even-row {
|
|
197
|
+
// > @{pls}-cell {
|
|
198
|
+
// background-color: var(--yee-table-even-row-bg-color);
|
|
199
|
+
// }
|
|
200
|
+
// }
|
|
177
201
|
|
|
178
202
|
&-footer {
|
|
179
203
|
display: flex;
|
package/src/Table/table.tsx
CHANGED
|
@@ -126,6 +126,36 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
|
|
|
126
126
|
|
|
127
127
|
// Track previous values to determine what action triggered onChange
|
|
128
128
|
const prevSortersRef = useRef<typeof sorters>({});
|
|
129
|
+
const contentWrapperRef = useRef<HTMLDivElement>(null);
|
|
130
|
+
const contentRef = useRef<HTMLDivElement>(null);
|
|
131
|
+
const [horizontalScroll, setHorizontalScroll] = React.useState({
|
|
132
|
+
left: false,
|
|
133
|
+
right: false,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const updateHorizontalScroll = React.useCallback(() => {
|
|
137
|
+
const wrapper = contentWrapperRef.current;
|
|
138
|
+
const content = contentRef.current;
|
|
139
|
+
if (!wrapper || !content) return;
|
|
140
|
+
|
|
141
|
+
const scrollContainer =
|
|
142
|
+
content.scrollWidth - content.clientWidth > 1 ? content : wrapper;
|
|
143
|
+
const maxScrollLeft =
|
|
144
|
+
scrollContainer.scrollWidth - scrollContainer.clientWidth;
|
|
145
|
+
const hasHorizontalScroll = maxScrollLeft > 1;
|
|
146
|
+
const next = {
|
|
147
|
+
left: hasHorizontalScroll && scrollContainer.scrollLeft > 1,
|
|
148
|
+
right:
|
|
149
|
+
hasHorizontalScroll &&
|
|
150
|
+
scrollContainer.scrollLeft < maxScrollLeft - 1,
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
setHorizontalScroll((current) =>
|
|
154
|
+
current.left === next.left && current.right === next.right
|
|
155
|
+
? current
|
|
156
|
+
: next,
|
|
157
|
+
);
|
|
158
|
+
}, []);
|
|
129
159
|
|
|
130
160
|
// Wrap onFilter to trigger onChange
|
|
131
161
|
const onFilter = React.useCallback(
|
|
@@ -173,6 +203,25 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
|
|
|
173
203
|
}
|
|
174
204
|
}, [sorters, current, pageSize, pageData, sortedData, onChange]);
|
|
175
205
|
|
|
206
|
+
useEffect(() => {
|
|
207
|
+
updateHorizontalScroll();
|
|
208
|
+
|
|
209
|
+
const wrapper = contentWrapperRef.current;
|
|
210
|
+
const content = contentRef.current;
|
|
211
|
+
if (!wrapper || !content) return undefined;
|
|
212
|
+
|
|
213
|
+
if (typeof ResizeObserver === 'undefined') {
|
|
214
|
+
window.addEventListener('resize', updateHorizontalScroll);
|
|
215
|
+
return () => window.removeEventListener('resize', updateHorizontalScroll);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const resizeObserver = new ResizeObserver(updateHorizontalScroll);
|
|
219
|
+
resizeObserver.observe(wrapper);
|
|
220
|
+
resizeObserver.observe(content);
|
|
221
|
+
|
|
222
|
+
return () => resizeObserver.disconnect();
|
|
223
|
+
}, [updateHorizontalScroll, wrapedColumns, pageData, scroll?.x]);
|
|
224
|
+
|
|
176
225
|
const renderHeader = () => {
|
|
177
226
|
return (
|
|
178
227
|
<Header
|
|
@@ -259,13 +308,23 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
|
|
|
259
308
|
);
|
|
260
309
|
|
|
261
310
|
return (
|
|
262
|
-
<div
|
|
311
|
+
<div
|
|
312
|
+
ref={contentWrapperRef}
|
|
313
|
+
className={clsx(`${prefixCls}-content-wrapper`, {
|
|
314
|
+
[`${prefixCls}-content-wrapper-scroll-left`]: horizontalScroll.left,
|
|
315
|
+
[`${prefixCls}-content-wrapper-scroll-right`]:
|
|
316
|
+
horizontalScroll.right,
|
|
317
|
+
})}
|
|
318
|
+
onScroll={updateHorizontalScroll}
|
|
319
|
+
>
|
|
263
320
|
<div
|
|
321
|
+
ref={contentRef}
|
|
264
322
|
className={clsx(`${prefixCls}-content`, {
|
|
265
323
|
[`${prefixCls}-${size}-size`]: size,
|
|
266
324
|
[`${prefixCls}-fixed-header`]: scroll?.y,
|
|
267
325
|
})}
|
|
268
326
|
style={{ height: scroll?.y, width: scroll?.x }}
|
|
327
|
+
onScroll={updateHorizontalScroll}
|
|
269
328
|
>
|
|
270
329
|
{table}
|
|
271
330
|
</div>
|
package/src/Table/tbody/cell.tsx
CHANGED
|
@@ -61,7 +61,7 @@ const TableCell: React.FC<BodyCellProps> = (props) => {
|
|
|
61
61
|
{
|
|
62
62
|
[`${prefixCls}-cell-fixed-${fixed}`]: fixed,
|
|
63
63
|
[`${prefixCls}-cell-fixed-${fixed}-first`]: isFixedRightFirst,
|
|
64
|
-
[`${prefixCls}-fixed-${fixed}-last`]: isFixedLeftLast,
|
|
64
|
+
[`${prefixCls}-cell-fixed-${fixed}-last`]: isFixedLeftLast,
|
|
65
65
|
},
|
|
66
66
|
className,
|
|
67
67
|
);
|
package/src/Table/util/header.ts
CHANGED
|
@@ -32,13 +32,17 @@ export function flattenLeafColumns(
|
|
|
32
32
|
*
|
|
33
33
|
* - Pass 1 (DFS): place each column into the row matching its depth; a group's
|
|
34
34
|
* colSpan equals the sum of its children's colSpans.
|
|
35
|
+
* - Fixed metadata from the resolved leaf columns is reused by leaf cells and
|
|
36
|
+
* aggregated for group cells whose descendants share the same fixed side.
|
|
35
37
|
* - Pass 2: leaf cells (no sub-columns) get rowSpan = rowCount - rowIndex so
|
|
36
38
|
* they stretch down to the last header row; group cells keep rowSpan = 1.
|
|
37
39
|
*/
|
|
38
40
|
export function parseHeaderRows(
|
|
39
41
|
rootColumns: WrapedColumnProps[],
|
|
42
|
+
resolvedLeafColumns: WrapedColumnProps[] = flattenLeafColumns(rootColumns),
|
|
40
43
|
): HeaderCell[][] {
|
|
41
44
|
const rows: HeaderCell[][] = [];
|
|
45
|
+
let leafIndex = 0;
|
|
42
46
|
|
|
43
47
|
const fillRowCells = (
|
|
44
48
|
columns: WrapedColumnProps[],
|
|
@@ -46,17 +50,59 @@ export function parseHeaderRows(
|
|
|
46
50
|
): number => {
|
|
47
51
|
rows[rowIndex] = rows[rowIndex] || [];
|
|
48
52
|
let colSpanTotal = 0;
|
|
49
|
-
columns.filter(Boolean).forEach((
|
|
53
|
+
columns.filter(Boolean).forEach((sourceColumn) => {
|
|
54
|
+
let column = sourceColumn;
|
|
55
|
+
const subColumns = sourceColumn.children as
|
|
56
|
+
| WrapedColumnProps[]
|
|
57
|
+
| undefined;
|
|
58
|
+
const leafStartIndex = leafIndex;
|
|
50
59
|
const cell: HeaderCell = {
|
|
51
60
|
column,
|
|
52
61
|
colSpan: 1,
|
|
53
62
|
rowSpan: 1,
|
|
54
63
|
};
|
|
55
|
-
|
|
64
|
+
|
|
56
65
|
if (subColumns && subColumns.length > 0) {
|
|
57
66
|
cell.colSpan = fillRowCells(subColumns, rowIndex + 1);
|
|
58
67
|
cell.hasSubColumns = true;
|
|
68
|
+
|
|
69
|
+
const groupLeaves = resolvedLeafColumns.slice(
|
|
70
|
+
leafStartIndex,
|
|
71
|
+
leafIndex,
|
|
72
|
+
);
|
|
73
|
+
const fixed = groupLeaves[0]?.fixed;
|
|
74
|
+
const isFixedGroup =
|
|
75
|
+
(fixed === 'left' || fixed === 'right') &&
|
|
76
|
+
groupLeaves.every((leaf) => leaf.fixed === fixed);
|
|
77
|
+
|
|
78
|
+
if (isFixedGroup) {
|
|
79
|
+
const offsetLeaf =
|
|
80
|
+
fixed === 'left'
|
|
81
|
+
? groupLeaves[0]
|
|
82
|
+
: groupLeaves[groupLeaves.length - 1];
|
|
83
|
+
const boundaryLeaf =
|
|
84
|
+
fixed === 'left'
|
|
85
|
+
? groupLeaves[groupLeaves.length - 1]
|
|
86
|
+
: groupLeaves[0];
|
|
87
|
+
column = {
|
|
88
|
+
...sourceColumn,
|
|
89
|
+
fixed,
|
|
90
|
+
style: {
|
|
91
|
+
...sourceColumn.style,
|
|
92
|
+
[fixed]: offsetLeaf.style?.[fixed],
|
|
93
|
+
},
|
|
94
|
+
isFixedLeftLast: fixed === 'left' && boundaryLeaf.isFixedLeftLast,
|
|
95
|
+
isFixedRightFirst:
|
|
96
|
+
fixed === 'right' && boundaryLeaf.isFixedRightFirst,
|
|
97
|
+
};
|
|
98
|
+
cell.column = column;
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
column = resolvedLeafColumns[leafIndex] || sourceColumn;
|
|
102
|
+
cell.column = column;
|
|
103
|
+
leafIndex += 1;
|
|
59
104
|
}
|
|
105
|
+
|
|
60
106
|
rows[rowIndex].push(cell);
|
|
61
107
|
colSpanTotal += cell.colSpan;
|
|
62
108
|
});
|
package/src/style/color.css
CHANGED
|
@@ -848,6 +848,7 @@
|
|
|
848
848
|
--yee-table-thead-stripe-borderbottom-color: var(
|
|
849
849
|
--yee-table-thead-borderbottom-color
|
|
850
850
|
);
|
|
851
|
+
--yee-table-row-bg-color: var(--yee-color-bg-container);
|
|
851
852
|
--yee-table-odd-row-bg-color: var(--yee-color-bg-container);
|
|
852
853
|
--yee-table-even-row-bg-color: var(--yee-color-bg-head);
|
|
853
854
|
--yee-table-elevated-thead-stripe-borderbottom-color: var(
|
|
@@ -870,6 +871,7 @@
|
|
|
870
871
|
--yee-table-head-filter-active-color: var(--yee-primary-color);
|
|
871
872
|
--yee-table-fixed-left-after-bs-color: var(--yee-box-shadow-color);
|
|
872
873
|
--yee-table-fixed-right-after-bs-color: var(--yee-box-shadow-color);
|
|
874
|
+
--yee-table-fixed-column-bg-color: inherit;
|
|
873
875
|
--yee-table-filter-list-bg-color: var(--yee-color-bg-elevated);
|
|
874
876
|
--yee-table-tbody-tr-expanded-bg-color: var(--yee-color-bg-container);
|
|
875
877
|
--yee-table-elevated-tbody-tr-expanded-bg-color: var(
|