Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build:
name: Build & Typecheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
cache: npm
- run: npm install
- run: npm run compile
- run: npm run prod:build
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup Node.js 18.x
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 18.x
- run: npm install
Expand Down
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18
94 changes: 94 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Contributing to quantecon-theme-src

Thank you for your interest in contributing to the QuantEcon theme!

## Prerequisites

- **Node.js** ≥ 18 (see `.nvmrc`)
- **npm** 8.x (see `packageManager` in `package.json`)

## Development Setup

```bash
# Clone the repository
git clone https://github.com/QuantEcon/quantecon-theme-src.git
cd quantecon-theme-src

# Install dependencies
npm install

# Start the development server (with hot reload)
npm run dev
```

The dev server runs at `http://localhost:3000` by default.

## Available Scripts

| Command | Description |
| ------------------- | ------------------------------------------------ |
| `npm run dev` | Start dev server with CSS watch + hot reload |
| `npm run prod:build`| Production build (CSS + Thebe assets + Remix) |
| `npm run compile` | TypeScript type-check (`tsc --noEmit`) |
| `npm run format` | Format code with Prettier |
| `npm run clean` | Remove build artifacts |

## Project Structure

```
app/
backend/ # Server-side loaders (Remix loader functions)
components/ # React components (toolbar/, sidebar, page layout)
hooks/ # Custom React hooks
routes/ # Remix route modules
root.tsx # App shell (document head, theme providers)
styles/
app.css # Tailwind CSS entry point
public/ # Static assets (logos, Thebe bundles)
patches/ # patch-package patches for upstream fixes
```

## Making Changes

1. **Create a branch** from `main`:
```bash
git checkout -b feat/my-feature
```

2. **Run type-checking** before committing:
```bash
npm run compile
```

3. **Test a production build** to catch build-time issues:
```bash
npm run prod:build
```

4. **Open a Pull Request** against `main`. CI will run type-check and build automatically.

## Commit Convention

We use conventional commits:

- `fix:` — Bug fixes
- `feat:` — New features
- `chore:` — Maintenance (deps, config, CI)
- `docs:` — Documentation only
- `ci:` — CI/workflow changes

## Releases

Releases are managed via [Changesets](https://github.com/changesets/changesets). To propose a version bump:

```bash
npm run changeset
```

Follow the prompts, then commit the generated changeset file with your PR.

## Notes

- The theme is built on [Remix v1](https://remix.run/) and [@myst-theme](https://github.com/jupyter-book/myst-theme).
- Tailwind CSS is used for styling — see `tailwind.config.js` for the theme configuration.
- TypeScript strict mode is enabled — all code must pass `tsc --noEmit`.
4 changes: 2 additions & 2 deletions app/components/ProjectFrontmatter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export function ProjectFrontmatter({
)}
</div>
{authors && (
<div aira-label="Author names and links">
<div aria-label="Author names and links">
{authors.reduce<React.ReactNode>((acc, a, i, authors) => {
let chunk: React.ReactNode = a.name;
if (a.url) {
Expand All @@ -61,7 +61,7 @@ export function ProjectFrontmatter({
chunk = <> and {chunk}</>;
}
return (
<span>
<span key={a.id ?? a.name ?? i}>
{acc}
{chunk}
</span>
Expand Down
4 changes: 2 additions & 2 deletions app/components/toolbar/SidebarToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function SidebarToggle() {
})}
width={24}
height={24}
aria-label="Show table of contents"
aria-label="Hide table of contents"
/>
<Menu
className={classNames('absolute transition-all duration-300 ease-in-out hover:scale-110', {
Expand All @@ -25,7 +25,7 @@ export function SidebarToggle() {
})}
width={24}
height={24}
aria-label="Hide table of contents"
aria-label="Show table of contents"
/>
</button>
);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"katex": "^0.16.21"
},
"engines": {
"node": ">=14"
"node": ">=18"
},
"packageManager": "npm@8.10.0"
}
Loading