@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
package/dist/esm/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, Fragment, jsx } from '@emotion/react/jsx-runtime';
|
|
2
2
|
import { css, Global } from '@emotion/react';
|
|
3
|
-
import React, { useRef, useEffect, useInsertionEffect, useCallback, useMemo, useState } from 'react';
|
|
3
|
+
import React, { useRef, useEffect, useInsertionEffect, useCallback, useMemo, useState, forwardRef, useImperativeHandle } from 'react';
|
|
4
4
|
|
|
5
5
|
/******************************************************************************
|
|
6
6
|
Copyright (c) Microsoft Corporation.
|
|
@@ -94,7 +94,7 @@ function AnimationCanvas(_a) {
|
|
|
94
94
|
if (!parent)
|
|
95
95
|
throw new Error("Canvas doesn't have a parent element.");
|
|
96
96
|
const memoCanvas = memoCanvasRef.current;
|
|
97
|
-
const memoContext = memoCanvas === null || memoCanvas ===
|
|
97
|
+
const memoContext = memoCanvas === null || memoCanvas === undefined ? undefined : memoCanvas.getContext('2d', options);
|
|
98
98
|
const resizeObserver = new ResizeObserver(() => {
|
|
99
99
|
// console.log('resize')
|
|
100
100
|
// Prevents loss of some context when the canvas is resized
|
|
@@ -150,15 +150,27 @@ function AnimationCanvas(_a) {
|
|
|
150
150
|
return (jsxs(Fragment, { children: [jsx("canvas", Object.assign({ className: clsx('tremolo-animation-canvas', className), width: relativeSize ? 0 : width, height: relativeSize ? 0 : height, css: css(style), ref: canvasRef }, props)), relativeSize && reduceFlickering && (jsx("canvas", { style: { display: 'none' }, width: relativeSize ? 0 : width, height: relativeSize ? 0 : height, ref: memoCanvasRef }))] }));
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
/**
|
|
154
|
+
* clamp value between min and max
|
|
155
|
+
* @category Math
|
|
156
|
+
*/
|
|
153
157
|
function clamp(value, min, max) {
|
|
154
158
|
return Math.max(min, Math.min(value, max));
|
|
155
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Normalize the value from 0 to 1
|
|
162
|
+
* @category Math
|
|
163
|
+
*/
|
|
156
164
|
function normalizeValue(rawValue, min, max, skew = 1) {
|
|
157
165
|
if (min >= max)
|
|
158
166
|
throw new RangeError('requirements: min < max');
|
|
159
167
|
const v = clamp((rawValue - min) / (max - min), 0, 1);
|
|
160
168
|
return Math.pow(v, skew);
|
|
161
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* Convert normalized values back to raw values.
|
|
172
|
+
* @category Math
|
|
173
|
+
*/
|
|
162
174
|
function rawValue(normalizedValue, min, max, skew = 1) {
|
|
163
175
|
if (min >= max)
|
|
164
176
|
throw new RangeError('requirements: min < max');
|
|
@@ -167,22 +179,38 @@ function rawValue(normalizedValue, min, max, skew = 1) {
|
|
|
167
179
|
: Math.exp(Math.log(clamp(normalizedValue, 0, 1)) / skew);
|
|
168
180
|
return min + v * (max - min);
|
|
169
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
*
|
|
184
|
+
* @category Math
|
|
185
|
+
*/
|
|
170
186
|
function stepValue(value, step) {
|
|
171
187
|
var _a;
|
|
172
188
|
if (step <= 0)
|
|
173
189
|
throw new RangeError('requirements: step > 0');
|
|
174
190
|
const quotient = Math.floor(value / step);
|
|
175
|
-
const decimalDigits = (_a = decimalPart$1(step)) === null || _a ===
|
|
191
|
+
const decimalDigits = (_a = decimalPart$1(step)) === null || _a === undefined ? undefined : _a.length;
|
|
176
192
|
const v = toFixed$2(quotient * step, decimalDigits);
|
|
177
193
|
const next = toFixed$2((quotient + 1) * step, decimalDigits);
|
|
178
194
|
return Math.abs(value - v) < Math.abs(value - next) ? v : next;
|
|
179
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
*
|
|
198
|
+
* @category Math
|
|
199
|
+
*/
|
|
180
200
|
function toFixed$2(x, fractionDigits) {
|
|
181
201
|
return Number(x.toFixed(fractionDigits));
|
|
182
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
*
|
|
205
|
+
* @category Math
|
|
206
|
+
*/
|
|
183
207
|
function decimalPart$1(x) {
|
|
184
208
|
return String(x).split('.')[1];
|
|
185
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
*
|
|
212
|
+
* @category Math
|
|
213
|
+
*/
|
|
186
214
|
function radian(degree) {
|
|
187
215
|
return (Math.PI * degree) / 180;
|
|
188
216
|
}
|
|
@@ -224,13 +252,13 @@ function useCallbackRef(callback, deps = []) {
|
|
|
224
252
|
useInsertionEffect(() => {
|
|
225
253
|
callbackRef.current = callback;
|
|
226
254
|
});
|
|
227
|
-
return useCallback((...args) => { var _a; return (_a = callbackRef.current) === null || _a ===
|
|
255
|
+
return useCallback((...args) => { var _a; return (_a = callbackRef.current) === null || _a === undefined ? undefined : _a.call(callbackRef, ...args); }, deps);
|
|
228
256
|
}
|
|
229
257
|
|
|
230
258
|
function useEventListener(target, event, handler, options) {
|
|
231
259
|
const listener = useCallbackRef(handler);
|
|
232
260
|
useEffect(() => {
|
|
233
|
-
const node = typeof target === 'function' ? target() : (target !== null && target !==
|
|
261
|
+
const node = typeof target === 'function' ? target() : (target !== null && target !== undefined ? target : document);
|
|
234
262
|
if (!handler || !node)
|
|
235
263
|
return;
|
|
236
264
|
node.addEventListener(event, listener, options);
|
|
@@ -239,8 +267,8 @@ function useEventListener(target, event, handler, options) {
|
|
|
239
267
|
};
|
|
240
268
|
}, [event, target, options, listener, handler]);
|
|
241
269
|
return () => {
|
|
242
|
-
const node = typeof target === 'function' ? target() : (target !== null && target !==
|
|
243
|
-
node === null || node ===
|
|
270
|
+
const node = typeof target === 'function' ? target() : (target !== null && target !== undefined ? target : document);
|
|
271
|
+
node === null || node === undefined ? undefined : node.removeEventListener(event, listener, options);
|
|
244
272
|
};
|
|
245
273
|
}
|
|
246
274
|
|
|
@@ -249,7 +277,7 @@ function useRefCallbackEvent(event, handler, options, deps = []) {
|
|
|
249
277
|
let cleanup;
|
|
250
278
|
return (node) => {
|
|
251
279
|
if (!node) {
|
|
252
|
-
cleanup === null || cleanup ===
|
|
280
|
+
cleanup === null || cleanup === undefined ? undefined : cleanup();
|
|
253
281
|
return;
|
|
254
282
|
}
|
|
255
283
|
node.addEventListener(event, handler, options);
|
|
@@ -260,6 +288,13 @@ function useRefCallbackEvent(event, handler, options, deps = []) {
|
|
|
260
288
|
}, deps);
|
|
261
289
|
}
|
|
262
290
|
|
|
291
|
+
function addNoSelect() {
|
|
292
|
+
document.body.classList.add('tremolo-no-select');
|
|
293
|
+
}
|
|
294
|
+
function removeNoSelect() {
|
|
295
|
+
document.body.classList.remove('tremolo-no-select');
|
|
296
|
+
}
|
|
297
|
+
|
|
263
298
|
const defaultOptions = {
|
|
264
299
|
active: '#7998ec',
|
|
265
300
|
inactive: '#eee',
|
|
@@ -272,14 +307,14 @@ const defaultOptions = {
|
|
|
272
307
|
* simple rotary Knob.
|
|
273
308
|
*/
|
|
274
309
|
function Knob(_a) {
|
|
275
|
-
var { value, min, max, defaultValue = min, startValue = min, step = 1, skew = 1, size, width = 50, height = 50, options = defaultOptions, draw, bodyNoSelect = true,
|
|
310
|
+
var { value, min, max, defaultValue = min, startValue = min, step = 1, skew = 1, size, width = 50, height = 50, options = defaultOptions, draw, bodyNoSelect = true, wheel, enableDoubleClickDefault = true, style, className, onChange, _active, _focus, _hover } = _a, props = __rest(_a, ["value", "min", "max", "defaultValue", "startValue", "step", "skew", "size", "width", "height", "options", "draw", "bodyNoSelect", "wheel", "enableDoubleClickDefault", "style", "className", "onChange", "_active", "_focus", "_hover"]);
|
|
276
311
|
// -- state and ref ---
|
|
277
312
|
// const [privateValue, setPrivateValue] = useState(value);
|
|
278
313
|
const dragOffsetY = useRef(undefined);
|
|
279
314
|
// --- interpret props ---
|
|
280
315
|
const opts = Object.assign(Object.assign({}, defaultOptions), options);
|
|
281
316
|
// const percent = normalizeValue(value, min, max, skew)
|
|
282
|
-
const isRelativeSize = typeof (size !== null && size !==
|
|
317
|
+
const isRelativeSize = typeof (size !== null && size !== undefined ? size : width) == 'string';
|
|
283
318
|
const adaptSize = (size) => {
|
|
284
319
|
if (typeof size == 'string') {
|
|
285
320
|
return Number(size.slice(0, -1));
|
|
@@ -294,7 +329,7 @@ function Knob(_a) {
|
|
|
294
329
|
event.preventDefault();
|
|
295
330
|
if (dragOffsetY.current) {
|
|
296
331
|
if (bodyNoSelect)
|
|
297
|
-
|
|
332
|
+
addNoSelect();
|
|
298
333
|
const screenY = isTouch ? event.touches[0].screenY : event.screenY;
|
|
299
334
|
const delta = dragOffsetY.current - screenY;
|
|
300
335
|
dragOffsetY.current = screenY;
|
|
@@ -307,12 +342,12 @@ function Knob(_a) {
|
|
|
307
342
|
};
|
|
308
343
|
// --- hooks ---
|
|
309
344
|
const wheelRefCallback = useRefCallbackEvent('wheel', (event) => {
|
|
310
|
-
if (!
|
|
345
|
+
if (!wheel)
|
|
311
346
|
return;
|
|
312
347
|
event.preventDefault();
|
|
313
|
-
const x = event.deltaY > 0 ? -
|
|
348
|
+
const x = event.deltaY > 0 ? -wheel[1] : wheel[1];
|
|
314
349
|
let v;
|
|
315
|
-
if (
|
|
350
|
+
if (wheel[0] == 'normalized') {
|
|
316
351
|
const n = normalizeValue(value, min, max, skew);
|
|
317
352
|
v = rawValue(n + x, min, max, skew);
|
|
318
353
|
}
|
|
@@ -321,18 +356,18 @@ function Knob(_a) {
|
|
|
321
356
|
}
|
|
322
357
|
if (onChange)
|
|
323
358
|
onChange(clamp(stepValue(v, step), min, max));
|
|
324
|
-
}, { passive: false }, [
|
|
359
|
+
}, { passive: false }, [wheel, value, min, max, skew, step, onChange]);
|
|
325
360
|
const touchMoveRefCallback = useRefCallbackEvent('touchmove', handleEvent, { passive: false }, [value, min, max, skew, step, onChange, bodyNoSelect]);
|
|
326
361
|
useEventListener(window, 'mousemove', handleEvent);
|
|
327
362
|
useEventListener(window, 'pointerup', () => {
|
|
328
363
|
dragOffsetY.current = undefined;
|
|
329
364
|
if (bodyNoSelect)
|
|
330
|
-
|
|
365
|
+
removeNoSelect();
|
|
331
366
|
});
|
|
332
367
|
return (jsxs("div", Object.assign({ className: clsx('tremolo-knob', className), ref: (div) => {
|
|
333
368
|
wheelRefCallback(div);
|
|
334
369
|
touchMoveRefCallback(div);
|
|
335
|
-
}, role: "slider", tabIndex: 0, "aria-valuenow": value, "aria-valuemax": max, "aria-valuemin": min, css: css(Object.assign(Object.assign({ display: 'inline-block', width: size !== null && size !==
|
|
370
|
+
}, role: "slider", tabIndex: 0, "aria-valuenow": value, "aria-valuemax": max, "aria-valuemin": min, css: css(Object.assign(Object.assign({ display: 'inline-block', width: size !== null && size !== undefined ? size : width, height: size !== null && size !== undefined ? size : height, cursor: 'pointer' }, style), { ':active': Object.assign({}, _active), ':focus': Object.assign({}, _focus), ':hover': Object.assign({}, _hover) })), onPointerDown: (event) => {
|
|
336
371
|
dragOffsetY.current = event.screenY;
|
|
337
372
|
handleEvent(event);
|
|
338
373
|
}, onDoubleClick: () => {
|
|
@@ -343,7 +378,7 @@ function Knob(_a) {
|
|
|
343
378
|
'.no-select': {
|
|
344
379
|
userSelect: 'none',
|
|
345
380
|
},
|
|
346
|
-
} }), jsx(AnimationCanvas, { width: adaptSize(size !== null && size !==
|
|
381
|
+
} }), jsx(AnimationCanvas, { width: adaptSize(size !== null && size !== undefined ? size : width), height: adaptSize(size !== null && size !== undefined ? size : height), relativeSize: isRelativeSize,
|
|
347
382
|
// TODO
|
|
348
383
|
// reduceFlickering={false}
|
|
349
384
|
draw: draw ? draw : (ctx, width, height) => {
|
|
@@ -388,10 +423,21 @@ function Knob(_a) {
|
|
|
388
423
|
} })] })));
|
|
389
424
|
}
|
|
390
425
|
|
|
426
|
+
/**
|
|
427
|
+
* clamp value between min and max
|
|
428
|
+
* @category Math
|
|
429
|
+
*/
|
|
430
|
+
/**
|
|
431
|
+
*
|
|
432
|
+
* @category Math
|
|
433
|
+
*/
|
|
391
434
|
function toFixed$1(x, fractionDigits) {
|
|
392
435
|
return Number(x.toFixed(fractionDigits));
|
|
393
436
|
}
|
|
394
437
|
|
|
438
|
+
/**
|
|
439
|
+
* @module NumberInput
|
|
440
|
+
*/
|
|
395
441
|
function selectUnit(units, value) {
|
|
396
442
|
if (typeof units == 'string')
|
|
397
443
|
return [units, 1];
|
|
@@ -454,14 +500,14 @@ function parseValue(inputString, units, digit, defaultValue = 0) {
|
|
|
454
500
|
* Input with some useful functions for entering numerical values.
|
|
455
501
|
*/
|
|
456
502
|
function NumberInput(_a) {
|
|
457
|
-
var { value, min, max, step, defaultValue = min, units, disabled = false, placeholder, readOnly, tabIndex,
|
|
503
|
+
var { value, min, max, step, defaultValue = min, units, disabled = false, placeholder, readOnly, tabIndex, typeNumber = false, digit, selectWithFocus = 'none', blurWithEnter = true, className, style, onChange, onFocus, onBlur } = _a, props = __rest(_a, ["value", "min", "max", "step", "defaultValue", "units", "disabled", "placeholder", "readOnly", "tabIndex", "typeNumber", "digit", "selectWithFocus", "blurWithEnter", "className", "style", "onChange", "onFocus", "onBlur"]);
|
|
458
504
|
const [showValue, setShowValue] = useState(parseValue(String(value), units, digit, defaultValue).formatValue);
|
|
459
|
-
const
|
|
460
|
-
const { _active, _focus, _hover } =
|
|
461
|
-
return (jsx("input", { className: clsx('tremolo-number-input', className), value: showValue, min: min, max: max, step: step, type:
|
|
505
|
+
const calculatedTypeNumber = units ? false : typeNumber;
|
|
506
|
+
const { _active, _focus, _hover } = props, rest = __rest(props, ["_active", "_focus", "_hover"]);
|
|
507
|
+
return (jsx("input", Object.assign({ className: clsx('tremolo-number-input', className), value: showValue, min: min, max: max, step: step, type: calculatedTypeNumber ? 'number' : 'text', spellCheck: 'false', disabled: disabled, placeholder: placeholder, readOnly: readOnly, tabIndex: tabIndex, css: css(Object.assign(Object.assign({ display: 'inline-block', font: 'inherit', margin: 0, paddingTop: 6, paddingBottom: 6, paddingLeft: 10, paddingRight: 10, borderStyle: 'solid', borderWidth: 1, borderColor: '#bbb', borderRadius: 4, outline: 0, transition: 'all 0.1s linear', appearance: 'textfield', '&:hover': Object.assign({ borderColor: 'var(--tremolo-theme-color)' }, _hover), '&:focus': Object.assign({ borderColor: 'var(--tremolo-theme-color)', boxShadow: '0px 0px 0px 2px rgba(var(--tremolo-theme-color-rgb), 0.1)' }, _focus) }, (_active && { '&:active': Object.assign({}, _active) })), style)), onChange: (event) => {
|
|
462
508
|
const v = event.currentTarget.value;
|
|
463
509
|
setShowValue(v);
|
|
464
|
-
const newValue = clamp(parseValue(v, units, digit, defaultValue).rawValue, min !== null && min !==
|
|
510
|
+
const newValue = clamp(parseValue(v, units, digit, defaultValue).rawValue, min !== null && min !== undefined ? min : -Infinity, max !== null && max !== undefined ? max : Infinity);
|
|
465
511
|
if (onChange)
|
|
466
512
|
onChange(newValue, event);
|
|
467
513
|
}, onFocus: (event) => {
|
|
@@ -486,16 +532,31 @@ function NumberInput(_a) {
|
|
|
486
532
|
if (blurWithEnter && event.key == 'Enter') {
|
|
487
533
|
event.currentTarget.blur();
|
|
488
534
|
}
|
|
489
|
-
} }));
|
|
535
|
+
} }, rest)));
|
|
490
536
|
}
|
|
491
537
|
|
|
538
|
+
/**
|
|
539
|
+
* clamp value between min and max
|
|
540
|
+
* @category Math
|
|
541
|
+
*/
|
|
542
|
+
/**
|
|
543
|
+
*
|
|
544
|
+
* @category Math
|
|
545
|
+
*/
|
|
492
546
|
function toFixed(x, fractionDigits) {
|
|
493
547
|
return Number(x.toFixed(fractionDigits));
|
|
494
548
|
}
|
|
549
|
+
/**
|
|
550
|
+
*
|
|
551
|
+
* @category Math
|
|
552
|
+
*/
|
|
495
553
|
function decimalPart(x) {
|
|
496
554
|
return String(x).split('.')[1];
|
|
497
555
|
}
|
|
498
556
|
|
|
557
|
+
/**
|
|
558
|
+
* @module Slider
|
|
559
|
+
*/
|
|
499
560
|
function isHorizontal(d) {
|
|
500
561
|
return d == 'right' || d == 'left';
|
|
501
562
|
}
|
|
@@ -524,46 +585,76 @@ function parseScaleOrderList(scale, min, max, step) {
|
|
|
524
585
|
const per = scale[0] == 'step' ? step : scale[0];
|
|
525
586
|
const count = Math.floor(max / per) - Math.ceil(min / per) + 1;
|
|
526
587
|
for (let i = 0; i < count; i++) {
|
|
527
|
-
const at = toFixed(per * (Math.ceil(min / per) + i), (_a = decimalPart(per)) === null || _a ===
|
|
588
|
+
const at = toFixed(per * (Math.ceil(min / per) + i), (_a = decimalPart(per)) === null || _a === undefined ? undefined : _a.length);
|
|
528
589
|
scalesList.push({ at: at, type: scale[1] });
|
|
529
590
|
}
|
|
530
591
|
}
|
|
531
592
|
return scalesList;
|
|
532
593
|
}
|
|
533
594
|
|
|
534
|
-
|
|
535
|
-
|
|
595
|
+
const SliderThumb = forwardRef(({ size, width = 22, height = 22, color = '#4e76e6', hoverColor = color, disabledColor = '#5d6478', disabledHoverColor = disabledColor, zIndex = 100, children, className, style, __disabled, __css, }, ref) => {
|
|
596
|
+
const wrapperRef = useRef(null);
|
|
597
|
+
useImperativeHandle(ref, () => {
|
|
598
|
+
return {
|
|
599
|
+
focus() {
|
|
600
|
+
var _a;
|
|
601
|
+
(_a = wrapperRef.current) === null || _a === undefined ? undefined : _a.focus();
|
|
602
|
+
},
|
|
603
|
+
blur() {
|
|
604
|
+
var _a;
|
|
605
|
+
(_a = wrapperRef.current) === null || _a === undefined ? undefined : _a.blur();
|
|
606
|
+
},
|
|
607
|
+
};
|
|
608
|
+
}, []);
|
|
609
|
+
return (jsx("div", { className: "tremolo-slider-thumb-wrapper", css: css(Object.assign({ position: 'absolute', translate: '-50% -50%', zIndex: zIndex }, __css)), children: children ? (children) : (
|
|
536
610
|
// default slider thumb
|
|
537
|
-
jsx("div", { className:
|
|
611
|
+
jsx("div", { ref: wrapperRef, className: clsx('tremolo-slider-thumb', className),
|
|
538
612
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
539
|
-
tabIndex: 0, css: css(Object.assign({ background: color, width:
|
|
540
|
-
background:
|
|
541
|
-
}, '&:
|
|
613
|
+
tabIndex: 0, css: css(Object.assign({ background: __disabled ? disabledColor : color, width: size !== null && size !== undefined ? size : width, height: size !== null && size !== undefined ? size : height, borderRadius: '50%', outline: 'none', '&:hover': {
|
|
614
|
+
background: __disabled ? disabledHoverColor : hoverColor
|
|
615
|
+
}, '&:focus': !__disabled && {
|
|
542
616
|
boxShadow: '0px 0px 0px 3px rgba(var(--tremolo-theme-color-rgb), 0.2)',
|
|
543
617
|
} }, style)) })) }));
|
|
544
|
-
}
|
|
618
|
+
});
|
|
545
619
|
|
|
546
|
-
function SliderTrack({ children, style,
|
|
547
|
-
|
|
620
|
+
function SliderTrack({ length = 140, thickness = 10, activeBg = '#7998ec', inactiveBg = '#eee', activeHoverBg = '#6387e9', inactiveHoverBg = '#e0e0e0', disabledActiveBg = '#858890', disabledInactiveBg = '#ddd', disabledActiveHoverBg = disabledActiveBg, disabledInactiveHoverBg = disabledInactiveBg, children, className, style, __thumb, __direction, __disabled, __percent, }) {
|
|
621
|
+
const active = __disabled ? disabledActiveBg : activeBg;
|
|
622
|
+
const inactive = __disabled ? disabledInactiveBg : inactiveBg;
|
|
623
|
+
const activeHover = __disabled ? disabledActiveHoverBg : activeHoverBg;
|
|
624
|
+
const inactiveHover = __disabled ? disabledInactiveHoverBg : inactiveHoverBg;
|
|
625
|
+
return (jsxs("div", { className: clsx('tremolo-slider-track', className), css: css(Object.assign({ position: 'relative', background: `linear-gradient(to ${gradientDirection(__direction)}, ${active} ${__percent}%, ${inactive} ${__percent}%)`, borderRadius: styleHelper(thickness, '/', 2), width: isHorizontal(__direction) ? length : thickness, height: isHorizontal(__direction) ? thickness : length, ':hover': {
|
|
626
|
+
background: `linear-gradient(to ${gradientDirection(__direction)}, ${activeHover} ${__percent}%, ${inactiveHover} ${__percent}%)`
|
|
627
|
+
} }, style)), children: [children, __thumb] }));
|
|
548
628
|
}
|
|
549
629
|
|
|
550
630
|
/**
|
|
551
631
|
* Customizable slider
|
|
552
632
|
*/
|
|
553
|
-
|
|
554
|
-
var _b, _c;
|
|
555
|
-
var { value, min, max, step = 1, skew = 1,
|
|
633
|
+
const Slider = forwardRef((_a, ref) => {
|
|
634
|
+
var _b, _c, _d, _e, _f, _g, _h;
|
|
635
|
+
var { value, min, max, step = 1, skew = 1, direction = 'right', scale, scaleOption, className, style, bodyNoSelect = true, wheel = ['raw', 1], keyboard = ['raw', 1], disabled = false, readonly = false, onChange, children } = _a; __rest(_a, ["value", "min", "max", "step", "skew", "direction", "scale", "scaleOption", "className", "style", "bodyNoSelect", "wheel", "keyboard", "disabled", "readonly", "onChange", "children"]);
|
|
556
636
|
// -- state and ref ---
|
|
557
637
|
const trackElementRef = useRef(null);
|
|
558
|
-
const
|
|
559
|
-
const
|
|
638
|
+
const thumbRef = useRef(null);
|
|
639
|
+
const thumbDragged = useRef(false);
|
|
640
|
+
const percent = toFixed$2(normalizeValue(value, min, max, skew) * 100);
|
|
641
|
+
const percentRev = isReversed(direction) ? toFixed$2(100 - percent) : percent;
|
|
642
|
+
const calcPercent = (v) => {
|
|
643
|
+
return toFixed$2(isReversed(direction)
|
|
644
|
+
? 100 - normalizeValue(v, min, max, skew) * 100
|
|
645
|
+
: normalizeValue(v, min, max, skew) * 100);
|
|
646
|
+
};
|
|
647
|
+
if (wheel.length != 2) {
|
|
648
|
+
throw new Error(`Slider.wheel expect ['normalized' | 'raw', number]`);
|
|
649
|
+
}
|
|
650
|
+
if (keyboard.length != 2) {
|
|
651
|
+
throw new Error(`Slider.keyboard expect ['normalized' | 'raw', number]`);
|
|
652
|
+
}
|
|
560
653
|
const scalesList = parseScaleOrderList(scale, min, max, step);
|
|
561
654
|
if (isReversed(direction))
|
|
562
655
|
scalesList.reverse();
|
|
563
656
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
564
|
-
let trackProps;
|
|
565
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
566
|
-
let thumbProps;
|
|
657
|
+
let trackProps, thumbProps;
|
|
567
658
|
if (children != undefined) {
|
|
568
659
|
React.Children.forEach(children, (child) => {
|
|
569
660
|
if (React.isValidElement(child)) {
|
|
@@ -582,15 +673,15 @@ function Slider(_a) {
|
|
|
582
673
|
}
|
|
583
674
|
});
|
|
584
675
|
}
|
|
585
|
-
|
|
676
|
+
// --- internal functions ---
|
|
586
677
|
const handleValue = (event) => {
|
|
587
|
-
if (!trackElementRef.current || !thumbDragged.current)
|
|
678
|
+
if (!trackElementRef.current || !thumbDragged.current || !onChange || readonly)
|
|
588
679
|
return;
|
|
589
680
|
const isTouch = event instanceof TouchEvent;
|
|
590
681
|
if (isTouch && event.cancelable)
|
|
591
682
|
event.preventDefault();
|
|
592
683
|
if (bodyNoSelect)
|
|
593
|
-
|
|
684
|
+
addNoSelect();
|
|
594
685
|
const { left: x1, top: y1, right: x2, bottom: y2, } = trackElementRef.current.getBoundingClientRect();
|
|
595
686
|
const mouseX = isTouch ? event.touches[0].clientX : event.clientX;
|
|
596
687
|
const mouseY = isTouch ? event.touches[0].clientY : event.clientY;
|
|
@@ -598,70 +689,90 @@ function Slider(_a) {
|
|
|
598
689
|
? normalizeValue(mouseX, x1, x2)
|
|
599
690
|
: normalizeValue(mouseY, y1, y2);
|
|
600
691
|
const v = rawValue(isReversed(direction) ? 1 - n : n, min, max, skew);
|
|
601
|
-
|
|
602
|
-
if (onChange)
|
|
603
|
-
onChange(v2);
|
|
692
|
+
onChange(clamp(stepValue(v, step), min, max));
|
|
604
693
|
};
|
|
694
|
+
const handleKeyDown = useCallback((event) => {
|
|
695
|
+
if (!keyboard || !onChange || readonly)
|
|
696
|
+
return;
|
|
697
|
+
const key = event.key;
|
|
698
|
+
if (['ArrowRight', 'ArrowLeft', 'ArrowUp', 'ArrowDown'].includes(key)) {
|
|
699
|
+
event.preventDefault();
|
|
700
|
+
let x = (key == 'ArrowRight' || key == 'ArrowUp') ? keyboard[1] : -keyboard[1];
|
|
701
|
+
if (direction == 'down' || direction == 'left')
|
|
702
|
+
x *= -1;
|
|
703
|
+
let v;
|
|
704
|
+
if (keyboard[0] == 'normalized') {
|
|
705
|
+
const n = normalizeValue(value, min, max, skew);
|
|
706
|
+
v = rawValue(n + x, min, max, skew);
|
|
707
|
+
}
|
|
708
|
+
else {
|
|
709
|
+
v = value + x;
|
|
710
|
+
}
|
|
711
|
+
onChange(clamp(stepValue(v, step), min, max));
|
|
712
|
+
}
|
|
713
|
+
}, [value, min, max, step, skew, direction, keyboard, onChange, readonly]);
|
|
605
714
|
// --- hooks ---
|
|
606
|
-
const touchMoveRefCallback = useRefCallbackEvent('touchmove', handleValue, { passive: false }, [min, max, skew, step, direction, onChange]);
|
|
715
|
+
const touchMoveRefCallback = useRefCallbackEvent('touchmove', handleValue, { passive: false }, [min, max, skew, step, direction, onChange, readonly]);
|
|
607
716
|
const wheelRefCallback = useRefCallbackEvent('wheel', (event) => {
|
|
608
|
-
if (!
|
|
717
|
+
if (!wheel || !onChange || readonly)
|
|
609
718
|
return;
|
|
610
719
|
event.preventDefault();
|
|
611
|
-
let x = event.deltaY > 0 ?
|
|
720
|
+
let x = event.deltaY > 0 ? wheel[1] : -wheel[1];
|
|
612
721
|
if (isReversed(direction) || isHorizontal(direction))
|
|
613
722
|
x *= -1;
|
|
614
723
|
let v;
|
|
615
|
-
if (
|
|
724
|
+
if (wheel[0] == 'normalized') {
|
|
616
725
|
const n = normalizeValue(value, min, max, skew);
|
|
617
726
|
v = rawValue(n + x, min, max, skew);
|
|
618
727
|
}
|
|
619
728
|
else {
|
|
620
729
|
v = value + x;
|
|
621
730
|
}
|
|
622
|
-
|
|
623
|
-
onChange(clamp(stepValue(v, step), min, max));
|
|
731
|
+
onChange(clamp(stepValue(v, step), min, max));
|
|
624
732
|
}, {
|
|
625
733
|
passive: false,
|
|
626
|
-
}, [
|
|
734
|
+
}, [wheel, value, min, max, skew, step]);
|
|
627
735
|
useEventListener(window, 'mousemove', (event) => {
|
|
628
736
|
handleValue(event);
|
|
629
737
|
});
|
|
630
738
|
useEventListener(window, 'mouseup', () => {
|
|
631
739
|
thumbDragged.current = false;
|
|
632
740
|
if (bodyNoSelect)
|
|
633
|
-
|
|
741
|
+
removeNoSelect();
|
|
634
742
|
});
|
|
743
|
+
useImperativeHandle(ref, () => {
|
|
744
|
+
return {
|
|
745
|
+
focus() {
|
|
746
|
+
var _a;
|
|
747
|
+
(_a = thumbRef.current) === null || _a === undefined ? undefined : _a.focus();
|
|
748
|
+
},
|
|
749
|
+
blur() {
|
|
750
|
+
var _a;
|
|
751
|
+
(_a = thumbRef.current) === null || _a === undefined ? undefined : _a.blur();
|
|
752
|
+
},
|
|
753
|
+
};
|
|
754
|
+
}, []);
|
|
635
755
|
return (jsxs("div", { className: clsx('tremolo-slider', className), ref: (div) => {
|
|
636
756
|
wheelRefCallback(div);
|
|
637
757
|
touchMoveRefCallback(div);
|
|
638
|
-
}, tabIndex: -1, role: "slider", "aria-valuenow": value, "aria-
|
|
758
|
+
}, tabIndex: -1, role: "slider", "aria-valuenow": value, "aria-valuemin": min, "aria-valuemax": max, "aria-orientation": isHorizontal(direction) ? 'horizontal' : 'vertical', "aria-disabled": disabled, "aria-readonly": readonly, css: css(Object.assign({ display: 'inline-block', margin: `calc(${styleHelper((_b = thumbProps === null || thumbProps === undefined ? undefined : thumbProps.size) !== null && _b !== undefined ? _b : 22)} / 2)`, cursor: readonly ? 'not-allowed' : 'pointer', outline: 0 }, style)), onPointerDown: (event) => {
|
|
639
759
|
thumbDragged.current = true;
|
|
640
760
|
handleValue(event);
|
|
641
|
-
}, children: [jsx(Global, { styles: {
|
|
761
|
+
}, onKeyDown: handleKeyDown, onFocus: (_c = thumbRef.current) === null || _c === undefined ? undefined : _c.focus, onBlur: (_d = thumbRef.current) === null || _d === undefined ? undefined : _d.blur, children: [jsx(Global, { styles: {
|
|
642
762
|
'.no-select': {
|
|
643
763
|
userSelect: 'none',
|
|
644
764
|
},
|
|
645
765
|
} }), jsxs("div", { css: css({
|
|
646
766
|
display: 'flex',
|
|
647
767
|
flexDirection: isHorizontal(direction) ? 'column' : 'row',
|
|
648
|
-
}), children: [
|
|
649
|
-
background: `linear-gradient(to ${gradientDirection(direction)}, ${color} ${percent}%, ${bg} ${percent}%)`,
|
|
650
|
-
borderRadius: styleHelper(thickness, '/', 2),
|
|
651
|
-
borderStyle: 'solid',
|
|
652
|
-
borderColor: '#ccc',
|
|
653
|
-
borderWidth: 2,
|
|
654
|
-
width: isHorizontal(direction) ? length : thickness,
|
|
655
|
-
height: isHorizontal(direction) ? thickness : length,
|
|
656
|
-
zIndex: 1,
|
|
657
|
-
} }, trackProps)), jsx(SliderThumb, Object.assign({ color: color, __css: {
|
|
768
|
+
}), children: [jsx("div", { className: "tremolo-slider-track-wrapper", ref: trackElementRef, children: jsx(SliderTrack, Object.assign({ __direction: direction, __disabled: disabled, __percent: percent, __thumb: jsx(SliderThumb, Object.assign({ ref: thumbRef, __disabled: disabled, __css: {
|
|
658
769
|
top: isHorizontal(direction) ? '50%' : `${percentRev}%`,
|
|
659
770
|
left: isHorizontal(direction) ? `${percentRev}%` : '50%',
|
|
660
|
-
} }, thumbProps))
|
|
661
|
-
? 2
|
|
662
|
-
:
|
|
663
|
-
? 2
|
|
664
|
-
:
|
|
771
|
+
} }, thumbProps)) }, trackProps)) }), scale && (jsx("div", { className: "tremolo-slider-scale-wrapper", css: css(Object.assign({ display: 'block', position: 'relative', marginLeft: isVertical(direction)
|
|
772
|
+
? ((_e = scaleOption === null || scaleOption === undefined ? undefined : scaleOption.gap) !== null && _e !== undefined ? _e : `calc((22px - ${styleHelper((_f = trackProps === null || trackProps === undefined ? undefined : trackProps.thickness) !== null && _f !== undefined ? _f : 10)}) / 2)`)
|
|
773
|
+
: undefined, marginTop: isHorizontal(direction)
|
|
774
|
+
? ((_g = scaleOption === null || scaleOption === undefined ? undefined : scaleOption.gap) !== null && _g !== undefined ? _g : `calc((22px - ${styleHelper((_h = trackProps === null || trackProps === undefined ? undefined : trackProps.thickness) !== null && _h !== undefined ? _h : 10)}) / 2)`)
|
|
775
|
+
: undefined }, scaleOption === null || scaleOption === undefined ? undefined : scaleOption.style)), children: scalesList.map((item, index) => {
|
|
665
776
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
666
777
|
return (jsxs("div", { css: css({
|
|
667
778
|
display: 'flex',
|
|
@@ -669,37 +780,29 @@ function Slider(_a) {
|
|
|
669
780
|
justifyContent: 'center',
|
|
670
781
|
alignItems: 'center',
|
|
671
782
|
position: 'absolute',
|
|
672
|
-
left: isHorizontal(direction)
|
|
673
|
-
|
|
674
|
-
? 100 - normalizeValue(item.at, min, max, skew) * 100
|
|
675
|
-
: normalizeValue(item.at, min, max, skew) * 100}%`
|
|
676
|
-
: undefined,
|
|
677
|
-
top: isVertical(direction)
|
|
678
|
-
? `${isReversed(direction)
|
|
679
|
-
? 100 - normalizeValue(item.at, min, max, skew) * 100
|
|
680
|
-
: normalizeValue(item.at, min, max, skew) * 100}%`
|
|
681
|
-
: undefined,
|
|
783
|
+
left: isHorizontal(direction) ? `${calcPercent(item.at)}%` : undefined,
|
|
784
|
+
top: isVertical(direction) ? `${calcPercent(item.at)}%` : undefined,
|
|
682
785
|
translate: isHorizontal(direction) ? '-50% 0' : '0 -50%',
|
|
683
786
|
zIndex: 10,
|
|
684
|
-
}), children: [((_b = (_a = item.type) !== null && _a !==
|
|
787
|
+
}), children: [((_b = (_a = item.type) !== null && _a !== undefined ? _a : scaleOption === null || scaleOption === undefined ? undefined : scaleOption.defaultType) !== null && _b !== undefined ? _b : 'mark-number') !=
|
|
685
788
|
'number' && (jsx("div", { className: "tremolo-slider-scale-mark", css: css({
|
|
686
789
|
width: isHorizontal(direction)
|
|
687
|
-
? ((_d = (_c = item.style) === null || _c ===
|
|
688
|
-
: ((_f = (_e = item.style) === null || _e ===
|
|
790
|
+
? ((_d = (_c = item.style) === null || _c === undefined ? undefined : _c.thickness) !== null && _d !== undefined ? _d : 1)
|
|
791
|
+
: ((_f = (_e = item.style) === null || _e === undefined ? undefined : _e.length) !== null && _f !== undefined ? _f : '0.5rem'),
|
|
689
792
|
height: isVertical(direction)
|
|
690
|
-
? ((_h = (_g = item.style) === null || _g ===
|
|
691
|
-
: ((_k = (_j = item.style) === null || _j ===
|
|
692
|
-
backgroundColor: (_o = (_m = (_l = item.style) === null || _l ===
|
|
793
|
+
? ((_h = (_g = item.style) === null || _g === undefined ? undefined : _g.thickness) !== null && _h !== undefined ? _h : 1)
|
|
794
|
+
: ((_k = (_j = item.style) === null || _j === undefined ? undefined : _j.length) !== null && _k !== undefined ? _k : '0.5rem'),
|
|
795
|
+
backgroundColor: (_o = (_m = (_l = item.style) === null || _l === undefined ? undefined : _l.markColor) !== null && _m !== undefined ? _m : scaleOption === null || scaleOption === undefined ? undefined : scaleOption.markColor) !== null && _o !== undefined ? _o : '#222',
|
|
693
796
|
marginBottom: isHorizontal(direction) ? 2 : undefined,
|
|
694
797
|
marginRight: isVertical(direction) ? 2 : undefined,
|
|
695
|
-
}) })), ((_q = (_p = item.type) !== null && _p !==
|
|
798
|
+
}) })), ((_q = (_p = item.type) !== null && _p !== undefined ? _p : scaleOption === null || scaleOption === undefined ? undefined : scaleOption.defaultType) !== null && _q !== undefined ? _q : 'mark-number') !=
|
|
696
799
|
'mark' && (jsx("div", { className: "tremolo-slider-scale-number", css: css({
|
|
697
|
-
color: (_s = (_r = item.style) === null || _r ===
|
|
698
|
-
width: scaleOption === null || scaleOption ===
|
|
800
|
+
color: (_s = (_r = item.style) === null || _r === undefined ? undefined : _r.labelColor) !== null && _s !== undefined ? _s : scaleOption === null || scaleOption === undefined ? undefined : scaleOption.labelColor,
|
|
801
|
+
width: scaleOption === null || scaleOption === undefined ? undefined : scaleOption.labelWidth,
|
|
699
802
|
textAlign: 'right',
|
|
700
|
-
}), children: (_t = item.text) !== null && _t !==
|
|
803
|
+
}), children: (_t = item.text) !== null && _t !== undefined ? _t : item.at }))] }, index));
|
|
701
804
|
}) }))] })] }));
|
|
702
|
-
}
|
|
805
|
+
});
|
|
703
806
|
|
|
704
807
|
export { AnimationCanvas, Knob, NumberInput, Slider, SliderThumb, SliderTrack, gradientDirection };
|
|
705
808
|
//# sourceMappingURL=index.js.map
|