@tremolo-ui/react 0.0.6 → 0.0.8

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 (133) hide show
  1. package/dist/cjs/index.js +954 -217
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/types/components/AnimationCanvas/index.d.ts +16 -9
  4. package/dist/cjs/types/components/AnimationCanvas/index.d.ts.map +1 -1
  5. package/dist/cjs/types/components/AnimationKnob/index.d.ts +53 -0
  6. package/dist/cjs/types/components/AnimationKnob/index.d.ts.map +1 -0
  7. package/dist/cjs/types/components/DragObserver/index.d.ts +19 -0
  8. package/dist/cjs/types/components/DragObserver/index.d.ts.map +1 -0
  9. package/dist/cjs/types/components/Knob/index.d.ts +26 -26
  10. package/dist/cjs/types/components/Knob/index.d.ts.map +1 -1
  11. package/dist/cjs/types/components/NumberInput/index.d.ts +2 -5
  12. package/dist/cjs/types/components/NumberInput/index.d.ts.map +1 -1
  13. package/dist/cjs/types/components/Piano/BlackKey.d.ts +3 -3
  14. package/dist/cjs/types/components/Piano/BlackKey.d.ts.map +1 -1
  15. package/dist/cjs/types/components/Piano/KeyLabel.d.ts +5 -8
  16. package/dist/cjs/types/components/Piano/KeyLabel.d.ts.map +1 -1
  17. package/dist/cjs/types/components/Piano/WhiteKey.d.ts +3 -3
  18. package/dist/cjs/types/components/Piano/WhiteKey.d.ts.map +1 -1
  19. package/dist/cjs/types/components/Piano/index.d.ts +4 -5
  20. package/dist/cjs/types/components/Piano/index.d.ts.map +1 -1
  21. package/dist/cjs/types/components/Piano/key.d.ts +4 -7
  22. package/dist/cjs/types/components/Piano/key.d.ts.map +1 -1
  23. package/dist/cjs/types/components/Piano/keyboardShortcuts.d.ts.map +1 -1
  24. package/dist/cjs/types/components/Slider/Scale.d.ts +11 -0
  25. package/dist/cjs/types/components/Slider/Scale.d.ts.map +1 -0
  26. package/dist/cjs/types/components/Slider/ScaleOption.d.ts +25 -0
  27. package/dist/cjs/types/components/Slider/ScaleOption.d.ts.map +1 -0
  28. package/dist/cjs/types/components/Slider/Thumb.d.ts +5 -13
  29. package/dist/cjs/types/components/Slider/Thumb.d.ts.map +1 -1
  30. package/dist/cjs/types/components/Slider/Track.d.ts +10 -21
  31. package/dist/cjs/types/components/Slider/Track.d.ts.map +1 -1
  32. package/dist/cjs/types/components/Slider/context.d.ts +21 -0
  33. package/dist/cjs/types/components/Slider/context.d.ts.map +1 -0
  34. package/dist/cjs/types/components/Slider/index.d.ts +18 -12
  35. package/dist/cjs/types/components/Slider/index.d.ts.map +1 -1
  36. package/dist/cjs/types/components/WheelObserver/index.d.ts +24 -0
  37. package/dist/cjs/types/components/WheelObserver/index.d.ts.map +1 -0
  38. package/dist/cjs/types/components/XYPad/Area.d.ts +13 -0
  39. package/dist/cjs/types/components/XYPad/Area.d.ts.map +1 -0
  40. package/dist/cjs/types/components/XYPad/Thumb.d.ts +19 -0
  41. package/dist/cjs/types/components/XYPad/Thumb.d.ts.map +1 -0
  42. package/dist/cjs/types/components/XYPad/index.d.ts +39 -0
  43. package/dist/cjs/types/components/XYPad/index.d.ts.map +1 -0
  44. package/dist/cjs/types/hooks/useCallbackRef.d.ts.map +1 -1
  45. package/dist/cjs/types/index.d.ts +11 -0
  46. package/dist/cjs/types/index.d.ts.map +1 -1
  47. package/dist/esm/index.js +932 -218
  48. package/dist/esm/index.js.map +1 -1
  49. package/dist/esm/types/components/AnimationCanvas/index.d.ts +16 -9
  50. package/dist/esm/types/components/AnimationCanvas/index.d.ts.map +1 -1
  51. package/dist/esm/types/components/AnimationKnob/index.d.ts +53 -0
  52. package/dist/esm/types/components/AnimationKnob/index.d.ts.map +1 -0
  53. package/dist/esm/types/components/DragObserver/index.d.ts +19 -0
  54. package/dist/esm/types/components/DragObserver/index.d.ts.map +1 -0
  55. package/dist/esm/types/components/Knob/index.d.ts +26 -26
  56. package/dist/esm/types/components/Knob/index.d.ts.map +1 -1
  57. package/dist/esm/types/components/NumberInput/index.d.ts +2 -5
  58. package/dist/esm/types/components/NumberInput/index.d.ts.map +1 -1
  59. package/dist/esm/types/components/Piano/BlackKey.d.ts +3 -3
  60. package/dist/esm/types/components/Piano/BlackKey.d.ts.map +1 -1
  61. package/dist/esm/types/components/Piano/KeyLabel.d.ts +5 -8
  62. package/dist/esm/types/components/Piano/KeyLabel.d.ts.map +1 -1
  63. package/dist/esm/types/components/Piano/WhiteKey.d.ts +3 -3
  64. package/dist/esm/types/components/Piano/WhiteKey.d.ts.map +1 -1
  65. package/dist/esm/types/components/Piano/index.d.ts +4 -5
  66. package/dist/esm/types/components/Piano/index.d.ts.map +1 -1
  67. package/dist/esm/types/components/Piano/key.d.ts +4 -7
  68. package/dist/esm/types/components/Piano/key.d.ts.map +1 -1
  69. package/dist/esm/types/components/Piano/keyboardShortcuts.d.ts.map +1 -1
  70. package/dist/esm/types/components/Slider/Scale.d.ts +11 -0
  71. package/dist/esm/types/components/Slider/Scale.d.ts.map +1 -0
  72. package/dist/esm/types/components/Slider/ScaleOption.d.ts +25 -0
  73. package/dist/esm/types/components/Slider/ScaleOption.d.ts.map +1 -0
  74. package/dist/esm/types/components/Slider/Thumb.d.ts +5 -13
  75. package/dist/esm/types/components/Slider/Thumb.d.ts.map +1 -1
  76. package/dist/esm/types/components/Slider/Track.d.ts +10 -21
  77. package/dist/esm/types/components/Slider/Track.d.ts.map +1 -1
  78. package/dist/esm/types/components/Slider/context.d.ts +21 -0
  79. package/dist/esm/types/components/Slider/context.d.ts.map +1 -0
  80. package/dist/esm/types/components/Slider/index.d.ts +18 -12
  81. package/dist/esm/types/components/Slider/index.d.ts.map +1 -1
  82. package/dist/esm/types/components/WheelObserver/index.d.ts +24 -0
  83. package/dist/esm/types/components/WheelObserver/index.d.ts.map +1 -0
  84. package/dist/esm/types/components/XYPad/Area.d.ts +13 -0
  85. package/dist/esm/types/components/XYPad/Area.d.ts.map +1 -0
  86. package/dist/esm/types/components/XYPad/Thumb.d.ts +19 -0
  87. package/dist/esm/types/components/XYPad/Thumb.d.ts.map +1 -0
  88. package/dist/esm/types/components/XYPad/index.d.ts +39 -0
  89. package/dist/esm/types/components/XYPad/index.d.ts.map +1 -0
  90. package/dist/esm/types/hooks/useCallbackRef.d.ts.map +1 -1
  91. package/dist/esm/types/index.d.ts +11 -0
  92. package/dist/esm/types/index.d.ts.map +1 -1
  93. package/dist/styles/index.css +241 -0
  94. package/package.json +2 -5
  95. package/src/components/AnimationCanvas/index.tsx +87 -57
  96. package/src/components/AnimationKnob/index.tsx +305 -0
  97. package/src/components/DragObserver/index.tsx +94 -0
  98. package/src/components/Knob/index.css +48 -0
  99. package/src/components/Knob/index.tsx +152 -165
  100. package/src/components/NumberInput/index.css +25 -0
  101. package/src/components/NumberInput/index.tsx +8 -41
  102. package/src/components/Piano/BlackKey.tsx +104 -98
  103. package/src/components/Piano/KeyLabel.tsx +18 -40
  104. package/src/components/Piano/WhiteKey.tsx +92 -87
  105. package/src/components/Piano/index.css +63 -0
  106. package/src/components/Piano/index.tsx +78 -61
  107. package/src/components/Piano/key.ts +4 -7
  108. package/src/components/Piano/keyboardShortcuts.ts +23 -4
  109. package/src/components/Slider/Scale.tsx +55 -0
  110. package/src/components/Slider/ScaleOption.tsx +103 -0
  111. package/src/components/Slider/Thumb.tsx +69 -76
  112. package/src/components/Slider/Track.tsx +37 -48
  113. package/src/components/Slider/context.tsx +66 -0
  114. package/src/components/Slider/index.css +76 -0
  115. package/src/components/Slider/index.tsx +256 -298
  116. package/src/components/WheelObserver/index.tsx +47 -0
  117. package/src/components/XYPad/Area.tsx +40 -0
  118. package/src/components/XYPad/Thumb.tsx +92 -0
  119. package/src/components/XYPad/index.css +24 -0
  120. package/src/components/XYPad/index.tsx +317 -0
  121. package/src/hooks/useCallbackRef.ts +1 -0
  122. package/src/hooks/useRefCallbackEvent.ts +1 -0
  123. package/src/index.ts +12 -0
  124. package/dist/cjs/types/components/Slider/type.d.ts +0 -7
  125. package/dist/cjs/types/components/Slider/type.d.ts.map +0 -1
  126. package/dist/cjs/types/system/pseudo.d.ts +0 -14
  127. package/dist/cjs/types/system/pseudo.d.ts.map +0 -1
  128. package/dist/esm/types/components/Slider/type.d.ts +0 -7
  129. package/dist/esm/types/components/Slider/type.d.ts.map +0 -1
  130. package/dist/esm/types/system/pseudo.d.ts +0 -14
  131. package/dist/esm/types/system/pseudo.d.ts.map +0 -1
  132. package/src/components/Slider/type.ts +0 -16
  133. package/src/system/pseudo.ts +0 -55
