@moises.ai/design-system 3.11.9 → 3.11.11
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 +4270 -4205
- package/package.json +1 -1
- package/src/components/InputLevelMeter/InputLevelMeter.jsx +53 -27
- package/src/components/InputLevelMeter/InputLevelMeter.module.css +13 -6
- package/src/components/InputLevelMeter/InputLevelMeter.stories.jsx +22 -0
- package/src/components/PeakLevel/PeakLevel.jsx +73 -0
- package/src/components/PeakLevel/PeakLevel.module.css +63 -0
- package/src/components/PeakLevel/PeakLevel.stories.jsx +202 -0
- package/src/icons/TrackPreviousIcon.jsx +18 -0
- package/src/icons.jsx +1 -0
- package/src/index.jsx +1 -0
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { memo, useCallback, useRef, useState } from 'react'
|
|
1
|
+
import { memo, useCallback, useEffect, useRef, useState } from 'react'
|
|
2
2
|
import { Tooltip } from '../Tooltip/Tooltip'
|
|
3
3
|
import styles from './InputLevelMeter.module.css'
|
|
4
4
|
|
|
@@ -86,6 +86,8 @@ export const InputLevelMeter = memo(function InputLevelMeter({
|
|
|
86
86
|
onVolumeChange,
|
|
87
87
|
showHandler = true,
|
|
88
88
|
showMeter = true,
|
|
89
|
+
hover = false,
|
|
90
|
+
resetPeakHold,
|
|
89
91
|
}) {
|
|
90
92
|
const [linearL, linearR] = linear
|
|
91
93
|
const leftLevel = clampLevel(linearToMeterLevel(linearL ?? 0))
|
|
@@ -95,6 +97,18 @@ export const InputLevelMeter = memo(function InputLevelMeter({
|
|
|
95
97
|
const isPressedRef = useRef(false)
|
|
96
98
|
const meterRef = useRef(null)
|
|
97
99
|
const peakHoldRef = useRef(0)
|
|
100
|
+
const peakTimerRef = useRef(null)
|
|
101
|
+
const [peakHoldPct, setPeakHoldPct] = useState(0)
|
|
102
|
+
const [peakRising, setPeakRising] = useState(false)
|
|
103
|
+
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
peakHoldRef.current = 0
|
|
106
|
+
setPeakHoldPct(0)
|
|
107
|
+
}, [resetPeakHold])
|
|
108
|
+
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
return () => clearTimeout(peakTimerRef.current)
|
|
111
|
+
}, [])
|
|
98
112
|
|
|
99
113
|
const faderPercent = Math.max(
|
|
100
114
|
0,
|
|
@@ -105,14 +119,28 @@ export const InputLevelMeter = memo(function InputLevelMeter({
|
|
|
105
119
|
const rightNormalized = getNormalizedLevel(rightLevel)
|
|
106
120
|
const currentPeakPct = Math.max(leftNormalized, rightNormalized)
|
|
107
121
|
|
|
108
|
-
|
|
109
|
-
peakHoldRef.current
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
if (currentPeakPct > peakHoldRef.current) {
|
|
124
|
+
peakHoldRef.current = currentPeakPct
|
|
125
|
+
setPeakHoldPct(currentPeakPct)
|
|
126
|
+
setPeakRising(true)
|
|
127
|
+
clearTimeout(peakTimerRef.current)
|
|
128
|
+
peakTimerRef.current = setTimeout(() => {
|
|
129
|
+
setPeakRising(false)
|
|
130
|
+
requestAnimationFrame(() => {
|
|
131
|
+
requestAnimationFrame(() => {
|
|
132
|
+
peakHoldRef.current = 0
|
|
133
|
+
setPeakHoldPct(0)
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
}, 400)
|
|
137
|
+
}
|
|
138
|
+
if (currentPeakPct <= 0) {
|
|
139
|
+
peakHoldRef.current = 0
|
|
140
|
+
setPeakHoldPct(0)
|
|
141
|
+
}
|
|
142
|
+
}, [currentPeakPct])
|
|
114
143
|
|
|
115
|
-
const peakHoldPct = peakHoldRef.current
|
|
116
144
|
const peakHoldColor = getPeakHoldColor(peakHoldPct)
|
|
117
145
|
const showPeakHold = peakHoldPct > 0
|
|
118
146
|
|
|
@@ -189,30 +217,28 @@ export const InputLevelMeter = memo(function InputLevelMeter({
|
|
|
189
217
|
delayDuration={0}
|
|
190
218
|
>
|
|
191
219
|
<div
|
|
192
|
-
className={`${styles.thumb} ${isPressed ? styles.pressed : ''}`}
|
|
220
|
+
className={`${styles.thumb} ${isPressed ? styles.pressed : hover ? styles.hovered : ''}`}
|
|
193
221
|
style={{ left: `${faderPercent}%` }}
|
|
194
222
|
/>
|
|
195
223
|
</Tooltip>
|
|
196
224
|
)}
|
|
197
225
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
</>
|
|
215
|
-
)}
|
|
226
|
+
<div
|
|
227
|
+
className={`${styles.peakDotTop} ${peakRising ? styles.peakRising : ''}`}
|
|
228
|
+
style={{
|
|
229
|
+
left: `min(calc(${peakHoldPct}% + 3px), calc(100% - 3px))`,
|
|
230
|
+
background: peakHoldColor,
|
|
231
|
+
opacity: showPeakHold ? 1 : 0,
|
|
232
|
+
}}
|
|
233
|
+
/>
|
|
234
|
+
<div
|
|
235
|
+
className={`${styles.peakDotBottom} ${peakRising ? styles.peakRising : ''}`}
|
|
236
|
+
style={{
|
|
237
|
+
left: `min(calc(${peakHoldPct}% + 3px), calc(100% - 3px))`,
|
|
238
|
+
background: peakHoldColor,
|
|
239
|
+
opacity: showPeakHold ? 1 : 0,
|
|
240
|
+
}}
|
|
241
|
+
/>
|
|
216
242
|
</div>
|
|
217
243
|
|
|
218
244
|
{showMeter && (
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
padding: 2px;
|
|
16
16
|
border-radius: 3px;
|
|
17
17
|
width: 100%;
|
|
18
|
-
background: rgba(
|
|
18
|
+
background: rgba(211, 237, 248, 0.11);
|
|
19
19
|
transition: background-color 0.1s ease;
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -23,10 +23,6 @@
|
|
|
23
23
|
cursor: ew-resize;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
.bars.pressed {
|
|
27
|
-
background: rgba(221, 234, 248, 0.08);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
26
|
.barRow {
|
|
31
27
|
display: inline-grid;
|
|
32
28
|
grid-template-rows: max-content;
|
|
@@ -66,12 +62,18 @@
|
|
|
66
62
|
width: 8px;
|
|
67
63
|
height: 19px;
|
|
68
64
|
border-radius: 9999px;
|
|
69
|
-
background: #
|
|
65
|
+
background: #777b84;
|
|
66
|
+
border: 1px solid rgba(46, 49, 53, 0.3);
|
|
70
67
|
cursor: ew-resize;
|
|
71
68
|
z-index: 2;
|
|
72
69
|
touch-action: none;
|
|
73
70
|
}
|
|
74
71
|
|
|
72
|
+
.thumb.hovered,
|
|
73
|
+
.container:hover .thumb {
|
|
74
|
+
background: white;
|
|
75
|
+
}
|
|
76
|
+
|
|
75
77
|
.thumb.pressed {
|
|
76
78
|
background: white;
|
|
77
79
|
}
|
|
@@ -83,6 +85,11 @@
|
|
|
83
85
|
border-radius: 9999px;
|
|
84
86
|
z-index: 1;
|
|
85
87
|
pointer-events: none;
|
|
88
|
+
transition: left 0.5s ease-out, opacity 0.5s ease-out;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.peakDot.peakRising {
|
|
92
|
+
transition: opacity 0.3s ease-out;
|
|
86
93
|
}
|
|
87
94
|
|
|
88
95
|
.peakDotTop {
|
|
@@ -23,6 +23,7 @@ export default {
|
|
|
23
23
|
},
|
|
24
24
|
showHandler: { control: 'boolean' },
|
|
25
25
|
showMeter: { control: 'boolean' },
|
|
26
|
+
hover: { control: 'boolean' },
|
|
26
27
|
onVolumeChange: { action: 'volumeChanged' },
|
|
27
28
|
},
|
|
28
29
|
}
|
|
@@ -147,6 +148,25 @@ export const AsymmetricLevels = {
|
|
|
147
148
|
},
|
|
148
149
|
}
|
|
149
150
|
|
|
151
|
+
export const HoverState = {
|
|
152
|
+
render: () => (
|
|
153
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
154
|
+
<div>
|
|
155
|
+
<span style={{ color: 'rgba(255,255,255,0.4)', fontSize: '10px', fontFamily: 'monospace', display: 'block', marginBottom: '4px' }}>
|
|
156
|
+
Default
|
|
157
|
+
</span>
|
|
158
|
+
<AnimatedMeter />
|
|
159
|
+
</div>
|
|
160
|
+
<div>
|
|
161
|
+
<span style={{ color: 'rgba(255,255,255,0.4)', fontSize: '10px', fontFamily: 'monospace', display: 'block', marginBottom: '4px' }}>
|
|
162
|
+
hover=true (parent hovered)
|
|
163
|
+
</span>
|
|
164
|
+
<AnimatedMeter hover />
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
),
|
|
168
|
+
}
|
|
169
|
+
|
|
150
170
|
export const WithoutHandler = {
|
|
151
171
|
render: () => <AnimatedMeter showHandler={false} />,
|
|
152
172
|
}
|
|
@@ -289,6 +309,7 @@ export const Playground = {
|
|
|
289
309
|
volume: 1,
|
|
290
310
|
showHandler: true,
|
|
291
311
|
showMeter: true,
|
|
312
|
+
hover: false,
|
|
292
313
|
},
|
|
293
314
|
render: (args) => {
|
|
294
315
|
function PlaygroundMeter() {
|
|
@@ -306,6 +327,7 @@ export const Playground = {
|
|
|
306
327
|
onVolumeChange={([v]) => setVolume(v)}
|
|
307
328
|
showHandler={args.showHandler}
|
|
308
329
|
showMeter={args.showMeter}
|
|
330
|
+
hover={args.hover}
|
|
309
331
|
/>
|
|
310
332
|
)
|
|
311
333
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { memo, useRef } from 'react'
|
|
2
|
+
import styles from './PeakLevel.module.css'
|
|
3
|
+
|
|
4
|
+
const THRESHOLD_CLIP = 0
|
|
5
|
+
const THRESHOLD_RED = -6
|
|
6
|
+
const THRESHOLD_YELLOW = -12
|
|
7
|
+
|
|
8
|
+
function linearToPeakDb(linear) {
|
|
9
|
+
if (!Array.isArray(linear)) return null
|
|
10
|
+
const peak = Math.max(linear[0] ?? 0, linear[1] ?? 0)
|
|
11
|
+
if (peak <= 0) return null
|
|
12
|
+
const db = 20 * Math.log10(peak)
|
|
13
|
+
if (db <= -96) return null
|
|
14
|
+
return db
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getLevel(db) {
|
|
18
|
+
if (db == null) return 'reset'
|
|
19
|
+
if (db >= THRESHOLD_CLIP) return 'clip'
|
|
20
|
+
if (db >= THRESHOLD_RED) return 'high'
|
|
21
|
+
if (db >= THRESHOLD_YELLOW) return 'medium'
|
|
22
|
+
return 'regular'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function formatPeakDb(db) {
|
|
26
|
+
if (db == null) return '--'
|
|
27
|
+
return db.toFixed(1)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const PeakLevel = memo(function PeakLevel({
|
|
31
|
+
linear,
|
|
32
|
+
value,
|
|
33
|
+
onClick,
|
|
34
|
+
}) {
|
|
35
|
+
const peakHoldRef = useRef(null)
|
|
36
|
+
|
|
37
|
+
let displayDb = value ?? null
|
|
38
|
+
|
|
39
|
+
if (linear !== undefined) {
|
|
40
|
+
const currentDb = linearToPeakDb(linear)
|
|
41
|
+
|
|
42
|
+
if (currentDb != null) {
|
|
43
|
+
if (peakHoldRef.current == null || currentDb > peakHoldRef.current) {
|
|
44
|
+
peakHoldRef.current = currentDb
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (linear[0] <= 0 && linear[1] <= 0) {
|
|
49
|
+
peakHoldRef.current = null
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
displayDb = peakHoldRef.current
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const level = getLevel(displayDb)
|
|
56
|
+
const text = formatPeakDb(displayDb)
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<div
|
|
60
|
+
className={styles.container}
|
|
61
|
+
onClick={onClick}
|
|
62
|
+
role={onClick ? 'button' : undefined}
|
|
63
|
+
tabIndex={onClick ? 0 : undefined}
|
|
64
|
+
style={onClick ? { cursor: 'pointer' } : undefined}
|
|
65
|
+
>
|
|
66
|
+
<span className={`${styles.value} ${styles[level]}`}>
|
|
67
|
+
{text}
|
|
68
|
+
</span>
|
|
69
|
+
</div>
|
|
70
|
+
)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
PeakLevel.displayName = 'PeakLevel'
|
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
.clip {
|
|
36
|
+
color: #ec5d5e;
|
|
37
|
+
animation: blink 0.6s steps(1) infinite;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@keyframes blink {
|
|
41
|
+
0%, 100% { opacity: 1; }
|
|
42
|
+
50% { opacity: 0.4; }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.container:hover .reset {
|
|
46
|
+
color: rgba(214, 235, 253, 0.19);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.container:hover .regular {
|
|
50
|
+
color: #75ebf5;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.container:hover .medium {
|
|
54
|
+
color: #ffe7b3;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.container:hover .high {
|
|
58
|
+
color: #ff9592;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.container:hover .clip {
|
|
62
|
+
color: #ff9592;
|
|
63
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
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 GreenLevel = {
|
|
27
|
+
render: () => <PeakLevel value={-18} />,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const YellowLevel = {
|
|
31
|
+
render: () => <PeakLevel value={-9} />,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const RedLevel = {
|
|
35
|
+
render: () => <PeakLevel value={-3} />,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const ClipLevel = {
|
|
39
|
+
render: () => <PeakLevel value={1.3} />,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const AllLevels = {
|
|
43
|
+
render: () => (
|
|
44
|
+
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
|
45
|
+
<div style={{ textAlign: 'center' }}>
|
|
46
|
+
<PeakLevel value={null} />
|
|
47
|
+
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', display: 'block', marginTop: '4px' }}>
|
|
48
|
+
Reset
|
|
49
|
+
</span>
|
|
50
|
+
</div>
|
|
51
|
+
<div style={{ textAlign: 'center' }}>
|
|
52
|
+
<PeakLevel value={-18} />
|
|
53
|
+
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', display: 'block', marginTop: '4px' }}>
|
|
54
|
+
Green (<-12)
|
|
55
|
+
</span>
|
|
56
|
+
</div>
|
|
57
|
+
<div style={{ textAlign: 'center' }}>
|
|
58
|
+
<PeakLevel value={-9} />
|
|
59
|
+
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', display: 'block', marginTop: '4px' }}>
|
|
60
|
+
Yellow (-12 to -6)
|
|
61
|
+
</span>
|
|
62
|
+
</div>
|
|
63
|
+
<div style={{ textAlign: 'center' }}>
|
|
64
|
+
<PeakLevel value={-3} />
|
|
65
|
+
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', display: 'block', marginTop: '4px' }}>
|
|
66
|
+
Red (>-6)
|
|
67
|
+
</span>
|
|
68
|
+
</div>
|
|
69
|
+
<div style={{ textAlign: 'center' }}>
|
|
70
|
+
<PeakLevel value={1.3} />
|
|
71
|
+
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', display: 'block', marginTop: '4px' }}>
|
|
72
|
+
Clip (0+)
|
|
73
|
+
</span>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
),
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const WithLinearInput = {
|
|
80
|
+
render: () => {
|
|
81
|
+
function LivePeak() {
|
|
82
|
+
const linear = useSimulatedInputLevel()
|
|
83
|
+
return (
|
|
84
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
85
|
+
<div style={{ width: '200px' }}>
|
|
86
|
+
<InputLevelMeter linear={linear} />
|
|
87
|
+
</div>
|
|
88
|
+
<PeakLevel linear={linear} />
|
|
89
|
+
</div>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
return <LivePeak />
|
|
93
|
+
},
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const WithClickToReset = {
|
|
97
|
+
render: () => {
|
|
98
|
+
function ResettablePeak() {
|
|
99
|
+
const linear = useSimulatedInputLevel()
|
|
100
|
+
const [peakDb, setPeakDb] = useState(null)
|
|
101
|
+
const peakRef = useRef(null)
|
|
102
|
+
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
const peak = Math.max(linear[0] ?? 0, linear[1] ?? 0)
|
|
105
|
+
if (peak > 0) {
|
|
106
|
+
const db = 20 * Math.log10(peak)
|
|
107
|
+
if (db > -96) {
|
|
108
|
+
if (peakRef.current == null || db > peakRef.current) {
|
|
109
|
+
peakRef.current = db
|
|
110
|
+
setPeakDb(db)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}, [linear])
|
|
115
|
+
|
|
116
|
+
const handleReset = () => {
|
|
117
|
+
peakRef.current = null
|
|
118
|
+
setPeakDb(null)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
123
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
124
|
+
<div style={{ width: '200px' }}>
|
|
125
|
+
<InputLevelMeter linear={linear} />
|
|
126
|
+
</div>
|
|
127
|
+
<PeakLevel value={peakDb} onClick={handleReset} />
|
|
128
|
+
</div>
|
|
129
|
+
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '10px', fontFamily: 'monospace' }}>
|
|
130
|
+
Click the peak value to reset
|
|
131
|
+
</span>
|
|
132
|
+
</div>
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
return <ResettablePeak />
|
|
136
|
+
},
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export const WithVolumeFader = {
|
|
140
|
+
render: () => {
|
|
141
|
+
function FaderWithPeak() {
|
|
142
|
+
const linear = useSimulatedInputLevel()
|
|
143
|
+
const [volume, setVolume] = useState(1)
|
|
144
|
+
|
|
145
|
+
return (
|
|
146
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
147
|
+
<div style={{ width: '200px' }}>
|
|
148
|
+
<InputLevelMeter
|
|
149
|
+
linear={linear}
|
|
150
|
+
volume={volume}
|
|
151
|
+
onVolumeChange={([v]) => setVolume(v)}
|
|
152
|
+
/>
|
|
153
|
+
</div>
|
|
154
|
+
<PeakLevel linear={linear} />
|
|
155
|
+
</div>
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
return <FaderWithPeak />
|
|
159
|
+
},
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export const BoundaryValues = {
|
|
163
|
+
render: () => (
|
|
164
|
+
<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>
|
|
165
|
+
{[-96, -60, -24, -6, -1, -0.1, 0, 0.1, 1, 3, 6].map((db) => (
|
|
166
|
+
<div key={db} style={{ textAlign: 'center' }}>
|
|
167
|
+
<PeakLevel value={db} />
|
|
168
|
+
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', fontFamily: 'monospace', display: 'block', marginTop: '4px' }}>
|
|
169
|
+
{db} dB
|
|
170
|
+
</span>
|
|
171
|
+
</div>
|
|
172
|
+
))}
|
|
173
|
+
</div>
|
|
174
|
+
),
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export const MultipleChannels = {
|
|
178
|
+
render: () => {
|
|
179
|
+
function MultiChannel() {
|
|
180
|
+
const linear = useSimulatedInputLevel()
|
|
181
|
+
const labels = ['Master', 'Vocals', 'Guitar', 'Drums']
|
|
182
|
+
const multipliers = [1, 0.7, 0.4, 0.15]
|
|
183
|
+
|
|
184
|
+
return (
|
|
185
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
186
|
+
{labels.map((label, i) => (
|
|
187
|
+
<div key={label} style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
188
|
+
<span style={{ color: 'rgba(255,255,255,0.4)', fontSize: '10px', fontFamily: 'monospace', width: '48px' }}>
|
|
189
|
+
{label}
|
|
190
|
+
</span>
|
|
191
|
+
<div style={{ width: '160px' }}>
|
|
192
|
+
<InputLevelMeter linear={linear.map((l) => l * multipliers[i])} />
|
|
193
|
+
</div>
|
|
194
|
+
<PeakLevel linear={linear.map((l) => l * multipliers[i])} />
|
|
195
|
+
</div>
|
|
196
|
+
))}
|
|
197
|
+
</div>
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
return <MultiChannel />
|
|
201
|
+
},
|
|
202
|
+
}
|
|
@@ -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'
|