Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions apps/www/content/blog/next-js-getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,12 @@ And that's literally all it takes. You've just created the `/about` route. Now,
// app/about/page.tsx
export default function AboutPage() {
return (

<main className="p-24">
<h1 className="text-4xl font-bold">About Us</h1>
<p className="mt-4">This is the about page for our first Next.js app!</p>
<h1 className="text-4xl font-bold">About Us</h1>
<p className="mt-4">This is the about page for our first Next.js app!</p>
</main>
);
}
); }

With that code in place, Next.js handles the rest. Fire up your browser and navigate to `localhost:3000/about`, and you'll see your new component rendered on the screen.

Expand Down Expand Up @@ -225,19 +225,19 @@ export default async function ProductsPage() {
const data = await getProducts();

return (

<main className="p-24">
<h1 className="text-4xl font-bold mb-8">Our Products</h1>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{data.products.map((product) => (
<div key={product.id} className="border rounded-lg p-4">
<h2 className="text-xl font-semibold">{product.title}</h2>
<p className="mt-2 text-gray-600">{product.description}</p>
</div>
))}
</div>
<h1 className="mb-8 text-4xl font-bold">Our Products</h1>
<div className="grid grid-cols-1 gap-6 md:grid-cols-3">
{data.products.map((product) => (
<div key={product.id} className="rounded-lg border p-4">
<h2 className="text-xl font-semibold">{product.title}</h2>
<p className="mt-2 text-gray-600">{product.description}</p>
</div>
))}
</div>
</main>
);
}
); }

Did you catch it? `ProductsPage` is an `async` function. That one keyword lets you `await` the `getProducts()` call right before returning your JSX. It’s an incredibly clean and direct way to handle what used to be a much more complicated task.

