@remotion/studio
Version:
APIs for interacting with the Remotion Studio
104 lines (103 loc) • 4.55 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CompositionIdsDropdown = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const Button_1 = require("../../components/Button");
const colors_1 = require("../../helpers/colors");
const CompositionIdListItem_1 = require("./CompositionIdListItem");
const carets_1 = require("./carets");
const containerStyle = {
display: 'inline-block',
position: 'relative',
};
// Button styling provided by shared Button component
const dropdownStyle = {
position: 'absolute',
top: '110%',
left: 0,
width: 320,
maxHeight: 300,
overflowY: 'auto',
backgroundColor: colors_1.INPUT_BACKGROUND,
border: `1px solid ${colors_1.INPUT_BORDER_COLOR_UNHOVERED}`,
borderRadius: 8,
padding: 8,
boxShadow: '0 6px 24px rgba(0,0,0,0.35)',
zIndex: 1000,
fontFamily: 'inherit',
fontSize: 14,
};
const searchStyle = {
width: '100%',
padding: '6px 8px',
borderRadius: 6,
border: `1px solid ${colors_1.INPUT_BORDER_COLOR_UNHOVERED}`,
background: colors_1.INPUT_BACKGROUND,
color: colors_1.TEXT_COLOR,
marginBottom: 8,
outline: 'none',
fontFamily: 'inherit',
fontSize: 14,
};
const CompositionIdsDropdown = ({ compositionIds, currentId }) => {
const [open, setOpen] = (0, react_1.useState)(false);
const [query, setQuery] = (0, react_1.useState)('');
const containerRef = (0, react_1.useRef)(null);
const filtered = (0, react_1.useMemo)(() => {
const q = query.trim().toLowerCase();
if (!q) {
return compositionIds;
}
return compositionIds.filter((id) => id.toLowerCase().includes(q));
}, [compositionIds, query]);
const onSelect = (id) => {
const isQuery = window.remotion_isReadOnlyStudio;
if (isQuery) {
window.location.href = `${window.location.pathname}?/${id}`;
}
else {
window.location.href = `/${id}`;
}
};
(0, react_1.useEffect)(() => {
if (!open) {
return;
}
const onClickAway = (e) => {
if (!containerRef.current) {
return;
}
if (!containerRef.current.contains(e.target)) {
setOpen(false);
}
};
const onKey = (e) => {
if (e.key === 'Escape') {
setOpen(false);
}
};
document.addEventListener('mousedown', onClickAway);
document.addEventListener('touchstart', onClickAway, { passive: true });
document.addEventListener('keydown', onKey);
return () => {
document.removeEventListener('mousedown', onClickAway);
document.removeEventListener('touchstart', onClickAway);
document.removeEventListener('keydown', onKey);
};
}, [open, containerRef]);
return ((0, jsx_runtime_1.jsxs)("div", { ref: containerRef, style: containerStyle, children: [(0, jsx_runtime_1.jsxs)(Button_1.Button, { onClick: () => setOpen((p) => !p), buttonContainerStyle: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
gap: 8,
minWidth: 180,
}, children: [(0, jsx_runtime_1.jsx)("span", { style: {
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
fontSize: '14px',
lineHeight: '24px',
}, children: currentId !== null && currentId !== void 0 ? currentId : 'Select composition' }), (0, jsx_runtime_1.jsx)(carets_1.CaretDown, { size: 20, invert: open })] }), open ? ((0, jsx_runtime_1.jsxs)("div", { style: dropdownStyle, children: [(0, jsx_runtime_1.jsx)("input", { value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Search compositions...", style: searchStyle, "aria-label": "Search compositions" }), (0, jsx_runtime_1.jsx)("div", { children: filtered.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { style: { opacity: 0.7, padding: 8, textAlign: 'center' }, children: "No compositions found" })) : (filtered.map((id) => ((0, jsx_runtime_1.jsx)(CompositionIdListItem_1.CompositionIdListItem, { id: id, isActive: id === currentId, onSelect: onSelect }, id)))) })] })) : null] }));
};
exports.CompositionIdsDropdown = CompositionIdsDropdown;