import { For, Show, createEffect, createMemo, createSignal, onMount, type JSX } from "solid-js"; import { Portal } from "solid-js/web"; import { ChevronRight, Plus } from "../../../lib/icons"; import { getWorkspaceContextMenuEyebrow, getWorkspaceContextMenuSections, type WorkspaceContextMenuAction, type WorkspaceContextMenuShortcut, type WorkspaceContextMenuTarget, } from "../data/shell.data"; import styles from "./WorkspaceContextMenu.module.scss"; type ShortcutPlatform = "mac" | "windows"; type NavigatorWithUserAgentData = Navigator & { userAgentData?: { platform?: string; }; }; type WorkspaceContextMenuPosition = { x: number; y: number; }; type WorkspaceContextMenuProps = { target: WorkspaceContextMenuTarget | null; position: WorkspaceContextMenuPosition | null; onClose: VoidFunction; onSelect: (action: WorkspaceContextMenuAction, target: WorkspaceContextMenuTarget) => void; menuRef: (element: HTMLDivElement) => void; }; const getShortcutPlatform = (): ShortcutPlatform => { if (typeof navigator === "undefined") { return "mac"; } const navigatorWithUserAgentData = navigator as NavigatorWithUserAgentData; const platform = typeof navigatorWithUserAgentData.userAgentData?.platform === "string" ? navigatorWithUserAgentData.userAgentData.platform : navigator.platform; return /mac|iphone|ipad|ipod/i.test(platform) ? "mac" : "windows"; }; const formatShortcut = (shortcut: WorkspaceContextMenuShortcut, platform: ShortcutPlatform): string => { const keyLabel = (() => { switch (shortcut.key) { case "enter": return platform === "mac" ? "↩" : "Enter"; case "delete": return platform === "mac" ? "⌫" : "Del"; default: return shortcut.key.toUpperCase(); } })(); const modifierLabels = shortcut.modifiers?.map((modifier) => { switch (modifier) { case "meta": return platform === "mac" ? "⌘" : "Ctrl"; case "alt": return platform === "mac" ? "⌥" : "Alt"; case "shift": return platform === "mac" ? "⇧" : "Shift"; } }) ?? []; if (platform === "mac") { return `${modifierLabels.join("")}${keyLabel}`; } return [...modifierLabels, keyLabel].join("+"); }; export const WorkspaceContextMenu = (props: WorkspaceContextMenuProps): JSX.Element => { const [activeSubmenuActionId, setActiveSubmenuActionId] = createSignal(null); const [shortcutPlatform, setShortcutPlatform] = createSignal("mac"); const sections = createMemo(() => (props.target ? getWorkspaceContextMenuSections(props.target) : [])); const handleActionSelect = (action: WorkspaceContextMenuAction, target: WorkspaceContextMenuTarget): void => { props.onSelect(action, target); props.onClose(); }; const menuState = createMemo<{ target: WorkspaceContextMenuTarget; position: WorkspaceContextMenuPosition; } | null>(() => props.target && props.position ? { target: props.target, position: props.position, } : null, ); const showHeader = (): boolean => props.target?.kind !== "workspace"; const sectionHasLabel = createMemo(() => sections().some((section) => Boolean(section.label))); onMount(() => { setShortcutPlatform(getShortcutPlatform()); }); createEffect(() => { void props.target; setActiveSubmenuActionId(null); }); return ( {(resolvedMenuState): JSX.Element => { const target = resolvedMenuState().target; const position = resolvedMenuState().position; return ( ); }} ); };