@moises.ai/design-system 3.5.3 → 3.5.5

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.
Files changed (42) hide show
  1. package/dist/{EditIcon-DOFkQeiV.js → EditIcon-Bn6TqXCt.js} +12 -6
  2. package/dist/icons.js +1 -1
  3. package/dist/index.js +3431 -3348
  4. package/package.json +1 -1
  5. package/src/components/Button/Button.module.css +19 -2
  6. package/src/components/DataTable/DataTable.jsx +120 -33
  7. package/src/components/DataTable/DataTable.module.css +14 -32
  8. package/src/components/DataTable/DataTable.stories.jsx +13 -7
  9. package/src/components/DropdownMenu/DropdownMenu.stories.jsx +62 -23
  10. package/src/components/IconButton/IconButton.module.css +47 -8
  11. package/src/components/MoreButton/MoreButton.jsx +25 -0
  12. package/src/components/MoreButton/MoreButton.module.css +43 -0
  13. package/src/components/MoreButton/MoreButton.stories.jsx +30 -0
  14. package/src/components/ProductsBrandPattern/Patterns/thumb-song-lyrics.jpg +0 -0
  15. package/src/components/ProductsBrandPattern/Patterns/thumb-song-master.jpg +0 -0
  16. package/src/components/ProductsBrandPattern/Patterns/thumb-song-stems.jpg +0 -0
  17. package/src/components/ProductsBrandPattern/Patterns/thumb-song-studio.jpg +0 -0
  18. package/src/components/ProductsBrandPattern/Patterns/thumb-song-voice.jpg +0 -0
  19. package/src/components/ProductsBrandPattern/ProductsBrandPattern.jsx +15 -13
  20. package/src/components/ProductsBrandPattern/ProductsBrandPattern.stories.jsx +61 -15
  21. package/src/components/ProfileMenu/MenuTrigger.jsx +14 -9
  22. package/src/components/ProjectsList/ProjectsList.jsx +122 -94
  23. package/src/components/ProjectsList/ProjectsList.stories.jsx +7 -5
  24. package/src/components/ProjectsList/utils-stories.js +24 -0
  25. package/src/components/SetlistList/SetlistList.jsx +13 -43
  26. package/src/components/SetlistList/SetlistList.module.css +1 -1
  27. package/src/components/Sidebar/Sidebar.jsx +6 -3
  28. package/src/components/Sidebar/Sidebar.module.css +1 -1
  29. package/src/components/Sidebar/SidebarSection/SidebarSection.module.css +1 -1
  30. package/src/components/TextArea/TextArea.jsx +1 -1
  31. package/src/components/TextArea/TextArea.module.css +16 -0
  32. package/src/components/TextField/TextField.jsx +16 -4
  33. package/src/components/TextField/TextField.module.css +45 -1
  34. package/src/components/TextField/TextField.stories.jsx +32 -0
  35. package/src/icons/DotsVertical2Icon.jsx +7 -8
  36. package/src/index.jsx +2 -0
  37. package/src/lib/menu/Menu.module.css +2 -11
  38. package/src/components/ProductsBrandPattern/Patterns/aiStudio.png +0 -0
  39. package/src/components/ProductsBrandPattern/Patterns/mastering.png +0 -0
  40. package/src/components/ProductsBrandPattern/Patterns/product.png +0 -0
  41. package/src/components/ProductsBrandPattern/Patterns/stemSeparation.png +0 -0
  42. package/src/components/ProductsBrandPattern/Patterns/voiceStudio.png +0 -0
@@ -109,7 +109,8 @@
109
109
 
110
110
  .ghost.cyan.highContrast:active:not(.disabled),
111
111
  .ghost.cyan.highContrast[class*="_dropdownMenuTrigger"][data-state='open']:not(.disabled),
112
- .ghost.cyan.highContrast[class*="_popoverTrigger"][data-state='open']:not(.disabled) {
112
+ .ghost.cyan.highContrast[class*="_popoverTrigger"][data-state='open']:not(.disabled),
113
+ .ghost.cyan.highContrast[class*="_menuTrigger"][data-state='open']:not(.disabled) {
113
114
  background-color: transparent;
114
115
  color: var(--aqua-dark-alpha-10) !important;
115
116
  }
@@ -146,6 +147,7 @@
146
147
  width: 24px;
147
148
  height: 24px;
148
149
  padding: 0 !important;
150
+ border-radius: 4px;
149
151
  }
