Skip to content

Commit 7fbdebb

Browse files
committed
Merge remote-tracking branch 'origin/upstream'
2 parents 4d8d2ad + a2244d4 commit 7fbdebb

File tree

16 files changed

+668
-807
lines changed

16 files changed

+668
-807
lines changed

apps/v4/app/layout.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Metadata } from "next"
2+
import { NuqsAdapter } from "nuqs/adapters/next/app"
23

34
import { META_THEME_COLORS, siteConfig } from "@/lib/config"
45
import { fontVariables } from "@/lib/fonts"
@@ -91,12 +92,14 @@ export default function RootLayout({
9192
>
9293
<ThemeProvider>
9394
<LayoutProvider>
94-
<ActiveThemeProvider>
95-
{children}
96-
<TailwindIndicator />
97-
<Toaster position="top-center" />
98-
<Analytics />
99-
</ActiveThemeProvider>
95+
<NuqsAdapter>
96+
<ActiveThemeProvider>
97+
{children}
98+
<TailwindIndicator />
99+
<Toaster position="top-center" />
100+
<Analytics />
101+
</ActiveThemeProvider>
102+
</NuqsAdapter>
100103
</LayoutProvider>
101104
</ThemeProvider>
102105
</body>
Lines changed: 68 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
"use client"
2+
13
import * as React from "react"
24
import { IconArrowUpRight } from "@tabler/icons-react"
35

6+
import { useSearchRegistry } from "@/hooks/use-search-registry"
47
import { DirectoryAddButton } from "@/components/directory-add-button"
5-
import registries from "@/registry/directory.json"
8+
import globalRegistries from "@/registry/directory.json"
69
import { Button } from "@/registry/new-york-v4/ui/button"
710
import {
811
Item,
@@ -16,55 +19,72 @@ import {
1619
ItemTitle,
1720
} from "@/registry/new-york-v4/ui/item"
1821

22+
import { SearchDirectory } from "./search-directory"
23+
24+
function getHomepageUrl(homepage: string) {
25+
const url = new URL(homepage)
26+
url.searchParams.set("utm_source", "ui.shadcn.com")
27+
url.searchParams.set("utm_medium", "referral")
28+
url.searchParams.set("utm_campaign", "directory")
29+
return url.toString()
30+
}
31+
1932
export function DirectoryList() {
33+
const { registries } = useSearchRegistry()
34+
2035
return (
21-
<ItemGroup className="my-8">
22-
{registries.map((registry, index) => (
23-
<React.Fragment key={index}>
24-
<Item className="group/item relative gap-6 px-0 sm:px-4">
25-
<ItemMedia
26-
variant="image"
27-
dangerouslySetInnerHTML={{ __html: registry.logo }}
28-
className="*:[svg]:fill-foreground grayscale *:[svg]:size-8"
29-
/>
30-
<ItemContent>
31-
<ItemTitle>
32-
<a
33-
href={registry.homepage}
34-
target="_blank"
35-
rel="noopener noreferrer"
36-
>
37-
{registry.name}
38-
</a>
39-
</ItemTitle>
40-
{registry.description && (
41-
<ItemDescription className="text-pretty">
42-
{registry.description}
43-
</ItemDescription>
44-
)}
45-
</ItemContent>
46-
<ItemActions className="relative z-10 hidden self-start sm:flex">
47-
<Button size="sm" variant="outline" asChild>
48-
<a
49-
href={registry.homepage}
50-
target="_blank"
51-
rel="noopener noreferrer"
52-
>
36+
<div className="mt-6">
37+
<SearchDirectory />
38+
<ItemGroup className="my-8">
39+
{registries.map((registry, index) => (
40+
<React.Fragment key={index}>
41+
<Item className="group/item relative gap-6 px-0">
42+
<ItemMedia
43+
variant="image"
44+
dangerouslySetInnerHTML={{ __html: registry.logo }}
45+
className="*:[svg]:fill-foreground grayscale *:[svg]:size-8"
46+
/>
47+
<ItemContent>
48+
<ItemTitle>
49+
<a
50+
href={getHomepageUrl(registry.homepage)}
51+
target="_blank"
52+
rel="noopener noreferrer external"
53+
>
54+
{registry.name}
55+
</a>
56+
</ItemTitle>
57+
{registry.description && (
58+
<ItemDescription className="text-pretty">
59+
{registry.description}
60+
</ItemDescription>
61+
)}
62+
</ItemContent>
63+
<ItemActions className="relative z-10 hidden self-start sm:flex">
64+
<Button size="sm" variant="outline" asChild>
65+
<a
66+
href={getHomepageUrl(registry.homepage)}
67+
target="_blank"
68+
rel="noopener noreferrer external"
69+
>
70+
View <IconArrowUpRight />
71+
</a>
72+
</Button>
73+
<DirectoryAddButton registry={registry} />
74+
</ItemActions>
75+
<ItemFooter className="justify-start pl-16 sm:hidden">
76+
<Button size="sm" variant="outline">
5377
View <IconArrowUpRight />
54-
</a>
55-
</Button>
56-
<DirectoryAddButton registry={registry} />
57-
</ItemActions>
58-
<ItemFooter className="justify-start pl-16 sm:hidden">
59-
<Button size="sm" variant="outline">
60-
View <IconArrowUpRight />
61-
</Button>
62-
<DirectoryAddButton registry={registry} />
63-
</ItemFooter>
64-
</Item>
65-
{index < registries.length - 1 && <ItemSeparator className="my-1" />}
66-
</React.Fragment>
67-
))}
68-
</ItemGroup>
78+
</Button>
79+
<DirectoryAddButton registry={registry} />
80+
</ItemFooter>
81+
</Item>
82+
{index < globalRegistries.length - 1 && (
83+
<ItemSeparator className="my-1" />
84+
)}
85+
</React.Fragment>
86+
))}
87+
</ItemGroup>
88+
</div>
6989
)
7090
}

apps/v4/components/github-link.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,20 @@ export function GitHubLink() {
2121

2222
export async function StarsCount() {
2323
const data = await fetch("https://api.github.com/repos/shadcn-ui/ui", {
24-
next: { revalidate: 86400 }, // Cache for 1 day (86400 seconds)
24+
next: { revalidate: 86400 },
2525
})
2626
const json = await data.json()
2727

28+
const formattedCount =
29+
json.stargazers_count >= 1000
30+
? json.stargazers_count % 1000 === 0
31+
? `${Math.floor(json.stargazers_count / 1000)}k`
32+
: `${(json.stargazers_count / 1000).toFixed(1)}k`
33+
: json.stargazers_count.toLocaleString()
34+
2835
return (
29-
<span className="text-muted-foreground w-8 text-xs tabular-nums">
30-
{json.stargazers_count >= 1000
31-
? `${(json.stargazers_count / 1000).toFixed(1)}k`
32-
: json.stargazers_count.toLocaleString()}
36+
<span className="text-muted-foreground w-fit text-xs tabular-nums">
37+
{formattedCount.replace(".0k", "k")}
3338
</span>
3439
)
3540
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import * as React from "react"
2+
import { Search, X } from "lucide-react"
3+
4+
import { useSearchRegistry } from "@/hooks/use-search-registry"
5+
import { Field } from "@/registry/new-york-v4/ui/field"
6+
import {
7+
InputGroup,
8+
InputGroupAddon,
9+
InputGroupButton,
10+
InputGroupInput,
11+
} from "@/registry/new-york-v4/ui/input-group"
12+
13+
export const SearchDirectory = () => {
14+
const { query, setQuery } = useSearchRegistry()
15+
16+
const onQueryChange = (e: React.ChangeEvent<HTMLInputElement>) => {
17+
const value = e.target.value
18+
setQuery(value)
19+
}
20+
21+
return (
22+
<Field>
23+
<InputGroup>
24+
<InputGroupAddon>
25+
<Search />
26+
</InputGroupAddon>
27+
<InputGroupInput
28+
placeholder="Search"
29+
value={query}
30+
onChange={onQueryChange}
31+
/>
32+
<InputGroupAddon
33+
align="inline-end"
34+
data-disabled={!query.length}
35+
className="data-[disabled=true]:hidden"
36+
>
37+
<InputGroupButton
38+
aria-label="Clear"
39+
title="Clear"
40+
size="icon-xs"
41+
onClick={() => setQuery(null)}
42+
>
43+
<X />
44+
</InputGroupButton>
45+
</InputGroupAddon>
46+
</InputGroup>
47+
</Field>
48+
)
49+
}

apps/v4/content/docs/components/chart.mdx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ component: true
3131
```tsx showLineNumbers /ChartContainer/ /ChartTooltipContent/
3232
import { Bar, BarChart } from "recharts"
3333

34-
import { ChartContainer, ChartTooltipContent } from "@/components/ui/charts"
34+
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
3535

3636
export function MyChart() {
3737
return (
@@ -193,7 +193,7 @@ const chartConfig = {
193193

194194
<Callout className="mt-4 bg-amber-50 border-amber-200 dark:bg-amber-950/50 dark:border-amber-950">
195195

196-
**重要** 记得为 `ChartContainer` 组件设置一个 `min-h-[值]`,这是实现图表响应式所必需的
196+
**重要提示**请记得在 `ChartContainer` 组件上设置 `min-h-[VALUE]`。这是让图表具备响应式所必需的
197197

198198
</Callout>
199199

@@ -366,11 +366,11 @@ import { ChartLegend, ChartLegendContent } from "@/components/ui/chart"
366366

367367
## 图表配置
368368

369-
图表配置是定义图表标签、图标和颜色的地方
369+
图表配置用于定义图表的标签、图标和颜色
370370

371-
它刻意与图表数据解耦
371+
它有意与图表数据分离
372372

373-
这样您可以在多个图表间共享配置和颜色令牌。它也能独立工作,适用于数据或颜色令牌存储在远程或不同格式的场景
373+
这样可以在多个图表之间共享配置和颜色标记。对于数据或颜色标记存储在远程或不同格式的情况,也可以独立工作
374374

375375
```tsx showLineNumbers /ChartConfig/
376376
import { Monitor } from "lucide-react"
@@ -394,7 +394,7 @@ const chartConfig = {
394394

395395
## 主题定制
396396

397-
Charts 支持内置主题。您可以使用 CSS 变量(推荐)或者任何格式的颜色值,如 hex、hsl 或 oklch。
397+
图表内置了主题支持。你可以使用 CSS 变量(推荐)或任何颜色格式的颜色值,如 hex、hsl 或 oklch。
398398

399399
### CSS 变量
400400

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { debounce, useQueryState } from "nuqs"
2+
3+
import globalRegistries from "@/registry/directory.json"
4+
5+
const normalizeQuery = (query: string) =>
6+
query.toLowerCase().replaceAll(" ", "").replaceAll("@", "")
7+
8+
function finderFn<T extends (typeof globalRegistries)[0]>(
9+
registry: T,
10+
query: string
11+
) {
12+
const normalizedName = normalizeQuery(registry.name)
13+
const normalizedDecription = normalizeQuery(registry.description)
14+
const normalizedQuery = normalizeQuery(query)
15+
16+
return (
17+
normalizedName.includes(normalizedQuery) ||
18+
normalizedDecription.includes(normalizedQuery)
19+
)
20+
}
21+
22+
const searchDirectory = (query: string | null) => {
23+
if (!query) return globalRegistries
24+
25+
return globalRegistries.filter((registry) => finderFn(registry, query))
26+
}
27+
28+
export const useSearchRegistry = () => {
29+
const [query, setQuery] = useQueryState("q", {
30+
defaultValue: "",
31+
limitUrlUpdates: debounce(250),
32+
})
33+
34+
return {
35+
query,
36+
registries: searchDirectory(query),
37+
setQuery,
38+
}
39+
}

apps/v4/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"@faker-js/faker": "^10.1.0",
2626
"@hookform/resolvers": "^3.10.0",
2727
"@radix-ui/react-accessible-icon": "^1.1.1",
28-
"@radix-ui/react-accordion": "^1.2.2",
28+
"@radix-ui/react-accordion": "^1.2.12",
2929
"@radix-ui/react-alert-dialog": "^1.1.5",
3030
"@radix-ui/react-aspect-ratio": "^1.1.1",
3131
"@radix-ui/react-avatar": "^1.1.2",
@@ -51,9 +51,9 @@
5151
"@radix-ui/react-switch": "^1.1.2",
5252
"@radix-ui/react-tabs": "^1.1.2",
5353
"@radix-ui/react-toast": "^1.2.5",
54-
"@radix-ui/react-toggle": "^1.1.1",
54+
"@radix-ui/react-toggle": "^1.1.10",
5555
"@radix-ui/react-toggle-group": "^1.1.1",
56-
"@radix-ui/react-tooltip": "^1.1.7",
56+
"@radix-ui/react-tooltip": "^1.2.8",
5757
"@tabler/icons-react": "^3.31.0",
5858
"@tailwindcss/postcss": "^4.1.11",
5959
"@tanstack/react-form": "^1.20.0",
@@ -80,6 +80,7 @@
8080
"motion": "^12.12.1",
8181
"next": "16.0.0",
8282
"next-themes": "0.4.6",
83+
"nuqs": "^2.7.2",
8384
"postcss": "^8.5.1",
8485
"react": "19.2.0",
8586
"react-day-picker": "^9.7.0",

apps/v4/public/r/registries.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"@8bitcn": "https://8bitcn.com/r/{name}.json",
33
"@97cn": "https://97cn.itzik.co/r/{name}.json",
44
"@aceternity": "https://ui.aceternity.com/registry/{name}.json",
5+
"@aevr": "https://ui.aevr.space/r/{name}.json",
56
"@ai-elements": "https://registry.ai-sdk.dev/{name}.json",
67
"@alexcarpenter": "https://ui.alexcarpenter.me/r/{name}.json",
78
"@algolia": "https://sitesearch.algolia.com/r/{name}.json",
@@ -17,6 +18,7 @@
1718
"@bucharitesh": "https://bucharitesh.in/r/{name}.json",
1819
"@clerk": "https://clerk.com/r/{name}.json",
1920
"@coss": "https://coss.com/ui/r/{name}.json",
21+
"@commercn": "https://commercn.com/r/{name}.json",
2022
"@chisom-ui": "https://chisom-ui.netlify.app/r/{name}.json",
2123
"@creative-tim": "https://www.creative-tim.com/ui/r/{name}.json",
2224
"@cult-ui": "https://cult-ui.com/r/{name}.json",
@@ -39,11 +41,13 @@
3941
"@magicui": "https://magicui.design/r/{name}.json",
4042
"@magicui-pro": "https://pro.magicui.design/registry/{name}",
4143
"@motion-primitives": "https://motion-primitives.com/c/{name}.json",
44+
"@mui-treasury": "https://mui-treasury.com/r/{name}.json",
4245
"@nativeui": "https://nativeui.io/registry/{name}.json",
4346
"@ncdai": "https://chanhdai.com/r/{name}.json",
4447
"@nuqs": "https://nuqs.dev/r/{name}.json",
4548
"@oui": "https://oui.mw10013.workers.dev/r/{name}.json",
4649
"@paceui": "https://ui.paceui.com/r/{name}.json",
50+
"@plate": "https://platejs.org/r/{name}.json",
4751
"@prompt-kit": "https://prompt-kit.com/c/{name}.json",
4852
"@prosekit": "https://prosekit.dev/r/{name}.json",
4953
"@react-bits": "https://reactbits.dev/r/{name}.json",
@@ -54,10 +58,12 @@
5458
"@roiui": "https://roiui.com/r/{name}.json",
5559
"@solaceui": "https://www.solaceui.com/r/{name}.json",
5660
"@scrollxui": "https://www.scrollxui.dev/registry/{name}.json",
61+
"@systaliko-ui": "https://systaliko-ui.vercel.app/r/{name}.json",
5762
"@shadcn-editor": "https://shadcn-editor.vercel.app/r/{name}.json",
5863
"@shadcn-map": "http://shadcn-map.vercel.app/r/{name}.json",
5964
"@shadcn-studio": "https://shadcnstudio.com/r/{name}.json",
6065
"@shadcnblocks": "https://shadcnblocks.com/r/{name}.json",
66+
"@shadcnui-blocks": "https://shadcnui-blocks.com/r/{name}.json",
6167
"@simple-ai": "https://simple-ai.dev/r/{name}.json",
6268
"@skiper-ui": "https://skiper-ui.com/registry/{name}.json",
6369
"@skyr": "https://ui-play.skyroc.me/r/{name}.json",
@@ -76,5 +82,8 @@
7682
"@shadcndesign": "https://shadcndesign-free.vercel.app/r/{name}.json",
7783
"@ha-components": "https://hacomponents.keshuac.com/r/{name}.json",
7884
"@shadix-ui": "https://shadix-ui.vercel.app/r/{name}.json",
79-
"@utilcn": "https://utilcn.dev/r/{name}.json"
85+
"@utilcn": "https://utilcn.dev/r/{name}.json",
86+
"@hextaui": "https://hextaui.com/r/{name}.json",
87+
"@taki": "https://taki-ui.com/r/{name}.json",
88+
"@square-ui": "https://square.lndev.me/registry/{name}.json"
8089
}

0 commit comments

Comments
 (0)