@tremolo-ui/react 0.1.5 → 0.2.0

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.
Files changed (40) hide show
  1. package/dist/index.cjs +325 -239
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +149 -64
  4. package/dist/index.css.map +1 -1
  5. package/dist/index.d.cts +229 -199
  6. package/dist/index.d.cts.map +1 -1
  7. package/dist/index.d.ts +229 -199
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +314 -223
  10. package/dist/index.js.map +1 -1
  11. package/package.json +2 -2
  12. package/src/components/Knob/index.css +50 -25
  13. package/src/components/Knob/index.tsx +37 -32
  14. package/src/components/NumberInput/index.css +31 -15
  15. package/src/components/NumberInput/index.tsx +22 -14
  16. package/src/components/Piano/context.tsx +1 -1
  17. package/src/components/Piano/index.css +17 -8
  18. package/src/components/Piano/index.tsx +259 -220
  19. package/src/components/Piano/key.tsx +3 -3
  20. package/src/components/Slider/Thumb.tsx +1 -1
  21. package/src/components/Slider/Track.tsx +3 -3
  22. package/src/components/Slider/index.css +33 -8
  23. package/src/components/Slider/index.tsx +25 -25
  24. package/src/components/XYPad/Area.tsx +4 -3
  25. package/src/components/XYPad/Thumb.tsx +8 -4
  26. package/src/components/XYPad/index.css +18 -4
  27. package/src/components/XYPad/index.tsx +25 -19
  28. package/src/hooks/useAnimationFrame.ts +3 -0
  29. package/src/hooks/useCallbackRef.ts +2 -2
  30. package/src/hooks/useDrag.ts +2 -1
  31. package/src/hooks/useDragWithElement.ts +2 -1
  32. package/src/hooks/useEventListener.ts +3 -0
  33. package/src/hooks/useInterval.ts +3 -0
  34. package/src/hooks/useLongPress.ts +3 -0
  35. package/src/hooks/useMIDIAccess.ts +40 -0
  36. package/src/hooks/useMIDIInput.ts +50 -0
  37. package/src/hooks/useMIDIMessage.ts +24 -0
  38. package/src/hooks/useRefCallbackEvent.ts +4 -0
  39. package/src/index.ts +30 -35
  40. package/src/styles/global.css +0 -4
