This commit is contained in:
shadcn
2026-02-19 13:45:00 +04:00
parent b530f4928e
commit c171ae4761
35 changed files with 55 additions and 48 deletions

View File

@@ -133,7 +133,11 @@ export function useDesignSystemSearchParams(options: Options = {}) {
// Use ref so setParams callback stays stable across renders.
const paramsRef = React.useRef(params)
paramsRef.current = params
React.useEffect(() => {
paramsRef.current = params
}, [params])
type RawSetParamsInput = Parameters<typeof rawSetParams>[0]
const setParams = React.useCallback(
(
@@ -153,7 +157,7 @@ export function useDesignSystemSearchParams(options: Options = {}) {
if (!hasDesignSystemUpdate) {
// No design system change, pass through directly.
return rawSetParams(resolvedUpdates as any, setOptions)
return rawSetParams(resolvedUpdates as RawSetParamsInput, setOptions)
}
// Merge current decoded values with updates.
@@ -187,7 +191,7 @@ export function useDesignSystemSearchParams(options: Options = {}) {
}
}
return rawSetParams(rawUpdate as any, setOptions)
return rawSetParams(rawUpdate as RawSetParamsInput, setOptions)
},
[rawSetParams]
)

View File

@@ -1,11 +1,11 @@
export const EXPLORE_PRESETS: string[] = [
"AuFzoPZ",
"A1zDJJ",
"A1DN5Lx2",
"AbZIu0W",
"AL1Qw4",
"A2He4G",
"A1DOCw6i",
"A1D5CKfo",
"AbYAmrx",
"auFzoPZ",
"a1zDJJ",
"a1DN5Lx2",
"abZIu0W",
"a2r6bw",
"a2He4G",
"a1DOCw6i",
"a1D5CKfo",
"abYAmrx",
]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -202,14 +202,14 @@ export default function PreviewExample() {
}, [params.radius])
return (
<ExampleWrapper className="w-full max-w-none! lg:p-0">
<div>
<Example
containerClassName="col-span-2 max-w-none"
className="bg-muted dark:bg-background flex min-h-svh flex-col items-center justify-center border-none sm:p-16"
className="bg-muted dark:bg-background flex min-h-svh flex-col items-center justify-center border-none p-0 sm:p-0"
>
<div
data-slot="capture-target"
className="grid max-w-4xl gap-6 p-6 lg:grid-cols-2"
className="grid max-w-4xl gap-6 p-8 lg:grid-cols-2"
style={
{
"--radius": radiusValue,
@@ -241,7 +241,7 @@ export default function PreviewExample() {
key={variant}
className="flex flex-col flex-wrap items-center gap-2"
>
<Card
<Item
className="ring-border aspect-square w-full bg-(--color) ring"
style={
{
@@ -294,7 +294,7 @@ export default function PreviewExample() {
<div className="flex flex-col gap-6">
<Card className="hidden md:flex">
<CardContent>
<div className="grid grid-cols-4 place-items-center gap-6 md:grid-cols-7">
<div className="grid grid-cols-4 place-items-center gap-4 md:grid-cols-7">
{PREVIEW_ICONS.map((icon, index) => (
<Card
key={index}
@@ -313,7 +313,7 @@ export default function PreviewExample() {
</CardContent>
</Card>
<Card className="flex-1">
<CardContent className="flex flex-col gap-6">
<CardContent className="flex flex-1 flex-col gap-6">
<div className="flex flex-col gap-4">
<div className="flex flex-wrap gap-2">
<Button>Default</Button>
@@ -357,7 +357,7 @@ export default function PreviewExample() {
<Field className="flex-row">
<Input placeholder="Name" />
</Field>
<Field className="flex-row">
<Field className="flex-1 flex-row">
<Textarea placeholder="Message" className="resize-none" />
</Field>
<Slider
@@ -503,6 +503,6 @@ export default function PreviewExample() {
</div>
</div>
</Example>
</ExampleWrapper>
</div>
)
}

View File

@@ -202,14 +202,14 @@ export default function PreviewExample() {
}, [params.radius])
return (
<ExampleWrapper className="w-full max-w-none! lg:p-0">
<div>
<Example
containerClassName="col-span-2 max-w-none"
className="bg-muted dark:bg-background flex min-h-svh flex-col items-center justify-center border-none sm:p-16"
className="bg-muted dark:bg-background flex min-h-svh flex-col items-center justify-center border-none p-0 sm:p-0"
>
<div
data-slot="capture-target"
className="grid max-w-4xl gap-6 p-6 lg:grid-cols-2"
className="grid max-w-4xl gap-6 p-8 lg:grid-cols-2"
style={
{
"--radius": radiusValue,
@@ -241,7 +241,7 @@ export default function PreviewExample() {
key={variant}
className="flex flex-col flex-wrap items-center gap-2"
>
<Card
<Item
className="ring-border aspect-square w-full bg-(--color) ring"
style={
{
@@ -294,7 +294,7 @@ export default function PreviewExample() {
<div className="flex flex-col gap-6">
<Card className="hidden md:flex">
<CardContent>
<div className="grid grid-cols-4 place-items-center gap-6 md:grid-cols-7">
<div className="grid grid-cols-4 place-items-center gap-4 md:grid-cols-7">
{PREVIEW_ICONS.map((icon, index) => (
<Card
key={index}
@@ -313,7 +313,7 @@ export default function PreviewExample() {
</CardContent>
</Card>
<Card className="flex-1">
<CardContent className="flex flex-col gap-6">
<CardContent className="flex flex-1 flex-col gap-6">
<div className="flex flex-col gap-4">
<div className="flex flex-wrap gap-2">
<Button>Default</Button>
@@ -357,7 +357,7 @@ export default function PreviewExample() {
<Field className="flex-row">
<Input placeholder="Name" />
</Field>
<Field className="flex-row">
<Field className="flex-1 flex-row">
<Textarea placeholder="Message" className="resize-none" />
</Field>
<Slider
@@ -505,6 +505,6 @@ export default function PreviewExample() {
</div>
</div>
</Example>
</ExampleWrapper>
</div>
)
}

View File

@@ -6,6 +6,7 @@ import { decodePreset } from "shadcn/preset"
import { EXPLORE_PRESETS } from "../lib/explore"
const PRESETS_PATH = path.join(process.cwd(), "public/presets")
const force = process.argv.includes("--force")
// ----------------------------------------------------------------------------
// Capture explore preset screenshots.
@@ -16,11 +17,13 @@ async function captureScreenshots() {
mkdirSync(PRESETS_PATH, { recursive: true })
}
const presets = EXPLORE_PRESETS.filter((code) => {
const lightPath = path.join(PRESETS_PATH, `${code}-light.png`)
const darkPath = path.join(PRESETS_PATH, `${code}-dark.png`)
return !existsSync(lightPath) || !existsSync(darkPath)
})
const presets = force
? EXPLORE_PRESETS
: EXPLORE_PRESETS.filter((code) => {
const lightPath = path.join(PRESETS_PATH, `${code}-light.png`)
const darkPath = path.join(PRESETS_PATH, `${code}-dark.png`)
return !existsSync(lightPath) || !existsSync(darkPath)
})
if (presets.length === 0) {
console.log("✨ All screenshots exist, nothing to capture")
@@ -57,7 +60,7 @@ async function captureScreenshots() {
`${code}-${theme}.png`
)
if (existsSync(screenshotPath)) {
if (!force && existsSync(screenshotPath)) {
continue
}

View File

@@ -68,7 +68,7 @@ describe("encodePreset / decodePreset", () => {
it("should start with the version character", () => {
const code = encodePreset(DEFAULT_PRESET_CONFIG)
expect(code[0]).toBe("A")
expect(code[0]).toBe("a")
})
it("should handle partial config by filling defaults", () => {
@@ -153,7 +153,7 @@ describe("decodePreset edge cases", () => {
})
it("should return null for wrong version prefix", () => {
expect(decodePreset("B123")).toBeNull()
expect(decodePreset("b123")).toBeNull()
})
it("should return null for invalid base62 characters", () => {
@@ -196,7 +196,7 @@ describe("isValidPreset", () => {
it("should return false for invalid codes", () => {
expect(isValidPreset("")).toBe(false)
expect(isValidPreset("B123")).toBe(false)
expect(isValidPreset("b123")).toBe(false)
})
})

View File

@@ -100,7 +100,7 @@ export const DEFAULT_PRESET_CONFIG: PresetConfig = Object.fromEntries(
const BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
// Version prefix — 'A' = version 1.
const VERSION_CHAR = "A"
const VERSION_CHAR = "a"
export function toBase62(num: number) {
if (num === 0) return "0"