funda-ui 4.7.723 → 4.7.735

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.
@@ -5,6 +5,7 @@ import useComId from 'funda-utils/dist/cjs/useComId';
5
5
  import { clsWrite, combinedCls } from 'funda-utils/dist/cjs/cls';
6
6
 
7
7
 
8
+
8
9
  import { TableProvider } from './TableContext';
9
10
  import useTableResponsive from './utils/hooks/useTableResponsive';
10
11
  import useTableDraggable from './utils/hooks/useTableDraggable';
@@ -148,10 +149,10 @@ const Table = forwardRef<HTMLDivElement, TableProps>((
148
149
 
149
150
  // initialize drag & drop data
150
151
  const {
151
- handleDragStart,
152
- handleDragEnd,
153
- handledragOver,
154
- handleTbodyEnter
152
+ isDragging,
153
+ dragHandlers,
154
+ handleTbodyEnter,
155
+ handleTbodyLeave
155
156
  } = useTableDraggable({
156
157
  enabled: rowDraggable && rootRef.current,
157
158
  data: data,
@@ -268,9 +269,10 @@ const Table = forwardRef<HTMLDivElement, TableProps>((
268
269
 
269
270
  // drag & drop
270
271
  rowDraggable,
271
- handleDragStart,
272
- handleDragEnd,
273
- handledragOver,
272
+ isRowDragging: isDragging,
273
+ handleDragStart: dragHandlers.handleDragStart,
274
+ handleDragEnd: dragHandlers.handleDragEnd,
275
+ handledragOver: dragHandlers.handleDragOver,
274
276
  handleTbodyEnter,
275
277
 
276
278
 
@@ -44,9 +44,15 @@ const TableRow = forwardRef<HTMLTableRowElement, TableRowProps>((
44
44
  // selection
45
45
  // ================================================================
46
46
  const _res = convertMapToArr(selectedItems);
47
+ // Performance optimization: stringify itemData only once instead of N times
48
+ const itemDataStr = itemData ? JSON.stringify(itemData) : '';
47
49
  const filteredSelectedItems = _res.map((v: any) => Number(v)).map((rowNum: number) => {
48
- if (JSON.stringify(itemData) === JSON.stringify(originData[rowNum])) {
49
- return originData[rowNum];
50
+ const originItem = originData?.[rowNum];
51
+ // Fast path: reference equality
52
+ if (itemData === originItem) return originItem;
53
+ // Fallback: JSON comparison (itemDataStr is cached)
54
+ if (itemDataStr && itemDataStr === JSON.stringify(originItem)) {
55
+ return originItem;
50
56
  }
51
57
  }).filter(Boolean);
52
58
  const selectedClassName = activeClassName || 'active';
@@ -64,7 +70,7 @@ const TableRow = forwardRef<HTMLTableRowElement, TableRowProps>((
64
70
  onDragEnd={rowDraggable ? handleDragEnd : () => void(0)}
65
71
  data-row-data={`${itemData && typeof itemData === 'object' ? JSON.stringify(itemData) : itemData}`}
66
72
 
67
- className={`row-obj ${className || ''} ${active ? selectedClassName : ''} ${itemData && originData ? (filteredData.every((item: any) => filterFieldsData.some((s: string) => !item[s]?.toLowerCase().includes(itemData[s]?.toLowerCase())) ) ? 'd-none' : '') : ''} ${itemData && originData ? (filteredSelectedItems.some((item: any) => JSON.stringify(itemData) === JSON.stringify(item) ) ? selectedClassName : '') : ''}`}
73
+ className={`row-obj ${className || ''} ${active ? selectedClassName : ''} ${itemData && originData ? (filteredData.every((item: any) => filterFieldsData.some((s: string) => !item[s]?.toLowerCase().includes(itemData[s]?.toLowerCase())) ) ? 'd-none' : '') : ''} ${itemData && originData && filteredSelectedItems.length > 0 ? selectedClassName : ''}`}
68
74
  >
69
75
  {children}
70
76
  </tr>
@@ -1,3 +1,5 @@
1
+
2
+
1
3
  /* ======================================================
2
4
  <!-- Table (Synthetic) -->
3
5
  /* ====================================================== */
@@ -7,7 +9,7 @@
7
9
  --syntable-row-active-bg: #f0f8ff;
8
10
  --syntable-scrollbar-color: rgba(0, 0, 0, 0.2);
9
11
  --syntable-scrollbar-track: rgba(0, 0, 0, 0);
10
- --syntable-scrollbar-h: 3px;
12
+ --syntable-scrollbar-h: 10px;
11
13
  --syntable-scrollbar-w: 10px;
12
14
  --syntable-padding-x: 1rem;
13
15
  --syntable-padding-y: 0.5rem;
@@ -165,11 +167,13 @@
165
167
 
166
168
  .row-obj-clonelast {
167
169
  height: 0 !important;
168
-
170
+ border-color: transparent !important;
171
+ padding: 0 !important;
169
172
 
170
173
  td {
171
174
  border: none;
172
175
  box-shadow: none;
176
+ padding: 0 !important;
173
177
  }
174
178
  }
175
179
 
@@ -190,11 +194,13 @@
190
194
  }
191
195
 
192
196
  /* placeholder */
197
+ .row-obj-lastplaceholder,
193
198
  .row-placeholder {
194
199
  border: 2px dotted #b5ba91;
195
200
  background-color: #e4e9c3;
196
201
  }
197
202
 
203
+
198
204
  /* trigger */
199
205
  .drag-trigger {
200
206
  display: inline-block;
@@ -15,7 +15,8 @@ const DragHandleSprite = forwardRef((props: DragHandleSpriteProps, externalRef:
15
15
 
16
16
  const {
17
17
  rowDraggable,
18
- handleTbodyEnter
18
+ handleTbodyEnter,
19
+ handleTbodyLeave
19
20
  } = useContext(TableContext);
20
21
 
21
22
  return (
@@ -23,7 +24,10 @@ const DragHandleSprite = forwardRef((props: DragHandleSpriteProps, externalRef:
23
24
  {rowDraggable ? <span
24
25
  ref={externalRef}
25
26
  className={className || 'drag-trigger'}
26
- onMouseEnter={handleTbodyEnter}
27
+ // Only when mousedown happens on this handle will we allow row dragging.
28
+ onMouseDown={handleTbodyEnter}
29
+ onMouseUp={handleTbodyLeave}
30
+ onMouseLeave={handleTbodyLeave}
27
31
  >
28
32
  {icon || <svg width="1em" height="1em" viewBox="0 0 24 24" fill="none">
29
33
  <g>
@@ -63,6 +63,14 @@ export function initOrderProps(rootElem: any) {
63
63
 
64
64
  export function initRowColProps(rootElem: any) {
65
65
  if (rootElem === null) return;
66
+
67
+ // !!! Important, performance optimization for large data renderings
68
+ // With this protection, it is only performed once
69
+ if (typeof rootElem.dataset.rowColPropsInit !== 'undefined') return;
70
+ rootElem.dataset.rowColPropsInit = '1';
71
+
72
+
73
+ //
66
74
  const _allRows = allRows(rootElem);
67
75
  const _allHeadRows = allHeadRows(rootElem);
68
76
 
@@ -167,7 +175,10 @@ export function cellMark(row: number | string | undefined, col: number | string
167
175
 
168
176
  export function removeCellFocusClassName(root: any) {
169
177
  if (root) {
170
- [].slice.call(root.querySelectorAll('td, th')).forEach((el: HTMLTableElement) => {
178
+ // !!! Important, performance optimization for large data renderings
179
+ // Only query elements with cell-focus classes
180
+ const focusedCells = root.querySelectorAll('td.cell-focus, th.cell-focus');
181
+ focusedCells.forEach((el: HTMLElement) => {
171
182
  el.classList.remove('cell-focus');
172
183
  });
173
184
  }