mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-07-07 14:08:47 +00:00
feat(create): pick shuffle presets from a curated list (#11092)
* feat(create): pick shuffle presets from a curated list Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore: format Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { decodePreset } from "shadcn/preset"
|
||||
|
||||
import {
|
||||
BASE_COLORS,
|
||||
@@ -10,10 +11,20 @@ import {
|
||||
MENU_COLORS,
|
||||
RADII,
|
||||
STYLES,
|
||||
type BaseColorName,
|
||||
type ChartColorName,
|
||||
type FontHeadingValue,
|
||||
type FontValue,
|
||||
type IconLibraryName,
|
||||
type MenuAccentValue,
|
||||
type MenuColorValue,
|
||||
type RadiusValue,
|
||||
type StyleName,
|
||||
type ThemeName,
|
||||
} from "@/registry/config"
|
||||
import { useLocks } from "@/app/(app)/create/hooks/use-locks"
|
||||
import { FONTS } from "@/app/(app)/create/lib/fonts"
|
||||
import { getPresetCode } from "@/app/(app)/create/lib/preset-code"
|
||||
import {
|
||||
applyBias,
|
||||
RANDOMIZE_BIASES,
|
||||
@@ -23,6 +34,7 @@ import {
|
||||
isTranslucentMenuColor,
|
||||
useDesignSystemSearchParams,
|
||||
} from "@/app/(app)/create/lib/search-params"
|
||||
import { SHUFFLE_PRESETS } from "@/app/(app)/create/lib/shuffle-presets"
|
||||
|
||||
function randomItem<T>(array: readonly T[]): T {
|
||||
return array[Math.floor(Math.random() * array.length)]
|
||||
@@ -37,7 +49,9 @@ export function useRandom() {
|
||||
paramsRef.current = params
|
||||
}, [params])
|
||||
|
||||
const randomize = React.useCallback(() => {
|
||||
// True-random implementation. Kept, but shuffle is now wired to the
|
||||
// curated preset list below.
|
||||
const randomizeTrueRandom = React.useCallback(() => {
|
||||
const selectedStyle = locks.has("style")
|
||||
? paramsRef.current.style
|
||||
: randomItem(STYLES).name
|
||||
@@ -149,6 +163,60 @@ export function useRandom() {
|
||||
setParams(nextParams)
|
||||
}, [setParams, locks])
|
||||
|
||||
// Picks a random preset from the curated list instead of true random.
|
||||
// Locked params are preserved over the decoded preset values.
|
||||
const randomize = React.useCallback(() => {
|
||||
// Avoid re-picking the preset that is currently applied.
|
||||
const currentCode = getPresetCode(paramsRef.current)
|
||||
const availableCodes = SHUFFLE_PRESETS.filter(
|
||||
(code) => code !== currentCode
|
||||
)
|
||||
const decoded = decodePreset(
|
||||
randomItem(availableCodes.length > 0 ? availableCodes : SHUFFLE_PRESETS)
|
||||
)
|
||||
|
||||
if (!decoded) {
|
||||
return
|
||||
}
|
||||
|
||||
const current = paramsRef.current
|
||||
const nextParams = {
|
||||
style: locks.has("style") ? current.style : (decoded.style as StyleName),
|
||||
baseColor: locks.has("baseColor")
|
||||
? current.baseColor
|
||||
: (decoded.baseColor as BaseColorName),
|
||||
theme: locks.has("theme") ? current.theme : (decoded.theme as ThemeName),
|
||||
chartColor: locks.has("chartColor")
|
||||
? current.chartColor
|
||||
: ((decoded.chartColor ?? decoded.theme) as ChartColorName),
|
||||
iconLibrary: locks.has("iconLibrary")
|
||||
? current.iconLibrary
|
||||
: (decoded.iconLibrary as IconLibraryName),
|
||||
font: locks.has("font") ? current.font : (decoded.font as FontValue),
|
||||
fontHeading: locks.has("fontHeading")
|
||||
? current.fontHeading
|
||||
: (decoded.fontHeading as FontHeadingValue),
|
||||
menuAccent: locks.has("menuAccent")
|
||||
? current.menuAccent
|
||||
: (decoded.menuAccent as MenuAccentValue),
|
||||
menuColor: locks.has("menuColor")
|
||||
? current.menuColor
|
||||
: (decoded.menuColor as MenuColorValue),
|
||||
radius: locks.has("radius")
|
||||
? current.radius
|
||||
: (decoded.radius as RadiusValue),
|
||||
}
|
||||
|
||||
// Keep the ref in sync so rapid repeats use the latest randomized state
|
||||
// even before the URL state finishes committing.
|
||||
paramsRef.current = {
|
||||
...paramsRef.current,
|
||||
...nextParams,
|
||||
}
|
||||
|
||||
setParams(nextParams)
|
||||
}, [setParams, locks])
|
||||
|
||||
const randomizeRef = React.useRef(randomize)
|
||||
React.useEffect(() => {
|
||||
randomizeRef.current = randomize
|
||||
@@ -177,5 +245,5 @@ export function useRandom() {
|
||||
}
|
||||
}, [])
|
||||
|
||||
return { randomize }
|
||||
return { randomize, randomizeTrueRandom }
|
||||
}
|
||||
|
||||
28
apps/v4/app/(app)/create/lib/shuffle-presets.ts
Normal file
28
apps/v4/app/(app)/create/lib/shuffle-presets.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
// Curated preset codes from https://dialectcn.xyz.
|
||||
export const SHUFFLE_PRESETS = [
|
||||
"b6sUj34d9",
|
||||
"b2tqYzpa88",
|
||||
"b1W4tDrk",
|
||||
"b1aIuQ2XC",
|
||||
"b7jsW1RxJ5",
|
||||
"b870VEw0in",
|
||||
"b3Zheoix4U",
|
||||
"b1x9M2c4aI",
|
||||
"b1W7jDEW",
|
||||
"b51GFh7y6",
|
||||
"b2fms620zo",
|
||||
"b1Q5GC",
|
||||
"buKEvLs",
|
||||
"b5rR41Mtnc",
|
||||
"b6tOz2I0x",
|
||||
"b2hNTREGRN",
|
||||
"bdIJ7Sq",
|
||||
"b6TqMNb5Wb",
|
||||
"bJIirQ",
|
||||
"b4aRK5K0fb",
|
||||
"b5HCiD38LI",
|
||||
"bdHjvCi",
|
||||
"b7QDHijUjj",
|
||||
"b4ZVZIPi9h",
|
||||
"b1W4bcno",
|
||||
]
|
||||
Reference in New Issue
Block a user