Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
122b72f
Create @neaps/react package
bkeepers Feb 22, 2026
6b3ebeb
Extract TideConditions component
bkeepers Feb 23, 2026
5702b6a
Debounce Map
bkeepers Feb 23, 2026
69c3a91
Truncate station names in list
bkeepers Feb 24, 2026
5a41d26
Use theme colors on TideGraph
bkeepers Feb 24, 2026
0de0a09
Improvements to TideGraph
bkeepers Feb 24, 2026
7c6a564
Update components to support website
bkeepers Feb 24, 2026
7e11000
Major updates to react UI
bkeepers Feb 27, 2026
012e2cc
Fix tsc errors
bkeepers Feb 28, 2026
6e36fa2
Polyfill intersection observer
bkeepers Feb 28, 2026
ead08c8
Fix tests
bkeepers Feb 28, 2026
5945e6b
Publish packages to pkg.pr.new
bkeepers Feb 28, 2026
541b05d
Switch to browser testing
bkeepers Mar 1, 2026
490d675
Tweak graphs, Add unit/datum/timezone settings
bkeepers Mar 1, 2026
c13e109
Limit height of table
bkeepers Mar 1, 2026
bf3c3f3
Play with mobile experience on TideGraph
bkeepers Mar 1, 2026
c296e38
Allow previewing storybook on local network
bkeepers Mar 1, 2026
423829f
Refactor/simplify TideChart
bkeepers Mar 2, 2026
70a7185
Rearrange imports/exports
bkeepers Mar 2, 2026
25d9d67
Convert timestamps to Date objects in API client
bkeepers Mar 2, 2026
7984fc8
Set browser locale
bkeepers Mar 2, 2026
21374c4
Revert station types to avoid dep
bkeepers Mar 2, 2026
965195b
Cleanup
bkeepers Mar 2, 2026
450a0f5
Show TideConditions in map popup
bkeepers Mar 2, 2026
1beb607
Remove min-h on map
bkeepers Mar 2, 2026
b3d7244
Add mini station map story
bkeepers Mar 3, 2026
3dde08d
Fix lint error
bkeepers Mar 5, 2026
d219237
Fix bbox handling in Stations Map
bkeepers Mar 5, 2026
8d57268
Move test.yml => ci.yml workflow, publish to pkg.pr.new in separate job
bkeepers Mar 5, 2026
57a5c2a
Add aliases to run again local src
bkeepers Mar 5, 2026
b955a32
Build before publshing to pk.pr.new
bkeepers Mar 5, 2026
78614c7
Center date labels on sunrise/sunset midpoint
bkeepers Mar 5, 2026
9b4894b
Share vitest resolve config with storybook
bkeepers Mar 5, 2026
5f38954
Improve local alias handling
bkeepers Mar 5, 2026
c7f0eb5
Fix distance for nearby stations
bkeepers Mar 6, 2026
e42c50c
Exclude current station from nearby stations
bkeepers Mar 6, 2026
84e9f38
Fix lint errors
bkeepers Mar 6, 2026
9596180
Fix base url handling
bkeepers Mar 6, 2026
196b247
Add support for SSR hydration
bkeepers Mar 6, 2026
7250abb
Improve test coverage
bkeepers Mar 6, 2026
1b3af23
Add custom map text/bg overrides
bkeepers Mar 6, 2026
2b4cce8
Lint and test fixes
bkeepers Mar 6, 2026
db4794f
Add locale to prefetching
bkeepers Mar 6, 2026
8750b17
Exclude stories from coverage
bkeepers Mar 6, 2026
bc368fe
Use `color-scheme` css property to control dark mode
bkeepers Mar 7, 2026
2663cc3
Try setting default locale
bkeepers Mar 7, 2026
30e6bb8
Remove dark stories after adding theme toggle
bkeepers Mar 7, 2026
ea8d1e8
Make units explicit in flaky test
bkeepers Mar 7, 2026
c12079f
Remove settings from localstorage after each test
bkeepers Mar 7, 2026
638b20d
Merge remote-tracking branch 'origin/main' into react-ui
bkeepers Mar 8, 2026
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
29 changes: 28 additions & 1 deletion .github/workflows/test.yml → .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Test
name: CI
on:
push:

Expand Down Expand Up @@ -40,6 +40,7 @@ jobs:
runs-on: ubuntu-latest
permissions:
id-token: write
pull-requests: write
steps:
- uses: actions/checkout@v6

Expand All @@ -50,6 +51,12 @@ jobs:
- name: Install modules
run: npm install

- name: Install Playwright browsers
run: npx playwright install chromium

# Do not run npm build here! This intentonally runs tests against the unbuilt source
# to ensure that the tests are properly configured to run against the source files.

- name: Test
run: npm run coverage

Expand All @@ -60,6 +67,26 @@ jobs:
fail_ci_if_error: true
files: ./coverage/coverage-final.json

publish:
runs-on: ubuntu-latest
permissions:
id-token: write
pull-requests: write
steps:
- uses: actions/checkout@v6

- uses: actions/setup-node@v6
with:
node-version: "22"
- name: Install modules
run: npm install

- name: Build
run: npm run build

