@moises.ai/design-system 3.10.6 → 3.10.7

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.6",
3
+ "version": "3.10.7",
4
4
  "description": "Design System package based on @radix-ui/themes with custom defaults",
5
5
  "private": false,
6
6
  "type": "module",
@@ -37,6 +37,7 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@dnd-kit/core": "^6.3.1",
40
+ "@dnd-kit/modifiers": "^9.0.0",
40
41
  "@dnd-kit/sortable": "^10.0.0",
41
42
  "@dnd-kit/utilities": "^3.2.2",
42
43
  "@radix-ui/react-icons": "1.3.2",
@@ -1,5 +1,6 @@
1
1
  import React, { useCallback, useMemo, useRef } from 'react'
2
2
  import { DndContext, DragOverlay } from '@dnd-kit/core'
3
+ import { snapCenterToCursor } from '@dnd-kit/modifiers'
3
4
  import { Table } from '../../index'
4
5
  import styles from './DataTable.module.css'
5
6
  import classNames from 'classnames'
@@ -27,10 +28,12 @@ export const DataTable = ({
27
28
  onReorder,
28
29
  rowDraggable,
29
30
  onRowDragStart,
31
+ onRowDragMove,
30
32
  onRowDragEnd,
31
33
  getDragPreviewLabel,
32
34
  getDragPreviewCountLabel,
33
35
  renderDragPreview,
36
+ renderDndContext = true,
34
37
  ...props
35
38
  }) => {
36
39
  const anchorRowIndexRef = useRef(null)
@@ -128,6 +131,7 @@ export const DataTable = ({
128
131
  reorderable,
129
132
  onReorder,
130
133
  onRowDragStart,
134
+ onRowDragMove,
131
135
  onRowDragEnd,
132
136
  })
133
137
 
@@ -137,55 +141,62 @@ export const DataTable = ({
137
141
  const stickyBodyOffsetValue =
138
142
  typeof stickyBodyOffset === 'number' ? `${stickyBodyOffset}px` : stickyBodyOffset
139
143
 
144
+ const tableRoot = (
145
+ <Table.Root
146
+ className={classNames(styles.DataTable, className)}
147
+ size="1"
148
+ style={{
149
+ '--datatable-sticky-offset': stickyOffsetValue,
150
+ '--datatable-sticky-body-offset': stickyBodyOffsetValue,
151
+ ...style,
152
+ }}
153
+ {...restProps}
154
+ >
155
+ <DataTableHeader
156
+ columns={columns}
157
+ sortedKey={sortedKey}
158
+ sorting={sorting}
159
+ mobileSecondaryColumnId={mobileSecondaryColumnId}
160
+ anyRowChecked={anyRowChecked}
161
+ allRowsChecked={allRowsChecked}
162
+ selectedFilesLabel={selectedFilesLabel}
163
+ selectedCount={selectedCount}
164
+ total={total}
165
+ hasDropdownOptions={hasDropdownOptions}
166
+ onSort={onSort}
167
+ onSelectAll={onSelectAll}
168
+ renderHeaderActions={renderHeaderActions}
169
+ />
170
+
171
+ <DataTableBody
172
+ rows={normalizedRows}
173
+ columns={columns}
174
+ sortableItems={sortableItems}
175
+ isRowSelected={isRowSelected}
176
+ anyRowChecked={anyRowChecked}
177
+ selectedCount={selectedCount}
178
+ sortedKey={sortedKey}
179
+ mobileSecondaryColumnId={mobileSecondaryColumnId}
180
+ hasDropdownOptions={hasDropdownOptions}
181
+ onClick={handleRowClick}
182
+ onSelectRow={handleSelectRow}
183
+ onShiftClickRow={handleShiftClickRow}
184
+ rowDraggable={rowDraggable}
185
+ reorderable={reorderable}
186
+ activeDragRowId={activeDragRowId}
187
+ overDragRowId={overDragRowId}
188
+ />
189
+ </Table.Root>
190
+ )
191
+
192
+ if (!renderDndContext) {
193
+ return tableRoot
194
+ }
195
+
140
196
  return (
141
197
  <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}
151
- >
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
- />
167
-
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>
198
+ {tableRoot}
199
+ <DragOverlay modifiers={[snapCenterToCursor]}>
189
200
  {activeDragContext ? (
190
201
  <div className={styles.dragOverlayContent}>
191
202
  <DataTableDragOverlay
@@ -195,17 +195,17 @@ const auxHeaderTable = [
195
195
  id: 'title',
196
196
  label: 'Title',
197
197
  sortable: true,
198
- onClick: () => { },
198
+ onClick: () => {},
199
199
  },
200
200
  {
201
201
  id: 'RECENT',
202
202
  label: 'Created',
203
203
  sortable: true,
204
- onClick: () => { },
204
+ onClick: () => {},
205
205
  },
206
- { id: 'BPM', label: 'BPM', onClick: () => { }, sortable: true },
207
- { id: 'KEY', label: 'Key', onClick: () => { }, sortable: true },
208
- { id: 'DURATION', label: 'Duration', onClick: () => { }, sortable: true },
206
+ { id: 'BPM', label: 'BPM', onClick: () => {}, sortable: true },
207
+ { id: 'KEY', label: 'Key', onClick: () => {}, sortable: true },
208
+ { id: 'DURATION', label: 'Duration', onClick: () => {}, sortable: true },
209
209
  ]
210
210
 
211
211
  const applyReorder = (rows, payload) => {
@@ -214,13 +214,18 @@ const applyReorder = (rows, payload) => {
214
214
 
215
215
  if (Array.isArray(orders) && orders.length > 1) {
216
216
  const validOrders = orders
217
- .filter((index) => Number.isInteger(index) && index >= 0 && index < rows.length)
217
+ .filter(
218
+ (index) => Number.isInteger(index) && index >= 0 && index < rows.length,
219
+ )
218
220
  .sort((a, b) => a - b)
219
221
  if (!validOrders.length) return rows
220
222
 
221
223
  const moveSet = new Set(validOrders)
222
224
  const rowsToMove = validOrders.map((index) => rows[index]).filter(Boolean)
223
- const safeMoveBefore = Math.max(0, Math.min(move_before ?? rows.length, rows.length))
225
+ const safeMoveBefore = Math.max(
226
+ 0,
227
+ Math.min(move_before ?? rows.length, rows.length),
228
+ )
224
229
  const selectedBeforeTarget = validOrders.filter(
225
230
  (index) => index < safeMoveBefore,
226
231
  ).length
@@ -232,13 +237,20 @@ const applyReorder = (rows, payload) => {
232
237
  }
233
238
 
234
239
  if (!Number.isInteger(order)) return rows
235
- const safeMoveBefore = Math.max(0, Math.min(move_before ?? rows.length, rows.length))
240
+ const safeMoveBefore = Math.max(
241
+ 0,
242
+ Math.min(move_before ?? rows.length, rows.length),
243
+ )
236
244
  if (order === safeMoveBefore || order + 1 === safeMoveBefore) return rows
237
245
 
238
246
  const nextRows = [...rows]
239
247
  const [item] = nextRows.splice(order, 1)
240
248
  if (!item) return rows
241
- nextRows.splice(safeMoveBefore > order ? safeMoveBefore - 1 : safeMoveBefore, 0, item)
249
+ nextRows.splice(
250
+ safeMoveBefore > order ? safeMoveBefore - 1 : safeMoveBefore,
251
+ 0,
252
+ item,
253
+ )
242
254
  return nextRows
243
255
  }
244
256
 
@@ -394,7 +406,7 @@ const SelectableTemplate = (args) => {
394
406
  getDragPreviewLabel={(row, selectedRows) =>
395
407
  selectedRows.length > 1
396
408
  ? `${selectedRows.length} files`
397
- : row.trackName ?? row.title
409
+ : (row.trackName ?? row.title)
398
410
  }
399
411
  stickyOffset={16}
400
412
  />
@@ -451,9 +463,7 @@ const ReorderableTemplate = (args) => {
451
463
  onSelectAll={(checked) =>
452
464
  setSelectedRowIds(checked ? rows.map((r) => r.id) : [])
453
465
  }
454
- onSort={(field, direction) =>
455
- setSorting({ field, sort: direction })
456
- }
466
+ onSort={(field, direction) => setSorting({ field, sort: direction })}
457
467
  onClick={(row) => console.log('Row clicked:', row)}
458
468
  reorderable={args.reorderable}
459
469
  rowDraggable={args.rowDraggable}
@@ -462,7 +472,7 @@ const ReorderableTemplate = (args) => {
462
472
  getDragPreviewLabel={(row, selectedRows) =>
463
473
  selectedRows.length > 1
464
474
  ? `${selectedRows.length} files`
465
- : row.trackName ?? row.title
475
+ : (row.trackName ?? row.title)
466
476
  }
467
477
  onReorder={handleReorder}
468
478
  stickyOffset={16}
@@ -506,12 +516,21 @@ export const Reorderable = {
506
516
  export const DragWithSelectionPreview = {
507
517
  render: (args) => {
508
518
  const [rows, setRows] = useState(auxBodyTable.slice(0, 7))
509
- const [selectedRowIds, setSelectedRowIds] = useState([rows[0].id, rows[1].id])
519
+ const [selectedRowIds, setSelectedRowIds] = useState([
520
+ rows[0].id,
521
+ rows[1].id,
522
+ ])
510
523
  const [dragInfo, setDragInfo] = useState('Start dragging a row')
511
524
 
512
525
  return (
513
526
  <div style={{ width: '100%', maxWidth: '1620px', maxHeight: '400px' }}>
514
- <div style={{ fontSize: 12, color: 'var(--neutral-alpha-11)', marginBottom: 8 }}>
527
+ <div
528
+ style={{
529
+ fontSize: 12,
530
+ color: 'var(--neutral-alpha-11)',
531
+ marginBottom: 8,
532
+ }}
533
+ >
515
534
  {dragInfo}
516
535
  </div>
517
536
  <DataTable
@@ -552,7 +571,7 @@ export const DragWithSelectionPreview = {
552
571
  getDragPreviewLabel={(row, selectedRows) =>
553
572
  selectedRows.length > 1
554
573
  ? `${selectedRows.length} files`
555
- : row.trackName ?? row.title
574
+ : (row.trackName ?? row.title)
556
575
  }
557
576
  getDragPreviewCountLabel={(count) =>
558
577
  count === 1 ? '1 arquivo' : `${count} arquivos`
@@ -582,8 +601,8 @@ export const Default = {
582
601
  children: 'DataTable Component',
583
602
  reorderable: false,
584
603
  rowDraggable: true,
585
- onSort: () => { },
586
- onClick: () => { },
604
+ onSort: () => {},
605
+ onClick: () => {},
587
606
  renderHeaderActions: ({ selectedCount, total }) => (
588
607
  <>
589
608
  <Button size="1" variant="soft" color="gray" disabled={!selectedCount}>
@@ -641,4 +660,4 @@ export const SortedByKey = {
641
660
  sort: 'ASC',
642
661
  },
643
662
  },
644
- }
663
+ }
@@ -1,5 +1,10 @@
1
1
  import { useCallback, useMemo, useState } from 'react'
2
- import { pointerWithin, PointerSensor, useSensor, useSensors } from '@dnd-kit/core'
2
+ import {
3
+ pointerWithin,
4
+ PointerSensor,
5
+ useSensor,
6
+ useSensors,
7
+ } from '@dnd-kit/core'
3
8
  import {
4
9
  buildReorderPayload,
5
10
  DATA_TABLE_DROP_TOP_ID,
@@ -1,19 +1,23 @@
1
1
  import { Flex, Text, Avatar, ScrollArea } from '@radix-ui/themes'
2
+ import { useDroppable } from '@dnd-kit/core'
2
3
  import styles from './SetlistList.module.css'
3
4
  import classNames from 'classnames'
4
- import {
5
- SetlistIcon,
6
- PlusIcon,
7
- } from '../../icons'
5
+ import { SetlistIcon, PlusIcon } from '../../icons'
8
6
  import { DropdownMenu } from '../DropdownMenu/DropdownMenu'
9
7
  import { Tooltip } from '../Tooltip/Tooltip'
10
- import { useState, useEffect, useRef, useMemo, Fragment } from 'react'
8
+ import { useState, useEffect, useRef, Fragment } from 'react'
11
9
  import { MoreButton } from '../MoreButton/MoreButton'
12
10
  import { useMobileDrawerContext } from '../../contexts/MobileDrawerContext'
13
11
 
14
12
  const SetlistIconFallback = () => <SetlistIcon width={16} height={16} />
15
13
 
16
- function SetlistExpandButton({ onExpand, className, style, collapsed = false, tooltip }) {
14
+ function SetlistExpandButton({
15
+ onExpand,
16
+ className,
17
+ style,
18
+ collapsed = false,
19
+ tooltip,
20
+ }) {
17
21
  const button = (
18
22
  <button
19
23
  type="button"
@@ -48,7 +52,12 @@ function SetlistExpandButton({ onExpand, className, style, collapsed = false, to
48
52
  )
49
53
  }
50
54
 
51
- function NewSetlistButton({ onClick, className, collapsed = false, text = 'New Setlist', }) {
55
+ function NewSetlistButton({
56
+ onClick,
57
+ className,
58
+ collapsed = false,
59
+ text = 'New Setlist',
60
+ }) {
52
61
  return (
53
62
  <SetlistItem
54
63
  isSelected={false}
@@ -58,12 +67,20 @@ function NewSetlistButton({ onClick, className, collapsed = false, text = 'New S
58
67
  <PlusIcon
59
68
  width={16}
60
69
  height={16}
61
- className={classNames(styles.iconSwapLayer, styles.iconVisible, styles.plusIcon)}
70
+ className={classNames(
71
+ styles.iconSwapLayer,
72
+ styles.iconVisible,
73
+ styles.plusIcon,
74
+ )}
62
75
  />
63
76
  </div>
64
77
  }
65
78
  text={text}
66
- className={classNames(styles.newSetlistItemButton, styles.collapsedTransition, className)}
79
+ className={classNames(
80
+ styles.newSetlistItemButton,
81
+ styles.collapsedTransition,
82
+ className,
83
+ )}
67
84
  collapsed={collapsed}
68
85
  />
69
86
  )
@@ -125,6 +142,7 @@ export const SetlistItem = ({
125
142
  isMobile = false,
126
143
  droppable = false,
127
144
  isDropTarget = false,
145
+ dndDroppableId,
128
146
  onDragEnter,
129
147
  onDragLeave,
130
148
  onDragOver,
@@ -132,6 +150,12 @@ export const SetlistItem = ({
132
150
  }) => {
133
151
  const [isHovering, setIsHovering] = useState(false)
134
152
 
153
+ const dndEnabled = Boolean(dndDroppableId)
154
+ const { setNodeRef: setDropRef, isOver: isDndOver } = useDroppable({
155
+ id: dndDroppableId ?? '__setlist-item-noop__',
156
+ disabled: !dndEnabled,
157
+ })
158
+
135
159
  const handleMouseEnter = () => {
136
160
  setIsHovering(true)
137
161
  }
@@ -150,6 +174,7 @@ export const SetlistItem = ({
150
174
 
151
175
  return (
152
176
  <Flex
177
+ ref={dndEnabled ? setDropRef : undefined}
153
178
  gap="3"
154
179
  align="center"
155
180
  role={onClick ? 'button' : undefined}
@@ -159,7 +184,7 @@ export const SetlistItem = ({
159
184
  [styles.navItemSelected]: isSelected,
160
185
  [styles.collapsed]: collapsed,
161
186
  [styles.menuOpen]: dropdownMenuOpen,
162
- [styles.dropTarget]: droppable && isDropTarget,
187
+ [styles.dropTarget]: (droppable && isDropTarget) || isDndOver,
163
188
  })}
164
189
  onMouseEnter={handleMouseEnter}
165
190
  onMouseLeave={handleMouseLeave}
@@ -171,11 +196,11 @@ export const SetlistItem = ({
171
196
  onKeyDown={
172
197
  onClick
173
198
  ? (e) => {
174
- if (e.key === 'Enter' || e.key === ' ') {
175
- e.preventDefault()
176
- onClick?.()
199
+ if (e.key === 'Enter' || e.key === ' ') {
200
+ e.preventDefault()
201
+ onClick?.()
202
+ }
177
203
  }
178
- }
179
204
  : undefined
180
205
  }
181
206
  style={style}