init commit

This commit is contained in:
Carlos
2026-02-21 10:33:18 +01:00
parent c863a943ed
commit 9d955bf338
9512 changed files with 2015317 additions and 1305 deletions

View File

@@ -0,0 +1,2 @@
import React from 'react';
export declare const MenuDivider: React.FC;

View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MenuDivider = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const colors_1 = require("../../helpers/colors");
const menuDivider = {
marginTop: 4,
marginBottom: 4,
height: 1,
backgroundColor: colors_1.INPUT_BORDER_COLOR_HOVERED,
};
const MenuDivider = () => {
return (0, jsx_runtime_1.jsx)("div", { style: menuDivider });
};
exports.MenuDivider = MenuDivider;

View File

@@ -0,0 +1,22 @@
import type { SetStateAction } from 'react';
import React from 'react';
import type { ComboboxValue } from '../NewComposition/ComboBox';
export type MenuId = 'remotion' | 'file' | 'view' | 'install' | 'tools' | 'help';
export type Menu = {
id: MenuId;
label: React.ReactNode;
items: ComboboxValue[];
leaveLeftPadding: boolean;
};
export declare const MenuItem: React.FC<{
readonly label: React.ReactNode;
readonly id: MenuId;
readonly selected: boolean;
readonly onItemSelected: (s: SetStateAction<string | null>) => void;
readonly onItemHovered: (id: MenuId) => void;
readonly onItemQuit: () => void;
readonly onPreviousMenu: () => void;
readonly onNextMenu: () => void;
readonly menu: Menu;
readonly leaveLeftPadding: boolean;
}>;

View File

