mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
82 lines
2.5 KiB
TypeScript
82 lines
2.5 KiB
TypeScript
import { useStore } from '@nanostores/react';
|
|
import { motion, type Variants } from 'framer-motion';
|
|
import { memo } from 'react';
|
|
import { IconButton } from '~/components/ui/IconButton';
|
|
import { workbenchStore } from '~/lib/stores/workbench';
|
|
import { classNames } from '~/utils/classNames';
|
|
import { cubicEasingFn } from '~/utils/easings';
|
|
import { renderLogger } from '~/utils/logger';
|
|
import { Preview } from './Preview';
|
|
import useViewport from '~/lib/hooks';
|
|
|
|
interface WorkspaceProps {
|
|
chatStarted?: boolean;
|
|
}
|
|
|
|
const workbenchVariants = {
|
|
closed: {
|
|
width: 0,
|
|
transition: {
|
|
duration: 0.2,
|
|
ease: cubicEasingFn,
|
|
},
|
|
},
|
|
open: {
|
|
width: 'var(--workbench-width)',
|
|
transition: {
|
|
duration: 0.2,
|
|
ease: cubicEasingFn,
|
|
},
|
|
},
|
|
} satisfies Variants;
|
|
|
|
export const Workbench = memo(({ chatStarted }: WorkspaceProps) => {
|
|
renderLogger.trace('Workbench');
|
|
|
|
const showWorkbench = useStore(workbenchStore.showWorkbench);
|
|
|
|
const isSmallViewport = useViewport(1024);
|
|
|
|
return (
|
|
chatStarted && (
|
|
<motion.div
|
|
initial="closed"
|
|
animate={showWorkbench ? 'open' : 'closed'}
|
|
variants={workbenchVariants}
|
|
className="z-workbench"
|
|
>
|
|
<div
|
|
className={classNames(
|
|
'fixed top-[calc(var(--header-height)+1.5rem)] bottom-6 w-[var(--workbench-inner-width)] mr-4 z-0 transition-[left,width] duration-200 bolt-ease-cubic-bezier',
|
|
{
|
|
'w-full': isSmallViewport,
|
|
'left-0': showWorkbench && isSmallViewport,
|
|
'left-[var(--workbench-left)]': showWorkbench,
|
|
'left-[100%]': !showWorkbench,
|
|
},
|
|
)}
|
|
>
|
|
<div className="absolute inset-0 px-2 lg:px-6">
|
|
<div className="h-full flex flex-col bg-bolt-elements-background-depth-2 border border-bolt-elements-borderColor shadow-sm rounded-lg overflow-hidden">
|
|
<div className="flex items-center px-3 py-2 border-b border-bolt-elements-borderColor">
|
|
<div className="ml-auto" />
|
|
<IconButton
|
|
icon="i-ph:x-circle"
|
|
className="-mr-1"
|
|
size="xl"
|
|
onClick={() => {
|
|
workbenchStore.showWorkbench.set(false);
|
|
}}
|
|
/>
|
|
</div>
|
|
<div className="relative flex-1 overflow-hidden">
|
|
<Preview />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
)
|
|
);
|
|
});
|