@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.
- package/dist/cjs/index.js +196 -93
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/AnimationCanvas/index.d.ts +3 -4
- package/dist/cjs/types/components/AnimationCanvas/index.d.ts.map +1 -1
- package/dist/cjs/types/components/Knob/index.d.ts +6 -7
- package/dist/cjs/types/components/Knob/index.d.ts.map +1 -1
- package/dist/cjs/types/components/NumberInput/index.d.ts +10 -7
- package/dist/cjs/types/components/NumberInput/index.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/BlackKey.d.ts +4 -0
- package/dist/cjs/types/components/Piano/BlackKey.d.ts.map +1 -0
- package/dist/cjs/types/components/Piano/KeyLabel.d.ts +20 -0
- package/dist/cjs/types/components/Piano/KeyLabel.d.ts.map +1 -0
- package/dist/cjs/types/components/Piano/WhiteKey.d.ts +4 -0
- package/dist/cjs/types/components/Piano/WhiteKey.d.ts.map +1 -0
- package/dist/cjs/types/components/Piano/index.d.ts +35 -0
- package/dist/cjs/types/components/Piano/index.d.ts.map +1 -0
- package/dist/cjs/types/components/Piano/key.d.ts +39 -0
- package/dist/cjs/types/components/Piano/key.d.ts.map +1 -0
- package/dist/cjs/types/components/Piano/keyboardShortcuts.d.ts +12 -0
- package/dist/cjs/types/components/Piano/keyboardShortcuts.d.ts.map +1 -0
- package/dist/cjs/types/components/Slider/Thumb.d.ts +17 -2
- package/dist/cjs/types/components/Slider/Thumb.d.ts.map +1 -1
- package/dist/cjs/types/components/Slider/Track.d.ts +21 -2
- package/dist/cjs/types/components/Slider/Track.d.ts.map +1 -1
- package/dist/cjs/types/components/Slider/index.d.ts +18 -10
- package/dist/cjs/types/components/Slider/index.d.ts.map +1 -1
- package/dist/cjs/types/components/_util/index.d.ts +4 -0
- package/dist/cjs/types/components/_util/index.d.ts.map +1 -0
- package/dist/esm/index.js +197 -94
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/AnimationCanvas/index.d.ts +3 -4
- package/dist/esm/types/components/AnimationCanvas/index.d.ts.map +1 -1
- package/dist/esm/types/components/Knob/index.d.ts +6 -7
- package/dist/esm/types/components/Knob/index.d.ts.map +1 -1
- package/dist/esm/types/components/NumberInput/index.d.ts +10 -7
- package/dist/esm/types/components/NumberInput/index.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/BlackKey.d.ts +4 -0
- package/dist/esm/types/components/Piano/BlackKey.d.ts.map +1 -0
- package/dist/esm/types/components/Piano/KeyLabel.d.ts +20 -0
- package/dist/esm/types/components/Piano/KeyLabel.d.ts.map +1 -0
- package/dist/esm/types/components/Piano/WhiteKey.d.ts +4 -0
- package/dist/esm/types/components/Piano/WhiteKey.d.ts.map +1 -0
- package/dist/esm/types/components/Piano/index.d.ts +35 -0
- package/dist/esm/types/components/Piano/index.d.ts.map +1 -0
- package/dist/esm/types/components/Piano/key.d.ts +39 -0
- package/dist/esm/types/components/Piano/key.d.ts.map +1 -0
- package/dist/esm/types/components/Piano/keyboardShortcuts.d.ts +12 -0
- package/dist/esm/types/components/Piano/keyboardShortcuts.d.ts.map +1 -0
- package/dist/esm/types/components/Slider/Thumb.d.ts +17 -2
- package/dist/esm/types/components/Slider/Thumb.d.ts.map +1 -1
- package/dist/esm/types/components/Slider/Track.d.ts +21 -2
- package/dist/esm/types/components/Slider/Track.d.ts.map +1 -1
- package/dist/esm/types/components/Slider/index.d.ts +18 -10
- package/dist/esm/types/components/Slider/index.d.ts.map +1 -1
- package/dist/esm/types/components/_util/index.d.ts +4 -0
- package/dist/esm/types/components/_util/index.d.ts.map +1 -0
- package/dist/styles/{variables.css → index.css} +4 -0
- package/package.json +7 -7
- package/src/components/AnimationCanvas/index.tsx +3 -7
- package/src/components/Knob/index.tsx +15 -19
- package/src/components/NumberInput/index.tsx +18 -11
- package/src/components/Piano/BlackKey.tsx +108 -0
- package/src/components/Piano/KeyLabel.tsx +69 -0
- package/src/components/Piano/WhiteKey.tsx +109 -0
- package/src/components/Piano/index.tsx +222 -0
- package/src/components/Piano/key.ts +43 -0
- package/src/components/Piano/keyboardShortcuts.ts +12 -0
- package/src/components/Slider/Thumb.tsx +56 -15
- package/src/components/Slider/Track.tsx +62 -3
- package/src/components/Slider/index.tsx +125 -89
- package/src/components/_util/index.ts +11 -0
- package/src/styles/{variables.css → index.css} +4 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { css, CSSObject, Global } from '@emotion/react'
|
|
2
|
+
import clsx from 'clsx'
|
|
2
3
|
import {
|
|
3
4
|
Direction,
|
|
4
|
-
gradientDirection,
|
|
5
5
|
isHorizontal,
|
|
6
6
|
isReversed,
|
|
7
7
|
isVertical,
|
|
@@ -9,21 +9,20 @@ import {
|
|
|
9
9
|
ScaleOrderList,
|
|
10
10
|
ScaleType,
|
|
11
11
|
} from '@tremolo-ui/functions/Slider'
|
|
12
|
-
import { clamp, normalizeValue, rawValue, stepValue } from '@tremolo-ui/functions'
|
|
13
|
-
import {
|
|
14
|
-
import { styleHelper } from '@tremolo-ui/functions'
|
|
15
|
-
import React, { ReactElement, useRef } from 'react'
|
|
16
|
-
import clsx from 'clsx'
|
|
12
|
+
import { clamp, normalizeValue, rawValue, stepValue, toFixed, InputEventOption, styleHelper } from '@tremolo-ui/functions'
|
|
13
|
+
import React, { forwardRef, ReactElement, useCallback, useImperativeHandle, useRef } from 'react'
|
|
17
14
|
|
|
18
15
|
import { useEventListener } from '../../hooks/useEventListener'
|
|
19
16
|
import { useRefCallbackEvent } from '../../hooks/useRefCallbackEvent'
|
|
20
17
|
import { UserActionPseudoProps } from '../../system/pseudo'
|
|
18
|
+
import { addNoSelect, removeNoSelect } from '../_util'
|
|
21
19
|
|
|
22
|
-
import { SliderThumb } from './Thumb'
|
|
20
|
+
import { SliderThumb, SliderThumbMethods } from './Thumb'
|
|
23
21
|
import { SliderTrack } from './Track'
|
|
24
22
|
import { ScaleOption } from './type'
|
|
25
23
|
|
|
26
|
-
interface SliderProps {
|
|
24
|
+
export interface SliderProps {
|
|
25
|
+
// TODO: property docs
|
|
27
26
|
// required
|
|
28
27
|
value: number
|
|
29
28
|
min: number
|
|
@@ -31,16 +30,22 @@ interface SliderProps {
|
|
|
31
30
|
|
|
32
31
|
// optional
|
|
33
32
|
step?: number
|
|
34
|
-
skew?: number // | SkewFunction
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
direction?: Direction
|
|
33
|
+
skew?: number // TODO | SkewFunction
|
|
34
|
+
direction?: Direction // TODO: vertical & reverse
|
|
35
|
+
// TODO: scales component
|
|
38
36
|
scale?: ['step', ScaleType] | [number, ScaleType] | ScaleOrderList[]
|
|
39
37
|
scaleOption?: ScaleOption
|
|
40
|
-
color?: string
|
|
41
|
-
bg?: string
|
|
42
38
|
bodyNoSelect?: boolean
|
|
43
|
-
|
|
39
|
+
/**
|
|
40
|
+
* wheel control option
|
|
41
|
+
*/
|
|
42
|
+
wheel?: InputEventOption
|
|
43
|
+
/**
|
|
44
|
+
* keyboard control option
|
|
45
|
+
*/
|
|
46
|
+
keyboard?: InputEventOption
|
|
47
|
+
disabled?: boolean
|
|
48
|
+
readonly?: boolean
|
|
44
49
|
className?: string
|
|
45
50
|
style?: CSSObject
|
|
46
51
|
onChange?: (value: number) => void
|
|
@@ -48,45 +53,62 @@ interface SliderProps {
|
|
|
48
53
|
// ReactElement<typeof SliderThumb, typeof SliderTrack>[]
|
|
49
54
|
}
|
|
50
55
|
|
|
56
|
+
export interface SliderMethods {
|
|
57
|
+
focus: () => void
|
|
58
|
+
blur: () => void
|
|
59
|
+
}
|
|
60
|
+
|
|
51
61
|
/**
|
|
52
62
|
* Customizable slider
|
|
53
63
|
*/
|
|
54
|
-
export
|
|
64
|
+
export const Slider = forwardRef<SliderMethods, SliderProps>(({
|
|
55
65
|
value,
|
|
56
66
|
min,
|
|
57
67
|
max,
|
|
58
68
|
step = 1,
|
|
59
69
|
skew = 1,
|
|
60
|
-
length = 140,
|
|
61
|
-
thickness = 10,
|
|
62
70
|
direction = 'right',
|
|
63
71
|
scale,
|
|
64
72
|
scaleOption,
|
|
65
|
-
color = '#4e76e6',
|
|
66
|
-
bg = '#eee',
|
|
67
73
|
className,
|
|
68
74
|
style,
|
|
69
75
|
bodyNoSelect = true,
|
|
70
|
-
|
|
76
|
+
wheel = ['raw', 1],
|
|
77
|
+
keyboard = ['raw', 1],
|
|
78
|
+
disabled = false,
|
|
79
|
+
readonly = false,
|
|
71
80
|
onChange,
|
|
72
81
|
children,
|
|
73
82
|
...pseudo
|
|
74
|
-
}: SliderProps & UserActionPseudoProps) {
|
|
83
|
+
}: SliderProps & UserActionPseudoProps, ref) => {
|
|
75
84
|
// -- state and ref ---
|
|
76
85
|
const trackElementRef = useRef<HTMLDivElement>(null)
|
|
86
|
+
const thumbRef = useRef<SliderThumbMethods>(null)
|
|
87
|
+
const thumbDragged = useRef(false)
|
|
77
88
|
|
|
78
89
|
// --- interpret props ---
|
|
79
90
|
const { _active, _focus, _hover } = pseudo
|
|
80
|
-
const percent = normalizeValue(value, min, max, skew) * 100
|
|
81
|
-
const percentRev = isReversed(direction) ? 100 - percent : percent
|
|
91
|
+
const percent = toFixed(normalizeValue(value, min, max, skew) * 100)
|
|
92
|
+
const percentRev = isReversed(direction) ? toFixed(100 - percent) : percent
|
|
93
|
+
const calcPercent = (v: number) => {
|
|
94
|
+
return toFixed(
|
|
95
|
+
isReversed(direction)
|
|
96
|
+
? 100 - normalizeValue(v, min, max, skew) * 100
|
|
97
|
+
: normalizeValue(v, min, max, skew) * 100
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
if (wheel.length != 2) {
|
|
101
|
+
throw new Error(`Slider.wheel expect ['normalized' | 'raw', number]`)
|
|
102
|
+
}
|
|
103
|
+
if (keyboard.length != 2) {
|
|
104
|
+
throw new Error(`Slider.keyboard expect ['normalized' | 'raw', number]`)
|
|
105
|
+
}
|
|
82
106
|
|
|
83
107
|
const scalesList = parseScaleOrderList(scale, min, max, step)
|
|
84
108
|
if (isReversed(direction)) scalesList.reverse()
|
|
85
109
|
|
|
86
110
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
87
|
-
let trackProps: any
|
|
88
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
89
|
-
let thumbProps: any
|
|
111
|
+
let trackProps: any, thumbProps: any
|
|
90
112
|
if (children != undefined) {
|
|
91
113
|
React.Children.forEach(children, (child) => {
|
|
92
114
|
if (React.isValidElement(child)) {
|
|
@@ -103,14 +125,14 @@ export function Slider({
|
|
|
103
125
|
})
|
|
104
126
|
}
|
|
105
127
|
|
|
106
|
-
|
|
128
|
+
// --- internal functions ---
|
|
107
129
|
const handleValue = (
|
|
108
130
|
event: MouseEvent | React.PointerEvent<HTMLDivElement> | TouchEvent,
|
|
109
131
|
) => {
|
|
110
|
-
if (!trackElementRef.current || !thumbDragged.current) return
|
|
132
|
+
if (!trackElementRef.current || !thumbDragged.current || !onChange || readonly) return
|
|
111
133
|
const isTouch = event instanceof TouchEvent
|
|
112
134
|
if (isTouch && event.cancelable) event.preventDefault()
|
|
113
|
-
if (bodyNoSelect)
|
|
135
|
+
if (bodyNoSelect) addNoSelect()
|
|
114
136
|
const {
|
|
115
137
|
left: x1,
|
|
116
138
|
top: y1,
|
|
@@ -123,38 +145,55 @@ export function Slider({
|
|
|
123
145
|
? normalizeValue(mouseX, x1, x2)
|
|
124
146
|
: normalizeValue(mouseY, y1, y2)
|
|
125
147
|
const v = rawValue(isReversed(direction) ? 1 - n : n, min, max, skew)
|
|
126
|
-
|
|
127
|
-
if (onChange) onChange(v2)
|
|
148
|
+
onChange(clamp(stepValue(v, step), min, max))
|
|
128
149
|
}
|
|
129
150
|
|
|
151
|
+
const handleKeyDown = useCallback((event: React.KeyboardEvent<HTMLDivElement>) => {
|
|
152
|
+
if (!keyboard || !onChange || readonly) return
|
|
153
|
+
const key = event.key
|
|
154
|
+
if (['ArrowRight', 'ArrowLeft', 'ArrowUp', 'ArrowDown'].includes(key)) {
|
|
155
|
+
event.preventDefault()
|
|
156
|
+
let x = (key == 'ArrowRight' || key == 'ArrowUp') ? keyboard[1] : -keyboard[1]
|
|
157
|
+
if (direction == 'down' || direction == 'left') x *= -1
|
|
158
|
+
let v
|
|
159
|
+
if (keyboard[0] == 'normalized') {
|
|
160
|
+
const n = normalizeValue(value, min, max, skew)
|
|
161
|
+
v = rawValue(n + x, min, max, skew)
|
|
162
|
+
} else {
|
|
163
|
+
v = value + x
|
|
164
|
+
}
|
|
165
|
+
onChange(clamp(stepValue(v, step), min, max))
|
|
166
|
+
}
|
|
167
|
+
}, [value, min, max, step, skew, direction, keyboard, onChange, readonly])
|
|
168
|
+
|
|
130
169
|
// --- hooks ---
|
|
131
170
|
const touchMoveRefCallback = useRefCallbackEvent(
|
|
132
171
|
'touchmove',
|
|
133
172
|
handleValue,
|
|
134
173
|
{ passive: false },
|
|
135
|
-
[min, max, skew, step, direction, onChange],
|
|
174
|
+
[min, max, skew, step, direction, onChange, readonly],
|
|
136
175
|
)
|
|
137
176
|
|
|
138
177
|
const wheelRefCallback = useRefCallbackEvent(
|
|
139
178
|
'wheel',
|
|
140
179
|
(event) => {
|
|
141
|
-
if (!
|
|
180
|
+
if (!wheel || !onChange || readonly) return
|
|
142
181
|
event.preventDefault()
|
|
143
|
-
let x = event.deltaY > 0 ?
|
|
182
|
+
let x = event.deltaY > 0 ? wheel[1] : -wheel[1]
|
|
144
183
|
if (isReversed(direction) || isHorizontal(direction)) x *= -1
|
|
145
184
|
let v
|
|
146
|
-
if (
|
|
185
|
+
if (wheel[0] == 'normalized') {
|
|
147
186
|
const n = normalizeValue(value, min, max, skew)
|
|
148
187
|
v = rawValue(n + x, min, max, skew)
|
|
149
188
|
} else {
|
|
150
189
|
v = value + x
|
|
151
190
|
}
|
|
152
|
-
|
|
191
|
+
onChange(clamp(stepValue(v, step), min, max))
|
|
153
192
|
},
|
|
154
193
|
{
|
|
155
194
|
passive: false,
|
|
156
195
|
},
|
|
157
|
-
[
|
|
196
|
+
[wheel, value, min, max, skew, step],
|
|
158
197
|
)
|
|
159
198
|
|
|
160
199
|
useEventListener(window, 'mousemove', (event) => {
|
|
@@ -163,9 +202,20 @@ export function Slider({
|
|
|
163
202
|
|
|
164
203
|
useEventListener(window, 'mouseup', () => {
|
|
165
204
|
thumbDragged.current = false
|
|
166
|
-
if (bodyNoSelect)
|
|
205
|
+
if (bodyNoSelect) removeNoSelect()
|
|
167
206
|
})
|
|
168
207
|
|
|
208
|
+
useImperativeHandle(ref, () => {
|
|
209
|
+
return {
|
|
210
|
+
focus() {
|
|
211
|
+
thumbRef.current?.focus()
|
|
212
|
+
},
|
|
213
|
+
blur() {
|
|
214
|
+
thumbRef.current?.blur()
|
|
215
|
+
},
|
|
216
|
+
}
|
|
217
|
+
}, [])
|
|
218
|
+
|
|
169
219
|
return (
|
|
170
220
|
<div
|
|
171
221
|
className={clsx('tremolo-slider', className)}
|
|
@@ -176,21 +226,25 @@ export function Slider({
|
|
|
176
226
|
tabIndex={-1}
|
|
177
227
|
role="slider"
|
|
178
228
|
aria-valuenow={value}
|
|
179
|
-
aria-valuemax={max}
|
|
180
229
|
aria-valuemin={min}
|
|
230
|
+
aria-valuemax={max}
|
|
181
231
|
aria-orientation={isHorizontal(direction) ? 'horizontal' : 'vertical'}
|
|
232
|
+
aria-disabled={disabled}
|
|
233
|
+
aria-readonly={readonly}
|
|
182
234
|
css={css({
|
|
183
235
|
display: 'inline-block',
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
cursor: 'pointer',
|
|
236
|
+
margin: `calc(${styleHelper(thumbProps?.size ?? 22)} / 2)`, // half thumb size
|
|
237
|
+
cursor: readonly ? 'not-allowed' : 'pointer',
|
|
238
|
+
outline: 0,
|
|
188
239
|
...style,
|
|
189
240
|
})}
|
|
190
241
|
onPointerDown={(event) => {
|
|
191
242
|
thumbDragged.current = true
|
|
192
243
|
handleValue(event)
|
|
193
244
|
}}
|
|
245
|
+
onKeyDown={handleKeyDown}
|
|
246
|
+
onFocus={thumbRef.current?.focus}
|
|
247
|
+
onBlur={thumbRef.current?.blur}
|
|
194
248
|
>
|
|
195
249
|
<Global
|
|
196
250
|
styles={{
|
|
@@ -205,49 +259,43 @@ export function Slider({
|
|
|
205
259
|
flexDirection: isHorizontal(direction) ? 'column' : 'row',
|
|
206
260
|
})}
|
|
207
261
|
>
|
|
208
|
-
{/* trackProps */}
|
|
209
262
|
<div
|
|
210
263
|
className="tremolo-slider-track-wrapper"
|
|
211
264
|
ref={trackElementRef}
|
|
212
|
-
css={css({ position: 'relative' })}
|
|
213
265
|
>
|
|
214
266
|
<SliderTrack
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
267
|
+
__direction={direction}
|
|
268
|
+
__disabled={disabled}
|
|
269
|
+
__percent={percent}
|
|
270
|
+
__thumb={
|
|
271
|
+
<SliderThumb
|
|
272
|
+
ref={thumbRef}
|
|
273
|
+
__disabled={disabled}
|
|
274
|
+
__css={{
|
|
275
|
+
top: isHorizontal(direction) ? '50%' : `${percentRev}%`,
|
|
276
|
+
left: isHorizontal(direction) ? `${percentRev}%` : '50%',
|
|
277
|
+
}}
|
|
278
|
+
{...thumbProps}
|
|
279
|
+
/>
|
|
280
|
+
}
|
|
225
281
|
{...trackProps}
|
|
226
282
|
/>
|
|
227
|
-
<SliderThumb
|
|
228
|
-
color={color}
|
|
229
|
-
__css={{
|
|
230
|
-
top: isHorizontal(direction) ? '50%' : `${percentRev}%`,
|
|
231
|
-
left: isHorizontal(direction) ? `${percentRev}%` : '50%',
|
|
232
|
-
}}
|
|
233
|
-
{...thumbProps}
|
|
234
|
-
/>
|
|
235
283
|
</div>
|
|
284
|
+
{/* TODO: scales component */}
|
|
236
285
|
{scale && (
|
|
237
286
|
<div
|
|
238
287
|
className="tremolo-slider-scale-wrapper"
|
|
239
288
|
css={css({
|
|
289
|
+
display: 'block',
|
|
240
290
|
position: 'relative',
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
: (scaleOption?.gap ??
|
|
250
|
-
`calc((1.4rem - ${styleHelper(thickness)}) / 2)`),
|
|
291
|
+
marginLeft: isVertical(direction)
|
|
292
|
+
? (scaleOption?.gap ??
|
|
293
|
+
`calc((22px - ${styleHelper(trackProps?.thickness ?? 10)}) / 2)`)
|
|
294
|
+
: undefined,
|
|
295
|
+
marginTop: isHorizontal(direction)
|
|
296
|
+
? (scaleOption?.gap ??
|
|
297
|
+
`calc((22px - ${styleHelper(trackProps?.thickness ?? 10)}) / 2)`)
|
|
298
|
+
: undefined,
|
|
251
299
|
...scaleOption?.style,
|
|
252
300
|
// zIndex: 10,
|
|
253
301
|
})}
|
|
@@ -261,20 +309,8 @@ export function Slider({
|
|
|
261
309
|
justifyContent: 'center',
|
|
262
310
|
alignItems: 'center',
|
|
263
311
|
position: 'absolute',
|
|
264
|
-
left: isHorizontal(direction)
|
|
265
|
-
|
|
266
|
-
isReversed(direction)
|
|
267
|
-
? 100 - normalizeValue(item.at, min, max, skew) * 100
|
|
268
|
-
: normalizeValue(item.at, min, max, skew) * 100
|
|
269
|
-
}%`
|
|
270
|
-
: undefined,
|
|
271
|
-
top: isVertical(direction)
|
|
272
|
-
? `${
|
|
273
|
-
isReversed(direction)
|
|
274
|
-
? 100 - normalizeValue(item.at, min, max, skew) * 100
|
|
275
|
-
: normalizeValue(item.at, min, max, skew) * 100
|
|
276
|
-
}%`
|
|
277
|
-
: undefined,
|
|
312
|
+
left: isHorizontal(direction) ? `${calcPercent(item.at)}%` : undefined,
|
|
313
|
+
top: isVertical(direction) ? `${calcPercent(item.at)}%` : undefined,
|
|
278
314
|
translate: isHorizontal(direction) ? '-50% 0' : '0 -50%',
|
|
279
315
|
zIndex: 10,
|
|
280
316
|
})}
|
|
@@ -319,7 +355,7 @@ export function Slider({
|
|
|
319
355
|
</div>
|
|
320
356
|
</div>
|
|
321
357
|
)
|
|
322
|
-
}
|
|
358
|
+
})
|
|
323
359
|
|
|
324
360
|
export * from './Thumb'
|
|
325
361
|
export * from './Track'
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function addNoSelect() {
|
|
2
|
+
document.body.classList.add('tremolo-no-select')
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function removeNoSelect() {
|
|
6
|
+
document.body.classList.remove('tremolo-no-select')
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function toggleNoSelect() {
|
|
10
|
+
document.body.classList.toggle('tremolo-no-select')
|
|
11
|
+
}
|