150
152
 
151
153
  /* size 2 → 32×32px */
@@ -154,6 +156,7 @@
154
156
  width: 32px ;
155
157
  height: 32px ;
156
158
  padding: 0 !important;
159
+ border-radius: 6px;
157
160
  }
158
161
 
159
162
  /* size 3 → 40×40px */
@@ -162,6 +165,7 @@
162
165
  width: 40px ;
163
166
  height: 40px ;
164
167
  padding: 0 !important;
168
+ border-radius: 8px;
165
169
  }
166
170
 
167
171
  /* size 4 → 48×48px */
@@ -170,6 +174,23 @@
170
174
  width: 48px;
171
175
  height: 48px;
172
176
  padding: 0 !important;
177
+ border-radius: 12px;
178
+ }
179
+
180
+ .size1 {
181
+ border-radius: 4px;
182
+ }
183
+
184
+ .size2 {
185
+ border-radius: 6px;
186
+ }
187
+
188
+ .size3 {
189
+ border-radius: 8px;
190
+ }
191
+
192
+ .size4 {
193
+ border-radius: 12px;
173
194
  }
174
195
 
175
196
  .solid.cyan {
@@ -192,7 +213,8 @@
192
213
 
193
214
  .solid.cyan.highContrast:active:not(.disabled):not(.loading),
194
215
  .solid.cyan.highContrast[class*="_dropdownMenuTrigger"][data-state='open']:not(.disabled),
195
- .solid.cyan.highContrast[class*="_popoverTrigger"][data-state='open']:not(.disabled) {
216
+ .solid.cyan.highContrast[class*="_popoverTrigger"][data-state='open']:not(.disabled),
217
+ .solid.cyan.highContrast[class*="_menuTrigger"][data-state='open']:not(.disabled) {
196
218
  opacity: 0.82;
197
219
  }
198
220
 
@@ -228,7 +250,8 @@
228
250
 
229
251
  .solid.red.highContrast:active:not(.disabled):not(.loading),
230
252
  .solid.red.highContrast[class*="_dropdownMenuTrigger"][data-state='open']:not(.disabled),
231
- .solid.red.highContrast[class*="_popoverTrigger"][data-state='open']:not(.disabled) {
253
+ .solid.red.highContrast[class*="_popoverTrigger"][data-state='open']:not(.disabled),
254
+ .solid.red.highContrast[class*="_menuTrigger"][data-state='open']:not(.disabled) {
232
255
  background-color: var(--red-12);
233
256
  opacity: 0.82;
234
257
  }
@@ -242,10 +265,23 @@
242
265
  background-color: var(--neutral-alpha-4);
243
266
  }
244
267
 
268
+
269
+ /*
270
+ quando é um trigger é assim que o botao ta ficando
271
+ <button data-accent-color="gray" type="button" id="radix-«r0»"
272
+ aria-haspopup="menu" aria-expanded="true" data-state="open"
273
+ class="rt-reset rt-BaseButton rt-r-size-1 rt-variant-soft
274
+ rt-IconButton _iconButton_1c4cc_1 _gray_1c4cc_61 _size1_1c4cc_144 _soft_1c4cc_256
275
+ _menuTrigger_17nux_207 _showActiveTrigger_17nux_207" aria-controls="radix-«r1»">conteudo do botao</button>
276
+
277
+
278
+ */
245
279
  .soft.gray:active:not(.disabled):not(.loading),
246
280
  .soft.gray[class*="_dropdownMenuTrigger"][data-state='open']:not(.disabled),
247
- .soft.gray[class*="_popoverTrigger"][data-state='open']:not(.disabled) {
248
- background-color: var(--neutral-alpha-5);
281
+ .soft.gray[class*="_popoverTrigger"][data-state='open']:not(.disabled),
282
+ .soft.gray[class*="_menuTrigger"][data-state='open']:not(.disabled)[class*="_showActiveTrigger"]
283
+ {
284
+ background-color: var(--neutral-alpha-5) !important;
249
285
  opacity: 0.92;
250
286
  }
251
287
 
@@ -261,7 +297,8 @@
261
297
 
262
298
  .soft.gray.highContrast:active:not(.disabled):not(.loading),
263
299
  .soft.gray.highContrast[class*="_dropdownMenuTrigger"][data-state='open']:not(.disabled),
264
- .soft.gray.highContrast[class*="_popoverTrigger"][data-state='open']:not(.disabled) {
300
+ .soft.gray.highContrast[class*="_popoverTrigger"][data-state='open']:not(.disabled),
301
+ .soft.gray.highContrast[class*="_menuTrigger"][data-state='open']:not(.disabled)[class*="_showActiveTrigger"] {
265
302
  background-color: var(--neutral-alpha-5);
266
303
  opacity: 0.82;
267
304
  }
@@ -277,7 +314,8 @@
277
314
 
278
315
  .surface.gray:active:not(.disabled):not(.loading),
279
316
  .surface.gray[class*="_dropdownMenuTrigger"][data-state='open']:not(.disabled),
280
- .surface.gray[class*="_popoverTrigger"][data-state='open']:not(.disabled) {
317
+ .surface.gray[class*="_popoverTrigger"][data-state='open']:not(.disabled),
318
+ .surface.gray[class*="_menuTrigger"][data-state='open']:not(.disabled)[class*="_showActiveTrigger"] {
281
319
  background-color: var(--neutral-alpha-3);
282
320
  border: 1px solid var(--neutral-alpha-8);
283
321
  opacity: 0.92;
@@ -295,7 +333,8 @@
295
333
 
296
334
  .surface.gray.highContrast:active:not(.disabled):not(.loading),
297
335
  .surface.gray.highContrast[class*="_dropdownMenuTrigger"][data-state='open']:not(.disabled),
298
- .surface.gray.highContrast[class*="_popoverTrigger"][data-state='open']:not(.disabled) {
336
+ .surface.gray.highContrast[class*="_popoverTrigger"][data-state='open']:not(.disabled),
337
+ .surface.gray.highContrast[class*="_menuTrigger"][data-state='open']:not(.disabled)[class*="_showActiveTrigger"] {
299
338
  background-color: var(--neutral-alpha-3);
300
339
  border: 1px solid var(--neutral-alpha-8);
301
340
  opacity: 0.82;
@@ -0,0 +1,25 @@
1
+ import styles from './MoreButton.module.css'
2
+ import classNames from 'classnames'
3
+ import { DotsVertical2Icon } from '../../icons'
4
+
5
+ export const MoreButton = ({
6
+ className,
7
+ 'aria-label': ariaLabel = 'More options',
8
+ hovered = false,
9
+ ...props
10
+ }) => {
11
+ return (
12
+ <button
13
+ type="button"
14
+ className={classNames(styles.MoreButton, className, {
15
+ [styles.hovered]: hovered,
16
+ })}
17
+ aria-label={ariaLabel}
18
+ {...props}
19
+ >
20
+ <DotsVertical2Icon className={styles.icon} />
21
+ </button >
22
+ )
23
+ }
24
+
25
+ MoreButton.displayName = 'MoreButton'
@@ -0,0 +1,43 @@
1
+ .MoreButton {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ width: 12px;
6
+ height: 24px;
7
+ padding: 0;
8
+ border: none;
9
+ background: transparent;
10
+ border-radius: 9999px;
11
+ cursor: pointer;
12
+ color: var(--neutral-alpha-7);
13
+ transition:
14
+ background-color 0.15s ease,
15
+ color 0.15s ease;
16
+ }
17
+
18
+ @media (pointer: coarse) {
19
+ .MoreButton {
20
+ width: auto;
21
+ height: auto;
22
+ min-width: 32px;
23
+ min-height: 32px;
24
+ padding: 4px 10px;
25
+ }
26
+ }
27
+
28
+ .MoreButton:hover,
29
+ .MoreButton.hovered {
30
+ background-color: var(--neutral-alpha-3);
31
+ color: var(--neutral-alpha-11);
32
+ }
33
+
34
+ .MoreButton:focus-visible {
35
+ outline: 2px solid var(--neutral-alpha-8);
36
+ outline-offset: 2px;
37
+ }
38
+
39
+ .icon {
40
+ width: 4px;
41
+ height: 14px;
42
+ flex-shrink: 0;
43
+ }
@@ -0,0 +1,30 @@
1
+ import { Box } from '@radix-ui/themes'
2
+ import { MoreButton } from './MoreButton'
3
+
4
+ export default {
5
+ title: 'Components/MoreButton',
6
+ component: MoreButton,
7
+ parameters: {
8
+ layout: 'centered',
9
+ },
10
+ tags: ['autodocs'],
11
+ decorators: [
12
+ (Story) => (
13
+ <Box
14
+ style={{
15
+ padding: 24,
16
+ background: 'var(--neutral-2)',
17
+ borderRadius: 8,
18
+ }}
19
+ >
20
+ <Story />
21
+ </Box>
22
+ ),
23
+ ],
24
+ }
25
+
26
+ export const Default = {
27
+ args: {
28
+ 'aria-label': 'More options',
29
+ },
30
+ }
@@ -1,32 +1,34 @@
1
- import { Flex } from '@radix-ui/themes'
2
1
  import classNames from 'classnames'
3
- import aiStudio from './Patterns/aiStudio.png'
4
- import mastering from './Patterns/mastering.png'
5
- import product from './Patterns/product.png'
6
- import stemSeparation from './Patterns/stemSeparation.png'
7
- import voiceStudio from './Patterns/voiceStudio.png'
2
+ import lyrics from './Patterns/thumb-song-lyrics.jpg'
3
+ import mastering from './Patterns/thumb-song-master.jpg'
4
+ import stems from './Patterns/thumb-song-stems.jpg'
5
+ import studio from './Patterns/thumb-song-studio.jpg'
6
+ import voice from './Patterns/thumb-song-voice.jpg'
8
7
 
9
8
  export const ProductsBrandPattern = ({
10
9
  className,
11
- type = 'stem-separation',
12
10
  size = '40px',
11
+ type = 'lyrics',
12
+ cover,
13
13
  ...props
14
14
  }) => {
15
15
  const patterns = {
16
- 'stem-separation': stemSeparation,
17
- 'voice-studio': voiceStudio,
18
- 'ai-studio': aiStudio,
19
- mastering,
20
- product,
16
+ 'stems': stems,
17
+ 'voice': voice,
18
+ 'studio': studio,
19
+ 'master': mastering,
20
+ 'lyrics': lyrics,
21
21
  }
22
22
 
23
- const pattern = patterns[type]
23
+
24
+ const pattern = cover || patterns[type]
24
25
  return (
25
26
  <img
26
27
  src={pattern}
27
28
  alt={`${type} pattern`}
28
29
  width={size}
29
30
  height={size}
31
+ draggable={false}
30
32
  className={classNames(className)}
31
33
  {...props}
32
34
  />
@@ -1,12 +1,7 @@
1
1
  import { ProductsBrandPattern } from './ProductsBrandPattern'
2
+ import { projects } from '../ProjectsList/utils-stories'
2
3
 
3
- const patternTypes = [
4
- 'stem-separation',
5
- 'voice-studio',
6
- 'ai-studio',
7
- 'mastering',
8
- 'product',
9
- ]
4
+ const patternTypes = ['stems', 'voice', 'studio', 'master', 'lyrics']
10
5
 
11
6
  export default {
12
7
  title: 'Components/ProductsBrandPattern',
@@ -25,23 +20,74 @@ export default {
25
20
  type: {
26
21
  control: 'select',
27
22
  options: patternTypes,
28
- description: 'Which product pattern to render.',
23
+ description: 'Product type for the pattern image.',
29
24
  },
30
25
  size: {
31
26
  control: 'text',
32
- description:
33
- 'Width/height of the pattern image. Accepts px, rem, or number.',
34
- },
35
- className: {
36
- control: false,
37
- description: 'Custom class applied to the wrapper Flex.',
27
+ description: 'Width/height of the pattern image. Accepts px, rem, or number.',
38
28
  },
39
29
  },
30
+ args: {
31
+ type: 'lyrics',
32
+ },
40
33
  }
41
34
 
42
35
  export const Default = {
43
36
  args: {
44
- type: 'stem-separation',
37
+ type: 'lyrics',
38
+ },
39
+ }
40
+
41
+ export const Stems = {
42
+ args: {
43
+ type: 'stems',
44
+ },
45
+ }
46
+
47
+ export const Voice = {
48
+ args: {
49
+ type: 'voice',
50
+ },
51
+ }
52
+
53
+ export const Studio = {
54
+ args: {
55
+ type: 'studio',
56
+ },
57
+ }
58
+
59
+ export const Master = {
60
+ args: {
61
+ type: 'master',
62
+ },
63
+ }
64
+
65
+ export const Lyrics = {
66
+ args: {
67
+ type: 'lyrics',
68
+ },
69
+ }
70
+
71
+ export const WithCustomCover = {
72
+ args: {
73
+ type: 'lyrics',
74
+ cover: projects.find((p) => p.cover)?.cover,
45
75
  size: '40px',
46
76
  },
47
77
  }
78
+
79
+ export const AllPatterns = {
80
+ render: ({ type: _type, ...args }) => (
81
+ <div style={{ display: 'flex', gap: 16, alignItems: 'center', flexWrap: 'wrap' }}>
82
+ {patternTypes.map((type) => (
83
+ <div key={type} style={{ textAlign: 'center' }}>
84
+ <ProductsBrandPattern type={type} {...args} />
85
+ <div style={{ fontSize: 12, marginTop: 4, textTransform: 'capitalize' }}>{type}</div>
86
+ </div>
87
+ ))}
88
+ </div>
89
+ ),
90
+ args: {
91
+ size: '48px',
92
+ },
93
+ }
@@ -1,12 +1,23 @@
1
1
  import classNames from 'classnames'
2
- import React from 'react'
3
- import { DotsVerticalIcon } from '../../icons'
2
+ import React, { useState } from 'react'
4
3
  import { Avatar, Flex, Text } from '../../index'
5
4
  import styles from './ProfileMenu.module.css'
5
+ import { MoreButton } from '../MoreButton/MoreButton'
6
6
 
7
7
  export function MenuTrigger({ className, user, collapsed, ...props }) {
8
+ const [hover, setHover] = useState(false)
9
+
10
+ const handleMouseEnter = () => {
11
+ setHover(true)
12
+ }
13
+
14
+ const handleMouseLeave = () => {
15
+ setHover(false)
16
+ }
8
17
  return (
9
18
  <Flex
19
+ onMouseEnter={handleMouseEnter}
20
+ onMouseLeave={handleMouseLeave}
10
21
  className={classNames(styles.userProfile, { [styles.collapsed]: collapsed }, className)}
11
22
  align="center"
12
23
  justify="between"
@@ -32,13 +43,7 @@ export function MenuTrigger({ className, user, collapsed, ...props }) {
32
43
  </div>
33
44
 
34
45
  <div className={styles.userMenuWrapper}>
35
- <Flex padding="4px 5px" className={styles.dropdownTriggerWrapper}>
36
- <DotsVerticalIcon
37
- className={styles.dropdownMenuTrigger}
38
- width={16}
39
- height={16}
40
- />
41
- </Flex>
46
+ <MoreButton hovered={hover} />
42
47
  </div>
43
48
  </Flex>
44
49
  )
@@ -1,25 +1,60 @@
1
1
  import { Flex, Text, Separator } from '@radix-ui/themes'
2
2
  import styles from './ProjectsList.module.css'
3
- import { useState } from 'react'
3
+ import { useState, createContext, useContext } from 'react'
4
4
  import { ArrowLeftIcon, NoMusicIcon, ChevronDownIcon, ChevronUpIcon } from '../../icons'
5
5
  import { getIconFromTrackId } from './utils'
6
6
  import { Button } from '../Button/Button'
7
+ import { ProductsBrandPattern } from '../ProductsBrandPattern/ProductsBrandPattern'
8
+
9
+ const ProjectsListContext = createContext({
10
+ onClickTrack: null,
11
+ onInsertAllTracks: null,
12
+ openedItem: null,
13
+ setOpenedItem: () => { },
14
+ })
7
15
 
8
16
  export const ProjectsList = ({
9
- projects = [],
17
+ children,
10
18
  onClickTrack,
11
19
  onInsertAllTracks,
12
20
  }) => {
13
21
  const [openedItem, setOpenedItem] = useState(null)
22
+
23
+ return (
24
+ <ProjectsListContext.Provider
25
+ value={{
26
+ onClickTrack,
27
+ onInsertAllTracks,
28
+ openedItem,
29
+ setOpenedItem,
30
+ }}
31
+ >
32
+ <Flex direction="column" width="100%">
33
+ {children}
34
+ </Flex>
35
+ </ProjectsListContext.Provider>
36
+ )
37
+ }
38
+
39
+ const ProjectsListItem = ({
40
+ id,
41
+ title,
42
+ artist,
43
+ cover,
44
+ type,
45
+ tracks = [],
46
+ ...props
47
+ }) => {
48
+ const { onClickTrack, onInsertAllTracks, openedItem, setOpenedItem } = useContext(ProjectsListContext)
14
49
  const [showAllTracks, setShowAllTracks] = useState(false)
15
50
 
16
- const handleClickProject = (projectId) => {
51
+ const handleClickProject = () => {
17
52
  setShowAllTracks(false)
18
53
 
19
- if (openedItem === projectId) {
54
+ if (openedItem === id) {
20
55
  setOpenedItem(null)
21
56
  } else {
22
- setOpenedItem(projectId)
57
+ setOpenedItem(id)
23
58
  }
24
59
  }
25
60
 
@@ -29,105 +64,98 @@ export const ProjectsList = ({
29
64
  setShowAllTracks(!showAllTracks)
30
65
  }
31
66
 
67
+
32
68
  return (
33
- <Flex direction="column" width="100%">
34
- {projects.map((project, index) => (
35
- <Flex
36
- key={project.id}
37
- direction="column"
38
- gap="2"
39
- p="1"
40
- className={`${styles.item} ${openedItem === project.id ? styles.opened : ''}`}
41
- onClick={() => handleClickProject(project.id)}
42
- >
43
- <Flex direction="row" gap="3">
44
- <Flex className={styles.projectCover}>
45
- <img
46
- src={project.cover || `https://picsum.photos/48?random=${index}`}
47
- alt={project.title}
48
- draggable={false}
49
- className={styles.projectCoverImage}
50
- />
51
- </Flex>
69
+ <Flex
70
+ direction="column"
71
+ gap="2"
72
+ p="1"
73
+ className={`${styles.item} ${openedItem === id ? styles.opened : ''}`}
74
+ onClick={handleClickProject}
75
+ {...props}
76
+ >
77
+ <Flex direction="row" gap="3">
78
+ <Flex className={styles.projectCover}>
79
+ <ProductsBrandPattern type={type} cover={cover} size="48px" />
80
+ </Flex>
52
81
 
53
- <Flex direction="column" gap="1" align="start" justify="center">
54
- <Text size="2" className={styles.projectTitle}>
55
- {project.title}
56
- </Text>
82
+ <Flex direction="column" gap="1" align="start" justify="center">
83
+ <Text size="2" className={styles.projectTitle}>
84
+ {title}
85
+ </Text>
57
86
 
58
- {project.artist && (
59
- <Text size="1" className={styles.projectArtist}>
60
- {project.artist}
61
- </Text>
62
- )}
87
+ {artist && (
88
+ <Text size="1" className={styles.projectArtist}>
89
+ {artist}
90
+ </Text>
91
+ )}
92
+ </Flex>
93
+ </Flex>
94
+
95
+ {openedItem === id && (
96
+ <Flex direction="column">
97
+ {tracks.length === 0 && (
98
+ <Flex direction="row" gap="3" p="5" pt="2" align="center" justify="center">
99
+ <NoMusicIcon width={16} height={16} style={{ color: 'var(--neutral-alpha-10)' }} />
100
+ <Text size="2" style={{ color: 'var(--neutral-alpha-10)' }}>This file has no tracks</Text>
63
101
  </Flex>
64
- </Flex>
65
-
66
- {openedItem === project.id && (
67
- <Flex direction="column">
68
- {project.tracks.length === 0 && (
69
- <Flex direction="row" gap="3" p="5" pt="2" align="center" justify="center">
70
- <NoMusicIcon width={16} height={16} style={{ color: 'var(--neutral-alpha-10)' }} />
71
- <Text size="2" style={{ color: 'var(--neutral-alpha-10)' }}>This file has no tracks</Text>
72
- </Flex>
73
- )}
74
-
75
- {project.tracks.length > 0 && (
76
- <Flex direction="column" gap="1">
77
- {project.tracks.slice(0, showAllTracks ? project.tracks.length : 6).map((track) => (
78
- <Flex
79
- key={track.id}
80
- direction="row"
81
- gap="3"
82
- className={styles.itemTrack}
83
- onClick={(e) => {
84
- e.stopPropagation()
85
- onClickTrack?.(track)
86
- }}
87
- >
88
- <div className={styles.icon}>
89
- <Flex className={styles.iconTrack}>
90
- {getIconFromTrackId(track.id)}
91
- </Flex>
92
- <ArrowLeftIcon width={16} height={16} className={styles.iconArrowLeft} />
93
- </div>
94
-
95
- <Flex direction="column" gap="1" align="start" justify="center">
96
- <Text size="2" className={styles.trackTitle}>
97
- {track.title}
98
- </Text>
99
- </Flex>
100
- </Flex>
101
- ))}
102
-
103
- <Flex direction="row" gap="3" p="2" align="center" justify="center">
104
- <Button variant="ghost" color="neutral" style={{ flex: '1' }}
105
- onClick={(e) => {
106
- e.stopPropagation()
107
- onInsertAllTracks?.(project.tracks)
108
- }}
109
- >
110
- <ArrowLeftIcon width={16} height={16} /> Insert all
111
- </Button>
102
+ )}
112
103
 
113
- {project.tracks.length > 6 && (
114
- <>
115
- <Separator orientation="vertical" />
104
+ {tracks.length > 0 && (
105
+ <Flex direction="column" gap="1">
106
+ {tracks.slice(0, showAllTracks ? tracks.length : 6).map((track) => (
107
+ <Flex
108
+ key={track.id}
109
+ direction="row"
110
+ gap="3"
111
+ className={styles.itemTrack}
112
+ onClick={(e) => {
113
+ e.stopPropagation()
114
+ onClickTrack?.(track)
115
+ }}
116
+ >
117
+ <div className={styles.icon}>
118
+ <Flex className={styles.iconTrack}>
119
+ {getIconFromTrackId(track.id)}
120
+ </Flex>
121
+ <ArrowLeftIcon width={16} height={16} className={styles.iconArrowLeft} />
122
+ </div>
116
123
 
117
- <Button variant="ghost" color="gray" style={{ flex: '1' }} onClick={handleClickShowAllTracks}>
118
- {showAllTracks ? 'Show less' : 'Show more'}
119
- {showAllTracks ? <ChevronUpIcon width={16} height={16} /> : <ChevronDownIcon width={16} height={16} />}
120
- </Button>
121
- </>
122
- )}
124
+ <Flex direction="column" gap="1" align="start" justify="center">
125
+ <Text size="2" className={styles.trackTitle}>
126
+ {track.title}
127
+ </Text>
123
128
  </Flex>
124
129
  </Flex>
125
- )}
130
+ ))}
131
+
132
+ <Flex direction="row" gap="3" p="2" align="center" justify="center">
133
+ <Button variant="ghost" color="neutral" style={{ flex: '1' }}
134
+ onClick={(e) => {
135
+ e.stopPropagation()
136
+ onInsertAllTracks?.(tracks)
137
+ }}
138
+ >
139
+ <ArrowLeftIcon width={16} height={16} /> Insert all
140
+ </Button>
141
+
142
+ {tracks.length > 6 && (
143
+ <>
144
+ <Separator orientation="vertical" />
145
+
146
+ <Button variant="ghost" color="gray" style={{ flex: '1' }} onClick={handleClickShowAllTracks}>
147
+ {showAllTracks ? 'Show less' : 'Show more'}
148
+ {showAllTracks ? <ChevronUpIcon width={16} height={16} /> : <ChevronDownIcon width={16} height={16} />}
149
+ </Button>
150
+ </>
151
+ )}
152
+ </Flex>
126
153
  </Flex>
127
154
  )}
128
155
  </Flex>
129
- ))
130
- }
131
- </Flex >
156
+ )}
157
+ </Flex>
132
158
  )
133
159
  }
160
+
161
+ ProjectsList.Item = ProjectsListItem