@zerodev/smart-routing-address-react-ui 0.0.2 → 0.0.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerodev/smart-routing-address-react-ui",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "React hooks, provider, and UI for ZeroDev Smart Routing Address deposits",
5
5
  "repository": {
6
6
  "type": "git",
@@ -45,7 +45,7 @@
45
45
  "@zerodev/smart-routing-address": "^0.2.6",
46
46
  "uqr": "^0.1.2",
47
47
  "zod": "^4.4.3",
48
- "@zerodev/react-ui": "0.0.6"
48
+ "@zerodev/react-ui": "0.0.8"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "react": "^18.0.0 || ^19.0.0",
@@ -4,9 +4,9 @@ import {
4
4
  BottomSheetContent,
5
5
  BottomSheetTitle,
6
6
  Button,
7
+ QrCode,
7
8
  Text,
8
9
  } from '@zerodev/react-ui'
9
- import { QrCode } from './QrCode'
10
10
 
11
11
  export interface QrSheetProps {
12
12
  /** Whether the modal is open. Controlled. */
@@ -28,17 +28,8 @@ export function QrSheet({ open, onOpenChange, address, onCopy }: QrSheetProps) {
28
28
  <BottomSheet open={open} onOpenChange={onOpenChange}>
29
29
  <BottomSheetContent>
30
30
  <BottomSheetTitle>Your deposit address</BottomSheetTitle>
31
- {/* Bottom-half gradient light blue at bottom-left fading into
32
- peach/orange at bottom-right mirrors the "amorphic" image used
33
- in the Figma design. Colors echo `MultiRadialBackground`. */}
34
- <div
35
- aria-hidden
36
- className="zd:absolute zd:inset-0 zd:pointer-events-none"
37
- style={{
38
- background:
39
- 'radial-gradient(ellipse 78% 65% at 5% 105%, rgba(69,171,251,0.35) 0%, rgba(69,171,251,0) 72%), radial-gradient(ellipse 82% 65% at 100% 105%, rgba(250,200,172,0.65) 0%, rgba(250,200,172,0) 72%), radial-gradient(ellipse 58% 52% at 100% 100%, rgba(242,123,62,0.35) 0%, rgba(242,123,62,0) 72%)',
40
- }}
41
- />
31
+ {/* Accent gradient is baked into `BottomSheetContent`; content sits
32
+ above it via `zd:relative`. */}
42
33
  <div className="zd:relative zd:flex zd:flex-col zd:gap-6 zd:items-center zd:pt-6 zd:px-4 zd:pb-3">
43
34
  <div className="zd:flex zd:flex-col zd:gap-3 zd:items-center">
44
35
  <Text className="zd:text-h2 zd:text-center">
@@ -1,28 +0,0 @@
1
- interface QrCodeProps {
2
- /** Data to encode. */
3
- value: string;
4
- /** Pixel size of the rendered SVG square. */
5
- size: number;
6
- /** Error correction level. Defaults to `'M'`. */
7
- errorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H';
8
- /** Corner radius (in modules, scaled to px internally) for finder patterns. */
9
- eyeRadius?: number;
10
- }
11
- /**
12
- * Custom QR renderer that draws runs of horizontally-adjacent data modules as
13
- * a single rounded pill. Finder patterns stay as sharp concentric squares
14
- * (rounding them breaks the 1:1:3:1:1 corner ratio scanners use to locate the
15
- * code). Isolated data modules render as pill-ish rects — visually close to
16
- * circles at very small `PILL_PAD_RATIO`, still square-adjacent for scanners.
17
- *
18
- * Default `errorCorrectionLevel` is `'H'` (30% recovery) so the decorative
19
- * rounding + shrinkage has plenty of headroom before scans fail.
20
- *
21
- * Quiet zone (spec: ≥4 modules of white around the code) is expected to be
22
- * provided by the caller — e.g. via a white-background padded wrapper. This
23
- * component fills the given `size` with the QR data area itself so the
24
- * consumer controls the visual footprint.
25
- */
26
- export declare function QrCode({ value, size, errorCorrectionLevel, eyeRadius, }: QrCodeProps): import("react").JSX.Element;
27
- export {};
28
- //# sourceMappingURL=QrCode.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"QrCode.d.ts","sourceRoot":"","sources":["../../../../src/components/QrSheet/QrCode.tsx"],"names":[],"mappings":"AAEA,UAAU,WAAW;IACnB,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,iDAAiD;IACjD,oBAAoB,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;IAC5C,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAUD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,IAAI,EACJ,oBAA0B,EAC1B,SAAa,GACd,EAAE,WAAW,+BAyHb"}
@@ -1,163 +0,0 @@
1
- import { encode } from 'uqr'
2
-
3
- interface QrCodeProps {
4
- /** Data to encode. */
5
- value: string
6
- /** Pixel size of the rendered SVG square. */
7
- size: number
8
- /** Error correction level. Defaults to `'M'`. */
9
- errorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H'
10
- /** Corner radius (in modules, scaled to px internally) for finder patterns. */
11
- eyeRadius?: number
12
- }
13
-
14
- const FINDER_SIZE = 7 // every QR has three 7×7 finder patterns
15
- const MODULE_COLOR = '#000'
16
- const BG_COLOR = '#fff'
17
- /** Vertical shrink applied to data-module pills so rows read as distinct
18
- * without introducing white slivers wide enough to look like transitions
19
- * to a scanner. Kept small (5%) so total black area stays close to spec. */
20
- const PILL_PAD_RATIO = 0.05
21
-
22
- /**
23
- * Custom QR renderer that draws runs of horizontally-adjacent data modules as
24
- * a single rounded pill. Finder patterns stay as sharp concentric squares
25
- * (rounding them breaks the 1:1:3:1:1 corner ratio scanners use to locate the
26
- * code). Isolated data modules render as pill-ish rects — visually close to
27
- * circles at very small `PILL_PAD_RATIO`, still square-adjacent for scanners.
28
- *
29
- * Default `errorCorrectionLevel` is `'H'` (30% recovery) so the decorative
30
- * rounding + shrinkage has plenty of headroom before scans fail.
31
- *
32
- * Quiet zone (spec: ≥4 modules of white around the code) is expected to be
33
- * provided by the caller — e.g. via a white-background padded wrapper. This
34
- * component fills the given `size` with the QR data area itself so the
35
- * consumer controls the visual footprint.
36
- */
37
- export function QrCode({
38
- value,
39
- size,
40
- errorCorrectionLevel = 'H',
41
- eyeRadius = 0,
42
- }: QrCodeProps) {
43
- // `uqr` returns a 2D boolean matrix (`data[row][col]`) and the module count
44
- // per side. Same information as `qrcode`, just shaped differently — the
45
- // pill/finder rendering below is unchanged.
46
- const qr = encode(value, { ecc: errorCorrectionLevel, border: 0 })
47
- const matrix = qr.data
48
- const moduleCount = qr.size
49
- const cellSize = size / moduleCount
50
- const eyeRadiusPx = eyeRadius * cellSize
51
-
52
- const finders = [
53
- { row: 0, col: 0 },
54
- { row: 0, col: moduleCount - FINDER_SIZE },
55
- { row: moduleCount - FINDER_SIZE, col: 0 },
56
- ]
57
-
58
- const inFinder = (row: number, col: number) =>
59
- finders.some(
60
- (f) =>
61
- row >= f.row &&
62
- row < f.row + FINDER_SIZE &&
63
- col >= f.col &&
64
- col < f.col + FINDER_SIZE,
65
- )
66
-
67
- // Collect maximal horizontal runs of `on` modules, skipping finder regions.
68
- const runs: { row: number; col: number; length: number }[] = []
69
- for (let row = 0; row < moduleCount; row++) {
70
- let col = 0
71
- while (col < moduleCount) {
72
- if (inFinder(row, col)) {
73
- col++
74
- continue
75
- }
76
- if (matrix[row]?.[col]) {
77
- let length = 1
78
- while (
79
- col + length < moduleCount &&
80
- !inFinder(row, col + length) &&
81
- matrix[row]?.[col + length]
82
- ) {
83
- length++
84
- }
85
- runs.push({ row, col, length })
86
- col += length
87
- } else {
88
- col++
89
- }
90
- }
91
- }
92
-
93
- return (
94
- <svg
95
- width={size}
96
- height={size}
97
- viewBox={`0 0 ${size} ${size}`}
98
- xmlns="http://www.w3.org/2000/svg"
99
- role="img"
100
- aria-label={`QR code for ${value}`}
101
- >
102
- <rect width={size} height={size} fill={BG_COLOR} />
103
- {runs.map(({ row, col, length }) => {
104
- // Shrink each pill vertically so rows read as distinct without
105
- // creating scanner-confusing white gaps mid-run. Isolated modules
106
- // (length === 1) also shrink horizontally so they render close to a
107
- // circle instead of an oval.
108
- const pad = cellSize * PILL_PAD_RATIO
109
- const pillHeight = cellSize - 2 * pad
110
- const isSingle = length === 1
111
- return (
112
- <rect
113
- key={`r${row}-${col}`}
114
- x={col * cellSize + (isSingle ? pad : 0)}
115
- y={row * cellSize + pad}
116
- width={length * cellSize - (isSingle ? 2 * pad : 0)}
117
- height={pillHeight}
118
- rx={pillHeight / 2}
119
- ry={pillHeight / 2}
120
- fill={MODULE_COLOR}
121
- />
122
- )
123
- })}
124
- {finders.map(({ row, col }) => {
125
- const x = col * cellSize
126
- const y = row * cellSize
127
- const outerSize = FINDER_SIZE * cellSize
128
- const innerSize = 3 * cellSize
129
- return (
130
- <g key={`f${row}-${col}`}>
131
- <rect
132
- x={x}
133
- y={y}
134
- width={outerSize}
135
- height={outerSize}
136
- rx={eyeRadiusPx}
137
- ry={eyeRadiusPx}
138
- fill={MODULE_COLOR}
139
- />
140
- <rect
141
- x={x + cellSize}
142
- y={y + cellSize}
143
- width={outerSize - 2 * cellSize}
144
- height={outerSize - 2 * cellSize}
145
- rx={Math.max(eyeRadiusPx - cellSize, 0)}
146
- ry={Math.max(eyeRadiusPx - cellSize, 0)}
147
- fill={BG_COLOR}
148
- />
149
- <rect
150
- x={x + 2 * cellSize}
151
- y={y + 2 * cellSize}
152
- width={innerSize}
153
- height={innerSize}
154
- rx={Math.max(eyeRadiusPx - 2 * cellSize, 0)}
155
- ry={Math.max(eyeRadiusPx - 2 * cellSize, 0)}
156
- fill={MODULE_COLOR}
157
- />
158
- </g>
159
- )
160
- })}
161
- </svg>
162
- )
163
- }