@@ -0,0 +1,97 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MenuItem = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const player_1 = require("@remotion/player");
const react_1 = require("react");
const react_dom_1 = __importDefault(require("react-dom"));
const colors_1 = require("../../helpers/colors");
const z_index_1 = require("../../state/z-index");
const MenuContent_1 = require("../NewComposition/MenuContent");
const is_menu_item_1 = require("./is-menu-item");
const portals_1 = require("./portals");
const styles_1 = require("./styles");
const container = {
fontSize: 13,
color: 'white',
paddingLeft: 10,
paddingRight: 10,
cursor: 'default',
paddingTop: 8,
paddingBottom: 8,
userSelect: 'none',
WebkitUserSelect: 'none',
border: 'none',
};
const MenuItem = ({ label: itemName, selected, id, onItemSelected, onItemHovered, onItemQuit, onPreviousMenu, onNextMenu, menu, }) => {
const [hovered, setHovered] = (0, react_1.useState)(false);
const ref = (0, react_1.useRef)(null);
const size = player_1.PlayerInternals.useElementSize(ref, {
triggerOnWindowResize: true,
shouldApplyCssTransforms: true,
});
const { tabIndex, currentZIndex } = (0, z_index_1.useZIndex)();
const containerStyle = (0, react_1.useMemo)(() => {
return {
...container,
backgroundColor: (0, colors_1.getBackgroundFromHoverState)({
hovered,
selected,
}),
};
}, [hovered, selected]);
const portalStyle = (0, react_1.useMemo)(() => {
if (!selected || !size) {
return null;
}
return {
...styles_1.menuContainerTowardsBottom,
left: size.left,
top: size.top + size.height,
};
}, [selected, size]);
const onPointerEnter = (0, react_1.useCallback)(() => {
onItemHovered(id);
setHovered(true);
}, [id, onItemHovered]);
const onPointerLeave = (0, react_1.useCallback)(() => {
setHovered(false);
}, []);
const onPointerDown = (0, react_1.useCallback)((e) => {
if (e.button !== 0) {
return;
}
onItemSelected(id);
window.addEventListener('pointerup', (evt) => {
if (!(0, is_menu_item_1.isMenuItem)(evt.target)) {
onItemQuit();
}
}, {
once: true,
});
}, [id, onItemQuit, onItemSelected]);
const onClick = (0, react_1.useCallback)((e) => {
e.stopPropagation();
const isKeyboardInitiated = e.detail === 0;
if (!isKeyboardInitiated) {
return;
}
onItemSelected((p) => {
return p === null ? id : null;
});
}, [id, onItemSelected]);
const outerStyle = (0, react_1.useMemo)(() => {
var _a, _b;
return {
...styles_1.outerPortal,
top: ((_a = size === null || size === void 0 ? void 0 : size.top) !== null && _a !== void 0 ? _a : 0) + ((_b = size === null || size === void 0 ? void 0 : size.height) !== null && _b !== void 0 ? _b : 0),
};
}, [size]);
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("button", { ref: ref, role: "button", tabIndex: tabIndex, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, onPointerDown: onPointerDown, onClick: onClick, style: containerStyle, type: "button", className: is_menu_item_1.MENU_INITIATOR_CLASSNAME, children: itemName }), portalStyle
? react_dom_1.default.createPortal((0, jsx_runtime_1.jsx)("div", { className: "css-reset", style: outerStyle, children: (0, jsx_runtime_1.jsx)(z_index_1.HigherZIndex, { onEscape: onItemQuit, onOutsideClick: onItemQuit, children: (0, jsx_runtime_1.jsx)("div", { style: portalStyle, children: (0, jsx_runtime_1.jsx)(MenuContent_1.MenuContent, { onNextMenu: onPreviousMenu, onPreviousMenu: onNextMenu, values: menu.items, onHide: onItemQuit, leaveLeftSpace: menu.leaveLeftPadding, preselectIndex: false, topItemCanBeUnselected: true, fixedHeight: null }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
: null] }));
};
exports.MenuItem = MenuItem;

View File

@@ -0,0 +1,20 @@
import type { PointerEvent } from 'react';
import React from 'react';
import type { SubMenu } from '../NewComposition/ComboBox';
export type SubMenuActivated = false | 'with-mouse' | 'without-mouse';
export declare const MenuSubItem: React.FC<{
readonly label: React.ReactNode;
readonly id: string;
readonly onActionChosen: (id: string, e: PointerEvent<HTMLDivElement>) => void;
readonly selected: boolean;
readonly onItemSelected: (id: string) => void;
readonly keyHint: string | null;
readonly leaveLeftSpace: boolean;
readonly leftItem: React.ReactNode;
readonly subMenu: SubMenu | null;
readonly onQuitMenu: () => void;
readonly onNextMenu: () => void;
readonly subMenuActivated: SubMenuActivated;
readonly setSubMenuActivated: React.Dispatch<React.SetStateAction<SubMenuActivated>>;
readonly disabled?: boolean;
}>;

View File

@@ -0,0 +1,121 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MenuSubItem = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const player_1 = require("@remotion/player");
const react_1 = require("react");
const react_dom_1 = __importDefault(require("react-dom"));
const colors_1 = require("../../helpers/colors");
const mobile_layout_1 = require("../../helpers/mobile-layout");
const use_keybinding_1 = require("../../helpers/use-keybinding");
const caret_1 = require("../../icons/caret");
const z_index_1 = require("../../state/z-index");
const layout_1 = require("../layout");
const SubMenu_1 = require("./SubMenu");
const is_menu_item_1 = require("./is-menu-item");
const portals_1 = require("./portals");
const styles_1 = require("./styles");
const container = {
paddingTop: 8,
paddingBottom: 8,
paddingLeft: 12,
paddingRight: 8,
cursor: 'default',
};
const labelStyle = {
fontSize: 13,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
flex: 1,
};
const keyHintCss = {
flexDirection: 'row',
color: colors_1.LIGHT_TEXT,
fontSize: 13,
};
const leftSpace = {
width: 24,
marginLeft: -6,
display: 'inline-flex',
justifyContent: 'center',
alignItems: 'center',
};
const MenuSubItem = ({ label, leaveLeftSpace, leftItem, onActionChosen, id, selected, onItemSelected, keyHint, subMenu, onQuitMenu, subMenuActivated, setSubMenuActivated, disabled, }) => {
const [hovered, setHovered] = (0, react_1.useState)(false);
const ref = (0, react_1.useRef)(null);
const size = player_1.PlayerInternals.useElementSize(ref, {
triggerOnWindowResize: true,
shouldApplyCssTransforms: true,
});
const mobileLayout = (0, mobile_layout_1.useMobileLayout)();
const { currentZIndex } = (0, z_index_1.useZIndex)();
const style = (0, react_1.useMemo)(() => {
return {
...container,
backgroundColor: selected && !disabled ? colors_1.CLEAR_HOVER : 'transparent',
opacity: disabled ? 0.5 : 1,
cursor: disabled ? 'not-allowed' : 'default',
};
}, [selected, disabled]);
const onPointerUp = (0, react_1.useCallback)((e) => {
if (disabled) {
return;
}
if (subMenu) {
setSubMenuActivated('with-mouse');
setHovered(true);
return;
}
onActionChosen(id, e);
}, [disabled, id, onActionChosen, setSubMenuActivated, subMenu]);
const onPointerEnter = (0, react_1.useCallback)(() => {
if (disabled) {
return;
}
onItemSelected(id);
setHovered(true);
}, [disabled, id, onItemSelected]);
const onPointerLeave = (0, react_1.useCallback)(() => {
setHovered(false);
}, []);
const onQuitSubmenu = (0, react_1.useCallback)(() => {
setSubMenuActivated(false);
}, [setSubMenuActivated]);
const portalStyle = (0, react_1.useMemo)(() => {
if (!selected || !size || !subMenu || !subMenuActivated) {
return null;
}
const left = size.left + size.width + styles_1.SUBMENU_LEFT_INSET;
return {
...styles_1.menuContainerTowardsBottom,
left: mobileLayout ? left * 0.7 : left,
top: size.top - styles_1.MENU_VERTICAL_PADDING,
};
}, [mobileLayout, selected, size, subMenu, subMenuActivated]);
(0, react_1.useEffect)(() => {
if (!hovered || !subMenu) {
return;
}
const hi = setTimeout(() => {
setSubMenuActivated('with-mouse');
}, 100);
return () => clearTimeout(hi);
}, [hovered, selected, setSubMenuActivated, subMenu]);
(0, react_1.useEffect)(() => {
var _a;
if (selected) {
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({
// block is vertical alignment, inline is horizontal alignment. So we use "block"
block: 'nearest',
});
}
}, [selected]);
return ((0, jsx_runtime_1.jsx)("div", { ref: ref, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, style: style, onPointerUp: onPointerUp, role: "button", className: is_menu_item_1.MENU_ITEM_CLASSNAME, children: (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [leaveLeftSpace ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: leftSpace, children: leftItem }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 })] })) : null, (0, jsx_runtime_1.jsx)("div", { style: labelStyle, title: typeof label === 'string' ? label : undefined, children: label }), ' ', (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), subMenu ? (0, jsx_runtime_1.jsx)(caret_1.CaretRight, {}) : null, keyHint && !(0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? ((0, jsx_runtime_1.jsx)("span", { style: keyHintCss, children: keyHint })) : null, portalStyle && subMenu
? react_dom_1.default.createPortal((0, jsx_runtime_1.jsx)(SubMenu_1.SubMenuComponent, { onQuitFullMenu: onQuitMenu, subMenu: subMenu, onQuitSubMenu: onQuitSubmenu, portalStyle: portalStyle, subMenuActivated: subMenuActivated }), (0, portals_1.getPortal)(currentZIndex))
: null] }) }));
};
exports.MenuSubItem = MenuSubItem;

