Skip to content

Commit

Permalink
Start from chat + Styling (#791)
Browse files Browse the repository at this point in the history
- Added folder icon (more understandable than the file icon in many places)
- Improved small stylings
  • Loading branch information
drfarrell authored Nov 18, 2024
1 parent fa0ff81 commit f8b7bfd
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 21 deletions.
2 changes: 1 addition & 1 deletion apps/studio/src/lib/editor/engine/chat/mockData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const GREETING_MSG = new AssistantChatMessageImpl(
[
{
type: 'text',
text: 'Hello! Click on any element to chat with it.',
text: 'Click on any element to chat with it. Try to be as detailed as possible for the best results!',
},
],
[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const ChatHistory = observer(() => {
</Tooltip>
<PopoverAnchor className="absolute -left-2 top-0" />
<PopoverContent side="left" align="start" className="rounded-xl p-0">
<div className="flex flex-col">
<div className="flex flex-col select-none">
<div className="border-b">
<div className="flex flex-row justify-between items-center p-1 h-fit text-xs text-foreground-tertiary">
<span className="px-2">Chat History</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ const ChatControls = observer(() => {
variant={'ghost'}
size={'icon'}
className="p-2 w-fit h-fit hover:bg-transparent"
onClick={() => editorEngine.chat.startNewConversation()}
onClick={() => setShowDeleteDialog(true)}
disabled={editorEngine.chat.isWaiting}
>
<Icons.Plus />
<Icons.Trash />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>New Chat</p>
Delete Chat
<TooltipArrow className="fill-foreground" />
</TooltipContent>
</Tooltip>
Expand All @@ -54,13 +54,16 @@ const ChatControls = observer(() => {
variant={'ghost'}
size={'icon'}
className="p-2 w-fit h-fit hover:bg-transparent"
onClick={() => setShowDeleteDialog(true)}
onClick={() => editorEngine.chat.startNewConversation()}
disabled={editorEngine.chat.isWaiting}
>
<Icons.Trash />
<Icons.Plus />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">Delete Chat</TooltipContent>
<TooltipContent side="bottom">
<p>New Chat</p>
<TooltipArrow className="fill-foreground" />
</TooltipContent>
</Tooltip>
<AlertDialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
<AlertDialogContent>
Expand Down
6 changes: 3 additions & 3 deletions apps/studio/src/routes/editor/EditPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ enum TabValue {
const EditPanel = observer(() => {
const editorEngine = useEditorEngine();
const [isOpen, setIsOpen] = useState(true);
const [selectedTab, setSelectedTab] = useState(TabValue.STYLES);
const [selectedTab, setSelectedTab] = useState(TabValue.CHAT);

function renderEmptyState() {
return (
Expand Down Expand Up @@ -81,15 +81,15 @@ const EditPanel = observer(() => {
className={cn(
'fixed right-0 transition-width duration-300 opacity-100 bg-background/80 rounded-tl-xl overflow-hidden',
editorEngine.mode === EditorMode.INTERACT ? 'hidden' : 'visible',
!isOpen && 'w-12 h-12 rounded-l-xl cursor-pointer',
!isOpen && 'w-10 h-10 rounded-l-xl cursor-pointer',
isOpen && 'h-[calc(100vh-5rem)]',
isOpen && selectedTab == TabValue.STYLES && 'w-60',
isOpen && selectedTab == TabValue.CHAT && 'w-[22rem]',
)}
>
{!isOpen && (
<button
className="w-full h-full flex justify-center items-center text-foreground hover:text-foreground-onlook"
className="border border-foreground/10 rounded-l-xl w-full h-full flex justify-center items-center text-foreground hover:text-foreground-onlook"
onClick={() => setIsOpen(true)}
>
<Icons.PinLeft className="z-51" />
Expand Down
4 changes: 2 additions & 2 deletions apps/studio/src/routes/editor/LayersPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ const LayersPanel = observer(() => {
className={cn(
'left-0 top-20 transition-width duration-300 opacity-100 bg-background/80 rounded-tr-xl overflow-hidden',
editorEngine.mode === EditorMode.INTERACT ? 'hidden' : 'visible',
isOpen ? 'w-full h-[calc(100vh-5rem)]' : 'w-12 h-12 rounded-r-xl cursor-pointer',
isOpen ? 'w-full h-[calc(100vh-5rem)]' : 'w-10 h-10 rounded-r-xl cursor-pointer',
)}
>
{!isOpen && (
<div
className="w-full h-full flex justify-center items-center text-foreground hover:text-foreground-onlook"
className="border border-foreground/10 rounded-r-xl w-full h-full flex justify-center items-center text-foreground hover:text-foreground-onlook"
onClick={() => setIsOpen(true)}
>
<Icons.PinRight className="z-51" />
Expand Down
1 change: 1 addition & 0 deletions apps/studio/src/routes/editor/RightClickMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ export const RightClickMenu = observer(({ children }: RightClickMenuProps) => {
key={item.label}
onClick={item.action}
disabled={item.disabled}
className="cursor-pointer"
>
<span
className={cn(
Expand Down
15 changes: 11 additions & 4 deletions apps/studio/src/routes/editor/TopBar/OpenCode/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const OpenCode = observer(() => {
const [root, setRoot] = useState<TemplateNode | undefined>();
const [ide, setIde] = useState<IDE>(IDE.VS_CODE);
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const [isFolderHovered, setIsFolderHovered] = useState(false);
const [scopeDropdownIcon, animateDropdownIcon] = useAnimate();

const IDEIcon = Icons[ide.icon];
Expand Down Expand Up @@ -143,8 +144,14 @@ const OpenCode = observer(() => {
onSelect={() => {
viewSource(folder);
}}
onMouseEnter={() => setIsFolderHovered(true)}
onMouseLeave={() => setIsFolderHovered(false)}
>
<Icons.File className="mr-2 w-3 h-3" />
{isFolderHovered ? (
<Icons.DirectoryOpen className="mr-2 w-3 h-3" />
) : (
<Icons.Directory className="mr-2 w-3 h-3" />
)}
Folder
</DropdownMenuItem>
{instance && (
Expand All @@ -165,8 +172,8 @@ const OpenCode = observer(() => {
viewSource(root);
}}
>
<Icons.Component className="mr-2 w-3 h-3" />
Component
<Icons.Code className="mr-2 w-3 h-3" />
Element
</DropdownMenuItem>
)}
</DropdownMenuContent>
Expand All @@ -184,7 +191,7 @@ const OpenCode = observer(() => {
<DropdownMenu onOpenChange={handleIDEDropdownOpenChange}>
<DropdownMenuTrigger asChild className="p-2">
<button
className="text-foreground-active bg-transperant hover:text-foreground-active/90 w-8 h-8 m-2 mr-1 flex items-center justify-center"
className="text-foreground-active bg-transperant hover:text-foreground-active/90 w-8 h-8 m-0.5 flex items-center justify-center"
onClick={() => viewSource(instance || root)}
>
<Icons.Gear ref={scopeDropdownIcon} />
Expand Down
14 changes: 12 additions & 2 deletions apps/studio/src/routes/editor/TopBar/ProjectSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@onlook/ui/tooltip';
import { toast } from '@onlook/ui/use-toast';
import { observer } from 'mobx-react-lite';
import ProjectNameInput from './ProjectNameInput';
import { useState } from 'react';

const ProjectBreadcrumb = observer(() => {
const editorEngine = useEditorEngine();
const projectsManager = useProjectsManager();
const [isDirectoryHovered, setIsDirectoryHovered] = useState(false);

async function handleReturn() {
await saveScreenshot();
Expand Down Expand Up @@ -81,9 +83,17 @@ const ProjectBreadcrumb = observer(() => {
<Icons.ChevronDown className="transition-all rotate-0 group-data-[state=open]:-rotate-180 duration-200 ease-in-out" />
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem onClick={handleOpenProjectFolder}>
<DropdownMenuItem
onClick={handleOpenProjectFolder}
onMouseEnter={() => setIsDirectoryHovered(true)}
onMouseLeave={() => setIsDirectoryHovered(false)}
>
<div className="flex row center items-center">
<Icons.File className="mr-2" />
{isDirectoryHovered ? (
<Icons.DirectoryOpen className="mr-2" />
) : (
<Icons.Directory className="mr-2" />
)}
{'Open Project Folder'}
</div>
</DropdownMenuItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export default function ProjectSettingsButton({ project }: { project: Project })
const [showRenameDialog, setShowRenameDialog] = useState(false);
const [projectName, setProjectName] = useState(project.name);
const isProjectNameEmpty = useMemo(() => projectName.length === 0, [projectName]);
const [isDirectoryHovered, setIsDirectoryHovered] = useState(false);

useEffect(() => {
setProjectName(project.name);
Expand Down Expand Up @@ -75,9 +76,15 @@ export default function ProjectSettingsButton({ project }: { project: Project })
<DropdownMenuContent>
<DropdownMenuItem
onSelect={handleOpenProjectFolder}
onMouseEnter={() => setIsDirectoryHovered(true)}
onMouseLeave={() => setIsDirectoryHovered(false)}
className="text-foreground-active hover:!bg-background-onlook hover:!text-foreground-active gap-2"
>
<Icons.File className="w-4 h-4" />
{isDirectoryHovered ? (
<Icons.DirectoryOpen className="w-4 h-4" />
) : (
<Icons.Directory className="w-4 h-4" />
)}
Open Project Folder
</DropdownMenuItem>
<DropdownMenuItem
Expand All @@ -101,7 +108,7 @@ export default function ProjectSettingsButton({ project }: { project: Project })
</DropdownMenuItem>
<DropdownMenuItem
onSelect={() => setShowDeleteDialog(true)}
className="gap-2 text-red-500 hover:!bg-red-400 hover:!text-red-800 dark:text-red-200 dark:hover:!bg-red-800 dark:hover:!text-red-100"
className="gap-2 text-red-400 hover:!bg-red-200/80 hover:!text-red-700 dark:text-red-200 dark:hover:!bg-red-800 dark:hover:!text-red-100"
>
<Icons.Trash className="w-4 h-4" />
Delete Project
Expand Down
36 changes: 36 additions & 0 deletions packages/ui/src/components/icons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,42 @@ export const Icons = {
</defs>
</svg>
),
Directory: ({ className, ...props }: IconProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={15}
height={15}
viewBox="0 0 15 15"
fill="none"
className={className}
{...props}
>
<path
d="M2 11.5C2 11.7761 2.22386 12 2.5 12H12.5C12.7761 12 13 11.7761 13 11.5V5C13 4.72386 12.7761 4.5 12.5 4.5H9.5H7.83333C7.50878 4.5 7.19298 4.39473 6.93333 4.2L5.33333 3H2.5C2.22386 3 2 3.22386 2 3.5L2 6.5L2 11.5ZM2.5 13C1.67157 13 1 12.3284 1 11.5L1 6.5L1 3.5C1 2.67157 1.67157 2 2.5 2H5.41667C5.57894 2 5.73684 2.05263 5.86667 2.15L7.53333 3.4C7.61988 3.46491 7.72515 3.5 7.83333 3.5H9.5H12.5C13.3284 3.5 14 4.17157 14 5V11.5C14 12.3284 13.3284 13 12.5 13H2.5Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
/>
</svg>
),
DirectoryOpen: ({ className, ...props }: IconProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={15}
height={15}
viewBox="0 0 15 15"
fill="none"
className={className}
{...props}
>
<path
d="M2.13713 11.844C2.22824 11.9401 2.35712 12 2.5 12H11.6916C11.9274 12 12.1311 11.8353 12.1805 11.6048L13.2519 6.60477C13.3186 6.29351 13.0813 6 12.763 6H12.5L3.80842 6C3.57265 6 3.36892 6.1647 3.31951 6.39524L3.1139 7.35476L2.7389 9.10476L2.3639 10.8548L2.1764 11.7298C2.16774 11.7702 2.15442 11.8084 2.13713 11.844ZM2 7.78036L2.1361 7.14524L2.34171 6.18571C2.48991 5.4941 3.10111 5 3.80842 5L12 5C12 4.72386 11.7761 4.5 11.5 4.5H9.5H7.83333C7.50878 4.5 7.19298 4.39473 6.93333 4.2L5.33333 3H2.5C2.22386 3 2 3.22386 2 3.5L2 6.5L2 7.78036ZM13 5.01844V5C13 4.17157 12.3284 3.5 11.5 3.5H9.5H7.83333C7.72515 3.5 7.61988 3.46491 7.53333 3.4L5.86667 2.15C5.73684 2.05263 5.57894 2 5.41667 2H2.5C1.67157 2 1 2.67157 1 3.5L1 6.5L1 11.5C1 12.3284 1.67157 13 2.5 13H11.6916C12.3989 13 13.0101 12.5059 13.1583 11.8143L14.2297 6.81429C14.4129 5.95961 13.832 5.14952 13 5.01844Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
/>
</svg>
),
EyeDropper: ({ className, ...props }: IconProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand Down

0 comments on commit f8b7bfd

Please sign in to comment.