This commit is contained in:
shadcn
2026-02-20 22:49:00 +04:00
parent 642d802eee
commit c1374c5592
23 changed files with 82 additions and 42 deletions

View File

@@ -10,6 +10,7 @@ import { HugeiconsIcon } from "@hugeicons/react"
import { useConfig } from "@/hooks/use-config"
import { copyToClipboardWithMeta } from "@/components/copy-button"
import { BASES } from "@/registry/config"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Collapsible,
@@ -87,23 +88,25 @@ export function ProjectForm() {
const commands = React.useMemo(() => {
const origin = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:4000"
const isLocalDev = origin.includes("localhost")
const baseFlag = params.base ? ` --base ${params.base}` : ""
const rtlFlag = params.rtl ? " --rtl" : ""
const templateFlag = params.template ? ` --template ${params.template}` : ""
const flags = `${baseFlag}${rtlFlag}`
return isLocalDev
? {
pnpm: `pnpm shadcn init${rtlFlag} --preset ${presetCode}${templateFlag}`,
npm: `pnpm shadcn init${rtlFlag} --preset ${presetCode}${templateFlag}`,
yarn: `pnpm shadcn init${rtlFlag} --preset ${presetCode}${templateFlag}`,
bun: `pnpm shadcn init${rtlFlag} --preset ${presetCode}${templateFlag}`,
pnpm: `pnpm shadcn init${flags} --preset ${presetCode}${templateFlag}`,
npm: `pnpm shadcn init${flags} --preset ${presetCode}${templateFlag}`,
yarn: `pnpm shadcn init${flags} --preset ${presetCode}${templateFlag}`,
bun: `pnpm shadcn init${flags} --preset ${presetCode}${templateFlag}`,
}
: {
pnpm: `pnpm dlx shadcn@latest init${rtlFlag} --preset ${presetCode}${templateFlag}`,
npm: `npx shadcn@latest init${rtlFlag} --preset ${presetCode}${templateFlag}`,
yarn: `yarn dlx shadcn@latest init${rtlFlag} --preset ${presetCode}${templateFlag}`,
bun: `bunx --bun shadcn@latest init${rtlFlag} --preset ${presetCode}${templateFlag}`,
pnpm: `pnpm dlx shadcn@latest init${flags} --preset ${presetCode}${templateFlag}`,
npm: `npx shadcn@latest init${flags} --preset ${presetCode}${templateFlag}`,
yarn: `yarn dlx shadcn@latest init${flags} --preset ${presetCode}${templateFlag}`,
bun: `bunx --bun shadcn@latest init${flags} --preset ${presetCode}${templateFlag}`,
}
}, [presetCode, params.rtl, params.template])
}, [presetCode, params.base, params.rtl, params.template])
const command = commands[packageManager]
@@ -222,7 +225,40 @@ export function ProjectForm() {
<path d="m6 9 6 6 6-6" />
</svg>
</CollapsibleTrigger>
<CollapsibleContent className="border-t px-3 py-3">
<CollapsibleContent className="space-y-4 border-t px-3 py-3">
<Field>
<FieldLabel className="text-sm">Component Library</FieldLabel>
<RadioGroup
value={params.base}
onValueChange={(value) => {
setParams({
base: value as "radix" | "base",
})
}}
className="grid grid-cols-2 gap-2"
>
{BASES.map((base) => (
<FieldLabel key={base.name} htmlFor={`base-${base.name}`}>
<Field className="flex min-w-0 flex-row items-center gap-2 p-3! *:w-auto!">
<RadioGroupItem
value={base.name}
id={`base-${base.name}`}
className="sr-only"
/>
{base.meta?.logo && (
<div
className="text-foreground *:[svg]:text-foreground! size-4 shrink-0 [&_svg]:size-4"
dangerouslySetInnerHTML={{
__html: base.meta.logo,
}}
/>
)}
<FieldTitle>{base.title}</FieldTitle>
</Field>
</FieldLabel>
))}
</RadioGroup>
</Field>
<Field orientation="horizontal" className="items-center">
<FieldContent className="gap-0.5">
<FieldLabel htmlFor="rtl" className="text-sm">

View File

@@ -17,7 +17,6 @@ export function usePresetCode() {
// Otherwise encode current params (e.g. on initial load before first interaction).
return encodePreset({
base: params.base ?? undefined,
style: params.style ?? undefined,
baseColor: params.baseColor ?? undefined,
theme: params.theme ?? undefined,
@@ -29,7 +28,6 @@ export function usePresetCode() {
} as Parameters<typeof encodePreset>[0])
}, [
params.preset,
params.base,
params.style,
params.baseColor,
params.theme,

View File

@@ -78,7 +78,6 @@ const designSystemSearchParams = {
// Design system param keys that get encoded into the preset code.
const DESIGN_SYSTEM_KEYS = [
"base",
"style",
"baseColor",
"theme",
@@ -90,7 +89,9 @@ const DESIGN_SYSTEM_KEYS = [
] as const
// Non-design-system keys that get passed through as-is.
// `base` is not encoded in preset codes — it's an architectural choice, not visual.
const NON_DESIGN_SYSTEM_KEYS = [
"base",
"item",
"template",
"rtl",
@@ -167,7 +168,6 @@ export function useDesignSystemSearchParams(options: Options = {}) {
// Cast needed: merged values may include null from nuqs resets,
// but encodePreset handles missing values by falling back to defaults.
const code = encodePreset({
base: merged.base ?? undefined,
style: merged.style ?? undefined,
baseColor: merged.baseColor ?? undefined,
theme: merged.theme ?? undefined,

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

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

@@ -1317,8 +1317,12 @@
@apply size-6 rounded-none p-0 has-[>svg]:p-0;
}
.cn-input-group-button-size-sm {
@apply gap-1;
}
.cn-input-group-button-size-icon-sm {
@apply size-8 p-0 has-[>svg]:p-0;
@apply size-7 p-0 has-[>svg]:p-0;
}
.cn-input-group-text {

View File

@@ -1344,8 +1344,12 @@
@apply size-6 p-0 has-[>svg]:p-0;
}
.cn-input-group-button-size-sm {
@apply gap-1;
}
.cn-input-group-button-size-icon-sm {
@apply size-8 p-0 has-[>svg]:p-0;
@apply size-7 p-0 has-[>svg]:p-0;
}
.cn-input-group-text {

View File

@@ -45,7 +45,7 @@ async function captureScreenshots() {
continue
}
const pageUrl = `http://localhost:4000/preview/${decoded.base}/preview?preset=${code}`
const pageUrl = `http://localhost:4000/preview/radix/preview?preset=${code}`
const page = await browser.newPage()
await page.goto(pageUrl, {

View File

@@ -58,8 +58,7 @@ export async function preFlightInit(
| Record<string, unknown>
| undefined
const projectInfo = await getProjectInfo(options.cwd, {
configCssFile:
typeof tailwind?.css === "string" ? tailwind.css : undefined,
configCssFile: typeof tailwind?.css === "string" ? tailwind.css : undefined,
})
if (!projectInfo || projectInfo?.framework.name === "manual") {
errors[ERRORS.UNSUPPORTED_FRAMEWORK] = true

View File

@@ -137,8 +137,8 @@ async function addProjectComponents(
// Write CSS last so the file watcher triggers a rebuild
// after all component files and dependencies are in place.
const overwriteCssVars = tree.cssVars
? (options.overwriteCssVars ??
(await shouldOverwriteCssVars(components, config)))
? options.overwriteCssVars ??
(await shouldOverwriteCssVars(components, config))
: undefined
await updateCss(tree.css, config, {
silent: options.silent,
@@ -267,7 +267,9 @@ async function addWorkspaceComponents(
const configKey = FILE_TYPE_TO_CONFIG_KEY[type]
const targetConfig =
configKey && workspaceConfig[configKey] ? workspaceConfig[configKey] : config
configKey && workspaceConfig[configKey]
? workspaceConfig[configKey]
: config
const typeWorkspaceRoot = findCommonRoot(
config.resolvedPaths.cwd,
@@ -309,8 +311,8 @@ async function addWorkspaceComponents(
// 6. Write CSS last so the file watcher triggers a rebuild
// after all component files and dependencies are in place.
const overwriteCssVars = tree.cssVars
? (options.overwriteCssVars ??
(await shouldOverwriteCssVars(components, config)))
? options.overwriteCssVars ??
(await shouldOverwriteCssVars(components, config))
: undefined
await updateCss(tree.css, mainTargetConfig, {
silent: true,

View File

@@ -245,10 +245,7 @@ export async function getTailwindVersion(
return "v4"
}
export async function getTailwindCssFile(
cwd: string,
configCssFile?: string
) {
export async function getTailwindCssFile(cwd: string, configCssFile?: string) {
// If the existing config has a known CSS file, check it first.
if (configCssFile) {
const resolvedPath = path.resolve(cwd, configCssFile)