Skip to content

Commit b167137

Browse files
authored
Merge pull request #16 from sadmann7/add-masonry
feat: add masonry
2 parents f9d3482 + cd15c72 commit b167137

40 files changed

+1531
-314
lines changed

.github/setup/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ runs:
1313
version: 9.15.4
1414

1515
- run: pnpm install
16-
shell: bash
16+
shell: bash

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,4 @@ jobs:
8181
version: 9.15.4
8282
- uses: ./.github/setup
8383

84-
- run: pnpm turbo typecheck
84+
- run: pnpm turbo typecheck

.github/workflows/release.yml

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,42 +19,10 @@ jobs:
1919
steps:
2020
- name: Checkout repo
2121
uses: actions/checkout@v4
22-
with:
23-
fetch-depth: 0
24-
token: ${{ secrets.MY_GITHUB_TOKEN }}
25-
26-
- name: Setup pnpm
27-
uses: pnpm/action-setup@v4
28-
with:
29-
version: 9.15.4
30-
3122
- uses: ./.github/setup
3223

33-
- name: Setup npm
34-
run: |
35-
# Create or update .npmrc
36-
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
37-
echo "@diceui:registry=https://registry.npmjs.org/" >> ~/.npmrc
38-
npm config set access public
39-
40-
# Debug info (without exposing token)
41-
echo "--- NPM Config ---"
42-
npm config list
43-
echo "--- NPM User ---"
44-
npm whoami || echo "Not authenticated"
45-
echo "--- Registry ---"
46-
npm config get registry
47-
env:
48-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
49-
50-
- name: Format and lint
51-
run: pnpm lint:fix
52-
5324
- name: Build
54-
run: pnpm turbo build --no-cache --force
55-
env:
56-
TURBO_TOKEN: ""
57-
TURBO_TEAM: ""
25+
run: pnpm build
5826

5927
- name: Create Release
6028
id: changesets
@@ -65,4 +33,5 @@ jobs:
6533
publish: pnpm changeset publish
6634
env:
6735
GITHUB_TOKEN: ${{ secrets.MY_GITHUB_TOKEN }}
68-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
36+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
37+

