Skip to content

Commit 1ecc2f4

Browse files
authored
Merge pull request #3594 from tanem/v18
Modernise packaging and rewrite as a function component
2 parents 0cb5bb4 + 2947e4d commit 1ecc2f4

51 files changed

Lines changed: 4429 additions & 4986 deletions

Some content is hidden

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

.github/copilot-instructions.md

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

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ name: CI
22

33
on:
44
push:
5-
branches: [master]
5+
branches: [master, 'v*']
66
pull_request:
7-
branches: [master]
7+
branches: [master, 'v*']
88

99
concurrency:
1010
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
.DS_Store
33
.vscode
44
build
5-
compiled
65
coverage
76
dist
87
examples/*/package-lock.json

.prettierignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
*.md
22
.next
33
build
4-
compiled
54
coverage
65
dist
76
package.json

AGENTS.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# AGENTS.md
2+
3+
Rules for coding agents that the code and config don't already state. Keep it
4+
that way: a constraint that can live in a comment next to the thing it
5+
constrains belongs there, not here.
6+
7+
## Writing
8+
9+
- NZ English everywhere ("colour", "behaviour", "initialise").
10+
- Single-line commit messages, `git log --oneline` style. Add a body only to
11+
explain why, and only for behaviour or type changes.
12+
- No conventional-commit prefixes (`feat:`, `fix:`, `chore(deps):`) in commit
13+
subjects or PR titles. Write a plain capitalised sentence. Nothing reads the
14+
prefix: the version bump comes from the PR label, and renovate is set to
15+
`semanticCommits: "disabled"` to match.
16+
- PR titles are copied verbatim into `CHANGELOG.md`, so write them as the
17+
changelog line you want readers to see.
18+
- Hard-wrap commit message bodies at 72 columns; `git log` does not reflow
19+
them. Do not hard-wrap PR or issue descriptions: GitHub reflows markdown,
20+
and its web editor leaves wrapped source ragged once anyone edits it.
21+
22+
## Architecture
23+
24+
Injection happens in a single effect in `src/ReactSVG.tsx`. The two-wrapper
25+
structure, outer managed by React and inner managed by `@tanem/svg-injector`,
26+
is load-bearing: don't collapse it.
27+
28+
That file's comments cover the rest: why `forwardRef` is required, why the
29+
effect's dependency list is deliberately narrow, why the callbacks are read
30+
through a ref, and what the teardown guard protects. Read them before changing
31+
the injection flow.
32+
33+
## Build & test
34+
35+
`npm run test:src` is the development loop. `npm test` is the full gate.
36+
`npm run test:react` runs the React matrix and is slow enough to be
37+
pre-release only. `npm run size`, `npm run test:dist` and the `package:*`
38+
checks read `dist/`, so they need a current `npm run build`. A new spec that
39+
reads `dist/` goes in `config/jest/dist-tests.js`, which keeps it out of
40+
`test:src`.
41+
42+
Give each test its own `faker.seed()` and a `faker.string.uuid()` SVG URL, or
43+
svg-injector's cache leaks state between tests. Injection is async: assert
44+
through `await waitFor(...)`.
45+
46+
Raising a `size-limit` budget in `package.json` is a decision, not a fix. Find
47+
what grew first, and say why in the commit message.
48+
49+
The React matrix covers boundary versions only: the first and last minor of
50+
each supported major, plus minors that changed behaviour. Currently 16.8,
51+
16.14, 17.0, 18.0, 18.3, 19.0, 19.1. Adding a boundary means replacing the
52+
previous last-minor for that major, not accumulating versions. Copy a sibling
53+
`test/react/<version>/package.json`, and see `scripts/test-react.ts` for how a
54+
single version is run.
55+
56+
## Releases
57+
58+
`npm run release` runs on a Monday cron against `master`. It takes the version
59+
bump from the labels on PRs merged since the last tag, then regenerates
60+
`CHANGELOG.md` and `AUTHORS` and bumps `version` in `package.json` and
61+
`package-lock.json`.
62+
63+
- Exactly one label per PR. None, or more than one, throws and blocks the
64+
release for everything merged alongside it. `breaking` gives a major,
65+
`enhancement` a minor, `bug` / `documentation` / `internal` a patch. Tooling,
66+
CI and dependency work is `internal`.
67+
- Never hand-edit `CHANGELOG.md`, `AUTHORS` or either `version` field.
68+
- Breaking changes need a `MIGRATION.md` entry in the same PR: the generated
69+
changelog is only a list of PR titles.
70+
71+
## Dependencies
72+
73+
Pin `devDependencies` to exact versions. Keep `dependencies` on caret ranges.
74+
75+
## Examples
76+
77+
`examples/` are built to open on CodeSandbox, so their platform dependencies
78+
(vite, @vitejs/plugin-react, next, typescript, @types/react, @types/react-dom)
79+
track the official
80+
[sandbox-templates](https://github.com/codesandbox/sandbox-templates/tree/main):
81+
`react-vite` / `react-vite-ts` for the Vite examples, `nextjs` for the SSR one.
82+
Don't bump those past the template, except for patch-level security fixes
83+
inside the template's major.minor. Example-only dependencies
84+
(`styled-components`, `glamor`, `react-frame-component`) aren't governed by it.
85+
86+
Renovate skips `examples/**`, so updates are manual: do every example in one
87+
commit and check at least one still opens on CodeSandbox.
88+
89+
## Conventions
90+
91+
- `src/types.ts` is the only prop contract. There is no runtime `propTypes`.
92+
- Keep `Props` flat. It extends `HTMLAttributes` and `SVGAttributes`, and
93+
nesting it trips excessive-depth errors in wrapper libraries.

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@AGENTS.md

MIGRATION.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,31 @@
22

33
Details relating to major changes that aren't presently in `CHANGELOG.md`, due to limitations with how that file is being generated.
44

5+
## v18.0.0
6+
7+
**Added**
8+
9+
- An `exports` map. `react-svg` and `react-svg/package.json` are the only entry points; paths into `dist` are no longer reachable, even though the top-level `main`, `module` and `types` fields are still set for webpack 4 and TypeScript `node10` resolution. Node ESM consumers now get the ES module build rather than falling back to CommonJS.
10+
- `sideEffects: false`, so bundlers can drop the package entirely when nothing is imported from it.
11+
12+
**Changed**
13+
14+
- The minimum supported React version is now 16.8, up from 16.0. The peer dependency range is `^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0`. React's support unit is the major, and fixes for the 16.x line only ever land on 16.14.x, so individual pre-16.8 minors were never separately supported.
15+
- `ReactSVG` is a function component built on hooks, rather than a class component. `defaultProps` is gone (React 19 ignores it on function components); prop defaults are unchanged and are now applied by destructuring.
16+
- `ReactSVG` is a value only, so it can no longer be used in a type position. A class declaration doubles as a type describing its instances, which made `Omit<ReactSVG, 'src'>` and similar valid; the same code now fails with `TS2749: 'ReactSVG' refers to a value, but is being used as a type here`. Use the exported `Props` type instead: `Omit<Props, 'src'>`.
17+
- `ref` now resolves to the outermost wrapper DOM element - an `HTMLDivElement`, `HTMLSpanElement` or `SVGSVGElement`, depending on `wrapper` - instead of the `ReactSVG` class instance. The class instance had no documented methods, so the DOM node is the useful thing to hand back. Type the ref as the exported `WrapperType` if you need it.
18+
- Re-injection now only happens when a prop that affects the injected SVG changes: `src`, `wrapper`, `title`, `desc`, `evalScripts`, `httpRequestWithCredentials`, `renumerateIRIElements` or `useRequestCache`. Previously any prop change re-fetched and re-injected, including ones that only apply to the React wrapper (`className`, `style`, event handlers) and inline `beforeInjection` / `afterInjection` / `onError` functions, whose identity changes on every render. Those callbacks are still always invoked in their latest form; they just no longer trigger an injection by themselves. If you were relying on a wrapper prop change to force a re-injection, change `src` instead.
19+
- Build output filenames. The CommonJS build is `dist/react-svg.cjs` (was `dist/react-svg.cjs.js`) and the ES module build is `dist/react-svg.mjs` (was `dist/react-svg.esm.js`). Type declarations are `dist/react-svg.d.cts` and `dist/react-svg.d.mts` (was `dist/index.d.ts` plus one file per source module). Importing `react-svg` is unaffected.
20+
- The build pipeline moved from TypeScript plus Rollup and Babel to [tsdown](https://tsdown.dev). Output still targets ES2019. `@babel/runtime` is no longer a runtime dependency, leaving `@tanem/svg-injector` as the only one.
21+
- `src` is now published alongside `dist` so the declaration maps resolve.
22+
23+
**Removed**
24+
25+
- The `State` type export. It described the internal state shape of the class component, which no longer exists.
26+
- `propTypes` validation. TypeScript types are the supported contract for props. React 19 ignores `propTypes` entirely, so this only changes behaviour for React 18 and earlier in development mode, where invalid props previously logged a console warning. `prop-types` and `@types/prop-types` are no longer dependencies.
27+
- The separate development and production CommonJS builds. `dist/react-svg.cjs.development.js`, `dist/react-svg.cjs.production.js` and the `dist/index.js` shim that switched between them on `process.env.NODE_ENV` are replaced by a single unminified CommonJS build. With `propTypes` gone the two builds differed only by minification, which bundlers apply themselves.
28+
- UMD builds. `dist/react-svg.umd.development.js` and `dist/react-svg.umd.production.js` are no longer published, and the `ReactSVG` browser global is gone. React itself stopped shipping UMD builds in v19, so script-tag usage already required pinning React 18 or earlier. If you load `react-svg` via a script tag, pin `react-svg@^17`, or switch to the ES module build with an import map or a bundler.
29+
530
## v17.0.0
631

732
**Changed**

0 commit comments

Comments
 (0)