@tremolo-ui/react 0.1.6 → 0.2.1

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 (68) hide show
  1. package/dist/index.cjs +1329 -1152
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +238 -183
  4. package/dist/index.d.cts +367 -366
  5. package/dist/index.d.cts.map +1 -1
  6. package/dist/index.d.ts +367 -366
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +1313 -1125
  9. package/dist/index.js.map +1 -1
  10. package/package.json +17 -19
  11. package/src/components/AnimationCanvas/index.tsx +0 -7
  12. package/src/components/DragObserver/index.tsx +9 -7
  13. package/src/components/Knob/ActiveLine.tsx +29 -0
  14. package/src/components/Knob/InactiveLine.tsx +53 -0
  15. package/src/components/Knob/SVGRoot.tsx +39 -0
  16. package/src/components/Knob/Thumb.tsx +64 -0
  17. package/src/components/Knob/context.tsx +120 -0
  18. package/src/components/Knob/index.css +25 -27
  19. package/src/components/Knob/index.tsx +110 -164
  20. package/src/components/NumberInput/DecrementStepper.tsx +0 -2
  21. package/src/components/NumberInput/IncrementStepper.tsx +0 -2
  22. package/src/components/NumberInput/InternalInput.tsx +3 -1
  23. package/src/components/NumberInput/Stepper.tsx +0 -2
  24. package/src/components/NumberInput/context.tsx +0 -1
  25. package/src/components/NumberInput/index.css +31 -15
  26. package/src/components/NumberInput/index.tsx +21 -14
  27. package/src/components/Piano/KeyLabel.tsx +0 -2
  28. package/src/components/Piano/context.tsx +0 -2
  29. package/src/components/Piano/index.css +7 -14
  30. package/src/components/Piano/index.tsx +14 -15
  31. package/src/components/Piano/key.tsx +0 -10
  32. package/src/components/Piano/keyboardShortcuts.ts +0 -2
  33. package/src/components/PointsEditor/Background.tsx +17 -0
  34. package/src/components/PointsEditor/Container.tsx +26 -0
  35. package/src/components/PointsEditor/Point.tsx +137 -0
  36. package/src/components/PointsEditor/context.tsx +91 -0
  37. package/src/components/PointsEditor/index.css +30 -0
  38. package/src/components/PointsEditor/index.tsx +129 -0
  39. package/src/components/Slider/Scale.tsx +0 -2
  40. package/src/components/Slider/ScaleOption.tsx +0 -2
  41. package/src/components/Slider/Thumb.tsx +1 -5
  42. package/src/components/Slider/Track.tsx +1 -3
  43. package/src/components/Slider/context.tsx +0 -1
  44. package/src/components/Slider/index.css +33 -8
  45. package/src/components/Slider/index.tsx +61 -33
  46. package/src/components/WheelObserver/index.tsx +17 -19
  47. package/src/components/XYPad/Area.tsx +4 -5
  48. package/src/components/XYPad/Thumb.tsx +8 -7
  49. package/src/components/XYPad/index.css +18 -4
  50. package/src/components/XYPad/index.tsx +71 -38
  51. package/src/components/_util/composeRefs.tsx +63 -0
  52. package/src/components/_util/index.ts +23 -6
  53. package/src/components/_util/type.ts +1 -0
  54. package/src/hooks/useAnimationFrame.ts +0 -3
  55. package/src/hooks/useCallbackRef.ts +2 -2
  56. package/src/hooks/useDrag.ts +12 -11
  57. package/src/hooks/useDragWithElement.ts +12 -17
  58. package/src/hooks/useEventListener.ts +6 -9
  59. package/src/hooks/useInterval.ts +0 -3
  60. package/src/hooks/useLongPress.ts +0 -3
  61. package/src/hooks/useMIDIAccess.ts +0 -1
  62. package/src/hooks/useMIDIInput.ts +0 -1
  63. package/src/hooks/useMIDIMessage.ts +0 -1
  64. package/src/hooks/usePianoDrag.ts +75 -0
  65. package/src/index.ts +21 -30
  66. package/src/styles/global.css +16 -4
  67. package/dist/index.css.map +0 -1
  68. package/src/components/AnimationKnob/index.tsx +0 -314
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tremolo-ui/react",
3
- "version": "0.1.6",
3
+ "version": "0.2.1",
4
4
  "description": "React component library for audio app",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -23,30 +23,26 @@
