diff --git a/src/components/CodeExplorer.tsx b/src/components/CodeExplorer.tsx index bf6373be6..0ae42bc38 100644 --- a/src/components/CodeExplorer.tsx +++ b/src/components/CodeExplorer.tsx @@ -1,23 +1,24 @@ import React from 'react' -import { FileExplorer } from './FileExplorer' +import { FileExplorer, type FileExplorerNode } from './FileExplorer' import { InteractiveSandbox } from './InteractiveSandbox' import { CodeExplorerTopBar } from './CodeExplorerTopBar' -import type { GitHubFileNode } from '~/utils/documents.server' +import { getExamplePanels, type ExamplePanel } from '~/utils/example-panel' import type { Library } from '~/libraries' import { twMerge } from 'tailwind-merge' import { CodeBlock } from '~/components/markdown' import { getCodeBlockLanguageFromFilePath } from '~/components/markdown/codeBlock.shared' interface CodeExplorerProps { - activeTab: 'code' | 'sandbox' + activeTab: ExamplePanel codeSandboxUrl: string currentCode: string currentPath: string examplePath: string - githubContents: GitHubFileNode[] | undefined + githubContents: FileExplorerNode[] | undefined library: Library prefetchFileContent: (path: string) => void - setActiveTab: (tab: 'code' | 'sandbox') => void + playground?: React.ReactNode + setActiveTab: (tab: ExamplePanel) => void setCurrentPath: (path: string) => void stackBlitzUrl: string } @@ -31,12 +32,23 @@ export function CodeExplorer({ githubContents, library, prefetchFileContent, + playground, setActiveTab, setCurrentPath, stackBlitzUrl, }: CodeExplorerProps) { const [isFullScreen, setIsFullScreen] = React.useState(false) const [isSidebarOpen, setIsSidebarOpen] = React.useState(true) + const [hasOpenedPlayground, setHasOpenedPlayground] = React.useState( + activeTab === 'playground', + ) + React.useEffect(() => { + if (activeTab === 'playground') setHasOpenedPlayground(true) + }, [activeTab]) + const panels = getExamplePanels({ + ...library, + hasPlayground: Boolean(playground), + }) const currentCodeLanguage = getCodeBlockLanguageFromFilePath(currentPath) // Add escape key handler @@ -60,6 +72,7 @@ export function CodeExplorer({ >
-
- setIsSidebarOpen(false)} - prefetchFileContent={prefetchFileContent} - setCurrentPath={setCurrentPath} - /> + {playground && (hasOpenedPlayground || activeTab === 'playground') ? ( +
+ {playground} +
+ ) : null} + {!playground ? (
- setIsSidebarOpen(false)} + prefetchFileContent={prefetchFileContent} + setCurrentPath={setCurrentPath} + /> +
- - {currentCode} - - + + + {currentCode} + + +
-
- + ) : null} + {!library.hideStackblitzUrl ? ( + + ) : null} + {!library.hideCodesandboxUrl ? ( + + ) : null}
) diff --git a/src/components/CodeExplorerTopBar.tsx b/src/components/CodeExplorerTopBar.tsx index a902d5687..e5c841baf 100644 --- a/src/components/CodeExplorerTopBar.tsx +++ b/src/components/CodeExplorerTopBar.tsx @@ -7,18 +7,21 @@ import { TextAlignLeftIcon, } from '@phosphor-icons/react' import { Tooltip } from '~/ui' +import type { ExamplePanel, ExamplePanelOption } from '~/utils/example-panel' interface CodeExplorerTopBarProps { - activeTab: 'code' | 'sandbox' + activeTab: ExamplePanel + panels: ReadonlyArray isFullScreen: boolean isSidebarOpen: boolean - setActiveTab: (tab: 'code' | 'sandbox') => void + setActiveTab: (tab: ExamplePanel) => void setIsFullScreen: React.Dispatch> setIsSidebarOpen: (isOpen: boolean) => void } export function CodeExplorerTopBar({ activeTab, + panels, isFullScreen, isSidebarOpen, setActiveTab, @@ -27,7 +30,7 @@ export function CodeExplorerTopBar({ }: CodeExplorerTopBarProps) { return (
-
+
{activeTab === 'code' ? ( isSidebarOpen ? ( @@ -62,38 +65,21 @@ export function CodeExplorerTopBar({ />
)} - - + {panels.map((panel) => ( + + ))}
+
+
+ ) + } return (
+
+ + If the embedded editor does not load, open it in a new tab. + + + Open in {provider} + +