@tremolo-ui/react 0.0.5 → 0.0.6

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 (72) hide show
  1. package/dist/cjs/index.js +196 -93
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/types/components/AnimationCanvas/index.d.ts +3 -4
  4. package/dist/cjs/types/components/AnimationCanvas/index.d.ts.map +1 -1
  5. package/dist/cjs/types/components/Knob/index.d.ts +6 -7
  6. package/dist/cjs/types/components/Knob/index.d.ts.map +1 -1
  7. package/dist/cjs/types/components/NumberInput/index.d.ts +10 -7
  8. package/dist/cjs/types/components/NumberInput/index.d.ts.map +1 -1
  9. package/dist/cjs/types/components/Piano/BlackKey.d.ts +4 -0
  10. package/dist/cjs/types/components/Piano/BlackKey.d.ts.map +1 -0
  11. package/dist/cjs/types/components/Piano/KeyLabel.d.ts +20 -0
  12. package/dist/cjs/types/components/Piano/KeyLabel.d.ts.map +1 -0
  13. package/dist/cjs/types/components/Piano/WhiteKey.d.ts +4 -0
  14. package/dist/cjs/types/components/Piano/WhiteKey.d.ts.map +1 -0
  15. package/dist/cjs/types/components/Piano/index.d.ts +35 -0
  16. package/dist/cjs/types/components/Piano/index.d.ts.map +1 -0
  17. package/dist/cjs/types/components/Piano/key.d.ts +39 -0
  18. package/dist/cjs/types/components/Piano/key.d.ts.map +1 -0
  19. package/dist/cjs/types/components/Piano/keyboardShortcuts.d.ts +12 -0
  20. package/dist/cjs/types/components/Piano/keyboardShortcuts.d.ts.map +1 -0
  21. package/dist/cjs/types/components/Slider/Thumb.d.ts +17 -2
  22. package/dist/cjs/types/components/Slider/Thumb.d.ts.map +1 -1
  23. package/dist/cjs/types/components/Slider/Track.d.ts +21 -2
  24. package/dist/cjs/types/components/Slider/Track.d.ts.map +1 -1
  25. package/dist/cjs/types/components/Slider/index.d.ts +18 -10
  26. package/dist/cjs/types/components/Slider/index.d.ts.map +1 -1
  27. package/dist/cjs/types/components/_util/index.d.ts +4 -0
  28. package/dist/cjs/types/components/_util/index.d.ts.map +1 -0
  29. package/dist/esm/index.js +197 -94
  30. package/dist/esm/index.js.map +1 -1
  31. package/dist/esm/types/components/AnimationCanvas/index.d.ts +3 -4
  32. package/dist/esm/types/components/AnimationCanvas/index.d.ts.map +1 -1
  33. package/dist/esm/types/components/Knob/index.d.ts +6 -7
  34. package/dist/esm/types/components/Knob/index.d.ts.map +1 -1
  35. package/dist/esm/types/components/NumberInput/index.d.ts +10 -7
  36. package/dist/esm/types/components/NumberInput/index.d.ts.map +1 -1
  37. package/dist/esm/types/components/Piano/BlackKey.d.ts +4 -0
  38. package/dist/esm/types/components/Piano/BlackKey.d.ts.map +1 -0
  39. package/dist/esm/types/components/Piano/KeyLabel.d.ts +20 -0
  40. package/dist/esm/types/components/Piano/KeyLabel.d.ts.map +1 -0
  41. package/dist/esm/types/components/Piano/WhiteKey.d.ts +4 -0
  42. package/dist/esm/types/components/Piano/WhiteKey.d.ts.map +1 -0
  43. package/dist/esm/types/components/Piano/index.d.ts +35 -0
  44. package/dist/esm/types/components/Piano/index.d.ts.map +1 -0
  45. package/dist/esm/types/components/Piano/key.d.ts +39 -0
  46. package/dist/esm/types/components/Piano/key.d.ts.map +1 -0
  47. package/dist/esm/types/components/Piano/keyboardShortcuts.d.ts +12 -0
  48. package/dist/esm/types/components/Piano/keyboardShortcuts.d.ts.map +1 -0
  49. package/dist/esm/types/components/Slider/Thumb.d.ts +17 -2
  50. package/dist/esm/types/components/Slider/Thumb.d.ts.map +1 -1
  51. package/dist/esm/types/components/Slider/Track.d.ts +21 -2
  52. package/dist/esm/types/components/Slider/Track.d.ts.map +1 -1
  53. package/dist/esm/types/components/Slider/index.d.ts +18 -10
  54. package/dist/esm/types/components/Slider/index.d.ts.map +1 -1
  55. package/dist/esm/types/components/_util/index.d.ts +4 -0
  56. package/dist/esm/types/components/_util/index.d.ts.map +1 -0
  57. package/dist/styles/{variables.css → index.css} +4 -0
  58. package/package.json +7 -7
  59. package/src/components/AnimationCanvas/index.tsx +3 -7
  60. package/src/components/Knob/index.tsx +15 -19
  61. package/src/components/NumberInput/index.tsx +18 -11
  62. package/src/components/Piano/BlackKey.tsx +108 -0
  63. package/src/components/Piano/KeyLabel.tsx +69 -0
  64. package/src/components/Piano/WhiteKey.tsx +109 -0
  65. package/src/components/Piano/index.tsx +222 -0
  66. package/src/components/Piano/key.ts +43 -0
  67. package/src/components/Piano/keyboardShortcuts.ts +12 -0
  68. package/src/components/Slider/Thumb.tsx +56 -15
  69. package/src/components/Slider/Track.tsx +62 -3
  70. package/src/components/Slider/index.tsx +125 -89
  71. package/src/components/_util/index.ts +11 -0
  72. package/src/styles/{variables.css → index.css} +4 -0