23
23
  "clean:sb": "rimraf ./storybook-static"
24
24
  },
25
25
  "devDependencies": {
26
- "@storybook/addon-a11y": "^8.6.7",
27
- "@storybook/addon-essentials": "^8.6.7",
28
- "@storybook/addon-interactions": "^8.6.7",
29
- "@storybook/addon-links": "^8.6.7",
30
- "@storybook/blocks": "^8.6.7",
31
- "@storybook/react": "^8.6.7",
32
- "@storybook/react-vite": "^8.6.7",
33
- "@storybook/test": "^8.6.7",
34
- "@testing-library/react": "^16.0.1",
35
- "@types/react": "^19.0.10",
36
- "@types/react-dom": "^19.0.4",
37
- "jest-environment-jsdom": "^29.7.0",
38
- "jotai": "^2.12.1",
39
- "react": "^19",
40
- "react-dom": "^19",
41
- "storybook": "^8.6.7",
42
- "tone": "^15"
26
+ "@storybook/addon-a11y": "10.5.10",
27
+ "@storybook/addon-links": "10.5.10",
28
+ "@storybook/react-vite": "10.5.10",
29
+ "@testing-library/react": "16.3.2",
30
+ "@types/react": "19.2.18",
31
+ "@types/react-dom": "19.2.4",
32
+ "jest-environment-jsdom": "29.7.0",
33
+ "jotai": "2.20.2",
34
+ "react": "19.2.8",
35
+ "react-dom": "19.2.8",
36
+ "storybook": "10.5.10",
37
+ "tone": "15.1.22",
38
+ "@storybook/addon-docs": "10.5.10"
43
39
  },
44
40
  "peerDependencies": {
45
41
  "react": "^18 ||^19",
46
42
  "react-dom": "^18 || ^19"
47
43
  },
48
44
  "dependencies": {
49
- "@tremolo-ui/functions": "^0.1.6",
45
+ "@tremolo-ui/functions": "^0.2.1",
50
46
  "clsx": "^2.1.1",
51
47
  "zustand": "^5.0.3"
52
48
  },
@@ -91,6 +87,8 @@
91
87
  "./styles/Knob.css": "./src/components/Knob/index.css",
92
88
  "./styles/NumberInput.css": "./src/components/NumberInput/index.css",
93
89
  "./styles/Piano.css": "./src/components/Piano/index.css",
90
+ "./styles/PointsEditor.css": "./src/components/PointsEditor/index.css",
91
+ "./styles/Slider.css": "./src/components/Slider/index.css",
94
92
  "./styles/XYPad.css": "./src/components/XYPad/index.css"
95
93
  }
96
94
  }
@@ -15,7 +15,6 @@ import {
15
15
  setDprConfig,
16
16
  } from './canvas'
17
17
 
