Skip to content

Commit e71e4d8

Browse files
committed
getting started
1 parent 831472e commit e71e4d8

File tree

5 files changed

+122
-7
lines changed

5 files changed

+122
-7
lines changed
110 KB
Loading
99 KB
Loading

docs/public/thunder-app-cli.png

42.4 KB
Loading

docs/src/components/tableOfContents/TableOfContents.tsx

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,29 @@ export const TableOfContents: React.FC = () => {
4646
if (headingElements.length === 0) return;
4747

4848
// Find the scrollable container
49-
const scrollContainer = headingElements[0]?.closest(
50-
".overflow-y-auto",
51-
) as HTMLElement | null;
49+
const scrollContainer = headingElements[0]?.closest(".overflow-y-auto");
50+
51+
if (!scrollContainer) return;
52+
53+
let scrollTimeout: ReturnType<typeof setTimeout> | null = null;
54+
const checkActiveHeading = () => {
55+
if (manualScrollRef.current !== null) {
56+
return;
57+
}
58+
59+
// Only handle the "at top" case - let IntersectionObserver handle the rest
60+
if (scrollContainer.scrollTop < 100) {
61+
setActiveId(headings[0]?.id ?? "");
62+
}
63+
};
64+
65+
const throttledCheckActiveHeading = () => {
66+
if (scrollTimeout) return;
67+
scrollTimeout = setTimeout(() => {
68+
checkActiveHeading();
69+
scrollTimeout = null;
70+
}, 100);
71+
};
5272

5373
const observer = new IntersectionObserver(
5474
(entries) => {
@@ -57,6 +77,12 @@ export const TableOfContents: React.FC = () => {
5777
if (manualScrollRef.current !== null) {
5878
return;
5979
}
80+
81+
// Skip if we're at the top (let scroll handler deal with it)
82+
if (scrollContainer.scrollTop < 100) {
83+
return;
84+
}
85+
6086
// Pick the most visible intersecting heading (highest intersectionRatio)
6187
let best: IntersectionObserverEntry | null = null;
6288
for (const entry of entries) {
@@ -76,17 +102,31 @@ export const TableOfContents: React.FC = () => {
76102
root: scrollContainer,
77103
rootMargin: "-100px 0px -66%",
78104
threshold: [0, 0.5, 1],
79-
},
105+
}
80106
);
81107

82108
headingElements.forEach((element) => {
83109
observer.observe(element);
84110
});
85111

112+
// Check on scroll to handle top case (throttled)
113+
scrollContainer.addEventListener("scroll", throttledCheckActiveHeading, {
114+
passive: true,
115+
});
116+
// Initial check
117+
checkActiveHeading();
118+
86119
return () => {
87120
headingElements.forEach((element) => {
88121
observer.unobserve(element);
89122
});
123+
scrollContainer.removeEventListener(
124+
"scroll",
125+
throttledCheckActiveHeading
126+
);
127+
if (scrollTimeout) {
128+
clearTimeout(scrollTimeout);
129+
}
90130
};
91131
}, [headings]);
92132

@@ -102,9 +142,7 @@ export const TableOfContents: React.FC = () => {
102142
manualScrollRef.current = id;
103143

104144
// Find the scrollable container (the content area)
105-
const scrollContainer = element.closest(
106-
".overflow-y-auto",
107-
) as HTMLElement | null;
145+
const scrollContainer = element.closest(".overflow-y-auto");
108146
if (scrollContainer) {
109147
// Get the current scroll position
110148
const currentScrollTop = scrollContainer.scrollTop;
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,80 @@
11
# Getting Started
22

33
Get up and running with Thunder App in minutes.
4+
5+
## Prerequisites
6+
7+
Before you begin, make sure you have the following installed:
8+
9+
- **Bun** (v1.3 or later) - [Install Bun](https://bun.sh/docs/installation)
10+
- **Node.js** (v22 or later) - Required for some tooling, though Bun handles most of it
11+
12+
_Note: Earlier versions may work but have not been tested_
13+
14+
## Installation
15+
16+
To create a new Thunder App project, run:
17+
18+
```bash
19+
bun create thunder-app@latest
20+
```
21+
22+
The CLI will guide you through the setup process and ask you a few questions about your project configuration.
23+
24+
![Thunder App CLI](/thunder-app-cli.png)
25+
26+
Once the project is created, navigate into your new project directory:
27+
28+
```bash
29+
cd <your-app-name>
30+
```
31+
32+
### Environment Variables
33+
34+
Copy the example environment files for both `frontend` and `backend` and fill in your values. You can see which variables are required by trying to spin up the app.
35+
36+
The backend will show invalid environment variables in the terminal:
37+
38+
![Invalid Env Vars Backend](/invalid-env-backend.png)
39+
40+
And the frontend will show invalid environment variables in the browser console:
41+
42+
![Invalid Env Vars Frontend](/invalid-env-frontend.png)
43+
44+
### Database Setup
45+
46+
Thunder App uses Drizzle ORM with PostgreSQL. To set up your database:
47+
48+
1. Make sure PostgreSQL is running
49+
2. Update your database connection string in `backend/.env`
50+
3. Run the database migrations:
51+
52+
```bash
53+
bun run db:push
54+
```
55+
56+
## Running the Development Server
57+
58+
Start all development environments simultaneously by running this command from the root of the monorepo:
59+
60+
```bash
61+
bun run dev
62+
```
63+
64+
This will start:
65+
66+
- Frontend dev server (defaults to `http://localhost:5173`)
67+
- Lib (watches for file changes)
68+
- Backend API server (defaults to `http://localhost:3000`)
69+
70+
All services support hot module replacement, so your changes will be reflected immediately.
71+
72+
## Next Steps
73+
74+
Now that you're up and running, here are some recommended next steps:
75+
76+
1. **Explore the Project Structure** - Check out the [Project Structure](/project-structure) guide to understand how everything is organized
77+
2. **Set Up Authentication** - Configure Auth.js for user authentication
78+
3. **Read the First Steps Guide** - Head over to [First Steps](/first-steps) for a walkthrough of common tasks
79+
80+
Happy coding!

0 commit comments

Comments
 (0)