@@ -0,0 +1,109 @@
1
+ import { css } from "@emotion/react"
2
+ import React, { forwardRef, useImperativeHandle } from "react"
3
+ import { useState } from "react"
4
+ import { KeyLabel } from "./KeyLabel"
5
+ import { KeyMethods, KeyProps } from "./key"
6
+
7
+
8
+ export const WhiteKey = forwardRef<KeyMethods, KeyProps>(({
9
+ width = 40,
10
+ height = '100%',
11
+ bg = 'white',
12
+ activeBg = '#ccc',
13
+ style,
14
+ children,
15
+ __glissando,
16
+ __position,
17
+ __note,
18
+ __disabled,
19
+ __index,
20
+ __fill,
21
+ __width,
22
+ __playNote,
23
+ __stopNote,
24
+ __label,
25
+ }: KeyProps, ref) => {
26
+ const [played, setPlayed] = useState(false)
27
+
28
+ useImperativeHandle(ref, () => {
29
+ return {
30
+ play() {
31
+ if (__disabled) return
32
+ setPlayed(true)
33
+ if (__playNote) __playNote(__note!)
34
+ },
35
+ stop() {
36
+ setPlayed(false)
37
+ if (__stopNote) __stopNote(__note!)
38
+ },
39
+ played() {
40
+ return played
41
+ }
42
+ }
43
+ }, [])
44
+
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ let keyLabelProps: any
47
+ if (children != undefined) {
48
+ React.Children.forEach(children, (child) => {
49
+ if (React.isValidElement(child)) {
50
+ if (child.type == KeyLabel) {
51
+ keyLabelProps = child.props
52
+ } else {
53
+ throw new Error('only <KeyLabel>')
54
+ }
55
+ } else {
56
+ throw new Error('children is an invalid element.')
57
+ }
58
+ })
59
+ }
60
+
61
+ return (
62
+ <div
63
+ className={`tremolo-piano-white-key`}
64
+ aria-disabled={__disabled}
65
+ css={css({
66
+ position: 'absolute',
67
+ backgroundColor: played ? activeBg : bg,
68
+ color: 'black',
69
+ left: __position,
70
+ width: __fill ? __width : (width ?? __width),
71
+ height: height,
72
+ border: '1px solid #555',
73
+ borderRadius: '0 0 8px 8px',
74
+ cursor: __disabled ? 'not-allowed' : 'pointer',
75
+ zIndex: 1,
76
+ ...style,
77
+ })}
78
+ onPointerDown={() => {
79
+ if (__disabled) return
80
+ setPlayed(true)
81
+ if (__playNote) __playNote(__note!)
82
+ }}
83
+ onPointerEnter={() => {
84
+ if (__disabled) return
85
+ if (__glissando) {
86
+ setPlayed(true)
87
+ if (__playNote) __playNote(__note!)
88
+ }
89
+ }}
90
+ onPointerUp={() => {
91
+ if (__disabled) return
92
+ setPlayed(false)
93
+ if (__stopNote) __stopNote(__note!)
94
+ }}
95
+ onPointerLeave={() => {
96
+ if (__disabled) return
97
+ setPlayed(false)
98
+ if (__stopNote) __stopNote(__note!)
99
+ }}
100
+ >
101
+ <KeyLabel
102
+ __note={__note}
103
+ __label={__label}
104
+ __index={__index}
105
+ {...keyLabelProps}
106
+ />
107
+ </div>
108
+ )
109
+ })
@@ -0,0 +1,222 @@
1
+ import React, { createRef, ReactElement, ReactNode, RefObject, useEffect, useMemo, useRef, useState } from 'react'
2
+ import { css, CSSObject } from '@emotion/react'
3
+ import { isWhiteKey, NoteName, noteName, noteNames, parseNoteName } from '@tremolo-ui/functions'
4
+
5
+ import { useEventListener } from '../../hooks/useEventListener'
6
+
7
+ import { KeyMethods } from './key'
8
+ import { WhiteKey } from './WhiteKey'
9
+ import { BlackKey } from './BlackKey'
10
+ import { KeyBoardShortcuts } from './keyboardShortcuts'
11
+
12
+ /**
13
+ * Piano component
14
+ *
15
+ * TODO:
16
+ * - add scale highlight
17
+ */
18
+
19
+ export interface PianoProps {
20
+ // required
21
+ noteRange: { first: number, last: number }
22
+
23
+ // optional
24
+ height?: number | string
25
+
26
+ glissando?: boolean
27
+ midiMax?: number
28
+ keyboardShortcuts?: KeyBoardShortcuts
29
+ fill?: boolean
30
+
31
+ style?: CSSObject
32
+
33
+ playNote?: (noteNumber: number) => void
34
+ stopNote?: (noteNumber: number) => void
35
+
36
+ label?: (note: number, index: number) => ReactNode
37
+
38
+ /**
39
+ * \<WhiteKey /> | \<BlackKey />
40
+ */
41
+ children?: ReactElement | ReactElement[]
42
+ }
43
+
44
+ export function Piano({
45
+ noteRange,
46
+ glissando = true,
47
+ midiMax = 127,
48
+ keyboardShortcuts,
49
+ fill = false,
50
+ height = fill ? '100%' : 160,
51
+ style,
52
+ playNote,
53
+ stopNote,
54
+ label,
55
+ children,
56
+ }: PianoProps) {
57
+ // -- state and ref ---
58
+ const [pressed, setPressed] = useState(false)
59
+ const [whiteNoteWidth, setWhiteNoteWidth] = useState(-1)
60
+ const keyRefs = useRef<RefObject<KeyMethods>[]>([])
61
+ for (let i = 0; i < noteRange.last - noteRange.first + 1; i++) {
62
+ keyRefs.current[i] = createRef<KeyMethods>()
63
+ }
64
+ const pianoRef = useRef<HTMLDivElement>(null)
65
+
66
+ // --- interpret props ---
67
+ const noteRangeArray = Array.from(
68
+ { length: noteRange.last - noteRange.first + 1 },
69
+ (_, i) => i + noteRange.first
70
+ )
71
+ const whiteNoteCount = noteRangeArray.filter((v) => isWhiteKey(v)).length
72
+
73
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
+ let whiteKeyProps: any, blackKeyProps: any
75
+ if (children != undefined) {
76
+ React.Children.forEach(children, (child) => {
77
+ if (React.isValidElement(child)) {
78
+ if (child.type == WhiteKey) {
79
+ whiteKeyProps = child.props
80
+ } else if (child.type == BlackKey) {
81
+ blackKeyProps = child.props
82
+ } else {
83
+ throw new Error('only <WhiteKey> or <BlackKey>')
84
+ }
85
+ } else {
86
+ throw new Error('children is an invalid element.')
87
+ }
88
+ })
89
+ }
90
+
91
+ // --- internal functions ---
92
+ function notePosition(note: number) {
93
+ const pitchPositions: Record<NoteName, number> = {
94
+ C: 0,
95
+ 'C#': 0.55,
96
+ D: 1,
97
+ 'D#': 1.8,
98
+ E: 2,
99
+ F: 3,
100
+ 'F#': 3.5,
101
+ G: 4,
102
+ 'G#': 4.7,
103
+ A: 5,
104
+ 'A#': 5.85,
105
+ B: 6,
106
+ }
107
+
108
+ const toNoteName = (n: number) => {
109
+ const { letter, accidental } = parseNoteName(noteName(n))
110
+ return (letter + accidental) as NoteName
111
+ }
112
+ const _noteName = toNoteName(note)
113
+ const firstNoteName = toNoteName(noteRange.first)
114
+ const pos = pitchPositions[_noteName] - pitchPositions[firstNoteName]
115
+ const octave = Math.floor((note - noteRange.first) / 12)
116
+ const octaveOffset = noteNames.indexOf(firstNoteName) > noteNames.indexOf(_noteName) ? 1 : 0
117
+ const length = whiteNoteWidth + 3
118
+ return pos * length + (octave + octaveOffset) * 7 * length
119
+ }
120
+
121
+ // --- hooks ---
122
+ useEffect(() => {
123
+ if (fill && pianoRef.current) {
124
+ const parent = pianoRef.current.parentElement
125
+ if (!parent) throw new Error("doesn't have a parent element.")
126
+ const resizeObserver = new ResizeObserver(() => {
127
+ const w = pianoRef.current!.clientWidth
128
+ setWhiteNoteWidth(w / whiteNoteCount - 3)
129
+ })
130
+ resizeObserver.observe(parent)
131
+ } else {
132
+ setWhiteNoteWidth(whiteKeyProps?.width || 40)
133
+ }
134
+ }, [])
135
+
136
+ useEventListener(window, 'keydown', (e) => {
137
+ if (e.repeat) return
138
+ if (!keyboardShortcuts) return
139
+ const index = keyboardShortcuts.keys.indexOf(e.key)
140
+ if (index != -1) {
141
+ if (!keyRefs.current[index]?.current?.played()) {
142
+ keyRefs.current[index]?.current?.play()
143
+ }
144
+ }
145
+ })
146
+
147
+ useEventListener(window, 'keyup', (e) => {
148
+ if (e.repeat) return
149
+ if (!keyboardShortcuts) return
150
+ const index = keyboardShortcuts.keys.indexOf(e.key)
151
+ if (index != -1) {
152
+ keyRefs.current[index]?.current?.stop()
153
+ }
154
+ })
155
+
156
+ return (
157
+ <div
158
+ ref={pianoRef}
159
+ className="tremolo-piano"
160
+ css={css({
161
+ display: 'inline-block',
162
+ boxSizing: 'border-box',
163
+ userSelect: 'none',
164
+ width: fill ? '100%' : undefined,
165
+ height: height,
166
+ position: 'relative',
167
+ ...style
168
+ })}
169
+ onPointerDown={() => {
170
+ setPressed(true)
171
+ }}
172
+ onPointerUp={() => {
173
+ setPressed(false)
174
+ }}
175
+ >
176
+ {noteRangeArray.map((note, index) => {
177
+ return (
178
+ isWhiteKey(note) ? (
179
+ <WhiteKey
180
+ key={note}
181
+ ref={keyRefs.current[index]}
182
+ __glissando={glissando && pressed}
183
+ __position={notePosition(note)}
184
+ __note={note}
185
+ __disabled={note > midiMax}
186
+ __index={index}
187
+ __fill={fill}
188
+ __width={whiteNoteWidth}
189
+ __playNote={playNote}
190
+ __stopNote={stopNote}
191
+ __label={label}
192
+ {...whiteKeyProps}
193
+ />
194
+ ) : (
195
+ <BlackKey
196
+ key={note}
197
+ ref={keyRefs.current[index]}
198
+ __glissando={glissando && pressed}
199
+ __position={notePosition(note)}
200
+ __note={note}
201
+ __disabled={note > midiMax}
202
+ __index={index}
203
+ __fill={fill}
204
+ __width={whiteNoteWidth * 0.65}
205
+ __playNote={playNote}
206
+ __stopNote={stopNote}
207
+ __label={label}
208
+ {...blackKeyProps}
209
+ />
210
+ )
211
+ )
212
+ })}
213
+ </div>
214
+ )
215
+ }
216
+
217
+ export * from './key'
218
+ export { WhiteKey } from './WhiteKey'
219
+ export { BlackKey } from './BlackKey'
220
+ export { KeyLabel } from './KeyLabel'
221
+
222
+ export * from './keyboardShortcuts'
@@ -0,0 +1,43 @@
1
+ import { CSSObject } from "@emotion/react"
2
+ import { ReactElement, ReactNode } from "react"
3
+
4
+ export interface KeyProps {
5
+ width?: number
6
+ height?: number | string
7
+
8
+ bg?: string
9
+ activeBg?: string
10
+ style?: CSSObject
11
+
12
+ /**
13
+ * \<KeyLabel />
14
+ */
15
+ children?: ReactElement
16
+
17
+ /** @internal */
18
+ __glissando?: boolean
19
+ /** @internal */
20
+ __position?: number
21
+ /** @internal */
22
+ __note?: number
23
+ /** @internal */
24
+ __disabled?: boolean
25
+ /** @internal */
26
+ __index?: number
27
+ /** @internal */
28
+ __fill?: boolean
29
+ /** @internal */
30
+ __width?: number
31
+ /** @internal */
32
+ __playNote?: (noteNumber: number) => void
33
+ /** @internal */
34
+ __stopNote?: (noteNumber: number) => void
35
+ /** @internal */
36
+ __label?: (note: number) => ReactNode
37
+ }
38
+
39
+ export interface KeyMethods {
40
+ play: () => void
41
+ stop: () => void
42
+ played: () => boolean
43
+ }
@@ -0,0 +1,12 @@
1
+ export type KeyBoardShortcuts = {
2
+ keys: string[],
3
+ flags?: {
4
+ naturalOnly?: boolean
5
+ },
6
+ }
7
+
8
+ export const Shortcuts = {
9
+ HOME_ROW: {
10
+ keys: ['a', 'w', 's', 'e', 'd', 'f', 't', 'g', 'y', 'h', 'u', 'j', 'k', 'o', 'l', 'p', ';']
11
+ }
12
+ }
@@ -1,28 +1,67 @@
1
1
  import { CSSObject, css } from '@emotion/react'
