Skip to content

Commit

Permalink
Merge pull request #880 from abhiroopc84/feat/window-settings
Browse files Browse the repository at this point in the history
Feat/window settings
  • Loading branch information
Kitenite authored Dec 12, 2024
2 parents b64255b + 531668a commit 692d928
Show file tree
Hide file tree
Showing 9 changed files with 312 additions and 11 deletions.
3 changes: 1 addition & 2 deletions apps/studio/electron/main/requirements/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ function checkNodeInstallation(): boolean {
`${process.env.VOLTA_HOME}/bin`, // Volta
`${process.env.HOME}/.volta/bin`, // Volta
`${process.env.HOME}/.asdf/installs/nodejs`, // ASDF
]
.filter(Boolean);
].filter(Boolean);

const existingPath = process.env.PATH || '';
const pathSeparator = process.platform === 'win32' ? ';' : ':';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Button } from '@onlook/ui/button';
import { Icons } from '@onlook/ui/icons/index';
import { useState } from 'react';

enum DeviceTheme {
Device = 'Device',
Dark = 'Dark',
Light = 'Light',
}

const DeviceSettings = () => {
const [deviceTheme, setDeviceTheme] = useState(DeviceTheme.Device);

return (
<div className="flex flex-col gap-2">
<p className="text-smallPlus text-foreground-primary">Device Settings</p>
<div className="flex flex-row justify-between items-center">
<span className="text-xs text-foreground-secondary">Theme</span>
<div className="flex flex-row p-0.5 w-3/5 bg-background-secondary rounded">
<Button
size={'icon'}
className={`h-full w-full px-0.5 py-1.5 bg-background-secondary rounded-sm ${
deviceTheme === DeviceTheme.Device
? 'bg-background-tertiary hover:bg-background-tertiary'
: 'hover:bg-background-tertiary/50 text-foreground-onlook'
}`}
variant={'ghost'}
onClick={() =>
deviceTheme !== DeviceTheme.Device && setDeviceTheme(DeviceTheme.Device)
}
>
<Icons.Laptop />
</Button>
<Button
size={'icon'}
className={`h-full w-full px-0.5 py-1.5 bg-background-secondary rounded-sm ${
deviceTheme === DeviceTheme.Dark
? 'bg-background-tertiary hover:bg-background-tertiary'
: 'hover:bg-background-tertiary/50 text-foreground-onlook'
}`}
variant={'ghost'}
onClick={() =>
deviceTheme !== DeviceTheme.Dark && setDeviceTheme(DeviceTheme.Dark)
}
>
<Icons.Moon />
</Button>
<Button
size={'icon'}
className={`h-full w-full px-0.5 py-1.5 bg-background-secondary rounded-sm ${
deviceTheme === DeviceTheme.Light
? 'bg-background-tertiary hover:bg-background-tertiary'
: 'hover:bg-background-tertiary/50 text-foreground-onlook'
}`}
variant={'ghost'}
onClick={() =>
deviceTheme !== DeviceTheme.Light && setDeviceTheme(DeviceTheme.Light)
}
>
<Icons.Sun />
</Button>
</div>
</div>
</div>
);
};

export default DeviceSettings;
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import { Button } from '@onlook/ui/button';
import { Icons } from '@onlook/ui/icons/index';
import { Input } from '@onlook/ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@onlook/ui/select';
import { useState } from 'react';

const deviceOptions = [
'iPhone SE',
'iPhone 12',
'iPhone 12 Pro',
'iPhone 12 Pro Max',
'iPhone 11',
'iPhone 11 Pro',
'iPhone 11 Pro Max',
'Google Pixel 5',
'Google Pixel 4a',
'Samsung Galaxy S21',
'Samsung Galaxy S21+',
'Samsung Galaxy S21 Ultra',
'Samsung Galaxy Note 20',
'Samsung Galaxy Note 20 Ultra',
'OnePlus 9',
'OnePlus 9 Pro',
];

enum Orientation {
Potrait = 'Potrait',
Landscape = 'Landscape',
}

