diff --git a/apps/v4/app/(app)/(root)/explore/copy-preset-button.tsx b/apps/v4/app/(app)/(root)/explore/copy-preset-button.tsx new file mode 100644 index 0000000000..71fa22a74c --- /dev/null +++ b/apps/v4/app/(app)/(root)/explore/copy-preset-button.tsx @@ -0,0 +1,31 @@ +"use client" + +import * as React from "react" + +import { Badge } from "@/examples/radix/ui/badge" +import { useCopyToClipboard } from "@/hooks/use-copy-to-clipboard" + +export function CopyPresetButton({ code }: { code: string }) { + const { copyToClipboard, isCopied } = useCopyToClipboard() + const presetValue = `--preset ${code}` + + return ( + + + + ) +} diff --git a/apps/v4/app/(app)/(root)/explore/page.tsx b/apps/v4/app/(app)/(root)/explore/page.tsx new file mode 100644 index 0000000000..d09f138f25 --- /dev/null +++ b/apps/v4/app/(app)/(root)/explore/page.tsx @@ -0,0 +1,71 @@ +import { type Metadata } from "next" +import Image from "next/image" +import Link from "next/link" +import { CopyPresetButton } from "./copy-preset-button" +import { decodePreset } from "shadcn/preset" + +import { EXPLORE_PRESETS } from "@/lib/explore" + +export const dynamic = "force-static" +export const revalidate = false + +const title = "Explore" +const description = + "Browse curated design system presets. Pick one and make it your own." + +export const metadata: Metadata = { + title, + description, +} + +export default function ExplorePage() { + const presets = EXPLORE_PRESETS.map((code) => ({ + code, + config: decodePreset(code), + })).filter( + (p): p is { code: string; config: NonNullable } => + p.config !== null + ) + + return ( +
+
+
+ {presets.map(({ code, config }) => ( + +
+
+
+ +
+
+ {`${config.style} + {`${config.style} +
+
+ + ))} +
+
+
+ ) +} diff --git a/apps/v4/app/(create)/components/random-button.tsx b/apps/v4/app/(create)/components/random-button.tsx index f6d5279c13..e91290d1ba 100644 --- a/apps/v4/app/(create)/components/random-button.tsx +++ b/apps/v4/app/(create)/components/random-button.tsx @@ -41,10 +41,6 @@ export function RandomButton() { const [params, setParams] = useDesignSystemSearchParams() const handleRandomize = React.useCallback(() => { - // Use current value if locked, otherwise randomize. - const baseColor = locks.has("baseColor") - ? params.baseColor - : randomItem(BASE_COLORS).name const selectedStyle = locks.has("style") ? params.style : randomItem(STYLES).name @@ -52,9 +48,18 @@ export function RandomButton() { // Build context for bias application. const context: RandomizeContext = { style: selectedStyle, - baseColor, } + const availableBaseColors = applyBias( + BASE_COLORS, + context, + RANDOMIZE_BIASES.baseColors + ) + const baseColor = locks.has("baseColor") + ? params.baseColor + : randomItem(availableBaseColors).name + context.baseColor = baseColor + const availableThemes = getThemesForBaseColor(baseColor) const availableFonts = applyBias(FONTS, context, RANDOMIZE_BIASES.fonts) const availableRadii = applyBias(RADII, context, RANDOMIZE_BIASES.radius) diff --git a/apps/v4/app/(create)/lib/randomize-biases.ts b/apps/v4/app/(create)/lib/randomize-biases.ts index c6505b73b7..de04164bfc 100644 --- a/apps/v4/app/(create)/lib/randomize-biases.ts +++ b/apps/v4/app/(create)/lib/randomize-biases.ts @@ -1,4 +1,5 @@ import type { + BaseColor, BaseColorName, Radius, StyleName, @@ -24,11 +25,11 @@ export type BiasFilter = ( ) => readonly T[] export type RandomizeBiases = { + baseColors?: BiasFilter fonts?: BiasFilter<(typeof FONTS)[number]> radius?: BiasFilter // Add more bias filters as needed: // styles?: BiasFilter