@moises.ai/design-system 3.10.4 → 3.10.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moises.ai/design-system",
3
- "version": "3.10.4",
3
+ "version": "3.10.6",
4
4
  "description": "Design System package based on @radix-ui/themes with custom defaults",
5
5
  "private": false,
6
6
  "type": "module",
@@ -36,6 +36,9 @@
36
36
  "extract": "lingui extract"
37
37
  },
38
38
  "dependencies": {
39
+ "@dnd-kit/core": "^6.3.1",
40
+ "@dnd-kit/sortable": "^10.0.0",
41
+ "@dnd-kit/utilities": "^3.2.2",
39
42
  "@radix-ui/react-icons": "1.3.2",
40
43
  "@radix-ui/themes": "3.2.1",
41
44
  "@wavesurfer/react": "^1.0.11",
@@ -1,205 +1,13 @@
1
- import React, { useState, useCallback, useMemo, useRef } from 'react'
2
- import {
3
- Flex,
4
- Table,
5
- Checkbox,
6
- Text,
7
- ProductsBrandPattern,
8
- DropdownMenu,
9
- } from '../../index'
10
- import { ArrowUpIcon, ArrowDownIcon } from '../../icons'
11
- import { MoreButton } from '../MoreButton/MoreButton'
1
+ import React, { useCallback, useMemo, useRef } from 'react'
2
+ import { DndContext, DragOverlay } from '@dnd-kit/core'
3
+ import { Table } from '../../index'
12
4
  import styles from './DataTable.module.css'
13
5
  import classNames from 'classnames'
14
-
15
- const toUpperCase = (str) => (typeof str === 'string' ? str.toUpperCase() : str)
16
-
17
- const DataRow = React.memo(function DataRow({
18
- row,
19
- rowIndex,
20
- columns,
21
- isSelected,
22
- anyRowSelected,
23
- selectedCount,
24
- sortedKey,
25
- mobileSecondaryColumnId,
26
- hasDropdownOptions,
27
- onRowClick,
28
- onSelectRow,
29
- onShiftClickRow,
30
- renderProjectCell,
31
- renderDataCell,
32
- reorderable,
33
- isDragging,
34
- isDragOver,
35
- onDragStart,
36
- onDragOver,
37
- onDragLeave,
38
- onDrop,
39
- onDragEnd,
40
- }) {
41
- const shiftClickRef = useRef(false)
42
- const didDragRef = useRef(false)
43
-
44
- const handleRowClick = (e) => {
45
- if (didDragRef.current) {
46
- didDragRef.current = false
47
- return
48
- }
49
- if (e.shiftKey) {
50
- e.preventDefault()
51
- onShiftClickRow?.(row, rowIndex)
52
- } else {
53
- onRowClick?.(row)
54
- }
55
- }
56
-
57
- const handleCheckboxClick = (e) => {
58
- e.stopPropagation()
59
- if (e.shiftKey) {
60
- e.preventDefault()
61
- shiftClickRef.current = true
62
- onShiftClickRow?.(row, rowIndex)
63
- setTimeout(() => {
64
- shiftClickRef.current = false
65
- }, 0)
66
- }
67
- }
68
-
69
- const handleCheckboxCellClick = (e) => {
70
- e.stopPropagation()
71
- if (e.shiftKey) {
72
- e.preventDefault()
73
- onShiftClickRow?.(row, rowIndex)
74
- } else {
75
- onSelectRow?.(row.id, !isSelected)
76
- }
77
- }
78
-
79
- const handleCheckedChange = (value) => {
80
- if (shiftClickRef.current) {
81
- shiftClickRef.current = false
82
- return
83
- }
84
- onSelectRow?.(row.id, value === true)
85
- }
86
-
87
- const showDropdownAlways = isSelected && selectedCount === 1
88
-
89
- const handleDragStart = (e) => {
90
- didDragRef.current = true
91
- e.dataTransfer.setData('text/plain', String(rowIndex))
92
- e.dataTransfer.effectAllowed = 'move'
93
- onDragStart?.(rowIndex)
94
-
95
- const table = e.currentTarget.closest('table')
96
- if (table) {
97
- const dragImage = document.createElement('div')
98
- dragImage.className = styles.dragImage
99
- dragImage.style.width = `${table.offsetWidth}px`
100
- dragImage.style.minWidth = `${table.offsetWidth}px`
101
- document.body.appendChild(dragImage)
102
- e.dataTransfer.setDragImage(dragImage, 0, 0)
103
- requestAnimationFrame(() => {
104
- if (dragImage.parentNode) {
105
- document.body.removeChild(dragImage)
106
- }
107
- })
108
- }
109
- }
110
-
111
- const handleDragOver = (e) => {
112
- e.preventDefault()
113
- e.dataTransfer.dropEffect = 'move'
114
- onDragOver?.(rowIndex)
115
- }
116
-
117
- const handleDrop = (e) => {
118
- e.preventDefault()
119
- const fromIndex = parseInt(e.dataTransfer.getData('text/plain'), 10)
120
- onDrop?.(fromIndex, rowIndex)
121
- }
122
-
123
- return (
124
- <Table.Row
125
- className={classNames({
126
- [styles.rowSelected]: isSelected,
127
- [styles.showDropdownOnSelect]: showDropdownAlways,
128
- [styles.rowDragging]: isDragging,
129
- [styles.rowDragOver]: isDragOver,
130
- [styles.rowReorderable]: reorderable,
131
- })}
132
- style={
133
- isSelected ? { '--row-bg': 'var(--aqua-dark-alpha-2)' } : undefined
134
- }
135
- draggable={reorderable}
136
- onDragStart={reorderable ? handleDragStart : undefined}
137
- onDragOver={reorderable ? handleDragOver : undefined}
138
- onDragLeave={reorderable ? onDragLeave : undefined}
139
- onDrop={reorderable ? handleDrop : undefined}
140
- onDragEnd={reorderable ? onDragEnd : undefined}
141
- >
142
- <Table.Cell
143
- className={styles.selectColumn}
144
- data-column-id="select"
145
- data-sorted="false"
146
- onClick={handleCheckboxCellClick}
147
- >
148
- <Checkbox
149
- size="1"
150
- checked={isSelected}
151
- onClick={handleCheckboxClick}
152
- onCheckedChange={handleCheckedChange}
153
- className={classNames(styles.checkboxCell, {
154
- [styles.showCheckboxCell]: isSelected || anyRowSelected,
155
- })}
156
- />
157
- </Table.Cell>
158
-
159
- {columns.map((column, index) => (
160
- <Table.Cell
161
- key={column.id}
162
- className={classNames(
163
- styles.projectCell,
164
- index === 0 ? styles.columnProject : styles.dataColumn,
165
- column.id === mobileSecondaryColumnId ? styles.mobileVisibleDataColumn : null,
166
- { [styles.sortedColumn]: sortedKey === column.id },
167
- )}
168
- data-column-id={column.id}
169
- data-sorted={sortedKey === column.id}
170
- onClick={handleRowClick}
171
- >
172
- {index === 0
173
- ? renderProjectCell(row)
174
- : renderDataCell(row, column, index)}
175
- </Table.Cell>
176
- ))}
177
-
178
- {hasDropdownOptions && (
179
- <Table.Cell
180
- className={classNames(styles.projectCell, styles.dropdownColumn, styles.dropdownColumnCell)}
181
- data-column-id="actions"
182
- >
183
- {row.dropdownOptions?.length ? (
184
- <DropdownMenu
185
- trigger={
186
- <Flex className={styles.dropdownTriggerWrapper}>
187
- <MoreButton
188
- aria-label={`More options for ${row.title ?? ''}`}
189
- className={classNames(styles.dropdownTriggerWrapperIcon, styles.dropdownColumnCell)}
190
- />
191
- </Flex>
192
- }
193
- options={row.dropdownOptions}
194
- side="bottom"
195
- align="end"
196
- />
197
- ) : null}
198
- </Table.Cell>
199
- )}
200
- </Table.Row>
201
- )
202
- })
6
+ import { DataTableDragOverlay } from './dnd/DataTableDragOverlay'
7
+ import { useDataTableDnd } from './dnd/useDataTableDnd'
8
+ import { resolveRowId, toDragRow } from './dnd/dataTableDnd.utils'
9
+ import { DataTableHeader } from './DataTableHeader'
10
+ import { DataTableBody } from './DataTableBody'
203
11
 
204
12
  export const DataTable = ({
205
13
  className,
@@ -217,11 +25,14 @@ export const DataTable = ({
217
25
  stickyBodyOffset = 0,
218
26
  reorderable = false,
219
27
  onReorder,
28
+ rowDraggable,
29
+ onRowDragStart,
30
+ onRowDragEnd,
31
+ getDragPreviewLabel,
32
+ getDragPreviewCountLabel,
33
+ renderDragPreview,
220
34
  ...props
221
35
  }) => {
222
- const [isHeaderHovering, setIsHeaderHovering] = useState(false)
223
- const [draggedRowIndex, setDraggedRowIndex] = useState(null)
224
- const [dragOverRowIndex, setDragOverRowIndex] = useState(null)
225
36
  const anchorRowIndexRef = useRef(null)
226
37
 
227
38
  const sortedKey = sorting?.field
@@ -230,19 +41,34 @@ export const DataTable = ({
230
41
 
231
42
  const mobileSecondaryColumnId = useMemo(() => {
232
43
  if (!columns?.length) return undefined
233
- if (!sortedKey || sortedKey === primaryColumnId) {
234
- return defaultSecondaryColumnId
235
- }
44
+ if (!sortedKey || sortedKey === primaryColumnId) return defaultSecondaryColumnId
236
45
  return sortedKey
237
46
  }, [columns, sortedKey, primaryColumnId, defaultSecondaryColumnId])
238
47
 
239
- const selectedSet = useMemo(() => new Set(selectedRowIds), [selectedRowIds])
48
+ const normalizedRows = useMemo(
49
+ () => data.map((row, index) => toDragRow(row, index)),
50
+ [data],
51
+ )
240
52
 
241
- const isRowSelected = useCallback((id) => selectedSet.has(id), [selectedSet])
53
+ const selectedSet = useMemo(
54
+ () => new Set((selectedRowIds ?? []).map((id) => String(id))),
55
+ [selectedRowIds],
56
+ )
57
+ const selectedRows = useMemo(
58
+ () => normalizedRows.filter((row) => row.id && selectedSet.has(row.id)),
59
+ [normalizedRows, selectedSet],
60
+ )
61
+
62
+ const isRowSelected = useCallback(
63
+ (row, index) => {
64
+ const rowId = resolveRowId(row, index)
65
+ return rowId != null && selectedSet.has(rowId)
66
+ },
67
+ [selectedSet],
68
+ )
242
69
 
243
70
  const selectedCount = selectedRowIds.length
244
71
  const total = data?.length ?? 0
245
-
246
72
  const anyRowChecked = selectedCount > 0
247
73
  const allRowsChecked = total > 0 && selectedCount === total
248
74
 
@@ -251,17 +77,6 @@ export const DataTable = ({
251
77
  [data],
252
78
  )
253
79
 
254
- const handleSortClick = useCallback(
255
- (columnId) => {
256
- const isActive = sorting?.field === columnId
257
- const nextDirection =
258
- isActive && sorting?.sort === 'ASC' ? 'DESC' : 'ASC'
259
-
260
- onSort?.(columnId, nextDirection)
261
- },
262
- [onSort, sorting],
263
- )
264
-
265
80
  const handleRowClick = useCallback(
266
81
  (row) => {
267
82
  onClick?.(row)
@@ -272,14 +87,15 @@ export const DataTable = ({
272
87
  const handleShiftClickRow = useCallback(
273
88
  (clickedRow, clickedIndex) => {
274
89
  if (!onSelectRow) return
275
-
276
90
  const anchorIndex = anchorRowIndexRef.current
277
91
  const start = anchorIndex != null ? Math.min(anchorIndex, clickedIndex) : clickedIndex
278
92
  const end = anchorIndex != null ? Math.max(anchorIndex, clickedIndex) : clickedIndex
279
93
 
280
94
  for (let i = start; i <= end; i++) {
281
- onSelectRow(data[i].id, true)
95
+ const rowId = resolveRowId(data[i], i)
96
+ if (rowId != null) onSelectRow(rowId, true)
282
97
  }
98
+
283
99
  if (anchorIndex == null) {
284
100
  anchorRowIndexRef.current = clickedIndex
285
101
  }
@@ -289,264 +105,100 @@ export const DataTable = ({
289
105
 
290
106
  const handleSelectRow = useCallback(
291
107
  (rowId, checked) => {
292
- const index = data?.findIndex((r) => r.id === rowId) ?? -1
108
+ const index =
109
+ data?.findIndex((row, idx) => resolveRowId(row, idx) === String(rowId)) ?? -1
293
110
  if (index >= 0) {
294
111
  anchorRowIndexRef.current = index
295
112
  }
296
- onSelectRow?.(rowId, checked)
113
+ onSelectRow?.(String(rowId), checked)
297
114
  },
298
115
  [data, onSelectRow],
299
116
  )
300
117
 
301
- const renderProjectCell = useCallback((row) => {
302
- return (
303
- <Flex align="center" gap="3">
304
- <ProductsBrandPattern
305
- title={row.title}
306
- size={48}
307
- className={styles.thumb}
308
- type={row.type}
309
- cover={row.thumb}
310
- />
311
-
312
- <Flex direction="column" style={{ minWidth: 0, flex: 1 }}>
313
- <Text size="2" className={styles.titleText}>
314
- {row.title}
315
- </Text>
316
- <Text size="1" className={styles.artistText}>
317
- {row.artist}
318
- </Text>
319
- </Flex>
320
- </Flex>
321
- )
322
- }, [])
323
-
324
- const handleSelectAllChange = useCallback(
325
- (value) => {
326
- if (anyRowChecked && !allRowsChecked) {
327
- onSelectAll?.(false)
328
- } else {
329
- onSelectAll?.(value === true)
330
- }
331
- },
332
- [anyRowChecked, allRowsChecked, onSelectAll],
333
- )
334
-
335
- const handleDragStart = useCallback((rowIndex) => {
336
- setDraggedRowIndex(rowIndex)
337
- }, [])
338
-
339
- const handleDragOver = useCallback((rowIndex) => {
340
- setDragOverRowIndex(rowIndex)
341
- }, [])
342
-
343
- const handleDragLeave = useCallback(() => {
344
- setDragOverRowIndex(null)
345
- }, [])
346
-
347
- const handleDrop = useCallback(
348
- (order, moveBefore) => {
349
- setDraggedRowIndex(null)
350
- setDragOverRowIndex(null)
351
- if (order === moveBefore || order + 1 === moveBefore) return
352
- onReorder?.({ order, move_before: moveBefore })
353
- },
354
- [onReorder],
355
- )
356
-
357
- const handleDragEnd = useCallback(() => {
358
- setDraggedRowIndex(null)
359
- setDragOverRowIndex(null)
360
- }, [])
361
-
362
- const handleDragOverEnd = useCallback(() => {
363
- setDragOverRowIndex(data?.length ?? 0)
364
- }, [data?.length])
365
-
366
- const handleDragLeaveEnd = useCallback(() => {
367
- setDragOverRowIndex(null)
368
- }, [])
369
-
370
- const handleDropOnEnd = useCallback(
371
- (e) => {
372
- e.preventDefault()
373
- const fromIndex = parseInt(e.dataTransfer.getData('text/plain'), 10)
374
- const moveBefore = data?.length ?? 0
375
- setDraggedRowIndex(null)
376
- setDragOverRowIndex(null)
377
- if (fromIndex === moveBefore || fromIndex + 1 === moveBefore) return
378
- onReorder?.({ order: fromIndex, move_before: moveBefore })
379
- },
380
- [data?.length, onReorder],
381
- )
382
-
383
- const totalColumnCount =
384
- 1 +
385
- (columns?.length ?? 0) +
386
- (hasDropdownOptions ? 1 : 0)
387
- const showDropAfterRow =
388
- reorderable && data?.length && draggedRowIndex !== null
389
-
390
- const renderDataCell = useCallback((row, column, index) => {
391
- const baseValue = row?.[column.id] ?? row?.[`${column.id}Formatted`]
392
- const value =
393
- column.render?.({ row, value: baseValue, column, index }) ?? baseValue
394
-
395
- const isPrimitive =
396
- typeof value === 'string' || typeof value === 'number' || value == null
397
-
398
- return isPrimitive ? (
399
- <Text size="2" className={styles.cellText}>
400
- {value}
401
- </Text>
402
- ) : (
403
- value
404
- )
405
- }, [])
118
+ const {
119
+ dndContextProps,
120
+ activeDragRowId,
121
+ overDragRowId,
122
+ activeDragContext,
123
+ sortableItems,
124
+ } = useDataTableDnd({
125
+ rows: normalizedRows,
126
+ selectedSet,
127
+ selectedRows,
128
+ reorderable,
129
+ onReorder,
130
+ onRowDragStart,
131
+ onRowDragEnd,
132
+ })
406
133
 
407
134
  const { style, ...restProps } = props
408
135
  const stickyOffsetValue =
409
136
  typeof stickyOffset === 'number' ? `${stickyOffset}px` : stickyOffset
410
-
411
137
  const stickyBodyOffsetValue =
412
138
  typeof stickyBodyOffset === 'number' ? `${stickyBodyOffset}px` : stickyBodyOffset
413
139
 
414
140
  return (
415
- <Table.Root
416
- className={classNames(styles.DataTable, className)}
417
- size="1"
418
- style={{
419
- '--datatable-sticky-offset': stickyOffsetValue,
420
- '--datatable-sticky-body-offset': stickyBodyOffsetValue,
421
- ...style,
422
- }}
423
- {...restProps}
424
- >
425
- <Table.Header
426
- onMouseEnter={() => setIsHeaderHovering(true)}
427
- onMouseLeave={() => setIsHeaderHovering(false)}
141
+ <DndContext {...dndContextProps}>
142
+ <Table.Root
143
+ className={classNames(styles.DataTable, className)}
144
+ size="1"
145
+ style={{
146
+ '--datatable-sticky-offset': stickyOffsetValue,
147
+ '--datatable-sticky-body-offset': stickyBodyOffsetValue,
148
+ ...style,
149
+ }}
150
+ {...restProps}
428
151
  >
429
- <Table.Row className={styles.headerRow}>
430
- <Table.Cell
431
- className={classNames(styles.checkboxCell, styles.selectColumn, {
432
- [styles.showCheckboxHeader]: isHeaderHovering || anyRowChecked,
433
- })}
434
- >
435
- <Checkbox
436
- size="1"
437
- checked={allRowsChecked}
438
- onCheckedChange={handleSelectAllChange}
439
- {...(anyRowChecked && !allRowsChecked
440
- ? { checked: 'indeterminate' }
441
- : {})}
442
- />
443
- </Table.Cell>
444
-
445
- {columns.map((column, index) => (
446
- <Table.ColumnHeaderCell
447
- key={column.id}
448
- className={classNames(styles.columnHeaderCell, {
449
- [styles.columnProject]: index === 0,
450
- [styles.dataColumn]: index !== 0,
451
- [styles.mobileVisibleDataColumn]: column.id === mobileSecondaryColumnId,
452
- [styles.sortedColumn]: toUpperCase(sortedKey) === toUpperCase(column.id),
453
- })}
454
- >
455
- <Flex align="center" gap="3" height="24px">
456
- {index === 0 && anyRowChecked ? (
457
- <Text size="2" weight="regular" className={styles.headerTextFirst}>
458
- {selectedFilesLabel}
459
- </Text>
460
- ) : column.sortable ? (
461
- <button
462
- type="button"
463
- className={classNames(styles.sortButton, {
464
- [styles.sortButtonFirst]: index === 0,
465
- })}
466
- onClick={() => handleSortClick(column.id)}
467
- >
468
- <Text size="2">{column.label}</Text>
469
- {toUpperCase(sortedKey) === toUpperCase(column.id) &&
470
- (sorting?.sort === 'DESC' ? (
471
- <ArrowUpIcon width={16} height={16} />
472
- ) : (
473
- <ArrowDownIcon width={16} height={16} />
474
- ))}
475
- </button>
476
- ) : (
477
- <Text size="2" className={styles.headerText}>
478
- {column.label}
479
- </Text>
480
- )}
481
-
482
- {index === 0 && renderHeaderActions && (
483
- <Flex gap="2" className={styles.headerActions}>
484
- {renderHeaderActions({
485
- selectedCount,
486
- total,
487
- anySelected: anyRowChecked,
488
- allSelected: allRowsChecked,
489
- })}
490
- </Flex>
491
- )}
492
- </Flex>
493
- </Table.ColumnHeaderCell>
494
- ))}
495
- {hasDropdownOptions && (
496
- <Table.ColumnHeaderCell
497
- className={styles.dropdownColumn}
498
- ></Table.ColumnHeaderCell>
499
- )}
500
- </Table.Row>
501
- </Table.Header>
152
+ <DataTableHeader
153
+ columns={columns}
154
+ sortedKey={sortedKey}
155
+ sorting={sorting}
156
+ mobileSecondaryColumnId={mobileSecondaryColumnId}
157
+ anyRowChecked={anyRowChecked}
158
+ allRowsChecked={allRowsChecked}
159
+ selectedFilesLabel={selectedFilesLabel}
160
+ selectedCount={selectedCount}
161
+ total={total}
162
+ hasDropdownOptions={hasDropdownOptions}
163
+ onSort={onSort}
164
+ onSelectAll={onSelectAll}
165
+ renderHeaderActions={renderHeaderActions}
166
+ />
502
167
 
503
- <Table.Body >
504
- {data.map((row, index) => (
505
- <DataRow
506
- key={row.id}
507
- row={row}
508
- rowIndex={index}
509
- columns={columns}
510
- isSelected={isRowSelected(row.id)}
511
- anyRowSelected={anyRowChecked}
512
- selectedCount={selectedCount}
513
- sortedKey={sortedKey}
514
- mobileSecondaryColumnId={mobileSecondaryColumnId}
515
- hasDropdownOptions={hasDropdownOptions}
516
- onRowClick={handleRowClick}
517
- onSelectRow={handleSelectRow}
518
- onShiftClickRow={handleShiftClickRow}
519
- renderProjectCell={renderProjectCell}
520
- renderDataCell={renderDataCell}
521
- reorderable={reorderable}
522
- isDragging={draggedRowIndex === index}
523
- isDragOver={dragOverRowIndex === index}
524
- onDragStart={handleDragStart}
525
- onDragOver={handleDragOver}
526
- onDragLeave={handleDragLeave}
527
- onDrop={handleDrop}
528
- onDragEnd={handleDragEnd}
529
- />
530
- ))}
531
- {showDropAfterRow && (
532
- <Table.Row
533
- className={classNames(styles.dropAfterRow, {
534
- [styles.dropAfterRowActive]: dragOverRowIndex === data.length,
535
- })}
536
- onDragOver={(e) => {
537
- e.preventDefault()
538
- e.dataTransfer.dropEffect = 'move'
539
- handleDragOverEnd()
540
- }}
541
- onDragLeave={handleDragLeaveEnd}
542
- onDrop={handleDropOnEnd}
543
- >
544
- <Table.Cell colSpan={totalColumnCount} className={styles.dropAfterCell} />
545
- </Table.Row>
546
- )}
547
- </Table.Body>
548
- </Table.Root>
168
+ <DataTableBody
169
+ rows={normalizedRows}
170
+ columns={columns}
171
+ sortableItems={sortableItems}
172
+ isRowSelected={isRowSelected}
173
+ anyRowChecked={anyRowChecked}
174
+ selectedCount={selectedCount}
175
+ sortedKey={sortedKey}
176
+ mobileSecondaryColumnId={mobileSecondaryColumnId}
177
+ hasDropdownOptions={hasDropdownOptions}
178
+ onClick={handleRowClick}
179
+ onSelectRow={handleSelectRow}
180
+ onShiftClickRow={handleShiftClickRow}
181
+ rowDraggable={rowDraggable}
182
+ reorderable={reorderable}
183
+ activeDragRowId={activeDragRowId}
184
+ overDragRowId={overDragRowId}
185
+ />
186
+ </Table.Root>
187
+
188
+ <DragOverlay>
189
+ {activeDragContext ? (
190
+ <div className={styles.dragOverlayContent}>
191
+ <DataTableDragOverlay
192
+ model={activeDragContext}
193
+ renderDragPreview={renderDragPreview}
194
+ getDragPreviewLabel={getDragPreviewLabel}
195
+ getDragPreviewCountLabel={getDragPreviewCountLabel}
196
+ />
197
+ </div>
198
+ ) : null}
199
+ </DragOverlay>
200
+ </DndContext>
549
201
  )
550
202
  }
551
203
 
552
- DataTable.displayName = 'DataTable'
204
+ DataTable.displayName = 'DataTable'