@@ -3,11 +3,13 @@ import React, {
3
3
  ComponentPropsWithoutRef,
4
4
  createRef,
5
5
  CSSProperties,
6
+ forwardRef,
6
7
  ReactElement,
7
8
  ReactNode,
8
9
  RefObject,
9
10
  useCallback,
10
11
  useEffect,
12
+ useImperativeHandle,
11
13
  useMemo,
12
14
  useRef,
13
15
  useState,
@@ -33,15 +35,12 @@ import {
33
35
  WhiteKey,
34
36
  } from './key'
35
37
  import { KeyboardShortcuts } from './keyboardShortcuts'
38
+ import { KeyLabel } from './KeyLabel'
36
39
 
37
40
  /**
38
- * Piano component
39
- *
40
- * TODO:
41
- * - add scale highlight
41
+ * [noteRange.first, noteRange.first + 1 ..., noteRange.last]
42
+ * @category Piano
42
43
  */
43
-
44
- /** @category Piano */
45
44
  export function getNoteRangeArray(noteRange: NoteRange) {
46
45
  return Array.from(
47
46
  { length: noteRange.last - noteRange.first + 1 },
@@ -51,10 +50,8 @@ export function getNoteRangeArray(noteRange: NoteRange) {
51
50
 
52
51
  /** @category Piano */
53
52
  export interface PianoProps {
54
- // required
55
53
  noteRange: NoteRange
56
54
 
57
- // optional
58
55
  glissando?: boolean
59
56
  midiMax?: number
60
57
  keyboardShortcuts?: KeyboardShortcuts
@@ -62,11 +59,10 @@ export interface PianoProps {
62
59
  whiteNoteWidth?: number
63
60
  blackNoteWidth?: number
64
61
  height?: number | string
65
-
66
62
  style?: CSSProperties
67
63
 
68
- onPlayNote?: (noteNumber: number) => void
69
- onStopNote?: (noteNumber: number) => void
64
+ onPlayNote?: (note: number, velocity?: number) => void
65
+ onStopNote?: (note: number) => void
70
66
 
71
67
  label?: (note: number, index: number) => ReactNode
72
68
 
@@ -79,236 +75,279 @@ export interface PianoProps {
79
75
  const blackPerWhiteWidth = defaultBlackKeyWidth / defaultWhiteKeyWidth // 0.65
80
76
 
81
77
  /**
82
- * Customizable piano component.
83
78
  * @category Piano
84
79
  */
85
- export function Piano({
86
- noteRange,
87
- glissando = true,
88
- midiMax = 127,
89
- keyboardShortcuts,
90
- fill = false,
91
- height = fill ? '100%' : 160,
92
- whiteNoteWidth: _whiteNoteWidth = defaultWhiteKeyWidth,
93
- style,
94
- className,
95
- onPlayNote,
96
- onStopNote,
97
- label,
98
- children,
99
- onPointerDown,
100
- ...props
101
- }: PianoProps & Omit<ComponentPropsWithoutRef<'div'>, keyof PianoProps>) {
102
- // -- state and ref ---
103
- const [whiteNoteWidth, setWhiteNoteWidth] = useState(_whiteNoteWidth)
104
- const keyRefs = useRef<RefObject<KeyMethods | null>[]>([])
105
- for (let i = 0; i < noteRange.last - noteRange.first + 1; i++) {
106
- keyRefs.current[i] = createRef<KeyMethods>()
107
- }
108
- const pianoRef = useRef<HTMLDivElement>(null)
109
- const hitKeyIndex = useRef(-1)
80
+ export interface PianoMethods {
81
+ playNote: (note: number, velocity?: number) => void
82
+ stopNote: (note: number) => void
83
+ }
110
84
 
111
- // --- interpret props ---
112
- const noteRangeArray = getNoteRangeArray(noteRange)
113
- const whiteNotes = noteRangeArray.filter((v) => isWhiteKey(v))
114
- const blackNotes = noteRangeArray.filter((v) => isBlackKey(v))
115
- const whiteNoteCount = whiteNotes.length
116
- const padding = 1
117
- const staticWidth = (whiteNoteWidth + padding) * whiteNoteCount
118
- // const blackNoteShiftPercent = 0.3
85
+ type Props = PianoProps &
86
+ Omit<ComponentPropsWithoutRef<'div'>, keyof PianoProps>
119
87
 
120
- const childrenWithProps = useMemo(() => {
121
- return (
122
- children &&
123
- React.Children.map(children, (child, index) => {
124
- if (React.isValidElement(child)) {
125
- const __width =
126
- child.type == WhiteKey ? whiteNoteWidth : whiteNoteWidth * 0.65
127
- const props = { ref: keyRefs.current[index], __width }
128
- return React.cloneElement(child, props)
88
+ const PianoImpl = forwardRef<PianoMethods, Props>(
89
+ (
90
+ {
91
+ noteRange,
92
+ glissando = true,
93
+ midiMax = 127,
94
+ keyboardShortcuts,
95
+ fill = false,
96
+ height = fill ? '100%' : 160,
97
+ whiteNoteWidth: _whiteNoteWidth = defaultWhiteKeyWidth,
98
+ style,
99
+ className,
100
+ onPlayNote,
101
+ onStopNote,
102
+ label,
103
+ children,
104
+ onPointerDown,
105
+ ...props
106
+ },
107
+ forwardedRef,
108
+ ) => {
109
+ // -- state and ref ---
110
+ const [whiteNoteWidth, setWhiteNoteWidth] = useState(_whiteNoteWidth)
111
+ const keyRefs = useRef<RefObject<KeyMethods | null>[]>([])
112
+ for (let i = 0; i < noteRange.last - noteRange.first + 1; i++) {
113
+ keyRefs.current[i] = createRef<KeyMethods>()
114
+ }
115
+ const pianoRef = useRef<HTMLDivElement>(null)
116
+ const hitKeyIndex = useRef(-1)
117
+
118
+ // --- interpret props ---
119
+ const noteRangeArray = getNoteRangeArray(noteRange)
120
+ const whiteNotes = noteRangeArray.filter((v) => isWhiteKey(v))
121
+ const blackNotes = noteRangeArray.filter((v) => isBlackKey(v))
122
+ const whiteNoteCount = whiteNotes.length
123
+ const padding = 1
124
+ const staticWidth = (whiteNoteWidth + padding) * whiteNoteCount
125
+ // const blackNoteShiftPercent = 0.3
126
+
127
+ const childrenWithProps = useMemo(() => {
128
+ return (
129
+ children &&
130
+ React.Children.map(children, (child, index) => {
131
+ if (React.isValidElement(child)) {
132
+ const __width =
133
+ child.type == WhiteKey ? whiteNoteWidth : whiteNoteWidth * 0.65
134
+ const props = { ref: keyRefs.current[index], __width }
135
+ return React.cloneElement(child, props)
136
+ }
137
+ return child
138
+ })
139
+ )
140
+ }, [children, whiteNoteWidth])
141
+
142
+ // --- internal functions ---
143
+ const notePosition = useCallback(
144
+ (note: number) => {
145
+ const pitchPositions: Record<NoteKey, number> = {
146
+ C: 0,
147
+ 'C#': 1,
148
+ D: 1,
149
+ 'D#': 2,
150
+ E: 2,
151
+ F: 3,
152
+ 'F#': 4,
153
+ G: 4,
154
+ 'G#': 5,
155
+ A: 5,
156
+ 'A#': 6,
157
+ B: 6,
129
158
  }
130
- return child
131
- })
132
- )
133
- }, [children, whiteNoteWidth])
134
159
 
135
- // --- internal functions ---
136
- const notePosition = useCallback(
137
- (note: number) => {
138
- const pitchPositions: Record<NoteKey, number> = {
139
- C: 0,
140
- 'C#': 1,
141
- D: 1,
142
- 'D#': 2,
143
- E: 2,
144
- F: 3,
145
- 'F#': 4,
146
- G: 4,
147
- 'G#': 5,
148
- A: 5,
149
- 'A#': 6,
150
- B: 6,
151
- }
160
+ const blackNoteWidth = whiteNoteWidth * blackPerWhiteWidth
161
+ const padding = 1
162
+ const targetNoteKey = noteKey(note)
163
+ const firstNoteKey = noteKey(noteRange.first)
164
+ const octave = Math.floor((note - noteRange.first) / 12)
165
+ const octaveOffset =
166
+ noteKeys.indexOf(firstNoteKey) > noteKeys.indexOf(targetNoteKey)
167
+ ? 1
168
+ : 0
169
+ const w = whiteNoteWidth + padding
170
+ const pos = pitchPositions[targetNoteKey] - pitchPositions[firstNoteKey]
171
+ const blackKeyOffset = isBlackKey(note) ? blackNoteWidth / 2 : 0
172
+ return pos * w + (octave + octaveOffset) * 7 * w - blackKeyOffset
173
+ },
174
+ [noteRange.first, whiteNoteWidth],
175
+ )
152
176
 
153
- const blackNoteWidth = whiteNoteWidth * blackPerWhiteWidth
154
- const padding = 1
155
- const targetNoteKey = noteKey(note)
156
- const firstNoteKey = noteKey(noteRange.first)
157
- const octave = Math.floor((note - noteRange.first) / 12)
158
- const octaveOffset =
159
- noteKeys.indexOf(firstNoteKey) > noteKeys.indexOf(targetNoteKey) ? 1 : 0
160
- const w = whiteNoteWidth + padding
161
- const pos = pitchPositions[targetNoteKey] - pitchPositions[firstNoteKey]
162
- const blackKeyOffset = isBlackKey(note) ? blackNoteWidth / 2 : 0
163
- return pos * w + (octave + octaveOffset) * 7 * w - blackKeyOffset
164
- },
165
- [noteRange.first, whiteNoteWidth],
166
- )
177
+ const getHitKeyIndex = useCallback(
178
+ (x: number, y: number) => {
179
+ if (!pianoRef.current) return -1
180
+ const containerHeight = pianoRef.current.clientHeight
181
+ const notes = [...blackNotes, ...whiteNotes]
182
+ for (let i = 0; i < notes.length; i++) {
183
+ const note = notes[i]
184
+ const pos = notePosition(note)
185
+ const w = isWhiteKey(note)
186
+ ? whiteNoteWidth
187
+ : whiteNoteWidth * blackPerWhiteWidth
188
+ const h = isWhiteKey(note) ? containerHeight : containerHeight * 0.6
189
+ if (pos <= x && x < pos + w && 0 <= y && y < h) {
190
+ return note
191
+ }
192
+ }
193
+ return -1
194
+ },
195
+ [blackNotes, notePosition, whiteNoteWidth, whiteNotes],
196
+ )
167
197
 
168
- const getHitKeyIndex = useCallback(
169
- (x: number, y: number) => {
170
- if (!pianoRef.current) return -1
171
- const containerHeight = pianoRef.current.clientHeight
172
- const notes = [...blackNotes, ...whiteNotes]
173
- for (let i = 0; i < notes.length; i++) {
174
- const note = notes[i]
175
- const pos = notePosition(note)
176
- const w = isWhiteKey(note)
177
- ? whiteNoteWidth
178
- : whiteNoteWidth * blackPerWhiteWidth
179
- const h = isWhiteKey(note) ? containerHeight : containerHeight * 0.6
180
- if (pos <= x && x < pos + w && 0 <= y && y < h) {
181
- return note
198
+ // TODO: 単一のポインターに対しては、useDragで対応可能だが、
199
+ // マルチタッチに対しては、TouchEventを使う必要がありそう
200
+ // 取り敢えず、シングルタッチだけ対応
201
+ const onDrag = useCallback(
202
+ (perX: number, perY: number) => {
203
+ if (!pianoRef.current) return
204
+ const x = perX * staticWidth
205
+ const y = perY * pianoRef.current.clientHeight
206
+ const note = getHitKeyIndex(x, y)
207
+ const index = noteRangeArray.indexOf(note)
208
+ if (index == -1) return
209
+ if (hitKeyIndex.current != index) {
210
+ keyRefs.current[hitKeyIndex.current]?.current?.stop()
211
+ keyRefs.current[index]?.current?.play()
212
+ hitKeyIndex.current = index
182
213
  }
183
- }
184
- return -1
185
- },
186
- [blackNotes, notePosition, whiteNoteWidth, whiteNotes],
187
- )
214
+ },
215
+ [getHitKeyIndex, noteRangeArray, staticWidth],
216
+ )
188
217
 
189
- // TODO: 単一のポインターに対しては、useDragで対応可能だが、
190
- // マルチタッチに対しては、TouchEventを使う必要がありそう
191
- // 取り敢えず、シングルタッチだけ対応
192
- const onDrag = useCallback(
193
- (perX: number, perY: number) => {
194
- if (!pianoRef.current) return
195
- const x = perX * staticWidth
196
- const y = perY * pianoRef.current.clientHeight
197
- const note = getHitKeyIndex(x, y)
198
- const index = noteRangeArray.indexOf(note)
199
- if (index == -1) return
200
- if (hitKeyIndex.current != index) {
218
+ const onDragEnd = useCallback(() => {
219
+ if (keyRefs.current[hitKeyIndex.current]?.current?.played()) {
201
220
  keyRefs.current[hitKeyIndex.current]?.current?.stop()
202
- keyRefs.current[index]?.current?.play()
203
- hitKeyIndex.current = index
204
221
  }
205
- },
206
- [getHitKeyIndex, noteRangeArray, staticWidth],
207
- )
222
+ hitKeyIndex.current = -1
223
+ }, [keyRefs])
208
224
 
209
- const onDragEnd = useCallback(() => {
210
- if (keyRefs.current[hitKeyIndex.current]?.current?.played()) {
211
- keyRefs.current[hitKeyIndex.current]?.current?.stop()
212
- }
213
- hitKeyIndex.current = -1
214
- }, [keyRefs])
225
+ // --- hooks ---
226
+ useEffect(() => {
227
+ if (fill && pianoRef.current) {
228
+ const parent = pianoRef.current.parentElement
229
+ if (!parent) throw new Error("doesn't have a parent element.")
230
+ const resizeObserver = new ResizeObserver(() => {
231
+ const w = pianoRef.current!.clientWidth
232
+ setWhiteNoteWidth(w / whiteNoteCount - padding)
233
+ })
234
+ resizeObserver.observe(parent)
235
+ return () => {
236
+ resizeObserver.unobserve(parent)
237
+ }
238
+ } else {
239
+ setWhiteNoteWidth(_whiteNoteWidth)
240
+ }
241
+ }, [fill, _whiteNoteWidth, whiteNoteCount])
215
242
 
216
- // --- hooks ---
217
- useEffect(() => {
218
- if (fill && pianoRef.current) {
219
- const parent = pianoRef.current.parentElement
220
- if (!parent) throw new Error("doesn't have a parent element.")
221
- const resizeObserver = new ResizeObserver(() => {
222
- const w = pianoRef.current!.clientWidth
223
- setWhiteNoteWidth(w / whiteNoteCount - padding)
243
+ const [touchMoveRefCallback, pointerDownHandler] =
244
+ useDragWithElement<HTMLDivElement>({
245
+ baseElementRef: pianoRef,
246
+ onDrag: onDrag,
247
+ onDragEnd: onDragEnd,
224
248
  })
225
- resizeObserver.observe(parent)
226
- return () => {
227
- resizeObserver.unobserve(parent)
228
- }
229
- } else {
230
- setWhiteNoteWidth(_whiteNoteWidth)
231
- }
232
- }, [fill, _whiteNoteWidth, whiteNoteCount])
233
249
 
234
- const [touchMoveRefCallback, pointerDownHandler] =
235
- useDragWithElement<HTMLDivElement>({
236
- baseElementRef: pianoRef,
237
- onDrag: onDrag,
238
- onDragEnd: onDragEnd,
250
+ useEventListener(globalThis.window, 'keydown', (e) => {
251
+ if (e.repeat) return
252
+ if (!keyboardShortcuts) return
253
+ const index = keyboardShortcuts.keys.indexOf(e.key)
254
+ if (index != -1) {
255
+ if (!keyRefs.current[index]?.current?.played()) {
256
+ keyRefs.current[index]?.current?.play()
257
+ }
258
+ }
239
259
  })
240
260
 
241
- useEventListener(globalThis.window, 'keydown', (e) => {
242
- if (e.repeat) return
243
- if (!keyboardShortcuts) return
244
- const index = keyboardShortcuts.keys.indexOf(e.key)
245
- if (index != -1) {
246
- if (!keyRefs.current[index]?.current?.played()) {
247
- keyRefs.current[index]?.current?.play()
261
+ useEventListener(globalThis.window, 'keyup', (e) => {
262
+ if (e.repeat) return
263
+ if (!keyboardShortcuts) return
264
+ const index = keyboardShortcuts.keys.indexOf(e.key)
265
+ if (index != -1) {
266
+ keyRefs.current[index]?.current?.stop()
248
267
  }
249
- }
250
- })
268
+ })
251
269
 
252
- useEventListener(globalThis.window, 'keyup', (e) => {
253
- if (e.repeat) return
254
- if (!keyboardShortcuts) return
255
- const index = keyboardShortcuts.keys.indexOf(e.key)
256
- if (index != -1) {
257
- keyRefs.current[index]?.current?.stop()
258
- }
259
- })
270
+ useImperativeHandle(forwardedRef, () => {
271
+ return {
272
+ playNote(note, velocity) {
273
+ const index = noteRangeArray.indexOf(note)
274
+ if (index != -1) {
275
+ if (!keyRefs.current[index]?.current?.played()) {
276
+ keyRefs.current[index]?.current?.play(velocity)
277
+ }
278
+ } else {
279
+ onPlayNote?.(note, velocity)
280
+ }
281
+ },
282
+ stopNote(note: number) {
283
+ const index = noteRangeArray.indexOf(note)
284
+ if (index != -1) {
285
+ keyRefs.current[index]?.current?.stop()
286
+ } else {
287
+ onStopNote?.(note)
288
+ }
289
+ },
290
+ }
291
+ }, [noteRangeArray, onPlayNote, onStopNote])
260
292
 
261
- return (
262
- <PianoProvider
263
- notePosition={notePosition}
264
- noteRange={noteRange}
265
- glissando={glissando}
266
- midiMax={midiMax}
267
- fill={fill}
268
- onPlayNote={onPlayNote}
269
- onStopNote={onStopNote}
270
- label={label}
271
- >
272
- <div
273
- ref={(div) => {
274
- pianoRef.current = div
275
- touchMoveRefCallback(div)
276
- }}
277
- className={clsx('tremolo-piano', className)}
278
- style={{
279
- width: fill ? '100%' : staticWidth,
280
- height: height,
281
- ...style,
282
- }}
283
- onPointerDown={(event) => {
284
- pointerDownHandler(event)
285
- onPointerDown?.(event)
286
- }}
287
- {...props}
293
+ return (
294
+ <PianoProvider
295
+ notePosition={notePosition}
296
+ noteRange={noteRange}
297
+ glissando={glissando}
298
+ midiMax={midiMax}
299
+ fill={fill}
300
+ onPlayNote={onPlayNote}
301
+ onStopNote={onStopNote}
302
+ label={label}
288
303
  >
289
- {childrenWithProps ||
290
- noteRangeArray.map((note, index) =>
291
- isWhiteKey(note) ? (
292
- <WhiteKey
293
- ref={keyRefs.current[index]}
294
- key={note}
295
- noteNumber={note}
296
- __width={whiteNoteWidth}
297
- />
298
- ) : (
299
- <BlackKey
300
- ref={keyRefs.current[index]}
301
- key={note}
302
- noteNumber={note}
303
- __width={whiteNoteWidth * blackPerWhiteWidth}
304
- />
305
- ),
306
- )}
307
- </div>
308
- </PianoProvider>
309
- )
310
- }
304
+ <div
305
+ ref={(div) => {
306
+ pianoRef.current = div
307
+ touchMoveRefCallback(div)
308
+ }}
309
+ className={clsx('tremolo-piano', className)}
310
+ style={{
311
+ width: fill ? '100%' : staticWidth,
312
+ height: height,
313
+ ...style,
314
+ }}
315
+ onPointerDown={(event) => {
316
+ pointerDownHandler(event)
317
+ onPointerDown?.(event)
318
+ }}
319
+ {...props}
320
+ >
321
+ {childrenWithProps ||
322
+ noteRangeArray.map((note, index) =>
323
+ isWhiteKey(note) ? (
324
+ <WhiteKey
325
+ ref={keyRefs.current[index]}
326
+ key={note}
327
+ noteNumber={note}
328
+ __width={whiteNoteWidth}
329
+ />
330
+ ) : (
331
+ <BlackKey
332
+ ref={keyRefs.current[index]}
333
+ key={note}
334
+ noteNumber={note}
335
+ __width={whiteNoteWidth * blackPerWhiteWidth}
336
+ />
337
+ ),
338
+ )}
339
+ </div>
340
+ </PianoProvider>
341
+ )
342
+ },
343
+ )
344
+
345
+ /**
346
+ * Customizable piano component.
347
+ * @category Piano
348
+ */
349
+ export const Piano = Object.assign(PianoImpl, { WhiteKey, BlackKey, KeyLabel })
311
350
 
312
351
  export { type KeyboardShortcuts, SHORTCUTS } from './keyboardShortcuts'
313
- export { WhiteKey, BlackKey, type KeyProps, type KeyMethods } from './key'
314
- export { KeyLabel, type KeyLabelProps } from './KeyLabel'
352
+ export { type KeyProps, type KeyMethods } from './key'
353
+ export { type KeyLabelProps } from './KeyLabel'
@@ -40,7 +40,7 @@ export interface KeyProps {
40
40
  * @category Piano
41
41
  */
42
42
  export interface KeyMethods {
43
- play: () => void
43
+ play: (velocity?: number) => void
44
44
  stop: () => void
45
45
  played: () => boolean
46
46
  }
@@ -92,10 +92,10 @@ const KeyImpl = forwardRef<KeyMethods, ImplProps>(
92
92
 
93
93
  useImperativeHandle(ref, () => {
94
94
  return {
95
- play() {
95
+ play(velocity) {
96
96
  if (disabled) return
97
97
  setPlayed(true)
98
- if (onPlayNote) onPlayNote(noteNumber)
98
+ if (onPlayNote) onPlayNote(noteNumber, velocity)
99
99
  },
100
100
  stop() {
101
101
  setPlayed(false)
@@ -35,7 +35,7 @@ export interface SliderThumbMethods {
35
35
  export const defaultThumbSize = 22
36
36
 
37
37
  /** @category Slider */
38
- export const SliderThumb = forwardRef<SliderThumbMethods, SliderThumbProps>(
38
+ export const Thumb = forwardRef<SliderThumbMethods, SliderThumbProps>(
39
39
  (
40
40
  {
41
41
  size,
@@ -29,7 +29,7 @@ export interface SliderTrackProps {
29
29
  }
30
30
 
31
31
  /** @category Slider */
32
- export function SliderTrack({
32
+ export function Track({
33
33
  length = defaultLength,
34
34
  thickness = defaultThickness,
35
35
  active,
@@ -64,8 +64,8 @@ export function SliderTrack({
64
64
  : {
65
65
  ...colors,
66
66
  background: xor(vertical, reverse)
67
- ? `linear-gradient(to ${direction}, var(--inactive, #eee) ${__percent}%, var(--active, #7998ec) ${__percent}%)`
68
- : `linear-gradient(to ${direction}, var(--active, #7998ec) ${__percent}%, var(--inactive, #eee) ${__percent}%)`,
67
+ ? `linear-gradient(to ${direction}, var(--inactive) ${__percent}%, var(--active) ${__percent}%)`
68
+ : `linear-gradient(to ${direction}, var(--active) ${__percent}%, var(--inactive) ${__percent}%)`,
69
69
  borderRadius: styleHelper(thickness!, '/', 2),
70
70
  width: !vertical ? length : thickness,
71
71
  height: vertical ? length : thickness,
@@ -16,14 +16,14 @@
16
16
  }
17
17
 
18
18
  .tremolo-slider-thumb {
19
- --color: var(--tremolo-theme-color);
19
+ --color: oklch(59.5% 0.17548 266.373);
20
20
 
21
21
  background: var(--color);
22
22
  border-radius: 50%;
23
23
  outline: none;
24
24
 
25
25
  &[aria-disabled='true'] {
26
- background: #5d6478;
26
+ background: oklch(50.462% 0.03307 270.021);
27
27
  }
28
28
 
29
29
  &[aria-readonly='false']:focus {
@@ -33,8 +33,8 @@
33
33
  }
34
34
 
35
35
  .tremolo-slider-track {
36
- --active: #7998ec;
37
- --inactive: #eee;
36
+ --active: oklch(69.212% 0.12903 267.633);
37
+ --inactive: oklch(95% 0 0);
38
38
 
39
39
  position: relative;
40
40
 
@@ -47,13 +47,13 @@
47
47
  }
48
48
 
49
49
  &:hover {
50
- --active: #6387e9;
50
+ --active: oklch(64.276% 0.15244 266.932);
51
51
  --inactive: #e0e0e0;
52
52
  }
53
53
 
54
54
  &[aria-disabled='true'] {
55
- --active: #858890;
56
- --inactive: #ddd;
55
+ --active: oklch(75.327% 0.01237 264.547);
56
+ --inactive: oklch(89.755% 0.0001 271.152);
57
57
  }
58
58
  }
59
59
 
@@ -64,7 +64,7 @@
64
64
 
65
65
  .tremolo-slider-scale-option {
66
66
  display: flex;
67
- color: #222;
67
+ color: oklch(25.197% 0.00003 271.152);
68
68
  flex-direction: column;
69
69
  justify-content: center;
70
70
  align-items: center;
@@ -85,3 +85,28 @@
85
85
  .tremolo-slider-scale-option-label {
86
86
  text-align: right;
87
87
  }
88
+
89
+ :where(.dark, [data-theme='dark']) {
90
+ .tremolo-slider-thumb {
91
+ --color: oklch(64.5% 0.17548 266.373);
92
+
93
+ &:hover {
94
+ --color: oklch(67.5% 0.17548 266.373);
95
+ }
96
+ }
97
+
98
+ .tremolo-slider-track {
99
+ --active: oklch(59.5% 0.17548 266.373);
100
+ --inactive: oklch(41.7% 0 0);
101
+
102
+ &:hover {
103
+ --active: oklch(62.5% 0.17548 266.373);
104
+ --inactive: oklch(44.7% 0 0);
105
+ }
106
+
107
+ &[aria-disabled='true'] {
108
+ --active: oklch(75.327% 0.01237 264.547);
109
+ --inactive: oklch(89.755% 0.0001 271.152);
110
+ }
111
+ }
112
+ }