@particle-academy/react-fancy 5.35.0 → 5.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -11,6 +11,87 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [5.36.0] - 2026-10-11
15
+
16
+ ### Added
17
+
18
+ - **`<QrCode>` — a QR code as an SVG, with no dependencies.** ISO/IEC 18004,
19
+ versions 1–40, error correction L/M/Q/H, and numeric / alphanumeric / byte
20
+ modes selected automatically. **Nothing to do** — it is a new component and
21
+ nothing else changed.
22
+
23
+ ```tsx
24
+ <QrCode value="https://host/pair#482913" size={192} label="Pair this device" />
25
+ ```
26
+
27
+ `label` is required. A QR code is unusable to anyone who cannot point a second
28
+ device at the screen, so it needs an accessible name describing the
29
+ *destination* — and the value should also appear as text or a link nearby,
30
+ which an `aria-label` cannot substitute for.
31
+
32
+ Also exported on the `./qr-code` subpath, and **the encoder is exported
33
+ separately** (`encodeQr`, `selectMode`) for a consumer that needs the modules
34
+ rather than an SVG — a canvas, a PDF, a thermal printer, a terminal. Without
35
+ that, getting at them would mean adding a dependency for something already in
36
+ the package.
37
+
38
+ Three notes that decide whether a code actually scans, none of which are
39
+ visible in a screenshot:
40
+
41
+ - **The quiet zone is not padding.** It is how a scanner finds the symbol's
42
+ edge, so it defaults to the standard's minimum of 4 modules. `quietZone={0}`
43
+ is allowed and is not a space saving.
44
+ - **`background` defaults to `"transparent"`**, which inherits whatever is
45
+ behind it — so on a dark surface the symbol renders dark-on-dark and most
46
+ scanners refuse it. Set `foreground` and `background` together there.
47
+ - **`"H"` is not a free upgrade over `"M"`.** It survives more damage and
48
+ holds a third less, so at the same pixel width the modules are smaller; on a
49
+ phone screen it can read *worse*. Raise it for print or a covered symbol.
50
+
51
+ Rendered as a single `<path>` on a module-unit `viewBox` rather than a `<rect>`
52
+ per module: a version 10 symbol has over three thousand modules, and the
53
+ module-unit viewBox is what lets `size` scale with no resampling — a raster
54
+ code at a non-integer multiple of its module size has blurred module edges,
55
+ and a scanner reading a blurred edge guesses.
56
+
57
+ `encodeQr` throws a `RangeError` rather than truncating a value that will not
58
+ fit, because a truncated symbol scans cleanly and yields the wrong string.
59
+ Kanji mode and structured append are not supported; an untested branch in an
60
+ encoder fails as a code a phone quietly refuses to read.
61
+
62
+ Built for `claude · tynn`'s device-pairing panel (Genie 2 §6.8), which
63
+ previously had only a typed URL.
64
+
65
+ ## [5.35.1] - 2026-10-10
66
+
67
+ ### Fixed
68
+
69
+ - **`ActivityLight direction="both"` drew as a tofu box in a container carrying
70
+ only the Liberation fonts.** The mark was U+21C4 (`⇄`), which those fonts do not
71
+ cover; it is now U+2194 (`↔`), which they do. **Nothing to do** — the prop, the
72
+ data attributes and the accessible name are unchanged, and the mark is
73
+ decorative (`aria-hidden`).
74
+
75
+ **One of three states failing is the expensive shape**, which is why this was
76
+ worth a release rather than a note. `in` and `out` drew arrows and `both` drew
77
+ a box, so a reader saw two working indicators and one they had no reason to
78
+ distrust — a font gap and a state are indistinguishable at that point, and a
79
+ direction mark going missing is the kind of absence nobody notices.
80
+
81
+ The choice is measured, not reasoned. `claude · tynn` rasterised each candidate
82
+ in a Liberation-only container and compared it pixel-for-pixel against a
83
+ Private Use Area codepoint no font covers: U+2190–2195 draw, U+21C4 and U+21C6
84
+ do not. **U+21C6 was included as a falsifier** — had it drawn, the finding
85
+ would have been "Liberation covers arrows" rather than "Liberation covers
86
+ WGL4", and this set would be the wrong fix.
87
+
88
+ Two glyph families in the kit are still outside that repertoire and are
89
+ deliberately NOT changed: the Dingbats (`✓` `✕` in `Checkbox`, `✦` in
90
+ `MagicWand`) have no in-repertoire substitute, so they are a genuine
91
+ glyph-versus-SVG trade rather than a one-character fix, and paying it for an
92
+ environment nobody ships a desktop app into is the wrong call today. A test
93
+ pins the `ActivityLight` set so a prettier arrow cannot drift back in.
94
+
14
95
  ## [5.35.0] - 2026-10-10
15
96
 
16
97
  ### Fixed
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
- var chunkEHNMKQ4O_cjs = require('./chunk-EHNMKQ4O.cjs');
3
+ var chunkWNUU7T62_cjs = require('./chunk-WNUU7T62.cjs');
4
4
  require('./chunk-ZU5Q77OT.cjs');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "ActivityLight", {
9
9
  enumerable: true,
10
- get: function () { return chunkEHNMKQ4O_cjs.ActivityLight; }
10
+ get: function () { return chunkWNUU7T62_cjs.ActivityLight; }
11
11
  });
12
12
  //# sourceMappingURL=activity-light.cjs.map
13
13
  //# sourceMappingURL=activity-light.cjs.map
@@ -1,4 +1,4 @@
1
- export { ActivityLight } from './chunk-PZTA6NCD.js';
1
+ export { ActivityLight } from './chunk-DCVR6NPP.js';
2
2
  import './chunk-MMW2JGKZ.js';
3
3
  //# sourceMappingURL=activity-light.js.map
4
4
  //# sourceMappingURL=activity-light.js.map