docs/__registry__/index.tsx

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,22 @@ export const Index: Record<string, any> = {
5757
subcategory: "",
5858
chunks: []
5959
},
60+
"masonry": {
61+
name: "masonry",
62+
description: "",
63+
type: "registry:ui",
64+
registryDependencies: undefined,
65+
files: [{
66+
path: "registry/default/ui/masonry.tsx",
67+
type: "registry:ui",
68+
target: ""
69+
}],
70+
component: React.lazy(() => import("@/registry/default/ui/masonry.tsx")),
71+
source: "",
72+
category: "",
73+
subcategory: "",
74+
chunks: []
75+
},
6076
"mention": {
6177
name: "mention",
6278
description: "",
@@ -333,6 +349,70 @@ export const Index: Record<string, any> = {
333349
subcategory: "",
334350
chunks: []
335351
},
352+
"masonry-demo": {
353+
name: "masonry-demo",
354+
description: "",
355+
type: "registry:example",
356+
registryDependencies: undefined,
357+
files: [{
358+
path: "registry/default/example/masonry-demo.tsx",
359+
type: "registry:example",
360+
target: ""
361+
}],
362+
component: React.lazy(() => import("@/registry/default/example/masonry-demo.tsx")),
363+
source: "",
364+
category: "",
365+
subcategory: "",
366+
chunks: []
367+
},
368+
"masonry-responsive-demo": {
369+
name: "masonry-responsive-demo",
370+
description: "",
371+
type: "registry:example",
372+
registryDependencies: ["skeleton"],
373+
files: [{
374+
path: "registry/default/example/masonry-responsive-demo.tsx",
375+
type: "registry:example",
376+
target: ""
377+
}],
378+
component: React.lazy(() => import("@/registry/default/example/masonry-responsive-demo.tsx")),
379+
source: "",
380+
category: "",
381+
subcategory: "",
382+
chunks: []
383+
},
384+
"masonry-linear-demo": {
385+
name: "masonry-linear-demo",
386+
description: "",
387+
type: "registry:example",
388+
registryDependencies: ["skeleton"],
389+
files: [{
390+
path: "registry/default/example/masonry-linear-demo.tsx",
391+
type: "registry:example",
392+
target: ""
393+
}],
394+
component: React.lazy(() => import("@/registry/default/example/masonry-linear-demo.tsx")),
395+
source: "",
396+
category: "",
397+
subcategory: "",
398+
chunks: []
399+
},
400+
"masonry-ssr-demo": {
401+
name: "masonry-ssr-demo",
402+
description: "",
403+
type: "registry:example",
404+
registryDependencies: ["skeleton"],
405+
files: [{
406+
path: "registry/default/example/masonry-ssr-demo.tsx",
407+
type: "registry:example",
408+
target: ""
409+
}],
410+
component: React.lazy(() => import("@/registry/default/example/masonry-ssr-demo.tsx")),
411+
source: "",
412+
category: "",
413+
subcategory: "",
414+
chunks: []
415+
},
336416
"mention-demo": {
337417
name: "mention-demo",
338418
description: "",

docs/app/(home)/pg/page.tsx

Lines changed: 104 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { HydrationBoundary } from "@/components/hydration-boundary";
12
import { Shell } from "@/components/shell";
23
import { Button } from "@/components/ui/button";
34
import {
@@ -15,6 +16,7 @@ import {
1516
SelectTrigger,
1617
SelectValue,
1718
} from "@/components/ui/select";
19+
import { Skeleton } from "@/components/ui/skeleton";
1820
import { Textarea } from "@/components/ui/textarea";
1921
import { tricks } from "@/lib/data";
2022
import {
@@ -26,85 +28,117 @@ import {
2628
ComboboxItem,
2729
ComboboxTrigger,
2830
} from "@/registry/default/ui/combobox";
31+
import * as Masonry from "@/registry/default/ui/masonry";
2932
import * as Mention from "@diceui/mention";
3033
import { ChevronDown } from "lucide-react";
34+
import * as React from "react";
3135

3236
export default function PlaygroundPage() {
37+
const items = React.useMemo(
38+
() =>
39+
Array.from({ length: 10 }, (_, i) => ({
40+
id: i.toString(),
41+
content: `Item ${i + 1}`,
42+
height: Math.floor(Math.random() * 100) + 100,
43+
})),
44+
[],
45+
);
46+
3347
return (
3448
<Shell>
35-
<Textarea
36-
placeholder="Type here..."
37-
className="min-h-[80px] max-w-[40rem]"
38-
/>
39-
<Mention.Root className="flex max-w-[40rem] flex-col gap-2 [&_[data-tag]]:rounded [&_[data-tag]]:bg-blue-200 [&_[data-tag]]:py-px [&_[data-tag]]:text-blue-950 dark:[&_[data-tag]]:bg-blue-800 dark:[&_[data-tag]]:text-blue-50">
40-
<Mention.Label>Tricks</Mention.Label>
41-
<Mention.Input
42-
placeholder="Enter @ to mention a trick..."
43-
className="flex min-h-[80px] w-full rounded-md border border-zinc-200 bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-zinc-500 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-zinc-600 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:border-zinc-800 focus-visible:dark:ring-zinc-300"
44-
asChild
45-
>
46-
<textarea />
47-
</Mention.Input>
48-
<Mention.Portal>
49-
<Mention.Content className="data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 min-w-40 rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=closed]:animate-out data-[state=open]:animate-in">
50-
{tricks.map((trick) => (
51-
<Mention.Item
52-
key={trick.value}
53-
label={trick.label}
54-
value={trick.value}
55-
className="relative flex w-full cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50"
56-
>
57-
{trick.label}
58-
</Mention.Item>
59-
))}
60-
</Mention.Content>
61-
</Mention.Portal>
62-
</Mention.Root>
63-
<Combobox className="w-[15rem]">
64-
<ComboboxAnchor>
65-
<ComboboxInput placeholder="Search tricks..." />
66-
<ComboboxTrigger>
67-
<ChevronDown className="h-4 w-4" />
68-
</ComboboxTrigger>
69-
</ComboboxAnchor>
70-
<ComboboxContent>
71-
<ComboboxEmpty>No tricks found</ComboboxEmpty>
72-
{tricks.map((trick) => (
73-
<ComboboxItem key={trick.value} value={trick.value}>
74-
{trick.label}
75-
</ComboboxItem>
76-
))}
77-
</ComboboxContent>
78-
</Combobox>
79-
<DropdownMenu>
80-
<DropdownMenuTrigger asChild>
81-
<Button variant="outline" size="sm" className="w-fit">
82-
Open
83-
</Button>
84-
</DropdownMenuTrigger>
85-
<DropdownMenuContent align="start">
86-
<DropdownMenuItem>Apple</DropdownMenuItem>
87-
<DropdownMenuItem>Banana</DropdownMenuItem>
88-
<DropdownMenuItem>Blueberry</DropdownMenuItem>
89-
<DropdownMenuItem>Grapes</DropdownMenuItem>
90-
<DropdownMenuItem>Pineapple</DropdownMenuItem>
91-
</DropdownMenuContent>
92-
</DropdownMenu>
93-
<Select>
94-
<SelectTrigger className="w-[11.25rem]">
95-
<SelectValue placeholder="Select a trick" />
96-
</SelectTrigger>
97-
<SelectContent>
98-
<SelectGroup>
99-
<SelectLabel>Tricks</SelectLabel>
49+
<Masonry.Root
50+
columnCount={{ initial: 1, md: 2, lg: 4 }}
51+
defaultColumnCount={4}
52+
gap={16}
53+
>
54+
{items.map((item) => (
55+
<Masonry.Item
56+
key={item.id}
57+
fallback={<Skeleton className="w-full" style={{ height: 160 }} />}
58+
className="rounded-lg border bg-card p-4 text-card-foreground shadow"
59+
style={{
60+
height: item.height,
61+
}}
62+
>
63+
{item.content}
64+
</Masonry.Item>
65+
))}
66+
</Masonry.Root>
67+
<HydrationBoundary fallback={<Skeleton className="h-svh w-full" />}>
68+
<Textarea
69+
placeholder="Type here..."
70+
className="min-h-[80px] max-w-[40rem]"
71+
/>
72+
<Mention.Root className="flex max-w-[40rem] flex-col gap-2 [&_[data-tag]]:rounded [&_[data-tag]]:bg-blue-200 [&_[data-tag]]:py-px [&_[data-tag]]:text-blue-950 dark:[&_[data-tag]]:bg-blue-800 dark:[&_[data-tag]]:text-blue-50">
73+
<Mention.Label>Tricks</Mention.Label>
74+
<Mention.Input
75+
placeholder="Enter @ to mention a trick..."
76+
className="flex min-h-[80px] w-full rounded-md border border-zinc-200 bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-zinc-500 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-zinc-600 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:border-zinc-800 focus-visible:dark:ring-zinc-300"
77+
asChild
78+
>
79+
<textarea />
80+
</Mention.Input>
81+
<Mention.Portal>
82+
<Mention.Content className="data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 min-w-40 rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=closed]:animate-out data-[state=open]:animate-in">
83+
{tricks.map((trick) => (
84+
<Mention.Item
85+
key={trick.value}
86+
label={trick.label}
87+
value={trick.value}
88+
className="relative flex w-full cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50"
89+
>
90+
{trick.label}
91+
</Mention.Item>
92+
))}
93+
</Mention.Content>
94+
</Mention.Portal>
95+
</Mention.Root>
96+
<Combobox className="w-[15rem]">
97+
<ComboboxAnchor>
98+
<ComboboxInput placeholder="Search tricks..." />
99+
<ComboboxTrigger>
100+
<ChevronDown className="h-4 w-4" />
101+
</ComboboxTrigger>
102+
</ComboboxAnchor>
103+
<ComboboxContent>
104+
<ComboboxEmpty>No tricks found</ComboboxEmpty>
100105
{tricks.map((trick) => (
101-
<SelectItem key={trick.value} value={trick.value}>
106+
<ComboboxItem key={trick.value} value={trick.value}>
102107
{trick.label}
103-
</SelectItem>
108+
</ComboboxItem>
104109
))}
105-
</SelectGroup>
106-
</SelectContent>
107-
</Select>
110+
</ComboboxContent>
111+
</Combobox>
112+
<DropdownMenu>
113+
<DropdownMenuTrigger asChild>
114+
<Button variant="outline" size="sm" className="w-fit">
115+
Open
116+
</Button>
117+
</DropdownMenuTrigger>
118+
<DropdownMenuContent align="start">
119+
<DropdownMenuItem>Apple</DropdownMenuItem>
120+
<DropdownMenuItem>Banana</DropdownMenuItem>
121+
<DropdownMenuItem>Blueberry</DropdownMenuItem>
122+
<DropdownMenuItem>Grapes</DropdownMenuItem>
123+
<DropdownMenuItem>Pineapple</DropdownMenuItem>
124+
</DropdownMenuContent>
125+
</DropdownMenu>
126+
<Select>
127+
<SelectTrigger className="w-[11.25rem]">
128+
<SelectValue placeholder="Select a trick" />
129+
</SelectTrigger>
130+
<SelectContent>
131+
<SelectGroup>
132+
<SelectLabel>Tricks</SelectLabel>
133+
{tricks.map((trick) => (
134+
<SelectItem key={trick.value} value={trick.value}>
135+
{trick.label}
136+
</SelectItem>
137+
))}
138+
</SelectGroup>
139+
</SelectContent>
140+
</Select>
141+
</HydrationBoundary>
108142
</Shell>
109143
);
110144
}

docs/app/layout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Providers } from "@/components/providers";
2+
import { TailwindIndicator } from "@/components/tailwind-indicator";
23
import { Toaster } from "@/components/ui/sonner";
34
import { siteConfig } from "@/config/site";
45
import { fontMono, fontSans } from "@/lib/fonts";
@@ -73,6 +74,8 @@ export default function RootLayout({ children }: RootLayoutProps) {
7374
data-site-id="diceui.com"
7475
src="https://assets.onedollarstats.com/tracker.js"
7576
/>
77+
<TailwindIndicator />
78+
<Toaster />
7679
<Providers
7780
theme={{
7881
attribute: "class",
@@ -83,7 +86,6 @@ export default function RootLayout({ children }: RootLayoutProps) {
8386
>
8487
{children}
8588
</Providers>
86-
<Toaster />
8789
</body>
8890
</html>
8991
);

0 commit comments

Comments
 (0)