2
- import { ReactNode } from 'react'
2
+ import { forwardRef, ReactNode, useImperativeHandle, useRef } from 'react'
3
+ import clsx from 'clsx'
3
4
 
4
5
  interface SliderThumbProps {
6
+ size?: number | string
7
+ width?: number | string
8
+ height?: number | string
5
9
  color?: string
10
+ hoverColor?: string
11
+ disabledColor?: string
12
+ disabledHoverColor?: string
13
+ zIndex?: number
14
+
15
+ className?: string
6
16
  style?: CSSObject
7
- __css?: CSSObject
8
17
  children?: ReactNode
18
+
19
+ /** @internal */
20
+ __disabled?: boolean
21
+ /** @internal */
22
+ __css?: CSSObject
9
23
  }
10
24
 
11
- export function SliderThumb({
12
- color,
25
+ export interface SliderThumbMethods {
26
+ focus: () => void
27
+ blur: () => void
28
+ }
29
+
30
+ export const SliderThumb = forwardRef<SliderThumbMethods, SliderThumbProps>(({
31
+ size,
32
+ width = 22,
33
+ height = 22,
34
+ color = '#4e76e6',
35
+ hoverColor = color,
36
+ disabledColor = '#5d6478',
37
+ disabledHoverColor = disabledColor,
38
+ zIndex = 100,
13
39
  children,
40
+ className,
14
41
  style,
42
+ __disabled,
15
43
  __css,
16
- }: SliderThumbProps) {
44
+ }: SliderThumbProps, ref) => {
45
+ const wrapperRef = useRef<HTMLDivElement>(null)
46
+
47
+ useImperativeHandle(ref, () => {
48
+ return {
49
+ focus() {
50
+ wrapperRef.current?.focus()
51
+ },
52
+ blur() {
53
+ wrapperRef.current?.blur()
54
+ },
55
+ }
56
+ }, [])
57
+
17
58
  return (
18
59
  <div
19
60
  className="tremolo-slider-thumb-wrapper"
20
61
  css={css({
21
- width: 'fit-content',
22
- height: 'fit-content',
23
62
  position: 'absolute',
24
63
  translate: '-50% -50%',
25
- zIndex: 100,
64
+ zIndex: zIndex,
26
65
  ...__css,
27
66
  })}
28
67
  >
@@ -31,18 +70,20 @@ export function SliderThumb({
31
70
  ) : (
32
71
  // default slider thumb
33
72
  <div
34
- className="tremolo-slider-thumb"
73
+ ref={wrapperRef}
74
+ className={clsx('tremolo-slider-thumb', className)}
35
75
  // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
36
76
  tabIndex={0}
37
77
  css={css({
38
- background: color,
39
- width: '1.4rem',
40
- height: '1.4rem',
78
+ background: __disabled ? disabledColor : color,
79
+ width: size ?? width,
80
+ height: size ?? height,
41
81
  borderRadius: '50%',
82
+ outline: 'none',
42
83
  '&:hover': {
43
- background: `color-mix(in srgb, ${color} 95%, black)`
84
+ background: __disabled ? disabledHoverColor : hoverColor
44
85
  },
45
- '&:active': {
86
+ '&:focus': !__disabled && {
46
87
  boxShadow: '0px 0px 0px 3px rgba(var(--tremolo-theme-color-rgb), 0.2)',
47
88
  },
48
89
  ...style,
@@ -51,4 +92,4 @@ export function SliderThumb({
51
92
  )}
52
93
  </div>
53
94
  )
54
- }
95
+ })
@@ -1,20 +1,79 @@
1
1
  import { css, CSSObject } from '@emotion/react'
2
2
  import { ReactElement } from 'react'
3
+ import clsx from 'clsx'
4
+ import { styleHelper } from '@tremolo-ui/functions'
5
+ import { isHorizontal } from '@tremolo-ui/functions/Slider'
6
+
7
+ import { Direction, gradientDirection } from './type'
3
8
 
4
9
  interface SliderTrackProps {
10
+ length?: number | string
11
+ thickness?: number | string
12
+
13
+ activeBg?: string
14
+ inactiveBg?: string
15
+ activeHoverBg?: string
16
+ inactiveHoverBg?: string
17
+
18
+ disabledActiveBg?: string
19
+ disabledInactiveBg?: string
20
+ disabledActiveHoverBg?: string
21
+ disabledInactiveHoverBg?: string
22
+
23
+ className?: string
5
24
  style?: CSSObject
6
25
  children?: ReactElement
7
- __css?: CSSObject
26
+
27
+ /** inherit */
28
+ __thumb?: ReactElement
29
+ /** inherit */
30
+ __direction?: Direction
31
+ /** inherit */
32
+ __disabled?: boolean
33
+ /** internal */
34
+ __percent?: number
8
35
  }
9
36
 
10
37
  export function SliderTrack({
38
+ length = 140,
39
+ thickness = 10,
40
+ activeBg = '#7998ec',
41
+ inactiveBg = '#eee',
42
+ activeHoverBg = '#6387e9',
43
+ inactiveHoverBg = '#e0e0e0',
44
+ disabledActiveBg = '#858890',
45
+ disabledInactiveBg = '#ddd',
46
+ disabledActiveHoverBg = disabledActiveBg,
47
+ disabledInactiveHoverBg = disabledInactiveBg,
11
48
  children,
49
+ className,
12
50
  style,
13
- __css,
51
+ __thumb,
52
+ __direction,
53
+ __disabled,
54
+ __percent,
14
55
  }: SliderTrackProps) {
56
+ const active = __disabled ? disabledActiveBg : activeBg
57
+ const inactive = __disabled ? disabledInactiveBg : inactiveBg
58
+ const activeHover = __disabled ? disabledActiveHoverBg : activeHoverBg
59
+ const inactiveHover = __disabled ? disabledInactiveHoverBg : inactiveHoverBg
15
60
  return (
16
- <div className="tremolo-slider-track" css={css({ ...__css, ...style })}>
61
+ <div
62
+ className={clsx('tremolo-slider-track', className)}
63
+ css={css({
64
+ position: 'relative',
65
+ background: `linear-gradient(to ${gradientDirection(__direction!)}, ${active} ${__percent}%, ${inactive} ${__percent}%)`,
66
+ borderRadius: styleHelper(thickness!, '/', 2),
67
+ width: isHorizontal(__direction!) ? length : thickness,
68
+ height: isHorizontal(__direction!) ? thickness : length,
69
+ ':hover': {
70
+ background: `linear-gradient(to ${gradientDirection(__direction!)}, ${activeHover} ${__percent}%, ${inactiveHover} ${__percent}%)`
71
+ },
72
+ ...style
73
+ })}
74
+ >
17
75
  {children}
76
+ {__thumb}
18
77
  </div>
19
78
  )
20
79
  }