View File

@@ -0,0 +1,10 @@
import React from 'react';
import type { SubMenu } from '../NewComposition/ComboBox';
import type { SubMenuActivated } from './MenuSubItem';
export declare const SubMenuComponent: React.FC<{
readonly portalStyle: React.CSSProperties;
readonly subMenu: SubMenu;
readonly onQuitFullMenu: () => void;
readonly onQuitSubMenu: () => void;
readonly subMenuActivated: SubMenuActivated;
}>;

View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SubMenuComponent = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const mobile_layout_1 = require("../../helpers/mobile-layout");
const noop_1 = require("../../helpers/noop");
const z_index_1 = require("../../state/z-index");
const MenuContent_1 = require("../NewComposition/MenuContent");
const portals_1 = require("./portals");
const SubMenuComponent = ({ portalStyle, subMenuActivated, subMenu, onQuitFullMenu, onQuitSubMenu, }) => {
const mobileLayout = (0, mobile_layout_1.useMobileLayout)();
const onOutsideClick = (0, react_1.useCallback)((e) => {
if (portals_1.portals.find((p) => p.contains(e)) || mobileLayout) {
onQuitSubMenu();
}
else {
onQuitFullMenu();
}
}, [mobileLayout, onQuitFullMenu, onQuitSubMenu]);
return ((0, jsx_runtime_1.jsx)(z_index_1.HigherZIndex, { onEscape: onQuitFullMenu, onOutsideClick: onOutsideClick, children: (0, jsx_runtime_1.jsx)("div", { style: portalStyle, className: "css-reset", children: (0, jsx_runtime_1.jsx)(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: onQuitSubMenu, values: subMenu.items, onHide: onQuitFullMenu, leaveLeftSpace: subMenu.leaveLeftSpace, preselectIndex: subMenuActivated === 'without-mouse' &&
typeof subMenu.preselectIndex === 'number'
? subMenu.preselectIndex
: false, topItemCanBeUnselected: false, fixedHeight: null }) }) }));
};
exports.SubMenuComponent = SubMenuComponent;

View File

