@moises.ai/design-system 3.7.0 → 3.7.1

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.
@@ -1,7 +1,7 @@
1
1
  import * as a from "react";
2
2
  import Y from "react";
3
- import { R as tr, u as ye, C as Yr, P as O, a as ae, b as Xr, T as Zr, c as le, d as or, e as _e, f as ce, g as G, h as Ie, i as P, A as Jr, j as Qr, k as en, G as tn, I as on, l as rn, L as nn, m as an, n as bt, o as sn, p as cn, q as ln, S as un, r as dn, s as fn, t as pn, v as Ve, w as vn, x as be, y as mn, z as Me, B as Xe, D as gn, E as Q, F as bn, H as hn, J as Cn, K as rr, M as nr, N as wn, O as Tn, Q as En, V as ar, U as yn, W as Rn, X as _n, Y as sr } from "./index-D51dkmoF.js";
4
- import { Z as Ni, _ as Fi, $ as Oi, a0 as Di, a1 as Li, a2 as ki, a3 as Vi, a4 as Ki, a5 as $i, a6 as Gi, a7 as Bi, a8 as Hi, a9 as zi, aa as Ui, ab as ji, ac as Wi, ad as qi, ae as Yi, af as Xi, ag as Zi, ah as Ji, ai as Qi } from "./index-D51dkmoF.js";
3
+ import { R as tr, u as ye, C as Yr, P as O, a as ae, b as Xr, T as Zr, c as le, d as or, e as _e, f as ce, g as G, h as Ie, i as P, A as Jr, j as Qr, k as en, G as tn, I as on, l as rn, L as nn, m as an, n as bt, o as sn, p as cn, q as ln, S as un, r as dn, s as fn, t as pn, v as Ve, w as vn, x as be, y as mn, z as Me, B as Xe, D as gn, E as Q, F as bn, H as hn, J as Cn, K as rr, M as nr, N as wn, O as Tn, Q as En, V as ar, U as yn, W as Rn, X as _n, Y as sr } from "./index-JoQmq6_y.js";
4
+ import { Z as Ni, _ as Fi, $ as Oi, a0 as Di, a1 as Li, a2 as ki, a3 as Vi, a4 as Ki, a5 as $i, a6 as Gi, a7 as Bi, a8 as Hi, a9 as zi, aa as Ui, ab as ji, ac as Wi, ad as qi, ae as Yi, af as Xi, ag as Zi, ah as Ji, ai as Qi } from "./index-JoQmq6_y.js";
5
5
  import { jsxs as ve, Fragment as me, jsx as i } from "react/jsx-runtime";
6
6
  import * as In from "react-dom";
7
7
  import Mn, { flushSync as pe } from "react-dom";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moises.ai/design-system",
3
- "version": "3.7.0",
3
+ "version": "3.7.1",
4
4
  "description": "Design System package based on @radix-ui/themes with custom defaults",
5
5
  "private": false,
6
6
  "type": "module",
