feat: Story 9 - Remove scroll bars for cleaner UI

Implemented Story 9: Hidden Scroll Bars
- Added CSS to hide scroll bars globally while maintaining functionality
- Used scrollbar-width: none for Firefox
- Used ::-webkit-scrollbar { display: none; } for Chrome/Safari/Edge
- Set overflow-x: hidden to prevent unwanted horizontal scrolling
- Maintained full scroll functionality (mouse wheel, trackpad, keyboard)

Updated Specs
- Added Scroll Bar Styling section to UI_UX.md
- Documented cross-browser compatibility requirements
- Specified areas affected and implementation approach

Bug Fixes
- Fixed biome linting issues in App.tsx (import organization, button type)
- Applied biome formatter for consistent code style
This commit is contained in:
Dave
2025-12-25 15:23:49 +00:00
parent 990441dfc1
commit ed15279dae
8 changed files with 180 additions and 77 deletions

View File

@@ -1,88 +1,90 @@
import { useState, useEffect } from "react";
import { invoke } from "@tauri-apps/api/core";
import { open } from "@tauri-apps/plugin-dialog";
import { useEffect, useState } from "react";
import { Chat } from "./components/Chat";
import "./App.css";
function App() {
const [projectPath, setProjectPath] = useState<string | null>(null);
const [errorMsg, setErrorMsg] = useState<string | null>(null);
const [projectPath, setProjectPath] = useState<string | null>(null);
const [errorMsg, setErrorMsg] = useState<string | null>(null);
useEffect(() => {
invoke<string | null>("get_current_project")
.then((path) => {
if (path) setProjectPath(path);
})
.catch((e) => console.error(e));
}, []);
useEffect(() => {
invoke<string | null>("get_current_project")
.then((path) => {
if (path) setProjectPath(path);
})
.catch((e) => console.error(e));
}, []);
async function closeProject() {
try {
await invoke("close_project");
setProjectPath(null);
} catch (e) {
console.error(e);
}
}
async function closeProject() {
try {
await invoke("close_project");
setProjectPath(null);
} catch (e) {
console.error(e);
}
}
async function selectProject() {
try {
setErrorMsg(null);
// Open native folder picker
const selected = await open({
directory: true,
multiple: false,
});
async function selectProject() {
try {
setErrorMsg(null);
// Open native folder picker
const selected = await open({
directory: true,
multiple: false,
});
if (selected === null) {
// User cancelled selection
return;
}
if (selected === null) {
// User cancelled selection
return;
}
// Invoke backend command to verify and set state
// Note: invoke argument names must match Rust function args
const confirmedPath = await invoke<string>("open_project", {
path: selected,
});
setProjectPath(confirmedPath);
} catch (e) {
console.error(e);
setErrorMsg(
typeof e === "string" ? e : "An error occurred opening the project.",
);
}
}
// Invoke backend command to verify and set state
// Note: invoke argument names must match Rust function args
const confirmedPath = await invoke<string>("open_project", {
path: selected,
});
setProjectPath(confirmedPath);
} catch (e) {
console.error(e);
setErrorMsg(
typeof e === "string" ? e : "An error occurred opening the project.",
);
}
}
return (
<main
className="container"
style={{ height: "100vh", padding: 0, maxWidth: "100%" }}
>
{!projectPath ? (
<div
className="selection-screen"
style={{ padding: "2rem", maxWidth: "800px", margin: "0 auto" }}
>
<h1>AI Code Assistant</h1>
<p>
Please select a project folder to start the Story-Driven Spec
Workflow.
</p>
<button onClick={selectProject}>Open Project Directory</button>
</div>
) : (
<div className="workspace" style={{ height: "100%" }}>
<Chat projectPath={projectPath} onCloseProject={closeProject} />
</div>
)}
return (
<main
className="container"
style={{ height: "100vh", padding: 0, maxWidth: "100%" }}
>
{!projectPath ? (
<div
className="selection-screen"
style={{ padding: "2rem", maxWidth: "800px", margin: "0 auto" }}
>
<h1>AI Code Assistant</h1>
<p>
Please select a project folder to start the Story-Driven Spec
Workflow.
</p>
<button type="button" onClick={selectProject}>
Open Project Directory
</button>
</div>
) : (
<div className="workspace" style={{ height: "100%" }}>
<Chat projectPath={projectPath} onCloseProject={closeProject} />
</div>
)}
{errorMsg && (
<div className="error-message" style={{ marginTop: "20px" }}>
<p style={{ color: "red" }}>Error: {errorMsg}</p>
</div>
)}
</main>
);
{errorMsg && (
<div className="error-message" style={{ marginTop: "20px" }}>
<p style={{ color: "red" }}>Error: {errorMsg}</p>
</div>
)}
</main>
);
}
export default App;