@tremolo-ui/react 0.0.12 → 0.1.0-alpha.0
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 +316 -232
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/Knob/index.d.ts +12 -0
- package/dist/cjs/types/components/Knob/index.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/KeyLabel.d.ts +1 -3
- package/dist/cjs/types/components/Piano/KeyLabel.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/context.d.ts +24 -0
- package/dist/cjs/types/components/Piano/context.d.ts.map +1 -0
- package/dist/cjs/types/components/Piano/index.d.ts +9 -9
- package/dist/cjs/types/components/Piano/index.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/key.d.ts +10 -19
- package/dist/cjs/types/components/Piano/key.d.ts.map +1 -1
- package/dist/cjs/types/components/Slider/index.d.ts.map +1 -1
- package/dist/cjs/types/components/XYPad/index.d.ts.map +1 -1
- package/dist/cjs/types/hooks/useDrag.d.ts.map +1 -1
- package/dist/cjs/types/hooks/useDragWithElement.d.ts +16 -0
- package/dist/cjs/types/hooks/useDragWithElement.d.ts.map +1 -0
- package/dist/esm/index.js +316 -233
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/Knob/index.d.ts +12 -0
- package/dist/esm/types/components/Knob/index.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/KeyLabel.d.ts +1 -3
- package/dist/esm/types/components/Piano/KeyLabel.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/context.d.ts +24 -0
- package/dist/esm/types/components/Piano/context.d.ts.map +1 -0
- package/dist/esm/types/components/Piano/index.d.ts +9 -9
- package/dist/esm/types/components/Piano/index.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/key.d.ts +10 -19
- package/dist/esm/types/components/Piano/key.d.ts.map +1 -1
- package/dist/esm/types/components/Slider/index.d.ts.map +1 -1
- package/dist/esm/types/components/XYPad/index.d.ts.map +1 -1
- package/dist/esm/types/hooks/useDrag.d.ts.map +1 -1
- package/dist/esm/types/hooks/useDragWithElement.d.ts +16 -0
- package/dist/esm/types/hooks/useDragWithElement.d.ts.map +1 -0
- package/dist/styles/index.css +2 -0
- package/package.json +2 -1
- package/src/components/Knob/index.tsx +14 -0
- package/src/components/Piano/KeyLabel.tsx +9 -5
- package/src/components/Piano/context.tsx +108 -0
- package/src/components/Piano/index.css +2 -0
- package/src/components/Piano/index.tsx +186 -114
- package/src/components/Piano/key.tsx +215 -0
- package/src/components/Slider/index.tsx +40 -52
- package/src/components/XYPad/index.tsx +64 -54
- package/src/hooks/useDrag.ts +6 -7
- package/src/hooks/useDragWithElement.ts +76 -0
- package/dist/cjs/types/components/Piano/BlackKey.d.ts +0 -5
- package/dist/cjs/types/components/Piano/BlackKey.d.ts.map +0 -1
- package/dist/cjs/types/components/Piano/WhiteKey.d.ts +0 -7
- package/dist/cjs/types/components/Piano/WhiteKey.d.ts.map +0 -1
- package/dist/esm/types/components/Piano/BlackKey.d.ts +0 -5
- package/dist/esm/types/components/Piano/BlackKey.d.ts.map +0 -1
- package/dist/esm/types/components/Piano/WhiteKey.d.ts +0 -7
- package/dist/esm/types/components/Piano/WhiteKey.d.ts.map +0 -1
- package/src/components/Piano/BlackKey.tsx +0 -132
- package/src/components/Piano/WhiteKey.tsx +0 -134
- package/src/components/Piano/key.ts +0 -51
package/dist/cjs/index.js
CHANGED
|
@@ -321,6 +321,13 @@ function isWhiteKey(note) {
|
|
|
321
321
|
mod(n, 12) == 9 ||
|
|
322
322
|
mod(n, 12) == 11);
|
|
323
323
|
}
|
|
324
|
+
/**
|
|
325
|
+
* @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'
|
|
326
|
+
* @category MIDI
|
|
327
|
+
*/
|
|
328
|
+
function isBlackKey(note) {
|
|
329
|
+
return !isWhiteKey(note);
|
|
330
|
+
}
|
|
324
331
|
|
|
325
332
|
/**
|
|
326
333
|
* This hook is user-land implementation of the experimental `useEffectEvent` hook.
|
|
@@ -401,8 +408,7 @@ function useDrag({ threshold = 1, onDrag, onDragStart, onDragEnd, }) {
|
|
|
401
408
|
}
|
|
402
409
|
if (Math.abs(deltaX) < threshold && Math.abs(deltaY) < threshold)
|
|
403
410
|
return;
|
|
404
|
-
|
|
405
|
-
onDrag(screenX - dragStartX.current, screenY - dragStartY.current, deltaX, deltaY);
|
|
411
|
+
onDrag(screenX - dragStartX.current, screenY - dragStartY.current, deltaX, deltaY);
|
|
406
412
|
}, [threshold, onDrag]);
|
|
407
413
|
const refHandler = useRefCallbackEvent('touchmove', handleDrag, { passive: false }, [onDrag]);
|
|
408
414
|
const pointerDownHandler = React.useCallback((event) => {
|
|
@@ -669,7 +675,7 @@ const Knob = React.forwardRef((_a, ref) => {
|
|
|
669
675
|
elmRef.current = div;
|
|
670
676
|
wheelRefCallback(div);
|
|
671
677
|
touchMoveRefCallback(div);
|
|
672
|
-
}, width: size, height: size, tabIndex: 0, "aria-valuenow": value, "aria-valuemin": min, "aria-valuemax": max, "aria-disabled": disabled, "aria-readonly": readonly, onPointerDown: (event) => {
|
|
678
|
+
}, width: size, height: size, tabIndex: 0, role: "slider", "aria-valuenow": value, "aria-valuemin": min, "aria-valuemax": max, "aria-disabled": disabled, "aria-readonly": readonly, onPointerDown: (event) => {
|
|
673
679
|
pointerDownHandler(event);
|
|
674
680
|
onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(event);
|
|
675
681
|
}, onDoubleClick: (event) => {
|
|
@@ -1059,21 +1065,73 @@ const NumberInput = React.forwardRef((_a, ref) => {
|
|
|
1059
1065
|
tabIndex: 0, style: Object.assign({}, colors), "data-stepper": !!children, "data-variant": variant, children: [jsxRuntime.jsx(InternalInput, Object.assign({ ref: ref, readonly: readonly, disabled: disabled, selectWithFocus: selectWithFocus, blurOnEnter: blurOnEnter, clampValueOnBlur: clampValueOnBlur, wheel: wheel, keyboard: keyboard, className: className, onChange: onChange, onFocus: onFocus, onBlur: onBlur }, props)), children] }) }));
|
|
1060
1066
|
});
|
|
1061
1067
|
|
|
1068
|
+
/**
|
|
1069
|
+
* @returns [refCallback, pointerDownHandler]
|
|
1070
|
+
*/
|
|
1071
|
+
function useDragWithElement({ baseElementRef, onDrag, onDragStart, onDragEnd, }) {
|
|
1072
|
+
const dragged = React.useRef(false);
|
|
1073
|
+
const normalizedX = React.useRef(0);
|
|
1074
|
+
const normalizedY = React.useRef(0);
|
|
1075
|
+
const handleDrag = React.useCallback((event) => {
|
|
1076
|
+
if (!baseElementRef.current || !dragged.current) {
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
const isTouch = event instanceof TouchEvent;
|
|
1080
|
+
if (isTouch && event.cancelable)
|
|
1081
|
+
event.preventDefault();
|
|
1082
|
+
const { left, top, right, bottom } = baseElementRef.current.getBoundingClientRect();
|
|
1083
|
+
const mouseX = isTouch ? event.touches[0].clientX : event.clientX;
|
|
1084
|
+
const mouseY = isTouch ? event.touches[0].clientY : event.clientY;
|
|
1085
|
+
const nx = normalizeValue(mouseX, left, right);
|
|
1086
|
+
const ny = normalizeValue(mouseY, top, bottom);
|
|
1087
|
+
normalizedX.current = nx;
|
|
1088
|
+
normalizedY.current = ny;
|
|
1089
|
+
onDrag(nx, ny);
|
|
1090
|
+
}, [onDrag, baseElementRef]);
|
|
1091
|
+
const refHandler = useRefCallbackEvent('touchmove', handleDrag, { passive: false }, [onDrag]);
|
|
1092
|
+
const pointerDownHandler = React.useCallback((event) => {
|
|
1093
|
+
dragged.current = true;
|
|
1094
|
+
handleDrag(event);
|
|
1095
|
+
onDragStart === null || onDragStart === void 0 ? void 0 : onDragStart(normalizedX.current, normalizedY.current);
|
|
1096
|
+
}, [handleDrag, onDragStart]);
|
|
1097
|
+
useEventListener(globalThis.window, 'pointermove', handleDrag);
|
|
1098
|
+
useEventListener(globalThis.window, 'pointerup', () => {
|
|
1099
|
+
if (!dragged.current)
|
|
1100
|
+
return;
|
|
1101
|
+
dragged.current = false;
|
|
1102
|
+
onDragEnd === null || onDragEnd === void 0 ? void 0 : onDragEnd(normalizedX.current, normalizedY.current);
|
|
1103
|
+
});
|
|
1104
|
+
return [refHandler, pointerDownHandler];
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1062
1107
|
/** @category Piano */
|
|
1063
1108
|
function KeyLabel(_a) {
|
|
1064
|
-
var { label, className, wrapperClassName, wrapperStyle, __note,
|
|
1109
|
+
var { label, className, wrapperClassName, wrapperStyle, __note, __label } = _a, props = __rest(_a, ["label", "className", "wrapperClassName", "wrapperStyle", "__note", "__label"]);
|
|
1110
|
+
const noteRange = usePianoContext((s) => s.noteRange);
|
|
1111
|
+
const noteRangeArray = getNoteRangeArray(noteRange);
|
|
1112
|
+
const index = noteRangeArray.indexOf(__note);
|
|
1065
1113
|
const content = label
|
|
1066
|
-
? label(__note,
|
|
1067
|
-
: __label && __label(__note,
|
|
1114
|
+
? label(__note, index)
|
|
1115
|
+
: __label && __label(__note, index);
|
|
1068
1116
|
return ((content != undefined || content != null) && (jsxRuntime.jsx("div", { className: clsx('tremolo-piano-key-label-wrapper', wrapperClassName), style: wrapperStyle, children: jsxRuntime.jsx("div", Object.assign({ className: clsx('tremolo-piano-key-label', className) }, props, { children: content })) })));
|
|
1069
1117
|
}
|
|
1070
1118
|
|
|
1071
1119
|
/** @category Piano */
|
|
1072
1120
|
const defaultWhiteKeyWidth = 40;
|
|
1073
1121
|
/** @category Piano */
|
|
1074
|
-
const
|
|
1075
|
-
|
|
1122
|
+
const defaultBlackKeyWidth = 26;
|
|
1123
|
+
const KeyImpl = React.forwardRef((_a, ref) => {
|
|
1124
|
+
var { keyType, noteNumber, width, height, bg, color, activeBg, activeColor, className, style, children, __width } = _a, props = __rest(_a, ["keyType", "noteNumber", "width", "height", "bg", "color", "activeBg", "activeColor", "className", "style", "children", "__width"]);
|
|
1076
1125
|
const [played, setPlayed] = React.useState(false);
|
|
1126
|
+
const midiMax = usePianoContext((s) => s.midiMax);
|
|
1127
|
+
const fill = usePianoContext((s) => s.fill);
|
|
1128
|
+
// const glissando = usePianoContext(s => s.glissando)
|
|
1129
|
+
const onPlayNote = usePianoContext((s) => s.onPlayNote);
|
|
1130
|
+
const onStopNote = usePianoContext((s) => s.onStopNote);
|
|
1131
|
+
const label = usePianoContext((s) => s.label);
|
|
1132
|
+
const notePosition = usePianoContext((s) => s.notePosition);
|
|
1133
|
+
const position = notePosition(noteNumber);
|
|
1134
|
+
const disabled = noteNumber > midiMax;
|
|
1077
1135
|
const colors = {
|
|
1078
1136
|
'--bg': bg,
|
|
1079
1137
|
'--color': color,
|
|
@@ -1083,22 +1141,22 @@ const WhiteKey = React.forwardRef((_a, ref) => {
|
|
|
1083
1141
|
React.useImperativeHandle(ref, () => {
|
|
1084
1142
|
return {
|
|
1085
1143
|
play() {
|
|
1086
|
-
if (
|
|
1144
|
+
if (disabled)
|
|
1087
1145
|
return;
|
|
1088
1146
|
setPlayed(true);
|
|
1089
|
-
if (
|
|
1090
|
-
|
|
1147
|
+
if (onPlayNote)
|
|
1148
|
+
onPlayNote(noteNumber);
|
|
1091
1149
|
},
|
|
1092
1150
|
stop() {
|
|
1093
1151
|
setPlayed(false);
|
|
1094
|
-
if (
|
|
1095
|
-
|
|
1152
|
+
if (onStopNote)
|
|
1153
|
+
onStopNote(noteNumber);
|
|
1096
1154
|
},
|
|
1097
1155
|
played() {
|
|
1098
1156
|
return played;
|
|
1099
1157
|
},
|
|
1100
1158
|
};
|
|
1101
|
-
}, [
|
|
1159
|
+
}, [disabled, noteNumber, onPlayNote, onStopNote, played]);
|
|
1102
1160
|
let keyLabelProps = {};
|
|
1103
1161
|
if (children != undefined) {
|
|
1104
1162
|
React.Children.forEach(children, (child) => {
|
|
@@ -1115,112 +1173,82 @@ const WhiteKey = React.forwardRef((_a, ref) => {
|
|
|
1115
1173
|
}
|
|
1116
1174
|
});
|
|
1117
1175
|
}
|
|
1118
|
-
return (jsxRuntime.jsx("div", Object.assign({ className: clsx(`tremolo-piano-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
}, onPointerEnter: () => {
|
|
1125
|
-
if (__disabled)
|
|
1126
|
-
return;
|
|
1127
|
-
if (__glissando) {
|
|
1128
|
-
setPlayed(true);
|
|
1129
|
-
if (__onPlayNote)
|
|
1130
|
-
__onPlayNote(__note);
|
|
1131
|
-
}
|
|
1132
|
-
}, onPointerUp: () => {
|
|
1133
|
-
if (__disabled)
|
|
1134
|
-
return;
|
|
1135
|
-
setPlayed(false);
|
|
1136
|
-
if (__onStopNote)
|
|
1137
|
-
__onStopNote(__note);
|
|
1138
|
-
}, onPointerLeave: () => {
|
|
1139
|
-
if (__disabled)
|
|
1140
|
-
return;
|
|
1141
|
-
if (__glissando) {
|
|
1142
|
-
setPlayed(false);
|
|
1143
|
-
if (__onStopNote)
|
|
1144
|
-
__onStopNote(__note);
|
|
1145
|
-
}
|
|
1146
|
-
}, onContextMenu: onContextMenu }, props, { children: jsxRuntime.jsx(KeyLabel, Object.assign({ __note: __note, __label: __label, __index: __index }, keyLabelProps)) })));
|
|
1176
|
+
return (jsxRuntime.jsx("div", Object.assign({ className: clsx(`tremolo-piano-${keyType}-key`, className), "aria-disabled": disabled, "data-active": played, style: Object.assign(Object.assign(Object.assign({}, colors), { left: position, width: fill ? __width : width, height: height }), style) }, props, { children: jsxRuntime.jsx(KeyLabel, Object.assign({ label: label, __note: noteNumber }, keyLabelProps)) })));
|
|
1177
|
+
});
|
|
1178
|
+
/** @category Piano */
|
|
1179
|
+
const WhiteKey = React.forwardRef((_a, ref) => {
|
|
1180
|
+
var { width = defaultWhiteKeyWidth, height = '100%', onContextMenu = (e) => e.preventDefault() } = _a, props = __rest(_a, ["width", "height", "onContextMenu"]);
|
|
1181
|
+
return (jsxRuntime.jsx(KeyImpl, Object.assign({ ref: ref, keyType: "white", width: width, height: height, onContextMenu: onContextMenu }, props)));
|
|
1147
1182
|
});
|
|
1148
|
-
|
|
1149
1183
|
/** @category Piano */
|
|
1150
1184
|
const BlackKey = React.forwardRef((_a, ref) => {
|
|
1151
|
-
var { width =
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1185
|
+
var { width = defaultBlackKeyWidth, height = '60%', onContextMenu = (e) => e.preventDefault() } = _a, props = __rest(_a, ["width", "height", "onContextMenu"]);
|
|
1186
|
+
return (jsxRuntime.jsx(KeyImpl, Object.assign({ ref: ref, keyType: "black", width: width, height: height, onContextMenu: onContextMenu }, props)));
|
|
1187
|
+
});
|
|
1188
|
+
|
|
1189
|
+
const createPianoStore = (initProps) => {
|
|
1190
|
+
const noteRange = (initProps === null || initProps === void 0 ? void 0 : initProps.noteRange) || { first: 0};
|
|
1191
|
+
const DEFAULT_PROPS = {
|
|
1192
|
+
noteRange: { first: 0, last: 127 },
|
|
1193
|
+
glissando: true,
|
|
1194
|
+
midiMax: 127,
|
|
1195
|
+
fill: false,
|
|
1196
|
+
label: () => undefined,
|
|
1197
|
+
onPlayNote: () => { },
|
|
1198
|
+
onStopNote: () => { },
|
|
1158
1199
|
};
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1200
|
+
return createStore()(() => (Object.assign(Object.assign(Object.assign({}, DEFAULT_PROPS), initProps), { notePosition: (note) => {
|
|
1201
|
+
const pitchPositions = {
|
|
1202
|
+
C: 0,
|
|
1203
|
+
'C#': 1,
|
|
1204
|
+
D: 1,
|
|
1205
|
+
'D#': 2,
|
|
1206
|
+
E: 2,
|
|
1207
|
+
F: 3,
|
|
1208
|
+
'F#': 4,
|
|
1209
|
+
G: 4,
|
|
1210
|
+
'G#': 5,
|
|
1211
|
+
A: 5,
|
|
1212
|
+
'A#': 6,
|
|
1213
|
+
B: 6,
|
|
1214
|
+
};
|
|
1215
|
+
const whiteNoteWidth = defaultWhiteKeyWidth;
|
|
1216
|
+
const blackNoteWidth = defaultBlackKeyWidth;
|
|
1217
|
+
const padding = 1;
|
|
1218
|
+
const targetNoteKey = noteKey(note);
|
|
1219
|
+
const firstNoteKey = noteKey(noteRange.first);
|
|
1220
|
+
const octave = Math.floor((note - noteRange.first) / 12);
|
|
1221
|
+
const octaveOffset = noteKeys.indexOf(firstNoteKey) > noteKeys.indexOf(targetNoteKey) ? 1 : 0;
|
|
1222
|
+
const w = whiteNoteWidth + padding;
|
|
1223
|
+
const pos = pitchPositions[targetNoteKey] - pitchPositions[firstNoteKey];
|
|
1224
|
+
const blackKeyOffset = isBlackKey(note) ? blackNoteWidth / 2 : 0;
|
|
1225
|
+
return pos * w + (octave + octaveOffset) * 7 * w - blackKeyOffset;
|
|
1226
|
+
} })));
|
|
1227
|
+
};
|
|
1228
|
+
const PianoContext = React.createContext(null);
|
|
1229
|
+
function PianoProvider(_a) {
|
|
1230
|
+
var { children } = _a, props = __rest(_a, ["children"]);
|
|
1231
|
+
const storeRef = React.useRef(null);
|
|
1232
|
+
if (!storeRef.current) {
|
|
1233
|
+
storeRef.current = createPianoStore(props);
|
|
1193
1234
|
}
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
}
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
setPlayed(false);
|
|
1212
|
-
if (__onStopNote)
|
|
1213
|
-
__onStopNote(__note);
|
|
1214
|
-
}, onPointerLeave: () => {
|
|
1215
|
-
if (__disabled)
|
|
1216
|
-
return;
|
|
1217
|
-
if (__glissando) {
|
|
1218
|
-
setPlayed(false);
|
|
1219
|
-
if (__onStopNote)
|
|
1220
|
-
__onStopNote(__note);
|
|
1221
|
-
}
|
|
1222
|
-
}, onContextMenu: onContextMenu }, props, { children: jsxRuntime.jsx(KeyLabel, Object.assign({ __note: __note, __label: __label, __index: __index }, keyLabelProps)) })));
|
|
1223
|
-
});
|
|
1235
|
+
React.useEffect(() => {
|
|
1236
|
+
if (storeRef.current) {
|
|
1237
|
+
storeRef.current.setState(props);
|
|
1238
|
+
}
|
|
1239
|
+
else {
|
|
1240
|
+
storeRef.current = createPianoStore(props);
|
|
1241
|
+
}
|
|
1242
|
+
}, [props]);
|
|
1243
|
+
return (jsxRuntime.jsx(PianoContext.Provider, { value: storeRef.current, children: children }));
|
|
1244
|
+
}
|
|
1245
|
+
/** @category Piano */
|
|
1246
|
+
function usePianoContext(selector) {
|
|
1247
|
+
const store = React.useContext(PianoContext);
|
|
1248
|
+
if (!store)
|
|
1249
|
+
throw new Error('Missing PianoContext.Provider in the tree');
|
|
1250
|
+
return useStore(store, selector);
|
|
1251
|
+
}
|
|
1224
1252
|
|
|
1225
1253
|
/** @category Piano */
|
|
1226
1254
|
const SHORTCUTS = {
|
|
@@ -1247,66 +1275,121 @@ const SHORTCUTS = {
|
|
|
1247
1275
|
},
|
|
1248
1276
|
};
|
|
1249
1277
|
|
|
1278
|
+
/**
|
|
1279
|
+
* Piano component
|
|
1280
|
+
*
|
|
1281
|
+
* TODO:
|
|
1282
|
+
* - add scale highlight
|
|
1283
|
+
*/
|
|
1284
|
+
/** @category Piano */
|
|
1285
|
+
function getNoteRangeArray(noteRange) {
|
|
1286
|
+
return Array.from({ length: noteRange.last - noteRange.first + 1 }, (_, i) => i + noteRange.first);
|
|
1287
|
+
}
|
|
1250
1288
|
/**
|
|
1251
1289
|
* Customizable piano component.
|
|
1252
1290
|
* @category Piano
|
|
1253
1291
|
*/
|
|
1254
1292
|
function Piano(_a) {
|
|
1255
|
-
var { noteRange, glissando = true, midiMax = 127, keyboardShortcuts, fill = false, height = fill ? '100%' : 160, style, className, onPlayNote, onStopNote, label, children,
|
|
1293
|
+
var { noteRange, glissando = true, midiMax = 127, keyboardShortcuts, fill = false, height = fill ? '100%' : 160, whiteNoteWidth: _whiteNoteWidth = defaultWhiteKeyWidth, style, className, onPlayNote, onStopNote, label, children, onPointerDown } = _a, props = __rest(_a, ["noteRange", "glissando", "midiMax", "keyboardShortcuts", "fill", "height", "whiteNoteWidth", "style", "className", "onPlayNote", "onStopNote", "label", "children", "onPointerDown"]);
|
|
1256
1294
|
// -- state and ref ---
|
|
1257
|
-
const [
|
|
1258
|
-
const [whiteNoteWidth, setWhiteNoteWidth] = React.useState(-1);
|
|
1295
|
+
const [whiteNoteWidth, setWhiteNoteWidth] = React.useState(_whiteNoteWidth);
|
|
1259
1296
|
const keyRefs = React.useRef([]);
|
|
1260
1297
|
for (let i = 0; i < noteRange.last - noteRange.first + 1; i++) {
|
|
1261
1298
|
keyRefs.current[i] = React.createRef();
|
|
1262
1299
|
}
|
|
1263
1300
|
const pianoRef = React.useRef(null);
|
|
1301
|
+
const hitKeyIndex = React.useRef(-1);
|
|
1264
1302
|
// --- interpret props ---
|
|
1265
|
-
const noteRangeArray =
|
|
1266
|
-
const
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1303
|
+
const noteRangeArray = getNoteRangeArray(noteRange);
|
|
1304
|
+
const whiteNotes = noteRangeArray.filter((v) => isWhiteKey(v));
|
|
1305
|
+
const blackNotes = noteRangeArray.filter((v) => isBlackKey(v));
|
|
1306
|
+
const whiteNoteCount = whiteNotes.length;
|
|
1307
|
+
const padding = 1;
|
|
1308
|
+
const staticWidth = (whiteNoteWidth + padding) * whiteNoteCount;
|
|
1309
|
+
// const blackNoteShiftPercent = 0.3
|
|
1310
|
+
// TODO: if fill setWhiteNoteWidth
|
|
1311
|
+
// useMemo
|
|
1312
|
+
// __width
|
|
1313
|
+
const childrenWithProps = React.useMemo(() => {
|
|
1314
|
+
return (children &&
|
|
1315
|
+
React.Children.map(children, (child, index) => {
|
|
1316
|
+
if (React.isValidElement(child)) {
|
|
1317
|
+
const props = { ref: keyRefs.current[index] };
|
|
1318
|
+
return React.cloneElement(child, props);
|
|
1279
1319
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
}
|
|
1284
|
-
});
|
|
1285
|
-
}
|
|
1320
|
+
return child;
|
|
1321
|
+
}));
|
|
1322
|
+
}, [children]);
|
|
1286
1323
|
// --- internal functions ---
|
|
1287
|
-
|
|
1324
|
+
const notePosition = React.useCallback((note) => {
|
|
1288
1325
|
const pitchPositions = {
|
|
1289
1326
|
C: 0,
|
|
1290
|
-
'C#':
|
|
1327
|
+
'C#': 1,
|
|
1291
1328
|
D: 1,
|
|
1292
|
-
'D#':
|
|
1329
|
+
'D#': 2,
|
|
1293
1330
|
E: 2,
|
|
1294
1331
|
F: 3,
|
|
1295
|
-
'F#':
|
|
1332
|
+
'F#': 4,
|
|
1296
1333
|
G: 4,
|
|
1297
|
-
'G#':
|
|
1334
|
+
'G#': 5,
|
|
1298
1335
|
A: 5,
|
|
1299
|
-
'A#':
|
|
1336
|
+
'A#': 6,
|
|
1300
1337
|
B: 6,
|
|
1301
1338
|
};
|
|
1339
|
+
const whiteNoteWidth = defaultWhiteKeyWidth;
|
|
1340
|
+
const blackNoteWidth = defaultBlackKeyWidth;
|
|
1341
|
+
const padding = 1;
|
|
1302
1342
|
const targetNoteKey = noteKey(note);
|
|
1303
1343
|
const firstNoteKey = noteKey(noteRange.first);
|
|
1304
|
-
const pos = pitchPositions[targetNoteKey] - pitchPositions[firstNoteKey];
|
|
1305
1344
|
const octave = Math.floor((note - noteRange.first) / 12);
|
|
1306
1345
|
const octaveOffset = noteKeys.indexOf(firstNoteKey) > noteKeys.indexOf(targetNoteKey) ? 1 : 0;
|
|
1307
|
-
const
|
|
1308
|
-
|
|
1309
|
-
|
|
1346
|
+
const w = whiteNoteWidth + padding;
|
|
1347
|
+
const pos = pitchPositions[targetNoteKey] - pitchPositions[firstNoteKey];
|
|
1348
|
+
const blackKeyOffset = isBlackKey(note) ? blackNoteWidth / 2 : 0;
|
|
1349
|
+
return pos * w + (octave + octaveOffset) * 7 * w - blackKeyOffset;
|
|
1350
|
+
}, [noteRange.first]);
|
|
1351
|
+
const getHitKeyIndex = React.useCallback((x, y) => {
|
|
1352
|
+
if (!pianoRef.current)
|
|
1353
|
+
return -1;
|
|
1354
|
+
const containerHeight = pianoRef.current.clientHeight;
|
|
1355
|
+
const notes = [...blackNotes, ...whiteNotes];
|
|
1356
|
+
for (let i = 0; i < notes.length; i++) {
|
|
1357
|
+
const note = notes[i];
|
|
1358
|
+
const pos = notePosition(note);
|
|
1359
|
+
const w = isWhiteKey(note) ? defaultWhiteKeyWidth : defaultBlackKeyWidth;
|
|
1360
|
+
const h = isWhiteKey(note) ? containerHeight : containerHeight * 0.6;
|
|
1361
|
+
if (pos <= x && x < pos + w && 0 <= y && y < h) {
|
|
1362
|
+
return note;
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
return -1;
|
|
1366
|
+
}, [blackNotes, notePosition, whiteNotes]);
|
|
1367
|
+
// TODO: 単一のポインターに対しては、useDragで対応可能だが、
|
|
1368
|
+
// マルチタッチに対しては、TouchEventを使う必要がありそう
|
|
1369
|
+
// 取り敢えず、シングルタッチだけ対応
|
|
1370
|
+
const onDrag = React.useCallback((perX, perY) => {
|
|
1371
|
+
var _a, _b, _c, _d;
|
|
1372
|
+
if (!pianoRef.current)
|
|
1373
|
+
return;
|
|
1374
|
+
const x = perX * staticWidth;
|
|
1375
|
+
const y = perY * pianoRef.current.clientHeight;
|
|
1376
|
+
const note = getHitKeyIndex(x, y);
|
|
1377
|
+
const index = noteRangeArray.indexOf(note);
|
|
1378
|
+
if (index == -1)
|
|
1379
|
+
return;
|
|
1380
|
+
if (hitKeyIndex.current != index) {
|
|
1381
|
+
(_b = (_a = keyRefs.current[hitKeyIndex.current]) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.stop();
|
|
1382
|
+
(_d = (_c = keyRefs.current[index]) === null || _c === void 0 ? void 0 : _c.current) === null || _d === void 0 ? void 0 : _d.play();
|
|
1383
|
+
hitKeyIndex.current = index;
|
|
1384
|
+
}
|
|
1385
|
+
}, [getHitKeyIndex, noteRangeArray, staticWidth]);
|
|
1386
|
+
const onDragEnd = React.useCallback(() => {
|
|
1387
|
+
var _a, _b, _c, _d;
|
|
1388
|
+
if ((_b = (_a = keyRefs.current[hitKeyIndex.current]) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.played()) {
|
|
1389
|
+
(_d = (_c = keyRefs.current[hitKeyIndex.current]) === null || _c === void 0 ? void 0 : _c.current) === null || _d === void 0 ? void 0 : _d.stop();
|
|
1390
|
+
}
|
|
1391
|
+
hitKeyIndex.current = -1;
|
|
1392
|
+
}, [keyRefs]);
|
|
1310
1393
|
// --- hooks ---
|
|
1311
1394
|
React.useEffect(() => {
|
|
1312
1395
|
if (fill && pianoRef.current) {
|
|
@@ -1315,7 +1398,7 @@ function Piano(_a) {
|
|
|
1315
1398
|
throw new Error("doesn't have a parent element.");
|
|
1316
1399
|
const resizeObserver = new ResizeObserver(() => {
|
|
1317
1400
|
const w = pianoRef.current.clientWidth;
|
|
1318
|
-
setWhiteNoteWidth(w / whiteNoteCount -
|
|
1401
|
+
setWhiteNoteWidth(w / whiteNoteCount - padding);
|
|
1319
1402
|
});
|
|
1320
1403
|
resizeObserver.observe(parent);
|
|
1321
1404
|
return () => {
|
|
@@ -1323,9 +1406,14 @@ function Piano(_a) {
|
|
|
1323
1406
|
};
|
|
1324
1407
|
}
|
|
1325
1408
|
else {
|
|
1326
|
-
setWhiteNoteWidth(
|
|
1409
|
+
setWhiteNoteWidth(_whiteNoteWidth);
|
|
1327
1410
|
}
|
|
1328
|
-
}, [fill,
|
|
1411
|
+
}, [fill, _whiteNoteWidth, whiteNoteCount]);
|
|
1412
|
+
const [touchMoveRefCallback, pointerDownHandler] = useDragWithElement({
|
|
1413
|
+
baseElementRef: pianoRef,
|
|
1414
|
+
onDrag: onDrag,
|
|
1415
|
+
onDragEnd: onDragEnd,
|
|
1416
|
+
});
|
|
1329
1417
|
useEventListener(globalThis.window, 'keydown', (e) => {
|
|
1330
1418
|
var _a, _b, _c, _d;
|
|
1331
1419
|
if (e.repeat)
|
|
@@ -1350,15 +1438,14 @@ function Piano(_a) {
|
|
|
1350
1438
|
(_b = (_a = keyRefs.current[index]) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.stop();
|
|
1351
1439
|
}
|
|
1352
1440
|
});
|
|
1353
|
-
return (jsxRuntime.jsx(
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
}) })));
|
|
1441
|
+
return (jsxRuntime.jsx(PianoProvider, { noteRange: noteRange, glissando: glissando, midiMax: midiMax, fill: fill, onPlayNote: onPlayNote, onStopNote: onStopNote, label: label, children: jsxRuntime.jsx("div", Object.assign({ ref: (div) => {
|
|
1442
|
+
pianoRef.current = div;
|
|
1443
|
+
touchMoveRefCallback(div);
|
|
1444
|
+
}, className: clsx('tremolo-piano', className), style: Object.assign({ width: fill ? '100%' : staticWidth, height: height }, style), onPointerDown: (event) => {
|
|
1445
|
+
pointerDownHandler(event);
|
|
1446
|
+
onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(event);
|
|
1447
|
+
} }, props, { children: childrenWithProps ||
|
|
1448
|
+
getNoteRangeArray(noteRange).map((note, index) => isWhiteKey(note) ? (jsxRuntime.jsx(WhiteKey, { ref: keyRefs.current[index], noteNumber: note }, note)) : (jsxRuntime.jsx(BlackKey, { ref: keyRefs.current[index], noteNumber: note }, note))) })) }));
|
|
1362
1449
|
}
|
|
1363
1450
|
|
|
1364
1451
|
const createSliderStore = (initProps) => {
|
|
@@ -1529,7 +1616,6 @@ const Slider = React.forwardRef((_a, ref) => {
|
|
|
1529
1616
|
// -- state and ref ---
|
|
1530
1617
|
const trackElementRef = React.useRef(null);
|
|
1531
1618
|
const thumbRef = React.useRef(null);
|
|
1532
|
-
const thumbDragged = React.useRef(false);
|
|
1533
1619
|
// --- interpret props ---
|
|
1534
1620
|
const p = toFixed$1(normalizeValue(value, min, max, skew) * 100);
|
|
1535
1621
|
const rev = toFixed$1(100 - p);
|
|
@@ -1565,29 +1651,14 @@ const Slider = React.forwardRef((_a, ref) => {
|
|
|
1565
1651
|
});
|
|
1566
1652
|
}
|
|
1567
1653
|
// --- internal functions ---
|
|
1568
|
-
const
|
|
1569
|
-
if (!
|
|
1570
|
-
!thumbDragged.current ||
|
|
1571
|
-
!onChange ||
|
|
1572
|
-
readonly) {
|
|
1654
|
+
const onDrag = React.useCallback((nx, ny) => {
|
|
1655
|
+
if (!onChange || readonly)
|
|
1573
1656
|
return;
|
|
1574
|
-
|
|
1575
|
-
const isTouch = event instanceof TouchEvent;
|
|
1576
|
-
if (isTouch && event.cancelable)
|
|
1577
|
-
event.preventDefault();
|
|
1578
|
-
if (bodyNoSelect)
|
|
1579
|
-
addNoSelect();
|
|
1580
|
-
const { left: x1, top: y1, right: x2, bottom: y2, } = trackElementRef.current.getBoundingClientRect();
|
|
1581
|
-
const mouseX = isTouch ? event.touches[0].clientX : event.clientX;
|
|
1582
|
-
const mouseY = isTouch ? event.touches[0].clientY : event.clientY;
|
|
1583
|
-
const n = vertical
|
|
1584
|
-
? normalizeValue(mouseY, y1, y2)
|
|
1585
|
-
: normalizeValue(mouseX, x1, x2);
|
|
1657
|
+
const n = vertical ? ny : nx;
|
|
1586
1658
|
const v = rawValue(displayReversed ? 1 - n : n, min, max, skew);
|
|
1587
1659
|
const v2 = clamp(stepValue(v, step), min, max);
|
|
1588
1660
|
onChange(v2);
|
|
1589
|
-
|
|
1590
|
-
};
|
|
1661
|
+
}, [displayReversed, max, min, onChange, readonly, skew, step, vertical]);
|
|
1591
1662
|
const updateValueByEvent = React.useCallback((eventType, x) => {
|
|
1592
1663
|
let newValue;
|
|
1593
1664
|
if (eventType == 'normalized') {
|
|
@@ -1612,7 +1683,26 @@ const Slider = React.forwardRef((_a, ref) => {
|
|
|
1612
1683
|
}
|
|
1613
1684
|
}, [keyboard, onChange, readonly, reverse, updateValueByEvent]);
|
|
1614
1685
|
// --- hooks ---
|
|
1615
|
-
const touchMoveRefCallback =
|
|
1686
|
+
const [touchMoveRefCallback, pointerDownHandler] = useDragWithElement({
|
|
1687
|
+
baseElementRef: trackElementRef,
|
|
1688
|
+
onDrag: onDrag,
|
|
1689
|
+
onDragStart: (nx, ny) => {
|
|
1690
|
+
var _a;
|
|
1691
|
+
if (readonly)
|
|
1692
|
+
return;
|
|
1693
|
+
if (bodyNoSelect)
|
|
1694
|
+
addNoSelect();
|
|
1695
|
+
(_a = thumbRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
1696
|
+
onDragStart === null || onDragStart === void 0 ? void 0 : onDragStart(clamp(stepValue(rawValue(vertical ? ny : nx, min, max, skew), step), min, max));
|
|
1697
|
+
},
|
|
1698
|
+
onDragEnd: (nx, ny) => {
|
|
1699
|
+
if (readonly)
|
|
1700
|
+
return;
|
|
1701
|
+
if (bodyNoSelect)
|
|
1702
|
+
removeNoSelect();
|
|
1703
|
+
onDragEnd === null || onDragEnd === void 0 ? void 0 : onDragEnd(clamp(stepValue(rawValue(vertical ? ny : nx, min, max, skew), step), min, max));
|
|
1704
|
+
},
|
|
1705
|
+
});
|
|
1616
1706
|
const wheelRefCallback = useRefCallbackEvent('wheel', (event) => {
|
|
1617
1707
|
if (!wheel || !onChange || readonly)
|
|
1618
1708
|
return;
|
|
@@ -1632,17 +1722,6 @@ const Slider = React.forwardRef((_a, ref) => {
|
|
|
1632
1722
|
}, {
|
|
1633
1723
|
passive: false,
|
|
1634
1724
|
}, [wheel, vertical, readonly, onChange, updateValueByEvent]);
|
|
1635
|
-
useEventListener(globalThis.window, 'mousemove', (event) => {
|
|
1636
|
-
handleValue(event);
|
|
1637
|
-
});
|
|
1638
|
-
useEventListener(globalThis.window, 'mouseup', () => {
|
|
1639
|
-
if (!thumbDragged.current || readonly)
|
|
1640
|
-
return;
|
|
1641
|
-
thumbDragged.current = false;
|
|
1642
|
-
onDragEnd === null || onDragEnd === void 0 ? void 0 : onDragEnd(value);
|
|
1643
|
-
if (bodyNoSelect)
|
|
1644
|
-
removeNoSelect();
|
|
1645
|
-
});
|
|
1646
1725
|
React.useImperativeHandle(ref, () => {
|
|
1647
1726
|
return {
|
|
1648
1727
|
focus() {
|
|
@@ -1659,10 +1738,7 @@ const Slider = React.forwardRef((_a, ref) => {
|
|
|
1659
1738
|
wheelRefCallback(div);
|
|
1660
1739
|
touchMoveRefCallback(div);
|
|
1661
1740
|
}, tabIndex: -1, role: "slider", "aria-valuenow": value, "aria-valuemin": min, "aria-valuemax": max, "aria-orientation": vertical ? 'vertical' : 'horizontal', "aria-disabled": disabled, "aria-readonly": readonly, style: Object.assign({ margin: `calc(${styleHelper((_b = thumbProps === null || thumbProps === void 0 ? void 0 : thumbProps.size) !== null && _b !== void 0 ? _b : 22)} / 2)` }, style), onPointerDown: (event) => {
|
|
1662
|
-
|
|
1663
|
-
const v = handleValue(event);
|
|
1664
|
-
if (!readonly)
|
|
1665
|
-
onDragStart === null || onDragStart === void 0 ? void 0 : onDragStart(v !== null && v !== void 0 ? v : value);
|
|
1741
|
+
pointerDownHandler(event);
|
|
1666
1742
|
onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(event);
|
|
1667
1743
|
}, onKeyDown: (event) => {
|
|
1668
1744
|
handleKeyDown(event);
|
|
@@ -1745,13 +1821,13 @@ const XYPad = React.forwardRef((_a, ref) => {
|
|
|
1745
1821
|
// -- state and ref ---
|
|
1746
1822
|
const areaElementRef = React.useRef(null);
|
|
1747
1823
|
const thumbRef = React.useRef(null);
|
|
1748
|
-
const thumbDragged = React.useRef(false);
|
|
1749
1824
|
// --- interpret props ---
|
|
1750
1825
|
const nx = normalizeValue(x.value, x.min, x.max, x.skew);
|
|
1751
1826
|
const ny = normalizeValue(y.value, y.min, y.max, y.skew);
|
|
1752
1827
|
const percentX = toFixed$1((x.reverse ? 1 - nx : nx) * 100);
|
|
1753
1828
|
const percentY = toFixed$1((y.reverse ? 1 - ny : ny) * 100);
|
|
1754
|
-
let areaProps = {}
|
|
1829
|
+
let areaProps = {};
|
|
1830
|
+
let thumbProps = {};
|
|
1755
1831
|
if (children != undefined) {
|
|
1756
1832
|
React.Children.forEach(children, (child) => {
|
|
1757
1833
|
if (React.isValidElement(child)) {
|
|
@@ -1771,29 +1847,28 @@ const XYPad = React.forwardRef((_a, ref) => {
|
|
|
1771
1847
|
});
|
|
1772
1848
|
}
|
|
1773
1849
|
// --- internal functions ---
|
|
1774
|
-
const
|
|
1775
|
-
if (!
|
|
1776
|
-
!thumbDragged.current ||
|
|
1777
|
-
!onChange ||
|
|
1778
|
-
readonly)
|
|
1850
|
+
const onDrag = React.useCallback((nx, ny) => {
|
|
1851
|
+
if (!onChange || readonly)
|
|
1779
1852
|
return;
|
|
1780
|
-
const isTouch = event instanceof TouchEvent;
|
|
1781
|
-
if (isTouch && event.cancelable)
|
|
1782
|
-
event.preventDefault();
|
|
1783
|
-
if (bodyNoSelect)
|
|
1784
|
-
addNoSelect();
|
|
1785
|
-
const { left: x1, top: y1, right: x2, bottom: y2, } = areaElementRef.current.getBoundingClientRect();
|
|
1786
|
-
const mouseX = isTouch ? event.touches[0].clientX : event.clientX;
|
|
1787
|
-
const mouseY = isTouch ? event.touches[0].clientY : event.clientY;
|
|
1788
|
-
const nx = normalizeValue(mouseX, x1, x2);
|
|
1789
|
-
const ny = normalizeValue(mouseY, y1, y2);
|
|
1790
1853
|
const vx = rawValue(x.reverse ? 1 - nx : nx, x.min, x.max, x.skew);
|
|
1791
1854
|
const vy = rawValue(y.reverse ? 1 - ny : ny, y.min, y.max, y.skew);
|
|
1792
1855
|
const newX = clamp(stepValue(vx, x.step), x.min, x.max);
|
|
1793
1856
|
const newY = clamp(stepValue(vy, y.step), y.min, y.max);
|
|
1794
1857
|
onChange(newX, newY);
|
|
1795
|
-
|
|
1796
|
-
|
|
1858
|
+
}, [
|
|
1859
|
+
onChange,
|
|
1860
|
+
readonly,
|
|
1861
|
+
x.max,
|
|
1862
|
+
x.min,
|
|
1863
|
+
x.reverse,
|
|
1864
|
+
x.skew,
|
|
1865
|
+
x.step,
|
|
1866
|
+
y.max,
|
|
1867
|
+
y.min,
|
|
1868
|
+
y.reverse,
|
|
1869
|
+
y.skew,
|
|
1870
|
+
y.step,
|
|
1871
|
+
]);
|
|
1797
1872
|
const updateValueByEvent = React.useCallback((eventType, target, x) => {
|
|
1798
1873
|
let v;
|
|
1799
1874
|
if (eventType == 'normalized') {
|
|
@@ -1830,7 +1905,30 @@ const XYPad = React.forwardRef((_a, ref) => {
|
|
|
1830
1905
|
}
|
|
1831
1906
|
}, [onChange, readonly, x, y, updateValueByEvent]);
|
|
1832
1907
|
// --- hooks ---
|
|
1833
|
-
const touchMoveRefCallback =
|
|
1908
|
+
const [touchMoveRefCallback, pointerDownHandler] = useDragWithElement({
|
|
1909
|
+
baseElementRef: areaElementRef,
|
|
1910
|
+
onDrag: onDrag,
|
|
1911
|
+
onDragStart: (nx, ny) => {
|
|
1912
|
+
var _a;
|
|
1913
|
+
if (readonly)
|
|
1914
|
+
return;
|
|
1915
|
+
if (bodyNoSelect)
|
|
1916
|
+
addNoSelect();
|
|
1917
|
+
(_a = thumbRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
1918
|
+
const valueX = clamp(stepValue(rawValue(nx, x.min, x.max, x.skew), x.step), x.min, x.max);
|
|
1919
|
+
const valueY = clamp(stepValue(rawValue(ny, y.min, y.max, y.skew), y.step), y.min, y.max);
|
|
1920
|
+
onDragStart === null || onDragStart === void 0 ? void 0 : onDragStart(valueX, valueY);
|
|
1921
|
+
},
|
|
1922
|
+
onDragEnd: (nx, ny) => {
|
|
1923
|
+
if (readonly)
|
|
1924
|
+
return;
|
|
1925
|
+
if (bodyNoSelect)
|
|
1926
|
+
removeNoSelect();
|
|
1927
|
+
const valueX = clamp(stepValue(rawValue(nx, x.min, x.max, x.skew), x.step), x.min, x.max);
|
|
1928
|
+
const valueY = clamp(stepValue(rawValue(ny, y.min, y.max, y.skew), y.step), y.min, y.max);
|
|
1929
|
+
onDragEnd === null || onDragEnd === void 0 ? void 0 : onDragEnd(valueX, valueY);
|
|
1930
|
+
},
|
|
1931
|
+
});
|
|
1834
1932
|
const wheelRefCallback = useRefCallbackEvent('wheel', (event) => {
|
|
1835
1933
|
if (!onChange || readonly)
|
|
1836
1934
|
return;
|
|
@@ -1853,17 +1951,6 @@ const XYPad = React.forwardRef((_a, ref) => {
|
|
|
1853
1951
|
}, {
|
|
1854
1952
|
passive: false,
|
|
1855
1953
|
}, [x, y, onChange, readonly, updateValueByEvent]);
|
|
1856
|
-
useEventListener(globalThis.window, 'mousemove', (event) => {
|
|
1857
|
-
handleValue(event);
|
|
1858
|
-
});
|
|
1859
|
-
useEventListener(globalThis.window, 'mouseup', () => {
|
|
1860
|
-
if (!thumbDragged.current || readonly)
|
|
1861
|
-
return;
|
|
1862
|
-
thumbDragged.current = false;
|
|
1863
|
-
onDragEnd === null || onDragEnd === void 0 ? void 0 : onDragEnd(x.value, y.value);
|
|
1864
|
-
if (bodyNoSelect)
|
|
1865
|
-
removeNoSelect();
|
|
1866
|
-
});
|
|
1867
1954
|
React.useImperativeHandle(ref, () => {
|
|
1868
1955
|
return {
|
|
1869
1956
|
focus() {
|
|
@@ -1882,11 +1969,7 @@ const XYPad = React.forwardRef((_a, ref) => {
|
|
|
1882
1969
|
wheelRefCallback(div);
|
|
1883
1970
|
touchMoveRefCallback(div);
|
|
1884
1971
|
}, tabIndex: -1, "aria-disabled": disabled, "aria-readonly": readonly, style: Object.assign({ margin: `calc(${styleHelper((_b = thumbProps === null || thumbProps === void 0 ? void 0 : thumbProps.size) !== null && _b !== void 0 ? _b : 22)} / 2)`, cursor: readonly ? 'not-allowed' : 'pointer', WebkitTapHighlightColor: 'transparent' }, style), onPointerDown: (event) => {
|
|
1885
|
-
|
|
1886
|
-
thumbDragged.current = true;
|
|
1887
|
-
const v = handleValue(event);
|
|
1888
|
-
if (!readonly)
|
|
1889
|
-
onDragStart === null || onDragStart === void 0 ? void 0 : onDragStart((_a = v === null || v === void 0 ? void 0 : v[0]) !== null && _a !== void 0 ? _a : x.value, (_b = v === null || v === void 0 ? void 0 : v[1]) !== null && _b !== void 0 ? _b : y.value);
|
|
1972
|
+
pointerDownHandler(event);
|
|
1890
1973
|
onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(event);
|
|
1891
1974
|
}, onKeyDown: (event) => {
|
|
1892
1975
|
handleKeyDown(event);
|
|
@@ -1940,6 +2023,7 @@ exports.WhiteKey = WhiteKey;
|
|
|
1940
2023
|
exports.XYPad = XYPad;
|
|
1941
2024
|
exports.XYPadArea = XYPadArea;
|
|
1942
2025
|
exports.XYPadThumb = XYPadThumb;
|
|
2026
|
+
exports.getNoteRangeArray = getNoteRangeArray;
|
|
1943
2027
|
exports.useAnimationFrame = useAnimationFrame;
|
|
1944
2028
|
exports.useDrag = useDrag;
|
|
1945
2029
|
exports.useEventListener = useEventListener;
|