Expand Down
4 changes: 2 additions & 2 deletions apps/www/public/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6619,8 +6619,8 @@ export const FlickeringGrid: React.FC<FlickeringGridProps> = ({
canvas.height = height * dpr
canvas.style.width = `${width}px`
canvas.style.height = `${height}px`
const cols = Math.floor(width / (squareSize + gridGap))
const rows = Math.floor(height / (squareSize + gridGap))
const cols = Math.ceil(width / (squareSize + gridGap))
const rows = Math.ceil(height / (squareSize + gridGap))

const squares = new Float32Array(cols * rows)
for (let i = 0; i < squares.length; i++) {
Expand Down
2 changes: 1 addition & 1 deletion apps/www/public/r/flickering-grid.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"files": [
{
"path": "registry/magicui/flickering-grid.tsx",
"content": "\"use client\"\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\ninterface FlickeringGridProps extends React.HTMLAttributes<HTMLDivElement> {\n squareSize?: number\n gridGap?: number\n flickerChance?: number\n color?: string\n width?: number\n height?: number\n className?: string\n maxOpacity?: number\n}\n\nexport const FlickeringGrid: React.FC<FlickeringGridProps> = ({\n squareSize = 4,\n gridGap = 6,\n flickerChance = 0.3,\n color = \"rgb(0, 0, 0)\",\n width,\n height,\n className,\n maxOpacity = 0.3,\n ...props\n}) => {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [isInView, setIsInView] = useState(false)\n const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0 })\n\n const memoizedColor = useMemo(() => {\n const toRGBA = (color: string) => {\n if (typeof window === \"undefined\") {\n return `rgba(0, 0, 0,`\n }\n const canvas = document.createElement(\"canvas\")\n canvas.width = canvas.height = 1\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return \"rgba(255, 0, 0,\"\n ctx.fillStyle = color\n ctx.fillRect(0, 0, 1, 1)\n const [r, g, b] = Array.from(ctx.getImageData(0, 0, 1, 1).data)\n return `rgba(${r}, ${g}, ${b},`\n }\n return toRGBA(color)\n }, [color])\n\n const setupCanvas = useCallback(\n (canvas: HTMLCanvasElement, width: number, height: number) => {\n const dpr = window.devicePixelRatio || 1\n canvas.width = width * dpr\n canvas.height = height * dpr\n canvas.style.width = `${width}px`\n canvas.style.height = `${height}px`\n const cols = Math.floor(width / (squareSize + gridGap))\n const rows = Math.floor(height / (squareSize + gridGap))\n\n const squares = new Float32Array(cols * rows)\n for (let i = 0; i < squares.length; i++) {\n squares[i] = Math.random() * maxOpacity\n }\n\n return { cols, rows, squares, dpr }\n },\n [squareSize, gridGap, maxOpacity]\n )\n\n const updateSquares = useCallback(\n (squares: Float32Array, deltaTime: number) => {\n for (let i = 0; i < squares.length; i++) {\n if (Math.random() < flickerChance * deltaTime) {\n squares[i] = Math.random() * maxOpacity\n }\n }\n },\n [flickerChance, maxOpacity]\n )\n\n const drawGrid = useCallback(\n (\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n cols: number,\n rows: number,\n squares: Float32Array,\n dpr: number\n ) => {\n ctx.clearRect(0, 0, width, height)\n ctx.fillStyle = \"transparent\"\n ctx.fillRect(0, 0, width, height)\n\n for (let i = 0; i < cols; i++) {\n for (let j = 0; j < rows; j++) {\n const opacity = squares[i * rows + j]\n ctx.fillStyle = `${memoizedColor}${opacity})`\n ctx.fillRect(\n i * (squareSize + gridGap) * dpr,\n j * (squareSize + gridGap) * dpr,\n squareSize * dpr,\n squareSize * dpr\n )\n }\n }\n },\n [memoizedColor, squareSize, gridGap]\n )\n\n useEffect(() => {\n const canvas = canvasRef.current\n const container = containerRef.current\n if (!canvas || !container) return\n\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n let animationFrameId: number\n let gridParams: ReturnType<typeof setupCanvas>\n\n const updateCanvasSize = () => {\n const newWidth = width || container.clientWidth\n const newHeight = height || container.clientHeight\n setCanvasSize({ width: newWidth, height: newHeight })\n gridParams = setupCanvas(canvas, newWidth, newHeight)\n }\n\n updateCanvasSize()\n\n let lastTime = 0\n const animate = (time: number) => {\n if (!isInView) return\n\n const deltaTime = (time - lastTime) / 1000\n lastTime = time\n\n updateSquares(gridParams.squares, deltaTime)\n drawGrid(\n ctx,\n canvas.width,\n canvas.height,\n gridParams.cols,\n gridParams.rows,\n gridParams.squares,\n gridParams.dpr\n )\n animationFrameId = requestAnimationFrame(animate)\n }\n\n const resizeObserver = new ResizeObserver(() => {\n updateCanvasSize()\n })\n\n resizeObserver.observe(container)\n\n const intersectionObserver = new IntersectionObserver(\n ([entry]) => {\n setIsInView(entry.isIntersecting)\n },\n { threshold: 0 }\n )\n\n intersectionObserver.observe(canvas)\n\n if (isInView) {\n animationFrameId = requestAnimationFrame(animate)\n }\n\n return () => {\n cancelAnimationFrame(animationFrameId)\n resizeObserver.disconnect()\n intersectionObserver.disconnect()\n }\n }, [setupCanvas, updateSquares, drawGrid, width, height, isInView])\n\n return (\n <div\n ref={containerRef}\n className={cn(`h-full w-full ${className}`)}\n {...props}\n >\n <canvas\n ref={canvasRef}\n className=\"pointer-events-none\"\n style={{\n width: canvasSize.width,\n height: canvasSize.height,\n }}\n />\n </div>\n )\n}\n",
"content": "\"use client\"\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\ninterface FlickeringGridProps extends React.HTMLAttributes<HTMLDivElement> {\n squareSize?: number\n gridGap?: number\n flickerChance?: number\n color?: string\n width?: number\n height?: number\n className?: string\n maxOpacity?: number\n}\n\nexport const FlickeringGrid: React.FC<FlickeringGridProps> = ({\n squareSize = 4,\n gridGap = 6,\n flickerChance = 0.3,\n color = \"rgb(0, 0, 0)\",\n width,\n height,\n className,\n maxOpacity = 0.3,\n ...props\n}) => {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [isInView, setIsInView] = useState(false)\n const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0 })\n\n const memoizedColor = useMemo(() => {\n const toRGBA = (color: string) => {\n if (typeof window === \"undefined\") {\n return `rgba(0, 0, 0,`\n }\n const canvas = document.createElement(\"canvas\")\n canvas.width = canvas.height = 1\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return \"rgba(255, 0, 0,\"\n ctx.fillStyle = color\n ctx.fillRect(0, 0, 1, 1)\n const [r, g, b] = Array.from(ctx.getImageData(0, 0, 1, 1).data)\n return `rgba(${r}, ${g}, ${b},`\n }\n return toRGBA(color)\n }, [color])\n\n const setupCanvas = useCallback(\n (canvas: HTMLCanvasElement, width: number, height: number) => {\n const dpr = window.devicePixelRatio || 1\n canvas.width = width * dpr\n canvas.height = height * dpr\n canvas.style.width = `${width}px`\n canvas.style.height = `${height}px`\n const cols = Math.ceil(width / (squareSize + gridGap))\n const rows = Math.ceil(height / (squareSize + gridGap))\n\n const squares = new Float32Array(cols * rows)\n for (let i = 0; i < squares.length; i++) {\n squares[i] = Math.random() * maxOpacity\n }\n\n return { cols, rows, squares, dpr }\n },\n [squareSize, gridGap, maxOpacity]\n )\n\n const updateSquares = useCallback(\n (squares: Float32Array, deltaTime: number) => {\n for (let i = 0; i < squares.length; i++) {\n if (Math.random() < flickerChance * deltaTime) {\n squares[i] = Math.random() * maxOpacity\n }\n }\n },\n [flickerChance, maxOpacity]\n )\n\n const drawGrid = useCallback(\n (\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n cols: number,\n rows: number,\n squares: Float32Array,\n dpr: number\n ) => {\n ctx.clearRect(0, 0, width, height)\n ctx.fillStyle = \"transparent\"\n ctx.fillRect(0, 0, width, height)\n\n for (let i = 0; i < cols; i++) {\n for (let j = 0; j < rows; j++) {\n const opacity = squares[i * rows + j]\n ctx.fillStyle = `${memoizedColor}${opacity})`\n ctx.fillRect(\n i * (squareSize + gridGap) * dpr,\n j * (squareSize + gridGap) * dpr,\n squareSize * dpr,\n squareSize * dpr\n )\n }\n }\n },\n [memoizedColor, squareSize, gridGap]\n )\n\n useEffect(() => {\n const canvas = canvasRef.current\n const container = containerRef.current\n if (!canvas || !container) return\n\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n let animationFrameId: number\n let gridParams: ReturnType<typeof setupCanvas>\n\n const updateCanvasSize = () => {\n const newWidth = width || container.clientWidth\n const newHeight = height || container.clientHeight\n setCanvasSize({ width: newWidth, height: newHeight })\n gridParams = setupCanvas(canvas, newWidth, newHeight)\n }\n\n updateCanvasSize()\n\n let lastTime = 0\n const animate = (time: number) => {\n if (!isInView) return\n\n const deltaTime = (time - lastTime) / 1000\n lastTime = time\n\n updateSquares(gridParams.squares, deltaTime)\n drawGrid(\n ctx,\n canvas.width,\n canvas.height,\n gridParams.cols,\n gridParams.rows,\n gridParams.squares,\n gridParams.dpr\n )\n animationFrameId = requestAnimationFrame(animate)\n }\n\n const resizeObserver = new ResizeObserver(() => {\n updateCanvasSize()\n })\n\n resizeObserver.observe(container)\n\n const intersectionObserver = new IntersectionObserver(\n ([entry]) => {\n setIsInView(entry.isIntersecting)\n },\n { threshold: 0 }\n )\n\n intersectionObserver.observe(canvas)\n\n if (isInView) {\n animationFrameId = requestAnimationFrame(animate)\n }\n\n return () => {\n cancelAnimationFrame(animationFrameId)\n resizeObserver.disconnect()\n intersectionObserver.disconnect()\n }\n }, [setupCanvas, updateSquares, drawGrid, width, height, isInView])\n\n return (\n <div\n ref={containerRef}\n className={cn(`h-full w-full ${className}`)}\n {...props}\n >\n <canvas\n ref={canvasRef}\n className=\"pointer-events-none\"\n style={{\n width: canvasSize.width,\n height: canvasSize.height,\n }}\n />\n </div>\n )\n}\n",
"type": "registry:ui"
}
]
Expand Down
4 changes: 2 additions & 2 deletions apps/www/registry/magicui/flickering-grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ export const FlickeringGrid: React.FC<FlickeringGridProps> = ({
canvas.height = height * dpr
canvas.style.width = `${width}px`
canvas.style.height = `${height}px`
const cols = Math.floor(width / (squareSize + gridGap))
const rows = Math.floor(height / (squareSize + gridGap))
const cols = Math.ceil(width / (squareSize + gridGap))
const rows = Math.ceil(height / (squareSize + gridGap))

const squares = new Float32Array(cols * rows)
for (let i = 0; i < squares.length; i++) {
Expand Down