@@ -0,0 +1,5 @@
export declare const MENU_INITIATOR_CLASSNAME = "__remotion-studio-menu-initiator";
export declare const MENU_ITEM_CLASSNAME = "__remotion-studio-menu-item";
export declare const HORIZONTAL_SCROLLBAR_CLASSNAME = "__remotion-horizontal-scrollbar";
export declare const VERTICAL_SCROLLBAR_CLASSNAME = "__remotion-vertical-scrollbar";
export declare const isMenuItem: (el: HTMLElement) => boolean;

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isMenuItem = exports.VERTICAL_SCROLLBAR_CLASSNAME = exports.HORIZONTAL_SCROLLBAR_CLASSNAME = exports.MENU_ITEM_CLASSNAME = exports.MENU_INITIATOR_CLASSNAME = void 0;
exports.MENU_INITIATOR_CLASSNAME = '__remotion-studio-menu-initiator';
exports.MENU_ITEM_CLASSNAME = '__remotion-studio-menu-item';
exports.HORIZONTAL_SCROLLBAR_CLASSNAME = '__remotion-horizontal-scrollbar';
exports.VERTICAL_SCROLLBAR_CLASSNAME = '__remotion-vertical-scrollbar';
const isMenuItem = (el) => {
return Boolean(el.classList.contains(exports.MENU_ITEM_CLASSNAME) ||
el.closest(`.${exports.MENU_ITEM_CLASSNAME}`) ||
el.classList.contains(exports.MENU_INITIATOR_CLASSNAME) ||
el.closest(`.${exports.MENU_INITIATOR_CLASSNAME}`));
};
exports.isMenuItem = isMenuItem;

View File

@@ -0,0 +1,2 @@
export declare const portals: Element[];
export declare const getPortal: (i: number) => Element;

View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPortal = exports.portals = void 0;
exports.portals = [
document.getElementById('menuportal-0'),
document.getElementById('menuportal-1'),
document.getElementById('menuportal-2'),
document.getElementById('menuportal-3'),
document.getElementById('menuportal-4'),
document.getElementById('menuportal-5'),
];
const getPortal = (i) => {
return exports.portals[i];
};
exports.getPortal = getPortal;

View File

@@ -0,0 +1,12 @@
import type React from 'react';
export declare const MENU_VERTICAL_PADDING = 4;
export declare const SUBMENU_LEFT_INSET = -8;
export declare const MAX_MENU_WIDTH = 400;
export declare const MAX_MOBILE_MENU_WIDTH = 300;
export declare const SHADOW_TOWARDS_BOTTOM = "0 2px 8px rgba(0, 0, 0, 0.5)";
export declare const SHADOW_TOWARDS_TOP = "0 -2px 8px rgba(0, 0, 0, 0.5)";
export declare const menuContainerTowardsBottom: React.CSSProperties;
export declare const menuContainerTowardsTop: React.CSSProperties;
export declare const fullScreenOverlay: React.CSSProperties;
export declare const outerPortal: React.CSSProperties;
export declare const inlineCodeSnippet: React.CSSProperties;

View File

@@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.inlineCodeSnippet = exports.outerPortal = exports.fullScreenOverlay = exports.menuContainerTowardsTop = exports.menuContainerTowardsBottom = exports.SHADOW_TOWARDS_TOP = exports.SHADOW_TOWARDS_BOTTOM = exports.MAX_MOBILE_MENU_WIDTH = exports.MAX_MENU_WIDTH = exports.SUBMENU_LEFT_INSET = exports.MENU_VERTICAL_PADDING = void 0;
const colors_1 = require("../../helpers/colors");
exports.MENU_VERTICAL_PADDING = 4;
exports.SUBMENU_LEFT_INSET = -8;
exports.MAX_MENU_WIDTH = 400;
exports.MAX_MOBILE_MENU_WIDTH = 300;
const menuContainer = {
backgroundColor: colors_1.BACKGROUND,
position: 'fixed',
color: 'white',
userSelect: 'none',
WebkitUserSelect: 'none',
};
exports.SHADOW_TOWARDS_BOTTOM = '0 2px 8px rgba(0, 0, 0, 0.5)';
exports.SHADOW_TOWARDS_TOP = '0 -2px 8px rgba(0, 0, 0, 0.5)';
exports.menuContainerTowardsBottom = {
...menuContainer,
boxShadow: exports.SHADOW_TOWARDS_BOTTOM,
};
exports.menuContainerTowardsTop = {
...menuContainer,
boxShadow: exports.SHADOW_TOWARDS_TOP,
};
exports.fullScreenOverlay = {
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
};
exports.outerPortal = {
position: 'fixed',
};
exports.inlineCodeSnippet = {
fontSize: 14,
color: colors_1.BLUE,
fontFamily: 'monospace',
};