@moises.ai/design-system 3.6.13 → 3.6.18
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/{UnlockIcon-DeCeTwbX.js → UnlockIcon-WuMcZKww.js} +852 -773
- package/dist/icons.js +1 -1
- package/dist/index.js +3076 -2974
- package/package.json +1 -1
- package/src/components/StemGenerationForm/CreateNew/CreateNew.jsx +110 -5
- package/src/components/StemGenerationForm/CreateNew/CreateNew.module.css +51 -0
- package/src/components/StemGenerationForm/StemGenerationForm.jsx +14 -0
- package/src/components/StemGenerationForm/StemGenerationForm.stories.jsx +156 -0
- package/src/components/TextArea/TextArea.module.css +5 -0
- package/src/icons/MagicWandIcon.jsx +70 -0
- package/src/icons.jsx +1 -0
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { useCallback } from 'react'
|
|
1
|
+
import { useCallback, useEffect, useRef } from 'react'
|
|
2
2
|
import { Flex, Box, Tooltip, Separator } from '@radix-ui/themes'
|
|
3
3
|
import { TextArea } from '../../TextArea/TextArea'
|
|
4
4
|
import { Button } from '../../Button/Button'
|
|
5
5
|
import { IconButton } from '../../IconButton/IconButton'
|
|
6
6
|
import { Text } from '../../Text/Text'
|
|
7
|
-
import { FileIcon, TrashIcon,
|
|
7
|
+
import { FileIcon, TrashIcon, AttachmentIcon, MagicWandIcon, RocketIcon } from '../../../icons'
|
|
8
8
|
import { formatFileInfo, getInstrumentDescription } from '../utils'
|
|
9
|
+
import styles from './CreateNew.module.css'
|
|
10
|
+
|
|
11
|
+
const DEBOUNCE_MS = 500
|
|
12
|
+
const SKELETON_WIDTHS = [60, 48, 68, 52, 56]
|
|
9
13
|
|
|
10
14
|
export const CreateNew = ({
|
|
11
15
|
formState,
|
|
@@ -13,7 +17,16 @@ export const CreateNew = ({
|
|
|
13
17
|
i18n = { _: (text) => text },
|
|
14
18
|
onAddConditioningAudio,
|
|
15
19
|
onTextConditioningFocus,
|
|
20
|
+
onInspireMe,
|
|
21
|
+
inspireMeLoading,
|
|
22
|
+
onBoost,
|
|
23
|
+
boostLoading,
|
|
24
|
+
suggestedTags,
|
|
25
|
+
onFetchSuggestedTags,
|
|
26
|
+
suggestedTagsLoading,
|
|
16
27
|
}) => {
|
|
28
|
+
const debounceRef = useRef(null)
|
|
29
|
+
|
|
17
30
|
const handleTextConditioningChange = useCallback(
|
|
18
31
|
(e) => {
|
|
19
32
|
const newValue = e.target.value
|
|
@@ -25,6 +38,30 @@ export const CreateNew = ({
|
|
|
25
38
|
[onFormStateChange],
|
|
26
39
|
)
|
|
27
40
|
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (!onFetchSuggestedTags) return
|
|
43
|
+
if (!formState.conditioningText) return
|
|
44
|
+
|
|
45
|
+
if (debounceRef.current) clearTimeout(debounceRef.current)
|
|
46
|
+
debounceRef.current = setTimeout(() => {
|
|
47
|
+
onFetchSuggestedTags(formState.conditioningText)
|
|
48
|
+
}, DEBOUNCE_MS)
|
|
49
|
+
|
|
50
|
+
return () => {
|
|
51
|
+
if (debounceRef.current) clearTimeout(debounceRef.current)
|
|
52
|
+
}
|
|
53
|
+
}, [formState.conditioningText, onFetchSuggestedTags])
|
|
54
|
+
|
|
55
|
+
const handleTagClick = useCallback(
|
|
56
|
+
(tag) => {
|
|
57
|
+
onFormStateChange((prevState) => ({
|
|
58
|
+
...prevState,
|
|
59
|
+
conditioningText: (prevState.conditioningText || '').trimEnd() + ' ' + tag + ' ',
|
|
60
|
+
}))
|
|
61
|
+
},
|
|
62
|
+
[onFormStateChange],
|
|
63
|
+
)
|
|
64
|
+
|
|
28
65
|
const handleClearConditioningAudio = useCallback(() => {
|
|
29
66
|
onFormStateChange((prevState) => ({
|
|
30
67
|
...prevState,
|
|
@@ -73,11 +110,11 @@ export const CreateNew = ({
|
|
|
73
110
|
>
|
|
74
111
|
<Button
|
|
75
112
|
variant="ghost"
|
|
76
|
-
color="cyan"
|
|
77
113
|
onClick={onAddConditioningAudio}
|
|
114
|
+
style={{ color: '#EDEEF0' }}
|
|
78
115
|
>
|
|
79
|
-
<
|
|
80
|
-
<Text size="1">{i18n._('Select Reference Audio')}</Text>
|
|
116
|
+
<AttachmentIcon width={16} height={16} style={{ color: '#B0B4BA' }} />
|
|
117
|
+
<Text size="1" style={{ color: '#EDEEF0' }}>{i18n._('Select Reference Audio')}</Text>
|
|
81
118
|
</Button>
|
|
82
119
|
</Tooltip>
|
|
83
120
|
)}
|
|
@@ -92,6 +129,7 @@ export const CreateNew = ({
|
|
|
92
129
|
value={formState.conditioningText}
|
|
93
130
|
onFocus={onTextConditioningFocus}
|
|
94
131
|
onChange={handleTextConditioningChange}
|
|
132
|
+
disabled={!!inspireMeLoading || !!boostLoading}
|
|
95
133
|
placeholder={i18n._(
|
|
96
134
|
`Describe your desired sound characteristics (ex: ${getInstrumentDescription(
|
|
97
135
|
formState.instrument,
|
|
@@ -101,6 +139,73 @@ export const CreateNew = ({
|
|
|
101
139
|
rows={6}
|
|
102
140
|
/>
|
|
103
141
|
</Box>
|
|
142
|
+
|
|
143
|
+
{!formState.conditioningText && onInspireMe && (
|
|
144
|
+
<Box px="3px" pb="2">
|
|
145
|
+
<Button
|
|
146
|
+
variant="soft"
|
|
147
|
+
color="cyan"
|
|
148
|
+
size="1"
|
|
149
|
+
onClick={onInspireMe}
|
|
150
|
+
loading={inspireMeLoading}
|
|
151
|
+
style={{ borderRadius: '9999px' }}
|
|
152
|
+
>
|
|
153
|
+
<MagicWandIcon width={14} height={14} />
|
|
154
|
+
{i18n._('Inspire me')}
|
|
155
|
+
</Button>
|
|
156
|
+
</Box>
|
|
157
|
+
)}
|
|
158
|
+
|
|
159
|
+
{formState.conditioningText && (onBoost || suggestedTagsLoading || suggestedTags?.length > 0) && (
|
|
160
|
+
<div className={styles.promptActions}>
|
|
161
|
+
{onBoost && (
|
|
162
|
+
<IconButton
|
|
163
|
+
className={styles.boostButton}
|
|
164
|
+
variant="soft"
|
|
165
|
+
color="orange"
|
|
166
|
+
size="2"
|
|
167
|
+
onClick={onBoost}
|
|
168
|
+
loading={boostLoading}
|
|
169
|
+
style={{ borderRadius: '9999px', width: 32, height: 32 }}
|
|
170
|
+
>
|
|
171
|
+
<RocketIcon width={14} height={14} />
|
|
172
|
+
</IconButton>
|
|
173
|
+
)}
|
|
174
|
+
{suggestedTagsLoading && (
|
|
175
|
+
<div className={styles.tagsContainer}>
|
|
176
|
+
{SKELETON_WIDTHS.map((w, i) => (
|
|
177
|
+
<div
|
|
178
|
+
key={i}
|
|
179
|
+
className={styles.skeletonChip}
|
|
180
|
+
style={{ width: w }}
|
|
181
|
+
/>
|
|
182
|
+
))}
|
|
183
|
+
</div>
|
|
184
|
+
)}
|
|
185
|
+
{!suggestedTagsLoading && suggestedTags?.length > 0 && (
|
|
186
|
+
<div className={styles.tagsContainer}>
|
|
187
|
+
{suggestedTags.map((tag) => (
|
|
188
|
+
<Button
|
|
189
|
+
key={tag}
|
|
190
|
+
className={styles.tagChip}
|
|
191
|
+
variant="ghost"
|
|
192
|
+
size="2"
|
|
193
|
+
onClick={() => handleTagClick(tag)}
|
|
194
|
+
style={{
|
|
195
|
+
borderRadius: '9999px',
|
|
196
|
+
color: 'rgba(241, 247, 254, 0.71)',
|
|
197
|
+
backgroundColor: 'rgba(221, 234, 248, 0.08)',
|
|
198
|
+
paddingLeft: 14,
|
|
199
|
+
paddingRight: 14,
|
|
200
|
+
}}
|
|
201
|
+
>
|
|
202
|
+
{tag}
|
|
203
|
+
</Button>
|
|
204
|
+
))}
|
|
205
|
+
</div>
|
|
206
|
+
)}
|
|
207
|
+
</div>
|
|
208
|
+
)}
|
|
104
209
|
</Flex>
|
|
105
210
|
</Flex>
|
|
106
211
|
)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
.promptActions {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: row;
|
|
4
|
+
align-items: center;
|
|
5
|
+
gap: 8px;
|
|
6
|
+
padding: 0 3px 8px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.tagsContainer {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: row;
|
|
12
|
+
align-items: center;
|
|
13
|
+
gap: 8px;
|
|
14
|
+
overflow-x: auto;
|
|
15
|
+
flex-wrap: nowrap;
|
|
16
|
+
flex: 1;
|
|
17
|
+
min-width: 0;
|
|
18
|
+
scrollbar-width: none;
|
|
19
|
+
-ms-overflow-style: none;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.tagsContainer::-webkit-scrollbar {
|
|
23
|
+
display: none;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.tagChip {
|
|
27
|
+
border-radius: 9999px;
|
|
28
|
+
white-space: nowrap;
|
|
29
|
+
flex-shrink: 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.boostButton {
|
|
33
|
+
flex-shrink: 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.skeletonChip {
|
|
37
|
+
border-radius: 9999px;
|
|
38
|
+
flex-shrink: 0;
|
|
39
|
+
height: 32px;
|
|
40
|
+
background: rgba(221, 234, 248, 0.06);
|
|
41
|
+
animation: shimmer 1.4s ease-in-out infinite;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@keyframes shimmer {
|
|
45
|
+
0%, 100% {
|
|
46
|
+
opacity: 0.4;
|
|
47
|
+
}
|
|
48
|
+
50% {
|
|
49
|
+
opacity: 1;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -39,6 +39,13 @@ export const StemGenerationForm = ({
|
|
|
39
39
|
unmutedTracksCount,
|
|
40
40
|
onMountConcurrency,
|
|
41
41
|
onClear,
|
|
42
|
+
onInspireMe,
|
|
43
|
+
inspireMeLoading,
|
|
44
|
+
onBoost,
|
|
45
|
+
boostLoading,
|
|
46
|
+
suggestedTags,
|
|
47
|
+
onFetchSuggestedTags,
|
|
48
|
+
suggestedTagsLoading,
|
|
42
49
|
}) => {
|
|
43
50
|
const [isAnimating, setIsAnimating] = useState(false)
|
|
44
51
|
const [presetSelected, setPresetSelected] = useState('2')
|
|
@@ -229,6 +236,13 @@ export const StemGenerationForm = ({
|
|
|
229
236
|
i18n={i18n}
|
|
230
237
|
onAddConditioningAudio={onAddConditioningAudio}
|
|
231
238
|
onTextConditioningFocus={showConditioningTextPaywall}
|
|
239
|
+
onInspireMe={onInspireMe}
|
|
240
|
+
inspireMeLoading={inspireMeLoading}
|
|
241
|
+
onBoost={onBoost}
|
|
242
|
+
boostLoading={boostLoading}
|
|
243
|
+
suggestedTags={suggestedTags}
|
|
244
|
+
onFetchSuggestedTags={onFetchSuggestedTags}
|
|
245
|
+
suggestedTagsLoading={suggestedTagsLoading}
|
|
232
246
|
/>
|
|
233
247
|
)}
|
|
234
248
|
|
|
@@ -231,6 +231,37 @@ generateFromTrack = {
|
|
|
231
231
|
description: 'Callback to clear generation state',
|
|
232
232
|
control: false,
|
|
233
233
|
},
|
|
234
|
+
onInspireMe: {
|
|
235
|
+
description:
|
|
236
|
+
'Callback when user clicks "Inspire me". Consumer fetches prompt and sets conditioningText.',
|
|
237
|
+
control: false,
|
|
238
|
+
},
|
|
239
|
+
inspireMeLoading: {
|
|
240
|
+
description: 'Loading state for the inspire action',
|
|
241
|
+
control: 'boolean',
|
|
242
|
+
},
|
|
243
|
+
onBoost: {
|
|
244
|
+
description:
|
|
245
|
+
'Callback when user clicks the boost (rocket) button. Consumer fetches boosted text and replaces conditioningText.',
|
|
246
|
+
control: false,
|
|
247
|
+
},
|
|
248
|
+
boostLoading: {
|
|
249
|
+
description: 'Loading state for the boost action',
|
|
250
|
+
control: 'boolean',
|
|
251
|
+
},
|
|
252
|
+
suggestedTags: {
|
|
253
|
+
description: 'Array of tag strings returned from upstream, shown as clickable chips next to the boost button',
|
|
254
|
+
control: false,
|
|
255
|
+
},
|
|
256
|
+
onFetchSuggestedTags: {
|
|
257
|
+
description:
|
|
258
|
+
'Callback fired (debounced) when the user types in the textarea. Receives the current text. Consumer fetches tags and passes them back via suggestedTags.',
|
|
259
|
+
control: false,
|
|
260
|
+
},
|
|
261
|
+
suggestedTagsLoading: {
|
|
262
|
+
description: 'Loading state for suggested tags. Shows skeleton chips when true.',
|
|
263
|
+
control: 'boolean',
|
|
264
|
+
},
|
|
234
265
|
},
|
|
235
266
|
}
|
|
236
267
|
|
|
@@ -701,3 +732,128 @@ export const WithCreativeControls = {
|
|
|
701
732
|
unmutedTracksCount: 3,
|
|
702
733
|
},
|
|
703
734
|
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* ## Inspire Me (Empty Textarea)
|
|
738
|
+
*
|
|
739
|
+
* Shows the "Inspire me" button below the textarea when no text has been entered.
|
|
740
|
+
* Clicking the button triggers the consumer to fetch and populate a prompt.
|
|
741
|
+
*/
|
|
742
|
+
export const InspireMeEmpty = {
|
|
743
|
+
args: {
|
|
744
|
+
formState: {
|
|
745
|
+
...FORM_DEFAULTS,
|
|
746
|
+
conditioningText: '',
|
|
747
|
+
},
|
|
748
|
+
presets: [],
|
|
749
|
+
i18n: mockI18n,
|
|
750
|
+
loading: false,
|
|
751
|
+
limitReached: false,
|
|
752
|
+
showUpgradeConcurrency: false,
|
|
753
|
+
error: null,
|
|
754
|
+
unmutedTracksCount: 3,
|
|
755
|
+
onInspireMe: () => console.log('Inspire me clicked'),
|
|
756
|
+
inspireMeLoading: false,
|
|
757
|
+
},
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* ## Inspire Me (Loading)
|
|
762
|
+
*
|
|
763
|
+
* Shows the "Inspire me" button in its loading state while a prompt is being fetched.
|
|
764
|
+
*/
|
|
765
|
+
export const InspireMeLoading = {
|
|
766
|
+
args: {
|
|
767
|
+
formState: {
|
|
768
|
+
...FORM_DEFAULTS,
|
|
769
|
+
conditioningText: '',
|
|
770
|
+
},
|
|
771
|
+
presets: [],
|
|
772
|
+
i18n: mockI18n,
|
|
773
|
+
loading: false,
|
|
774
|
+
limitReached: false,
|
|
775
|
+
showUpgradeConcurrency: false,
|
|
776
|
+
error: null,
|
|
777
|
+
unmutedTracksCount: 3,
|
|
778
|
+
onInspireMe: () => console.log('Inspire me clicked'),
|
|
779
|
+
inspireMeLoading: true,
|
|
780
|
+
},
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* ## Boost with Tags
|
|
785
|
+
*
|
|
786
|
+
* Shows the boost button and suggested tag chips when the textarea has text.
|
|
787
|
+
* Tags scroll horizontally and clicking a tag appends it to the prompt locally.
|
|
788
|
+
*/
|
|
789
|
+
export const BoostWithTags = {
|
|
790
|
+
args: {
|
|
791
|
+
formState: {
|
|
792
|
+
...FORM_DEFAULTS,
|
|
793
|
+
conditioningText: 'Heavy rock drums with double bass pedal',
|
|
794
|
+
},
|
|
795
|
+
presets: [],
|
|
796
|
+
i18n: mockI18n,
|
|
797
|
+
loading: false,
|
|
798
|
+
limitReached: false,
|
|
799
|
+
showUpgradeConcurrency: false,
|
|
800
|
+
error: null,
|
|
801
|
+
unmutedTracksCount: 3,
|
|
802
|
+
onBoost: () => console.log('Boost clicked'),
|
|
803
|
+
boostLoading: false,
|
|
804
|
+
suggestedTags: ['lo-fi', 'dub', 'soul-fi', 'swing', 'lo-rez'],
|
|
805
|
+
onFetchSuggestedTags: (text) => console.log('Fetch tags for:', text),
|
|
806
|
+
suggestedTagsLoading: false,
|
|
807
|
+
},
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* ## Boost Loading
|
|
812
|
+
*
|
|
813
|
+
* Shows the boost button in its loading state while boost text is being fetched.
|
|
814
|
+
*/
|
|
815
|
+
export const BoostLoading = {
|
|
816
|
+
args: {
|
|
817
|
+
formState: {
|
|
818
|
+
...FORM_DEFAULTS,
|
|
819
|
+
conditioningText: 'Smooth jazz guitar with warm tone',
|
|
820
|
+
},
|
|
821
|
+
presets: [],
|
|
822
|
+
i18n: mockI18n,
|
|
823
|
+
loading: false,
|
|
824
|
+
limitReached: false,
|
|
825
|
+
showUpgradeConcurrency: false,
|
|
826
|
+
error: null,
|
|
827
|
+
unmutedTracksCount: 3,
|
|
828
|
+
onBoost: () => console.log('Boost clicked'),
|
|
829
|
+
boostLoading: true,
|
|
830
|
+
suggestedTags: ['lo-fi', 'dub', 'soul-fi', 'swing', 'lo-rez'],
|
|
831
|
+
onFetchSuggestedTags: (text) => console.log('Fetch tags for:', text),
|
|
832
|
+
suggestedTagsLoading: false,
|
|
833
|
+
},
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* ## Suggested Tags Loading (Skeleton)
|
|
838
|
+
*
|
|
839
|
+
* Shows skeleton placeholders while suggested tags are being fetched from upstream.
|
|
840
|
+
*/
|
|
841
|
+
export const SuggestedTagsLoading = {
|
|
842
|
+
args: {
|
|
843
|
+
formState: {
|
|
844
|
+
...FORM_DEFAULTS,
|
|
845
|
+
conditioningText: 'Funky bass groove with slap technique',
|
|
846
|
+
},
|
|
847
|
+
presets: [],
|
|
848
|
+
i18n: mockI18n,
|
|
849
|
+
loading: false,
|
|
850
|
+
limitReached: false,
|
|
851
|
+
showUpgradeConcurrency: false,
|
|
852
|
+
error: null,
|
|
853
|
+
unmutedTracksCount: 3,
|
|
854
|
+
onBoost: () => console.log('Boost clicked'),
|
|
855
|
+
boostLoading: false,
|
|
856
|
+
onFetchSuggestedTags: (text) => console.log('Fetch tags for:', text),
|
|
857
|
+
suggestedTagsLoading: true,
|
|
858
|
+
},
|
|
859
|
+
}
|
|
@@ -26,7 +26,12 @@
|
|
|
26
26
|
color: var(--neutral-alpha-9) !important;
|
|
27
27
|
-webkit-text-fill-color: var(--neutral-alpha-9) !important;
|
|
28
28
|
background-color: var(--neutral-alpha-3) !important;
|
|
29
|
+
}
|
|
29
30
|
|
|
31
|
+
.disabled textarea {
|
|
32
|
+
color: var(--neutral-alpha-9) !important;
|
|
33
|
+
-webkit-text-fill-color: var(--neutral-alpha-9) !important;
|
|
34
|
+
opacity: 1 !important;
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
.focusRing:where(:focus-within) {
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export const MagicWandIcon = ({ width, height, className, ...props }) => (
|
|
2
|
+
<svg
|
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4
|
+
width={width}
|
|
5
|
+
height={height}
|
|
6
|
+
viewBox="0 0 16 16"
|
|
7
|
+
fill="none"
|
|
8
|
+
className={className}
|
|
9
|
+
{...props}
|
|
10
|
+
>
|
|
11
|
+
<path
|
|
12
|
+
d="M1.33301 14.667L10.333 5.66699"
|
|
13
|
+
stroke="currentColor"
|
|
14
|
+
strokeWidth="1.13"
|
|
15
|
+
strokeLinecap="round"
|
|
16
|
+
strokeLinejoin="round"
|
|
17
|
+
/>
|
|
18
|
+
<path
|
|
19
|
+
d="M8.33301 7.66699L10.333 5.66699"
|
|
20
|
+
stroke="currentColor"
|
|
21
|
+
strokeWidth="1.13"
|
|
22
|
+
strokeLinecap="round"
|
|
23
|
+
strokeLinejoin="round"
|
|
24
|
+
/>
|
|
25
|
+
<path
|
|
26
|
+
d="M11.667 1.33301V4.33301"
|
|
27
|
+
stroke="currentColor"
|
|
28
|
+
strokeWidth="1.13"
|
|
29
|
+
strokeLinecap="round"
|
|
30
|
+
strokeLinejoin="round"
|
|
31
|
+
/>
|
|
32
|
+
<path
|
|
33
|
+
d="M13.167 2.83301H10.167"
|
|
34
|
+
stroke="currentColor"
|
|
35
|
+
strokeWidth="1.13"
|
|
36
|
+
strokeLinecap="round"
|
|
37
|
+
strokeLinejoin="round"
|
|
38
|
+
/>
|
|
39
|
+
<path
|
|
40
|
+
d="M5.33301 2.33301V4.33301"
|
|
41
|
+
stroke="currentColor"
|
|
42
|
+
strokeWidth="1.13"
|
|
43
|
+
strokeLinecap="round"
|
|
44
|
+
strokeLinejoin="round"
|
|
45
|
+
/>
|
|
46
|
+
<path
|
|
47
|
+
d="M6.33301 3.33301H4.33301"
|
|
48
|
+
stroke="currentColor"
|
|
49
|
+
strokeWidth="1.13"
|
|
50
|
+
strokeLinecap="round"
|
|
51
|
+
strokeLinejoin="round"
|
|
52
|
+
/>
|
|
53
|
+
<path
|
|
54
|
+
d="M13.333 9.33301V11.333"
|
|
55
|
+
stroke="currentColor"
|
|
56
|
+
strokeWidth="1.13"
|
|
57
|
+
strokeLinecap="round"
|
|
58
|
+
strokeLinejoin="round"
|
|
59
|
+
/>
|
|
60
|
+
<path
|
|
61
|
+
d="M14.333 10.333H12.333"
|
|
62
|
+
stroke="currentColor"
|
|
63
|
+
strokeWidth="1.13"
|
|
64
|
+
strokeLinecap="round"
|
|
65
|
+
strokeLinejoin="round"
|
|
66
|
+
/>
|
|
67
|
+
</svg>
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
MagicWandIcon.displayName = 'MagicWandIcon'
|
package/src/icons.jsx
CHANGED
|
@@ -168,6 +168,7 @@ export { LoopSection3Icon } from './icons/LoopSection3Icon'
|
|
|
168
168
|
export { NoLoopSection2Icon } from './icons/NoLoopSection2Icon'
|
|
169
169
|
export { NoLoopSectionIcon } from './icons/NoLoopSectionIcon'
|
|
170
170
|
export { NoLyricsIcon } from './icons/NoLyricsIcon'
|
|
171
|
+
export { MagicWandIcon } from './icons/MagicWandIcon'
|
|
171
172
|
export { MasteringIcon } from './icons/MasteringIcon'
|
|
172
173
|
export { MonoIcon } from './icons/MonoIcon'
|
|
173
174
|
export { MusicControlIcon } from './icons/MusicControlIcon'
|