Skip to content

Commit cda7ae5

Browse files
tanemclaude
andcommitted
Smoke-test the examples against a packed v7 tarball
The examples pin `"@tanem/react-nprogress": "latest"` and nothing in CI touches them, so v7's packaging would first meet them the moment 7.0.0 publishes. Ran `npm run build && npm pack`, clean-installed the tarball into all eight examples in place of the registry pin, and drove each progress bar in a headless browser. Both Next examples were additionally checked under `next build && next start`. Every example starts, advances and completes with no console errors, and the CJS entry plus the `"use client"` directive hold up on the Next server. The `"latest"` pins are restored: CodeSandbox resolves the registry, not the tarball. Three things needed fixing along the way. The react-router example passed one `nodeRef`, held by `Home`, to every CSSTransition, and it was never attached to a DOM node, since `<Routes>` cannot take a ref. react-transition-group ends the transition on the next tick when the ref does not resolve, so the fade classes never applied and `onEntered` fired straight after `onEnter`: the bar completed 323ms after a click instead of running for the 1200ms the example configures. A `Fade` wrapper now owns a ref per `key` and renders the element it points at. Reproduced against the published 6.0.4 too, so it predates v7. Next rewrites `next-env.d.ts` on every run, with different contents for `next dev` and `next build`, and in a format prettier rejects. It is now gitignored and prettier-ignored in both Next examples, as create-next-app has it. `next build` also reconfigures `jsx` to `react-jsx`, which Next 16 requires, so both example tsconfigs now carry that instead of `preserve`. AGENTS.md records the tarball smoke-test procedure. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 5827110 commit cda7ae5

9 files changed

Lines changed: 57 additions & 23 deletions

File tree

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
README.md
22
coverage
33
dist
4+
next-env.d.ts
45
package.json

AGENTS.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,18 @@ needed but test on CodeSandbox before merging.
126126
Do not bump vite, @vitejs/plugin-react, next, or typescript in examples
127127
beyond the versions in the reference templates.
128128

129+
Before a release that changes packaging, smoke-test the examples against the
130+
tarball rather than the registry: `npm run build && npm pack` at the repo
131+
root, point each example's `@tanem/react-nprogress` dependency at the tarball,
132+
clean-install so it wins over any stale `node_modules`, then run the example
133+
and drive its progress bar in a browser. The Next examples also need
134+
`next build && next start`, since they resolve the CJS entry on the server.
135+
Restore the `"latest"` pin afterwards: CodeSandbox resolves the registry.
136+
137+
`next-env.d.ts` in the Next examples is generated, and `next dev` and
138+
`next build` write different contents into it, so it is gitignored and listed
139+
in `.prettierignore` rather than tracked.
140+
129141
## Writing Style
130142

131143
- Avoid marketing or promotional language. State facts plainly.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.next/
22
/node_modules
3+
next-env.d.ts

examples/next-app-router/next-env.d.ts

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

examples/next-app-router/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"moduleResolution": "bundler",
1717
"resolveJsonModule": true,
1818
"isolatedModules": true,
19-
"jsx": "preserve",
19+
"jsx": "react-jsx",
2020
"incremental": true,
2121
"plugins": [
2222
{
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.next/
2-
/node_modules
2+
/node_modules
3+
next-env.d.ts

examples/next-pages-router/next-env.d.ts

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

examples/next-pages-router/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"moduleResolution": "bundler",
1717
"resolveJsonModule": true,
1818
"isolatedModules": true,
19-
"jsx": "preserve",
19+
"jsx": "react-jsx",
2020
"incremental": true
2121
},
2222
"include": [

examples/react-router/src/main.tsx

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
useParams,
1414
} from 'react-router-dom'
1515
import { CSSTransition, TransitionGroup } from 'react-transition-group'
16+
import type { CSSTransitionProps } from 'react-transition-group/CSSTransition'
1617

1718
import Bar from './Bar'
1819
import Container from './Container'
@@ -122,10 +123,45 @@ const Progress: FC<{ isAnimating: boolean }> = ({ isAnimating }) => {
122123
)
123124
}
124125

126+
// `nodeRef` has to resolve to a mounted DOM node, and `<Routes>` cannot take a
127+
// ref, so the transition owns a wrapper element to point at. It also has to be
128+
// a fresh ref per `key`, which is why this is a component rather than a ref
129+
// held by `Home`. With an unresolved ref, react-transition-group ends the
130+
// transition on the next tick: the fade classes never apply and `onEntered`
131+
// fires immediately, so the progress bar completes on click instead of over
132+
// `timeout`. TransitionGroup clones its children with the props it manages, so
133+
// everything else is forwarded through.
134+
const Fade: FC<
135+
{
136+
children: ReactNode
137+
onEnter(): void
138+
onEntered(): void
139+
} & Pick<
140+
CSSTransitionProps<HTMLDivElement>,
141+
'appear' | 'enter' | 'exit' | 'in' | 'onExited'
142+
>
143+
> = ({ children, onEnter, onEntered, ...managed }) => {
144+
const nodeRef = useRef<HTMLDivElement>(null)
145+
146+
return (
147+
<CSSTransition
148+
{...managed}
149+
classNames="fade"
150+
nodeRef={nodeRef}
151+
onEnter={onEnter}
152+
onEntered={onEntered}
153+
// Timeout has been increased by 4x from the original version for demo
154+
// purposes.
155+
timeout={1200}
156+
>
157+
<div ref={nodeRef}>{children}</div>
158+
</CSSTransition>
159+
)
160+
}
161+
125162
const Home = () => {
126163
const [isLoading, setIsLoading] = useState(false)
127164
const location = useLocation()
128-
const nodeRef = useRef(null)
129165

130166
return (
131167
<>
@@ -144,29 +180,22 @@ const Home = () => {
144180
</ul>
145181
<div style={styles.content}>
146182
<TransitionGroup>
147-
{/*
148-
Timeout has been increased by 4x from the original version
149-
for demo purposes.
150-
*/}
151-
<CSSTransition
152-
classNames="fade"
183+
<Fade
153184
key={location.key}
154-
nodeRef={nodeRef}
155185
onEnter={() => {
156186
setIsLoading(true)
157187
}}
158188
onEntered={() => {
159189
setIsLoading(false)
160190
}}
161-
timeout={1200}
162191
>
163192
<Routes location={location}>
164193
<Route element={<HSL home={true} />} path="/" />
165194
<Route element={<HSL />} path="/hsl/:h/:s/:l" />
166195
<Route element={<RGB />} path="/rgb/:r/:g/:b" />
167196
<Route element={<div>Not Found</div>} path="*" />
168197
</Routes>
169-
</CSSTransition>
198+
</Fade>
170199
</TransitionGroup>
171200
</div>
172201
</div>

0 commit comments

Comments
 (0)