Skip to content

Commit 5721278

Browse files
authored
major: React Router v7 support (#49)
* feat: React Router v7 support BREAKING CHANGE: React Router migration
1 parent 291e79a commit 5721278

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+8397
-8936
lines changed

.eslintignore

Lines changed: 0 additions & 5 deletions
This file was deleted.

.eslintrc.js

Lines changed: 0 additions & 8 deletions
This file was deleted.

.github/ISSUE_TEMPLATE/bug_report.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: '🐛 Bug report'
1+
name: "🐛 Bug report"
22
description: Create a report to help us improve
33
body:
44
- type: markdown
@@ -55,8 +55,7 @@ body:
5555
id: expected
5656
attributes:
5757
label: Expected behavior
58-
description:
59-
Provide a clear and concise description of what you expected to happen.
58+
description: Provide a clear and concise description of what you expected to happen.
6059
placeholder: |
6160
As a user, I expected ___ behavior but i am seeing ___
6261
validations:

.github/workflows/validate.yml

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ name: validate
22
on:
33
push:
44
branches:
5-
- '+([0-9])?(.{+([0-9]),x}).x'
6-
- 'main'
7-
- 'next'
8-
- 'next-major'
9-
- 'beta'
10-
- 'alpha'
11-
- '!all-contributors/**'
5+
- "+([0-9])?(.{+([0-9]),x}).x"
6+
- "main"
7+
- "next"
8+
- "next-major"
9+
- "beta"
10+
- "alpha"
11+
- "!all-contributors/**"
1212
pull_request: {}
1313
jobs:
1414
main:
@@ -17,30 +17,30 @@ jobs:
1717
runs-on: ubuntu-latest
1818
steps:
1919
- name: 🛑 Cancel Previous Runs
20-
uses: styfle/cancel-workflow-action@0.11.0
20+
uses: styfle/cancel-workflow-action@0.12.1
2121

2222
- name: ⬇️ Checkout repo
23-
uses: actions/checkout@v3
23+
uses: actions/checkout@v4
2424

2525
- name: ⎔ Setup node
26-
uses: actions/setup-node@v3
26+
uses: actions/setup-node@v4
2727
with:
28-
node-version-file: '.nvmrc'
29-
cache: 'yarn'
28+
node-version-file: ".nvmrc"
29+
cache: "npm"
3030

3131
- name: 📥 Install deps
32-
run: yarn --frozen-lockfile
32+
run: npm install
3333

3434
- name: ▶️ Run validate script
35-
run: yarn validate
35+
run: npm run validate
3636

3737
- name: 📥 Install Playwright Browsers
3838
id: playwright-version
3939
run: |
40-
echo "PLAYWRIGHT_VERSION=$(node -e "console.log(JSON.parse(require('child_process').execSync('yarn info @playwright/test version --json')).data.trim())")" >> $GITHUB_ENV
40+
echo "PLAYWRIGHT_VERSION=$(node -e "console.log(JSON.parse(require('child_process').execSync('npm info @playwright/test version --json')).trim())")" >> $GITHUB_ENV
4141
- name: 🏎️ Cache playwright binaries
42-
uses: actions/cache@v3
43-
id: playwright-cache
42+
uses: actions/cache@v4
43+
id: planwright-cache
4444
with:
4545
path: |
4646
~/.cache/ms-playwright
@@ -54,7 +54,7 @@ jobs:
5454
run: npx playwright test
5555

5656
- name: 📊 Upload report
57-
uses: actions/upload-artifact@v3
57+
uses: actions/upload-artifact@v4
5858
if: always()
5959
with:
6060
name: playwright-report
@@ -64,36 +64,35 @@ jobs:
6464
release:
6565
needs: main
6666
runs-on: ubuntu-latest
67-
if:
68-
${{ github.repository == 'abereghici/remix-themes' &&
67+
if: ${{ github.repository == 'abereghici/remix-themes' &&
6968
contains('refs/heads/main,refs/heads/beta,refs/heads/next,refs/heads/alpha',
7069
github.ref) && github.event_name == 'push' }}
7170
steps:
7271
- name: 🛑 Cancel Previous Runs
73-
uses: styfle/cancel-workflow-action@0.11.0
72+
uses: styfle/cancel-workflow-action@0.12.1
7473

7574
- name: ⬇️ Checkout repo
76-
uses: actions/checkout@v3
75+
uses: actions/checkout@v4
7776

7877
- name: ⎔ Setup node
79-
uses: actions/setup-node@v3
78+
uses: actions/setup-node@v4
8079
with:
81-
node-version-file: '.nvmrc'
82-
cache: 'yarn'
80+
node-version-file: ".nvmrc"
81+
cache: "npm"
8382

8483
- name: 📥 Install deps
8584
run: |
86-
cp README.md packages/remix-themes
87-
node -e "let pkg=require('./package.json');pkg.workspaces=['packages/remix-themes'];require('fs').writeFileSync('./package.json',JSON.stringify(pkg),'utf8')"
88-
yarn --frozen-lockfile
85+
# cp README.md packages/remix-themes
86+
# node -e "let pkg=require('./package.json');pkg.workspaces=['packages/remix-themes'];require('fs').writeFileSync('./package.json',JSON.stringify(pkg),'utf8')"
87+
npm install
8988
9089
- name: 🏗 Run build script
91-
run: yarn build
90+
run: npm run build
9291

9392
- name: 🚀 Release
94-
uses: cycjimmy/semantic-release-action@v3
93+
uses: cycjimmy/semantic-release-action@v4
9594
with:
96-
working_directory: ./packages/remix-themes
95+
working_directory: .
9796
semantic_version: 17
9897
branches: |
9998
[

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
18
1+
20

LICENSE

Lines changed: 0 additions & 21 deletions
This file was deleted.

README.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Remix Themes
22

3-
### An abstraction for themes in your [Remix](https://remix.run/) app.
3+
### An abstraction for themes in your React router v7 / [Remix](https://remix.run/) app.
44

55
## Features
66

@@ -15,6 +15,8 @@ Check out the
1515
[Example](https://github.com/abereghici/remix-themes/tree/main/packages/remix-themes-app)
1616
to see it in action.
1717

18+
If you are using Remix.run you can use v1.5.1 of this library or lower. V2 onwards is only react-router v7 compatible.
19+
1820
## Install
1921

2022
```bash
@@ -30,22 +32,22 @@ $ yarn add remix-themes
3032
```ts
3133
// sessions.server.tsx
3234

33-
import {createThemeSessionResolver} from 'remix-themes'
34-
import { createCookieSessionStorage } from "@remix-run/node"
35+
import { createThemeSessionResolver } from "remix-themes";
36+
import { createCookieSessionStorage } from "react-router";
3537

3638
const sessionStorage = createCookieSessionStorage({
3739
cookie: {
38-
name: '__remix-themes',
40+
name: "__remix-themes",
3941
// domain: 'remix.run',
40-
path: '/',
42+
path: "/",
4143
httpOnly: true,
42-
sameSite: 'lax',
43-
secrets: ['s3cr3t'],
44+
sameSite: "lax",
45+
secrets: ["s3cr3t"],
4446
// secure: true,
4547
},
46-
})
48+
});
4749

48-
export const themeSessionResolver = createThemeSessionResolver(sessionStorage)
50+
export const themeSessionResolver = createThemeSessionResolver(sessionStorage);
4951
```
5052

5153
Note: make sure you have `domain` and `secure` parameters set only for your
@@ -100,7 +102,6 @@ function App() {
100102
<Outlet />
101103
<ScrollRestoration />
102104
<Scripts />
103-
{process.env.NODE_ENV === 'development' && <LiveReload />}
104105
</body>
105106
</html>
106107
)
@@ -123,10 +124,10 @@ This route is used to store the preferred theme in the session storage when
123124
the user changes it.
124125

125126
```ts
126-
import {createThemeAction} from 'remix-themes'
127-
import {themeSessionResolver} from './sessions.server'
127+
import { createThemeAction } from "remix-themes";
128+
import { themeSessionResolver } from "./sessions.server";
128129

129-
export const action = createThemeAction(themeSessionResolver)
130+
export const action = createThemeAction(themeSessionResolver);
130131
```
131132

132133
## API

biome.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
3+
"formatter": {
4+
"indentStyle": "tab",
5+
"indentWidth": 2,
6+
"lineWidth": 100,
7+
"formatWithErrors": true
8+
},
9+
"organizeImports": {
10+
"enabled": true
11+
},
12+
"linter": {
13+
"enabled": true,
14+
"rules": {
15+
"recommended": true
16+
}
17+
},
18+
"javascript": {
19+
"jsxRuntime": "transparent",
20+
"formatter": {
21+
"trailingCommas": "all",
22+
"semicolons": "always"
23+
}
24+
},
25+
"vcs": {
26+
"clientKind": "git",
27+
"enabled": true,
28+
"useIgnoreFile": true
29+
}
30+
}

e2e-tests/themes.spec.ts

Lines changed: 0 additions & 42 deletions
This file was deleted.

e2e/e2e.spec.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { type Page, expect, test } from "@playwright/test";
2+
3+
test("toggling the theme", async ({ page }) => {
4+
await page.goto("/");
5+
6+
const html = () => page.locator("html");
7+
8+
const themeAttribute = "data-theme";
9+
const initialTheme = await html().getAttribute(themeAttribute);
10+
const oppositeTheme = initialTheme === "light" ? "dark" : "light";
11+
12+
await page.locator("select").selectOption({
13+
value: oppositeTheme,
14+
});
15+
16+
await page.waitForTimeout(1000);
17+
18+
expect(html()).toHaveAttribute(themeAttribute, oppositeTheme);
19+
20+
await page.reload();
21+
22+
await expect(page.locator("select")).toBeVisible();
23+
24+
await expect(html()).toHaveAttribute(themeAttribute, oppositeTheme);
25+
});
26+
27+
test("sync between tabs when theme change", async ({ context }) => {
28+
const pageOne = await context.newPage();
29+
const pageTwo = await context.newPage();
30+
31+
await pageOne.goto("/");
32+
await pageTwo.goto("/");
33+
34+
const html = (page: Page) => page.locator("html");
35+
36+
const themeAttribute = "data-theme";
37+
const initialTheme = await html(pageOne).getAttribute(themeAttribute);
38+
const oppositeTheme = initialTheme === "light" ? "dark" : "light";
39+
40+
await pageOne.locator("select").selectOption({ value: oppositeTheme });
41+
42+
await pageOne.waitForTimeout(1000);
43+
44+
await expect(html(pageOne)).toHaveAttribute(themeAttribute, oppositeTheme);
45+
await expect(html(pageTwo)).toHaveAttribute(themeAttribute, oppositeTheme);
46+
});

0 commit comments

Comments
 (0)