18
- /** @category AnimationCanvas */
19
18
  export type InitFunction = (
20
19
  context: CanvasRenderingContext2D,
21
20
  option: {
@@ -26,7 +25,6 @@ export type InitFunction = (
26
25
  },
27
26
  ) => void
28
27
 
29
- /** @category AnimationCanvas */
30
28
  export type DrawFunction = (
31
29
  context: CanvasRenderingContext2D,
32
30
  option: {
@@ -45,7 +43,6 @@ export type DrawFunction = (
45
43
  },
46
44
  ) => void
47
45
 
48
- /** @category AnimationCanvas */
49
46
  export interface CommonProps {
50
47
  draw: DrawFunction
51
48
  init?: InitFunction
@@ -56,26 +53,22 @@ export interface CommonProps {
56
53
  options?: CanvasRenderingContext2DSettings
57
54
  }
58
55
 
59
- /** @category AnimationCanvas */
60
56
  export interface AbsoluteSizingProps {
61
57
  width?: number
62
58
  height?: number
63
59
  }
64
60
 
65
- /** @category AnimationCanvas */
66
61
  export interface RelativeSizingProps {
67
62
  relativeSize?: boolean
68
63
  reduceFlickering?: boolean
69
64
  }
70
65
 
71
- /** @category AnimationCanvas */
72
66
  export type AnimationCanvasProps = CommonProps &
73
67
  AbsoluteSizingProps &
74
68
  RelativeSizingProps
75
69
 
76
70
  /**
77
71
  * A simple animatable canvas with requestAnimationFrame()
78
- * @category AnimationCanvas
79
72
  */
80
73
  export function AnimationCanvas(
81
74
  props: CommonProps &
@@ -1,8 +1,8 @@
1
1
  import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react'
2
2
 
3
3
  import { useDrag } from '../../hooks/useDrag'
4
+ import { Override } from '../_util/type'
4
5
 
5
- /** @category DragObserver */
6
6
  export interface DragObserverProps<T extends ElementType> {
7
7
  /**
8
8
  * React.ElementType
@@ -17,23 +17,22 @@ export interface DragObserverProps<T extends ElementType> {
17
17
  threshold?: number
18
18
 
19
19
  children?: ReactNode
20
- onDrag: (x: number, y: number, deltaX: number, deltaY: number) => void
20
+ onDrag?: (x: number, y: number, deltaX: number, deltaY: number) => void
21
21
  onDragStart?: () => void
22
22
  onDragEnd?: () => void
23
23
  }
24
24
 
25
- /** @category DragObserver */
26
25
  export function DragObserver<T extends ElementType = 'div'>(
27
- props: DragObserverProps<T> &
28
- Omit<ComponentPropsWithoutRef<T>, keyof DragObserverProps<T>>,
26
+ props: Override<DragObserverProps<T>, ComponentPropsWithoutRef<T>>,
29
27
  ) {
30
28
  const {
31
29
  as: Component = 'div',
32
30
  threshold = 1,
33
- children,
34
31
  onDrag,
35
32
  onDragStart,
36
33
  onDragEnd,
34
+ children,
35
+ onPointerDown,
37
36
  ...attributes
38
37
  } = props
39
38
 
@@ -47,7 +46,10 @@ export function DragObserver<T extends ElementType = 'div'>(
47
46
  return (
48
47
  <Component
49
48
  ref={refCallback}
50
- onPointerDown={pointerDownHandler}
49
+ onPointerDown={(e) => {
50
+ pointerDownHandler(e)
51
+ onPointerDown?.(e)
52
+ }}
51
53
  {...attributes}
52
54
  >
53
55
  {children}
@@ -0,0 +1,29 @@
1
+ import clsx from 'clsx'
2
+ import { SVGProps } from 'react'
3
+
4
+ import { center, useKnobContext } from './context'
5
+
6
+ export function ActiveLine({
7
+ stroke = 'currentColor',
8
+ strokeWidth = 6,
9
+ className,
10
+ ...props
11
+ }: Omit<SVGProps<SVGPathElement>, 'd'>) {
12
+ const r2 = useKnobContext((s) => s.r2)
13
+ const r3 = useKnobContext((s) => s.r3)
14
+ const x2 = useKnobContext((s) => s.x2)
15
+ const y2 = useKnobContext((s) => s.y2)
16
+ const x3 = useKnobContext((s) => s.x3)
17
+ const y3 = useKnobContext((s) => s.y3)
18
+
19
+ return (
20
+ <path
21
+ className={clsx('tremolo-knob-active-line', className)}
22
+ d={`M ${x2} ${y2} A ${center} ${center} -135 ${r3 - r2 > 180 ? 1 : 0} 1 ${x3} ${y3}`}
23
+ fill="none"
24
+ stroke={stroke}
25
+ strokeWidth={strokeWidth}
26
+ {...props}
27
+ />
28
+ )
29
+ }
@@ -0,0 +1,53 @@
1
+ import clsx from 'clsx'
2
+ import { SVGProps } from 'react'
3
+
4
+ import { center, useKnobContext } from './context'
5
+
6
+ export function InactiveLine({
7
+ stroke = 'currentColor',
8
+ strokeWidth = 6,
9
+ className,
10
+ ...props
11
+ }: Omit<SVGProps<SVGPathElement>, 'd'>) {
12
+ const min = useKnobContext((s) => s.min)
13
+ const max = useKnobContext((s) => s.max)
14
+ const startValue = useKnobContext((s) => s.startValue)
15
+
16
+ const r1 = useKnobContext((s) => s.r1)
17
+ const r2 = useKnobContext((s) => s.r2)
18
+ const r3 = useKnobContext((s) => s.r3)
19
+ const r4 = useKnobContext((s) => s.r4)
20
+ const x1 = useKnobContext((s) => s.x1)
21
+ const y1 = useKnobContext((s) => s.y1)
22
+ const x2 = useKnobContext((s) => s.x2)
23
+ const y2 = useKnobContext((s) => s.y2)
24
+ const x3 = useKnobContext((s) => s.x3)
25
+ const y3 = useKnobContext((s) => s.y3)
26
+ const x4 = useKnobContext((s) => s.x4)
27
+ const y4 = useKnobContext((s) => s.y4)
28
+
29
+ return (
30
+ <>
31
+ {startValue > min && (
32
+ <path
33
+ className={clsx('tremolo-knob-inactive-line', className)}
34
+ d={`M ${x1} ${y1} A ${center} ${center} -135 ${r2 - r1 > 180 ? 1 : 0} 1 ${x2} ${y2}`}
35
+ fill="none"
36
+ stroke={stroke}
37
+ strokeWidth={strokeWidth}
38
+ {...props}
39
+ />
40
+ )}
41
+ {startValue < max && (
42
+ <path
43
+ className={clsx('tremolo-knob-inactive-line', className)}
44
+ d={`M ${x3} ${y3} A ${center} ${center} -135 ${r4 - r3 > 180 ? 1 : 0} 1 ${x4} ${y4}`}
45
+ fill="none"
46
+ stroke={stroke}
47
+ strokeWidth={strokeWidth}
48
+ {...props}
49
+ />
50
+ )}
51
+ </>
52
+ )
53
+ }
@@ -0,0 +1,39 @@
1
+ import { SVGProps } from 'react'
2
+
3
+ import { Override } from '../_util/type'
4
+
5
+ import { ActiveLine } from './ActiveLine'
6
+ import { viewBoxSize } from './context'
7
+ import { InactiveLine } from './InactiveLine'
8
+ import { Thumb } from './Thumb'
9
+
10
+ interface SVGRoot {
11
+ block?: boolean
12
+ overflowVisible?: boolean
13
+ }
14
+
15
+ export function SVGRoot({
16
+ children,
17
+ style,
18
+ ...props
19
+ }: Override<SVGRoot, SVGProps<SVGSVGElement>>) {
20
+ return (
21
+ <svg
22
+ viewBox={`0 0 ${viewBoxSize} ${viewBoxSize}`}
23
+ style={{
24
+ display: 'block',
25
+ overflow: 'visible',
26
+ ...style,
27
+ }}
28
+ {...props}
29
+ >
30
+ {children || (
31
+ <>
32
+ <InactiveLine />
33
+ <ActiveLine />
34
+ <Thumb />
35
+ </>
36
+ )}
37
+ </svg>
38
+ )
39
+ }
@@ -0,0 +1,64 @@
1
+ import clsx from 'clsx'
2
+ import { SVGProps } from 'react'
3
+
4
+ import { clamp } from '@tremolo-ui/functions'
5
+
6
+ import { useKnobContext, viewBoxSize } from './context'
7
+
8
+ interface Props {
9
+ /** color */
10
+ thumb?: string
11
+ /** color */
12
+ thumbLine?: string
13
+ /** percent (0-100) */
14
+ thumbSize?: number
15
+ /** percent (0-100) */
16
+ thumbLineWeight?: number
17
+ /** percent (0-100) */
18
+ thumbLineLength?: number
19
+
20
+ classes?: {
21
+ thumb?: string
22
+ thumbLine?: string
23
+ }
24
+ }
25
+
26
+ export function Thumb({
27
+ className,
28
+
29
+ thumb = 'currentColor',
30
+ thumbLine = 'currentColor',
31
+ thumbSize = 84,
32
+ thumbLineWeight = 6,
33
+ thumbLineLength = 35,
34
+ classes,
35
+
36
+ ...props
37
+ }: Props & Omit<SVGProps<SVGSVGElement>, 'd' | keyof Props>) {
38
+ const angleRange = useKnobContext((s) => s.angleRange)
39
+
40
+ const p = useKnobContext((s) => s.p)
41
+ const r1 = useKnobContext((s) => s.r1)
42
+
43
+ return (
44
+ <svg className={clsx('tremolo-knob-thumb', classes?.thumb)} {...props}>
45
+ <circle cx="50%" cy="50%" r={`${thumbSize / 2}%`} fill={thumb} />
46
+ <line
47
+ className={clsx('tremolo-knob-thumb-line', classes?.thumbLine)}
48
+ x1="50%"
49
+ y1={`${(viewBoxSize - clamp(thumbSize, 0, 100)) / 2}%`}
50
+ x2="50%"
51
+ y2={`${thumbLineLength}%`}
52
+ stroke={thumbLine}
53
+ strokeWidth={`${thumbLineWeight}%`}
54
+ // NOTE
55
+ // https://bugs.webkit.org/show_bug.cgi?id=201854
56
+ // https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/transform-origin#browser_compatibility
57
+ style={{
58
+ transform: `rotate(${r1 + p * angleRange}deg)`,
59
+ transformOrigin: '50% 50%',
60
+ }}
61
+ />
62
+ </svg>
63
+ )
64
+ }
@@ -0,0 +1,120 @@
1
+ import {
2
+ createContext,
3
+ PropsWithChildren,
4
+ useContext,
5
+ useEffect,
6
+ useRef,
7
+ } from 'react'
8
+ import { createStore, useStore } from 'zustand'
9
+
10
+ import { normalizeValue, radian } from '@tremolo-ui/functions'
11
+
12
+ export const viewBoxSize = 100
13
+ export const center = viewBoxSize / 2
14
+
15
+ type State = {
16
+ value: number
17
+ min: number
18
+ max: number
19
+ step: number
20
+ skew: number // | SkewFunction // TODO
21
+ startValue: number
22
+ angleRange: number
23
+ }
24
+
25
+ type DrawingState = {
26
+ p: number // normalized value
27
+ r1: number // ロータリー開始位置
28
+ r2: number // activeLineの開始位置
29
+ r3: number // activeLineの終了位置
30
+ r4: number // ロータリー終了位置
31
+ x1: number
32
+ y1: number
33
+ x2: number
34
+ y2: number
35
+ x3: number
36
+ y3: number
37
+ x4: number
38
+ y4: number
39
+ }
40
+
41
+ function calcDrawingState({
42
+ value,
43
+ min,
44
+ max,
45
+ skew,
46
+ startValue,
47
+ angleRange,
48
+ }: State) {
49
+ const p = normalizeValue(value, min, max, skew)
50
+ const s = normalizeValue(startValue, min, max, skew)
51
+
52
+ const r1 = -angleRange / 2
53
+ const r2 = r1 + Math.min(p, s) * angleRange
54
+ const r3 = r1 + Math.max(p, s) * angleRange
55
+ const r4 = angleRange / 2
56
+ const x1 = center + center * Math.cos(radian(r1 - 90))
57
+ const y1 = center + center * Math.sin(radian(r1 - 90))
58
+ const x2 = center + center * Math.cos(radian(r2 - 90))
59
+ const y2 = center + center * Math.sin(radian(r2 - 90))
60
+ const x3 = center + center * Math.cos(radian(r3 - 90))
61
+ const y3 = center + center * Math.sin(radian(r3 - 90))
62
+ const x4 = center + center * Math.cos(radian(r4 - 90))
63
+ const y4 = center + center * Math.sin(radian(r4 - 90))
64
+
65
+ return {
66
+ p,
67
+ r1,
68
+ r2,
69
+ r3,
70
+ r4,
71
+ x1,
72
+ y1,
73
+ x2,
74
+ y2,
75
+ x3,
76
+ y3,
77
+ x4,
78
+ y4,
79
+ }
80
+ }
81
+
82
+ type KnobStore = ReturnType<typeof createKnobStore>
83
+
84
+ const createKnobStore = (initProps: State) => {
85
+ return createStore<State & DrawingState>()(() => ({
86
+ ...initProps,
87
+ ...calcDrawingState(initProps),
88
+ }))
89
+ }
90
+
91
+ const KnobContext = createContext<KnobStore | null>(null)
92
+
93
+ export function KnobProvider({ children, ...props }: PropsWithChildren<State>) {
94
+ const storeRef = useRef<KnobStore>(null)
95
+ if (!storeRef.current) {
96
+ storeRef.current = createKnobStore(props)
97
+ }
98
+
99
+ useEffect(() => {
100
+ if (storeRef.current) {
101
+ storeRef.current.setState({ ...props, ...calcDrawingState(props) })
102
+ } else {
103
+ storeRef.current = createKnobStore(props)
104
+ }
105
+ }, [props])
106
+
107
+ return (
108
+ <KnobContext.Provider value={storeRef.current}>
109
+ {children}
110
+ </KnobContext.Provider>
111
+ )
112
+ }
113
+
114
+ export function useKnobContext<T>(
115
+ selector: (state: State & DrawingState) => T,
116
+ ): T {
117
+ const store = useContext(KnobContext)
118
+ if (!store) throw new Error('Missing KnobContext.Provider in the tree')
119
+ return useStore(store, selector)
120
+ }
@@ -1,12 +1,16 @@
1
1
  .tremolo-knob {
2
2
  display: inline-block;
3
- cursor: pointer;
3
+ cursor: grab;
4
4
  overflow: visible;
5
5
  outline: 0;
6
6
 
7
7
  &[aria-readonly='true'] {
8
8
  cursor: not-allowed;
9
9
  }
10
+
11
+ &[data-dragging='true'] {
12
+ cursor: inherit;
13
+ }
10
14
  }
11
15
 
12
16
  .tremolo-knob-active-line {
@@ -14,7 +18,7 @@
14
18
  color: oklch(69.2% 0.17548 266.373);
15
19
 
16
20
  :where(.tremolo-knob:focus, .tremolo-knob:hover) & {
17
- color: var(--tremolo-theme-color);
21
+ color: oklch(59.5% 0.17548 266.373);
18
22
  }
19
23
 
20
24
  :where(.tremolo-knob[aria-disabled='true']) & {
@@ -22,43 +26,43 @@
22
26
  }
23
27
  }
24
28
 
25
- :where(.dark, [data-theme='dark']) {
26
- .tremolo-knob-active-line {
27
- color: var(--tremolo-theme-color);
29
+ .tremolo-knob-inactive-line {
30
+ color: oklch(95% 0 0);
28
31
 
29
- :where(.tremolo-knob:focus, .tremolo-knob:hover) & {
30
- color: oklch(65.2% 0.17548 266.373);
31
- }
32
+ :where(.tremolo-knob:focus, .tremolo-knob:hover) & {
33
+ color: oklch(90% 0 0);
32
34
  }
33
35
  }
34
36
 
35
- .tremolo-knob-inactive-line {
36
- color: oklch(95% 0 0);
37
+ .tremolo-knob-thumb {
38
+ color: oklch(85.7% 0 0);
37
39
 
38
40
  :where(.tremolo-knob:focus, .tremolo-knob:hover) & {
39
- color: oklch(90% 0 0);
41
+ color: oklch(84.5% 0 0);
40
42
  }
41
43
  }
42
44
 
45
+ .tremolo-knob-thumb-line {
46
+ color: oklch(94.2% 0 0);
47
+ }
48
+
43
49
  :where(.dark, [data-theme='dark']) {
44
- .tremolo-knob-inactive-line {
45
- color: oklch(41.7% 0 0);
50
+ .tremolo-knob-active-line {
51
+ color: oklch(59.5% 0.17548 266.373);
46
52
 
47
53
  :where(.tremolo-knob:focus, .tremolo-knob:hover) & {
48
- color: oklch(44.59% 0 0);
54
+ color: oklch(65.2% 0.17548 266.373);
49
55
  }
50
56
  }
51
- }
52
57
 
53
- .tremolo-knob-thumb {
54
- color: oklch(85.7% 0 0);
58
+ .tremolo-knob-inactive-line {
59
+ color: oklch(41.7% 0 0);
55
60
 
56
- :where(.tremolo-knob:focus, .tremolo-knob:hover) & {
57
- color: oklch(84.5% 0 0);
61
+ :where(.tremolo-knob:focus, .tremolo-knob:hover) & {
62
+ color: oklch(44.59% 0 0);
63
+ }
58
64
  }
59
- }
60
65
 
61
- :where(.dark, [data-theme='dark']) {
62
66
  .tremolo-knob-thumb {
63
67
  color: oklch(48.6% 0 0);
64
68
 
@@ -66,13 +70,7 @@
66
70
  color: oklch(51.7% 0 0);
67
71
  }
68
72
  }
69
- }
70
73
 
71
- .tremolo-knob-thumb-line {
72
- color: oklch(94.2% 0 0);
73
- }
74
-
75
- :where(.dark, [data-theme='dark']) {
76
74
  .tremolo-knob-thumb-line {
77
75
  color: oklch(84.2% 0 0);
78
76
  }