Skip to content

Commit 73607e8

Browse files
authored
feat(qr-code): add overlay primitive (#173)
* feat(qr-code): add overlay component for logos and icons - Add QRCodeOverlay component for placing content in center of QR codes - Works with all rendering methods (Image, Canvas, SVG) - Defaults to 20% of QR code size for optimal scannability - Add demo showing overlay with different rendering methods - Add documentation and API reference - Recommend level='H' for best error correction with overlays * feat: update demos * feat: add qr-code-skeleton * feat: update qr-code
1 parent 7847036 commit 73607e8

File tree

15 files changed

+314
-98
lines changed

15 files changed

+314
-98
lines changed

docs/__registry__/index.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,6 +1719,20 @@ export const Index: Record<string, any> = {
17191719
source: "",
17201720
chunks: []
17211721
},
1722+
"qr-code-overlay-demo": {
1723+
name: "qr-code-overlay-demo",
1724+
description: "",
1725+
type: "registry:example",
1726+
registryDependencies: ["qr-code"],
1727+
files: [{
1728+
path: "registry/default/examples/qr-code-overlay-demo.tsx",
1729+
type: "registry:example",
1730+
target: ""
1731+
}],
1732+
component: React.lazy(() => import("@/registry/default/examples/qr-code-overlay-demo.tsx")),
1733+
source: "",
1734+
chunks: []
1735+
},
17221736
"rating-demo": {
17231737
name: "rating-demo",
17241738
description: "",

docs/app/(lobby)/pg/page.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
import { Demo } from "@/components/demo";
22
import { Shell } from "@/components/shell";
33
import ColorPickerDemo from "@/registry/default/examples/color-picker-demo";
4+
import QRCodeDemo from "@/registry/default/examples/qr-code-demo";
5+
import QRCodeFormatsDemo from "@/registry/default/examples/qr-code-formats-demo";
6+
import QRCodeOverlayDemo from "@/registry/default/examples/qr-code-overlay-demo";
47
import ScrollSpyControlledDemo from "@/registry/default/examples/scroll-spy-controlled-demo";
58
import ScrollSpyDemo from "@/registry/default/examples/scroll-spy-demo";
69
import ScrollSpyVerticalDemo from "@/registry/default/examples/scroll-spy-vertical-demo";
7-
import StackDemo from "@/registry/default/examples/stack-demo";
8-
import StackSideDemo from "@/registry/default/examples/stack-side-demo";
910

1011
export default function PlaygroundPage() {
1112
return (
1213
<Shell>
1314
<Demo>
14-
<StackDemo />
15-
<StackSideDemo />
15+
<QRCodeDemo />
16+
<QRCodeFormatsDemo />
17+
<QRCodeOverlayDemo />
1618
<ScrollSpyDemo />
1719
<ScrollSpyControlledDemo />
1820
<ScrollSpyVerticalDemo />

docs/content/docs/components/qr-code.mdx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,13 @@ import { QRCode } from "@/components/ui/qr-code";
5050
return (
5151
<QRCode>
5252
<QRCode.Canvas />
53+
<QRCode.Overlay />
54+
<QRCode.Skeleton />
55+
<QRCode.Download />
5356
</QRCode>
5457
)
5558
```
59+
Swap `Canvas` with `Svg` or `Image` to render the qr code in svg and image formats respectively.
5660

5761
## Examples
5862

@@ -68,6 +72,12 @@ Customize colors, size, and error correction levels.
6872

6973
<ComponentTabs name="qr-code-customization-demo" />
7074

75+
### Overlay
76+
77+
Add logos, icons, or custom elements to the center of QR codes.
78+
79+
<ComponentTabs name="qr-code-overlay-demo" />
80+
7181
## API Reference
7282

7383
### Root
@@ -116,6 +126,24 @@ Renders the QR code as an SVG element.
116126
name="SvgProps"
117127
/>
118128

129+
### Overlay
130+
131+
Overlays content (like logos or icons) in the center of the QR code.
132+
133+
<AutoTypeTable
134+
path="./types/docs/qr-code.ts"
135+
name="OverlayProps"
136+
/>
137+
138+
### Skeleton
139+
140+
Displays a loading placeholder while the QR code is being generated. Automatically hides once the QR code is ready.
141+
142+
<AutoTypeTable
143+
path="./types/docs/qr-code.ts"
144+
name="SkeletonProps"
145+
/>
146+
119147
### Download
120148

121149
A button component for downloading the QR code.
@@ -161,3 +189,4 @@ Higher error correction levels result in denser QR codes but provide better resi
161189
- The download functionality works in all modern browsers
162190
- QR codes are generated client-side for privacy and performance
163191
- Child elements are automatically constrained by the `--qr-code-size` CSS variable to prevent layout issues
192+
- When using the Overlay component, set `level="H"` (High error correction) to ensure the QR code remains scannable with up to 30% coverage

docs/public/r/styles/default/qr-code-customization-demo.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"files": [
88
{
99
"path": "examples/qr-code-customization-demo.tsx",
10-
"content": "import { QRCode, QRCodeCanvas } from \"@/registry/default/ui/qr-code\";\n\nexport default function QRCodeCustomizationDemo() {\n return (\n <div className=\"grid grid-cols-1 gap-6 sm:grid-cols-2\">\n <div className=\"flex flex-col items-center gap-2\">\n <QRCode\n value=\"https://diceui.com\"\n size={150}\n foregroundColor=\"#3b82f6\"\n backgroundColor=\"#f1f5f9\"\n >\n <QRCodeCanvas />\n </QRCode>\n <p className=\"text-muted-foreground text-sm\">Custom Colors</p>\n </div>\n\n <div className=\"flex flex-col items-center gap-2\">\n <QRCode\n value=\"https://diceui.com\"\n size={150}\n level=\"H\"\n foregroundColor=\"#dc2626\"\n >\n <QRCodeCanvas />\n </QRCode>\n <p className=\"text-muted-foreground text-sm\">High Error Correction</p>\n </div>\n </div>\n );\n}\n",
10+
"content": "import {\n QRCode,\n QRCodeCanvas,\n QRCodeSkeleton,\n} from \"@/registry/default/ui/qr-code\";\n\nexport default function QRCodeCustomizationDemo() {\n return (\n <div className=\"grid grid-cols-1 gap-6 sm:grid-cols-2\">\n <div className=\"flex flex-col items-center gap-2\">\n <QRCode\n value=\"https://diceui.com\"\n size={150}\n foregroundColor=\"#3b82f6\"\n backgroundColor=\"#f1f5f9\"\n >\n <QRCodeCanvas />\n <QRCodeSkeleton />\n </QRCode>\n <p className=\"text-muted-foreground text-sm\">Custom Colors</p>\n </div>\n\n <div className=\"flex flex-col items-center gap-2\">\n <QRCode\n value=\"https://diceui.com\"\n size={150}\n level=\"H\"\n foregroundColor=\"#dc2626\"\n >\n <QRCodeCanvas />\n <QRCodeSkeleton />\n </QRCode>\n <p className=\"text-muted-foreground text-sm\">High Error Correction</p>\n </div>\n </div>\n );\n}\n",
1111
"type": "registry:example",
1212
"target": ""
1313
}

docs/public/r/styles/default/qr-code-demo.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"files": [
88
{
99
"path": "examples/qr-code-demo.tsx",
10-
"content": "import { QRCode, QRCodeCanvas } from \"@/registry/default/ui/qr-code\";\n\nexport default function QRCodeDemo() {\n return (\n <QRCode value=\"https://diceui.com\" size={200}>\n <QRCodeCanvas />\n </QRCode>\n );\n}\n",
10+
"content": "import {\n QRCode,\n QRCodeCanvas,\n QRCodeSkeleton,\n} from \"@/registry/default/ui/qr-code\";\n\nexport default function QRCodeDemo() {\n return (\n <QRCode value=\"https://diceui.com\" size={200}>\n <QRCodeSkeleton />\n <QRCodeCanvas />\n </QRCode>\n );\n}\n",
1111
"type": "registry:example",
1212
"target": ""
1313
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "qr-code-overlay-demo",
3+
"type": "registry:example",
4+
"dependencies": [
5+
"lucide-react"
6+
],
7+
"registryDependencies": [
8+
"qr-code"
9+
],
10+
"files": [
11+
{
12+
"path": "examples/qr-code-overlay-demo.tsx",
13+
"content": "import { Dice4 } from \"lucide-react\";\nimport {\n QRCode,\n QRCodeCanvas,\n QRCodeImage,\n QRCodeOverlay,\n QRCodeSkeleton,\n QRCodeSvg,\n} from \"@/registry/default/ui/qr-code\";\n\nexport default function QRCodeOverlayDemo() {\n return (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3\">\n <div className=\"flex flex-col items-center gap-2\">\n <QRCode\n value=\"https://diceui.com\"\n size={120}\n level=\"H\"\n className=\"gap-4\"\n >\n <QRCodeSkeleton />\n <QRCodeCanvas />\n <QRCodeOverlay className=\"rounded-full border-2 border-white p-2\">\n <Dice4 className=\"size-6\" />\n </QRCodeOverlay>\n </QRCode>\n <p className=\"text-center text-muted-foreground text-sm\">\n Canvas with Logo\n </p>\n </div>\n\n <div className=\"flex flex-col items-center gap-2\">\n <QRCode\n value=\"https://diceui.com\"\n size={120}\n level=\"H\"\n className=\"gap-4\"\n >\n <QRCodeSkeleton />\n <QRCodeSvg />\n <QRCodeOverlay className=\"rounded-full border-2 border-white bg-linear-to-br from-accent to-muted p-2\">\n <Dice4 className=\"size-6\" />\n </QRCodeOverlay>\n </QRCode>\n <p className=\"text-center text-muted-foreground text-sm\">\n SVG with Logo\n </p>\n </div>\n\n <div className=\"flex flex-col items-center gap-2\">\n <QRCode\n value=\"https://diceui.com\"\n size={120}\n level=\"H\"\n className=\"gap-4\"\n >\n <QRCodeSkeleton />\n <QRCodeImage />\n <QRCodeOverlay className=\"rounded-full border-2 border-white p-1.5\">\n <Dice4 className=\"size-6\" />\n </QRCodeOverlay>\n </QRCode>\n <p className=\"text-center text-muted-foreground text-sm\">\n Image with Logo\n </p>\n </div>\n </div>\n );\n}\n",
14+
"type": "registry:example",
15+
"target": ""
16+
}
17+
]
18+
}

0 commit comments

Comments
 (0)