@@ -0,0 +1,40 @@
1
+ import clsx from 'clsx'
2
+ import { CSSProperties, ReactElement } from 'react'
3
+
4
+ export interface AreaProps {
5
+ width?: number | string
6
+ height?: number | string
7
+ bg?: string
8
+ className?: string
9
+ style?: CSSProperties
10
+ children?: ReactElement
11
+
12
+ /** inherit */
13
+ __thumb?: ReactElement
14
+ }
15
+
16
+ export function XYPadArea({
17
+ width = 120,
18
+ height = 120,
19
+ bg = '#eee',
20
+ children,
21
+ className,
22
+ style,
23
+ __thumb,
24
+ }: AreaProps) {
25
+ return (
26
+ <div
27
+ className={clsx('tremolo-xy-pad-area', className)}
28
+ style={{
29
+ position: 'relative',
30
+ width: width,
31
+ height: height,
32
+ background: bg,
33
+ ...style,
34
+ }}
35
+ >
36
+ {children}
37
+ {__thumb}
38
+ </div>
39
+ )
40
+ }
@@ -0,0 +1,92 @@
1
+ import clsx from 'clsx'
2
+ import {
3
+ ComponentPropsWithoutRef,
4
+ CSSProperties,
5
+ forwardRef,
6
+ ReactNode,
7
+ useImperativeHandle,
8
+ useRef,
9
+ } from 'react'
10
+
11
+ export interface ThumbProps {
12
+ size?: number | string
13
+ width?: number | string
14
+ height?: number | string
15
+
16
+ wrapperClassName?: string
17
+ wrapperStyle?: CSSProperties
18
+
19
+ children?: ReactNode
20
+
21
+ /** @internal */
22
+ __disabled?: boolean
23
+ /** @internal */
24
+ __css?: CSSProperties
25
+ }
26
+
27
+ export interface XYPadThumbMethods {
28
+ focus: () => void
29
+ blur: () => void
30
+ }
31
+
32
+ type Props = ThumbProps &
33
+ Omit<ComponentPropsWithoutRef<'div'>, keyof ThumbProps>
34
+
35
+ export const XYPadThumb = forwardRef<XYPadThumbMethods, Props>(
36
+ (
37
+ {
38
+ size,
39
+ width = 22,
40
+ height = 22,
41
+ children,
42
+ wrapperClassName,
43
+ wrapperStyle,
44
+ className,
45
+ style,
46
+ __disabled,
47
+ __css,
48
+ }: Props,
49
+ ref,
50
+ ) => {
51
+ const wrapperRef = useRef<HTMLDivElement>(null)
52
+
53
+ useImperativeHandle(ref, () => {
54
+ return {
55
+ focus() {
56
+ wrapperRef.current?.focus()
57
+ },
58
+ blur() {
59
+ wrapperRef.current?.blur()
60
+ },
61
+ }
62
+ }, [])
63
+
64
+ return (
65
+ <div
66
+ className={clsx('tremolo-xy-pad-thumb-wrapper', wrapperClassName)}
67
+ style={{
68
+ ...__css,
69
+ ...wrapperStyle,
70
+ }}
71
+ >
72
+ {children ? (
73
+ children
74
+ ) : (
75
+ // default thumb
76
+ <div
77
+ ref={wrapperRef}
78
+ className={clsx('tremolo-xy-pad-thumb', className)}
79
+ // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
80
+ tabIndex={0}
81
+ aria-disabled={__disabled}
82
+ style={{
83
+ width: size ?? width,
84
+ height: size ?? height,
85
+ ...style,
86
+ }}
87
+ ></div>
88
+ )}
89
+ </div>
90
+ )
91
+ },
92
+ )
@@ -0,0 +1,24 @@
1
+ .tremolo-xy-pad {
2
+ display: inline-block;
3
+ cursor: pointer;
4
+ }
5
+
6
+ .tremolo-xy-pad-thumb-wrapper {
7
+ position: absolute;
8
+ translate: -50% -50%;
9
+ z-index: 100;
10
+ }
11
+
12
+ .tremolo-xy-pad-thumb {
13
+ border-radius: 50%;
14
+ outline: none;
15
+ background-color: #4e76e6;
16
+
17
+ &[aria-disabled='true'] {
18
+ background-color: #5d6478;
19
+ }
20
+
21
+ &:focus {
22
+ box-shadow: 0px 0px 0px 3px rgba(var(--tremolo-theme-color-rgb), 0.2);
23
+ }
24
+ }
@@ -0,0 +1,317 @@
1
+ import clsx from 'clsx'
2
+ import React, {
3
+ ComponentPropsWithoutRef,
4
+ forwardRef,
5
+ ReactElement,
6
+ useCallback,
7
+ useImperativeHandle,
8
+ useMemo,
9
+ useRef,
10
+ } from 'react'
11
+
12
+ import {
13
+ clamp,
14
+ normalizeValue,
15
+ rawValue,
16
+ stepValue,
17
+ toFixed,
18
+ InputEventOption,
19
+ styleHelper,
20
+ } from '@tremolo-ui/functions'
21
+
22
+ import { useEventListener } from '../../hooks/useEventListener'
23
+ import { useRefCallbackEvent } from '../../hooks/useRefCallbackEvent'
24
+ import { addNoSelect, removeNoSelect } from '../_util'
25
+
26
+ import { XYPadArea, AreaProps } from './Area'
27
+ import { XYPadThumb, XYPadThumbMethods, ThumbProps } from './Thumb'
28
+
29
+ export interface ValueOptions {
30
+ // required
31
+ value: number
32
+ min: number
33
+ max: number
34
+
35
+ // optional
36
+ step?: number
37
+ skew?: number
38
+ reverse?: boolean
39
+ /**
40
+ * wheel control option
41
+ */
42
+ wheel?: InputEventOption | null
43
+ /**
44
+ * keyboard control option
45
+ */
46
+ keyboard?: InputEventOption | null
47
+ }
48
+
49
+ export interface XYPadProps {
50
+ x: ValueOptions
51
+ y: ValueOptions
52
+
53
+ bodyNoSelect?: boolean
54
+ disabled?: boolean
55
+ readonly?: boolean
56
+ onChange?: (valueX: number, valueY: number) => void
57
+ /** \<XYPadThumb /> | \<XYPadArea /> */
58
+ children?: ReactElement | ReactElement[]
59
+ }
60
+
61
+ export interface XYPadMethods {
62
+ focus: () => void
63
+ blur: () => void
64
+ }
65
+
66
+ const defaultValueOptions = {
67
+ skew: 1,
68
+ step: 1,
69
+ reverse: false,
70
+ wheel: ['raw', 1] as InputEventOption,
71
+ keyboard: ['raw', 1] as InputEventOption,
72
+ }
73
+
74
+ type Props = XYPadProps &
75
+ Omit<ComponentPropsWithoutRef<'div'>, keyof XYPadProps>
76
+
77
+ /**
78
+ * Simple XYPad
79
+ */
80
+ export const XYPad = forwardRef<XYPadMethods, Props>(
81
+ (
82
+ {
83
+ x: _x,
84
+ y: _y,
85
+ className,
86
+ style,
87
+ bodyNoSelect = true,
88
+ disabled = false,
89
+ readonly = false,
90
+ onChange,
91
+ children,
92
+ ...props
93
+ }: Props,
94
+ ref,
95
+ ) => {
96
+ const x = useMemo(() => {
97
+ return { ...defaultValueOptions, ..._x }
98
+ }, [_x])
99
+ const y = useMemo(() => {
100
+ return { ...defaultValueOptions, ..._y }
101
+ }, [_y])
102
+
103
+ // -- state and ref ---
104
+ const areaElementRef = useRef<HTMLDivElement>(null)
105
+ const thumbRef = useRef<XYPadThumbMethods>(null)
106
+ const thumbDragged = useRef(false)
107
+
108
+ // --- interpret props ---
109
+ const nx = normalizeValue(x.value, x.min, x.max, x.skew)
110
+ const ny = normalizeValue(y.value, y.min, y.max, y.skew)
111
+ const percentX = toFixed((x.reverse ? 1 - nx : nx) * 100)
112
+ const percentY = toFixed((y.reverse ? 1 - ny : ny) * 100)
113
+
114
+ let areaProps: AreaProps = {},
115
+ thumbProps: ThumbProps = {}
116
+ if (children != undefined) {
117
+ React.Children.forEach(children, (child) => {
118
+ if (React.isValidElement(child)) {
119
+ if (child.type == XYPadThumb) {
120
+ thumbProps = child.props as ThumbProps
121
+ } else if (child.type == XYPadArea) {
122
+ areaProps = child.props as AreaProps
123
+ } else {
124
+ throw new Error('only <XYPadThumb> or <XYPadArea>')
125
+ }
126
+ } else {
127
+ throw new Error('children is an invalid element.')
128
+ }
129
+ })
130
+ }
131
+
132
+ // --- internal functions ---
133
+ const handleValue = (
134
+ event: MouseEvent | React.PointerEvent<HTMLDivElement> | TouchEvent,
135
+ ) => {
136
+ if (
137
+ !areaElementRef.current ||
138
+ !thumbDragged.current ||
139
+ !onChange ||
140
+ readonly
141
+ )
142
+ return
143
+ const isTouch = event instanceof TouchEvent
144
+ if (isTouch && event.cancelable) event.preventDefault()
145
+ if (bodyNoSelect) addNoSelect()
146
+ const {
147
+ left: x1,
148
+ top: y1,
149
+ right: x2,
150
+ bottom: y2,
151
+ } = areaElementRef.current.getBoundingClientRect()
152
+ const mouseX = isTouch ? event.touches[0].clientX : event.clientX
153
+ const mouseY = isTouch ? event.touches[0].clientY : event.clientY
154
+ const nx = normalizeValue(mouseX, x1, x2)
155
+ const ny = normalizeValue(mouseY, y1, y2)
156
+ const vx = rawValue(x.reverse ? 1 - nx : nx, x.min, x.max, x.skew)
157
+ const vy = rawValue(y.reverse ? 1 - ny : ny, y.min, y.max, y.skew)
158
+ const newX = clamp(stepValue(vx, x.step), x.min, x.max)
159
+ const newY = clamp(stepValue(vy, y.step), y.min, y.max)
160
+ onChange(newX, newY)
161
+ }
162
+
163
+ const handleKeyDown = useCallback(
164
+ (event: React.KeyboardEvent<HTMLDivElement>) => {
165
+ if (!onChange || readonly) return
166
+ const key = event.key
167
+ if (['ArrowRight', 'ArrowLeft', 'ArrowUp', 'ArrowDown'].includes(key)) {
168
+ const isHorizontal = key == 'ArrowRight' || key == 'ArrowLeft'
169
+ const target = isHorizontal ? x : y
170
+ if (!target.keyboard) return
171
+ event.preventDefault()
172
+ let delta = target.keyboard[1]
173
+ if (key == 'ArrowLeft' || key == 'ArrowUp') delta *= -1
174
+ if (target.reverse) delta *= -1
175
+ let v
176
+ if (target.keyboard[0] == 'normalized') {
177
+ const n = normalizeValue(
178
+ target.value,
179
+ target.min,
180
+ target.max,
181
+ target.skew,
182
+ )
183
+ v = rawValue(n + delta, target.min, target.max, target.skew)
184
+ } else {
185
+ v = target.value + delta
186
+ }
187
+ const newValue = clamp(
188
+ stepValue(v, target.step),
189
+ target.min,
190
+ target.max,
191
+ )
192
+ if (isHorizontal) {
193
+ onChange(newValue, y.value)
194
+ } else {
195
+ onChange(x.value, newValue)
196
+ }
197
+ }
198
+ },
199
+ [x, y, onChange, readonly],
200
+ )
201
+
202
+ // --- hooks ---
203
+ const touchMoveRefCallback = useRefCallbackEvent(
204
+ 'touchmove',
205
+ handleValue,
206
+ { passive: false },
207
+ [x, onChange, readonly],
208
+ )
209
+
210
+ const wheelRefCallback = useRefCallbackEvent(
211
+ 'wheel',
212
+ (event) => {
213
+ if (!onChange || readonly) return
214
+ const target = event.shiftKey ? x : y
215
+ if (!target.wheel) return
216
+ event.preventDefault()
217
+ let delta = target.wheel[1]
218
+ if (event.deltaY < 0) delta *= -1
219
+ if (target.reverse) delta *= -1
220
+ let v
221
+ if (target.wheel[0] == 'normalized') {
222
+ const n = normalizeValue(
223
+ target.value,
224
+ target.min,
225
+ target.max,
226
+ target.skew,
227
+ )
228
+ v = rawValue(n + delta, target.min, target.max, target.skew)
229
+ } else {
230
+ v = target.value + delta
231
+ }
232
+ const newValue = clamp(
233
+ stepValue(v, target.step),
234
+ target.min,
235
+ target.max,
236
+ )
237
+ if (event.shiftKey) {
238
+ onChange(newValue, y.value)
239
+ } else {
240
+ onChange(x.value, newValue)
241
+ }
242
+ },
243
+ {
244
+ passive: false,
245
+ },
246
+ [x, y],
247
+ )
248
+
249
+ useEventListener(window, 'mousemove', (event) => {
250
+ handleValue(event)
251
+ })
252
+
253
+ useEventListener(window, 'mouseup', () => {
254
+ thumbDragged.current = false
255
+ if (bodyNoSelect) removeNoSelect()
256
+ })
257
+
258
+ useImperativeHandle(ref, () => {
259
+ return {
260
+ focus() {
261
+ thumbRef.current?.focus()
262
+ },
263
+ blur() {
264
+ thumbRef.current?.blur()
265
+ },
266
+ }
267
+ }, [])
268
+
269
+ return (
270
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions
271
+ <div
272
+ className={clsx('tremolo-xy-pad', className)}
273
+ ref={(div) => {
274
+ wheelRefCallback(div)
275
+ touchMoveRefCallback(div)
276
+ }}
277
+ tabIndex={-1}
278
+ aria-disabled={disabled}
279
+ aria-readonly={readonly}
280
+ style={{
281
+ margin: `calc(${styleHelper(thumbProps?.size ?? 22)} / 2)`, // half thumb size
282
+ cursor: readonly ? 'not-allowed' : 'pointer',
283
+ WebkitTapHighlightColor: 'transparent',
284
+ ...style,
285
+ }}
286
+ onPointerDown={(event) => {
287
+ thumbDragged.current = true
288
+ handleValue(event)
289
+ }}
290
+ onKeyDown={handleKeyDown}
291
+ onFocus={thumbRef.current?.focus}
292
+ onBlur={thumbRef.current?.blur}
293
+ {...props}
294
+ >
295
+ <div className="tremolo-xy-pad-area-wrapper" ref={areaElementRef}>
296
+ <XYPadArea
297
+ __thumb={
298
+ <XYPadThumb
299
+ ref={thumbRef}
300
+ __disabled={disabled}
301
+ __css={{
302
+ top: `${percentY}%`,
303
+ left: `${percentX}%`,
304
+ }}
305
+ {...thumbProps}
306
+ />
307
+ }
308
+ {...areaProps}
309
+ />
310
+ </div>
311
+ </div>
312
+ )
313
+ },
314
+ )
315
+
316
+ export * from './Thumb'
317
+ export * from './Area'
@@ -16,5 +16,6 @@ export function useCallbackRef<Args extends unknown[], Return>(
16
16
  callbackRef.current = callback
17
17
  })