@@ -28,10 +28,23 @@ const DataRow = React.memo(function DataRow({
28
28
  onShiftClickRow,
29
29
  renderProjectCell,
30
30
  renderDataCell,
31
+ reorderable,
32
+ isDragging,
33
+ isDragOver,
34
+ onDragStart,
35
+ onDragOver,
36
+ onDragLeave,
37
+ onDrop,
38
+ onDragEnd,
31
39
  }) {
32
40
  const shiftClickRef = useRef(false)
41
+ const didDragRef = useRef(false)
33
42
 
34
43
  const handleRowClick = (e) => {
44
+ if (didDragRef.current) {
45
+ didDragRef.current = false
46
+ return
47
+ }
35
48
  if (e.shiftKey) {
36
49
  e.preventDefault()
37
50
  onShiftClickRow?.(row, rowIndex)
@@ -72,15 +85,58 @@ const DataRow = React.memo(function DataRow({
72
85
 
73
86
  const showDropdownAlways = isSelected && selectedCount === 1
74
87
 
88
+ const handleDragStart = (e) => {
89
+ didDragRef.current = true
90
+ e.dataTransfer.setData('text/plain', String(rowIndex))
91
+ e.dataTransfer.effectAllowed = 'move'
92
+ onDragStart?.(rowIndex)
93
+
94
+ const table = e.currentTarget.closest('table')
95
+ if (table) {
96
+ const dragImage = document.createElement('div')
97
+ dragImage.className = styles.dragImage
98
+ dragImage.style.width = `${table.offsetWidth}px`
99
+ dragImage.style.minWidth = `${table.offsetWidth}px`
100
+ document.body.appendChild(dragImage)
101
+ e.dataTransfer.setDragImage(dragImage, 0, 0)
102
+ requestAnimationFrame(() => {
103
+ if (dragImage.parentNode) {
104
+ document.body.removeChild(dragImage)
105
+ }
106
+ })
107
+ }
108
+ }
109
+
110
+ const handleDragOver = (e) => {
111
+ e.preventDefault()
112
+ e.dataTransfer.dropEffect = 'move'
113
+ onDragOver?.(rowIndex)
114
+ }
115
+
116
+ const handleDrop = (e) => {
117
+ e.preventDefault()
118
+ const fromIndex = parseInt(e.dataTransfer.getData('text/plain'), 10)
119
+ onDrop?.(fromIndex, rowIndex)
120
+ }
121
+
75
122
  return (
76
123
  <Table.Row
77
124
  className={classNames({
78
125
  [styles.rowSelected]: isSelected,
79
126
  [styles.showDropdownOnSelect]: showDropdownAlways,
127
+ [styles.rowDragging]: isDragging,
128
+ [styles.rowDragOver]: isDragOver,
129
+ [styles.rowReorderable]: reorderable,
80
130
  })}
81
131
  style={
82
132
  isSelected ? { '--row-bg': 'var(--aqua-dark-alpha-2)' } : undefined
83
133
  }
134
+ draggable={reorderable}
135
+ onDragStart={reorderable ? handleDragStart : undefined}
136
+ onDragOver={reorderable ? handleDragOver : undefined}
137
+ onDragLeave={reorderable ? onDragLeave : undefined}
138
+ onDrop={reorderable ? handleDrop : undefined}
139
+ onDragEnd={reorderable ? onDragEnd : undefined}
84
140
  >
85
141
  <Table.Cell
86
142
  className={styles.selectColumn}
@@ -156,9 +212,13 @@ export const DataTable = ({
156
212
  onSelectRow,
157
213
  stickyOffset = 0,
158
214
  stickyBodyOffset = 0,
215
+ reorderable = false,
216
+ onReorder,
159
217
  ...props
160
218
  }) => {
161
219
  const [isHeaderHovering, setIsHeaderHovering] = useState(false)
220
+ const [draggedRowIndex, setDraggedRowIndex] = useState(null)
221
+ const [dragOverRowIndex, setDragOverRowIndex] = useState(null)
162
222
  const anchorRowIndexRef = useRef(null)
163
223
 
164
224
  const sortedKey = sorting?.field
@@ -259,6 +319,61 @@ export const DataTable = ({
259
319
  [anyRowChecked, allRowsChecked, onSelectAll],
260
320
  )
261
321
 
322
+ const handleDragStart = useCallback((rowIndex) => {
323
+ setDraggedRowIndex(rowIndex)
324
+ }, [])
325
+
326
+ const handleDragOver = useCallback((rowIndex) => {
327
+ setDragOverRowIndex(rowIndex)
328
+ }, [])
329
+
330
+ const handleDragLeave = useCallback(() => {
331
+ setDragOverRowIndex(null)
332
+ }, [])
333
+
334
+ const handleDrop = useCallback(
335
+ (order, moveBefore) => {
336
+ setDraggedRowIndex(null)
337
+ setDragOverRowIndex(null)
338
+ if (order === moveBefore || order + 1 === moveBefore) return
339
+ onReorder?.({ order, move_before: moveBefore })
340
+ },
341
+ [onReorder],
342
+ )
343
+
344
+ const handleDragEnd = useCallback(() => {
345
+ setDraggedRowIndex(null)
346
+ setDragOverRowIndex(null)
347
+ }, [])
348
+
349
+ const handleDragOverEnd = useCallback(() => {
350
+ setDragOverRowIndex(data?.length ?? 0)
351
+ }, [data?.length])
352
+
353
+ const handleDragLeaveEnd = useCallback(() => {
354
+ setDragOverRowIndex(null)
355
+ }, [])
356
+
357
+ const handleDropOnEnd = useCallback(
358
+ (e) => {
359
+ e.preventDefault()
360
+ const fromIndex = parseInt(e.dataTransfer.getData('text/plain'), 10)
361
+ const moveBefore = data?.length ?? 0
362
+ setDraggedRowIndex(null)
363
+ setDragOverRowIndex(null)
364
+ if (fromIndex === moveBefore || fromIndex + 1 === moveBefore) return
365
+ onReorder?.({ order: fromIndex, move_before: moveBefore })
366
+ },
367
+ [data?.length, onReorder],
368
+ )
369
+
370
+ const totalColumnCount =
371
+ 1 +
372
+ (columns?.length ?? 0) +
373
+ (hasDropdownOptions ? 1 : 0)
374
+ const showDropAfterRow =
375
+ reorderable && data?.length && draggedRowIndex !== null
376
+
262
377
  const renderDataCell = useCallback((row, column, index) => {
263
378
  const baseValue = row?.[column.id] ?? row?.[`${column.id}Formatted`]
264
379
  const value =
@@ -382,8 +497,32 @@ export const DataTable = ({
382
497
  onShiftClickRow={handleShiftClickRow}
383
498
  renderProjectCell={renderProjectCell}
384
499
  renderDataCell={renderDataCell}
500
+ reorderable={reorderable}
501
+ isDragging={draggedRowIndex === index}
502
+ isDragOver={dragOverRowIndex === index}
503
+ onDragStart={handleDragStart}
504
+ onDragOver={handleDragOver}
505
+ onDragLeave={handleDragLeave}
506
+ onDrop={handleDrop}
507
+ onDragEnd={handleDragEnd}
385
508
  />
386
509
  ))}
510
+ {showDropAfterRow && (
511
+ <Table.Row
512
+ className={classNames(styles.dropAfterRow, {
513
+ [styles.dropAfterRowActive]: dragOverRowIndex === data.length,
514
+ })}
515
+ onDragOver={(e) => {
516
+ e.preventDefault()
517
+ e.dataTransfer.dropEffect = 'move'
518
+ handleDragOverEnd()
519
+ }}
520
+ onDragLeave={handleDragLeaveEnd}
521
+ onDrop={handleDropOnEnd}
522
+ >
523
+ <Table.Cell colSpan={totalColumnCount} className={styles.dropAfterCell} />
524
+ </Table.Row>
525
+ )}
387
526
  </Table.Body>
388
527
  </Table.Root>
389
528
  )
@@ -292,6 +292,62 @@
292
292
  opacity: 1;
293
293
  }
294
294
 
295
+ .rowDragging {
296
+ opacity: 0.5;
297
+ }
298
+
299
+ .rowDragOver {
300
+ box-shadow: inset 0 2px 0 0 var(--accent-9);
301
+ }
302
+
303
+ .rowReorderable {
304
+ cursor: grab;
305
+ }
306
+
307
+ .rowReorderable:active {
308
+ cursor: grabbing;
309
+ }
310
+
311
+ /* Drag image personalizada - largura total da tabela */
312
+ .dragImage {
313
+ position: absolute;
314
+ top: -9999px;
315
+ left: -9999px;
316
+ height: 56px;
317
+ min-height: 56px;
318
+ background: var(--accent-alpha-4);
319
+ border-radius: 8px;
320
+ opacity: 0.9;
321
+ pointer-events: none;
322
+ }
323
+
324
+ .dropAfterRow {
325
+ height: 8px;
326
+ min-height: 8px;
327
+ background: transparent;
328
+ border-radius: 0;
329
+ }
330
+
331
+ .dropAfterRowActive {
332
+ background: var(--accent-alpha-4);
333
+ box-shadow: inset 0 2px 0 0 var(--accent-9);
334
+ }
335
+
336
+ .dropAfterCell {
337
+ width: 100%;
338
+ height: 8px;
339
+ padding: 0;
340
+ vertical-align: middle;
341
+ border: none;
342
+ box-sizing: border-box;
343
+ }
344
+
345
+ /* Garante que a célula ocupe toda a largura da tabela */
346
+ .DataTable :global(.rt-TableRootTable) .dropAfterRow .dropAfterCell {
347
+ width: 100%;
348
+ min-width: 100%;
349
+ }
350
+
295
351
  .DataTable :global(.rt-TableRow:hover) .dropdownTriggerWrapperIcon,
296
352
  .dropdownColumn:focus-within .dropdownTriggerWrapperIcon,
297
353
  .showDropdownOnSelect .dropdownTriggerWrapperIcon {
@@ -219,6 +219,12 @@ export default {
219
219
  onSort: {
220
220
  action: 'onSort',
221
221
  },
222
+ onReorder: {
223
+ action: 'onReorder',
224
+ },
225
+ reorderable: {
226
+ control: 'boolean',
227
+ },
222
228
  renderHeaderActions: {
223
229
  control: 'function',
224
230
  },
@@ -335,6 +341,98 @@ const SelectableTemplate = (args) => {
335
341
  )
336
342
  }
337
343
 
344
+ const ReorderableTemplate = (args) => {
345
+ const [rows, setRows] = useState(auxBodyTable.slice(0, 5))
346
+ const [selectedRowIds, setSelectedRowIds] = useState([])
347
+ const [sorting, setSorting] = useState(
348
+ args.initialSorting ?? { field: 'RECENT', sort: 'DESC' },
349
+ )
350
+
351
+ const sortRows = (items, { field, sort } = {}) => {
352
+ if (!field) return items
353
+ const sorted = [...items].sort((a, b) => {
354
+ const av = a[field]
355
+ const bv = b[field]
356
+ if (av === bv) return 0
357
+ if (av == null) return -1
358
+ if (bv == null) return 1
359
+ if (typeof av === 'number' && typeof bv === 'number') return av - bv
360
+ return String(av).localeCompare(String(bv))
361
+ })
362
+ return String(sort).toUpperCase() === 'ASC' ? sorted : sorted.reverse()
363
+ }
364
+
365
+ const handleReorder = ({ order, move_before }) => {
366
+ args.onReorder?.({ order, move_before })
367
+ setRows((prev) => {
368
+ const next = [...prev]
369
+ const [item] = next.splice(order, 1)
370
+ next.splice(move_before > order ? move_before - 1 : move_before, 0, item)
371
+ return next
372
+ })
373
+ }
374
+
375
+ // Reorderable: mostra na ordem atual (sem reaplicar sort) para a reordenação refletir na tela
376
+ const displayRows = rows
377
+
378
+ return (
379
+ <DataTable
380
+ {...args}
381
+ columns={auxHeaderTable}
382
+ data={displayRows}
383
+ sorting={sorting}
384
+ selectedRowIds={selectedRowIds}
385
+ onSelectRow={(id, checked) =>
386
+ setSelectedRowIds((prev) =>
387
+ checked ? [...prev, id] : prev.filter((x) => x !== id),
388
+ )
389
+ }
390
+ onSelectAll={(checked) =>
391
+ setSelectedRowIds(checked ? rows.map((r) => r.id) : [])
392
+ }
393
+ onSort={(field, direction) =>
394
+ setSorting({ field, sort: direction })
395
+ }
396
+ onClick={(row) => console.log('Row clicked:', row)}
397
+ reorderable={args.reorderable}
398
+ onReorder={handleReorder}
399
+ stickyOffset={16}
400
+ />
401
+ )
402
+ }
403
+
404
+ export const Reorderable = {
405
+ render: (args) => (
406
+ <div
407
+ style={{
408
+ width: '100%',
409
+ maxWidth: '1620px',
410
+ maxHeight: '400px',
411
+ }}
412
+ >
413
+ <ReorderableTemplate {...args} />
414
+ </div>
415
+ ),
416
+ args: {
417
+ reorderable: true,
418
+ onReorder: (payload) => console.log('onReorder', payload),
419
+ renderHeaderActions: ({ selectedCount, total }) => (
420
+ <>
421
+ <Button size="1" variant="soft" color="gray" disabled={!selectedCount}>
422
+ Delete
423
+ </Button>
424
+ <Button size="1" variant="soft" disabled={!selectedCount}>
425
+ Add to setlist…
426
+ </Button>
427
+ </>
428
+ ),
429
+ initialSorting: {
430
+ field: 'RECENT',
431
+ sort: 'DESC',
432
+ },
433
+ },
434
+ }
435
+
338
436
  export const Default = {
339
437
  render: (args) => (
340
438
  <div
@@ -351,6 +449,7 @@ export const Default = {
351
449
  ),
352
450
  args: {
353
451
  children: 'DataTable Component',
452
+ reorderable: false,
354
453
  onSort: () => { },
355
454
  onClick: () => { },
356
455
  renderHeaderActions: ({ selectedCount, total }) => (