Skip to content

Commit 72dbe52

Browse files
fyalavuzruvnet
andcommitted
fix: restore workspace, fix CI workflows, and add motion elements
- Restore packages/* and apps/* in pnpm-workspace.yaml (broken by PR #1) - Add appshell-react as workspace dependency in docs - Remove e2e/playwright steps from CI (no e2e directory exists) - Simplify GitHub Pages deploy to docs-only build - Add h1 and p to MotionAdapter interface and adapters - Fix kitchen-sink Sidebar onOpenChange → onClose - Add kitchen-sink example and header title/subtitle support Co-Authored-By: claude-flow <ruv@ruv.net>
1 parent 247f3dd commit 72dbe52

15 files changed

Lines changed: 4685 additions & 278 deletions

File tree

.github/workflows/ci.yml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,6 @@ jobs:
1717
node-version: 20
1818
cache: pnpm
1919
- run: pnpm install --frozen-lockfile
20-
- name: Install Playwright browsers
21-
run: cd e2e && pnpm exec playwright install --with-deps chromium
2220
- run: pnpm turbo build
2321
- run: pnpm turbo lint
2422
- run: pnpm turbo test
25-
- uses: actions/upload-artifact@v4
26-
if: failure()
27-
with:
28-
name: playwright-report
29-
path: e2e/playwright-report/

.github/workflows/docs.yml

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,30 +28,15 @@ jobs:
2828
cache: pnpm
2929
- run: pnpm install --frozen-lockfile
3030

31-
- name: Build library
32-
run: pnpm turbo build --filter=appshell-react
33-
3431
- name: Build docs
3532
run: pnpm turbo build --filter=@appshell-react/docs
3633
env:
3734
NEXT_PUBLIC_BASE_PATH: /${{ env.REPO_NAME }}
3835

39-
- name: Build examples
40-
run: pnpm turbo build --filter=@appshell-react/examples
41-
env:
42-
NEXT_PUBLIC_BASE_PATH: /${{ env.REPO_NAME }}/examples
43-
44-
- name: Build Storybook
45-
run: cd packages/react && pnpm build-storybook
46-
4736
- name: Merge outputs
4837
run: |
4938
mkdir -p _site
5039
cp -r apps/docs/out/* _site/
51-
mkdir -p _site/examples
52-
cp -r apps/examples/out/* _site/examples/
53-
mkdir -p _site/storybook
54-
cp -r packages/react/storybook-static/* _site/storybook/
5540
5641
- name: Upload artifact
5742
uses: actions/upload-pages-artifact@v3

apps/docs/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"next-themes": "^0.4.4",
1818
"react": "^19.2.0",
1919
"react-dom": "^19.2.0",
20-
"shiki": "^3.2.1"
20+
"shiki": "^3.2.1",
21+
"appshell-react": "workspace:*"
2122
},
2223
"devDependencies": {
2324
"@tailwindcss/postcss": "^4.1.0",

apps/examples/app/_components/example-data.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
Layout,
1212
Moon,
1313
TableOfContents,
14+
Zap,
1415
} from "lucide-react";
1516
import type { LucideIcon } from "lucide-react";
1617

@@ -29,6 +30,20 @@ export interface ExampleCategory {
2930
}
3031

3132
export const categories: ExampleCategory[] = [
33+
{
34+
id: "showcase",
35+
title: "Showcase",
36+
examples: [
37+
{
38+
slug: "kitchen-sink",
39+
title: "Pro Showcase",
40+
description:
41+
"The ultimate app shell experience: reveal headers, auto-hide footers, sidebars, and premium motion.",
42+
icon: Zap,
43+
code: `<AppShell safeArea>\n <Header behavior="reveal-nav-context" />\n <Sidebar open={...} />\n <Footer behavior="auto-hide" />\n</AppShell>`,
44+
},
45+
],
46+
},
3247
{
3348
id: "headers",
3449
title: "Headers",
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"use client";
2+
3+
import { MotionProvider } from "appshell-react";
4+
import { framerMotionAdapter } from "appshell-react/motion-framer";
5+
import type { ReactNode } from "react";
6+
7+
export function Providers({ children }: { children: ReactNode }) {
8+
return (
9+
<MotionProvider adapter={framerMotionAdapter}>
10+
{children}
11+
</MotionProvider>
12+
);
13+
}
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
"use client";
2+
3+
import React, { useState } from "react";
4+
import {
5+
AppShell,
6+
Header,
7+
Footer,
8+
FooterItem,
9+
Content,
10+
HeaderNav,
11+
HeaderNavItem,
12+
Sidebar,
13+
NavGroup,
14+
NavItem,
15+
cn,
16+
} from "appshell-react";
17+
import {
18+
Home,
19+
Search,
20+
PlusSquare,
21+
Heart,
22+
User,
23+
Menu,
24+
Bell,
25+
Settings,
26+
Mail,
27+
Share2,
28+
Bookmark,
29+
MoreHorizontal,
30+
ChevronRight,
31+
Zap,
32+
Layout,
33+
Smartphone,
34+
Shield,
35+
Palette,
36+
Sparkles,
37+
} from "lucide-react";
38+
39+
export default function KitchenSinkPage() {
40+
const [activeTab, setActiveTab] = useState("home");
41+
const [sidebarOpen, setSidebarOpen] = useState(false);
42+
const [theme, setTheme] = useState<"light" | "dark" | "primary">("light");
43+
44+
const logo = (
45+
<div className="flex items-center gap-2 font-bold tracking-tight">
46+
<div className="size-8 rounded-xl bg-primary flex items-center justify-center shadow-lg shadow-primary/20 ring-1 ring-white/20">
47+
<Zap className="size-5 text-primary-foreground fill-primary-foreground" />
48+
</div>
49+
<span className="hidden sm:inline-block">AppShell Pro</span>
50+
</div>
51+
);
52+
53+
const actions = (
54+
<div className="flex items-center gap-1 sm:gap-2">
55+
<button className="p-2 rounded-full hover:bg-accent/50 transition-colors relative">
56+
<Bell className="size-5" />
57+
<span className="absolute top-2 right-2 size-2 bg-destructive rounded-full border-2 border-background" />
58+
</button>
59+
<button className="hidden sm:flex p-2 rounded-full hover:bg-accent/50 transition-colors">
60+
<Settings className="size-5" />
61+
</button>
62+
<div className="size-8 rounded-full bg-gradient-to-tr from-primary to-purple-500 border-2 border-background shadow-sm ml-1" />
63+
</div>
64+
);
65+
66+
const nav = (
67+
<HeaderNav>
68+
<HeaderNavItem label="Feed" active />
69+
<HeaderNavItem label="Discover" />
70+
<HeaderNavItem label="Community" />
71+
</HeaderNav>
72+
);
73+
74+
const mobileMenu = (
75+
<div className="grid gap-4 py-4">
76+
<div className="flex flex-col gap-2">
77+
<h4 className="px-2 text-xs font-semibold uppercase tracking-wider text-muted-foreground">Menu</h4>
78+
<NavItem icon={<Home className="size-4" />} label="Home" active />
79+
<NavItem icon={<Search className="size-4" />} label="Search" />
80+
<NavItem icon={<Bell className="size-4" />} label="Notifications" />
81+
<NavItem icon={<Mail className="size-4" />} label="Messages" />
82+
</div>
83+
<div className="flex flex-col gap-2">
84+
<h4 className="px-2 text-xs font-semibold uppercase tracking-wider text-muted-foreground">Theme</h4>
85+
<div className="flex gap-2 p-2">
86+
{(["light", "dark", "primary"] as const).map((t) => (
87+
<button
88+
key={t}
89+
onClick={() => setTheme(t)}
90+
className={cn(
91+
"flex-1 py-2 text-xs font-medium rounded-lg border capitalize transition-all",
92+
theme === t ? "bg-primary text-primary-foreground border-primary shadow-sm" : "bg-muted/50 hover:bg-muted"
93+
)}
94+
>
95+
{t}
96+
</button>
97+
))}
98+
</div>
99+
</div>
100+
</div>
101+
);
102+
103+
return (
104+
<AppShell safeArea className="bg-background">
105+
<Header
106+
logo={logo}
107+
actions={actions}
108+
nav={nav}
109+
theme={theme}
110+
behavior="reveal-nav-context"
111+
title="Experience the Future"
112+
subtitle="The most powerful app shell for React applications."
113+
searchContent={
114+
<div className="relative">
115+
<Search className="absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground" />
116+
<input
117+
type="text"
118+
placeholder="Search anything..."
119+
className="w-full h-10 pl-10 pr-4 rounded-xl border bg-muted/50 focus:bg-background focus:ring-2 focus:ring-primary/20 transition-all outline-none"
120+
/>
121+
</div>
122+
}
123+
mobileMenu={mobileMenu}
124+
/>
125+
126+
<Sidebar
127+
open={sidebarOpen}
128+
onClose={() => setSidebarOpen(false)}
129+
side="left"
130+
className="border-r"
131+
>
132+
<div className="p-4 space-y-6">
133+
<div className="flex items-center gap-3 px-2">
134+
<div className="size-10 rounded-2xl bg-primary/10 flex items-center justify-center text-primary">
135+
<Zap className="size-6 fill-primary" />
136+
</div>
137+
<div>
138+
<h3 className="font-bold">AppShell Pro</h3>
139+
<p className="text-xs text-muted-foreground">Premium Edition</p>
140+
</div>
141+
</div>
142+
143+
<NavGroup title="Main">
144+
<NavItem icon={<Home className="size-5" />} label="Dashboard" active />
145+
<NavItem icon={<Layout className="size-5" />} label="Layouts" badge={12} />
146+
<NavItem icon={<Smartphone className="size-5" />} label="Mobile" />
147+
</NavGroup>
148+
149+
<NavGroup title="Features">
150+
<NavItem icon={<Shield className="size-5" />} label="Security" />
151+
<NavItem icon={<Palette className="size-5" />} label="Themes" />
152+
<NavItem icon={<Sparkles className="size-5" />} label="Animations" />
153+
</NavGroup>
154+
</div>
155+
</Sidebar>
156+
157+
<Content className="max-w-4xl mx-auto px-4 py-8">
158+
<div className="space-y-10">
159+
{/* Welcome Card */}
160+
<div className="relative overflow-hidden rounded-3xl bg-primary p-8 text-primary-foreground shadow-2xl shadow-primary/20">
161+
<div className="relative z-10 max-w-md">
162+
<h2 className="text-3xl font-bold tracking-tight">Welcome to the Pro Showcase</h2>
163+
<p className="mt-4 text-primary-foreground/80 leading-relaxed">
164+
This example demonstrates all the power of appshell-react:
165+
reveal animations, spring-based motion, safe areas, and
166+
premium UI components working in harmony.
167+
</p>
168+
<button className="mt-6 inline-flex items-center gap-2 bg-white px-5 py-2.5 rounded-xl text-primary font-bold shadow-lg hover:scale-105 active:scale-95 transition-transform">
169+
Get Started
170+
<ChevronRight className="size-4" />
171+
</button>
172+
</div>
173+
{/* Abstract Background Shapes */}
174+
<div className="absolute top-0 right-0 -translate-y-1/4 translate-x-1/4 size-64 bg-white/10 rounded-full blur-3xl" />
175+
<div className="absolute bottom-0 left-0 translate-y-1/4 -translate-x-1/4 size-96 bg-black/10 rounded-full blur-3xl" />
176+
</div>
177+
178+
{/* Feature Grid */}
179+
<div className="grid gap-6 sm:grid-cols-2">
180+
{[
181+
{
182+
icon: Home,
183+
title: "Responsive Sidebar",
184+
desc: "Touch-optimized sidebar with seamless transitions.",
185+
color: "bg-blue-500/10 text-blue-500"
186+
},
187+
{
188+
icon: Layout,
189+
title: "Reveal Headers",
190+
desc: "Intelligent headers that hide on scroll and reveal on up-swipe.",
191+
color: "bg-purple-500/10 text-purple-500"
192+
},
193+
{
194+
icon: Smartphone,
195+
title: "Safe Area Support",
196+
desc: "Perfect layout on devices with notches and home indicators.",
197+
color: "bg-emerald-500/10 text-emerald-500"
198+
},
199+
{
200+
icon: Sparkles,
201+
title: "Premium Motion",
202+
desc: "Powered by Framer Motion for that high-end interactive feel.",
203+
color: "bg-orange-500/10 text-orange-500"
204+
},
205+
].map((f, i) => (
206+
<div key={i} className="group p-6 rounded-2xl border bg-card hover:bg-accent/50 transition-all hover:shadow-xl hover:shadow-black/5">
207+
<div className={cn("size-12 rounded-xl flex items-center justify-center mb-4 transition-transform group-hover:scale-110", f.color)}>
208+
<f.icon className="size-6" />
209+
</div>
210+
<h3 className="text-lg font-bold mb-2">{f.title}</h3>
211+
<p className="text-sm text-muted-foreground leading-relaxed">{f.desc}</p>
212+
</div>
213+
))}
214+
</div>
215+
216+
{/* Long Content for Scroll Testing */}
217+
<div className="space-y-8 pb-20">
218+
<h3 className="text-2xl font-bold tracking-tight px-2">Recent Activity</h3>
219+
{[1, 2, 3, 4, 5, 6].map((i) => (
220+
<div key={i} className="flex gap-4 p-4 rounded-2xl border bg-muted/30">
221+
<div className="size-12 rounded-full bg-muted shrink-0" />
222+
<div className="flex-1 space-y-2">
223+
<div className="h-4 w-1/3 bg-muted rounded" />
224+
<div className="h-3 w-full bg-muted/60 rounded" />
225+
<div className="h-3 w-2/3 bg-muted/60 rounded" />
226+
</div>
227+
</div>
228+
))}
229+
</div>
230+
</div>
231+
</Content>
232+
233+
<Footer behavior="auto-hide" variant="tab-bar">
234+
<FooterItem
235+
icon={<Home className="size-6" />}
236+
label="Home"
237+
active={activeTab === "home"}
238+
onClick={() => setActiveTab("home")}
239+
/>
240+
<FooterItem
241+
icon={<Search className="size-6" />}
242+
label="Explore"
243+
active={activeTab === "explore"}
244+
onClick={() => setActiveTab("explore")}
245+
/>
246+
<FooterItem
247+
icon={<PlusSquare className="size-6" />}
248+
label="Create"
249+
active={activeTab === "create"}
250+
onClick={() => setActiveTab("create")}
251+
/>
252+
<FooterItem
253+
icon={<Heart className="size-6" />}
254+
label="Activity"
255+
active={activeTab === "activity"}
256+
onClick={() => setActiveTab("activity")}
257+
badge={5}
258+
/>
259+
<FooterItem
260+
icon={<Menu className="size-6" />}
261+
label="Menu"
262+
active={sidebarOpen}
263+
onClick={() => setSidebarOpen(true)}
264+
/>
265+
</Footer>
266+
</AppShell>
267+
);
268+
}

apps/examples/app/layout.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Metadata } from "next";
22
import { Inter } from "next/font/google";
3+
import { Providers } from "./_shared/providers";
34
import "./globals.css";
45

56
const inter = Inter({
@@ -22,7 +23,11 @@ export default function RootLayout({
2223
<head>
2324
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
2425
</head>
25-
<body className={`${inter.variable} font-sans antialiased`}>{children}</body>
26+
<body className={`${inter.variable} font-sans antialiased`}>
27+
<Providers>
28+
{children}
29+
</Providers>
30+
</body>
2631
</html>
2732
);
2833
}

0 commit comments

Comments
 (0)