Skip to content

Commit 33175ba

Browse files
drfarrellKitenite
andauthored
UI sanding (#1406)
* moved zoom controls into left panel * moved undo / redo to the right, added Change IDE to Open Code Dropdown * fixed settings / subscriptions modal issue, editor --> Preferences in settings * clean up app bar, styles, add theme to settings * Move settings * Clean up mini code * Update IDE selector * Use custom modal for settings * Live button light mode --------- Co-authored-by: Kiet Ho <[email protected]>
1 parent 81617d4 commit 33175ba

File tree

23 files changed

+752
-380
lines changed

23 files changed

+752
-380
lines changed

apps/studio/src/components/AppBar/index.tsx

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { Icons } from '@onlook/ui/icons';
77
import { Tooltip, TooltipContent, TooltipTrigger } from '@onlook/ui/tooltip';
88
import { cn } from '@onlook/ui/utils';
99
import { observer } from 'mobx-react-lite';
10-
import { useTheme } from '../ThemeProvider';
1110
import { HotKeyLabel } from '../ui/hotkeys-label';
1211
import UpdateButton from './UpdateButton';
1312
import { WindowsControls } from './WindowsControls';
@@ -16,7 +15,6 @@ import { Hotkey } from '/common/hotkeys';
1615
const AppBar = observer(() => {
1716
const routeManager = useRouteManager();
1817
const updateManager = useUpdateManager();
19-
const { theme, nextTheme, setTheme } = useTheme();
2018
const className = cn(
2119
'opacity-50 hover:opacity-100',
2220
updateManager.updateAvailable &&
@@ -33,39 +31,6 @@ const AppBar = observer(() => {
3331
)}
3432
>
3533
<div className="appbar w-full h-full"></div>
36-
37-
<Tooltip>
38-
<TooltipTrigger asChild>
39-
<Button
40-
size="sm"
41-
variant="ghost"
42-
className={className}
43-
onClick={() => invokeMainChannel(MainChannels.RELOAD_APP)}
44-
>
45-
<Icons.Reload className="w-3.5" />
46-
</Button>
47-
</TooltipTrigger>
48-
<TooltipContent>
49-
<HotKeyLabel hotkey={Hotkey.RELOAD_APP} />
50-
</TooltipContent>
51-
</Tooltip>
52-
<Tooltip>
53-
<TooltipTrigger asChild>
54-
<Button
55-
size="sm"
56-
variant="ghost"
57-
className={className}
58-
onClick={() => {
59-
setTheme(nextTheme);
60-
}}
61-
>
62-
{theme === 'dark' && <Icons.Moon />}
63-
{theme === 'light' && <Icons.Sun />}
64-
{theme === 'system' && <Icons.Laptop />}
65-
</Button>
66-
</TooltipTrigger>
67-
<TooltipContent>Switch to {nextTheme} mode</TooltipContent>
68-
</Tooltip>
6934
<div className="flex mr-2 gap-2">
7035
<UpdateButton />
7136
</div>

apps/studio/src/lib/editor/engine/index.ts

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { EditorMode, EditorTabValue } from '@/lib/models';
1+
import { EditorMode, EditorTabValue, SettingsTabValue } from '@/lib/models';
22
import type { ProjectsManager } from '@/lib/projects';
3+
import type { UserManager } from '@/lib/user';
34
import { invokeMainChannel, sendAnalytics } from '@/lib/utils';
45
import { MainChannels } from '@onlook/models/constants';
56
import type { FrameSettings } from '@onlook/models/projects';
@@ -25,12 +26,14 @@ import { ProjectInfoManager } from './projectinfo';
2526
import { StyleManager } from './style';
2627
import { TextEditingManager } from './text';
2728
import { WebviewManager } from './webview';
28-
import type { UserManager } from '@/lib/user';
2929

3030
export class EditorEngine {
31-
private plansOpen: boolean = false;
32-
private editorMode: EditorMode = EditorMode.DESIGN;
33-
private editorPanelTab: EditorTabValue = EditorTabValue.CHAT;
31+
private _editorMode: EditorMode = EditorMode.DESIGN;
32+
private _plansOpen: boolean = false;
33+
private _settingsOpen: boolean = false;
34+
private _editorPanelTab: EditorTabValue = EditorTabValue.CHAT;
35+
private _settingsTab: SettingsTabValue = SettingsTabValue.DOMAIN;
36+
3437
private canvasManager: CanvasManager;
3538
private chatManager: ChatManager;
3639
private webviewManager: WebviewManager;
@@ -89,7 +92,7 @@ export class EditorEngine {
8992
return this.actionManager;
9093
}
9194
get mode() {
92-
return this.editorMode;
95+
return this._editorMode;
9396
}
9497
get insert() {
9598
return this.insertManager;
@@ -122,34 +125,47 @@ export class EditorEngine {
122125
return this.imageManager;
123126
}
124127
get editPanelTab() {
125-
return this.editorPanelTab;
128+
return this._editorPanelTab;
129+
}
130+
get settingsTab() {
131+
return this._settingsTab;
126132
}
127133
get isPlansOpen() {
128-
return this.plansOpen;
134+
return this._plansOpen;
135+
}
136+
get isSettingsOpen() {
137+
return this._settingsOpen;
129138
}
130139
get errors() {
131140
return this.errorManager;
132141
}
133-
134142
get isWindowSelected() {
135143
return this.webviews.selected.length > 0 && this.elements.selected.length === 0;
136144
}
137145

138146
set mode(mode: EditorMode) {
139-
this.editorMode = mode;
147+
this._editorMode = mode;
140148
}
141149

142150
set editPanelTab(tab: EditorTabValue) {
143-
this.editorPanelTab = tab;
151+
this._editorPanelTab = tab;
152+
}
153+
154+
set settingsTab(tab: SettingsTabValue) {
155+
this._settingsTab = tab;
144156
}
145157

146158
set isPlansOpen(open: boolean) {
147-
this.plansOpen = open;
159+
this._plansOpen = open;
148160
if (open) {
149161
sendAnalytics('open pro checkout');
150162
}
151163
}
152164

165+
set isSettingsOpen(open: boolean) {
166+
this._settingsOpen = open;
167+
}
168+
153169
get pages() {
154170
return this.pagesManager;
155171
}
@@ -174,8 +190,11 @@ export class EditorEngine {
174190
this.groupManager?.dispose();
175191
this.canvasManager?.clear();
176192
this.imageManager?.dispose();
177-
this.editorMode = EditorMode.DESIGN;
178-
this.editorPanelTab = EditorTabValue.STYLES;
193+
this._editorMode = EditorMode.DESIGN;
194+
this._editorPanelTab = EditorTabValue.STYLES;
195+
this._settingsTab = SettingsTabValue.DOMAIN;
196+
this._settingsOpen = false;
197+
this._plansOpen = false;
179198
}
180199

181200
clearUI() {

apps/studio/src/lib/models.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,9 @@ export enum EditorTabValue {
1818
CHAT = 'chat',
1919
PROPS = 'properties',
2020
}
21+
22+
export enum SettingsTabValue {
23+
DOMAIN = 'domain',
24+
PROJECT = 'project',
25+
PREFERENCES = 'preferences',
26+
}

apps/studio/src/routes/editor/EditPanel/ChatTab/ChatInput.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ export const ChatInput = observer(() => {
295295
disabled
296296
? projectsManager.runner?.isRunning ||
297297
projectsManager.runner?.isStarting
298-
? 'Select an element to start'
298+
? 'Select an element to chat'
299299
: 'Start the project to chat'
300300
: 'Ask follow up questions or provide more context...'
301301
}

apps/studio/src/routes/editor/EditPanel/WindowSettings/DeviceSettings.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const DeviceSettings = ({ settings }: { settings: FrameSettings }) => {
3232
}
3333

3434
const themeValue =
35-
theme === Theme.Device ? 'device' : theme === Theme.Dark ? 'dark' : 'light';
35+
theme === Theme.System ? 'device' : theme === Theme.Dark ? 'dark' : 'light';
3636

3737
webview.executeJavaScript(`window.api?.setTheme("${themeValue}")`).then((res) => {
3838
setDeviceTheme(theme);
@@ -52,12 +52,12 @@ const DeviceSettings = ({ settings }: { settings: FrameSettings }) => {
5252
<Button
5353
size={'icon'}
5454
className={`h-full w-full px-0.5 py-1.5 bg-background-secondary rounded-sm ${
55-
deviceTheme === Theme.Device
55+
deviceTheme === Theme.System
5656
? 'bg-background-tertiary hover:bg-background-tertiary'
5757
: 'hover:bg-background-tertiary/50 text-foreground-onlook'
5858
}`}
5959
variant={'ghost'}
60-
onClick={() => changeTheme(Theme.Device)}
60+
onClick={() => changeTheme(Theme.System)}
6161
>
6262
<Icons.Laptop />
6363
</Button>

apps/studio/src/routes/editor/EditPanel/index.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ const EditPanel = observer(() => {
8080
>
8181
<div className="flex items-center">
8282
<TabsTrigger
83-
className="bg-transparent py-2 px-1 text-xs hover:text-foreground-hover"
83+
className="bg-transparent py-2 px-1 text-small hover:text-foreground-hover"
8484
value={EditorTabValue.CHAT}
8585
>
86-
<Icons.Sparkles className="mr-1.5 mb-0.5" />
86+
<Icons.Sparkles className="mr-1.5 mb-0.5 h-4 w-4" />
8787
Chat
8888
<Icons.ChevronDown className="ml-1 h-3 w-3 text-muted-foreground" />
8989
</TabsTrigger>
@@ -150,10 +150,10 @@ const EditPanel = observer(() => {
150150
</DropdownMenuContent>
151151
</DropdownMenu>
152152
<TabsTrigger
153-
className="bg-transparent py-2 px-1 text-xs hover:text-foreground-hover"
153+
className="bg-transparent py-2 px-1 text-small hover:text-foreground-hover"
154154
value={EditorTabValue.STYLES}
155155
>
156-
<Icons.Styles className="mr-1.5" />
156+
<Icons.Styles className="mr-1.5 h-4 w-4" />
157157
Styles
158158
</TabsTrigger>
159159
</div>
Lines changed: 96 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
1+
import { useEditorEngine } from '@/components/Context';
2+
import { useTheme } from '@/components/ThemeProvider';
13
import { invokeMainChannel } from '@/lib/utils';
2-
import { Links, MainChannels } from '@onlook/models/constants';
4+
import { Links, MainChannels, Theme } from '@onlook/models/constants';
35
import {
46
DropdownMenu,
57
DropdownMenuContent,
68
DropdownMenuItem,
79
DropdownMenuSeparator,
10+
DropdownMenuSub,
11+
DropdownMenuSubContent,
12+
DropdownMenuSubTrigger,
813
DropdownMenuTrigger,
914
} from '@onlook/ui/dropdown-menu';
1015
import { Icons } from '@onlook/ui/icons';
16+
import { observer } from 'mobx-react-lite';
17+
import { useState } from 'react';
18+
19+
export const HelpDropdown = observer(() => {
20+
const editorEngine = useEditorEngine();
21+
const { theme, setTheme } = useTheme();
22+
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
1123

12-
export const HelpDropdown = () => {
1324
return (
14-
<DropdownMenu>
25+
<DropdownMenu open={isDropdownOpen} onOpenChange={setIsDropdownOpen}>
1526
<DropdownMenuTrigger asChild>
1627
<button className="w-16 h-16 rounded-xl flex flex-col items-center justify-center gap-1.5 p-2 text-muted-foreground hover:text-foreground">
1728
<Icons.QuestionMarkCircled className="w-5 h-5" />
@@ -21,38 +32,98 @@ export const HelpDropdown = () => {
2132
align="end"
2233
side="left"
2334
alignOffset={55}
24-
sideOffset={-45}
35+
sideOffset={-55}
2536
className="w-48"
2637
>
27-
<DropdownMenuItem onClick={() => window.open('https://onlook.com', '_blank')}>
28-
<Icons.InfoCircled className="w-4 h-4 mr-2" />
29-
About Onlook
30-
</DropdownMenuItem>
31-
<DropdownMenuItem onClick={() => window.open(Links.DISCORD, '_blank')}>
32-
<Icons.DiscordLogo className="w-4 h-4 mr-2" />
33-
Join our Discord
34-
</DropdownMenuItem>
35-
<DropdownMenuItem onClick={() => window.open(Links.GITHUB, '_blank')}>
36-
<Icons.GitHubLogo className="w-4 h-4 mr-2" />
37-
Visit our GitHub
38+
<DropdownMenuItem onClick={() => invokeMainChannel(MainChannels.RELOAD_APP)}>
39+
<Icons.Reload className="w-4 h-4 mr-2" />
40+
Reload Onlook
3841
</DropdownMenuItem>
39-
<DropdownMenuSeparator />
42+
<DropdownMenuSub>
43+
<DropdownMenuSubTrigger className="text-sm">
44+
{theme === Theme.Dark && <Icons.Moon className="w-4 h-4 mr-2" />}
45+
{theme === Theme.Light && <Icons.Sun className="w-4 h-4 mr-2" />}
46+
{theme === Theme.System && <Icons.Laptop className="w-4 h-4 mr-2" />}
47+
Theme
48+
</DropdownMenuSubTrigger>
49+
<DropdownMenuSubContent className="w-32 ml-2">
50+
<DropdownMenuItem
51+
className="text-sm"
52+
onClick={() => {
53+
setTheme(Theme.Light);
54+
}}
55+
>
56+
<Icons.Sun className="w-4 h-4 mr-2" />
57+
Light
58+
</DropdownMenuItem>
59+
<DropdownMenuItem
60+
className="text-sm"
61+
onClick={() => {
62+
setTheme(Theme.Dark);
63+
}}
64+
>
65+
<Icons.Moon className="w-4 h-4 mr-2" />
66+
Dark
67+
</DropdownMenuItem>
68+
<DropdownMenuItem
69+
className="text-sm"
70+
onClick={() => {
71+
setTheme(Theme.System);
72+
}}
73+
>
74+
<Icons.Laptop className="w-4 h-4 mr-2" />
75+
System
76+
</DropdownMenuItem>
77+
</DropdownMenuSubContent>
78+
</DropdownMenuSub>
4079
<DropdownMenuItem
41-
onClick={() =>
42-
invokeMainChannel(
43-
MainChannels.OPEN_EXTERNAL_WINDOW,
44-
45-
)
46-
}
80+
className="text-sm"
81+
onClick={() => {
82+
editorEngine.isSettingsOpen = true;
83+
}}
4784
>
48-
<Icons.EnvelopeClosed className="w-4 h-4 mr-2" />
49-
Email Us
85+
<Icons.Gear className="w-4 h-4 mr-2" />
86+
Open Settings
5087
</DropdownMenuItem>
88+
<DropdownMenuSeparator />
89+
<DropdownMenuSub>
90+
<DropdownMenuSubTrigger className="text-sm">
91+
<Icons.EnvelopeClosed className="w-4 h-4 mr-2" />
92+
Contact Us
93+
</DropdownMenuSubTrigger>
94+
<DropdownMenuSubContent className="w-48 ml-2">
95+
<DropdownMenuItem
96+
onClick={() => window.open('https://onlook.com', '_blank')}
97+
>
98+
<Icons.Globe className="w-4 h-4 mr-2" />
99+
Website
100+
</DropdownMenuItem>
101+
<DropdownMenuItem onClick={() => window.open(Links.DISCORD, '_blank')}>
102+
<Icons.DiscordLogo className="w-4 h-4 mr-2" />
103+
Discord
104+
</DropdownMenuItem>
105+
<DropdownMenuItem onClick={() => window.open(Links.GITHUB, '_blank')}>
106+
<Icons.GitHubLogo className="w-4 h-4 mr-2" />
107+
GitHub
108+
</DropdownMenuItem>
109+
<DropdownMenuItem
110+
onClick={() =>
111+
invokeMainChannel(
112+
MainChannels.OPEN_EXTERNAL_WINDOW,
113+
114+
)
115+
}
116+
>
117+
<Icons.EnvelopeClosed className="w-4 h-4 mr-2" />
118+
Email
119+
</DropdownMenuItem>
120+
</DropdownMenuSubContent>
121+
</DropdownMenuSub>
51122
<DropdownMenuItem onClick={() => window.open(Links.OPEN_ISSUE, '_blank')}>
52123
<Icons.ExclamationTriangle className="w-4 h-4 mr-2" />
53124
Report Issue
54125
</DropdownMenuItem>
55126
</DropdownMenuContent>
56127
</DropdownMenu>
57128
);
58-
};
129+
});

0 commit comments

Comments
 (0)