mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
feat: support tailwind and daisyUI (#266)
* feat: support tailwind and daisyUI * feat: some styling improvements with daisyUI * fix: remove flex in app.css and edit height in CodeEditor
This commit is contained in:
parent
2590570109
commit
658b860d04
814
frontend/package-lock.json
generated
814
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -65,6 +65,8 @@
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.12",
|
||||
"@typescript-eslint/parser": "^7.0.0",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"daisyui": "^4.9.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
@ -77,7 +79,9 @@
|
||||
"jest": "^29.7.0",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"lint-staged": "^15.2.2",
|
||||
"postcss": "^8.4.38",
|
||||
"prettier": "^3.2.5",
|
||||
"tailwindcss": "^3.4.2",
|
||||
"ts-jest": "^29.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
6
frontend/postcss.config.js
Normal file
6
frontend/postcss.config.js
Normal file
@ -0,0 +1,6 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
@ -1,6 +1,9 @@
|
||||
/* App.css */
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
.app {
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
background-color: #1e1e1e;
|
||||
color: #fff;
|
||||
@ -36,8 +39,9 @@
|
||||
.workspace-heading {
|
||||
padding: 0 1rem;
|
||||
display: flex;
|
||||
margin: 1rem 0;
|
||||
justify-content: space-between;
|
||||
font-size: 20px;
|
||||
font-size: 30px;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
// App.tsx
|
||||
import React, { useState } from "react";
|
||||
import "./App.css";
|
||||
import ChatInterface from "./components/ChatInterface";
|
||||
@ -19,8 +18,11 @@ type TabProps = {
|
||||
};
|
||||
function Tab({ name, active, onClick }: TabProps): JSX.Element {
|
||||
return (
|
||||
<div className={`tab ${active ? "active" : ""}`} onClick={() => onClick()}>
|
||||
{name}
|
||||
<div
|
||||
className={`tab ${active ? "tab-active" : ""}`}
|
||||
onClick={() => onClick()}
|
||||
>
|
||||
<p className="font-bold">{name}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -48,31 +50,28 @@ function App(): JSX.Element {
|
||||
const [activeTab, setActiveTab] = useState<TabOption>("terminal");
|
||||
|
||||
return (
|
||||
<div className="app">
|
||||
<div className="app flex">
|
||||
<Errors />
|
||||
<div className="left-pane">
|
||||
<ChatInterface />
|
||||
</div>
|
||||
<div className="right-pane">
|
||||
<div className="workspace-content">
|
||||
<div className="workspace-heading">
|
||||
<p>OpenDevin's Workspace</p>
|
||||
<BannerSettings />
|
||||
</div>
|
||||
<div className="tab-container">
|
||||
{TAB_OPTIONS.map((tab) => (
|
||||
<Tab
|
||||
key={tab}
|
||||
name={tabData[tab].name}
|
||||
active={activeTab === tab}
|
||||
onClick={() => setActiveTab(tab)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{/* Keep terminal permanently open - see component for more details */}
|
||||
<Terminal key="terminal" hidden={activeTab !== "terminal"} />
|
||||
<div className="tab-content">{tabData[activeTab].component}</div>
|
||||
<div className="workspace-heading">
|
||||
<p>OpenDevin Workspace</p>
|
||||
</div>
|
||||
<div role="tablist" className="tabs tabs-bordered tabs-lg">
|
||||
{TAB_OPTIONS.map((tab) => (
|
||||
<Tab
|
||||
key={tab}
|
||||
name={tabData[tab].name}
|
||||
active={activeTab === tab}
|
||||
onClick={() => setActiveTab(tab)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{/* Keep terminal permanently open - see component for more details */}
|
||||
<Terminal key="terminal" hidden={activeTab !== "terminal"} />
|
||||
{tabData[activeTab].component}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -3,41 +3,56 @@ import "./Browser.css";
|
||||
import { useSelector } from "react-redux";
|
||||
import { RootState } from "../store";
|
||||
|
||||
type UrlBarProps = {
|
||||
url: string;
|
||||
};
|
||||
// type UrlBarProps = {
|
||||
// url: string;
|
||||
// };
|
||||
|
||||
function UrlBar({ url }: UrlBarProps): JSX.Element {
|
||||
return (
|
||||
<div className="mac-url-bar">
|
||||
<div className="left-icons">
|
||||
<div className="icon icon-red" />
|
||||
<div className="icon icon-yellow" />
|
||||
<div className="icon icon-green" />
|
||||
</div>
|
||||
<div className="url">{url}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
// function UrlBar({ url }: UrlBarProps): JSX.Element {
|
||||
// return (
|
||||
// <div className="mac-url-bar">
|
||||
// <div className="left-icons">
|
||||
// <div className="icon icon-red" />
|
||||
// <div className="icon icon-yellow" />
|
||||
// <div className="icon icon-green" />
|
||||
// </div>
|
||||
// <div className="url">{url}</div>
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
||||
type ScreenshotProps = {
|
||||
src: string;
|
||||
};
|
||||
// type ScreenshotProps = {
|
||||
// src: string;
|
||||
// };
|
||||
|
||||
function Screenshot({ src }: ScreenshotProps): JSX.Element {
|
||||
return <img className="screenshot" src={src} alt="screenshot" />;
|
||||
}
|
||||
// function Screenshot({ src }: ScreenshotProps): JSX.Element {
|
||||
// return <img className="screenshot" src={src} alt="screenshot" />;
|
||||
// }
|
||||
|
||||
function Browser(): JSX.Element {
|
||||
const url = useSelector((state: RootState) => state.browser.url);
|
||||
const screenshotSrc = useSelector(
|
||||
(state: RootState) => state.browser.screenshotSrc,
|
||||
);
|
||||
// const screenshotSrc = useSelector(
|
||||
// (state: RootState) => state.browser.screenshotSrc,
|
||||
// );
|
||||
|
||||
return (
|
||||
<div className="browser">
|
||||
<UrlBar url={url} />
|
||||
<Screenshot src={screenshotSrc} />
|
||||
// <div className="browser">
|
||||
// <UrlBar url={url} />
|
||||
// <Screenshot src={screenshotSrc} />
|
||||
// </div>
|
||||
<div
|
||||
className="mockup-browser"
|
||||
style={{
|
||||
background: "black",
|
||||
padding: "1rem",
|
||||
height: "90%",
|
||||
margin: "1rem",
|
||||
borderRadius: "1rem",
|
||||
}}
|
||||
>
|
||||
<div className="mockup-browser-toolbar">
|
||||
<div className="input">{url}</div>
|
||||
</div>
|
||||
{/* <div className="flex justify-center px-4 py-16 bg-base-100 " >Hello World!</div> */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ function MessageList(): JSX.Element {
|
||||
alt={`${msg.sender} avatar`}
|
||||
className="avatar"
|
||||
/>
|
||||
<div className="message-content">{msg.content}</div>
|
||||
<div className="chat chat-bubble">{msg.content}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
9
frontend/tailwind.config.js
Normal file
9
frontend/tailwind.config.js
Normal file
@ -0,0 +1,9 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: ['./src/**/*.{js,ts,jsx,tsx}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [require('daisyui')],
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user