- name: Publish to pkg.pr.new
run: npx pkg-pr-new publish ./packages/*

benchmarks:
runs-on: ubuntu-latest
concurrency:
Expand Down
30 changes: 30 additions & 0 deletions aliases.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { readFileSync } from "node:fs";
import { resolve } from "node:path";

const root = import.meta.dirname;

interface PackageJson {
name: string;
workspaces?: string[];
}

const rootPkg: PackageJson = JSON.parse(readFileSync(resolve(root, "package.json"), "utf-8"));

/**
* Resolve aliases for all workspace packages to their `src/index.ts` entry
* points. Optionally exclude the current package (to avoid self-aliasing).
*/
export function aliases(exclude?: string): Record<string, string> {
const result: Record<string, string> = {};

for (const workspace of rootPkg.workspaces ?? []) {
const pkgPath = resolve(root, workspace, "package.json");
const pkg: PackageJson = JSON.parse(readFileSync(pkgPath, "utf-8"));

if (pkg.name === exclude) continue;

result[pkg.name] = resolve(root, workspace, "src/index.ts");
}

return result;
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"globals": "^17.2.0",
"make-fetch-happen": "^15.0.3",
"npm-run-all": "^4.1.5",
"pkg-pr-new": "^0.0.65",
"prettier": "^3.7.4",
"tsdown": "^0.21.0",
"typescript": "^5.3.3",
Expand All @@ -34,6 +35,7 @@
"packages/tide-predictor",
"packages/neaps",
"packages/api",
"packages/cli"
"packages/cli",
"packages/react"
]
}
6 changes: 2 additions & 4 deletions packages/api/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { defineProject } from "vitest/config";
import { resolve } from "node:path";
import { aliases } from "../../aliases.js";

export default defineProject({
resolve: {
alias: {
neaps: resolve(__dirname, "../neaps/src/index.ts"),
"@neaps/tide-predictor": resolve(__dirname, "../tide-predictor/src/index.ts"),
},
alias: aliases("@neaps/api"),
},
test: {
environment: "node",
Expand Down
7 changes: 2 additions & 5 deletions packages/cli/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { defineProject } from "vitest/config";
import { resolve } from "node:path";
import { aliases } from "../../aliases.js";

export default defineProject({
resolve: {
alias: {
neaps: resolve(__dirname, "../neaps/src/index.ts"),
"@neaps/api": resolve(__dirname, "../api/src/index.ts"),
"@neaps/tide-predictor": resolve(__dirname, "../tide-predictor/src/index.ts"),
},
alias: aliases("@neaps/cli"),
},
test: {
environment: "node",
Expand Down
5 changes: 2 additions & 3 deletions packages/neaps/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { defineProject } from "vitest/config";
import { resolve } from "node:path";
import { aliases } from "../../aliases.js";

export default defineProject({
resolve: {
alias: {
"@neaps/tide-predictor": resolve(__dirname, "../tide-predictor/src/index.ts"),
},
alias: aliases("neaps"),
},
test: {
environment: "node",
Expand Down
30 changes: 30 additions & 0 deletions packages/react/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { StorybookConfig } from "@storybook/react-vite";
import tailwindcss from "@tailwindcss/vite";
import { createApp } from "@neaps/api";

const API_PORT = 6007;

const config: StorybookConfig = {
stories: ["../src/**/*.stories.@(ts|tsx)"],
addons: ["@storybook/addon-themes"],
framework: {
name: "@storybook/react-vite",
options: {},
},
viteFinal(config) {
config.plugins ??= [];
config.plugins.push(tailwindcss());
config.plugins.push({
name: "neaps-api",
async configureServer() {
const app = createApp();
app.listen(API_PORT, "0.0.0.0", () => {
console.log(`Neaps API listening on http://0.0.0.0:${API_PORT}`);
});
},
});
return config;
},
};

export default config;
6 changes: 6 additions & 0 deletions packages/react/.storybook/manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { addons } from "storybook/internal/manager-api";
import { light, dark } from "./theme.js";

const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;

addons.setConfig({ theme: prefersDark ? dark : light });
34 changes: 34 additions & 0 deletions packages/react/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Preview } from "@storybook/react";
import { withThemeByDataAttribute } from "@storybook/addon-themes";
import { NeapsProvider } from "../src/provider.js";
import "./storybook.css";

const API_URL = `${window.location.protocol}//${window.location.hostname}:6007`;

const preview: Preview = {
decorators: [
(Story) => (
<NeapsProvider baseUrl={API_URL}>
<Story />
</NeapsProvider>
),
withThemeByDataAttribute({
themes: {
light: "light",
dark: "dark",
},
defaultTheme: "light",
attributeName: "data-theme",
}),
],
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};

export default preview;
10 changes: 10 additions & 0 deletions packages/react/.storybook/storybook.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@import "tailwindcss";
@import "../src/styles.css";

[data-theme="dark"] {
color-scheme: dark;
}

[data-theme="light"] {
color-scheme: light;
}
9 changes: 9 additions & 0 deletions packages/react/.storybook/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { create } from "storybook/internal/theming";

const brand = {
brandTitle: "Neaps",
brandUrl: "https://openwaters.io/tides/neaps",
};

export const light = create({ base: "light", ...brand });
export const dark = create({ base: "dark", ...brand });
Loading
Loading