@moises.ai/design-system 3.11.9 → 3.11.10
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/{Share2Icon-Bxgx9Zfv.js → TrackPreviousIcon-QO8TnAez.js} +1124 -1120
- package/dist/icons.js +1 -1
- package/dist/index.js +3079 -3032
- package/package.json +1 -1
- package/src/components/PeakLevel/PeakLevel.jsx +71 -0
- package/src/components/PeakLevel/PeakLevel.module.css +49 -0
- package/src/components/PeakLevel/PeakLevel.stories.jsx +192 -0
- package/src/icons/TrackPreviousIcon.jsx +18 -0
- package/src/icons.jsx +1 -0
- package/src/index.jsx +1 -0
package/package.json
CHANGED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { memo, useRef } from 'react'
|
|
2
|
+
import styles from './PeakLevel.module.css'
|
|
3
|
+
|
|
4
|
+
const PEAK_HOLD_THRESHOLD_HIGH = 0
|
|
5
|
+
const PEAK_HOLD_THRESHOLD_MEDIUM = -1
|
|
6
|
+
|
|
7
|
+
function linearToPeakDb(linear) {
|
|
8
|
+
if (!Array.isArray(linear)) return null
|
|
9
|
+
const peak = Math.max(linear[0] ?? 0, linear[1] ?? 0)
|
|
10
|
+
if (peak <= 0) return null
|
|
11
|
+
const db = 20 * Math.log10(peak)
|
|
12
|
+
if (db <= -96) return null
|
|
13
|
+
return db
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function getLevel(db) {
|
|
17
|
+
if (db == null) return 'reset'
|
|
18
|
+
if (db >= PEAK_HOLD_THRESHOLD_HIGH) return 'high'
|
|
19
|
+
if (db >= PEAK_HOLD_THRESHOLD_MEDIUM) return 'medium'
|
|
20
|
+
return 'regular'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function formatPeakDb(db) {
|
|
24
|
+
if (db == null) return '--'
|
|
25
|
+
return db.toFixed(1)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const PeakLevel = memo(function PeakLevel({
|
|
29
|
+
linear,
|
|
30
|
+
value,
|
|
31
|
+
onClick,
|
|
32
|
+
}) {
|
|
33
|
+
const peakHoldRef = useRef(null)
|
|
34
|
+
|
|
35
|
+
let displayDb = value ?? null
|
|
36
|
+
|
|
37
|
+
if (linear !== undefined) {
|
|
38
|
+
const currentDb = linearToPeakDb(linear)
|
|
39
|
+
|
|
40
|
+
if (currentDb != null) {
|
|
41
|
+
if (peakHoldRef.current == null || currentDb > peakHoldRef.current) {
|
|
42
|
+
peakHoldRef.current = currentDb
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (linear[0] <= 0 && linear[1] <= 0) {
|
|
47
|
+
peakHoldRef.current = null
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
displayDb = peakHoldRef.current
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const level = getLevel(displayDb)
|
|
54
|
+
const text = formatPeakDb(displayDb)
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<div
|
|
58
|
+
className={styles.container}
|
|
59
|
+
onClick={onClick}
|
|
60
|
+
role={onClick ? 'button' : undefined}
|
|
61
|
+
tabIndex={onClick ? 0 : undefined}
|
|
62
|
+
style={onClick ? { cursor: 'pointer' } : undefined}
|
|
63
|
+
>
|
|
64
|
+
<span className={`${styles.value} ${styles[level]}`}>
|
|
65
|
+
{text}
|
|
66
|
+
</span>
|
|
67
|
+
</div>
|
|
68
|
+
)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
PeakLevel.displayName = 'PeakLevel'
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
justify-content: center;
|
|
5
|
+
width: 24px;
|
|
6
|
+
padding: 2px 0;
|
|
7
|
+
border-radius: 4px;
|
|
8
|
+
user-select: none;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.value {
|
|
12
|
+
font-size: 12px;
|
|
13
|
+
font-weight: 500;
|
|
14
|
+
line-height: 16px;
|
|
15
|
+
letter-spacing: 0.04px;
|
|
16
|
+
white-space: nowrap;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.reset {
|
|
20
|
+
color: rgba(214, 235, 253, 0.19);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.regular {
|
|
24
|
+
color: #00dae8;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.medium {
|
|
28
|
+
color: #ffc53d;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.high {
|
|
32
|
+
color: #ec5d5e;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.container:hover .reset {
|
|
36
|
+
color: rgba(214, 235, 253, 0.19);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.container:hover .regular {
|
|
40
|
+
color: #75ebf5;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.container:hover .medium {
|
|
44
|
+
color: #ffe7b3;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.container:hover .high {
|
|
48
|
+
color: #ff9592;
|
|
49
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { useState, useEffect, useRef } from 'react'
|
|
2
|
+
import { PeakLevel } from './PeakLevel'
|
|
3
|
+
import { InputLevelMeter } from '../InputLevelMeter/InputLevelMeter'
|
|
4
|
+
import { useSimulatedInputLevel } from '../InputLevelMeter/useSimulatedInputLevel'
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
title: 'Components/PeakLevel',
|
|
8
|
+
component: PeakLevel,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: 'centered',
|
|
12
|
+
},
|
|
13
|
+
decorators: [
|
|
14
|
+
(Story) => (
|
|
15
|
+
<div style={{ padding: '16px', background: '#1d1d1d' }}>
|
|
16
|
+
<Story />
|
|
17
|
+
</div>
|
|
18
|
+
),
|
|
19
|
+
],
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const Reset = {
|
|
23
|
+
render: () => <PeakLevel value={null} />,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const RegularLevel = {
|
|
27
|
+
render: () => <PeakLevel value={-2} />,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const MediumLevel = {
|
|
31
|
+
render: () => <PeakLevel value={-0.2} />,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const HighLevel = {
|
|
35
|
+
render: () => <PeakLevel value={1.3} />,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const AllLevels = {
|
|
39
|
+
render: () => (
|
|
40
|
+
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
|
41
|
+
<div style={{ textAlign: 'center' }}>
|
|
42
|
+
<PeakLevel value={null} />
|
|
43
|
+
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', display: 'block', marginTop: '4px' }}>
|
|
44
|
+
Reset
|
|
45
|
+
</span>
|
|
46
|
+
</div>
|
|
47
|
+
<div style={{ textAlign: 'center' }}>
|
|
48
|
+
<PeakLevel value={-12} />
|
|
49
|
+
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', display: 'block', marginTop: '4px' }}>
|
|
50
|
+
Regular
|
|
51
|
+
</span>
|
|
52
|
+
</div>
|
|
53
|
+
<div style={{ textAlign: 'center' }}>
|
|
54
|
+
<PeakLevel value={-0.5} />
|
|
55
|
+
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', display: 'block', marginTop: '4px' }}>
|
|
56
|
+
Medium
|
|
57
|
+
</span>
|
|
58
|
+
</div>
|
|
59
|
+
<div style={{ textAlign: 'center' }}>
|
|
60
|
+
<PeakLevel value={1.3} />
|
|
61
|
+
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', display: 'block', marginTop: '4px' }}>
|
|
62
|
+
High
|
|
63
|
+
</span>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
),
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const WithLinearInput = {
|
|
70
|
+
render: () => {
|
|
71
|
+
function LivePeak() {
|
|
72
|
+
const linear = useSimulatedInputLevel()
|
|
73
|
+
return (
|
|
74
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
75
|
+
<div style={{ width: '200px' }}>
|
|
76
|
+
<InputLevelMeter linear={linear} />
|
|
77
|
+
</div>
|
|
78
|
+
<PeakLevel linear={linear} />
|
|
79
|
+
</div>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
return <LivePeak />
|
|
83
|
+
},
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export const WithClickToReset = {
|
|
87
|
+
render: () => {
|
|
88
|
+
function ResettablePeak() {
|
|
89
|
+
const linear = useSimulatedInputLevel()
|
|
90
|
+
const [peakDb, setPeakDb] = useState(null)
|
|
91
|
+
const peakRef = useRef(null)
|
|
92
|
+
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
const peak = Math.max(linear[0] ?? 0, linear[1] ?? 0)
|
|
95
|
+
if (peak > 0) {
|
|
96
|
+
const db = 20 * Math.log10(peak)
|
|
97
|
+
if (db > -96) {
|
|
98
|
+
if (peakRef.current == null || db > peakRef.current) {
|
|
99
|
+
peakRef.current = db
|
|
100
|
+
setPeakDb(db)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}, [linear])
|
|
105
|
+
|
|
106
|
+
const handleReset = () => {
|
|
107
|
+
peakRef.current = null
|
|
108
|
+
setPeakDb(null)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
113
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
114
|
+
<div style={{ width: '200px' }}>
|
|
115
|
+
<InputLevelMeter linear={linear} />
|
|
116
|
+
</div>
|
|
117
|
+
<PeakLevel value={peakDb} onClick={handleReset} />
|
|
118
|
+
</div>
|
|
119
|
+
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '10px', fontFamily: 'monospace' }}>
|
|
120
|
+
Click the peak value to reset
|
|
121
|
+
</span>
|
|
122
|
+
</div>
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
return <ResettablePeak />
|
|
126
|
+
},
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export const WithVolumeFader = {
|
|
130
|
+
render: () => {
|
|
131
|
+
function FaderWithPeak() {
|
|
132
|
+
const linear = useSimulatedInputLevel()
|
|
133
|
+
const [volume, setVolume] = useState(1)
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
137
|
+
<div style={{ width: '200px' }}>
|
|
138
|
+
<InputLevelMeter
|
|
139
|
+
linear={linear}
|
|
140
|
+
volume={volume}
|
|
141
|
+
onVolumeChange={([v]) => setVolume(v)}
|
|
142
|
+
/>
|
|
143
|
+
</div>
|
|
144
|
+
<PeakLevel linear={linear} />
|
|
145
|
+
</div>
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
return <FaderWithPeak />
|
|
149
|
+
},
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export const BoundaryValues = {
|
|
153
|
+
render: () => (
|
|
154
|
+
<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>
|
|
155
|
+
{[-96, -60, -24, -6, -1, -0.1, 0, 0.1, 1, 3, 6].map((db) => (
|
|
156
|
+
<div key={db} style={{ textAlign: 'center' }}>
|
|
157
|
+
<PeakLevel value={db} />
|
|
158
|
+
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', fontFamily: 'monospace', display: 'block', marginTop: '4px' }}>
|
|
159
|
+
{db} dB
|
|
160
|
+
</span>
|
|
161
|
+
</div>
|
|
162
|
+
))}
|
|
163
|
+
</div>
|
|
164
|
+
),
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export const MultipleChannels = {
|
|
168
|
+
render: () => {
|
|
169
|
+
function MultiChannel() {
|
|
170
|
+
const linear = useSimulatedInputLevel()
|
|
171
|
+
const labels = ['Master', 'Vocals', 'Guitar', 'Drums']
|
|
172
|
+
const multipliers = [1, 0.7, 0.4, 0.15]
|
|
173
|
+
|
|
174
|
+
return (
|
|
175
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
176
|
+
{labels.map((label, i) => (
|
|
177
|
+
<div key={label} style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
178
|
+
<span style={{ color: 'rgba(255,255,255,0.4)', fontSize: '10px', fontFamily: 'monospace', width: '48px' }}>
|
|
179
|
+
{label}
|
|
180
|
+
</span>
|
|
181
|
+
<div style={{ width: '160px' }}>
|
|
182
|
+
<InputLevelMeter linear={linear.map((l) => l * multipliers[i])} />
|
|
183
|
+
</div>
|
|
184
|
+
<PeakLevel linear={linear.map((l) => l * multipliers[i])} />
|
|
185
|
+
</div>
|
|
186
|
+
))}
|
|
187
|
+
</div>
|
|
188
|
+
)
|
|
189
|
+
}
|
|
190
|
+
return <MultiChannel />
|
|
191
|
+
},
|
|
192
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function TrackPreviousIcon({ width = 32, height = 32 }) {
|
|
2
|
+
return (
|
|
3
|
+
<svg
|
|
4
|
+
width={width}
|
|
5
|
+
height={height}
|
|
6
|
+
viewBox="0 0 32 32"
|
|
7
|
+
fill="none"
|
|
8
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
9
|
+
>
|
|
10
|
+
<path
|
|
11
|
+
d="M21.1797 9.6884C21.4546 9.86496 21.625 10.1751 21.625 10.5188L21.625 21.4812C21.625 21.8248 21.4546 22.135 21.1797 22.3116C20.9021 22.4898 20.5259 22.5208 20.2018 22.3202L11.8333 17.4237L11.8333 20.7917C11.8333 21.367 11.367 21.8333 10.7917 21.8333C10.2164 21.8333 9.75 21.367 9.75 20.7917V11.2083C9.75 10.633 10.2164 10.1667 10.7917 10.1667C11.367 10.1667 11.8333 10.633 11.8333 11.2083L11.8333 14.5762L20.2018 9.67975C20.5259 9.47916 20.9021 9.51013 21.1797 9.6884Z"
|
|
12
|
+
fill="currentColor"
|
|
13
|
+
/>
|
|
14
|
+
</svg>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
TrackPreviousIcon.displayName = 'TrackPreviousIcon'
|
package/src/icons.jsx
CHANGED
|
@@ -350,3 +350,4 @@ export { Play1Icon } from './icons/Play1Icon'
|
|
|
350
350
|
export { ChevronRightFilledIcon } from './icons/ChevronRightFilledIcon'
|
|
351
351
|
export { ChevronDownFilledIcon } from './icons/ChevronDownFilledIcon'
|
|
352
352
|
export { Share2Icon } from './icons/Share2Icon'
|
|
353
|
+
export { TrackPreviousIcon } from './icons/TrackPreviousIcon'
|
package/src/index.jsx
CHANGED
|
@@ -111,6 +111,7 @@ export { MoreButton } from './components/MoreButton/MoreButton'
|
|
|
111
111
|
export { MultiSelect } from './components/MultiSelect/MultiSelect'
|
|
112
112
|
export { MultiSelectCards } from './components/MultiSelectCards/MultiSelectCards'
|
|
113
113
|
export { PanControl } from './components/PanControl/PanControl'
|
|
114
|
+
export { PeakLevel } from './components/PeakLevel/PeakLevel'
|
|
114
115
|
export { ProductsBrandPattern } from './components/ProductsBrandPattern/ProductsBrandPattern'
|
|
115
116
|
export { ProductsList } from './components/ProductsList/ProductsList'
|
|
116
117
|
export { ProfileMenu } from './components/ProfileMenu/ProfileMenu'
|