@remotion/studio
Version:
APIs for interacting with the Remotion Studio
185 lines (184 loc) • 8.14 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.InputDragger = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = __importStar(require("react"));
const remotion_1 = require("remotion");
const colors_1 = require("../../helpers/colors");
const noop_1 = require("../../helpers/noop");
const input_dragger_click_lock_1 = require("../../state/input-dragger-click-lock");
const z_index_1 = require("../../state/z-index");
const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
const RemInput_1 = require("./RemInput");
const isInt = (num) => {
return num % 1 === 0;
};
const InputDraggerForwardRefFn = ({ onValueChange, onValueChangeEnd, min: _min, max: _max, step: _step, value, onTextChange, formatter = (q) => String(q), status, rightAlign, small, ...props }, ref) => {
const [inputFallback, setInputFallback] = (0, react_1.useState)(false);
const [dragging, setDragging] = (0, react_1.useState)(false);
const fallbackRef = (0, react_1.useRef)(null);
const pointerDownRef = (0, react_1.useRef)(false);
const style = (0, react_1.useMemo)(() => {
return {
...RemInput_1.inputBaseStyle,
backgroundColor: 'transparent',
borderColor: 'transparent',
padding: '4px 6px',
...{ outline: 'none' },
};
}, []);
const span = (0, react_1.useMemo)(() => ({
color: dragging ? 'var(--remotion-cli-internals-blue-hovered)' : colors_1.BLUE,
cursor: 'ew-resize',
userSelect: 'none',
WebkitUserSelect: 'none',
fontSize: small ? 12 : 14,
fontVariantNumeric: 'tabular-nums',
}), [dragging, small]);
const onFocus = (0, react_1.useCallback)(() => {
if (!small || pointerDownRef.current) {
return;
}
setInputFallback(true);
}, [small]);
const onClick = (0, react_1.useCallback)((e) => {
if (!(0, input_dragger_click_lock_1.getClickLock)()) {
e.stopPropagation();
}
if ((0, input_dragger_click_lock_1.getClickLock)()) {
return;
}
setInputFallback(true);
}, []);
const onEscape = (0, react_1.useCallback)(() => {
setInputFallback(false);
}, []);
const onInputChange = (0, react_1.useCallback)((e) => {
const parsed = Number(e.target.value);
if (e.target.value !== '' && !Number.isNaN(parsed)) {
onValueChange(parsed);
}
}, [onValueChange]);
const onBlur = (0, react_1.useCallback)(() => {
if (!fallbackRef.current) {
return;
}
const newValue = fallbackRef.current.value;
if (newValue.trim() === '') {
onEscape();
return;
}
if (fallbackRef.current.checkValidity()) {
onValueChangeEnd === null || onValueChangeEnd === void 0 ? void 0 : onValueChangeEnd(Number(newValue));
setInputFallback(false);
}
else {
fallbackRef.current.reportValidity();
}
}, [onEscape, onValueChangeEnd]);
const onKeyPress = (0, react_1.useCallback)((e) => {
var _a;
if (e.key === 'Enter') {
(_a = fallbackRef.current) === null || _a === void 0 ? void 0 : _a.blur();
}
}, []);
const roundToStep = (val, stepSize) => {
const factor = 1 / stepSize;
return Math.ceil(val * factor) / factor;
};
const onPointerDown = (0, react_1.useCallback)((e) => {
pointerDownRef.current = true;
const target = e.currentTarget;
const { pageX, pageY, button } = e;
if (button !== 0) {
return;
}
let lastDragValue = null;
const moveListener = (ev) => {
const xDistance = ev.pageX - pageX;
const distanceFromStart = Math.sqrt(xDistance ** 2 + (ev.pageY - pageY) ** 2);
const step = Number(_step !== null && _step !== void 0 ? _step : 1);
const min = Number(_min !== null && _min !== void 0 ? _min : 0);
const max = Number(_max !== null && _max !== void 0 ? _max : Infinity);
if (distanceFromStart > 4) {
(0, input_dragger_click_lock_1.setClickLock)(true);
setDragging(true);
(0, ForceSpecificCursor_1.forceSpecificCursor)('ew-resize');
target.blur();
}
const diff = (0, remotion_1.interpolate)(xDistance, [-5, -4, 0, 4, 5], [-step, 0, 0, 0, step]);
const newValue = Math.min(max, Math.max(min, Number(value) + diff));
const roundedToStep = roundToStep(newValue, step);
lastDragValue = roundedToStep;
onValueChange(roundedToStep);
};
window.addEventListener('mousemove', moveListener);
window.addEventListener('pointerup', () => {
window.removeEventListener('mousemove', moveListener);
pointerDownRef.current = false;
setDragging(false);
(0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
if (lastDragValue !== null && onValueChangeEnd) {
onValueChangeEnd(lastDragValue);
}
setTimeout(() => {
(0, input_dragger_click_lock_1.setClickLock)(false);
}, 2);
}, {
once: true,
});
}, [_step, _min, _max, value, onValueChange, onValueChangeEnd]);
(0, react_1.useEffect)(() => {
var _a;
if (inputFallback) {
(_a = fallbackRef.current) === null || _a === void 0 ? void 0 : _a.select();
}
}, [inputFallback]);
const deriveStep = (0, react_1.useMemo)(() => {
if (_step !== undefined) {
return _step;
}
if (typeof _min === 'number' && isInt(_min)) {
return 1;
}
return 0.0001;
}, [_min, _step]);
if (inputFallback) {
return (jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onEscape: onEscape, onOutsideClick: noop_1.noop, children: jsx_runtime_1.jsx(RemInput_1.RemotionInput, { ref: fallbackRef, autoFocus: true, onKeyPress: onKeyPress, onBlur: onBlur, onChange: onInputChange, min: _min, max: _max, step: deriveStep, defaultValue: value, status: status, pattern: '[0-9]*[.]?[0-9]*', rightAlign: rightAlign, ...props, ...(small ? { style: { padding: '4px 6px', fontSize: 12 } } : {}) }) }));
}
return (jsx_runtime_1.jsx("button", { ref: ref, type: "button", className: '__remotion_input_dragger', style: style, onClick: onClick, onFocus: onFocus, onPointerDown: onPointerDown, children: jsx_runtime_1.jsx("span", { style: span, children: formatter(value) }) }));
};
exports.InputDragger = react_1.default.forwardRef(InputDraggerForwardRefFn);