const FrameDimensions = () => {
const [device, setDevice] = useState('iPhone SE');
const [orientation, setOrientation] = useState(Orientation.Potrait);
const [width, setWidth] = useState('375px');
const [height, setHeight] = useState('667px');
const [responsive, setResponsive] = useState('Closest Size');

return (
<div className="flex flex-col gap-2">
<p className="text-smallPlus text-foreground-primary">Frame Dimensions</p>
<div className="flex flex-row justify-between items-center">
<span className="text-xs text-foreground-secondary">Device</span>
<Select value={device} onValueChange={setDevice}>
<SelectTrigger className="w-3/5 bg-background-secondary border-background-secondary py-1.5 px-2 h-fit text-xs rounded focus:outline-none focus:ring-0">
<SelectValue placeholder="Select device" />
</SelectTrigger>
<SelectContent className="rounded-md bg-background-secondary">
{deviceOptions.map((deviceName) => (
<SelectItem
key={deviceName}
value={deviceName}
className="focus:bg-background-tertiary rounded-md text-xs cursor-pointer"
>
{deviceName}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="flex flex-row justify-between items-center">
<span className="text-xs text-foreground-secondary">Orientation</span>
<div className="flex flex-row p-0.5 w-3/5 bg-background-secondary rounded">
<Button
size={'icon'}
className={`h-full w-full px-0.5 py-1.5 bg-background-secondary rounded-sm ${orientation === Orientation.Potrait ? 'bg-background-tertiary hover:bg-background-tertiary' : 'hover:bg-background-tertiary/50'}`}
variant={'ghost'}
onClick={() =>
orientation === Orientation.Landscape &&
setOrientation(Orientation.Potrait)
}
>
<Icons.Potrait
className={`h-4 w-4 ${orientation !== Orientation.Potrait ? 'text-foreground-secondary hover:text-foreground-onlook' : ''}`}
/>
</Button>
<Button
size={'icon'}
className={`h-full w-full px-0.5 py-1.5 bg-background-secondary rounded-sm ${orientation === 'Landscape' ? 'bg-background-tertiary hover:bg-background-tertiary' : 'hover:bg-background-tertiary/50'}`}
variant={'ghost'}
onClick={() =>
orientation === Orientation.Potrait &&
setOrientation(Orientation.Landscape)
}
>
<Icons.Landscape
className={`h-4 w-4 ${orientation !== Orientation.Landscape ? 'text-foreground-secondary hover:text-foreground-onlook' : ''}`}
/>
</Button>
</div>
</div>
<div className="flex flex-row justify-between items-center">
<span className="text-xs text-foreground-secondary">Width</span>
<div className="relative w-3/5">
<Input
className="w-full px-2 h-8 text-xs rounded border-none text-foreground-active bg-background-secondary text-start focus:outline-none focus:ring-0 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
value={width}
onChange={(event) => setWidth(event.target.value)}
/>
<Button
size={'icon'}
className="p-0 h-fit w-fit absolute right-2 top-1/2 transform -translate-y-1/2"
variant={'ghost'}
>
<Icons.Link className="text-foreground-secondary" />
</Button>
</div>
</div>
<div className="flex flex-row justify-between items-center">
<span className="text-xs text-foreground-secondary">Height</span>
<div className="relative w-3/5">
<Input
className="w-full px-2 h-8 text-xs rounded border-none text-foreground-active bg-background-secondary text-start focus:outline-none focus:ring-0 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
value={height}
onChange={(event) => setHeight(event.target.value)}
/>
<Button
size={'icon'}
className="p-0 h-fit w-fit absolute right-2 top-1/2 transform -translate-y-1/2"
variant={'ghost'}
>
<Icons.Link className="text-foreground-secondary" />
</Button>
</div>
</div>
<div className="flex flex-row justify-between items-center">
<span className="text-xs text-foreground-secondary">Responsive</span>
<Select value={responsive} onValueChange={setResponsive}>
<SelectTrigger className="w-3/5 rounded bg-background-secondary border-background-secondary px-2 h-8 text-xs">
<SelectValue placeholder="Select size" defaultValue={'Closest Size'} />
</SelectTrigger>
<SelectContent className="rounded-md bg-background-secondary">
<SelectItem
value="Closest Size"
className="focus:bg-background-tertiary rounded-md text-xs cursor-pointer"
>
Closest Size
</SelectItem>
</SelectContent>
</Select>
</div>
</div>
);
};

export default FrameDimensions;
49 changes: 49 additions & 0 deletions apps/studio/src/routes/editor/EditPanel/WindowSettings/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Button } from '@onlook/ui/button';
import { Icons } from '@onlook/ui/icons/index';
import { Separator } from '@onlook/ui/separator';
import FrameDimensions from './FrameDimensions';
import DeviceSettings from './DeviceSettings';

const WindowSettings = ({ setIsOpen }: { setIsOpen: (isOpen: boolean) => void }) => {
return (
<div className="flex flex-col">
<div className="rounded-lg p-1 text-muted-foreground bg-transparent w-full gap-2 select-none justify-between items-center h-full px-2">
<div className="flex flex-row items-center gap-2">
<button
className="text-default rounded-lg p-2 bg-transparent hover:text-foreground-hover"
onClick={() => setIsOpen(false)}
>
<Icons.PinRight />
</button>
<div className="bg-transparent py-2 px-1 text-xs text-foreground-primary">
Window
</div>
</div>
</div>
<Separator />
<div className="flex flex-col gap-3 px-3 py-2">
<div className="flex flex-row gap-1">
<Button
variant={'outline'}
className="h-fit py-1.5 px-2.5 text-foreground-tertiary w-full items-center"
>
<Icons.Copy className="mr-2" />
<span className="text-xs">Duplicate</span>
</Button>
<Button
variant={'outline'}
className="h-fit py-1.5 px-2.5 text-foreground-tertiary w-full items-center"
>
<Icons.Trash className="mr-2" />
<span className="text-xs">Delete</span>
</Button>
</div>
<FrameDimensions />
<Separator />
<DeviceSettings />
</div>
</div>
);
};

export default WindowSettings;
7 changes: 4 additions & 3 deletions apps/studio/src/routes/editor/EditPanel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEditorEngine } from '@/components/Context';
import { EditorMode } from '@/lib/models';
import { EditorMode, EditorTabValue } from '@/lib/models';
import { Icons } from '@onlook/ui/icons';
import { Separator } from '@onlook/ui/separator';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@onlook/ui/tabs';
Expand All @@ -9,12 +9,13 @@ import { useEffect, useState } from 'react';
import ChatTab from './ChatTab';
import ChatControls from './ChatTab/ChatControls';
import ManualTab from './StylesTab';
import { EditorTabValue } from '@/lib/models';
import WindowSettings from './WindowSettings';

const EditPanel = observer(() => {
const editorEngine = useEditorEngine();
const [isOpen, setIsOpen] = useState(true);
const [selectedTab, setSelectedTab] = useState<EditorTabValue>(editorEngine.editPanelTab);
const [windowSettingsOpen, setWindowSettingsOpen] = useState(false);

useEffect(() => {
tabChange(editorEngine.editPanelTab);
Expand Down Expand Up @@ -104,7 +105,7 @@ const EditPanel = observer(() => {
isOpen ? 'opacity-100 visible' : 'opacity-0 invisible',
)}
>
{renderTabs()}
{windowSettingsOpen ? <WindowSettings setIsOpen={setIsOpen} /> : renderTabs()}
</div>
</div>
);
Expand Down
Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-progress": "^1.1.0",
"@radix-ui/react-scroll-area": "^1.2.0",
"@radix-ui/react-select": "^2.1.1",
"@radix-ui/react-select": "^2.1.2",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.0",
Expand Down
34 changes: 34 additions & 0 deletions packages/ui/src/components/icons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,40 @@ export const Icons = {
{...props}
/>
),
Landscape: ({ className, ...props }: IconProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
className={className}
{...props}
>
<rect width="20" height="12" x="2" y="6" rx="2" />
</svg>
),
Potrait: ({ className, ...props }: IconProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
className={className}
{...props}
>
<rect width="12" height="20" x="6" y="2" rx="2" />
</svg>
),
ArrowDown: ArrowDownIcon,
ArrowLeft: ArrowLeftIcon,
ArrowRight: ArrowRightIcon,
Expand Down
15 changes: 10 additions & 5 deletions packages/ui/src/components/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,20 @@ const SelectTrigger = React.forwardRef<
<SelectPrimitive.Trigger
ref={ref}
className={cn(
'flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
'flex h-9 w-full items-center whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 relative',
className,
)}
{...props}
>
{children}
<SelectPrimitive.Icon asChild>
<CaretSortIcon className="h-4 w-4 opacity-50" />
</SelectPrimitive.Icon>
<div className="relative flex items-center w-full">
<div className="w-full overflow-hidden">
<div className="text-left overflow-hidden">{children}</div>
</div>
<div className="absolute right-[0px] top-0 h-full w-12 bg-gradient-to-r from-transparent to-background-secondary pointer-events-none" />
<SelectPrimitive.Icon asChild className="absolute right-[-6px]">
<CaretSortIcon className="h-4 w-4 flex-shrink-0 z-4" />
</SelectPrimitive.Icon>
</div>
</SelectPrimitive.Trigger>
));
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
Expand Down

0 comments on commit 692d928

Please sign in to comment.