@moises.ai/design-system 3.11.10 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moises.ai/design-system",
3
- "version": "3.11.10",
3
+ "version": "3.11.11",
4
4
  "description": "Design System package based on @radix-ui/themes with custom defaults",
5
5
  "private": false,
6
6
  "type": "module",
@@ -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
- if (currentPeakPct > peakHoldRef.current) {
109
- peakHoldRef.current = currentPeakPct
110
- }
111
- if (currentPeakPct <= 0) {
112
- peakHoldRef.current = 0
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
- {showPeakHold && (
199
- <>
200
- <div
201
- className={styles.peakDotTop}
202
- style={{
203
- left: `min(calc(${peakHoldPct}% + 3px), calc(100% - 3px))`,
204
- background: peakHoldColor,
205
- }}
206
- />
207
- <div
208
- className={styles.peakDotBottom}
209
- style={{
210
- left: `min(calc(${peakHoldPct}% + 3px), calc(100% - 3px))`,
211
- background: peakHoldColor,
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(216, 244, 246, 0.04);
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: #edeef0;
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
  }
@@ -1,8 +1,9 @@
1
1
  import { memo, useRef } from 'react'
2
2
  import styles from './PeakLevel.module.css'
3
3
 
4
- const PEAK_HOLD_THRESHOLD_HIGH = 0
5
- const PEAK_HOLD_THRESHOLD_MEDIUM = -1
4
+ const THRESHOLD_CLIP = 0
5
+ const THRESHOLD_RED = -6
6
+ const THRESHOLD_YELLOW = -12
6
7
 
7
8
  function linearToPeakDb(linear) {
8
9
  if (!Array.isArray(linear)) return null
@@ -15,8 +16,9 @@ function linearToPeakDb(linear) {
15
16
 
16
17
  function getLevel(db) {
17
18
  if (db == null) return 'reset'
18
- if (db >= PEAK_HOLD_THRESHOLD_HIGH) return 'high'
19
- if (db >= PEAK_HOLD_THRESHOLD_MEDIUM) return 'medium'
19
+ if (db >= THRESHOLD_CLIP) return 'clip'
20
+ if (db >= THRESHOLD_RED) return 'high'
21
+ if (db >= THRESHOLD_YELLOW) return 'medium'
20
22
  return 'regular'
21
23
  }
22
24
 
@@ -32,6 +32,16 @@
32
32
  color: #ec5d5e;
33
33
  }
34
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
+
35
45
  .container:hover .reset {
36
46
  color: rgba(214, 235, 253, 0.19);
37
47
  }
@@ -47,3 +57,7 @@
47
57
  .container:hover .high {
48
58
  color: #ff9592;
49
59
  }
60
+
61
+ .container:hover .clip {
62
+ color: #ff9592;
63
+ }
@@ -23,15 +23,19 @@ export const Reset = {
23
23
  render: () => <PeakLevel value={null} />,
24
24
  }
25
25
 
26
- export const RegularLevel = {
27
- render: () => <PeakLevel value={-2} />,
26
+ export const GreenLevel = {
27
+ render: () => <PeakLevel value={-18} />,
28
28
  }
29
29
 
30
- export const MediumLevel = {
31
- render: () => <PeakLevel value={-0.2} />,
30
+ export const YellowLevel = {
31
+ render: () => <PeakLevel value={-9} />,
32
32
  }
33
33
 
34
- export const HighLevel = {
34
+ export const RedLevel = {
35
+ render: () => <PeakLevel value={-3} />,
36
+ }
37
+
38
+ export const ClipLevel = {
35
39
  render: () => <PeakLevel value={1.3} />,
36
40
  }
37
41
 
@@ -45,21 +49,27 @@ export const AllLevels = {
45
49
  </span>
46
50
  </div>
47
51
  <div style={{ textAlign: 'center' }}>
48
- <PeakLevel value={-12} />
52
+ <PeakLevel value={-18} />
53
+ <span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', display: 'block', marginTop: '4px' }}>
54
+ Green (&lt;-12)
55
+ </span>
56
+ </div>
57
+ <div style={{ textAlign: 'center' }}>
58
+ <PeakLevel value={-9} />
49
59
  <span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', display: 'block', marginTop: '4px' }}>
50
- Regular
60
+ Yellow (-12 to -6)
51
61
  </span>
52
62
  </div>
53
63
  <div style={{ textAlign: 'center' }}>
54
- <PeakLevel value={-0.5} />
64
+ <PeakLevel value={-3} />
55
65
  <span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', display: 'block', marginTop: '4px' }}>
56
- Medium
66
+ Red (&gt;-6)
57
67
  </span>
58
68
  </div>
59
69
  <div style={{ textAlign: 'center' }}>
60
70
  <PeakLevel value={1.3} />
61
71
  <span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '9px', display: 'block', marginTop: '4px' }}>
62
- High
72
+ Clip (0+)
63
73
  </span>
64
74
  </div>
65
75
  </div>