mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-11 09:51:40 +00:00
Compare commits
47 Commits
shadcn@4.5
...
revert-106
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9f57eb0e8 | ||
|
|
d7066f4a2d | ||
|
|
5274de83d6 | ||
|
|
7e4dac7f31 | ||
|
|
28122dba18 | ||
|
|
93cde61946 | ||
|
|
c2dc06a99c | ||
|
|
c9930b7fda | ||
|
|
d1149454a8 | ||
|
|
36139f6200 | ||
|
|
15ac1be92b | ||
|
|
8ca30ed32c | ||
|
|
e2605bc7c2 | ||
|
|
b8608d0976 | ||
|
|
fc1ca40af4 | ||
|
|
f454f6e4d1 | ||
|
|
8cc7073aec | ||
|
|
031387a471 | ||
|
|
dd3567c39d | ||
|
|
ad2b8891a5 | ||
|
|
f6e18c65cf | ||
|
|
1c4a53a37a | ||
|
|
bc2db187aa | ||
|
|
92b4927a80 | ||
|
|
3cbabe012e | ||
|
|
1137b24a97 | ||
|
|
bb251e2ab6 | ||
|
|
28b3e5f360 | ||
|
|
309d95017f | ||
|
|
eb42ae25fd | ||
|
|
3977fb9ace | ||
|
|
7865621397 | ||
|
|
b07070cd07 | ||
|
|
ad68a44717 | ||
|
|
56161142f1 | ||
|
|
c2e1a5793f | ||
|
|
ea6086cbcc | ||
|
|
68a69d81f7 | ||
|
|
55fd4dc71b | ||
|
|
6dea65ebcb | ||
|
|
ba10089b8d | ||
|
|
8a814f926b | ||
|
|
c236d0c009 | ||
|
|
fd0e0c369b | ||
|
|
07d14abde1 | ||
|
|
8dd51c49f8 | ||
|
|
c20e0cc596 |
5
.changeset/angry-stars-pick.md
Normal file
5
.changeset/angry-stars-pick.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"shadcn": patch
|
||||
---
|
||||
|
||||
fix failing version derivation test
|
||||
75
.github/workflows/signed-commits.yml
vendored
Normal file
75
.github/workflows/signed-commits.yml
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
name: Signed commits
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
- ready_for_review
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
signed-commits:
|
||||
if: github.repository_owner == 'shadcn-ui'
|
||||
runs-on: ubuntu-latest
|
||||
name: Signed commits
|
||||
steps:
|
||||
- name: Check PR commits
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const body = "Can you sign the commits please? See https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits. Thank you."
|
||||
|
||||
const { owner, repo } = context.repo
|
||||
const pullNumber = context.payload.pull_request.number
|
||||
|
||||
const commits = await github.paginate(github.rest.pulls.listCommits, {
|
||||
owner,
|
||||
repo,
|
||||
pull_number: pullNumber,
|
||||
per_page: 100,
|
||||
})
|
||||
|
||||
const unsignedCommits = commits.filter((commit) => {
|
||||
return commit.commit.verification?.reason === "unsigned"
|
||||
})
|
||||
|
||||
const comments = await github.paginate(github.rest.issues.listComments, {
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pullNumber,
|
||||
per_page: 100,
|
||||
})
|
||||
|
||||
const existingComments = comments.filter((comment) => {
|
||||
return comment.user.type === "Bot" && comment.body.trim() === body
|
||||
})
|
||||
|
||||
if (unsignedCommits.length > 0) {
|
||||
core.info(`Found ${unsignedCommits.length} unsigned commits.`)
|
||||
|
||||
if (existingComments.length === 0) {
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pullNumber,
|
||||
body,
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
core.info("All commits are signed.")
|
||||
|
||||
for (const comment of existingComments) {
|
||||
await github.rest.issues.deleteComment({
|
||||
owner,
|
||||
repo,
|
||||
comment_id: comment.id,
|
||||
})
|
||||
}
|
||||
@@ -12,20 +12,25 @@ import { HugeiconsIcon } from "@hugeicons/react"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { useConfig } from "@/hooks/use-config"
|
||||
import { copyToClipboardWithMeta } from "@/components/copy-button"
|
||||
import { BASES, type BaseName } from "@/registry/config"
|
||||
import {
|
||||
BASES,
|
||||
buildThemeForPreset,
|
||||
DEFAULT_CONFIG,
|
||||
type BaseName,
|
||||
type DesignSystemConfig,
|
||||
} from "@/registry/config"
|
||||
import { Button } from "@/styles/base-nova/ui/button"
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/styles/base-nova/ui/dialog"
|
||||
import {
|
||||
Field,
|
||||
FieldContent,
|
||||
FieldDescription,
|
||||
FieldGroup,
|
||||
FieldLabel,
|
||||
FieldLegend,
|
||||
@@ -41,6 +46,10 @@ import {
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
} from "@/styles/base-nova/ui/tabs"
|
||||
import {
|
||||
ToggleGroup,
|
||||
ToggleGroupItem,
|
||||
} from "@/styles/base-nova/ui/toggle-group"
|
||||
import { usePresetCode } from "@/app/(app)/create/hooks/use-design-system"
|
||||
import {
|
||||
useDesignSystemSearchParams,
|
||||
@@ -61,6 +70,54 @@ const SHADCN_VERSION = process.env.NEXT_PUBLIC_RC ? "@rc" : "@latest"
|
||||
const PACKAGE_MANAGERS = ["pnpm", "npm", "yarn", "bun"] as const
|
||||
type PackageManager = (typeof PACKAGE_MANAGERS)[number]
|
||||
|
||||
const APPLY_MODES = [
|
||||
{
|
||||
value: "full",
|
||||
title: "Full preset",
|
||||
description:
|
||||
"Everything from the preset, including components, theme, and fonts.",
|
||||
flag: null,
|
||||
label: "full preset",
|
||||
},
|
||||
{
|
||||
value: "theme",
|
||||
title: "Theme only",
|
||||
description:
|
||||
"Theme tokens only, like colors, radii, and shadows. Components stay as they are.",
|
||||
flag: "--only theme",
|
||||
label: "--only theme",
|
||||
},
|
||||
{
|
||||
value: "font",
|
||||
title: "Fonts only",
|
||||
description:
|
||||
"Only preset fonts for body and headings. Components stay as they are.",
|
||||
flag: "--only font",
|
||||
label: "--only font",
|
||||
},
|
||||
] as const
|
||||
type ApplyMode = (typeof APPLY_MODES)[number]["value"]
|
||||
type ProjectFormTab = "new-project" | "existing-project" | "theme"
|
||||
type CopyTarget = "command" | "apply" | "theme"
|
||||
type ThemeCssVars = NonNullable<
|
||||
ReturnType<typeof buildThemeForPreset>["cssVars"]
|
||||
>
|
||||
|
||||
function formatCssVarsRule(selector: string, cssVars?: Record<string, string>) {
|
||||
const declarations = Object.entries(cssVars ?? {})
|
||||
.map(([key, value]) => ` --${key}: ${value};`)
|
||||
.join("\n")
|
||||
|
||||
return `${selector} {\n${declarations}\n}`
|
||||
}
|
||||
|
||||
function formatThemeCss(cssVars: ThemeCssVars) {
|
||||
return [
|
||||
formatCssVarsRule(":root", cssVars.light),
|
||||
formatCssVarsRule(".dark", cssVars.dark),
|
||||
].join("\n\n")
|
||||
}
|
||||
|
||||
export function ProjectForm({
|
||||
className,
|
||||
}: React.ComponentProps<typeof Button>) {
|
||||
@@ -68,7 +125,12 @@ export function ProjectForm({
|
||||
const [params, setParams] = useDesignSystemSearchParams()
|
||||
const presetCode = usePresetCode()
|
||||
const [config, setConfig] = useConfig()
|
||||
const [hasCopied, setHasCopied] = React.useState(false)
|
||||
const [copiedTarget, setCopiedTarget] = React.useState<CopyTarget | null>(
|
||||
null
|
||||
)
|
||||
const [applyMode, setApplyMode] = React.useState<ApplyMode>("full")
|
||||
const [activeTab, setActiveTab] =
|
||||
React.useState<ProjectFormTab>("new-project")
|
||||
|
||||
const packageManager = (config.packageManager || "pnpm") as PackageManager
|
||||
const framework = React.useMemo(
|
||||
@@ -117,12 +179,85 @@ export function ProjectForm({
|
||||
|
||||
const command = commands[packageManager]
|
||||
|
||||
const applyCommands = React.useMemo(() => {
|
||||
const presetFlag = ` --preset ${presetCode}`
|
||||
const onlyFlag =
|
||||
applyMode === "theme"
|
||||
? " --only theme"
|
||||
: applyMode === "font"
|
||||
? " --only font"
|
||||
: ""
|
||||
const flags = `${presetFlag}${onlyFlag}`
|
||||
|
||||
return IS_LOCAL_DEV
|
||||
? {
|
||||
pnpm: `shadcn apply${flags}`,
|
||||
npm: `shadcn apply${flags}`,
|
||||
yarn: `shadcn apply${flags}`,
|
||||
bun: `shadcn apply${flags}`,
|
||||
}
|
||||
: {
|
||||
pnpm: `pnpm dlx shadcn${SHADCN_VERSION} apply${flags}`,
|
||||
npm: `npx shadcn${SHADCN_VERSION} apply${flags}`,
|
||||
yarn: `yarn dlx shadcn${SHADCN_VERSION} apply${flags}`,
|
||||
bun: `bunx --bun shadcn${SHADCN_VERSION} apply${flags}`,
|
||||
}
|
||||
}, [applyMode, presetCode])
|
||||
|
||||
const applyCommand = applyCommands[packageManager]
|
||||
const themeConfig = React.useMemo<DesignSystemConfig>(() => {
|
||||
const isRadiusLocked = params.style === "lyra" || params.style === "sera"
|
||||
|
||||
return {
|
||||
...DEFAULT_CONFIG,
|
||||
base: params.base,
|
||||
style: params.style,
|
||||
baseColor: params.baseColor,
|
||||
theme: params.theme,
|
||||
chartColor: params.chartColor,
|
||||
iconLibrary: params.iconLibrary,
|
||||
font: params.font,
|
||||
fontHeading: params.fontHeading,
|
||||
menuAccent: params.menuAccent,
|
||||
menuColor: params.menuColor,
|
||||
radius: isRadiusLocked ? "none" : params.radius,
|
||||
template: params.template,
|
||||
rtl: params.rtl,
|
||||
pointer: params.pointer,
|
||||
}
|
||||
}, [
|
||||
params.base,
|
||||
params.baseColor,
|
||||
params.chartColor,
|
||||
params.font,
|
||||
params.fontHeading,
|
||||
params.iconLibrary,
|
||||
params.menuAccent,
|
||||
params.menuColor,
|
||||
params.pointer,
|
||||
params.radius,
|
||||
params.rtl,
|
||||
params.style,
|
||||
params.template,
|
||||
params.theme,
|
||||
])
|
||||
|
||||
const themeCss = React.useMemo(() => {
|
||||
const theme = buildThemeForPreset(themeConfig)
|
||||
|
||||
if (!theme.cssVars) {
|
||||
return ""
|
||||
}
|
||||
|
||||
return formatThemeCss(theme.cssVars)
|
||||
}, [themeConfig])
|
||||
|
||||
React.useEffect(() => {
|
||||
if (hasCopied) {
|
||||
const timer = setTimeout(() => setHasCopied(false), 2000)
|
||||
if (copiedTarget) {
|
||||
const timer = setTimeout(() => setCopiedTarget(null), 2000)
|
||||
return () => clearTimeout(timer)
|
||||
}
|
||||
}, [hasCopied])
|
||||
}, [copiedTarget])
|
||||
|
||||
const handleCopy = React.useCallback(() => {
|
||||
const properties: Record<string, string> = {
|
||||
@@ -135,159 +270,316 @@ export function ProjectForm({
|
||||
name: "copy_npm_command",
|
||||
properties,
|
||||
})
|
||||
setHasCopied(true)
|
||||
setCopiedTarget("command")
|
||||
}, [command, params.template])
|
||||
|
||||
const handleCopyApply = React.useCallback(() => {
|
||||
copyToClipboardWithMeta(applyCommand, {
|
||||
name: "copy_apply_command",
|
||||
properties: {
|
||||
command: applyCommand,
|
||||
applyMode,
|
||||
},
|
||||
})
|
||||
setCopiedTarget("apply")
|
||||
}, [applyCommand, applyMode])
|
||||
|
||||
const handleCopyTheme = React.useCallback(() => {
|
||||
copyToClipboardWithMeta(themeCss, {
|
||||
name: "copy_theme_code",
|
||||
properties: {
|
||||
preset: presetCode,
|
||||
baseColor: params.baseColor,
|
||||
theme: params.theme,
|
||||
format: "css",
|
||||
},
|
||||
})
|
||||
setCopiedTarget("theme")
|
||||
}, [params.baseColor, params.theme, presetCode, themeCss])
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger render={<Button className={cn(className)} />}>
|
||||
Create Project
|
||||
Get Code
|
||||
</DialogTrigger>
|
||||
<DialogContent className="dark no-scrollbar max-h-[calc(100svh-2rem)] overflow-y-auto rounded-2xl p-6 shadow-xl **:data-[slot=field-separator]:h-2 sm:max-w-sm">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Create Project</DialogTitle>
|
||||
<DialogDescription>
|
||||
Pick a template and configure your project.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div>
|
||||
<FieldGroup>
|
||||
<FieldSeparator className="-mx-6" />
|
||||
<Field className="-mt-2 gap-3">
|
||||
<FieldLabel>Template</FieldLabel>
|
||||
<TemplateGrid template={params.template} setParams={setParams} />
|
||||
</Field>
|
||||
<FieldSeparator className="-mx-6" />
|
||||
<Field className="-mt-2">
|
||||
<FieldLabel>Base</FieldLabel>
|
||||
<BaseGrid base={params.base} setParams={setParams} />
|
||||
</Field>
|
||||
<FieldSeparator className="-mx-6" />
|
||||
<FieldSet>
|
||||
<FieldLegend variant="label" className="sr-only">
|
||||
Options
|
||||
</FieldLegend>
|
||||
<Field orientation="horizontal">
|
||||
<FieldLabel htmlFor="pointer">
|
||||
<HugeiconsIcon
|
||||
icon={HandPointingRight04Icon}
|
||||
className="size-4 -rotate-90"
|
||||
/>
|
||||
Use pointer on buttons
|
||||
</FieldLabel>
|
||||
<Switch
|
||||
id="pointer"
|
||||
checked={params.pointer}
|
||||
onCheckedChange={(checked) =>
|
||||
setParams({ pointer: checked === true })
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
<FieldSeparator className="-mx-6" />
|
||||
<Field
|
||||
orientation="horizontal"
|
||||
data-disabled={hasMonorepo ? undefined : "true"}
|
||||
>
|
||||
<FieldLabel htmlFor="monorepo">
|
||||
<span
|
||||
className="size-4 text-neutral-100 [&_svg]:size-4 [&_svg]:fill-current"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: TURBOREPO_LOGO,
|
||||
}}
|
||||
/>
|
||||
Create a monorepo
|
||||
</FieldLabel>
|
||||
<Switch
|
||||
id="monorepo"
|
||||
checked={params.template?.endsWith("-monorepo") ?? false}
|
||||
disabled={!hasMonorepo}
|
||||
onCheckedChange={(checked) => {
|
||||
const framework = getFramework(params.template ?? "next")
|
||||
setParams({
|
||||
template: getTemplateValue(
|
||||
framework,
|
||||
checked === true
|
||||
) as typeof params.template,
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
<FieldSeparator className="-mx-6" />
|
||||
<Field orientation="horizontal">
|
||||
<FieldLabel htmlFor="rtl">
|
||||
<HugeiconsIcon icon={Globe02Icon} className="size-4" />
|
||||
Enable RTL support
|
||||
</FieldLabel>
|
||||
<Switch
|
||||
id="rtl"
|
||||
checked={params.rtl}
|
||||
onCheckedChange={(checked) =>
|
||||
setParams({ rtl: checked === true })
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
</FieldSet>
|
||||
</FieldGroup>
|
||||
</div>
|
||||
<DialogFooter className="-mx-6 -mb-6 min-w-0">
|
||||
<div className="flex w-full min-w-0 flex-col gap-3">
|
||||
<Tabs
|
||||
value={packageManager}
|
||||
onValueChange={(value) => {
|
||||
setConfig((prev) => ({
|
||||
...prev,
|
||||
packageManager: value as PackageManager,
|
||||
}))
|
||||
}}
|
||||
className="min-w-0 gap-0 overflow-hidden rounded-xl border-0 ring-1 ring-border"
|
||||
<DialogContent className="dark top-[64px] no-scrollbar flex max-h-[calc(100svh-2rem)] translate-y-0 flex-col rounded-2xl p-0 shadow-xl **:data-[slot=dialog-close]:top-4.5 **:data-[slot=dialog-close]:right-4 **:data-[slot=field-separator]:h-2 sm:max-w-md">
|
||||
<div className="flex min-w-0 flex-1 flex-col gap-0 overflow-hidden rounded-2xl">
|
||||
<DialogHeader className="border-b px-6 py-5">
|
||||
<ToggleGroup
|
||||
value={[activeTab]}
|
||||
onValueChange={(values) =>
|
||||
setActiveTab((values[0] as typeof activeTab) ?? "new-project")
|
||||
}
|
||||
aria-label="Project type"
|
||||
spacing={2}
|
||||
className="**:data-[slot=toggle-group-item]:data-pressed:bg-neutral-700/70"
|
||||
>
|
||||
<div className="flex items-center gap-2 py-1 pr-1.5 pl-1">
|
||||
<TabsList className="bg-transparent font-mono">
|
||||
{PACKAGE_MANAGERS.map((manager) => {
|
||||
return (
|
||||
<TabsTrigger
|
||||
key={manager}
|
||||
value={manager}
|
||||
className="py-0 leading-none data-[state=active]:shadow-none"
|
||||
<ToggleGroupItem value="new-project">New Project</ToggleGroupItem>
|
||||
<ToggleGroupItem value="existing-project">
|
||||
Existing Project
|
||||
</ToggleGroupItem>
|
||||
<ToggleGroupItem value="theme">Theme</ToggleGroupItem>
|
||||
</ToggleGroup>
|
||||
</DialogHeader>
|
||||
{activeTab === "new-project" && (
|
||||
<div className="no-scrollbar overflow-y-auto">
|
||||
<FieldGroup className="px-6 py-4">
|
||||
<Field className="gap-3">
|
||||
<FieldLabel>Template</FieldLabel>
|
||||
<TemplateGrid
|
||||
template={params.template}
|
||||
setParams={setParams}
|
||||
/>
|
||||
</Field>
|
||||
<FieldSeparator className="-mx-6" />
|
||||
<Field>
|
||||
<FieldLabel>Base</FieldLabel>
|
||||
<BaseGrid base={params.base} setParams={setParams} />
|
||||
</Field>
|
||||
<FieldSeparator className="-mx-6" />
|
||||
<FieldSet>
|
||||
<FieldLegend variant="label" className="sr-only">
|
||||
Options
|
||||
</FieldLegend>
|
||||
<Field orientation="horizontal">
|
||||
<FieldLabel htmlFor="pointer">
|
||||
<HugeiconsIcon
|
||||
icon={HandPointingRight04Icon}
|
||||
className="size-4 -rotate-90"
|
||||
/>
|
||||
Use pointer on buttons
|
||||
</FieldLabel>
|
||||
<Switch
|
||||
id="pointer"
|
||||
checked={params.pointer}
|
||||
onCheckedChange={(checked) =>
|
||||
setParams({ pointer: checked === true })
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
<FieldSeparator className="-mx-6" />
|
||||
<Field
|
||||
orientation="horizontal"
|
||||
data-disabled={hasMonorepo ? undefined : "true"}
|
||||
>
|
||||
<FieldLabel htmlFor="monorepo">
|
||||
<span
|
||||
className="size-4 text-neutral-100 [&_svg]:size-4 [&_svg]:fill-current"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: TURBOREPO_LOGO,
|
||||
}}
|
||||
/>
|
||||
Create a monorepo
|
||||
</FieldLabel>
|
||||
<Switch
|
||||
id="monorepo"
|
||||
checked={params.template?.endsWith("-monorepo") ?? false}
|
||||
disabled={!hasMonorepo}
|
||||
onCheckedChange={(checked) => {
|
||||
const framework = getFramework(
|
||||
params.template ?? "next"
|
||||
)
|
||||
setParams({
|
||||
template: getTemplateValue(
|
||||
framework,
|
||||
checked === true
|
||||
) as typeof params.template,
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
<FieldSeparator className="-mx-6" />
|
||||
<Field orientation="horizontal">
|
||||
<FieldLabel htmlFor="rtl">
|
||||
<HugeiconsIcon icon={Globe02Icon} className="size-4" />
|
||||
Enable RTL support
|
||||
</FieldLabel>
|
||||
<Switch
|
||||
id="rtl"
|
||||
checked={params.rtl}
|
||||
onCheckedChange={(checked) =>
|
||||
setParams({ rtl: checked === true })
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
</FieldSet>
|
||||
</FieldGroup>
|
||||
<DialogFooter className="m-0 min-w-0 p-6">
|
||||
<div className="flex w-full min-w-0 flex-col gap-3">
|
||||
<Tabs
|
||||
value={packageManager}
|
||||
onValueChange={(value) => {
|
||||
setConfig((prev) => ({
|
||||
...prev,
|
||||
packageManager: value as PackageManager,
|
||||
}))
|
||||
}}
|
||||
className="min-w-0 gap-0 overflow-hidden rounded-xl border-0 ring-1 ring-border"
|
||||
>
|
||||
<div className="flex items-center gap-2 py-1 pr-1.5 pl-1">
|
||||
<TabsList className="bg-transparent font-mono">
|
||||
{PACKAGE_MANAGERS.map((manager) => {
|
||||
return (
|
||||
<TabsTrigger
|
||||
key={manager}
|
||||
value={manager}
|
||||
className="py-0 leading-none data-[state=active]:shadow-none"
|
||||
>
|
||||
{manager}
|
||||
</TabsTrigger>
|
||||
)
|
||||
})}
|
||||
</TabsList>
|
||||
<Button
|
||||
size="icon-sm"
|
||||
variant="ghost"
|
||||
className="ml-auto"
|
||||
onClick={handleCopy}
|
||||
>
|
||||
{manager}
|
||||
</TabsTrigger>
|
||||
)
|
||||
})}
|
||||
</TabsList>
|
||||
<Button
|
||||
size="icon-sm"
|
||||
variant="ghost"
|
||||
className="ml-auto"
|
||||
onClick={handleCopy}
|
||||
>
|
||||
{hasCopied ? (
|
||||
<HugeiconsIcon icon={Tick02Icon} />
|
||||
) : (
|
||||
<HugeiconsIcon icon={Copy01Icon} />
|
||||
)}
|
||||
<span className="sr-only">Copy command</span>
|
||||
</Button>
|
||||
</div>
|
||||
{Object.entries(commands).map(([key, cmd]) => {
|
||||
return (
|
||||
<TabsContent key={key} value={key}>
|
||||
<div className="relative overflow-hidden border-t bg-popover p-3">
|
||||
<div className="no-scrollbar overflow-x-auto">
|
||||
<code className="font-mono text-sm whitespace-nowrap">
|
||||
{cmd}
|
||||
</code>
|
||||
</div>
|
||||
{copiedTarget === "command" ? (
|
||||
<HugeiconsIcon icon={Tick02Icon} />
|
||||
) : (
|
||||
<HugeiconsIcon icon={Copy01Icon} />
|
||||
)}
|
||||
<span className="sr-only">Copy command</span>
|
||||
</Button>
|
||||
</div>
|
||||
</TabsContent>
|
||||
)
|
||||
})}
|
||||
</Tabs>
|
||||
<Button onClick={handleCopy} className="h-9 w-full">
|
||||
{hasCopied ? "Copied" : "Copy Command"}
|
||||
</Button>
|
||||
</div>
|
||||
</DialogFooter>
|
||||
{Object.entries(commands).map(([key, cmd]) => {
|
||||
return (
|
||||
<TabsContent key={key} value={key}>
|
||||
<div className="relative overflow-hidden border-t bg-popover p-3">
|
||||
<div className="no-scrollbar overflow-x-auto">
|
||||
<code className="font-mono text-sm whitespace-nowrap">
|
||||
{cmd}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
</TabsContent>
|
||||
)
|
||||
})}
|
||||
</Tabs>
|
||||
<Button onClick={handleCopy} className="h-9 w-full">
|
||||
{copiedTarget === "command" ? "Copied" : "Copy Command"}
|
||||
</Button>
|
||||
</div>
|
||||
</DialogFooter>
|
||||
</div>
|
||||
)}
|
||||
{activeTab === "existing-project" && (
|
||||
<div className="no-scrollbar overflow-y-auto">
|
||||
<FieldGroup className="px-6 py-4">
|
||||
<FieldSet className="gap-3">
|
||||
<FieldLegend variant="label">Apply Preset</FieldLegend>
|
||||
<FieldDescription>
|
||||
Pick which parts of the preset to apply.
|
||||
</FieldDescription>
|
||||
<ApplyModeGrid mode={applyMode} setMode={setApplyMode} />
|
||||
</FieldSet>
|
||||
</FieldGroup>
|
||||
<DialogFooter className="m-0 min-w-0 p-6">
|
||||
<div className="flex w-full min-w-0 flex-col gap-3">
|
||||
<Tabs
|
||||
value={packageManager}
|
||||
onValueChange={(value) => {
|
||||
setConfig((prev) => ({
|
||||
...prev,
|
||||
packageManager: value as PackageManager,
|
||||
}))
|
||||
}}
|
||||
className="min-w-0 gap-0 overflow-hidden rounded-xl border-0 ring-1 ring-border"
|
||||
>
|
||||
<div className="flex items-center gap-2 py-1 pr-1.5 pl-1">
|
||||
<TabsList className="bg-transparent font-mono">
|
||||
{PACKAGE_MANAGERS.map((manager) => {
|
||||
return (
|
||||
<TabsTrigger
|
||||
key={manager}
|
||||
value={manager}
|
||||
className="py-0 leading-none data-[state=active]:shadow-none"
|
||||
>
|
||||
{manager}
|
||||
</TabsTrigger>
|
||||
)
|
||||
})}
|
||||
</TabsList>
|
||||
<Button
|
||||
size="icon-sm"
|
||||
variant="ghost"
|
||||
className="ml-auto"
|
||||
onClick={handleCopyApply}
|
||||
>
|
||||
{copiedTarget === "apply" ? (
|
||||
<HugeiconsIcon icon={Tick02Icon} />
|
||||
) : (
|
||||
<HugeiconsIcon icon={Copy01Icon} />
|
||||
)}
|
||||
<span className="sr-only">Copy command</span>
|
||||
</Button>
|
||||
</div>
|
||||
{Object.entries(applyCommands).map(([key, cmd]) => {
|
||||
return (
|
||||
<TabsContent key={key} value={key}>
|
||||
<div className="relative overflow-hidden border-t bg-popover p-3">
|
||||
<div className="no-scrollbar overflow-x-auto">
|
||||
<code className="font-mono text-sm whitespace-nowrap">
|
||||
{cmd}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
</TabsContent>
|
||||
)
|
||||
})}
|
||||
</Tabs>
|
||||
<Button onClick={handleCopyApply} className="h-9 w-full">
|
||||
{copiedTarget === "apply" ? "Copied" : "Copy Command"}
|
||||
</Button>
|
||||
</div>
|
||||
</DialogFooter>
|
||||
</div>
|
||||
)}
|
||||
{activeTab === "theme" && (
|
||||
<div className="no-scrollbar overflow-y-auto">
|
||||
<FieldGroup className="min-w-0 px-6 py-4">
|
||||
<FieldSet className="min-w-0 gap-3">
|
||||
<FieldLegend variant="label">Theme Tokens</FieldLegend>
|
||||
<FieldDescription>
|
||||
Copy the CSS variables for this preset.
|
||||
</FieldDescription>
|
||||
<div className="w-full min-w-0 overflow-hidden rounded-xl border-0 ring-1 ring-border">
|
||||
<div className="flex items-center gap-2 py-1 pr-1.5 pl-3">
|
||||
<div className="min-w-0 truncate font-mono text-sm text-muted-foreground">
|
||||
globals.css
|
||||
</div>
|
||||
<Button
|
||||
size="icon-sm"
|
||||
variant="ghost"
|
||||
className="ml-auto"
|
||||
onClick={handleCopyTheme}
|
||||
>
|
||||
{copiedTarget === "theme" ? (
|
||||
<HugeiconsIcon icon={Tick02Icon} />
|
||||
) : (
|
||||
<HugeiconsIcon icon={Copy01Icon} />
|
||||
)}
|
||||
<span className="sr-only">Copy theme</span>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="relative no-scrollbar max-h-[45svh] overflow-auto border-t bg-popover p-3">
|
||||
<pre className="min-w-max font-mono leading-normal whitespace-pre">
|
||||
<code>{themeCss}</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</FieldSet>
|
||||
</FieldGroup>
|
||||
<DialogFooter className="m-0 min-w-0 p-6">
|
||||
<Button onClick={handleCopyTheme} className="h-9 w-full">
|
||||
{copiedTarget === "theme" ? "Copied" : "Copy Theme"}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)
|
||||
@@ -352,6 +644,34 @@ const TemplateGrid = React.memo(function TemplateGrid({
|
||||
)
|
||||
})
|
||||
|
||||
const ApplyModeGrid = React.memo(function ApplyModeGrid({
|
||||
mode,
|
||||
setMode,
|
||||
}: {
|
||||
mode: ApplyMode
|
||||
setMode: (mode: ApplyMode) => void
|
||||
}) {
|
||||
return (
|
||||
<RadioGroup
|
||||
value={mode}
|
||||
onValueChange={(value) => setMode(value as ApplyMode)}
|
||||
aria-label="Apply"
|
||||
>
|
||||
{APPLY_MODES.map((option) => (
|
||||
<FieldLabel key={option.value} htmlFor={`apply-${option.value}`}>
|
||||
<Field orientation="horizontal">
|
||||
<RadioGroupItem value={option.value} id={`apply-${option.value}`} />
|
||||
<FieldContent>
|
||||
<FieldTitle>{option.title}</FieldTitle>
|
||||
<FieldDescription>{option.description}</FieldDescription>
|
||||
</FieldContent>
|
||||
</Field>
|
||||
</FieldLabel>
|
||||
))}
|
||||
</RadioGroup>
|
||||
)
|
||||
})
|
||||
|
||||
const BaseGrid = React.memo(function BaseGrid({
|
||||
base,
|
||||
setParams,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import * as React from "react"
|
||||
|
||||
import { PRESETS, type Style, type StyleName } from "@/registry/config"
|
||||
import { type Style, type StyleName } from "@/registry/config"
|
||||
import { LockButton } from "@/app/(app)/create/components/lock-button"
|
||||
import {
|
||||
Picker,
|
||||
@@ -53,24 +53,7 @@ export function StylePicker({
|
||||
<PickerRadioGroup
|
||||
value={currentStyle?.name}
|
||||
onValueChange={(value) => {
|
||||
const styleName = value as StyleName
|
||||
const preset = PRESETS.find(
|
||||
(p) => p.base === params.base && p.style === styleName
|
||||
)
|
||||
setParams({
|
||||
style: styleName,
|
||||
...(preset && {
|
||||
baseColor: preset.baseColor,
|
||||
theme: preset.theme,
|
||||
chartColor: preset.chartColor,
|
||||
iconLibrary: preset.iconLibrary,
|
||||
font: preset.font,
|
||||
fontHeading: preset.fontHeading,
|
||||
menuAccent: preset.menuAccent,
|
||||
menuColor: preset.menuColor,
|
||||
radius: preset.radius,
|
||||
}),
|
||||
})
|
||||
setParams({ style: value as StyleName })
|
||||
}}
|
||||
>
|
||||
<PickerGroup>
|
||||
|
||||
@@ -6,6 +6,8 @@ import { source } from "@/lib/source"
|
||||
import { getActiveStyle, type Style } from "@/registry/_legacy-styles"
|
||||
|
||||
export const revalidate = false
|
||||
export const dynamic = "force-static"
|
||||
export const dynamicParams = true
|
||||
|
||||
function getStyleFromSlug(slug: string[] | undefined, fallbackStyle: string) {
|
||||
// Detect base from URL: /docs/components/base/... or /docs/components/radix/...
|
||||
@@ -47,5 +49,5 @@ export async function GET(
|
||||
}
|
||||
|
||||
export function generateStaticParams() {
|
||||
return source.generateParams()
|
||||
return []
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { notFound } from "next/navigation"
|
||||
import { siteConfig } from "@/lib/config"
|
||||
import { absoluteUrl } from "@/lib/utils"
|
||||
import { TailwindIndicator } from "@/components/tailwind-indicator"
|
||||
import { BASES, type Base, type BaseName } from "@/registry/config"
|
||||
import { BASES, type Base } from "@/registry/config"
|
||||
import { ActionMenuScript } from "@/app/(app)/create/components/action-menu"
|
||||
import { DesignSystemProvider } from "@/app/(app)/create/components/design-system-provider"
|
||||
import { HistoryScript } from "@/app/(app)/create/components/history-buttons"
|
||||
@@ -13,15 +13,13 @@ import { DarkModeScript } from "@/app/(app)/create/components/mode-switcher"
|
||||
import { OpenPresetScript } from "@/app/(app)/create/components/open-preset"
|
||||
import { PreviewStyle } from "@/app/(app)/create/components/preview-style"
|
||||
import { RandomizeScript } from "@/app/(app)/create/components/random-button"
|
||||
import {
|
||||
getBaseComponent,
|
||||
getBaseItem,
|
||||
getItemsForBase,
|
||||
} from "@/app/(app)/create/lib/api"
|
||||
import { getBaseComponent, getBaseItem } from "@/app/(app)/create/lib/api"
|
||||
|
||||
export const revalidate = false
|
||||
export const dynamic = "force-static"
|
||||
export const dynamicParams = false
|
||||
export const dynamicParams = true
|
||||
|
||||
const STATIC_PREVIEW_ITEMS = ["preview", "preview-02"] as const
|
||||
|
||||
function PreventScrollOnFocusScript() {
|
||||
return (
|
||||
@@ -96,19 +94,12 @@ export async function generateMetadata({
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const params: Array<{ base: string; name: string }> = []
|
||||
|
||||
for (const base of BASES) {
|
||||
const items = await getItemsForBase(base.name as BaseName)
|
||||
for (const item of items) {
|
||||
params.push({
|
||||
base: base.name,
|
||||
name: item.name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return params
|
||||
return BASES.flatMap((base) =>
|
||||
STATIC_PREVIEW_ITEMS.map((name) => ({
|
||||
base: base.name,
|
||||
name,
|
||||
}))
|
||||
)
|
||||
}
|
||||
|
||||
export default async function BlockPage({
|
||||
|
||||
@@ -6,8 +6,8 @@ import { Badge } from "@/registry/new-york-v4/ui/badge"
|
||||
export function Announcement() {
|
||||
return (
|
||||
<Badge asChild variant="secondary" className="bg-muted">
|
||||
<Link href="/sera">
|
||||
Introducing Sera <ArrowRightIcon />
|
||||
<Link href="/docs/changelog">
|
||||
New preset commands <ArrowRightIcon />
|
||||
</Link>
|
||||
</Badge>
|
||||
)
|
||||
|
||||
@@ -92,13 +92,13 @@ Options:
|
||||
Use the `apply` command to apply a preset to an existing project.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest apply --preset a2r6bw
|
||||
npx shadcn@latest apply a2r6bw
|
||||
```
|
||||
|
||||
You can apply only the theme or fonts from a preset without reinstalling UI components:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest apply --preset a2r6bw --only theme
|
||||
npx shadcn@latest apply a2r6bw --only theme
|
||||
```
|
||||
|
||||
Supported values for `--only` are `theme` and `font`.
|
||||
@@ -124,6 +124,110 @@ Options:
|
||||
|
||||
---
|
||||
|
||||
## preset
|
||||
|
||||
Use the `preset` command to inspect preset codes and resolve the preset for an existing project.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset decode a2r6bw
|
||||
```
|
||||
|
||||
### preset decode
|
||||
|
||||
Use `preset decode` to decode a preset code.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset decode a2r6bw
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn preset decode [options] <code>
|
||||
|
||||
decode a preset code
|
||||
|
||||
Arguments:
|
||||
code the preset code to decode
|
||||
|
||||
Options:
|
||||
--json output as JSON. (default: false)
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
### preset resolve
|
||||
|
||||
Use `preset resolve` to resolve the preset from the current project.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset resolve
|
||||
```
|
||||
|
||||
The `preset info` command is an alias for `preset resolve`:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset info
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn preset resolve|info [options]
|
||||
|
||||
resolve a preset from your project
|
||||
|
||||
Options:
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory.
|
||||
--json output as JSON. (default: false)
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
### preset url
|
||||
|
||||
Use `preset url` to print the create URL for a preset code.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset url a2r6bw
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn preset url [options] <code>
|
||||
|
||||
get the create URL for a preset code
|
||||
|
||||
Arguments:
|
||||
code the preset code
|
||||
|
||||
Options:
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
### preset open
|
||||
|
||||
Use `preset open` to open a preset code in the browser.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset open a2r6bw
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn preset open [options] <code>
|
||||
|
||||
open a preset code in the browser
|
||||
|
||||
Arguments:
|
||||
code the preset code
|
||||
|
||||
Options:
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## view
|
||||
|
||||
Use the `view` command to view items from the registry before installing them.
|
||||
|
||||
@@ -140,15 +140,91 @@ Setting this option to `false` allows components to be added as JavaScript with
|
||||
|
||||
## aliases
|
||||
|
||||
The CLI uses these values and the `paths` config from your `tsconfig.json` or `jsconfig.json` file to place generated components in the correct location.
|
||||
The CLI uses these values to place generated components in the correct location and rewrite imports.
|
||||
|
||||
Path aliases have to be set up in your `tsconfig.json` or `jsconfig.json` file.
|
||||
You can back these aliases with either:
|
||||
|
||||
1. `compilerOptions.paths` in your `tsconfig.json` or `jsconfig.json`
|
||||
2. `package.json#imports` with TypeScript package import resolution enabled
|
||||
|
||||
The aliases in `components.json` are still required when using the CLI. They tell the CLI which import roots map to `components`, `ui`, `lib`, `hooks`, and `utils`.
|
||||
|
||||
<Callout className="mt-6">
|
||||
**Important:** If you're using the `src` directory, make sure it is included
|
||||
under `paths` in your `tsconfig.json` or `jsconfig.json` file.
|
||||
**Important:** If you're using package imports, enable
|
||||
`resolvePackageJsonImports` and use `moduleResolution: "bundler"` in your
|
||||
`tsconfig.json`. If you're using `paths`, make sure your aliases include the
|
||||
`src` directory when applicable.
|
||||
</Callout>
|
||||
|
||||
### Using `tsconfig` or `jsconfig` paths
|
||||
|
||||
```json title="tsconfig.json"
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Using `package.json#imports`
|
||||
|
||||
Recommended setup for a single-package app:
|
||||
|
||||
```json title="package.json"
|
||||
{
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json title="tsconfig.json"
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "bundler",
|
||||
"resolvePackageJsonImports": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"ui": "#components/ui",
|
||||
"lib": "#lib",
|
||||
"hooks": "#hooks",
|
||||
"utils": "#lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The aliases in `components.json` still tell the CLI where to place
|
||||
`components`, `ui`, `lib`, `hooks`, and `utils`. `package.json#imports`
|
||||
provides the runtime and TypeScript resolution for those `#...` specifiers.
|
||||
|
||||
The matched `imports` target also controls whether generated `#...` imports keep
|
||||
file extensions:
|
||||
|
||||
- `"#components/*": "./src/components/*"` preserves source extensions and can
|
||||
generate imports like
|
||||
`#components/button.tsx`
|
||||
- `"#components/*": "./src/components/*.tsx"` strips source extensions and
|
||||
generates imports like
|
||||
`#components/button`
|
||||
|
||||
For monorepos, see the <Link href="/docs/monorepo">monorepo docs</Link>. Local
|
||||
workspace aliases can use `package.json#imports`, while shared workspace
|
||||
imports such as `@workspace/ui/components` are resolved from the target
|
||||
package's `exports`.
|
||||
|
||||
For framework-specific setup, see the [package imports guide](/docs/package-imports).
|
||||
|
||||
### aliases.utils
|
||||
|
||||
Import alias for your utility functions.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"index",
|
||||
"[Installation](/docs/installation)",
|
||||
"components-json",
|
||||
"package-imports",
|
||||
"theming",
|
||||
"[Dark Mode](/docs/dark-mode)",
|
||||
"[RTL](/docs/rtl)",
|
||||
|
||||
@@ -164,3 +164,91 @@ turbo.json
|
||||
4. **For Tailwind CSS v4, leave the `tailwind` config empty in the `components.json` file.**
|
||||
|
||||
By following these requirements, the CLI will be able to install ui components, blocks, libs and hooks to the correct paths and handle imports for you.
|
||||
|
||||
<Callout className="mt-6">
|
||||
`package.json#imports` works well for package-local aliases inside a
|
||||
workspace, for example inside `packages/ui`. For shared workspace imports such
|
||||
as `@workspace/ui/components`, keep explicit aliases in `components.json`. The
|
||||
CLI uses those aliases to route files across workspace boundaries.
|
||||
</Callout>
|
||||
|
||||
## Using `package.json#imports`
|
||||
|
||||
For a monorepo that uses package imports and does not rely on
|
||||
`tsconfig.json` `paths`, use:
|
||||
|
||||
- local `#...` aliases for files inside each workspace
|
||||
- workspace package `exports` for shared imports such as
|
||||
`@workspace/ui/components`
|
||||
|
||||
For example, an app workspace can use local package imports:
|
||||
|
||||
```json showLineNumbers title="apps/web/package.json"
|
||||
{
|
||||
"name": "web",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@workspace/ui": "workspace:*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json showLineNumbers title="apps/web/components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"ui": "@workspace/ui/components",
|
||||
"lib": "#lib",
|
||||
"hooks": "#hooks",
|
||||
"utils": "@workspace/ui/lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And the shared UI package can expose its install targets with `exports`:
|
||||
|
||||
```json showLineNumbers title="packages/ui/package.json"
|
||||
{
|
||||
"name": "@workspace/ui",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
},
|
||||
"exports": {
|
||||
"./globals.css": "./src/styles/globals.css",
|
||||
"./components/*": "./src/components/*.tsx",
|
||||
"./lib/*": "./src/lib/*.ts",
|
||||
"./hooks/*": "./src/hooks/*.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json showLineNumbers title="packages/ui/components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"ui": "#components",
|
||||
"lib": "#lib",
|
||||
"hooks": "#hooks",
|
||||
"utils": "#lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In this setup:
|
||||
|
||||
- files added from the app to the shared UI package are routed through
|
||||
`@workspace/ui/...`
|
||||
- files added inside `packages/ui` use the package-local `#...` aliases
|
||||
- the shared package must export any path referenced by another workspace
|
||||
|
||||
For framework-specific package import setup, see the [package imports guide](/docs/package-imports).
|
||||
|
||||
234
apps/v4/content/docs/(root)/package-imports.mdx
Normal file
234
apps/v4/content/docs/(root)/package-imports.mdx
Normal file
@@ -0,0 +1,234 @@
|
||||
---
|
||||
title: Package Imports
|
||||
description: Configure shadcn/ui with package.json imports.
|
||||
---
|
||||
|
||||
The `shadcn` CLI supports [package imports](https://nodejs.org/api/packages.html#imports)
|
||||
for installing components, rewriting imports, and resolving third-party
|
||||
registries.
|
||||
|
||||
Package imports let you use private `#...` import aliases from your
|
||||
`package.json` instead of `compilerOptions.paths` in `tsconfig.json`.
|
||||
|
||||
## Example
|
||||
|
||||
You configure `imports` in your `package.json`:
|
||||
|
||||
```json title="package.json" showLineNumbers
|
||||
{
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then import generated components using `#...` specifiers:
|
||||
|
||||
```tsx
|
||||
import { Button } from "#components/ui/button"
|
||||
import { cn } from "#lib/utils"
|
||||
```
|
||||
|
||||
<Callout className="mt-6">
|
||||
Package import specifiers must start with `#`. Use TypeScript 5 or later with
|
||||
`moduleResolution: "bundler"` and `resolvePackageJsonImports: true`.
|
||||
</Callout>
|
||||
|
||||
## App
|
||||
|
||||
For Next.js, Vite, and TanStack Start apps that install
|
||||
components into the same workspace.
|
||||
|
||||
<Steps>
|
||||
|
||||
### Configure `package.json`
|
||||
|
||||
Add imports for the shadcn/ui install targets.
|
||||
|
||||
```json title="package.json" showLineNumbers
|
||||
{
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If your app does not use a `src` directory, remove `src/` from the targets. For
|
||||
example:
|
||||
|
||||
```json title="package.json" showLineNumbers
|
||||
{
|
||||
"imports": {
|
||||
"#components/*": "./components/*.tsx",
|
||||
"#lib/*": "./lib/*.ts",
|
||||
"#hooks/*": "./hooks/*.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Configure TypeScript
|
||||
|
||||
Enable package import resolution.
|
||||
|
||||
```json title="tsconfig.json" showLineNumbers
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "bundler",
|
||||
"resolvePackageJsonImports": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You do not need `compilerOptions.paths` for these aliases.
|
||||
|
||||
### Configure `components.json`
|
||||
|
||||
Use the same `#...` roots in `components.json`.
|
||||
|
||||
```json title="components.json" showLineNumbers
|
||||
{
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"ui": "#components/ui",
|
||||
"lib": "#lib",
|
||||
"hooks": "#hooks",
|
||||
"utils": "#lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `ui` alias uses `#components/ui`. It is still covered by the
|
||||
`#components/*` import in `package.json`.
|
||||
|
||||
The `utils` alias uses `#lib/utils`. It is covered by `#lib/*`, so you do not
|
||||
need a separate `#utils` import.
|
||||
|
||||
</Steps>
|
||||
|
||||
## Monorepo
|
||||
|
||||
In a monorepo, use package imports for files inside each package and package
|
||||
exports for files shared across workspaces.
|
||||
|
||||
For an app workspace:
|
||||
|
||||
```json title="apps/web/package.json" showLineNumbers
|
||||
{
|
||||
"name": "web",
|
||||
"private": true,
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@workspace/ui": "workspace:*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json title="apps/web/components.json" showLineNumbers
|
||||
{
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"ui": "@workspace/ui/components",
|
||||
"lib": "#lib",
|
||||
"hooks": "#hooks",
|
||||
"utils": "@workspace/ui/lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For the shared UI package:
|
||||
|
||||
```json title="packages/ui/package.json" showLineNumbers
|
||||
{
|
||||
"name": "@workspace/ui",
|
||||
"private": true,
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
},
|
||||
"exports": {
|
||||
"./globals.css": "./src/styles/globals.css",
|
||||
"./components/*": "./src/components/*.tsx",
|
||||
"./lib/*": "./src/lib/*.ts",
|
||||
"./hooks/*": "./src/hooks/*.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json title="packages/ui/components.json" showLineNumbers
|
||||
{
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"ui": "#components",
|
||||
"lib": "#lib",
|
||||
"hooks": "#hooks",
|
||||
"utils": "#lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When you run `add` from `apps/web`, app-local files use `#...` imports and
|
||||
shared UI files are imported from `@workspace/ui`.
|
||||
|
||||
```tsx
|
||||
import { Button } from "@workspace/ui/components/button"
|
||||
import { LoginForm } from "#components/login-form"
|
||||
```
|
||||
|
||||
## File extensions
|
||||
|
||||
The target pattern in `package.json#imports` controls whether generated imports
|
||||
include file extensions.
|
||||
|
||||
```json title="package.json" showLineNumbers
|
||||
{
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This generates imports without extensions:
|
||||
|
||||
```tsx
|
||||
import { Button } from "#components/ui/button"
|
||||
```
|
||||
|
||||
If you use a target without the extension:
|
||||
|
||||
```json title="package.json" showLineNumbers
|
||||
{
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The generated import keeps the source extension:
|
||||
|
||||
```tsx
|
||||
import { Button } from "#components/ui/button.tsx"
|
||||
```
|
||||
|
||||
For most apps, use the extension in the target pattern.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If TypeScript cannot resolve a `#...` import, check that:
|
||||
|
||||
- the specifier starts with `#`
|
||||
- the `imports` entry is in the nearest `package.json`
|
||||
- `moduleResolution` is set to `bundler`
|
||||
- `resolvePackageJsonImports` is enabled
|
||||
- the matching target exists after components are added
|
||||
|
||||
If a component is installed but imports still point to `@/...`, check that
|
||||
`components.json` uses the same `#...` aliases as your package imports.
|
||||
@@ -116,7 +116,7 @@ npx shadcn@latest docs combobox
|
||||
|
||||
combobox
|
||||
- docs https://ui.shadcn.com/docs/components/radix/combobox
|
||||
- examples https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/combobox-example.tsx
|
||||
- examples https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/combobox-example.tsx
|
||||
- api https://base-ui.com/react/components/combobox
|
||||
```
|
||||
|
||||
|
||||
93
apps/v4/content/docs/changelog/2026-04-preset-commands.mdx
Normal file
93
apps/v4/content/docs/changelog/2026-04-preset-commands.mdx
Normal file
@@ -0,0 +1,93 @@
|
||||
---
|
||||
title: April 2026 - shadcn preset
|
||||
description: Decode, share, open, and resolve preset codes from the shadcn CLI.
|
||||
date: 2026-04-28
|
||||
---
|
||||
|
||||
We added `shadcn preset` commands for working with preset codes.
|
||||
|
||||
## Decode a preset
|
||||
|
||||
You can decode a preset code to see exactly what it contains:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset decode b5owWMfJ8l
|
||||
```
|
||||
|
||||
```txt
|
||||
Preset
|
||||
code b5owWMfJ8l
|
||||
version b
|
||||
style mira
|
||||
baseColor mauve
|
||||
theme mauve
|
||||
chartColor amber
|
||||
iconLibrary hugeicons
|
||||
font inter
|
||||
fontHeading oxanium
|
||||
radius large
|
||||
menuAccent subtle
|
||||
menuColor inverted-translucent
|
||||
url https://ui.shadcn.com/create?preset=b5owWMfJ8l
|
||||
```
|
||||
|
||||
## Resolve from a project
|
||||
|
||||
Use `preset resolve` in an existing project to see the preset that matches your current configuration.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset resolve
|
||||
```
|
||||
|
||||
```txt
|
||||
Preset
|
||||
code b5Kc6P0Vc
|
||||
version b
|
||||
style luma
|
||||
baseColor olive
|
||||
theme lime
|
||||
chartColor sky
|
||||
iconLibrary hugeicons
|
||||
font geist
|
||||
fontHeading inherit
|
||||
radius default
|
||||
menuAccent subtle
|
||||
menuColor default
|
||||
url https://ui.shadcn.com/create?preset=b5Kc6P0Vc
|
||||
```
|
||||
|
||||
It works with monorepos too:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset resolve -c apps/web
|
||||
```
|
||||
|
||||
## Share or open
|
||||
|
||||
Use `preset url` when you need a shareable link:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset url b5owWMfJ8l
|
||||
```
|
||||
|
||||
```txt
|
||||
https://ui.shadcn.com/create?preset=b5owWMfJ8l
|
||||
```
|
||||
|
||||
Use `preset open` to open the preset on shadcn/create for customization:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset open b5owWMfJ8l
|
||||
```
|
||||
|
||||
```txt
|
||||
Opening https://ui.shadcn.com/create?preset=b5owWMfJ8l in your browser.
|
||||
```
|
||||
|
||||
This makes presets easier to inspect, share, and hand off to coding agents without manually decoding codes or building URLs.
|
||||
|
||||
<Button asChild size="sm">
|
||||
<Link href="/create" className="mt-6 no-underline!">
|
||||
Try a Preset
|
||||
</Link>
|
||||
</Button>
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
title: May 2026 - Package Imports and Target Aliases
|
||||
description: Configure shadcn/ui with package.json imports and portable registry target aliases.
|
||||
date: 2026-05-05
|
||||
---
|
||||
|
||||
We've added support for package imports and aliases in `files.target` in `shadcn@4.7.0`.
|
||||
|
||||
## Package imports
|
||||
|
||||
The `shadcn` CLI now supports `package.json#imports` for installing components,
|
||||
rewriting imports, and resolving third-party registries. You can use private
|
||||
`#...` import aliases from your `package.json` instead of relying only on
|
||||
`compilerOptions.paths` in `tsconfig.json`.
|
||||
|
||||
```json title="package.json" showLineNumbers
|
||||
{
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then use the same roots in `components.json`:
|
||||
|
||||
```json title="components.json" showLineNumbers
|
||||
{
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"ui": "#components/ui",
|
||||
"lib": "#lib",
|
||||
"hooks": "#hooks",
|
||||
"utils": "#lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This also works in monorepos where app-local files use package imports and
|
||||
shared UI files are imported from workspace package exports.
|
||||
|
||||
See the [package imports guide](/docs/package-imports) for setup details.
|
||||
|
||||
## Target aliases
|
||||
|
||||
Registry items can now use target aliases in `files[].target` to install files
|
||||
under the user's configured shadcn directories. For example, the following registry item will install the `prompt-input.tsx` file under the `ui/ai` directory.
|
||||
|
||||
```json title="example.json" showLineNumbers
|
||||
{
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/default/ai/prompt-input.tsx",
|
||||
"type": "registry:ui",
|
||||
"target": "@ui/ai/prompt-input.tsx"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
See the [registry examples](/docs/registry/examples#target-placeholders) for
|
||||
more details.
|
||||
@@ -156,7 +156,7 @@ The `Field` family is designed for composing accessible forms. A typical field i
|
||||
|
||||
## Form
|
||||
|
||||
See the [Form](/docs/forms) documentation for building forms with the `Field` component and [React Hook Form](/docs/forms/react-hook-form) or [Tanstack Form](/docs/forms/tanstack-form).
|
||||
See the [Form](/docs/forms) documentation for building forms with the `Field` component and [React Hook Form](/docs/forms/react-hook-form), [Tanstack Form](/docs/forms/tanstack-form), or [Formisch](/docs/forms/formisch).
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
@@ -129,3 +129,9 @@ To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl)
|
||||
## API Reference
|
||||
|
||||
See the [Base UI Toggle Group](https://base-ui.com/react/components/toggle-group#api-reference) documentation.
|
||||
|
||||
## Changelog
|
||||
|
||||
### 2026-05-17 Default Spacing
|
||||
|
||||
Changed the default `spacing` from `0` to `2` so toggle groups render with space between items by default. Use `spacing={0}` for connected items.
|
||||
|
||||
@@ -156,7 +156,7 @@ The `Field` family is designed for composing accessible forms. A typical field i
|
||||
|
||||
## Form
|
||||
|
||||
See the [Form](/docs/forms) documentation for building forms with the `Field` component and [React Hook Form](/docs/forms/react-hook-form) or [Tanstack Form](/docs/forms/tanstack-form).
|
||||
See the [Form](/docs/forms) documentation for building forms with the `Field` component and [React Hook Form](/docs/forms/react-hook-form), [Tanstack Form](/docs/forms/tanstack-form), or [Formisch](/docs/forms/formisch).
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
@@ -129,3 +129,9 @@ To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl)
|
||||
## API Reference
|
||||
|
||||
See the [Radix Toggle Group](https://www.radix-ui.com/docs/primitives/components/toggle-group#api-reference) documentation.
|
||||
|
||||
## Changelog
|
||||
|
||||
### 2026-05-17 Default Spacing
|
||||
|
||||
Changed the default `spacing` from `0` to `2` so toggle groups render with space between items by default. Use `spacing={0}` for connected items.
|
||||
|
||||
669
apps/v4/content/docs/forms/formisch.mdx
Normal file
669
apps/v4/content/docs/forms/formisch.mdx
Normal file
@@ -0,0 +1,669 @@
|
||||
---
|
||||
title: Formisch
|
||||
description: Build forms in React using Formisch and Valibot.
|
||||
links:
|
||||
doc: https://formisch.dev
|
||||
---
|
||||
|
||||
import { InfoIcon } from "lucide-react"
|
||||
|
||||
This guide covers building forms with [Formisch](https://formisch.dev), the lightweight, schema-first, and fully type-safe form library for React. We'll create forms with the `<Field />` component, validate them with Valibot schemas, handle errors, and ensure accessibility.
|
||||
|
||||
## Demo
|
||||
|
||||
We'll build the following form. It has a simple text input and a textarea. On submit, we'll validate the form data and display any errors.
|
||||
|
||||
<Callout icon={<InfoIcon />}>
|
||||
**Note:** For the purpose of this demo, we have intentionally disabled browser
|
||||
validation to show how schema validation and form errors work in Formisch. It
|
||||
is recommended to add basic browser validation in your production code.
|
||||
</Callout>
|
||||
|
||||
<ComponentPreview
|
||||
name="form-formisch-demo"
|
||||
className="sm:[&_.preview]:h-[700px]"
|
||||
chromeLessOnMobile
|
||||
/>
|
||||
|
||||
## Approach
|
||||
|
||||
This form leverages Formisch for headless, schema-first form handling. We'll build our form using the `<Field />` component, which gives you **complete flexibility over the markup and styling**.
|
||||
|
||||
- Uses Formisch's `useForm` hook for form state management.
|
||||
- `<Form />` component to wrap the native `<form>` element with submit handling.
|
||||
- `<Field />` render-prop component for controlled inputs.
|
||||
- Schema validation using [Valibot](https://valibot.dev).
|
||||
- Type-safe field paths inferred from the schema.
|
||||
|
||||
## Form Methods
|
||||
|
||||
Formisch exposes form operations as **top-level functions** rather than methods on a form object. Import only what you need:
|
||||
|
||||
```ts
|
||||
import { getInput, insert, reset, submit } from "@formisch/react"
|
||||
```
|
||||
|
||||
Every method follows the same signature: the **first parameter is always the form store**, and the **second parameter (if necessary) is always a config object**.
|
||||
|
||||
```ts
|
||||
// Read a field value
|
||||
const email = getInput(form, { path: ["email"] })
|
||||
|
||||
// Reset the form with new initial values
|
||||
reset(form, { initialInput: { email: "", password: "" } })
|
||||
|
||||
// Move an item in a field array
|
||||
move(form, { path: ["items"], from: 0, to: 3 })
|
||||
```
|
||||
|
||||
This design keeps the API flexible and consistent across all methods. You'll see the same `(form, config)` shape used throughout this guide for reading state (`getInput`, `getErrors`), writing state (`setInput`, `setErrors`), form control (`submit`, `validate`, `focus`), and array operations (`insert`, `remove`, `move`, `swap`, `replace`). See the [full methods reference](https://formisch.dev/react/guides/form-methods) for details.
|
||||
|
||||
## Anatomy
|
||||
|
||||
Here's a basic example of a form using the `<Field />` component from Formisch and the shadcn `<Field />` component.
|
||||
|
||||
```tsx showLineNumbers {3-21}
|
||||
<Form of={form} onSubmit={handleSubmit}>
|
||||
<FieldGroup>
|
||||
<FormischField of={form} path={["title"]}>
|
||||
{(field) => (
|
||||
<Field data-invalid={field.errors !== null}>
|
||||
<FieldLabel htmlFor="form-title">Bug Title</FieldLabel>
|
||||
<Input
|
||||
{...field.props}
|
||||
id="form-title"
|
||||
value={field.input}
|
||||
aria-invalid={field.errors !== null}
|
||||
placeholder="Login button not working on mobile"
|
||||
autoComplete="off"
|
||||
/>
|
||||
<FieldDescription>
|
||||
Provide a concise title for your bug report.
|
||||
</FieldDescription>
|
||||
{field.errors && (
|
||||
<FieldError errors={field.errors.map((message) => ({ message }))} />
|
||||
)}
|
||||
</Field>
|
||||
)}
|
||||
</FormischField>
|
||||
</FieldGroup>
|
||||
</Form>
|
||||
```
|
||||
|
||||
<Callout icon={<InfoIcon />}>
|
||||
**Note:** Formisch ships its own `Field` component. To avoid a name clash with
|
||||
the shadcn `Field`, the examples below import the Formisch one as
|
||||
`FormischField` and keep the shadcn `Field` under its original name. In your
|
||||
own code you can alias either side — just be consistent.
|
||||
</Callout>
|
||||
|
||||
## Form
|
||||
|
||||
### Create a form schema
|
||||
|
||||
We'll start by defining the shape of our form using a Valibot schema. Formisch infers all input and output types directly from this schema.
|
||||
|
||||
```tsx showLineNumbers title="form.tsx"
|
||||
import * as v from "valibot"
|
||||
|
||||
const FormSchema = v.object({
|
||||
title: v.pipe(
|
||||
v.string(),
|
||||
v.minLength(5, "Bug title must be at least 5 characters."),
|
||||
v.maxLength(32, "Bug title must be at most 32 characters.")
|
||||
),
|
||||
description: v.pipe(
|
||||
v.string(),
|
||||
v.minLength(20, "Description must be at least 20 characters."),
|
||||
v.maxLength(100, "Description must be at most 100 characters.")
|
||||
),
|
||||
})
|
||||
```
|
||||
|
||||
### Set up the form
|
||||
|
||||
Next, we'll use the `useForm` hook from Formisch to create our form instance. The schema is passed directly to `useForm` — there is no resolver step.
|
||||
|
||||
```tsx showLineNumbers title="form.tsx" {1-2,21-25}
|
||||
import { Form, Field as FormischField, useForm } from "@formisch/react"
|
||||
import type { SubmitHandler } from "@formisch/react"
|
||||
import * as v from "valibot"
|
||||
|
||||
const FormSchema = v.object({
|
||||
title: v.pipe(
|
||||
v.string(),
|
||||
v.minLength(5, "Bug title must be at least 5 characters."),
|
||||
v.maxLength(32, "Bug title must be at most 32 characters.")
|
||||
),
|
||||
description: v.pipe(
|
||||
v.string(),
|
||||
v.minLength(20, "Description must be at least 20 characters."),
|
||||
v.maxLength(100, "Description must be at most 100 characters.")
|
||||
),
|
||||
})
|
||||
|
||||
export function BugReportForm() {
|
||||
const form = useForm({
|
||||
schema: FormSchema,
|
||||
initialInput: {
|
||||
title: "",
|
||||
description: "",
|
||||
},
|
||||
})
|
||||
|
||||
const handleSubmit: SubmitHandler<typeof FormSchema> = (output) => {
|
||||
// Do something with the validated form values.
|
||||
console.log(output)
|
||||
}
|
||||
|
||||
return (
|
||||
<Form of={form} onSubmit={handleSubmit}>
|
||||
{/* ... */}
|
||||
{/* Build the form here */}
|
||||
{/* ... */}
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
The `<Form />` component wraps a native `<form>` element. It calls `event.preventDefault()`, runs validation, and only invokes `onSubmit` when the data is valid. The `output` you receive is fully typed from the schema.
|
||||
|
||||
### Build the form
|
||||
|
||||
We can now build the form using the `<Field />` component from Formisch and the shadcn `<Field />` component.
|
||||
|
||||
<ComponentSource
|
||||
src="/registry/new-york-v4/examples/form-formisch-demo.tsx"
|
||||
title="form.tsx"
|
||||
/>
|
||||
|
||||
### Done
|
||||
|
||||
That's it. You now have a fully accessible form with client-side validation.
|
||||
|
||||
When you submit the form, the `handleSubmit` function will be called with the validated form data. If the form data is invalid, Formisch will populate `field.errors` for each invalid field and the UI will display them.
|
||||
|
||||
## Validation
|
||||
|
||||
### Client-side Validation
|
||||
|
||||
Formisch validates your form data using the Valibot schema you pass to `useForm`. There is no resolver — the schema is the single source of truth for both runtime validation and static types.
|
||||
|
||||
```tsx showLineNumbers title="form.tsx" {1,3-6,11}
|
||||
import { useForm } from "@formisch/react"
|
||||
|
||||
const FormSchema = v.object({
|
||||
title: v.string(),
|
||||
description: v.optional(v.string()),
|
||||
})
|
||||
|
||||
export function ExampleForm() {
|
||||
const form = useForm({
|
||||
schema: FormSchema,
|
||||
initialInput: {
|
||||
title: "",
|
||||
description: "",
|
||||
},
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### Validation Modes
|
||||
|
||||
Formisch separates the **first** validation from **subsequent** validations. You configure them with the `validate` and `revalidate` options on `useForm`.
|
||||
|
||||
```tsx showLineNumbers title="form.tsx" {3-4}
|
||||
const form = useForm({
|
||||
schema: FormSchema,
|
||||
validate: "blur",
|
||||
revalidate: "input",
|
||||
})
|
||||
```
|
||||
|
||||
| Option | Value | Description |
|
||||
| ------------ | ----------- | --------------------------------------------------------------- |
|
||||
| `validate` | `"submit"` | Validate on form submission (default). |
|
||||
| `validate` | `"blur"` | Validate when a field loses focus. |
|
||||
| `validate` | `"input"` | Validate on every input change. |
|
||||
| `validate` | `"initial"` | Validate immediately on form creation. |
|
||||
| `revalidate` | `"input"` | Revalidate on every input change after the first run (default). |
|
||||
| `revalidate` | `"blur"` | Revalidate on blur after the first run. |
|
||||
| `revalidate` | `"submit"` | Revalidate only on form submission. |
|
||||
|
||||
## Displaying Errors
|
||||
|
||||
Display errors next to the field using `<FieldError />`. Formisch returns errors as an array of strings, so map them to the shape `<FieldError />` expects. For styling and accessibility:
|
||||
|
||||
- Add the `data-invalid` prop to the `<Field />` component.
|
||||
- Add the `aria-invalid` prop to the form control such as `<Input />`, `<SelectTrigger />`, `<Checkbox />`, etc.
|
||||
|
||||
```tsx showLineNumbers title="form.tsx" {3,10,12-14}
|
||||
<FormischField of={form} path={["email"]}>
|
||||
{(field) => (
|
||||
<Field data-invalid={field.errors !== null}>
|
||||
<FieldLabel htmlFor="form-email">Email</FieldLabel>
|
||||
<Input
|
||||
{...field.props}
|
||||
id="form-email"
|
||||
value={field.input}
|
||||
type="email"
|
||||
aria-invalid={field.errors !== null}
|
||||
/>
|
||||
{field.errors && (
|
||||
<FieldError errors={field.errors.map((message) => ({ message }))} />
|
||||
)}
|
||||
</Field>
|
||||
)}
|
||||
</FormischField>
|
||||
```
|
||||
|
||||
## Working with Different Field Types
|
||||
|
||||
Formisch exposes two ways to bind a field to an element:
|
||||
|
||||
- **Native HTML elements** (like `<Input />` and `<Textarea />`) — spread `field.props` and provide `value={field.input}`. Formisch wires up `name`, `ref`, `onChange`, `onBlur`, and `onFocus` for you.
|
||||
- **Component-library inputs** (like Radix-based `<Select />`, `<Checkbox />`, `<RadioGroup />`, `<Switch />`) — read the value from `field.input` and call `field.onChange(value)` to update it.
|
||||
|
||||
### Input
|
||||
|
||||
- For input fields, spread `field.props` and provide `value={field.input}`.
|
||||
- To show errors, add the `aria-invalid` prop to the `<Input />` component and the `data-invalid` prop to the `<Field />` component.
|
||||
|
||||
<ComponentPreview
|
||||
name="form-formisch-input"
|
||||
className="sm:[&_.preview]:h-[700px]"
|
||||
chromeLessOnMobile
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers title="form.tsx" {5-8}
|
||||
<FormischField of={form} path={["username"]}>
|
||||
{(field) => (
|
||||
<Field data-invalid={field.errors !== null}>
|
||||
<FieldLabel htmlFor="form-username">Username</FieldLabel>
|
||||
<Input
|
||||
{...field.props}
|
||||
id="form-username"
|
||||
value={field.input}
|
||||
aria-invalid={field.errors !== null}
|
||||
/>
|
||||
{field.errors && (
|
||||
<FieldError errors={field.errors.map((message) => ({ message }))} />
|
||||
)}
|
||||
</Field>
|
||||
)}
|
||||
</FormischField>
|
||||
```
|
||||
|
||||
### Textarea
|
||||
|
||||
- For textarea fields, spread `field.props` and provide `value={field.input}`.
|
||||
- To show errors, add the `aria-invalid` prop to the `<Textarea />` component and the `data-invalid` prop to the `<Field />` component.
|
||||
|
||||
<ComponentPreview
|
||||
name="form-formisch-textarea"
|
||||
className="sm:[&_.preview]:h-[700px]"
|
||||
chromeLessOnMobile
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers title="form.tsx" {7-10}
|
||||
<FormischField of={form} path={["about"]}>
|
||||
{(field) => (
|
||||
<Field data-invalid={field.errors !== null}>
|
||||
<FieldLabel htmlFor="form-about">More about you</FieldLabel>
|
||||
<Textarea
|
||||
{...field.props}
|
||||
id="form-about"
|
||||
value={field.input}
|
||||
aria-invalid={field.errors !== null}
|
||||
placeholder="I'm a software engineer..."
|
||||
className="min-h-[120px]"
|
||||
/>
|
||||
<FieldDescription>
|
||||
Tell us more about yourself. This will be used to help us personalize
|
||||
your experience.
|
||||
</FieldDescription>
|
||||
{field.errors && (
|
||||
<FieldError errors={field.errors.map((message) => ({ message }))} />
|
||||
)}
|
||||
</Field>
|
||||
)}
|
||||
</FormischField>
|
||||
```
|
||||
|
||||
### Select
|
||||
|
||||
- For select components, read `field.input` and call `field.onChange` from `<Select />`'s `onValueChange`.
|
||||
- To show errors, add the `aria-invalid` prop to the `<SelectTrigger />` component and the `data-invalid` prop to the `<Field />` component.
|
||||
|
||||
<ComponentPreview
|
||||
name="form-formisch-select"
|
||||
className="sm:[&_.preview]:h-[500px]"
|
||||
chromeLessOnMobile
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers title="form.tsx" {15-19}
|
||||
<FormischField of={form} path={["language"]}>
|
||||
{(field) => (
|
||||
<Field orientation="responsive" data-invalid={field.errors !== null}>
|
||||
<FieldContent>
|
||||
<FieldLabel htmlFor="form-language">Spoken Language</FieldLabel>
|
||||
<FieldDescription>
|
||||
For best results, select the language you speak.
|
||||
</FieldDescription>
|
||||
{field.errors && (
|
||||
<FieldError errors={field.errors.map((message) => ({ message }))} />
|
||||
)}
|
||||
</FieldContent>
|
||||
<Select value={field.input} onValueChange={field.onChange}>
|
||||
<SelectTrigger
|
||||
id="form-language"
|
||||
aria-invalid={field.errors !== null}
|
||||
className="min-w-[120px]"
|
||||
>
|
||||
<SelectValue placeholder="Select" />
|
||||
</SelectTrigger>
|
||||
<SelectContent position="item-aligned">
|
||||
<SelectItem value="auto">Auto</SelectItem>
|
||||
<SelectItem value="en">English</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</Field>
|
||||
)}
|
||||
</FormischField>
|
||||
```
|
||||
|
||||
### Checkbox
|
||||
|
||||
- For checkbox arrays, read `field.input` and update it from `onCheckedChange` using `field.onChange`.
|
||||
- To show errors, add the `aria-invalid` prop to the `<Checkbox />` component and the `data-invalid` prop to the `<Field />` component.
|
||||
- Remember to add `data-slot="checkbox-group"` to the `<FieldGroup />` component for proper styling and spacing.
|
||||
|
||||
<ComponentPreview
|
||||
name="form-formisch-checkbox"
|
||||
className="sm:[&_.preview]:h-[700px]"
|
||||
chromeLessOnMobile
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers title="form.tsx" {16,19-25}
|
||||
<FormischField of={form} path={["tasks"]}>
|
||||
{(field) => (
|
||||
<FieldSet>
|
||||
<FieldLegend variant="label">Tasks</FieldLegend>
|
||||
<FieldDescription>
|
||||
Get notified when tasks you've created have updates.
|
||||
</FieldDescription>
|
||||
<FieldGroup data-slot="checkbox-group">
|
||||
{tasks.map((task) => (
|
||||
<Field
|
||||
key={task.id}
|
||||
orientation="horizontal"
|
||||
data-invalid={field.errors !== null}
|
||||
>
|
||||
<Checkbox
|
||||
id={`form-checkbox-${task.id}`}
|
||||
aria-invalid={field.errors !== null}
|
||||
checked={field.input?.includes(task.id) ?? false}
|
||||
onCheckedChange={(checked) => {
|
||||
const current = field.input ?? []
|
||||
field.onChange(
|
||||
checked === true
|
||||
? [...current, task.id]
|
||||
: current.filter((value) => value !== task.id)
|
||||
)
|
||||
}}
|
||||
/>
|
||||
<FieldLabel
|
||||
htmlFor={`form-checkbox-${task.id}`}
|
||||
className="font-normal"
|
||||
>
|
||||
{task.label}
|
||||
</FieldLabel>
|
||||
</Field>
|
||||
))}
|
||||
</FieldGroup>
|
||||
{field.errors && (
|
||||
<FieldError errors={field.errors.map((message) => ({ message }))} />
|
||||
)}
|
||||
</FieldSet>
|
||||
)}
|
||||
</FormischField>
|
||||
```
|
||||
|
||||
### Radio Group
|
||||
|
||||
- For radio groups, read `field.input` and call `field.onChange` from `onValueChange`.
|
||||
- To show errors, add the `aria-invalid` prop to the `<RadioGroupItem />` component and the `data-invalid` prop to the `<Field />` component.
|
||||
|
||||
<ComponentPreview
|
||||
name="form-formisch-radiogroup"
|
||||
className="sm:[&_.preview]:h-[700px]"
|
||||
chromeLessOnMobile
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers title="form.tsx" {9-13,21}
|
||||
<FormischField of={form} path={["plan"]}>
|
||||
{(field) => (
|
||||
<FieldSet>
|
||||
<FieldLegend>Plan</FieldLegend>
|
||||
<FieldDescription>
|
||||
You can upgrade or downgrade your plan at any time.
|
||||
</FieldDescription>
|
||||
<RadioGroup value={field.input} onValueChange={field.onChange}>
|
||||
{plans.map((plan) => (
|
||||
<FieldLabel key={plan.id} htmlFor={`form-radiogroup-${plan.id}`}>
|
||||
<Field
|
||||
orientation="horizontal"
|
||||
data-invalid={field.errors !== null}
|
||||
>
|
||||
<FieldContent>
|
||||
<FieldTitle>{plan.title}</FieldTitle>
|
||||
<FieldDescription>{plan.description}</FieldDescription>
|
||||
</FieldContent>
|
||||
<RadioGroupItem
|
||||
value={plan.id}
|
||||
id={`form-radiogroup-${plan.id}`}
|
||||
aria-invalid={field.errors !== null}
|
||||
/>
|
||||
</Field>
|
||||
</FieldLabel>
|
||||
))}
|
||||
</RadioGroup>
|
||||
{field.errors && (
|
||||
<FieldError errors={field.errors.map((message) => ({ message }))} />
|
||||
)}
|
||||
</FieldSet>
|
||||
)}
|
||||
</FormischField>
|
||||
```
|
||||
|
||||
### Switch
|
||||
|
||||
- For switches, read `field.input` and call `field.onChange` from `onCheckedChange`.
|
||||
- To show errors, add the `aria-invalid` prop to the `<Switch />` component and the `data-invalid` prop to the `<Field />` component.
|
||||
|
||||
<ComponentPreview
|
||||
name="form-formisch-switch"
|
||||
className="sm:[&_.preview]:h-[500px]"
|
||||
chromeLessOnMobile
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers title="form.tsx" {15-19}
|
||||
<FormischField of={form} path={["twoFactor"]}>
|
||||
{(field) => (
|
||||
<Field orientation="horizontal" data-invalid={field.errors !== null}>
|
||||
<FieldContent>
|
||||
<FieldLabel htmlFor="form-twoFactor">
|
||||
Multi-factor authentication
|
||||
</FieldLabel>
|
||||
<FieldDescription>
|
||||
Enable multi-factor authentication to secure your account.
|
||||
</FieldDescription>
|
||||
{field.errors && (
|
||||
<FieldError errors={field.errors.map((message) => ({ message }))} />
|
||||
)}
|
||||
</FieldContent>
|
||||
<Switch
|
||||
id="form-twoFactor"
|
||||
checked={field.input ?? false}
|
||||
onCheckedChange={field.onChange}
|
||||
aria-invalid={field.errors !== null}
|
||||
/>
|
||||
</Field>
|
||||
)}
|
||||
</FormischField>
|
||||
```
|
||||
|
||||
### Complex Forms
|
||||
|
||||
Here is an example of a more complex form with multiple fields and validation.
|
||||
|
||||
<ComponentPreview
|
||||
name="form-formisch-complex"
|
||||
className="sm:[&_.preview]:h-[1300px]"
|
||||
chromeLessOnMobile
|
||||
/>
|
||||
|
||||
## Resetting the Form
|
||||
|
||||
Formisch exposes a top-level `reset` function. Pass the form store to reset it to its initial input.
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Button type="button" variant="outline" onClick={() => reset(form)}>
|
||||
Reset
|
||||
</Button>
|
||||
```
|
||||
|
||||
You can also reset to new initial values, or reset while keeping the user's current input:
|
||||
|
||||
```tsx showLineNumbers
|
||||
// Reset to a fresh set of initial values
|
||||
reset(form, { initialInput: { title: "", description: "" } })
|
||||
|
||||
// Sync the baseline to new server data, but keep the user's edits
|
||||
reset(form, { initialInput: serverData, keepInput: true })
|
||||
```
|
||||
|
||||
## Array Fields
|
||||
|
||||
Formisch provides a `<FieldArray />` component and a set of helper functions for managing dynamic array fields. Use it whenever you need to add, remove, or reorder items.
|
||||
|
||||
<ComponentPreview
|
||||
name="form-formisch-array"
|
||||
className="sm:[&_.preview]:h-[700px]"
|
||||
chromeLessOnMobile
|
||||
/>
|
||||
|
||||
### Using FieldArray
|
||||
|
||||
`<FieldArray />` follows the same render-prop pattern as `<Field />`. Its `items` array contains a stable key per item that you should use as the React `key`.
|
||||
|
||||
```tsx showLineNumbers title="form.tsx" {1,7-22}
|
||||
import {
|
||||
Field as FormischField,
|
||||
FieldArray,
|
||||
insert,
|
||||
remove,
|
||||
} from "@formisch/react"
|
||||
|
||||
export function ExampleForm() {
|
||||
// ... form config
|
||||
|
||||
return (
|
||||
<FieldArray of={form} path={["emails"]}>
|
||||
{(fieldArray) => (
|
||||
<FieldGroup className="gap-4">
|
||||
{fieldArray.items.map((item, index) => (
|
||||
<FormischField
|
||||
key={item}
|
||||
of={form}
|
||||
path={["emails", index, "address"]}
|
||||
>
|
||||
{(field) => /* ... */}
|
||||
</FormischField>
|
||||
))}
|
||||
</FieldGroup>
|
||||
)}
|
||||
</FieldArray>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Array Field Structure
|
||||
|
||||
Wrap your array fields in a `<FieldSet />` with a `<FieldLegend />` and `<FieldDescription />`.
|
||||
|
||||
```tsx showLineNumbers title="form.tsx"
|
||||
<FieldSet className="gap-4">
|
||||
<FieldLegend variant="label">Email Addresses</FieldLegend>
|
||||
<FieldDescription>
|
||||
Add up to 5 email addresses where we can contact you.
|
||||
</FieldDescription>
|
||||
<FieldGroup className="gap-4">{/* Array items go here */}</FieldGroup>
|
||||
</FieldSet>
|
||||
```
|
||||
|
||||
### Adding Items
|
||||
|
||||
Use the `insert` function to add new items to the array. By default new items are appended to the end. You can also pass an `at` index to insert at a specific position.
|
||||
|
||||
```tsx showLineNumbers title="form.tsx"
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() =>
|
||||
insert(form, { path: ["emails"], initialInput: { address: "" } })
|
||||
}
|
||||
disabled={fieldArray.items.length >= 5}
|
||||
>
|
||||
Add Email Address
|
||||
</Button>
|
||||
```
|
||||
|
||||
### Removing Items
|
||||
|
||||
Use the `remove` function with an `at` index to remove items from the array.
|
||||
|
||||
```tsx showLineNumbers title="form.tsx"
|
||||
import { remove } from "@formisch/react"
|
||||
|
||||
{
|
||||
fieldArray.items.length > 1 && (
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupButton
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon-xs"
|
||||
onClick={() => remove(form, { path: ["emails"], at: index })}
|
||||
aria-label={`Remove email ${index + 1}`}
|
||||
>
|
||||
<XIcon />
|
||||
</InputGroupButton>
|
||||
</InputGroupAddon>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Formisch also exposes `move`, `swap`, and `replace` for reordering and replacing items. They follow the same `(form, config)` signature.
|
||||
|
||||
### Array Validation
|
||||
|
||||
Use Valibot's `array` and pipeline validators to constrain array fields.
|
||||
|
||||
```tsx showLineNumbers title="form.tsx"
|
||||
const FormSchema = v.object({
|
||||
emails: v.pipe(
|
||||
v.array(
|
||||
v.object({
|
||||
address: v.pipe(
|
||||
v.string(),
|
||||
v.nonEmpty("Enter an email address."),
|
||||
v.email("Enter a valid email address.")
|
||||
),
|
||||
})
|
||||
),
|
||||
v.minLength(1, "Add at least one email address."),
|
||||
v.maxLength(5, "You can add up to 5 email addresses.")
|
||||
),
|
||||
})
|
||||
```
|
||||
@@ -25,6 +25,24 @@ Start by selecting your framework. Then follow the instructions to learn how to
|
||||
</svg>
|
||||
<p className="mt-2 font-medium">TanStack Form</p>
|
||||
</LinkedCard>
|
||||
<LinkedCard href="/docs/forms/formisch">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
className="size-10"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="20"
|
||||
d="M90.9 291.7 49 299.4v125.5l193.3 63.8 221-63.8V304.7l-62-13.7m-352.2 8.6 193.2 53.6V488m221-183.2-221.1 48.4m-171-67.7 147.5 47 212.7-48.3L437 76 271.9 25 72.1 66.3Zm1-219.3L220.5 118l-1.8 214m1.8-214.3 216.2-41.6m-84.4 159.6-.9 1.9c-5.2 11.3-16.2 34.8-33.5 35.5h-1a22 22 0 0 1-9.7-2.2 26 26 0 0 1-7.4-5.5c-4.3-4.4-7.4-10-10-14.5q-1.2-2.4-2.7-4.7a54 54 0 0 0 21.7 4.1 74 74 0 0 0 23.6-4 70 70 0 0 0 11.4-5 64 64 0 0 0 8.5-5.6M247.6 168c19.5-20.8 34.8-12.3 36-18.4 1.5-7-12.2-7.7-22.2-2.6s-18 17.7-13.8 21m101.2-33.2c1.6 2.6 8.7-1.6 19.5-1.2s15.8 5.7 18 4.1-4.6-14.7-17.1-15.2-22 9.7-20.4 12.3m21.2 16.3c9.4.6 17.1 12.8 16.1 27.6s-10.4 25.9-19.8 25.2-17.1-12.9-16.1-27.7 10.4-25.8 19.8-25.1m-97.4 19c11 1.2 19 15.1 17.4 30.5s-12.3 27.4-23.4 26.2-19-15-17.4-30.5 12.3-27.3 23.4-26.2"
|
||||
/>
|
||||
</svg>
|
||||
<p className="mt-2 font-medium">Formisch</p>
|
||||
</LinkedCard>
|
||||
<LinkedCard href="#" className="border border-dashed bg-transparent">
|
||||
<svg
|
||||
role="img"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"pages": ["react-hook-form", "tanstack-form"]
|
||||
"pages": ["react-hook-form", "tanstack-form", "formisch"]
|
||||
}
|
||||
|
||||
@@ -19,9 +19,11 @@ Add the following dependencies to your project:
|
||||
npm install shadcn class-variance-authority clsx tailwind-merge lucide-react tw-animate-css
|
||||
```
|
||||
|
||||
### Configure path aliases
|
||||
### Configure import aliases
|
||||
|
||||
Configure the path aliases in your `tsconfig.json` file.
|
||||
Choose one of the following alias setups.
|
||||
|
||||
#### Option A: `tsconfig.json` paths
|
||||
|
||||
```json {3-6} title="tsconfig.json" showLineNumbers
|
||||
{
|
||||
@@ -34,7 +36,31 @@ Configure the path aliases in your `tsconfig.json` file.
|
||||
}
|
||||
```
|
||||
|
||||
The `@` alias is a preference. You can use other aliases if you want.
|
||||
#### Option B: `package.json#imports`
|
||||
|
||||
```json title="package.json" showLineNumbers
|
||||
{
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json title="tsconfig.json" showLineNumbers
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "bundler",
|
||||
"resolvePackageJsonImports": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `@` alias is a preference. You can use other aliases if you want. If you
|
||||
use `package.json#imports`, keep the matching alias roots in `components.json`.
|
||||
See the <Link href="/docs/package-imports">package imports guide</Link> for
|
||||
framework-specific setup.
|
||||
|
||||
### Configure styles
|
||||
|
||||
@@ -211,6 +237,20 @@ Create a `components.json` file in the root of your project.
|
||||
}
|
||||
```
|
||||
|
||||
If you're using `package.json#imports`, use the corresponding `#...` aliases instead:
|
||||
|
||||
```json title="components.json" showLineNumbers
|
||||
{
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"utils": "#lib/utils",
|
||||
"ui": "#components/ui",
|
||||
"lib": "#lib",
|
||||
"hooks": "#hooks"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### That's it
|
||||
|
||||
You can now start adding components to your project.
|
||||
|
||||
@@ -309,6 +309,94 @@ A `registry:hook` item is a custom React hook.
|
||||
}
|
||||
```
|
||||
|
||||
## Target Placeholders
|
||||
|
||||
Use `files[].target` placeholders when a registry item should install files
|
||||
under the user's configured shadcn directories. The available placeholders are
|
||||
`@components/`, `@ui/`, `@lib/` and `@hooks/`.
|
||||
|
||||
The placeholders are resolved from `components.json`, so the same registry item
|
||||
works in projects using `@/`, custom TypeScript aliases, package imports or
|
||||
workspace package exports.
|
||||
|
||||
Anything after the placeholder is preserved. For example,
|
||||
`@ui/ai/prompt-input.tsx` installs under the user's configured `ui` directory
|
||||
at `ai/prompt-input.tsx`.
|
||||
|
||||
```json title="alias-child.json" showLineNumbers {9,15,21}
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "alias-child",
|
||||
"type": "registry:item",
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york/alias/target-alias-button.tsx",
|
||||
"type": "registry:ui",
|
||||
"target": "@ui/target-alias-button.tsx",
|
||||
"content": "..."
|
||||
},
|
||||
{
|
||||
"path": "registry/new-york/alias/target-alias-helper.ts",
|
||||
"type": "registry:lib",
|
||||
"target": "@lib/target-alias-helper.ts",
|
||||
"content": "..."
|
||||
},
|
||||
{
|
||||
"path": "registry/new-york/alias/prompt-input.tsx",
|
||||
"type": "registry:ui",
|
||||
"target": "@ui/ai/prompt-input.tsx",
|
||||
"content": "..."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Registry dependencies can use target placeholders too. In the following example,
|
||||
the child item installs a UI component and a helper, while the parent item
|
||||
installs an app component and a hook.
|
||||
|
||||
```json title="alias-parent.json" showLineNumbers {7,13}
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "alias-parent",
|
||||
"type": "registry:item",
|
||||
"registryDependencies": ["https://example.com/r/alias-child.json"],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york/alias/target-alias-panel.tsx",
|
||||
"type": "registry:component",
|
||||
"target": "@components/target-alias-panel.tsx",
|
||||
"content": "..."
|
||||
},
|
||||
{
|
||||
"path": "registry/new-york/alias/use-target-alias.ts",
|
||||
"type": "registry:hook",
|
||||
"target": "@hooks/use-target-alias.ts",
|
||||
"content": "..."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The `target` controls where the file is written, even when it differs from the
|
||||
file `type`.
|
||||
|
||||
```json title="type-mismatch.json" showLineNumbers {9}
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "type-mismatch",
|
||||
"type": "registry:item",
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york/example/format-date.ts",
|
||||
"type": "registry:ui",
|
||||
"target": "@lib/format-date.ts",
|
||||
"content": "..."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## registry:font
|
||||
|
||||
### Custom font
|
||||
|
||||
@@ -226,6 +226,80 @@ By default, the `shadcn` cli will read a project's `components.json` file to det
|
||||
|
||||
Use `~` to refer to the root of the project e.g `~/foo.config.js`.
|
||||
|
||||
You can also use registry target placeholders to place files under the
|
||||
directories configured by the user's `components.json`. These placeholders are
|
||||
only supported at the start of `target` and are independent of the project's
|
||||
import prefix. For example, `@ui/button.tsx` works whether the project imports
|
||||
components with `@/`, `#`, package imports or workspace exports.
|
||||
|
||||
| Placeholder | Resolves to |
|
||||
| -------------- | -------------------- |
|
||||
| `@components/` | `aliases.components` |
|
||||
| `@ui/` | `aliases.ui` |
|
||||
| `@lib/` | `aliases.lib` |
|
||||
| `@hooks/` | `aliases.hooks` |
|
||||
|
||||
Use these placeholders when you want a registry item to install into the
|
||||
project's configured shadcn directories without hardcoding `components`, `src`
|
||||
or workspace package paths. Anything after the placeholder is preserved, so
|
||||
`@ui/ai/prompt-input.tsx` installs under the user's configured `ui` directory
|
||||
at `ai/prompt-input.tsx`.
|
||||
|
||||
```json title="registry-item.json" showLineNumbers
|
||||
{
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york/example/button.tsx",
|
||||
"type": "registry:ui",
|
||||
"target": "@ui/button.tsx"
|
||||
},
|
||||
{
|
||||
"path": "registry/new-york/example/prompt-input.tsx",
|
||||
"type": "registry:ui",
|
||||
"target": "@ui/ai/prompt-input.tsx"
|
||||
},
|
||||
{
|
||||
"path": "registry/new-york/example/card.tsx",
|
||||
"type": "registry:component",
|
||||
"target": "@components/card.tsx"
|
||||
},
|
||||
{
|
||||
"path": "registry/new-york/example/helper.ts",
|
||||
"type": "registry:lib",
|
||||
"target": "@lib/helper.ts"
|
||||
},
|
||||
{
|
||||
"path": "registry/new-york/example/use-demo.ts",
|
||||
"type": "registry:hook",
|
||||
"target": "@hooks/use-demo.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The `target` property decides where the file is written. It can point to a
|
||||
different shadcn directory than the file `type`.
|
||||
|
||||
```json title="registry-item.json" showLineNumbers
|
||||
{
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york/example/format-date.ts",
|
||||
"type": "registry:ui",
|
||||
"target": "@lib/format-date.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Unknown placeholders are treated as regular target paths. For example,
|
||||
`@foo/bar.ts` is written as `foo/bar.ts`. Embedded placeholders such as
|
||||
`components/@ui/button.tsx` are also treated as regular paths.
|
||||
|
||||
<Callout>
|
||||
`@utils/` is not supported because `utils` points to a file, not a directory.
|
||||
</Callout>
|
||||
|
||||
### tailwind
|
||||
|
||||
**DEPRECATED:** Use `cssVars.theme` instead for Tailwind v4 projects.
|
||||
|
||||
@@ -21,6 +21,7 @@ const eventSchema = z.object({
|
||||
"copy_create_share_url",
|
||||
"copy_registry_add_command",
|
||||
"copy_preset_command",
|
||||
"copy_apply_command",
|
||||
]),
|
||||
// declare type AllowedPropertyValues = string | number | boolean | null
|
||||
properties: z
|
||||
|
||||
@@ -55,69 +55,156 @@ function ComponentsListWrapper() {
|
||||
)
|
||||
}
|
||||
|
||||
function getNodeText(node: React.ReactNode): string {
|
||||
if (typeof node === "string" || typeof node === "number") {
|
||||
return String(node)
|
||||
}
|
||||
|
||||
if (Array.isArray(node)) {
|
||||
return node.map((child) => getNodeText(child)).join("")
|
||||
}
|
||||
|
||||
if (React.isValidElement<{ children?: React.ReactNode }>(node)) {
|
||||
return getNodeText(node.props.children)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
function getHeadingId(children: React.ReactNode) {
|
||||
const id = getNodeText(children)
|
||||
.trim()
|
||||
.replace(/\s+/g, "-")
|
||||
.replace(/'/g, "")
|
||||
.replace(/\?/g, "")
|
||||
.toLowerCase()
|
||||
|
||||
return id || undefined
|
||||
}
|
||||
|
||||
function HeadingAnchor({
|
||||
id,
|
||||
children,
|
||||
}: {
|
||||
id?: string
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
if (!id) {
|
||||
return children
|
||||
}
|
||||
|
||||
return (
|
||||
<a className="group no-underline" href={`#${id}`}>
|
||||
<span className="underline-offset-4 group-hover:underline">
|
||||
{children}
|
||||
</span>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className="ml-2 text-muted-foreground opacity-0 group-hover:opacity-100"
|
||||
>
|
||||
#
|
||||
</span>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
export const mdxComponents = {
|
||||
h1: ({ className, ...props }: React.ComponentProps<"h1">) => (
|
||||
<h1
|
||||
className={cn(
|
||||
"mt-2 scroll-m-28 font-heading text-3xl font-bold tracking-tight",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
h2: ({ className, ...props }: React.ComponentProps<"h2">) => {
|
||||
h1: ({ className, children, id, ...props }: React.ComponentProps<"h1">) => {
|
||||
const headingId = id ?? getHeadingId(children)
|
||||
|
||||
return (
|
||||
<h1
|
||||
id={headingId}
|
||||
className={cn(
|
||||
"mt-2 scroll-m-28 font-heading text-3xl font-bold tracking-tight",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<HeadingAnchor id={headingId}>{children}</HeadingAnchor>
|
||||
</h1>
|
||||
)
|
||||
},
|
||||
h2: ({ className, children, id, ...props }: React.ComponentProps<"h2">) => {
|
||||
const headingId = id ?? getHeadingId(children)
|
||||
|
||||
return (
|
||||
<h2
|
||||
id={props.children
|
||||
?.toString()
|
||||
.replace(/ /g, "-")
|
||||
.replace(/'/g, "")
|
||||
.replace(/\?/g, "")
|
||||
.toLowerCase()}
|
||||
id={headingId}
|
||||
className={cn(
|
||||
"[&+]*:[code]:text-xl mt-10 scroll-m-28 font-heading text-xl font-medium tracking-tight first:mt-0 lg:mt-12 [&+.steps]:mt-0! [&+.steps>h3]:mt-4! [&+h3]:mt-6! [&+p]:mt-4!",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
>
|
||||
<HeadingAnchor id={headingId}>{children}</HeadingAnchor>
|
||||
</h2>
|
||||
)
|
||||
},
|
||||
h3: ({ className, children, id, ...props }: React.ComponentProps<"h3">) => {
|
||||
const headingId = id ?? getHeadingId(children)
|
||||
|
||||
return (
|
||||
<h3
|
||||
id={headingId}
|
||||
className={cn(
|
||||
"mt-12 scroll-m-28 font-heading text-lg font-medium tracking-tight [&+p]:mt-4! *:[code]:text-xl",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<HeadingAnchor id={headingId}>{children}</HeadingAnchor>
|
||||
</h3>
|
||||
)
|
||||
},
|
||||
h4: ({ className, children, id, ...props }: React.ComponentProps<"h4">) => {
|
||||
const headingId = id ?? getHeadingId(children)
|
||||
|
||||
return (
|
||||
<h4
|
||||
id={headingId}
|
||||
className={cn(
|
||||
"mt-8 scroll-m-28 font-heading text-base font-medium tracking-tight",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<HeadingAnchor id={headingId}>{children}</HeadingAnchor>
|
||||
</h4>
|
||||
)
|
||||
},
|
||||
h5: ({ className, children, id, ...props }: React.ComponentProps<"h5">) => {
|
||||
const headingId = id ?? getHeadingId(children)
|
||||
|
||||
return (
|
||||
<h5
|
||||
id={headingId}
|
||||
className={cn(
|
||||
"mt-8 scroll-m-28 text-base font-medium tracking-tight",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<HeadingAnchor id={headingId}>{children}</HeadingAnchor>
|
||||
</h5>
|
||||
)
|
||||
},
|
||||
h6: ({ className, children, id, ...props }: React.ComponentProps<"h6">) => {
|
||||
const headingId = id ?? getHeadingId(children)
|
||||
|
||||
return (
|
||||
<h6
|
||||
id={headingId}
|
||||
className={cn(
|
||||
"mt-8 scroll-m-28 text-base font-medium tracking-tight",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<HeadingAnchor id={headingId}>{children}</HeadingAnchor>
|
||||
</h6>
|
||||
)
|
||||
},
|
||||
h3: ({ className, ...props }: React.ComponentProps<"h3">) => (
|
||||
<h3
|
||||
className={cn(
|
||||
"mt-12 scroll-m-28 font-heading text-lg font-medium tracking-tight [&+p]:mt-4! *:[code]:text-xl",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
h4: ({ className, ...props }: React.ComponentProps<"h4">) => (
|
||||
<h4
|
||||
className={cn(
|
||||
"mt-8 scroll-m-28 font-heading text-base font-medium tracking-tight",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
h5: ({ className, ...props }: React.ComponentProps<"h5">) => (
|
||||
<h5
|
||||
className={cn(
|
||||
"mt-8 scroll-m-28 text-base font-medium tracking-tight",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
h6: ({ className, ...props }: React.ComponentProps<"h6">) => (
|
||||
<h6
|
||||
className={cn(
|
||||
"mt-8 scroll-m-28 text-base font-medium tracking-tight",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
a: ({ className, ...props }: React.ComponentProps<"a">) => (
|
||||
<a
|
||||
className={cn("font-medium underline underline-offset-4", className)}
|
||||
|
||||
@@ -132,6 +132,12 @@ const nextConfig = {
|
||||
destination: "/create",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/code/:path*",
|
||||
destination:
|
||||
"https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/:path*",
|
||||
permanent: false,
|
||||
},
|
||||
]
|
||||
},
|
||||
rewrites() {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"@dnd-kit/sortable": "^10.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@faker-js/faker": "^10.1.0",
|
||||
"@formisch/react": "^0.4.4",
|
||||
"@hookform/resolvers": "^3.10.0",
|
||||
"@hugeicons/core-free-icons": "^1.2.1",
|
||||
"@hugeicons/react": "^1.1.1",
|
||||
@@ -76,12 +77,13 @@
|
||||
"rehype-pretty-code": "^0.14.1",
|
||||
"rimraf": "^6.0.1",
|
||||
"server-only": "^0.0.1",
|
||||
"shadcn": "4.5.0",
|
||||
"shadcn": "4.7.0",
|
||||
"shiki": "^1.10.1",
|
||||
"sonner": "^2.0.0",
|
||||
"swr": "^2.3.6",
|
||||
"tailwind-merge": "^3.0.1",
|
||||
"ts-morph": "26.0.0",
|
||||
"valibot": "^1.4.0",
|
||||
"vaul": "1.1.2",
|
||||
"zod": "^3.25.76"
|
||||
},
|
||||
|
||||
@@ -124,6 +124,7 @@
|
||||
- [Forms Overview](https://ui.shadcn.com/docs/forms): Guide to building forms with shadcn/ui.
|
||||
- [React Hook Form](https://ui.shadcn.com/docs/forms/react-hook-form): Using shadcn/ui with React Hook Form.
|
||||
- [TanStack Form](https://ui.shadcn.com/docs/forms/tanstack-form): Using shadcn/ui with TanStack Form.
|
||||
- [Formisch](https://ui.shadcn.com/docs/forms/formisch): Using shadcn/ui with Formisch.
|
||||
- [Forms - Next.js](https://ui.shadcn.com/docs/forms/next): Building forms in Next.js with Server Actions.
|
||||
|
||||
## Advanced
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/accordion",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/accordion-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/accordion-example.tsx",
|
||||
"api": "https://www.radix-ui.com/primitives/docs/components/accordion.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/accordion",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/accordion-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/accordion-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/accordion.md"
|
||||
}
|
||||
}
|
||||
@@ -36,11 +36,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/alert",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/alert-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/alert-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/alert",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/alert-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/alert-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,12 +59,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/alert-dialog",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/alert-dialog-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/alert-dialog-example.tsx",
|
||||
"api": "https://www.radix-ui.com/primitives/docs/components/alert-dialog.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/alert-dialog",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/alert-dialog-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/alert-dialog-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/alert-dialog.md"
|
||||
}
|
||||
}
|
||||
@@ -83,12 +83,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/aspect-ratio",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/aspect-ratio-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/aspect-ratio-example.tsx",
|
||||
"api": "https://www.radix-ui.com/primitives/docs/components/aspect-ratio.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/aspect-ratio",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/aspect-ratio-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/aspect-ratio-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,12 +106,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/avatar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/avatar-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/avatar-example.tsx",
|
||||
"api": "https://www.radix-ui.com/primitives/docs/components/avatar.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/avatar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/avatar-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/avatar-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/avatar.md"
|
||||
}
|
||||
}
|
||||
@@ -130,11 +130,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/badge",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/badge-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/badge-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/badge",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/badge-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/badge-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,11 +152,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/breadcrumb",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/breadcrumb-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/breadcrumb-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/breadcrumb",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/breadcrumb-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/breadcrumb-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,11 +174,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/button",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/button-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/button-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/button",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/button-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/button-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -197,11 +197,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/button-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/button-group-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/button-group-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/button-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/button-group-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/button-group-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,12 +221,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/calendar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/calendar-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/calendar-example.tsx",
|
||||
"api": "https://react-day-picker.js.org"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/calendar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/calendar-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/calendar-example.tsx",
|
||||
"api": "https://react-day-picker.js.org"
|
||||
}
|
||||
}
|
||||
@@ -245,11 +245,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/card",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/card-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/card-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/card",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/card-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/card-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -269,12 +269,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/carousel",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/carousel-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/carousel-example.tsx",
|
||||
"api": "https://www.embla-carousel.com/get-started/react"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/carousel",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/carousel-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/carousel-example.tsx",
|
||||
"api": "https://www.embla-carousel.com/get-started/react"
|
||||
}
|
||||
}
|
||||
@@ -294,11 +294,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/chart",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/chart-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/chart-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/chart",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/chart-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/chart-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -316,12 +316,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/checkbox",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/checkbox-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/checkbox-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/checkbox.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/checkbox",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/checkbox-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/checkbox-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/checkbox.md"
|
||||
}
|
||||
}
|
||||
@@ -340,12 +340,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/collapsible",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/collapsible-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/collapsible-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/collapsible.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/collapsible",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/collapsible-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/collapsible-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/collapsible.md"
|
||||
}
|
||||
}
|
||||
@@ -366,12 +366,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/combobox",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/combobox-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/combobox-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/combobox"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/combobox",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/combobox-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/combobox-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/combobox.md"
|
||||
}
|
||||
}
|
||||
@@ -392,12 +392,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/command",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/command-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/command-example.tsx",
|
||||
"api": "https://github.com/dip/cmdk"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/command",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/command-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/command-example.tsx",
|
||||
"api": "https://github.com/dip/cmdk"
|
||||
}
|
||||
}
|
||||
@@ -416,12 +416,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/context-menu",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/context-menu-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/context-menu-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/context-menu.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/context-menu",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/context-menu-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/context-menu-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/context-menu.md"
|
||||
}
|
||||
}
|
||||
@@ -441,12 +441,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/dialog",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/dialog-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/dialog-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/dialog.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/dialog",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/dialog-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/dialog-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/dialog.md"
|
||||
}
|
||||
}
|
||||
@@ -488,12 +488,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/drawer",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/drawer-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/drawer-example.tsx",
|
||||
"api": "https://vaul.emilkowal.ski/getting-started"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/drawer",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/drawer-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/drawer-example.tsx",
|
||||
"api": "https://vaul.emilkowal.ski/getting-started"
|
||||
}
|
||||
}
|
||||
@@ -512,12 +512,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/dropdown-menu",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/dropdown-menu-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/dropdown-menu-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/dropdown-menu.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/dropdown-menu",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/dropdown-menu-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/dropdown-menu-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/menu.md"
|
||||
}
|
||||
}
|
||||
@@ -536,11 +536,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/empty",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/empty-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/empty-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/empty",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/empty-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/empty-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -559,11 +559,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/field",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/field-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/field-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/field",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/field-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/field-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -585,12 +585,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/hover-card",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/hover-card-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/hover-card-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/hover-card.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/hover-card",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/hover-card-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/hover-card-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/hover-card.md"
|
||||
}
|
||||
}
|
||||
@@ -609,11 +609,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/input",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/input-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/input-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/input",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/input-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/input-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -632,11 +632,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/input-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/input-group-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/input-group-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/input-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/input-group-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/input-group-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -655,12 +655,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/input-otp",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/input-otp-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/input-otp-example.tsx",
|
||||
"api": "https://input-otp.rodz.dev"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/input-otp",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/input-otp-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/input-otp-example.tsx",
|
||||
"api": "https://input-otp.rodz.dev"
|
||||
}
|
||||
}
|
||||
@@ -680,11 +680,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/item",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/item-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/item-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/item",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/item-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/item-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -702,11 +702,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/kbd",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/kbd-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/kbd-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/kbd",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/kbd-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/kbd-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -724,12 +724,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/label",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/label-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/label-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/label.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/label",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/label-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/label-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/label.md"
|
||||
}
|
||||
}
|
||||
@@ -748,12 +748,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/menubar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/menubar-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/menubar-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/menubar.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/menubar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/menubar-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/menubar-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/menubar.md"
|
||||
}
|
||||
}
|
||||
@@ -772,11 +772,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/native-select",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/native-select-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/native-select-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/native-select",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/native-select-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/native-select-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -794,12 +794,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/navigation-menu",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/navigation-menu-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/navigation-menu-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/navigation-menu.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/navigation-menu",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/navigation-menu-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/navigation-menu-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/navigation-menu.md"
|
||||
}
|
||||
}
|
||||
@@ -819,11 +819,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/pagination",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/pagination-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/pagination-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/pagination",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/pagination-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/pagination-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -841,12 +841,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/popover",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/popover-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/popover-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/popover.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/popover",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/popover-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/popover-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/popover.md"
|
||||
}
|
||||
}
|
||||
@@ -865,12 +865,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/progress",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/progress-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/progress-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/progress.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/progress",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/progress-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/progress-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/progress.md"
|
||||
}
|
||||
}
|
||||
@@ -889,12 +889,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/radio-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/radio-group-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/radio-group-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/radio-group.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/radio-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/radio-group-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/radio-group-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/radio-group.md"
|
||||
}
|
||||
}
|
||||
@@ -914,12 +914,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/resizable",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/resizable-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/resizable-example.tsx",
|
||||
"api": "https://github.com/bvaughn/react-resizable-panels"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/resizable",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/resizable-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/resizable-example.tsx",
|
||||
"api": "https://github.com/bvaughn/react-resizable-panels"
|
||||
}
|
||||
}
|
||||
@@ -938,12 +938,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/scroll-area",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/scroll-area-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/scroll-area-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/scroll-area.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/scroll-area",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/scroll-area-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/scroll-area-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/scroll-area.md"
|
||||
}
|
||||
}
|
||||
@@ -962,12 +962,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/select",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/select-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/select-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/select.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/select",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/select-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/select-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/select.md"
|
||||
}
|
||||
}
|
||||
@@ -986,12 +986,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/separator",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/separator-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/separator-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/separator.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/separator",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/separator-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/separator-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/separator.md"
|
||||
}
|
||||
}
|
||||
@@ -1011,12 +1011,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/sheet",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/sheet-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/sheet-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/dialog.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/sheet",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/sheet-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/sheet-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/dialog.md"
|
||||
}
|
||||
}
|
||||
@@ -1044,11 +1044,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/sidebar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/sidebar-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/sidebar-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/sidebar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/sidebar-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/sidebar-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1066,11 +1066,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/skeleton",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/skeleton-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/skeleton-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/skeleton",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/skeleton-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/skeleton-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1088,12 +1088,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/slider",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/slider-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/slider-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/slider.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/slider",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/slider-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/slider-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/slider.md"
|
||||
}
|
||||
}
|
||||
@@ -1113,12 +1113,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/sonner",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/sonner-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/sonner-example.tsx",
|
||||
"api": "https://sonner.emilkowal.ski"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/sonner",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/sonner-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/sonner-example.tsx",
|
||||
"api": "https://sonner.emilkowal.ski"
|
||||
}
|
||||
}
|
||||
@@ -1137,11 +1137,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/spinner",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/spinner-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/spinner-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/spinner",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/spinner-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/spinner-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1159,12 +1159,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/switch",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/switch-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/switch-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/switch.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/switch",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/switch-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/switch-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/switch.md"
|
||||
}
|
||||
}
|
||||
@@ -1183,11 +1183,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/table",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/table-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/table-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/table",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/table-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/table-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1205,12 +1205,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/tabs",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/tabs-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/tabs-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/tabs.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/tabs",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/tabs-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/tabs-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/tabs.md"
|
||||
}
|
||||
}
|
||||
@@ -1229,11 +1229,11 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/textarea",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/textarea-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/textarea-example.tsx"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/textarea",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/textarea-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/textarea-example.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1251,12 +1251,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/toggle",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/toggle-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/toggle-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/toggle.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/toggle",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/toggle-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/toggle-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/toggle.md"
|
||||
}
|
||||
}
|
||||
@@ -1276,12 +1276,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/toggle-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/toggle-group-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/toggle-group-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/toggle-group.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/toggle-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/toggle-group-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/toggle-group-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/toggle-group.md"
|
||||
}
|
||||
}
|
||||
@@ -1301,12 +1301,12 @@
|
||||
"links": {
|
||||
"radix": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/radix/tooltip",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/radix/examples/tooltip-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/tooltip-example.tsx",
|
||||
"api": "https://www.radix-ui.com/docs/primitives/components/tooltip.md"
|
||||
},
|
||||
"base": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/tooltip",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/tooltip-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/tooltip-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/tooltip.md"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +83,12 @@
|
||||
"url": "https://aliimam.in/r/{name}.json",
|
||||
"description": "I create digital experiences that connect and inspire. I build apps, websites, brands, and products end-to-end."
|
||||
},
|
||||
{
|
||||
"name": "@amplo",
|
||||
"homepage": "https://amplo.ale.design",
|
||||
"url": "https://amplo.ale.design/r/{name}.json",
|
||||
"description": "OKLCH-native, Display-P3-aware composable fill picker with WCAG/APCA contrast metrics, gamut detection, and full keyboard accessibility."
|
||||
},
|
||||
{
|
||||
"name": "@animate-ui",
|
||||
"homepage": "https://animate-ui.com",
|
||||
@@ -131,6 +137,12 @@
|
||||
"url": "https://boldkit.dev/r/{name}.json",
|
||||
"description": "Neubrutalism component library with 43 components, 42 SVG shapes, thick borders, and hard shadows. Supports React, Vue, and Nuxt. Built on shadcn/ui."
|
||||
},
|
||||
{
|
||||
"name": "@bklit",
|
||||
"homepage": "https://ui.bklit.com",
|
||||
"url": "https://ui.bklit.com/r/{name}.json",
|
||||
"description": "Open-source composable chart components for React — line, area, bar, pie, radar, maps, and more. Built with Visx, Motion, and shadcn/ui."
|
||||
},
|
||||
{
|
||||
"name": "@bundui",
|
||||
"homepage": "https://bundui.io",
|
||||
@@ -161,12 +173,24 @@
|
||||
"url": "https://coderabbit-shadcn-registry.vercel.app/r/{name}.json",
|
||||
"description": "A framework-agnostic API client, pluggable storage adapters (LocalStorage, Convex, Supabase, PostgreSQL, MySQL), and React components for generating developer activity reports."
|
||||
},
|
||||
{
|
||||
"name": "@cognicatch",
|
||||
"homepage": "https://cognicatch.dev",
|
||||
"url": "https://cognicatch.dev/registry/{name}.json",
|
||||
"description": "Adaptive Error Boundaries and graceful fallback UIs (Banners, Modals, Toasts)."
|
||||
},
|
||||
{
|
||||
"name": "@commercn",
|
||||
"homepage": "https://commercn.com",
|
||||
"url": "https://commercn.com/r/{name}.json",
|
||||
"description": "Shadcn UI Blocks for Ecommerce websites"
|
||||
},
|
||||
{
|
||||
"name": "@corr",
|
||||
"homepage": "https://ui.corr.sh",
|
||||
"url": "https://ui.corr.sh/r/{name}.json",
|
||||
"description": "A collection of shadcn-based React components, charts, animated components, and blocks built over time."
|
||||
},
|
||||
{
|
||||
"name": "@coss",
|
||||
"homepage": "https://coss.com/ui",
|
||||
@@ -233,6 +257,12 @@
|
||||
"url": "https://eldoraui.site/r/{name}.json",
|
||||
"description": "An open-source, modern UI component library for React, built with TypeScript, Tailwind CSS, and Framer Motion. Eldora UI offers beautifully crafted, reusable components designed for performance and elegance."
|
||||
},
|
||||
{
|
||||
"name": "@evilcharts",
|
||||
"homepage": "https://evilcharts.com",
|
||||
"url": "https://evilcharts.com/r/{name}.json",
|
||||
"description": "EvilCharts is an open-source chart UI website built with shadcn and Recharts, beautifully designed and handcrafted."
|
||||
},
|
||||
{
|
||||
"name": "@formcn",
|
||||
"homepage": "https://formcn.dev",
|
||||
@@ -269,6 +299,12 @@
|
||||
"url": "https://glass-ui.crenspire.com/r/{name}.json",
|
||||
"description": "A shadcn-ui compatible registry distributing 40+ glassmorphic React/TypeScript components with Apple-inspired design. Components include enhanced visual effects (glow, shimmer, ripple), theme support, and customizable glassmorphism styling."
|
||||
},
|
||||
{
|
||||
"name": "@glasscn",
|
||||
"homepage": "https://glasscn-components.vercel.app/",
|
||||
"url": "https://glasscn-components.vercel.app/r/{name}.json",
|
||||
"description": "A shadcn-compatible registry of glassmorphism components inspired by Apple"
|
||||
},
|
||||
{
|
||||
"name": "@ha-components",
|
||||
"homepage": "https://hacomponents.keshuac.com",
|
||||
@@ -293,6 +329,12 @@
|
||||
"url": "https://ui.inference.sh/r/{name}.json",
|
||||
"description": "batteries-included agent components by inference.sh. chat interfaces with streaming, tool invocation rendering, syntax-highlighted code blocks, markdown renderer, and more."
|
||||
},
|
||||
{
|
||||
"name": "@indiacn",
|
||||
"homepage": "https://indiacn.in",
|
||||
"url": "https://indiacn.in/r/{name}.json",
|
||||
"description": "UX4G 2.0 design system for India — many accessible React components and an 8-color theme preset for native apps."
|
||||
},
|
||||
{
|
||||
"name": "@intentui",
|
||||
"homepage": "https://intentui.com",
|
||||
@@ -407,11 +449,17 @@
|
||||
"url": "https://motion-primitives.com/c/{name}.json",
|
||||
"description": "Beautifully designed motions components. Easy copy-paste. Customizable. Open Source. Built for engineers and designers."
|
||||
},
|
||||
{
|
||||
"name": "@nordaun",
|
||||
"homepage": "https://ui.nordaun.com",
|
||||
"url": "https://ui.nordaun.com/r/{name}.json",
|
||||
"description": "Simple components for your extraordinary creations."
|
||||
},
|
||||
{
|
||||
"name": "@ncdai",
|
||||
"homepage": "https://chanhdai.com/components",
|
||||
"url": "https://chanhdai.com/r/{name}.json",
|
||||
"description": "A collection of reusable components."
|
||||
"description": "Pixel-perfect, uniquely crafted."
|
||||
},
|
||||
{
|
||||
"name": "@nteract",
|
||||
@@ -473,6 +521,12 @@
|
||||
"url": "https://gsap.pacekit.dev/r/{name}.json",
|
||||
"description": "Animated GSAP components crafted for smooth interaction and rich detail."
|
||||
},
|
||||
{
|
||||
"name": "@paddle",
|
||||
"homepage": "https://developer.paddle.com/",
|
||||
"url": "https://developer.paddle.com/r/{name}.json",
|
||||
"description": "Drop-in components for building checkouts, pricing pages, and subscription management screens using Paddle Billing."
|
||||
},
|
||||
{
|
||||
"name": "@pastecn",
|
||||
"homepage": "https://pastecn.com",
|
||||
@@ -719,6 +773,12 @@
|
||||
"url": "https://onboarding-tour.vercel.app/r/{name}.json",
|
||||
"description": "A component for building onboarding tours. Designed to integrate with shadcn/ui."
|
||||
},
|
||||
{
|
||||
"name": "@trophy-ui",
|
||||
"homepage": "https://ui.trophy.so",
|
||||
"url": "https://ui.trophy.so/r/{name}.json",
|
||||
"description": "Open-source gamification UI components for streaks, achievements, leaderboards, points, and more. Built on shadcn/ui and Tailwind CSS."
|
||||
},
|
||||
{
|
||||
"name": "@uitripled",
|
||||
"homepage": "https://ui.tripled.work",
|
||||
@@ -833,6 +893,12 @@
|
||||
"url": "https://darshitdev.in/r/{name}.json",
|
||||
"description": "Magic 3D Tabs component featuring mouse-interactive 3D rotation, floating particles background effect, and smooth spring animations."
|
||||
},
|
||||
{
|
||||
"name": "@devl",
|
||||
"homepage": "https://devl.dev",
|
||||
"url": "https://devl.dev/r/{name}.json",
|
||||
"description": "Hand-crafted layouts and UI primitives for shipping fast."
|
||||
},
|
||||
{
|
||||
"name": "@beste-ui",
|
||||
"homepage": "https://ui.beste.co",
|
||||
@@ -1054,5 +1120,59 @@
|
||||
"homepage": "https://ui.radiumcoders.com",
|
||||
"url": "https://ui.radiumcoders.com/r/xcn/{name}.json",
|
||||
"description": "Hand-crafted, beautiful, and minimal UI components built with Tailwind CSS and Motion."
|
||||
},
|
||||
{
|
||||
"name": "@dotmatrix",
|
||||
"homepage": "https://dotmatrix.zzzzshawn.cloud",
|
||||
"url": "https://dotmatrix.zzzzshawn.cloud/r/{name}.json",
|
||||
"description": "Production-ready dot-matrix loading components for React, featuring square, circular, and triangle animations with polished motion."
|
||||
},
|
||||
{
|
||||
"name": "@delta",
|
||||
"homepage": "https://deltacomponents.dev",
|
||||
"url": "https://deltacomponents.dev/r/{name}.json",
|
||||
"description": "A shadcn registry for AI and media-rich interfaces — streaming LLM chat, zoomable images, swipeable card decks, interactive maps, plus dashboard and landing-page blocks."
|
||||
},
|
||||
{
|
||||
"name": "@shieldcn",
|
||||
"homepage": "https://shieldcn.dev",
|
||||
"url": "https://shieldcn.dev/r/{name}.json",
|
||||
"description": "Beautiful README badges as a service. A shields.io alternative with the visual quality of shadcn/ui. Drop-in SVG badge components for npm, GitHub, Discord, and more."
|
||||
},
|
||||
{
|
||||
"name": "@evilbuttons",
|
||||
"homepage": "https://evilbuttons.radiumcoders.com/docs",
|
||||
"url": "https://evilbuttons.radiumcoders.com/r/{name}.json",
|
||||
"description": "A shadcn/ui registry featuring a collection of animated buttons built with Motion. Each component is designed to add punchy, interactive feedback to your UI with minimal setup."
|
||||
},
|
||||
{
|
||||
"name": "@stepper",
|
||||
"homepage": "https://francozeta-stepper.vercel.app",
|
||||
"url": "https://francozeta-stepper.vercel.app/{name}.json",
|
||||
"description": "A modern, accessible and composable Stepper component for React and Tailwind CSS. Built for shadcn/ui-style workflows with registry-first distribution."
|
||||
},
|
||||
{
|
||||
"name": "@text-ui",
|
||||
"homepage": "https://joelachance.github.io/text-ui/docs",
|
||||
"url": "https://joelachance.github.io/text-ui/r/{name}.json",
|
||||
"description": "A shadcn/ui registry with EchoText (`echo-text`): layered stroke text that follows the pointer—minimal setup, drop-in component."
|
||||
},
|
||||
{
|
||||
"name": "@framecn",
|
||||
"homepage": "https://framecn.vercel.app",
|
||||
"url": "https://framecn.vercel.app/r/{name}.json",
|
||||
"description": "Beautiful videos, made simple. Ready to use, customizable video components for React."
|
||||
},
|
||||
{
|
||||
"name": "@turbopills-ui",
|
||||
"homepage": "https://www.turbopills.com/ui/docs",
|
||||
"url": "https://ui.turbopills.com/r/{name}.json",
|
||||
"description": "Beautiful, accessible, and customizable React components for your telehealth applications."
|
||||
},
|
||||
{
|
||||
"name": "@wensity",
|
||||
"homepage": "https://wensity.com",
|
||||
"url": "https://raw.githubusercontent.com/ksparth12/wensity-shadcn-registry/main/{name}.json",
|
||||
"description": "Motion-rich React components for AI interfaces, SaaS blocks, and cinematic interactions. Free Wensity components only."
|
||||
}
|
||||
]
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/accordion",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/accordion-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/accordion-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/accordion.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/alert-dialog",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/alert-dialog-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/alert-dialog-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/alert-dialog.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/alert",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/alert-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/alert-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/aspect-ratio",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/aspect-ratio-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/aspect-ratio-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/avatar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/avatar-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/avatar-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/avatar.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/badge",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/badge-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/badge-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/breadcrumb",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/breadcrumb-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/breadcrumb-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/button-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/button-group-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/button-group-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/button",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/button-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/button-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/calendar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/calendar-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/calendar-example.tsx",
|
||||
"api": "https://react-day-picker.js.org"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/card",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/card-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/card-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/carousel",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/carousel-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/carousel-example.tsx",
|
||||
"api": "https://www.embla-carousel.com/get-started/react"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/chart",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/chart-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/chart-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/checkbox",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/checkbox-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/checkbox-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/checkbox.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/collapsible",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/collapsible-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/collapsible-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/collapsible.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/combobox",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/combobox-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/combobox-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/combobox.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/command",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/command-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/command-example.tsx",
|
||||
"api": "https://github.com/dip/cmdk"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/context-menu",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/context-menu-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/context-menu-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/context-menu.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/dialog",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/dialog-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/dialog-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/dialog.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/drawer",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/drawer-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/drawer-example.tsx",
|
||||
"api": "https://vaul.emilkowal.ski/getting-started"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/dropdown-menu",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/dropdown-menu-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/dropdown-menu-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/menu.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/empty",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/empty-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/empty-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/field",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/field-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/field-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/hover-card",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/hover-card-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/hover-card-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/hover-card.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/input-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/input-group-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/input-group-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/input-otp",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/input-otp-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/input-otp-example.tsx",
|
||||
"api": "https://input-otp.rodz.dev"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/input",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/input-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/input-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/item",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/item-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/item-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/kbd",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/kbd-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/kbd-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/label",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/label-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/label-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/label.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/menubar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/menubar-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/menubar-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/menubar.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/native-select",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/native-select-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/native-select-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/navigation-menu",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/navigation-menu-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/navigation-menu-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/navigation-menu.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/pagination",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/pagination-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/pagination-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/popover",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/popover-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/popover-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/popover.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/progress",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/progress-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/progress-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/progress.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/radio-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/radio-group-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/radio-group-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/radio-group.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/accordion",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/accordion-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/accordion-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/accordion.md"
|
||||
}
|
||||
},
|
||||
@@ -80,7 +80,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/alert",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/alert-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/alert-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -97,7 +97,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/alert-dialog",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/alert-dialog-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/alert-dialog-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/alert-dialog.md"
|
||||
}
|
||||
},
|
||||
@@ -114,7 +114,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/aspect-ratio",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/aspect-ratio-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/aspect-ratio-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -130,7 +130,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/avatar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/avatar-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/avatar-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/avatar.md"
|
||||
}
|
||||
},
|
||||
@@ -147,7 +147,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/badge",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/badge-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/badge-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -163,7 +163,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/breadcrumb",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/breadcrumb-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/breadcrumb-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -179,7 +179,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/button",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/button-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/button-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -196,7 +196,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/button-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/button-group-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/button-group-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -214,7 +214,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/calendar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/calendar-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/calendar-example.tsx",
|
||||
"api": "https://react-day-picker.js.org"
|
||||
}
|
||||
},
|
||||
@@ -231,7 +231,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/card",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/card-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/card-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -249,7 +249,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/carousel",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/carousel-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/carousel-example.tsx",
|
||||
"api": "https://www.embla-carousel.com/get-started/react"
|
||||
}
|
||||
},
|
||||
@@ -268,7 +268,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/chart",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/chart-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/chart-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -284,7 +284,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/checkbox",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/checkbox-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/checkbox-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/checkbox.md"
|
||||
}
|
||||
},
|
||||
@@ -301,7 +301,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/collapsible",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/collapsible-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/collapsible-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/collapsible.md"
|
||||
}
|
||||
},
|
||||
@@ -320,7 +320,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/combobox",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/combobox-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/combobox-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/combobox.md"
|
||||
}
|
||||
},
|
||||
@@ -339,7 +339,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/command",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/command-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/command-example.tsx",
|
||||
"api": "https://github.com/dip/cmdk"
|
||||
}
|
||||
},
|
||||
@@ -356,7 +356,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/context-menu",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/context-menu-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/context-menu-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/context-menu.md"
|
||||
}
|
||||
},
|
||||
@@ -374,7 +374,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/dialog",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/dialog-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/dialog-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/dialog.md"
|
||||
}
|
||||
},
|
||||
@@ -392,7 +392,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/drawer",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/drawer-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/drawer-example.tsx",
|
||||
"api": "https://vaul.emilkowal.ski/getting-started"
|
||||
}
|
||||
},
|
||||
@@ -409,7 +409,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/dropdown-menu",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/dropdown-menu-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/dropdown-menu-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/menu.md"
|
||||
}
|
||||
},
|
||||
@@ -426,7 +426,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/empty",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/empty-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/empty-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -443,7 +443,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/field",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/field-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/field-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -463,7 +463,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/hover-card",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/hover-card-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/hover-card-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/hover-card.md"
|
||||
}
|
||||
},
|
||||
@@ -480,7 +480,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/input",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/input-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/input-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -497,7 +497,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/input-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/input-group-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/input-group-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -514,7 +514,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/input-otp",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/input-otp-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/input-otp-example.tsx",
|
||||
"api": "https://input-otp.rodz.dev"
|
||||
}
|
||||
},
|
||||
@@ -532,7 +532,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/item",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/item-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/item-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -548,7 +548,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/label",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/label-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/label-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/label.md"
|
||||
}
|
||||
},
|
||||
@@ -566,7 +566,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/menubar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/menubar-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/menubar-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/menubar.md"
|
||||
}
|
||||
},
|
||||
@@ -583,7 +583,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/navigation-menu",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/navigation-menu-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/navigation-menu-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/navigation-menu.md"
|
||||
}
|
||||
},
|
||||
@@ -601,7 +601,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/pagination",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/pagination-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/pagination-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -617,7 +617,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/popover",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/popover-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/popover-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/popover.md"
|
||||
}
|
||||
},
|
||||
@@ -634,7 +634,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/progress",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/progress-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/progress-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/progress.md"
|
||||
}
|
||||
},
|
||||
@@ -651,7 +651,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/radio-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/radio-group-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/radio-group-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/radio-group.md"
|
||||
}
|
||||
},
|
||||
@@ -669,7 +669,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/resizable",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/resizable-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/resizable-example.tsx",
|
||||
"api": "https://github.com/bvaughn/react-resizable-panels"
|
||||
}
|
||||
},
|
||||
@@ -686,7 +686,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/scroll-area",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/scroll-area-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/scroll-area-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/scroll-area.md"
|
||||
}
|
||||
},
|
||||
@@ -703,7 +703,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/select",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/select-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/select-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/select.md"
|
||||
}
|
||||
},
|
||||
@@ -720,7 +720,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/separator",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/separator-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/separator-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/separator.md"
|
||||
}
|
||||
},
|
||||
@@ -738,7 +738,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/sheet",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/sheet-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/sheet-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/dialog.md"
|
||||
}
|
||||
},
|
||||
@@ -764,7 +764,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/sidebar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/sidebar-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/sidebar-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -780,7 +780,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/skeleton",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/skeleton-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/skeleton-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -796,7 +796,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/slider",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/slider-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/slider-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/slider.md"
|
||||
}
|
||||
},
|
||||
@@ -814,7 +814,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/sonner",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/sonner-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/sonner-example.tsx",
|
||||
"api": "https://sonner.emilkowal.ski"
|
||||
}
|
||||
},
|
||||
@@ -831,7 +831,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/spinner",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/spinner-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/spinner-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -847,7 +847,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/switch",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/switch-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/switch-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/switch.md"
|
||||
}
|
||||
},
|
||||
@@ -864,7 +864,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/table",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/table-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/table-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -880,7 +880,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/tabs",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/tabs-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/tabs-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/tabs.md"
|
||||
}
|
||||
},
|
||||
@@ -897,7 +897,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/textarea",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/textarea-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/textarea-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -913,7 +913,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/toggle",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/toggle-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/toggle-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/toggle.md"
|
||||
}
|
||||
},
|
||||
@@ -931,7 +931,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/toggle-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/toggle-group-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/toggle-group-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/toggle-group.md"
|
||||
}
|
||||
},
|
||||
@@ -948,7 +948,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/tooltip",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/tooltip-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/tooltip-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/tooltip.md"
|
||||
}
|
||||
},
|
||||
@@ -966,7 +966,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/kbd",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/kbd-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/kbd-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
@@ -982,7 +982,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/native-select",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/native-select-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/native-select-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/resizable",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/resizable-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/resizable-example.tsx",
|
||||
"api": "https://github.com/bvaughn/react-resizable-panels"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/scroll-area",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/scroll-area-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/scroll-area-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/scroll-area.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/select",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/select-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/select-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/select.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/separator",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/separator-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/separator-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/separator.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/sheet",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/sheet-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/sheet-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/dialog.md"
|
||||
}
|
||||
},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/skeleton",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/skeleton-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/skeleton-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/slider",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/slider-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/slider-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/slider.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/sonner",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/sonner-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/sonner-example.tsx",
|
||||
"api": "https://sonner.emilkowal.ski"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/spinner",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/spinner-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/spinner-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/switch",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/switch-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/switch-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/switch.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/table",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/table-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/table-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/tabs",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/tabs-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/tabs-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/tabs.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/textarea",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/textarea-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/textarea-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/base-luma/ui/toggle-group.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Toggle as TogglePrimitive } from \"@base-ui/react/toggle\"\nimport { ToggleGroup as ToggleGroupPrimitive } from \"@base-ui/react/toggle-group\"\nimport { type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/registry/base-luma/lib/utils\"\nimport { toggleVariants } from \"@/registry/base-luma/ui/toggle\"\n\nconst ToggleGroupContext = React.createContext<\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }\n>({\n size: \"default\",\n variant: \"default\",\n spacing: 0,\n orientation: \"horizontal\",\n})\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n spacing = 0,\n orientation = \"horizontal\",\n children,\n ...props\n}: ToggleGroupPrimitive.Props &\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }) {\n return (\n <ToggleGroupPrimitive\n data-slot=\"toggle-group\"\n data-variant={variant}\n data-size={size}\n data-spacing={spacing}\n data-orientation={orientation}\n style={{ \"--gap\": spacing } as React.CSSProperties}\n className={cn(\n \"group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] data-[spacing=0]:data-[variant=outline]:rounded-3xl data-vertical:flex-col data-vertical:items-stretch\",\n className\n )}\n {...props}\n >\n <ToggleGroupContext.Provider\n value={{ variant, size, spacing, orientation }}\n >\n {children}\n </ToggleGroupContext.Provider>\n </ToggleGroupPrimitive>\n )\n}\n\nfunction ToggleGroupItem({\n className,\n children,\n variant = \"default\",\n size = \"default\",\n ...props\n}: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {\n const context = React.useContext(ToggleGroupContext)\n\n return (\n <TogglePrimitive\n data-slot=\"toggle-group-item\"\n data-variant={context.variant || variant}\n data-size={context.size || size}\n data-spacing={context.spacing}\n className={cn(\n \"shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-3 group-data-[spacing=0]/toggle-group:shadow-none focus:z-10 focus-visible:z-10 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-2.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-2.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-3xl group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-3xl group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-3xl group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-3xl data-[state=on]:bg-muted group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t\",\n toggleVariants({\n variant: context.variant || variant,\n size: context.size || size,\n }),\n className\n )}\n {...props}\n >\n {children}\n </TogglePrimitive>\n )\n}\n\nexport { ToggleGroup, ToggleGroupItem }\n",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Toggle as TogglePrimitive } from \"@base-ui/react/toggle\"\nimport { ToggleGroup as ToggleGroupPrimitive } from \"@base-ui/react/toggle-group\"\nimport { type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/registry/base-luma/lib/utils\"\nimport { toggleVariants } from \"@/registry/base-luma/ui/toggle\"\n\nconst ToggleGroupContext = React.createContext<\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }\n>({\n size: \"default\",\n variant: \"default\",\n spacing: 2,\n orientation: \"horizontal\",\n})\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n spacing = 2,\n orientation = \"horizontal\",\n children,\n ...props\n}: ToggleGroupPrimitive.Props &\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }) {\n return (\n <ToggleGroupPrimitive\n data-slot=\"toggle-group\"\n data-variant={variant}\n data-size={size}\n data-spacing={spacing}\n data-orientation={orientation}\n style={{ \"--gap\": spacing } as React.CSSProperties}\n className={cn(\n \"group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] data-[spacing=0]:data-[variant=outline]:rounded-3xl data-vertical:flex-col data-vertical:items-stretch\",\n className\n )}\n {...props}\n >\n <ToggleGroupContext.Provider\n value={{ variant, size, spacing, orientation }}\n >\n {children}\n </ToggleGroupContext.Provider>\n </ToggleGroupPrimitive>\n )\n}\n\nfunction ToggleGroupItem({\n className,\n children,\n variant = \"default\",\n size = \"default\",\n ...props\n}: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {\n const context = React.useContext(ToggleGroupContext)\n\n return (\n <TogglePrimitive\n data-slot=\"toggle-group-item\"\n data-variant={context.variant || variant}\n data-size={context.size || size}\n data-spacing={context.spacing}\n className={cn(\n \"shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-3 group-data-[spacing=0]/toggle-group:shadow-none focus:z-10 focus-visible:z-10 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-2.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-2.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-3xl group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-3xl group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-3xl group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-3xl data-[state=on]:bg-muted group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t\",\n toggleVariants({\n variant: context.variant || variant,\n size: context.size || size,\n }),\n className\n )}\n {...props}\n >\n {children}\n </TogglePrimitive>\n )\n}\n\nexport { ToggleGroup, ToggleGroupItem }\n",
|
||||
"type": "registry:ui"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/toggle-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/toggle-group-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/toggle-group-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/toggle-group.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/toggle",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/toggle-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/toggle-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/toggle.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/tooltip",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/tooltip-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/tooltip-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/tooltip.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/accordion",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/accordion-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/accordion-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/accordion.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/alert-dialog",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/alert-dialog-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/alert-dialog-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/alert-dialog.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/alert",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/alert-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/alert-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/aspect-ratio",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/aspect-ratio-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/aspect-ratio-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/avatar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/avatar-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/avatar-example.tsx",
|
||||
"api": "https://base-ui.com/react/components/avatar.md"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/badge",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/badge-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/badge-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/breadcrumb",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/breadcrumb-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/breadcrumb-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/button-group",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/button-group-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/button-group-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/button",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/button-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/button-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/calendar",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/calendar-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/calendar-example.tsx",
|
||||
"api": "https://react-day-picker.js.org"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/card",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/card-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/card-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/carousel",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/carousel-example.tsx",
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/carousel-example.tsx",
|
||||
"api": "https://www.embla-carousel.com/get-started/react"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"meta": {
|
||||
"links": {
|
||||
"docs": "https://ui.shadcn.com/docs/components/base/chart",
|
||||
"examples": "https://raw.githubusercontent.com/shadcn-ui/ui/refs/heads/main/apps/v4/registry/bases/base/examples/chart-example.tsx"
|
||||
"examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/base/examples/chart-example.tsx"
|
||||
}
|
||||
},
|
||||
"type": "registry:ui"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user