@moises.ai/design-system 3.6.3 → 3.6.4

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.6.3",
3
+ "version": "3.6.4",
4
4
  "description": "Design System package based on @radix-ui/themes with custom defaults",
5
5
  "private": false,
6
6
  "type": "module",
@@ -13,12 +13,51 @@ import { Tooltip } from '../Tooltip/Tooltip'
13
13
  import { useState, useEffect, useRef, useMemo, Fragment } from 'react'
14
14
  import { MoreButton } from '../MoreButton/MoreButton'
15
15
 
16
+ const SetlistIconFallback = () => <SetlistIcon width={16} height={16} />
17
+
18
+ function renderSetlistAvatar(icon) {
19
+ if (!icon) return <SetlistIconFallback />
20
+ if (typeof icon === 'string') {
21
+ return (
22
+ <Avatar
23
+ src={icon}
24
+ fallback={<SetlistIconFallback />}
25
+ size="3"
26
+ radius="small"
27
+ />
28
+ )
29
+ }
30
+ if (Array.isArray(icon)) {
31
+ if (icon.length === 0) return <SetlistIconFallback />
32
+ if (icon.length >= 4) {
33
+ const urls = icon.slice(0, 4)
34
+ return (
35
+ <div className={styles.iconGrid}>
36
+ {urls.map((src, i) => (
37
+ <div key={i} className={styles.iconGridCell}>
38
+ <img src={src} alt="" />
39
+ </div>
40
+ ))}
41
+ </div>
42
+ )
43
+ }
44
+ return (
45
+ <Avatar
46
+ src={icon[0]}
47
+ fallback={<SetlistIconFallback />}
48
+ size="3"
49
+ radius="small"
50
+ />
51
+ )
52
+ }
53
+ return icon
54
+ }
55
+
16
56
  export const SetlistItem = ({
17
57
  isSelected,
18
58
  onClick,
19
59
  className,
20
60
  style,
21
- avatarStyle,
22
61
  avatar,
23
62
  text,
24
63
  subtitle,
@@ -78,14 +117,13 @@ export const SetlistItem = ({
78
117
  })}
79
118
  >
80
119
  {avatar && (
81
- <div className={styles.avatarSetlist} style={avatarStyle}>
120
+ <div className={styles.avatarSetlist}>
82
121
  {typeof avatar === 'string' ? (
83
122
  <Avatar
84
123
  src={avatar}
85
124
  fallback={<SetlistIcon width={16} height={16} />}
86
- // size="3"
125
+ size="3"
87
126
  radius="small"
88
- style={avatarStyle}
89
127
  />
90
128
  ) : (
91
129
  avatar
@@ -152,12 +190,13 @@ export const SetlistList = ({
152
190
  }) => {
153
191
  const [openSetlistMenuId, setOpenSetlistMenuId] = useState(null)
154
192
  const [isHoveredWhenCollapsed, setIsHoveredWhenCollapsed] = useState(false)
155
- const [isFullyCollapsed, setIsFullyCollapsed] = useState(false)
193
+ const [isShrinking, setIsShrinking] = useState(false)
156
194
  const hoverTimeoutRef = useRef(null)
157
- const collapseCenterTimeoutRef = useRef(null)
195
+ const shrinkTimeoutRef = useRef(null)
158
196
  const hoverRegionRef = useRef(null)
197
+ const shrinkDuration = 260
159
198
  const collapsedItemHeight = 44
160
- const collapsedVisibleOffset = 8
199
+ const collapsedVisibleOffset = 4
161
200
  const maxCollapsedItems = 4
162
201
  const collapsedNewItemOffset = collapsed && onNewSetlistClick ? 1 : 0
163
202
  const showCollapsedStack = collapsed && !isHoveredWhenCollapsed
@@ -171,6 +210,11 @@ export const SetlistList = ({
171
210
  clearTimeout(hoverTimeoutRef.current)
172
211
  hoverTimeoutRef.current = null
173
212
  }
213
+ if (shrinkTimeoutRef.current) {
214
+ clearTimeout(shrinkTimeoutRef.current)
215
+ shrinkTimeoutRef.current = null
216
+ }
217
+ setIsShrinking(false)
174
218
  setIsHoveredWhenCollapsed(true)
175
219
  }
176
220
  const handleMouseLeave = () => {
@@ -179,8 +223,13 @@ export const SetlistList = ({
179
223
  clearTimeout(hoverTimeoutRef.current)
180
224
  }
181
225
  hoverTimeoutRef.current = setTimeout(() => {
182
- setIsHoveredWhenCollapsed(false)
183
226
  hoverTimeoutRef.current = null
227
+ setIsShrinking(true)
228
+ shrinkTimeoutRef.current = setTimeout(() => {
229
+ shrinkTimeoutRef.current = null
230
+ setIsHoveredWhenCollapsed(false)
231
+ setIsShrinking(false)
232
+ }, shrinkDuration)
184
233
  }, 180)
185
234
  }
186
235
 
@@ -199,33 +248,10 @@ export const SetlistList = ({
199
248
  }, 0)
200
249
  }
201
250
 
202
- // Só centraliza os avatares depois que a sidebar terminou de colapsar (width 280ms + delay 100ms)
203
- const collapseAnimationDuration = 400
204
251
  useEffect(() => {
205
- if (showCollapsedStack) {
206
- collapseCenterTimeoutRef.current = setTimeout(() => {
207
- setIsFullyCollapsed(true)
208
- collapseCenterTimeoutRef.current = null
209
- }, collapseAnimationDuration)
210
- } else {
211
- setIsFullyCollapsed(false)
212
- if (collapseCenterTimeoutRef.current) {
213
- clearTimeout(collapseCenterTimeoutRef.current)
214
- collapseCenterTimeoutRef.current = null
215
- }
216
- }
217
252
  return () => {
218
- if (collapseCenterTimeoutRef.current) {
219
- clearTimeout(collapseCenterTimeoutRef.current)
220
- }
221
- }
222
- }, [showCollapsedStack])
223
-
224
- useEffect(() => {
225
- return () => {
226
- if (hoverTimeoutRef.current) {
227
- clearTimeout(hoverTimeoutRef.current)
228
- }
253
+ if (hoverTimeoutRef.current) clearTimeout(hoverTimeoutRef.current)
254
+ if (shrinkTimeoutRef.current) clearTimeout(shrinkTimeoutRef.current)
229
255
  }
230
256
  }, [])
231
257
 
@@ -251,9 +277,7 @@ export const SetlistList = ({
251
277
  </div>
252
278
  )
253
279
 
254
- const collapsedStackAvatarSizes = ['38px', '37px', '36px', '35px']
255
-
256
- const getCollapsedStackStyle = (index, setlist) => {
280
+ const getCollapsedStackStyle = (index) => {
257
281
  if (!collapsed) return undefined
258
282
  if (!showCollapsedStack) {
259
283
  return {
@@ -304,8 +328,8 @@ export const SetlistList = ({
304
328
  direction="column"
305
329
  className={classNames(styles.setlistsContent, {
306
330
  [styles.collapsedStack]: showCollapsedStack,
307
- [styles.collapsedStackCentered]: isFullyCollapsed,
308
331
  [styles.collapsedMask]: collapsed,
332
+ [styles.collapsedShrinking]: isShrinking,
309
333
  })}
310
334
  >
311
335
  {onNewSetlistClick &&
@@ -347,15 +371,7 @@ export const SetlistList = ({
347
371
  onDropdownMenuOpenChange={(nextOpen) => {
348
372
  setOpenSetlistMenuId(nextOpen ? setlist.id : null)
349
373
  }}
350
- avatar={setlist.icon || <SetlistIcon width={16} height={16} />}
351
- avatarStyle={
352
- showCollapsedStack
353
- ? {
354
- width: collapsedStackAvatarSizes[index],
355
- height: collapsedStackAvatarSizes[index],
356
- }
357
- : undefined
358
- }
374
+ avatar={renderSetlistAvatar(setlist.icon)}
359
375
  group={setlist.group}
360
376
  moises={setlist.moises}
361
377
  text={setlist.label}
@@ -367,7 +383,7 @@ export const SetlistList = ({
367
383
  [styles.collapsedStackItem]: showCollapsedStack,
368
384
  [styles.collapsedTransition]: collapsed,
369
385
  })}
370
- style={getCollapsedStackStyle(index, setlist)}
386
+ style={getCollapsedStackStyle(index)}
371
387
  />
372
388
  )
373
389
  return collapsed && !showCollapsedStack ? (
@@ -90,6 +90,30 @@
90
90
  z-index: 1;
91
91
  }
92
92
 
93
+ .iconGrid {
94
+ display: grid;
95
+ grid-template-columns: 1fr 1fr;
96
+ grid-template-rows: 1fr 1fr;
97
+ width: 100%;
98
+ height: 100%;
99
+ border-radius: 4px;
100
+ overflow: hidden;
101
+ background: var(--neutral-2);
102
+ }
103
+
104
+ .iconGridCell {
105
+ position: relative;
106
+ overflow: hidden;
107
+ }
108
+
109
+ .iconGridCell img {
110
+ position: absolute;
111
+ inset: 0;
112
+ width: 100%;
113
+ height: 100%;
114
+ object-fit: cover;
115
+ }
116
+
93
117
  .textNewSetlist {
94
118
  max-width: 115px;
95
119
  opacity: 1;
@@ -201,9 +225,6 @@
201
225
  gap: 0;
202
226
  }
203
227
 
204
- .collapsedStackCentered {
205
- align-items: center;
206
- }
207
228
  .collapsedStackItem {
208
229
  position: relative;
209
230
  /* justify-content: flex-start; */
@@ -214,7 +235,13 @@
214
235
  overflow: hidden;
215
236
  padding-top: 2px;
216
237
  display: flex;
217
-
238
+ max-height: 80vh;
239
+ transition: max-height 260ms ease-in-out;
240
+ }
241
+
242
+ .collapsedMask.collapsedStack,
243
+ .collapsedMask.collapsedShrinking {
244
+ max-height: 120px;
218
245
  }
219
246
 
220
247
  /* .collapsedStack.collapsedMask {
@@ -222,7 +249,7 @@
222
249
  } */
223
250
 
224
251
  .collapsedTransition {
225
- transition: margin-top 360ms ease-in-out;
252
+ transition: margin-top 260ms ease-in-out;
226
253
  }
227
254
 
228
255
  .contentInner {
@@ -1,6 +1,164 @@
1
1
  import { useState } from 'react'
2
2
  import { SetlistList } from './SetlistList'
3
- import { MusicNoteIcon } from '../../icons'
3
+
4
+ const defaultSetlists = [
5
+ {
6
+ id: 'b55ae387-6f5e-44e9-af9f-c05e0438db69',
7
+ label: 'Jam Sessions with Charlie Puth',
8
+ description:
9
+ 'Submit your cover or remix of "Beat Yourself Up" for a chance to win your share of $100,000* in prizes, including cash, music gear, and an all-expenses-paid NYC trip to meet Charlie backstage at Madison Square Garden.',
10
+ subtitle: 'By Moises',
11
+ moises: true,
12
+ icon: 'https://storage.googleapis.com/moises-stage-api-assets/setlists/jam-sessions-charlie-puth-setlist-title/logo-1770055262172-charlie-puth-cover-132x132-3x-png',
13
+ group: false,
14
+ dropdownMenuOptions: [
15
+ {
16
+ type: 'item',
17
+ key: 'leave-setlist',
18
+ label: 'Leave setlist',
19
+ color: 'red',
20
+ },
21
+ ],
22
+ },
23
+ {
24
+ id: '00fc53a1-da6f-4b9c-afc0-64e40892d32a',
25
+ label: 'track, master and voice',
26
+ description: '',
27
+ subtitle: 'By testeqajp265',
28
+ moises: false,
29
+ icon: [
30
+ 'https://d2-stage.moises.ai/v3/download/moises-stage--tasks/operations/FILEMETADATA_A/bf262dfd-8fe5-4e2a-8baa-ca8971690f62/cover.jpeg',
31
+ 'https://d2-stage.moises.ai/v3/download/moises-stage--tasks/operations/FILEMETADATA_A/62b4b14d-b81f-4ef4-b681-bf6c863f9db8/cover.jpeg',
32
+ 'https://d2-stage.moises.ai/v3/download/moises-stage--tasks/operations/FILEMETADATA_A/5db13e39-a0ac-4251-a4b5-4edb35f6b4a2/cover.jpeg',
33
+ 'https://d3-stage.moises.ai/v3/download/moises-stage--tasks/operations/FILEMETADATA_A/9315c6df-aa12-4265-bb6d-594f638d8a63/cover.jpeg',
34
+ ],
35
+ group: true,
36
+ dropdownMenuOptions: [
37
+ {
38
+ type: 'item',
39
+ key: 'leave-setlist',
40
+ label: 'Leave setlist',
41
+ color: 'red',
42
+ },
43
+ ],
44
+ },
45
+ {
46
+ id: '15c1b18e-a0b8-439a-9480-78660562173b',
47
+ label: 'Minha setlist #532',
48
+ description: '',
49
+ subtitle: 'By Swanny Kathllen',
50
+ moises: false,
51
+ icon: [
52
+ 'https://d2-stage.moises.ai/v3/download/moises-stage--tasks-us-east1/operations/FILEMETADATA_A/8e5ec2e6-61f4-4721-9ed0-c31fda5904ab/cover.jpeg',
53
+ 'https://d2-stage.moises.ai/v3/download/moises-stage--tasks/operations/FILEMETADATA_A/b4112cfb-3f37-4551-bd42-8ce9fcaec2b0/cover.jpeg',
54
+ 'https://d1-stage.moises.ai/v3/download/moises-stage--tasks/operations/FILEMETADATA_A/2e6d2a5f-d9c8-4750-bf9e-12f5d0b43f1d/cover.jpeg',
55
+ ],
56
+ group: false,
57
+ dropdownMenuOptions: [
58
+ { type: 'item', key: 'edit', label: 'Edit' },
59
+ { type: 'separator', key: 'separator-edit' },
60
+ { type: 'item', key: 'delete', label: 'Delete', color: 'red' },
61
+ ],
62
+ },
63
+ {
64
+ id: '85aabd11-4bfe-4f5e-814a-c450fa3695fd',
65
+ label: 'My Setlist #4',
66
+ description: '',
67
+ subtitle: 'By Swanny Kathllen',
68
+ moises: false,
69
+ icon: [],
70
+ group: true,
71
+ dropdownMenuOptions: [
72
+ {
73
+ type: 'item',
74
+ key: 'leave-setlist',
75
+ label: 'Leave setlist',
76
+ color: 'red',
77
+ },
78
+ ],
79
+ },
80
+ {
81
+ id: 'd234cc21-b271-4f11-af53-73fdc685e83b',
82
+ label: 'My Setlist #3',
83
+ description: '',
84
+ subtitle: 'By Swanny Kathllen',
85
+ moises: false,
86
+ group: false,
87
+ dropdownMenuOptions: [
88
+ { type: 'item', key: 'edit', label: 'Edit' },
89
+ { type: 'separator', key: 'separator-edit' },
90
+ { type: 'item', key: 'delete', label: 'Delete', color: 'red' },
91
+ ],
92
+ },
93
+ {
94
+ id: 'd7fe60bb-261e-4f55-89c3-80cffcb018d1',
95
+ label: 'playlist de outro user [não editável]',
96
+ description: '',
97
+ subtitle: 'By Swanny Kathllen',
98
+ moises: false,
99
+ group: true,
100
+ dropdownMenuOptions: [
101
+ {
102
+ type: 'item',
103
+ key: 'leave-setlist',
104
+ label: 'Leave setlist',
105
+ color: 'red',
106
+ },
107
+ ],
108
+ },
109
+ {
110
+ id: '0a3668ac-24f0-4363-a018-5ca9b1d22cfe',
111
+ label: 'Playlist de outro usuário [editável]',
112
+ description: '',
113
+ subtitle: 'By Swanny Kathllen',
114
+ moises: false,
115
+ group: true,
116
+ dropdownMenuOptions: [
117
+ {
118
+ type: 'item',
119
+ key: 'leave-setlist',
120
+ label: 'Leave setlist',
121
+ color: 'red',
122
+ },
123
+ ],
124
+ },
125
+ {
126
+ id: 'df74975a-fbfe-4000-9ce1-d02d998ecd7f',
127
+ label: 'Guitar Exercises',
128
+ description:
129
+ 'Improve your chops with these Berklee Online guitar exercises, pulled from actual courses.',
130
+ subtitle: 'By Berklee Online',
131
+ moises: true,
132
+ icon: 'https://storage.googleapis.com/moises-api-assets/setlists/berklee2.png',
133
+ group: false,
134
+ dropdownMenuOptions: [
135
+ {
136
+ type: 'item',
137
+ key: 'leave-setlist',
138
+ label: 'Leave setlist',
139
+ color: 'red',
140
+ },
141
+ ],
142
+ },
143
+ {
144
+ id: '66d16b7e-2dc0-46e9-8706-56b7d4133104',
145
+ label: 'Moises Collection',
146
+ description:
147
+ 'Songs written and recorded by the Moises community. For demo purposes only.',
148
+ subtitle: 'By Moises',
149
+ moises: true,
150
+ icon: 'https://storage.googleapis.com/moises-api-assets/moises-collection-cover.png',
151
+ group: true,
152
+ dropdownMenuOptions: [
153
+ {
154
+ type: 'item',
155
+ key: 'leave-setlist',
156
+ label: 'Leave setlist',
157
+ color: 'red',
158
+ },
159
+ ],
160
+ },
161
+ ]
4
162
 
5
163
  export default {
6
164
  title: 'Components/SetlistList',
@@ -14,12 +172,14 @@ export default {
14
172
 
15
173
  export const Default = {
16
174
  render: (args) => {
17
- const [selectedSetlistId, setSelectedSetlistId] =
18
- useState('piano-exercises')
175
+ const [selectedSetlistId, setSelectedSetlistId] = useState(
176
+ defaultSetlists[0].id
177
+ )
19
178
 
20
179
  return (
21
180
  <SetlistList
22
181
  {...args}
182
+ setlists={defaultSetlists}
23
183
  selectedSetlistId={selectedSetlistId}
24
184
  onSetlistClick={(id) => {
25
185
  setSelectedSetlistId(id)
@@ -32,63 +192,7 @@ export const Default = {
32
192
  )
33
193
  },
34
194
  args: {
35
- setlists: [
36
- {
37
- id: 'piano-exercises',
38
- label: 'Piano Exercises',
39
- subtitle: 'By Berklee',
40
- moises: true,
41
- icon: 'https://storage.googleapis.com/moises-api-assets/setlists/jamsession_cory/cover.png',
42
- dropdownMenuOptions: [
43
- {
44
- type: 'item',
45
- key: 'edit',
46
- label: 'Edit',
47
- onClick: () => console.log('Edit clicked'),
48
- },
49
- ],
50
- },
51
- {
52
- id: 'bossa-nova',
53
- label: 'Bossa Nova Essentials',
54
- dropdownMenuOptions: [
55
- {
56
- type: 'item',
57
- key: 'edit',
58
- label: 'Edit',
59
- onClick: () => console.log('Edit clicked'),
60
- },
61
- ],
62
- },
63
- {
64
- id: 'band-rehearsal',
65
- label: 'Band Rehearsal',
66
- subtitle: 'By Nickyz dsdasdas',
67
- moises: true,
68
- group: true,
69
- dropdownMenuOptions: [
70
- {
71
- type: 'item',
72
- key: 'edit',
73
- label: 'Edit',
74
- onClick: () => console.log('Edit clicked'),
75
- },
76
- ],
77
- },
78
- {
79
- id: 'gig-dec-21',
80
- label: 'Gig Dec 21th',
81
- icon: <MusicNoteIcon width={16} height={16} />,
82
- dropdownMenuOptions: [
83
- {
84
- type: 'item',
85
- key: 'edit',
86
- label: 'Edit',
87
- onClick: () => console.log('Edit clicked'),
88
- },
89
- ],
90
- },
91
- ],
195
+ setlists: defaultSetlists,
92
196
  collapsed: false,
93
197
  isMobile: false,
94
198
  },