1+ import { ReactNode } from "react" ;
12import { OpenInV0Button } from "@/components/open-in-v0-button" ;
23import { HelloWorld } from "@/registry/new-york/blocks/hello-world/hello-world" ;
34import { ExampleForm } from "@/registry/new-york/blocks/example-form/example-form" ;
@@ -18,6 +19,28 @@ import { SearchableInputExample } from "@/registry/new-york/blocks/searchable-in
1819// This page displays items from the custom registry.
1920// You are free to implement this with your own design as needed.
2021
22+ const ComponentCard = ( {
23+ name,
24+ description,
25+ children,
26+ minHeight = "min-h-[400px]" ,
27+ } : {
28+ name : string ;
29+ description : string ;
30+ children : ReactNode ;
31+ minHeight ?: string ;
32+ } ) => (
33+ < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
34+ < div className = "flex items-center justify-between" >
35+ < h2 className = "text-sm text-muted-foreground sm:pl-3" > { description } </ h2 >
36+ < OpenInV0Button name = { name } className = "w-fit" />
37+ </ div >
38+ < div className = { `flex items-center justify-center ${ minHeight } relative` } >
39+ { children }
40+ </ div >
41+ </ div >
42+ ) ;
43+
2144export default function Home ( ) {
2245 return (
2346 < div className = "max-w-3xl mx-auto flex flex-col min-h-svh px-4 py-8 gap-8" >
@@ -28,206 +51,118 @@ export default function Home() {
2851 </ p >
2952 </ header >
3053 < main className = "flex flex-col flex-1 gap-8" >
31- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
32- < div className = "flex items-center justify-between" >
33- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
34- A simple hello world component
35- </ h2 >
36- < OpenInV0Button name = "hello-world" className = "w-fit" />
37- </ div >
38- < div className = "flex items-center justify-center min-h-[400px] relative" >
39- < HelloWorld />
40- </ div >
41- </ div >
42-
43- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
44- < div className = "flex items-center justify-between" >
45- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
46- A contact form with Zod validation.
47- </ h2 >
48- < OpenInV0Button name = "example-form" className = "w-fit" />
49- </ div >
50- < div className = "flex items-center justify-center min-h-[500px] relative" >
51- < ExampleForm />
52- </ div >
53- </ div >
54-
55- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
56- < div className = "flex items-center justify-between" >
57- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
58- A complex component showing hooks, libs and components.
59- </ h2 >
60- < OpenInV0Button name = "complex-component" className = "w-fit" />
61- </ div >
62- < div className = "flex items-center justify-center min-h-[400px] relative" >
63- < PokemonPage />
64- </ div >
65- </ div >
66-
67- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
68- < div className = "flex items-center justify-between" >
69- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
70- A login form with a CSS file.
71- </ h2 >
72- < OpenInV0Button name = "example-with-css" className = "w-fit" />
73- </ div >
74- < div className = "flex items-center justify-center min-h-[400px] relative" >
75- < ExampleCard />
76- </ div >
77- </ div >
78-
79- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
80- < div className = "flex items-center justify-between" >
81- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
82- A component for displaying a list of badges with optional click
83- and delete handlers.
84- </ h2 >
85- < OpenInV0Button name = "badge-bar" className = "w-fit" />
86- </ div >
87- < div className = "flex items-center justify-center min-h-[400px] relative" >
88- < BadgeBarExample />
89- </ div >
90- </ div >
91-
92- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
93- < div className = "flex items-center justify-between" >
94- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
95- A pagination component with page size and page index controls.
96- </ h2 >
97- < OpenInV0Button name = "pager" className = "w-fit" />
98- </ div >
99- < div className = "flex items-center justify-center min-h-[400px] relative" >
100- < PagerExample />
101- </ div >
102- </ div >
103-
104- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
105- < div className = "flex items-center justify-between" >
106- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
107- An image preview component with modal viewing and download
108- functionality.
109- </ h2 >
110- < OpenInV0Button name = "image-preview" className = "w-fit" />
111- </ div >
112- < div className = "flex items-center justify-center min-h-[400px] relative" >
113- < ImagePreviewExample />
114- </ div >
115- </ div >
116-
117- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
118- < div className = "flex items-center justify-between" >
119- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
120- A file preview component supporting images, audio, video, and
121- documents.
122- </ h2 >
123- < OpenInV0Button name = "file-preview" className = "w-fit" />
124- </ div >
125- < div className = "flex items-center justify-center min-h-[400px] relative" >
126- < FilePreviewExample />
127- </ div >
128- </ div >
129-
130- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
131- < div className = "flex items-center justify-between" >
132- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
133- A component that detects when scroll reaches edges using
134- IntersectionObserver.
135- </ h2 >
136- < OpenInV0Button name = "scroll-boundary" className = "w-fit" />
137- </ div >
138- < div className = "flex items-center justify-center min-h-[400px] relative" >
139- < ScrollBoundaryExample />
140- </ div >
141- </ div >
142-
143- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
144- < div className = "flex items-center justify-between" >
145- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
146- An infinite scroll list component using MobX for state management.
147- </ h2 >
148- < OpenInV0Button name = "scroll-list" className = "w-fit" />
149- </ div >
150- < div className = "flex items-center justify-center min-h-[400px] relative" >
151- < ScrollListExample />
152- </ div >
153- </ div >
154-
155- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
156- < div className = "flex items-center justify-between" >
157- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
158- A dynamic array field component with add/remove functionality for
159- form arrays.
160- </ h2 >
161- < OpenInV0Button name = "array-field" className = "w-fit" />
162- </ div >
163- < div className = "flex items-center justify-center min-h-[400px] relative" >
164- < ArrayFieldExample />
165- </ div >
166- </ div >
167-
168- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
169- < div className = "flex items-center justify-between" >
170- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
171- An input component that displays values as removable badges,
172- supporting multiple entries.
173- </ h2 >
174- < OpenInV0Button name = "badge-input" className = "w-fit" />
175- </ div >
176- < div className = "flex items-center justify-center min-h-[400px] relative" >
177- < BadgeInputExample />
178- </ div >
179- </ div >
180-
181- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
182- < div className = "flex items-center justify-between" >
183- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
184- A range slider input with optional custom icon display for each
185- step.
186- </ h2 >
187- < OpenInV0Button name = "range-input" className = "w-fit" />
188- </ div >
189- < div className = "flex items-center justify-center min-h-[400px] relative" >
190- < RangeInputExample />
191- </ div >
192- </ div >
193-
194- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
195- < div className = "flex items-center justify-between" >
196- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
197- A file picker component with preview and remove functionality.
198- </ h2 >
199- < OpenInV0Button name = "file-picker" className = "w-fit" />
200- </ div >
201- < div className = "flex items-center justify-center min-h-[400px] relative" >
202- < FilePickerExample />
203- </ div >
204- </ div >
205-
206- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
207- < div className = "flex items-center justify-between" >
208- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
209- A unified form field component supporting input, textarea, and
210- select elements with labels.
211- </ h2 >
212- < OpenInV0Button name = "form-field" className = "w-fit" />
213- </ div >
214- < div className = "flex items-center justify-center min-h-[400px] relative" >
215- < FormFieldExample />
216- </ div >
217- </ div >
218-
219- < div className = "flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative" >
220- < div className = "flex items-center justify-between" >
221- < h2 className = "text-sm text-muted-foreground sm:pl-3" >
222- A searchable select input with badge display, supporting single or
223- multiple selection.
224- </ h2 >
225- < OpenInV0Button name = "searchable-input" className = "w-fit" />
226- </ div >
227- < div className = "flex items-center justify-center min-h-[400px] relative" >
228- < SearchableInputExample />
229- </ div >
230- </ div >
54+ < ComponentCard
55+ name = "hello-world"
56+ description = "A simple hello world component"
57+ >
58+ < HelloWorld />
59+ </ ComponentCard >
60+
61+ < ComponentCard
62+ name = "example-form"
63+ description = "A contact form with Zod validation."
64+ minHeight = "min-h-[500px]"
65+ >
66+ < ExampleForm />
67+ </ ComponentCard >
68+
69+ < ComponentCard
70+ name = "complex-component"
71+ description = "A complex component showing hooks, libs and components."
72+ >
73+ < PokemonPage />
74+ </ ComponentCard >
75+
76+ < ComponentCard
77+ name = "example-with-css"
78+ description = "A login form with a CSS file."
79+ >
80+ < ExampleCard />
81+ </ ComponentCard >
82+
83+ < ComponentCard
84+ name = "badge-bar"
85+ description = "A component for displaying a list of badges with optional click and delete handlers."
86+ >
87+ < BadgeBarExample />
88+ </ ComponentCard >
89+
90+ < ComponentCard
91+ name = "pager"
92+ description = "A pagination component with page size and page index controls."
93+ >
94+ < PagerExample />
95+ </ ComponentCard >
96+
97+ < ComponentCard
98+ name = "image-preview"
99+ description = "An image preview component with modal viewing and download functionality."
100+ >
101+ < ImagePreviewExample />
102+ </ ComponentCard >
103+
104+ < ComponentCard
105+ name = "file-preview"
106+ description = "A file preview component supporting images, audio, video, and documents."
107+ >
108+ < FilePreviewExample />
109+ </ ComponentCard >
110+
111+ < ComponentCard
112+ name = "scroll-boundary"
113+ description = "A component that detects when scroll reaches edges using IntersectionObserver."
114+ >
115+ < ScrollBoundaryExample />
116+ </ ComponentCard >
117+
118+ < ComponentCard
119+ name = "scroll-list"
120+ description = "An infinite scroll list component using MobX for state management."
121+ >
122+ < ScrollListExample />
123+ </ ComponentCard >
124+
125+ < ComponentCard
126+ name = "array-field"
127+ description = "A dynamic array field component with add/remove functionality for form arrays."
128+ >
129+ < ArrayFieldExample />
130+ </ ComponentCard >
131+
132+ < ComponentCard
133+ name = "badge-input"
134+ description = "An input component that displays values as removable badges, supporting multiple entries."
135+ >
136+ < BadgeInputExample />
137+ </ ComponentCard >
138+
139+ < ComponentCard
140+ name = "range-input"
141+ description = "A range slider input with optional custom icon display for each step."
142+ >
143+ < RangeInputExample />
144+ </ ComponentCard >
145+
146+ < ComponentCard
147+ name = "file-picker"
148+ description = "A file picker component with preview and remove functionality."
149+ >
150+ < FilePickerExample />
151+ </ ComponentCard >
152+
153+ < ComponentCard
154+ name = "form-field"
155+ description = "A unified form field component supporting input, textarea, and select elements with labels."
156+ >
157+ < FormFieldExample />
158+ </ ComponentCard >
159+
160+ < ComponentCard
161+ name = "searchable-input"
162+ description = "A searchable select input with badge display, supporting single or multiple selection."
163+ >
164+ < SearchableInputExample />
165+ </ ComponentCard >
231166 </ main >
232167 </ div >
233168 ) ;
0 commit comments