Skip to content

Commit 1bb20fc

Browse files
CopilotTechQuery
andauthored
[add] 6 simple MobX-RESTful components with Shadcn UI registry patterns (#2)
Co-authored-by: South Drifter <[email protected]>
1 parent 29ee1c7 commit 1bb20fc

File tree

24 files changed

+3466
-1222
lines changed

24 files changed

+3466
-1222
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,7 @@ yarn-error.log*
3939
# typescript
4040
*.tsbuildinfo
4141
next-env.d.ts
42+
43+
# Shadcn UI components
44+
components/.stash/
45+
components/ui/*

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
auto-install-peers = false

app/globals.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
}
4545

4646
:root {
47+
--font-geist-sans: 'Geist Sans', ui-sans-serif, system-ui, sans-serif;
48+
--font-geist-mono: 'Geist Mono', ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace;
4749
--radius: 0.625rem;
4850
--background: oklch(1 0 0);
4951
--foreground: oklch(0.145 0 0);

app/layout.tsx

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
import type { Metadata } from "next";
2-
import { Geist, Geist_Mono } from "next/font/google";
32
import "./globals.css";
43

5-
const geistSans = Geist({
6-
variable: "--font-geist-sans",
7-
subsets: ["latin"],
8-
});
9-
10-
const geistMono = Geist_Mono({
11-
variable: "--font-geist-mono",
12-
subsets: ["latin"],
13-
});
14-
154
export const metadata: Metadata = {
165
title: "Create Next App",
176
description: "Generated by create next app",
@@ -24,9 +13,15 @@ export default function RootLayout({
2413
}>) {
2514
return (
2615
<html lang="en">
27-
<body
28-
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
29-
>
16+
<head>
17+
<link rel="preconnect" href="https://fonts.googleapis.com" />
18+
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
19+
<link
20+
href="https://fonts.googleapis.com/css2?family=Geist+Sans:wght@400;500;600;700&family=Geist+Mono:wght@400;500;600;700&display=swap"
21+
rel="stylesheet"
22+
/>
23+
</head>
24+
<body className="antialiased">
3025
{children}
3126
</body>
3227
</html>

app/page.tsx

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
import * as React from "react"
2-
import { OpenInV0Button } from "@/components/open-in-v0-button"
3-
import { HelloWorld } from "@/registry/new-york/blocks/hello-world/hello-world"
4-
import { ExampleForm } from "@/registry/new-york/blocks/example-form/example-form"
5-
import PokemonPage from "@/registry/new-york/blocks/complex-component/page"
6-
import { ExampleCard } from "@/registry/new-york/blocks/example-with-css/example-card"
1+
import { OpenInV0Button } from "@/components/open-in-v0-button";
2+
import { HelloWorld } from "@/registry/new-york/blocks/hello-world/hello-world";
3+
import { ExampleForm } from "@/registry/new-york/blocks/example-form/example-form";
4+
import PokemonPage from "@/registry/new-york/blocks/complex-component/page";
5+
import { ExampleCard } from "@/registry/new-york/blocks/example-with-css/example-card";
6+
import { BadgeBarExample } from "@/registry/new-york/blocks/badge-bar/example";
7+
import { PagerExample } from "@/registry/new-york/blocks/pager/example";
8+
import { ImagePreviewExample } from "@/registry/new-york/blocks/image-preview/example";
9+
import { FilePreviewExample } from "@/registry/new-york/blocks/file-preview/example";
10+
import { ScrollBoundaryExample } from "@/registry/new-york/blocks/scroll-boundary/example";
11+
import { ScrollListExample } from "@/registry/new-york/blocks/scroll-list/example";
712
// This page displays items from the custom registry.
813
// You are free to implement this with your own design as needed.
914

@@ -64,7 +69,83 @@ export default function Home() {
6469
<ExampleCard />
6570
</div>
6671
</div>
72+
73+
<div className="flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative">
74+
<div className="flex items-center justify-between">
75+
<h2 className="text-sm text-muted-foreground sm:pl-3">
76+
A component for displaying a list of badges with optional click
77+
and delete handlers.
78+
</h2>
79+
<OpenInV0Button name="badge-bar" className="w-fit" />
80+
</div>
81+
<div className="flex items-center justify-center min-h-[400px] relative">
82+
<BadgeBarExample />
83+
</div>
84+
</div>
85+
86+
<div className="flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative">
87+
<div className="flex items-center justify-between">
88+
<h2 className="text-sm text-muted-foreground sm:pl-3">
89+
A pagination component with page size and page index controls.
90+
</h2>
91+
<OpenInV0Button name="pager" className="w-fit" />
92+
</div>
93+
<div className="flex items-center justify-center min-h-[400px] relative">
94+
<PagerExample />
95+
</div>
96+
</div>
97+
98+
<div className="flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative">
99+
<div className="flex items-center justify-between">
100+
<h2 className="text-sm text-muted-foreground sm:pl-3">
101+
An image preview component with modal viewing and download
102+
functionality.
103+
</h2>
104+
<OpenInV0Button name="image-preview" className="w-fit" />
105+
</div>
106+
<div className="flex items-center justify-center min-h-[400px] relative">
107+
<ImagePreviewExample />
108+
</div>
109+
</div>
110+
111+
<div className="flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative">
112+
<div className="flex items-center justify-between">
113+
<h2 className="text-sm text-muted-foreground sm:pl-3">
114+
A file preview component supporting images, audio, video, and
115+
documents.
116+
</h2>
117+
<OpenInV0Button name="file-preview" className="w-fit" />
118+
</div>
119+
<div className="flex items-center justify-center min-h-[400px] relative">
120+
<FilePreviewExample />
121+
</div>
122+
</div>
123+
124+
<div className="flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative">
125+
<div className="flex items-center justify-between">
126+
<h2 className="text-sm text-muted-foreground sm:pl-3">
127+
A component that detects when scroll reaches edges using
128+
IntersectionObserver.
129+
</h2>
130+
<OpenInV0Button name="scroll-boundary" className="w-fit" />
131+
</div>
132+
<div className="flex items-center justify-center min-h-[400px] relative">
133+
<ScrollBoundaryExample />
134+
</div>
135+
</div>
136+
137+
<div className="flex flex-col gap-4 border rounded-lg p-4 min-h-[450px] relative">
138+
<div className="flex items-center justify-between">
139+
<h2 className="text-sm text-muted-foreground sm:pl-3">
140+
An infinite scroll list component using MobX for state management.
141+
</h2>
142+
<OpenInV0Button name="scroll-list" className="w-fit" />
143+
</div>
144+
<div className="flex items-center justify-center min-h-[400px] relative">
145+
<ScrollListExample />
146+
</div>
147+
</div>
67148
</main>
68149
</div>
69-
)
150+
);
70151
}

babel.config.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module.exports = {
2+
presets: [
3+
// https://babeljs.io/docs/babel-preset-react
4+
[
5+
"@babel/preset-react",
6+
{
7+
runtime: "automatic",
8+
development: process.env.BABEL_ENV === "development",
9+
},
10+
],
11+
],
12+
plugins: [
13+
// https://github.com/babel/babel/issues/16262#issuecomment-1962832499
14+
[
15+
"@babel/plugin-transform-typescript",
16+
{
17+
allowDeclareFields: true,
18+
allowNamespaces: true,
19+
allExtensions: true,
20+
isTSX: true,
21+
},
22+
],
23+
// https://babeljs.io/docs/babel-plugin-proposal-decorators#note-compatibility-with-babelplugin-transform-class-properties
24+
["@babel/plugin-proposal-decorators", { version: "2023-05" }],
25+
],
26+
};

components/index.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
badge
2+
button
3+
dialog
4+
input

lib/utils.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import { clsx, type ClassValue } from "clsx"
2-
import { twMerge } from "tailwind-merge"
1+
import { clsx, type ClassValue } from "clsx";
2+
import { twMerge } from "tailwind-merge";
33

4-
export function cn(...inputs: ClassValue[]) {
5-
return twMerge(clsx(inputs))
6-
}
4+
export const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));

package.json

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,58 @@
33
"version": "0.1.0",
44
"private": true,
55
"scripts": {
6-
"dev": "next dev --turbopack",
7-
"build": "next build",
6+
"postinstall": "shadcn-helper install",
7+
"dev": "next dev --webpack",
8+
"build": "next build --webpack",
89
"start": "next start",
9-
"lint": "next lint",
1010
"registry:build": "shadcn build"
1111
},
1212
"dependencies": {
13-
"@radix-ui/react-label": "^2.1.7",
14-
"@radix-ui/react-slot": "^1.2.3",
13+
"@radix-ui/react-dialog": "^1.1.15",
14+
"@radix-ui/react-label": "^2.1.8",
15+
"@radix-ui/react-slot": "^1.2.4",
1516
"class-variance-authority": "^0.7.1",
1617
"clsx": "^2.1.1",
17-
"lucide-react": "^0.487.0",
18-
"next": "15.5.2",
19-
"react": "19.1.0",
20-
"react-dom": "19.1.0",
21-
"shadcn": "^3.0.0",
22-
"tailwind-merge": "^3.3.1",
23-
"tw-animate-css": "^1.3.6",
18+
"lodash.debounce": "^4.0.8",
19+
"lucide-react": "^0.562.0",
20+
"mobx": "^6.15.0",
21+
"mobx-i18n": "^0.7.2",
22+
"mobx-react": "^9.2.1",
23+
"mobx-react-helper": "^0.5.1",
24+
"mobx-restful": "^2.1.4",
25+
"next": "^16.1.0",
26+
"react": "^19.2.3",
27+
"react-dom": "^19.2.3",
28+
"tailwind-merge": "^3.4.0",
29+
"tw-animate-css": "^1.4.0",
30+
"web-utility": "^4.6.4",
2431
"zod": "^3.25.76"
2532
},
2633
"devDependencies": {
27-
"@eslint/eslintrc": "^3.3.1",
28-
"@tailwindcss/postcss": "^4.1.11",
29-
"@types/node": "^20.19.9",
30-
"@types/react": "19.1.2",
31-
"@types/react-dom": "19.1.2",
32-
"eslint": "^9.32.0",
33-
"eslint-config-next": "15.3.1",
34-
"tailwindcss": "^4.1.11",
35-
"typescript": "^5.9.2"
34+
"@babel/plugin-proposal-decorators": "^7.28.0",
35+
"@babel/plugin-transform-typescript": "^7.28.5",
36+
"@babel/preset-react": "^7.28.5",
37+
"@eslint/eslintrc": "^3.3.3",
38+
"@tailwindcss/postcss": "^4.1.18",
39+
"@types/lodash.debounce": "^4.0.9",
40+
"@types/node": "^22.19.3",
41+
"@types/react": "^19.2.7",
42+
"@types/react-dom": "^19.2.3",
43+
"eslint": "^9.39.2",
44+
"eslint-config-next": "16.1.0",
45+
"mobx-github": "^0.6.2",
46+
"shadcn": "^3.6.2",
47+
"shadcn-helper": "^0.5.2",
48+
"tailwindcss": "^4.1.18",
49+
"typescript": "~5.9.3"
3650
},
3751
"pnpm": {
3852
"overrides": {
39-
"@types/react": "19.1.2",
40-
"@types/react-dom": "19.1.2"
41-
}
53+
"@types/react": "^19.1.2",
54+
"@types/react-dom": "^19.1.2"
55+
},
56+
"onlyBuiltDependencies": [
57+
"core-js"
58+
]
4259
}
4360
}

0 commit comments

Comments
 (0)