@zentauri-ui/zentauri-components 2.2.2 → 2.3.1
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/README.md +10 -6
- package/cli/props.json +526 -0
- package/cli/registry.json +11 -0
- package/dist/chunk-4U6PVVST.mjs +15 -0
- package/dist/chunk-4U6PVVST.mjs.map +1 -0
- package/dist/{chunk-DIAA5VH4.mjs → chunk-CIZQQ32L.mjs} +3 -3
- package/dist/chunk-CIZQQ32L.mjs.map +1 -0
- package/dist/chunk-EZNR7VLJ.js +65 -0
- package/dist/chunk-EZNR7VLJ.js.map +1 -0
- package/dist/{chunk-PQ2XTY3M.js → chunk-G36ZV446.js} +13 -13
- package/dist/{chunk-PQ2XTY3M.js.map → chunk-G36ZV446.js.map} +1 -1
- package/dist/{chunk-H3BJOK22.js → chunk-HNAUUCR5.js} +3 -3
- package/dist/chunk-HNAUUCR5.js.map +1 -0
- package/dist/{chunk-UZ6Y5CSV.js → chunk-K7UU3K54.js} +39 -18
- package/dist/chunk-K7UU3K54.js.map +1 -0
- package/dist/chunk-MY3DQVNF.js +19 -0
- package/dist/{chunk-ILPPXWR3.js.map → chunk-MY3DQVNF.js.map} +1 -1
- package/dist/{chunk-ATE5SCTR.mjs → chunk-N6Q4ZLQR.mjs} +3 -3
- package/dist/{chunk-ATE5SCTR.mjs.map → chunk-N6Q4ZLQR.mjs.map} +1 -1
- package/dist/{chunk-GFE6ZX5Y.mjs → chunk-PJATBFEK.mjs} +30 -9
- package/dist/chunk-PJATBFEK.mjs.map +1 -0
- package/dist/chunk-PVVYOIU2.js +38 -0
- package/dist/chunk-PVVYOIU2.js.map +1 -0
- package/dist/chunk-PWEZB53R.js +90 -0
- package/dist/chunk-PWEZB53R.js.map +1 -0
- package/dist/chunk-PWYEC3KY.mjs +30 -0
- package/dist/chunk-PWYEC3KY.mjs.map +1 -0
- package/dist/{chunk-5I4GAURE.js → chunk-RBNZNWYQ.js} +6 -6
- package/dist/{chunk-5I4GAURE.js.map → chunk-RBNZNWYQ.js.map} +1 -1
- package/dist/chunk-RDYR4DHG.mjs +62 -0
- package/dist/chunk-RDYR4DHG.mjs.map +1 -0
- package/dist/chunk-RWF3NVZP.mjs +29 -0
- package/dist/chunk-RWF3NVZP.mjs.map +1 -0
- package/dist/{chunk-NUV2I337.mjs → chunk-STWXN5EM.mjs} +3 -3
- package/dist/{chunk-NUV2I337.mjs.map → chunk-STWXN5EM.mjs.map} +1 -1
- package/dist/{chunk-W5MTZJPE.mjs → chunk-TTKTPERV.mjs} +3 -3
- package/dist/{chunk-W5MTZJPE.mjs.map → chunk-TTKTPERV.mjs.map} +1 -1
- package/dist/chunk-UBQY572I.mjs +81 -0
- package/dist/chunk-UBQY572I.mjs.map +1 -0
- package/dist/{chunk-IY72Z65Z.js → chunk-UN5RRNPV.js} +12 -12
- package/dist/{chunk-IY72Z65Z.js.map → chunk-UN5RRNPV.js.map} +1 -1
- package/dist/{chunk-N2G7IWHS.mjs → chunk-VMVG2RVZ.mjs} +4 -4
- package/dist/{chunk-N2G7IWHS.mjs.map → chunk-VMVG2RVZ.mjs.map} +1 -1
- package/dist/chunk-XUK5P37Y.js +19 -0
- package/dist/chunk-XUK5P37Y.js.map +1 -0
- package/dist/chunk-YRQN3AV4.js +38 -0
- package/dist/chunk-YRQN3AV4.js.map +1 -0
- package/dist/design-system/facade.js +12 -9
- package/dist/design-system/facade.js.map +1 -1
- package/dist/design-system/facade.mjs +11 -8
- package/dist/design-system/facade.mjs.map +1 -1
- package/dist/design-system/hash-generator.d.ts +15 -0
- package/dist/design-system/hash-generator.d.ts.map +1 -0
- package/dist/design-system/index.d.ts +3 -0
- package/dist/design-system/index.d.ts.map +1 -1
- package/dist/design-system/qr-code.d.ts +4 -0
- package/dist/design-system/qr-code.d.ts.map +1 -0
- package/dist/design-system/qr-scanner.d.ts +11 -0
- package/dist/design-system/qr-scanner.d.ts.map +1 -0
- package/dist/design-system/secret-reveal.d.ts +1 -1
- package/dist/design-system/secret-reveal.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useHash/index.d.ts +2 -0
- package/dist/hooks/useHash/index.d.ts.map +1 -0
- package/dist/hooks/useHash/useHash.d.ts +20 -0
- package/dist/hooks/useHash/useHash.d.ts.map +1 -0
- package/dist/hooks/useHash.js +18 -0
- package/dist/hooks/useHash.js.map +1 -0
- package/dist/hooks/useHash.mjs +5 -0
- package/dist/hooks/useHash.mjs.map +1 -0
- package/dist/ui/buttons/animated.js +14 -11
- package/dist/ui/buttons/animated.js.map +1 -1
- package/dist/ui/buttons/animated.mjs +12 -9
- package/dist/ui/buttons/animated.mjs.map +1 -1
- package/dist/ui/buttons.js +15 -12
- package/dist/ui/buttons.mjs +13 -10
- package/dist/ui/data-table.js +24 -21
- package/dist/ui/data-table.js.map +1 -1
- package/dist/ui/data-table.mjs +14 -11
- package/dist/ui/data-table.mjs.map +1 -1
- package/dist/ui/dynamic-stepper.js +24 -21
- package/dist/ui/dynamic-stepper.js.map +1 -1
- package/dist/ui/dynamic-stepper.mjs +13 -10
- package/dist/ui/dynamic-stepper.mjs.map +1 -1
- package/dist/ui/hash-generator/hash-generator-base.d.ts +6 -0
- package/dist/ui/hash-generator/hash-generator-base.d.ts.map +1 -0
- package/dist/ui/hash-generator/hash-generator.d.ts +2 -0
- package/dist/ui/hash-generator/hash-generator.d.ts.map +1 -0
- package/dist/ui/hash-generator/index.d.ts +5 -0
- package/dist/ui/hash-generator/index.d.ts.map +1 -0
- package/dist/ui/hash-generator/types.d.ts +17 -0
- package/dist/ui/hash-generator/types.d.ts.map +1 -0
- package/dist/ui/hash-generator/variants.d.ts +10 -0
- package/dist/ui/hash-generator/variants.d.ts.map +1 -0
- package/dist/ui/hash-generator.js +126 -0
- package/dist/ui/hash-generator.js.map +1 -0
- package/dist/ui/hash-generator.mjs +117 -0
- package/dist/ui/hash-generator.mjs.map +1 -0
- package/dist/ui/pagination.js +16 -13
- package/dist/ui/pagination.mjs +13 -10
- package/dist/ui/qr-code/animated/animations.d.ts +8 -0
- package/dist/ui/qr-code/animated/animations.d.ts.map +1 -0
- package/dist/ui/qr-code/animated/index.d.ts +4 -0
- package/dist/ui/qr-code/animated/index.d.ts.map +1 -0
- package/dist/ui/qr-code/animated/qr-code-animated.d.ts +6 -0
- package/dist/ui/qr-code/animated/qr-code-animated.d.ts.map +1 -0
- package/dist/ui/qr-code/animated/types.d.ts +9 -0
- package/dist/ui/qr-code/animated/types.d.ts.map +1 -0
- package/dist/ui/qr-code/animated.js +156 -0
- package/dist/ui/qr-code/animated.js.map +1 -0
- package/dist/ui/qr-code/animated.mjs +149 -0
- package/dist/ui/qr-code/animated.mjs.map +1 -0
- package/dist/ui/qr-code/index.d.ts +5 -0
- package/dist/ui/qr-code/index.d.ts.map +1 -0
- package/dist/ui/qr-code/qr-code-base.d.ts +47 -0
- package/dist/ui/qr-code/qr-code-base.d.ts.map +1 -0
- package/dist/ui/qr-code/qr-code.d.ts +2 -0
- package/dist/ui/qr-code/qr-code.d.ts.map +1 -0
- package/dist/ui/qr-code/types.d.ts +14 -0
- package/dist/ui/qr-code/types.d.ts.map +1 -0
- package/dist/ui/qr-code/variants.d.ts +4 -0
- package/dist/ui/qr-code/variants.d.ts.map +1 -0
- package/dist/ui/qr-code.js +35 -0
- package/dist/ui/qr-code.js.map +1 -0
- package/dist/ui/qr-code.mjs +17 -0
- package/dist/ui/qr-code.mjs.map +1 -0
- package/dist/ui/qr-scanner/index.d.ts +4 -0
- package/dist/ui/qr-scanner/index.d.ts.map +1 -0
- package/dist/ui/qr-scanner/qr-scanner-base.d.ts +62 -0
- package/dist/ui/qr-scanner/qr-scanner-base.d.ts.map +1 -0
- package/dist/ui/qr-scanner/qr-scanner.d.ts +2 -0
- package/dist/ui/qr-scanner/qr-scanner.d.ts.map +1 -0
- package/dist/ui/qr-scanner/types.d.ts +28 -0
- package/dist/ui/qr-scanner/types.d.ts.map +1 -0
- package/dist/ui/qr-scanner/variants.d.ts +9 -0
- package/dist/ui/qr-scanner/variants.d.ts.map +1 -0
- package/dist/ui/qr-scanner.js +316 -0
- package/dist/ui/qr-scanner.js.map +1 -0
- package/dist/ui/qr-scanner.mjs +308 -0
- package/dist/ui/qr-scanner.mjs.map +1 -0
- package/dist/ui/secret-reveal/animated/secret-reveal-animated.d.ts.map +1 -1
- package/dist/ui/secret-reveal/animated.js +10 -7
- package/dist/ui/secret-reveal/animated.js.map +1 -1
- package/dist/ui/secret-reveal/animated.mjs +6 -3
- package/dist/ui/secret-reveal/animated.mjs.map +1 -1
- package/dist/ui/secret-reveal/secret-reveal-base.d.ts.map +1 -1
- package/dist/ui/secret-reveal.js +14 -11
- package/dist/ui/secret-reveal.js.map +1 -1
- package/dist/ui/secret-reveal.mjs +7 -4
- package/dist/ui/secret-reveal.mjs.map +1 -1
- package/dist/ui/split-button.js +26 -23
- package/dist/ui/split-button.js.map +1 -1
- package/dist/ui/split-button.mjs +13 -10
- package/dist/ui/split-button.mjs.map +1 -1
- package/package.json +5 -2
- package/src/design-system/hash-generator.ts +34 -0
- package/src/design-system/index.ts +3 -0
- package/src/design-system/qr-code.ts +13 -0
- package/src/design-system/qr-scanner.ts +32 -0
- package/src/design-system/secret-reveal.ts +1 -1
- package/src/hooks/index.ts +6 -0
- package/src/hooks/useHash/index.ts +6 -0
- package/src/hooks/useHash/useHash.test.ts +77 -0
- package/src/hooks/useHash/useHash.ts +89 -0
- package/src/ui/hash-generator/hash-generator-base.tsx +106 -0
- package/src/ui/hash-generator/hash-generator.test.tsx +73 -0
- package/src/ui/hash-generator/hash-generator.tsx +1 -0
- package/src/ui/hash-generator/index.ts +18 -0
- package/src/ui/hash-generator/types.ts +29 -0
- package/src/ui/hash-generator/variants.ts +31 -0
- package/src/ui/qr-code/animated/animations.ts +51 -0
- package/src/ui/qr-code/animated/index.ts +5 -0
- package/src/ui/qr-code/animated/qr-code-animated.tsx +111 -0
- package/src/ui/qr-code/animated/types.ts +10 -0
- package/src/ui/qr-code/index.ts +10 -0
- package/src/ui/qr-code/qr-code-base.tsx +149 -0
- package/src/ui/qr-code/qr-code.test.tsx +58 -0
- package/src/ui/qr-code/qr-code.tsx +2 -0
- package/src/ui/qr-code/types.ts +22 -0
- package/src/ui/qr-code/variants.ts +11 -0
- package/src/ui/qr-scanner/index.ts +17 -0
- package/src/ui/qr-scanner/qr-scanner-base.tsx +568 -0
- package/src/ui/qr-scanner/qr-scanner.test.tsx +61 -0
- package/src/ui/qr-scanner/qr-scanner.tsx +2 -0
- package/src/ui/qr-scanner/types.ts +32 -0
- package/src/ui/qr-scanner/variants.ts +26 -0
- package/src/ui/secret-reveal/animated/secret-reveal-animated.tsx +4 -1
- package/src/ui/secret-reveal/secret-reveal-base.tsx +4 -1
- package/dist/chunk-DIAA5VH4.mjs.map +0 -1
- package/dist/chunk-GFE6ZX5Y.mjs.map +0 -1
- package/dist/chunk-H3BJOK22.js.map +0 -1
- package/dist/chunk-ILPPXWR3.js +0 -19
- package/dist/chunk-UZ6Y5CSV.js.map +0 -1
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import QRCode from "qrcode";
|
|
5
|
+
|
|
6
|
+
import { cn } from "../../lib/utils";
|
|
7
|
+
|
|
8
|
+
import type { QrCodeBaseProps } from "./types";
|
|
9
|
+
import {
|
|
10
|
+
qrCodeCanvasWrapperVariants,
|
|
11
|
+
qrCodeCaptionVariants,
|
|
12
|
+
qrCodeVariants,
|
|
13
|
+
} from "./variants";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* QrCodeBase renders a QR code onto a `<canvas>` element using the `qrcode`
|
|
17
|
+
* npm package. It is the static (non-animated) implementation of the public
|
|
18
|
+
* `QrCode` component.
|
|
19
|
+
*
|
|
20
|
+
* --- Props ---
|
|
21
|
+
*
|
|
22
|
+
* - `value` — The string to encode. When empty/falsy the canvas is cleared.
|
|
23
|
+
* - `canvasSize` — Pixel dimensions of the canvas (default: 200). Both width
|
|
24
|
+
* and height are set to this value, producing a square QR code.
|
|
25
|
+
* - `level` — Error correction level (`"L"` | `"M"` | `"Q"` | `"H"`). Higher
|
|
26
|
+
* levels survive more visual damage but hold less data.
|
|
27
|
+
* - `bgColor` / `fgColor` — Background and foreground colours passed to the
|
|
28
|
+
* underlying `QRCode.toCanvas` options.
|
|
29
|
+
* - `margin` — Quiet-zone width in QR modules (default: 2). Passed directly
|
|
30
|
+
* to the `qrcode` library.
|
|
31
|
+
* - `caption` — Optional label rendered below the QR code.
|
|
32
|
+
* - `ref` — React 19 ref forwarded to the root `<div>` element.
|
|
33
|
+
* - `className` / `...rest` — Spread onto the root `<div>` for layout or
|
|
34
|
+
* style overrides.
|
|
35
|
+
*
|
|
36
|
+
* --- Rendering lifecycle ---
|
|
37
|
+
*
|
|
38
|
+
* A `useEffect` watches `[value, canvasSize, level, bgColor, fgColor, margin]`.
|
|
39
|
+
* On every change it:
|
|
40
|
+
* 1. Grabs the canvas element from the ref.
|
|
41
|
+
* 2. If `value` is empty, clears the canvas with `ctx.clearRect` so a stale
|
|
42
|
+
* QR code doesn't persist.
|
|
43
|
+
* 3. Otherwise calls `QRCode.toCanvas()` which draws the QR pattern
|
|
44
|
+
* asynchronously (via callback) onto the canvas element.
|
|
45
|
+
*
|
|
46
|
+
* The outer `<div>` uses design-system variants (`qrCodeVariants`) for
|
|
47
|
+
* consistent theming and carries `data-slot="qr-code"` for scoped styling and
|
|
48
|
+
* testing.
|
|
49
|
+
*
|
|
50
|
+
* --- Accessibility ---
|
|
51
|
+
*
|
|
52
|
+
* The `<canvas>` has an `aria-label` describing it as a "QR code for {value}".
|
|
53
|
+
* Screen readers will announce the purpose, though the raw value is exposed
|
|
54
|
+
* (consider truncating for secrets).
|
|
55
|
+
*/
|
|
56
|
+
export function QrCodeBase({
|
|
57
|
+
value,
|
|
58
|
+
canvasSize = 200,
|
|
59
|
+
level = "M",
|
|
60
|
+
bgColor = "#ffffff",
|
|
61
|
+
fgColor = "#000000",
|
|
62
|
+
margin = 2,
|
|
63
|
+
caption,
|
|
64
|
+
className,
|
|
65
|
+
ref,
|
|
66
|
+
...rest
|
|
67
|
+
}: QrCodeBaseProps) {
|
|
68
|
+
const canvasRef = useRef<HTMLCanvasElement>(null);
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Draw the QR pattern whenever input props change.
|
|
72
|
+
*
|
|
73
|
+
* The conditional `if (!value)` branch handles the "clear" case: when the
|
|
74
|
+
* user deletes the input text, we clear the canvas so a stale QR code isn't
|
|
75
|
+
* displayed. Without this the old QR pattern persists because
|
|
76
|
+
* `QRCode.toCanvas` is never called (it returns early for empty values).
|
|
77
|
+
*/
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
const canvas = canvasRef.current;
|
|
80
|
+
if (!canvas) return;
|
|
81
|
+
|
|
82
|
+
if (!value) {
|
|
83
|
+
const ctx = canvas.getContext("2d");
|
|
84
|
+
if (ctx) {
|
|
85
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
86
|
+
}
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
QRCode.toCanvas(
|
|
91
|
+
canvas,
|
|
92
|
+
value,
|
|
93
|
+
{
|
|
94
|
+
width: canvasSize,
|
|
95
|
+
margin,
|
|
96
|
+
color: {
|
|
97
|
+
dark: fgColor,
|
|
98
|
+
light: bgColor,
|
|
99
|
+
},
|
|
100
|
+
errorCorrectionLevel: level,
|
|
101
|
+
},
|
|
102
|
+
(error) => {
|
|
103
|
+
if (error) {
|
|
104
|
+
console.error("QR Code generation error:", error);
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
);
|
|
108
|
+
}, [value, canvasSize, level, bgColor, fgColor, margin]);
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The root element is a `<div>` (not the `<canvas>`) so consumers can apply
|
|
112
|
+
* layout classes, the caption sits outside the canvas, and the component
|
|
113
|
+
* plays well with flex/grid containers.
|
|
114
|
+
*
|
|
115
|
+
* Nested structure:
|
|
116
|
+
* <div data-slot="qr-code"> ← root (ref, className, ...rest)
|
|
117
|
+
* <div> ← canvas wrapper (theme rounding/overflow)
|
|
118
|
+
* <canvas data-slot="qr-code-canvas" />
|
|
119
|
+
* </div>
|
|
120
|
+
* {caption && <span data-slot="qr-code-caption" />}
|
|
121
|
+
* </div>
|
|
122
|
+
*/
|
|
123
|
+
return (
|
|
124
|
+
<div
|
|
125
|
+
ref={ref}
|
|
126
|
+
data-slot="qr-code"
|
|
127
|
+
className={cn(qrCodeVariants(), className)}
|
|
128
|
+
{...rest}
|
|
129
|
+
>
|
|
130
|
+
<div className={qrCodeCanvasWrapperVariants()}>
|
|
131
|
+
<canvas
|
|
132
|
+
ref={canvasRef}
|
|
133
|
+
width={canvasSize}
|
|
134
|
+
height={canvasSize}
|
|
135
|
+
data-slot="qr-code-canvas"
|
|
136
|
+
className="block h-auto max-w-full"
|
|
137
|
+
aria-label={`QR code for ${value}`}
|
|
138
|
+
/>
|
|
139
|
+
</div>
|
|
140
|
+
{caption ? (
|
|
141
|
+
<span data-slot="qr-code-caption" className={qrCodeCaptionVariants()}>
|
|
142
|
+
{caption}
|
|
143
|
+
</span>
|
|
144
|
+
) : null}
|
|
145
|
+
</div>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
QrCodeBase.displayName = "QrCode";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createRef } from "react";
|
|
2
|
+
import { render, screen } from "@testing-library/react";
|
|
3
|
+
import { describe, expect, it, vi } from "vitest";
|
|
4
|
+
|
|
5
|
+
import { QrCode } from "./qr-code";
|
|
6
|
+
|
|
7
|
+
vi.mock("qrcode", () => ({
|
|
8
|
+
default: {
|
|
9
|
+
toCanvas: vi.fn(
|
|
10
|
+
(
|
|
11
|
+
_canvas: HTMLCanvasElement,
|
|
12
|
+
_value: string,
|
|
13
|
+
_opts: unknown,
|
|
14
|
+
cb?: (err?: Error) => void,
|
|
15
|
+
) => {
|
|
16
|
+
cb?.();
|
|
17
|
+
},
|
|
18
|
+
),
|
|
19
|
+
},
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
describe("QrCode", () => {
|
|
23
|
+
it("should expose displayName", () => {
|
|
24
|
+
expect(QrCode.displayName).toBe("QrCode");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("should stamp data-slot", () => {
|
|
28
|
+
render(<QrCode value="https://example.com" />);
|
|
29
|
+
const root = document.querySelector('[data-slot="qr-code"]');
|
|
30
|
+
expect(root).toBeTruthy();
|
|
31
|
+
expect(root?.getAttribute("data-slot")).toBe("qr-code");
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("should render canvas element", () => {
|
|
35
|
+
render(<QrCode value="https://example.com" />);
|
|
36
|
+
const canvas = document.querySelector('[data-slot="qr-code-canvas"]');
|
|
37
|
+
expect(canvas).toBeTruthy();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should render with caption", () => {
|
|
41
|
+
render(<QrCode value="test" caption="Scan me" />);
|
|
42
|
+
expect(screen.getByText("Scan me")).toBeInTheDocument();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should forward ref", () => {
|
|
46
|
+
const ref = createRef<HTMLDivElement>();
|
|
47
|
+
render(<QrCode value="test" ref={ref} />);
|
|
48
|
+
expect(ref.current?.getAttribute("data-slot")).toBe("qr-code");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("should apply custom className", () => {
|
|
52
|
+
const { container } = render(
|
|
53
|
+
<QrCode value="test" className="custom-class" />,
|
|
54
|
+
);
|
|
55
|
+
const root = container.querySelector('[data-slot="qr-code"]');
|
|
56
|
+
expect(root?.className).toMatch(/custom-class/);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef, ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
export type QrCodeLevel = "L" | "M" | "Q" | "H";
|
|
4
|
+
|
|
5
|
+
export interface QrCodeBaseProps extends ComponentPropsWithRef<"div"> {
|
|
6
|
+
value: string;
|
|
7
|
+
canvasSize?: number;
|
|
8
|
+
level?: QrCodeLevel;
|
|
9
|
+
bgColor?: string;
|
|
10
|
+
fgColor?: string;
|
|
11
|
+
margin?: number;
|
|
12
|
+
caption?: ReactNode;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type QrCodeProps = QrCodeBaseProps;
|
|
16
|
+
|
|
17
|
+
export const QR_CODE_LEVEL_LABELS: Record<QrCodeLevel, string> = {
|
|
18
|
+
L: "Low (7%)",
|
|
19
|
+
M: "Medium (15%)",
|
|
20
|
+
Q: "Quartile (25%)",
|
|
21
|
+
H: "High (30%)",
|
|
22
|
+
} as const;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { cva } from "class-variance-authority";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
zuiQrCodeBase,
|
|
5
|
+
zuiQrCodeCanvasWrapper,
|
|
6
|
+
zuiQrCodeCaptionBase,
|
|
7
|
+
} from "../../design-system/qr-code";
|
|
8
|
+
|
|
9
|
+
export const qrCodeVariants = cva(zuiQrCodeBase);
|
|
10
|
+
export const qrCodeCanvasWrapperVariants = cva(zuiQrCodeCanvasWrapper);
|
|
11
|
+
export const qrCodeCaptionVariants = cva(zuiQrCodeCaptionBase);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
export { QrScanner } from "./qr-scanner";
|
|
4
|
+
export type {
|
|
5
|
+
QrScannerBaseProps,
|
|
6
|
+
QrScannerProps,
|
|
7
|
+
QrScannerRef,
|
|
8
|
+
QrScannerVariantProps,
|
|
9
|
+
} from "./types";
|
|
10
|
+
export {
|
|
11
|
+
qrScannerFallbackVariants,
|
|
12
|
+
qrScannerOverlayVariants,
|
|
13
|
+
qrScannerStatusVariants,
|
|
14
|
+
qrScannerVariants,
|
|
15
|
+
qrScannerVideoVariants,
|
|
16
|
+
qrScannerViewfinderVariants,
|
|
17
|
+
} from "./variants";
|