@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.
- package/dist/{EditIcon-DOFkQeiV.js → EditIcon-Bn6TqXCt.js} +12 -6
- package/dist/icons.js +1 -1
- package/dist/index.js +3431 -3348
- package/package.json +1 -1
- package/src/components/Button/Button.module.css +19 -2
- package/src/components/DataTable/DataTable.jsx +120 -33
- package/src/components/DataTable/DataTable.module.css +14 -32
- package/src/components/DataTable/DataTable.stories.jsx +13 -7
- package/src/components/DropdownMenu/DropdownMenu.stories.jsx +62 -23
- package/src/components/IconButton/IconButton.module.css +47 -8
- package/src/components/MoreButton/MoreButton.jsx +25 -0
- package/src/components/MoreButton/MoreButton.module.css +43 -0
- package/src/components/MoreButton/MoreButton.stories.jsx +30 -0
- package/src/components/ProductsBrandPattern/Patterns/thumb-song-lyrics.jpg +0 -0
- package/src/components/ProductsBrandPattern/Patterns/thumb-song-master.jpg +0 -0
- package/src/components/ProductsBrandPattern/Patterns/thumb-song-stems.jpg +0 -0
- package/src/components/ProductsBrandPattern/Patterns/thumb-song-studio.jpg +0 -0
- package/src/components/ProductsBrandPattern/Patterns/thumb-song-voice.jpg +0 -0
- package/src/components/ProductsBrandPattern/ProductsBrandPattern.jsx +15 -13
- package/src/components/ProductsBrandPattern/ProductsBrandPattern.stories.jsx +61 -15
- package/src/components/ProfileMenu/MenuTrigger.jsx +14 -9
- package/src/components/ProjectsList/ProjectsList.jsx +122 -94
- package/src/components/ProjectsList/ProjectsList.stories.jsx +7 -5
- package/src/components/ProjectsList/utils-stories.js +24 -0
- package/src/components/SetlistList/SetlistList.jsx +13 -43
- package/src/components/SetlistList/SetlistList.module.css +1 -1
- package/src/components/Sidebar/Sidebar.jsx +6 -3
- package/src/components/Sidebar/Sidebar.module.css +1 -1
- package/src/components/Sidebar/SidebarSection/SidebarSection.module.css +1 -1
- package/src/components/TextArea/TextArea.jsx +1 -1
- package/src/components/TextArea/TextArea.module.css +16 -0
- package/src/components/TextField/TextField.jsx +16 -4
- package/src/components/TextField/TextField.module.css +45 -1
- package/src/components/TextField/TextField.stories.jsx +32 -0
- package/src/icons/DotsVertical2Icon.jsx +7 -8
- package/src/index.jsx +2 -0
- package/src/lib/menu/Menu.module.css +2 -11
- package/src/components/ProductsBrandPattern/Patterns/aiStudio.png +0 -0
- package/src/components/ProductsBrandPattern/Patterns/mastering.png +0 -0
- package/src/components/ProductsBrandPattern/Patterns/product.png +0 -0
- package/src/components/ProductsBrandPattern/Patterns/stemSeparation.png +0 -0
- 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
|
-
|
|
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
|
|
4
|
-
import mastering from './Patterns/
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
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
|
-
'
|
|
17
|
-
'voice
|
|
18
|
-
'
|
|
19
|
-
mastering,
|
|
20
|
-
|
|
16
|
+
'stems': stems,
|
|
17
|
+
'voice': voice,
|
|
18
|
+
'studio': studio,
|
|
19
|
+
'master': mastering,
|
|
20
|
+
'lyrics': lyrics,
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
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: '
|
|
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: '
|
|
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
|
-
<
|
|
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
|
-
|
|
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 = (
|
|
51
|
+
const handleClickProject = () => {
|
|
17
52
|
setShowAllTracks(false)
|
|
18
53
|
|
|
19
|
-
if (openedItem ===
|
|
54
|
+
if (openedItem === id) {
|
|
20
55
|
setOpenedItem(null)
|
|
21
56
|
} else {
|
|
22
|
-
setOpenedItem(
|
|
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
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
>
|
|
43
|
-
<
|
|
44
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
82
|
+
<Flex direction="column" gap="1" align="start" justify="center">
|
|
83
|
+
<Text size="2" className={styles.projectTitle}>
|
|
84
|
+
{title}
|
|
85
|
+
</Text>
|
|
57
86
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|