18
18
 
19
+ // eslint-disable-next-line react-hooks/exhaustive-deps
19
20
  return useCallback((...args: Args) => callbackRef.current?.(...args), deps)
20
21
  }
@@ -28,5 +28,6 @@ export function useRefCallbackEvent(
28
28
  node.removeEventListener(event, handler, options)
29
29
  }
30
30
  }
31
+ // eslint-disable-next-line react-hooks/exhaustive-deps
31
32
  }, deps)
32
33
  }
package/src/index.ts CHANGED
@@ -1,4 +1,16 @@
1
+ import './styles/index.css'
2
+ import './components/Knob/index.css'
3
+ import './components/NumberInput/index.css'
4
+ import './components/Piano/index.css'
5
+ import './components/Slider/index.css'
6
+ import './components/XYPad/index.css'
7
+
1
8
  export * from './components/AnimationCanvas'
9
+ export * from './components/AnimationKnob'
10
+ export * from './components/DragObserver'
2
11
  export * from './components/Knob'
3
12
  export * from './components/NumberInput'
13
+ export * from './components/Piano'
4
14
  export * from './components/Slider'
15
+ export * from './components/WheelObserver'
16
+ export * from './components/XYPad'
@@ -1,7 +0,0 @@
1
- import { CSSObject } from '@emotion/react';
2
- import type { ScaleOption as Opt } from '@tremolo-ui/functions/Slider';
3
- export type ScaleOption = Opt & {
4
- style?: CSSObject;
5
- };
6
- export { type Direction, type Horizontal, type ScaleOrderList, type ScaleType, type Vertical, gradientDirection } from '@tremolo-ui/functions/Slider';
7
- //# sourceMappingURL=type.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../../../src/components/Slider/type.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,OAAO,KAAK,EAAE,WAAW,IAAI,GAAG,EAAE,MAAM,8BAA8B,CAAA;AAEtE,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,CAAA;AAED,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,iBAAiB,EAClB,MAAM,8BAA8B,CAAA"}
@@ -1,14 +0,0 @@
1
- import { CSSObject } from '@emotion/react';
2
- export declare const inputPseudoSelectors: readonly ["&:enabled", "&:disabled", "&:read-only", "&:read-write", "&:placeholder-shown", "&:blank", "&:valid", "&:invalid", "&:in-range", "&:out-of-range"];
3
- export declare const inputPseudoPropNames: readonly ["_enabled", "_disabled", "_readOnly", "_readWrite", "_placeholderShown", "_blank", "_valid", "_invalid", "_inRange", "_outOfRange"];
4
- export type InputPseudos = (typeof inputPseudoPropNames)[number];
5
- export type InputPseudoProps = Partial<{
6
- [key in InputPseudos]: CSSObject;
7
- }>;
8
- export declare const userActionPseudoSelectors: readonly ["&:hover", "&:active", "&:focus"];
9
- export declare const userActionPseudoPropNames: readonly ["_hover", "_active", "_focus"];
10
- export type UserActionPseudos = (typeof userActionPseudoPropNames)[number];
11
- export type UserActionPseudoProps = Partial<{
12
- [key in UserActionPseudos]: CSSObject;
13
- }>;
14
- //# sourceMappingURL=pseudo.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pseudo.d.ts","sourceRoot":"","sources":["../../../../src/system/pseudo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAQ1C,eAAO,MAAM,oBAAoB,+JAWvB,CAAA;AAEV,eAAO,MAAM,oBAAoB,+IAWvB,CAAA;AAEV,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA;AAChE,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC;KACpC,GAAG,IAAI,YAAY,GAAG,SAAS;CACjC,CAAC,CAAA;AAEF,eAAO,MAAM,yBAAyB,6CAI5B,CAAA;AAEV,eAAO,MAAM,yBAAyB,0CAI5B,CAAA;AAEV,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAA;AAC1E,MAAM,MAAM,qBAAqB,GAAG,OAAO,CAAC;KACzC,GAAG,IAAI,iBAAiB,GAAG,SAAS;CACtC,CAAC,CAAA"}
@@ -1,7 +0,0 @@
1
- import { CSSObject } from '@emotion/react';
2
- import type { ScaleOption as Opt } from '@tremolo-ui/functions/Slider';
3
- export type ScaleOption = Opt & {
4
- style?: CSSObject;
5
- };
6
- export { type Direction, type Horizontal, type ScaleOrderList, type ScaleType, type Vertical, gradientDirection } from '@tremolo-ui/functions/Slider';
7
- //# sourceMappingURL=type.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../../../src/components/Slider/type.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,OAAO,KAAK,EAAE,WAAW,IAAI,GAAG,EAAE,MAAM,8BAA8B,CAAA;AAEtE,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,CAAA;AAED,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,iBAAiB,EAClB,MAAM,8BAA8B,CAAA"}
@@ -1,14 +0,0 @@
1
- import { CSSObject } from '@emotion/react';
2
- export declare const inputPseudoSelectors: readonly ["&:enabled", "&:disabled", "&:read-only", "&:read-write", "&:placeholder-shown", "&:blank", "&:valid", "&:invalid", "&:in-range", "&:out-of-range"];
3
- export declare const inputPseudoPropNames: readonly ["_enabled", "_disabled", "_readOnly", "_readWrite", "_placeholderShown", "_blank", "_valid", "_invalid", "_inRange", "_outOfRange"];
4
- export type InputPseudos = (typeof inputPseudoPropNames)[number];
5
- export type InputPseudoProps = Partial<{
6
- [key in InputPseudos]: CSSObject;
7
- }>;
8
- export declare const userActionPseudoSelectors: readonly ["&:hover", "&:active", "&:focus"];
9
- export declare const userActionPseudoPropNames: readonly ["_hover", "_active", "_focus"];
10
- export type UserActionPseudos = (typeof userActionPseudoPropNames)[number];
11
- export type UserActionPseudoProps = Partial<{
12
- [key in UserActionPseudos]: CSSObject;
13
- }>;
14
- //# sourceMappingURL=pseudo.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pseudo.d.ts","sourceRoot":"","sources":["../../../../src/system/pseudo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAQ1C,eAAO,MAAM,oBAAoB,+JAWvB,CAAA;AAEV,eAAO,MAAM,oBAAoB,+IAWvB,CAAA;AAEV,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA;AAChE,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC;KACpC,GAAG,IAAI,YAAY,GAAG,SAAS;CACjC,CAAC,CAAA;AAEF,eAAO,MAAM,yBAAyB,6CAI5B,CAAA;AAEV,eAAO,MAAM,yBAAyB,0CAI5B,CAAA;AAEV,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAA;AAC1E,MAAM,MAAM,qBAAqB,GAAG,OAAO,CAAC;KACzC,GAAG,IAAI,iBAAiB,GAAG,SAAS;CACtC,CAAC,CAAA"}
@@ -1,16 +0,0 @@
1
- import { CSSObject } from '@emotion/react'
2
-
3
- import type { ScaleOption as Opt } from '@tremolo-ui/functions/Slider'
4
-
5
- export type ScaleOption = Opt & {
6
- style?: CSSObject
7
- }
8
-
9
- export {
10
- type Direction,
11
- type Horizontal,
12
- type ScaleOrderList,
13
- type ScaleType,
14
- type Vertical,
15
- gradientDirection
16
- } from '@tremolo-ui/functions/Slider'
@@ -1,55 +0,0 @@
1
- import { CSSObject } from '@emotion/react'
2
-
3
- function _toPropName(str: string) {
4
- return str.replace(/-\w/, (s) => s.toUpperCase()).replace(/^::?/, '_')
5
- }
6
-
7
- // ref. https://developer.mozilla.org/ja/docs/Web/CSS/Pseudo-classes
8
-
9
- export const inputPseudoSelectors = [
10
- '&:enabled',
11
- '&:disabled',
12
- '&:read-only',
13
- '&:read-write',
14
- '&:placeholder-shown',
15
- '&:blank',
16
- '&:valid',
17
- '&:invalid',
18
- '&:in-range',
19
- '&:out-of-range',
20
- ] as const
21
-
22
- export const inputPseudoPropNames = [
23
- '_enabled',
24
- '_disabled',
25
- '_readOnly',
26
- '_readWrite',
27
- '_placeholderShown',
28
- '_blank',
29
- '_valid',
30
- '_invalid',
31
- '_inRange',
32
- '_outOfRange',
33
- ] as const
34
-
35
- export type InputPseudos = (typeof inputPseudoPropNames)[number]
36
- export type InputPseudoProps = Partial<{
37
- [key in InputPseudos]: CSSObject
38
- }>
39
-
40
- export const userActionPseudoSelectors = [
41
- '&:hover',
42
- '&:active',
43
- '&:focus',
44
- ] as const
45
-
46
- export const userActionPseudoPropNames = [
47
- '_hover',
48
- '_active',
49
- '_focus',
50
- ] as const
51
-
52
- export type UserActionPseudos = (typeof userActionPseudoPropNames)[number]
53
- export type UserActionPseudoProps = Partial<{
54
- [key in UserActionPseudos]: CSSObject
55
- }>