Skip to content

Commit 5fe87c9

Browse files
committed
fix(use_cases): add Shadcn UI entry
1 parent 98c43c0 commit 5fe87c9

File tree

5 files changed

+117
-58
lines changed

5 files changed

+117
-58
lines changed

docs/SHADCN_COMPONENT_INTEGRATION_TEST_PLAN.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Shadcn Component Integration Test Plan
22

3-
**Last Updated:** 2026-03-14
3+
**Last Updated:** 2026-03-16
44
**Status:** In Progress
55
**Target:** `integration_tests/specs/shadcn/`
66

@@ -30,6 +30,18 @@ Relevant local files:
3030
- Compare WebF output against Chrome before accepting new snapshot baselines.
3131
- Track progress in one place, PR by PR, with clear TODO lists and blockers.
3232

33+
## Related use_cases Rollout
34+
35+
This document still primarily tracks integration-test work. In parallel, the public
36+
`use_cases` demo app should expose shadcn like the existing `Cupertino UI` and
37+
`Lucide Icons` entries so the shipped component pages are easy to discover.
38+
39+
- [x] Expose shadcn routes outside the `import.meta.env.DEV` gate in `use_cases/src/App.tsx`.
40+
- [x] Add a `Shadcn UI` quick-start card in `use_cases/src/pages/HomePage.tsx`.
41+
- [x] Add a `Shadcn UI` section in `use_cases/src/pages/FeatureCatalogPage.tsx`.
42+
- [x] Expand `use_cases/src/pages/ShadcnShowcasePage.tsx` to list all currently shipped shadcn demos.
43+
- [x] Align the showcase-entry navigation helpers with `WebFRouter.push(...)`.
44+
3345
## Non-Goals
3446

3547
- Do not test the entire shadcn catalog in one pass.
@@ -258,6 +270,11 @@ Concrete PR1 blockers found so far:
258270
- Remaining open PR1 work: dependency decision and Chrome snapshot comparison.
259271
- **2026-03-14**: Added the first composed shadcn use-case case.
260272
- Added `specs/shadcn/use-cases/workspace-preferences.tsx` as a React settings-panel case instead of another low-level probe.
273+
- **2026-03-16**: Enabled the shadcn use_cases surface alongside Cupertino UI and Lucide Icons.
274+
- Exposed the `/shadcn-*` routes in `use_cases/src/App.tsx` outside the previous dev-only gate.
275+
- Added `Shadcn UI` discovery entries to the `HomePage` quick-start cards and the `FeatureCatalogPage`.
276+
- Expanded `ShadcnShowcasePage` to list all currently shipped shadcn demo pages grouped by component area.
277+
- Switched the showcase-entry navigation helpers to `WebFRouter.push(...)` so route mounting follows the hybrid-router path consistently.
261278
- Added local dependency files under `integration_tests/shadcn_support/workspace_preferences/` to model a small component tree with supporting data and types.
262279
- Reused the shared shadcn harness and extended the shared CSS with card/input/badge/toggle utility classes so future use-case specs do not need to inline component styling.
263280

use_cases/src/pages/CupertinoShowcasePage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { WebFRouter } from '../router';
33
import { WebFListView } from '@openwebf/react-core-ui';
44

55
export const CupertinoShowcasePage: React.FC = () => {
6-
const navigateTo = (path: string) => WebFRouter.pushState({}, path);
6+
const navigateTo = (path: string) => void WebFRouter.push(path, {});
77

88
const Item = (props: { label: string; desc: string; to?: string }) => (
99
<div

use_cases/src/pages/HomePage.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,13 @@ const quickStart: QuickStartItem[] = [
137137
icon: LucideIcons.smartphone,
138138
gradient: 'linear-gradient(135deg, #3b82f6, #6366f1)',
139139
},
140+
{
141+
title: 'Shadcn UI',
142+
desc: 'Component showcase',
143+
to: '/shadcn-showcase',
144+
icon: LucideIcons.layoutGrid,
145+
gradient: 'linear-gradient(135deg, #18181b, #57534e)',
146+
},
140147
{
141148
title: 'Lucide Icons',
142149
desc: '1600+ open source icons',
@@ -147,7 +154,7 @@ const quickStart: QuickStartItem[] = [
147154
];
148155

149156
export const HomePage: React.FC = () => {
150-
const go = (path: string) => WebFRouter.pushState({}, path);
157+
const go = (path: string) => void WebFRouter.push(path, {});
151158

152159
const QuickStartCard = ({ item }: { item: QuickStartItem }) => (
153160
<div
@@ -156,8 +163,8 @@ export const HomePage: React.FC = () => {
156163
borderRadius: '16px',
157164
padding: '20px 16px',
158165
cursor: 'pointer',
159-
flex: '1',
160-
minWidth: '0',
166+
flex: '1 1 180px',
167+
minWidth: '180px',
161168
display: 'flex',
162169
flexDirection: 'column',
163170
gap: '10px',
@@ -351,14 +358,15 @@ export const HomePage: React.FC = () => {
351358
<div style={{
352359
display: 'flex',
353360
gap: '12px',
361+
flexWrap: 'wrap',
354362
}}>
355363
{quickStart.map((qs) => (
356364
<QuickStartCard key={qs.to} item={qs} />
357365
))}
358366
</div>
359367
</div>
360368

361-
Feature Sections
369+
{/* Feature Sections */}
362370
<div style={{
363371
fontSize: '13px',
364372
fontWeight: 600,

use_cases/src/pages/LucideShowcasePage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { WebFRouter } from '../router';
33
import { WebFListView } from '@openwebf/react-core-ui';
44

55
export const LucideShowcasePage: React.FC = () => {
6-
const navigateTo = (path: string) => WebFRouter.pushState({}, path);
6+
const navigateTo = (path: string) => void WebFRouter.push(path, {});
77

88
const Item = (props: { label: string; desc: string; to?: string }) => (
99
<div

use_cases/src/pages/ShadcnShowcasePage.tsx

Lines changed: 85 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,74 +2,108 @@ import React from 'react';
22
import { WebFRouter } from '../router';
33
import { WebFListView } from '@openwebf/react-core-ui';
44

5+
type ShowcaseItem = {
6+
label: string;
7+
desc: string;
8+
to: string;
9+
};
10+
11+
type ShowcaseSection = {
12+
title: string;
13+
items: ShowcaseItem[];
14+
};
15+
16+
const sections: ShowcaseSection[] = [
17+
{
18+
title: 'Form Controls',
19+
items: [
20+
{ label: 'Buttons', desc: 'Primary, secondary, destructive, outline, ghost, and link buttons', to: '/shadcn/buttons' },
21+
{ label: 'Icon Button', desc: 'Compact icon-only actions with Lucide icons', to: '/shadcn/icon-button' },
22+
{ label: 'Input', desc: 'Text, email, password, and textarea inputs with helper states', to: '/shadcn/input' },
23+
{ label: 'Checkbox & Switch', desc: 'Binary toggles for settings and consent flows', to: '/shadcn/checkbox-switch' },
24+
{ label: 'Select', desc: 'Select menu and combobox-style choices', to: '/shadcn/select' },
25+
{ label: 'Slider', desc: 'Range selection with labeled values', to: '/shadcn/slider' },
26+
{ label: 'Radio Group', desc: 'Single-choice grouped selection patterns', to: '/shadcn/radio' },
27+
{ label: 'Form', desc: 'Composed form layout with validation-friendly structure', to: '/shadcn/form' },
28+
],
29+
},
30+
{
31+
title: 'Display & Feedback',
32+
items: [
33+
{ label: 'Card', desc: 'Flexible content containers with header and footer regions', to: '/shadcn/card' },
34+
{ label: 'Alert & Badge', desc: 'Status chips, inline alerts, and emphasis states', to: '/shadcn/alert-badge' },
35+
{ label: 'Avatar', desc: 'Profile surfaces with initials and image fallbacks', to: '/shadcn/avatar' },
36+
{ label: 'Progress', desc: 'Determinate progress indicators for long-running tasks', to: '/shadcn/progress' },
37+
{ label: 'Skeleton', desc: 'Loading placeholders for content-first layouts', to: '/shadcn/skeleton' },
38+
{ label: 'Table', desc: 'Structured row and column presentation for datasets', to: '/shadcn/table' },
39+
],
40+
},
41+
{
42+
title: 'Navigation & Layout',
43+
items: [
44+
{ label: 'Tabs', desc: 'Tabbed views with active state and content switching', to: '/shadcn/tabs' },
45+
{ label: 'Accordion', desc: 'Expandable sections for dense content blocks', to: '/shadcn/accordion' },
46+
{ label: 'Breadcrumb', desc: 'Hierarchy trails and backtracking patterns', to: '/shadcn/breadcrumb' },
47+
],
48+
},
49+
{
50+
title: 'Overlays & Menus',
51+
items: [
52+
{ label: 'Dialog', desc: 'Modal dialog and sheet-style interaction patterns', to: '/shadcn/dialog' },
53+
{ label: 'Popover', desc: 'Floating panels, popovers, and tooltip-style surfaces', to: '/shadcn/popover' },
54+
{ label: 'Dropdown Menu', desc: 'Compact action menus from trigger buttons', to: '/shadcn/dropdown' },
55+
{ label: 'Context Menu', desc: 'Contextual actions for secondary-click workflows', to: '/shadcn/context-menu' },
56+
],
57+
},
58+
{
59+
title: 'Date & Scheduling',
60+
items: [
61+
{ label: 'Calendar', desc: 'Date picking and month-grid scheduling UI', to: '/shadcn/calendar' },
62+
],
63+
},
64+
];
65+
566
export const ShadcnShowcasePage: React.FC = () => {
6-
const navigateTo = (path: string) => WebFRouter.pushState({}, path);
67+
const navigateTo = (path: string) => void WebFRouter.push(path, {});
768

8-
const Item = (props: { label: string; desc: string; to?: string }) => (
69+
const Item = ({ label, desc, to }: ShowcaseItem) => (
970
<div
10-
className={`flex items-center p-4 border-b border-[#f0f0f0] cursor-pointer transition-colors hover:bg-surface-hover ${props.to ? '' : 'pointer-events-none opacity-60'}`}
11-
onClick={props.to ? () => navigateTo(props.to!) : undefined}
71+
className="flex items-center p-4 border-b border-[#ececec] cursor-pointer transition-colors hover:bg-surface-hover"
72+
onClick={() => navigateTo(to)}
1273
>
1374
<div className="flex-1">
14-
<div className="text-[16px] font-semibold text-[#2c3e50] mb-1">{props.label}</div>
15-
<div className="text-[14px] text-[#7f8c8d] leading-snug">{props.desc}</div>
75+
<div className="text-[16px] font-semibold text-[#1f2937] mb-1">{label}</div>
76+
<div className="text-[14px] text-[#6b7280] leading-snug">{desc}</div>
1677
</div>
17-
<div className="text-[16px] text-[#bdc3c7] font-bold">&gt;</div>
78+
<div className="text-[16px] text-[#9ca3af] font-bold">&gt;</div>
1879
</div>
1980
);
2081

2182
return (
2283
<div id="main" className="min-h-screen w-full bg-surface">
2384
<WebFListView className="w-full px-3 md:px-6 max-w-4xl mx-auto py-6">
2485
<div className="w-full flex justify-center items-center">
25-
<div className="bg-gradient-to-tr from-zinc-800 to-zinc-600 p-6 rounded-2xl text-white shadow">
26-
<h1 className="text-[28px] font-bold mb-2 drop-shadow">Shadcn UI</h1>
27-
<p className="text-[16px]/[1.5] opacity-90">Beautiful components built with WebF and shadcn_ui</p>
86+
<div className="bg-gradient-to-br from-zinc-950 via-zinc-800 to-stone-700 p-6 rounded-2xl text-white shadow-lg w-full">
87+
<h1 className="text-[28px] font-bold mb-2 drop-shadow">Shadcn UI Showcase</h1>
88+
<p className="text-[16px]/[1.5] opacity-90">
89+
Explore the current WebF demos built with <code>@openwebf/react-shadcn-ui</code>.
90+
</p>
2891
</div>
2992
</div>
3093

3194
<div className="mt-6">
32-
<h2 className="text-lg font-semibold text-fg-primary mb-3 pl-3 border-l-4 border-zinc-500">Form Controls</h2>
33-
<div className="mb-5 bg-surface-secondary rounded-xl shadow overflow-hidden border border-line">
34-
<Item label="Buttons" desc="Primary, secondary, destructive, outline, ghost variants" to="/shadcn/buttons" />
35-
<Item label="Icon Button" desc="Icon-only buttons with Lucide icons" to="/shadcn/icon-button" />
36-
{/*<Item label="Input" desc="Text input with various types and states" to="/shadcn/input" />*/}
37-
<Item label="Checkbox & Switch" desc="Toggle controls for forms" to="/shadcn/checkbox-switch" />
38-
{/*<Item label="Select & Combobox" desc="Dropdown selection components" to="/shadcn/select" />*/}
39-
{/*<Item label="Slider" desc="Range selection slider" to="/shadcn/slider" />*/}
40-
{/*<Item label="Radio Group" desc="Single selection from multiple options" to="/shadcn/radio" />*/}
41-
{/*<Item label="Form" desc="Form state management with validation" to="/shadcn/form" />*/}
42-
</div>
43-
44-
<h2 className="text-lg font-semibold text-fg-primary mb-3 pl-3 border-l-4 border-zinc-500">Display Components</h2>
45-
<div className="mb-5 bg-surface-secondary rounded-xl shadow overflow-hidden border border-line">
46-
<Item label="Card" desc="Container with header, content, and footer" to="/shadcn/card" />
47-
<Item label="Alert & Badge" desc="Notifications and status indicators" to="/shadcn/alert-badge" />
48-
<Item label="Avatar" desc="User profile images" to="/shadcn/avatar" />
49-
{/*<Item label="Progress" desc="Loading and progress indicators" to="/shadcn/progress" />*/}
50-
{/*<Item label="Skeleton" desc="Loading placeholder animations" to="/shadcn/skeleton" />*/}
51-
</div>
52-
53-
<h2 className="text-lg font-semibold text-fg-primary mb-3 pl-3 border-l-4 border-zinc-500">Navigation & Layout</h2>
54-
<div className="mb-5 bg-surface-secondary rounded-xl shadow overflow-hidden border border-line">
55-
{/*<Item label="Tabs" desc="Tabbed content navigation" to="/shadcn/tabs" />*/}
56-
<Item label="Accordion" desc="Collapsible content sections" to="/shadcn/accordion" />
57-
<Item label="Dialog & Sheet" desc="Modal dialogs and bottom sheets" to="/shadcn/dialog" />
58-
<Item label="Breadcrumb" desc="Navigation hierarchy" to="/shadcn/breadcrumb" />
59-
</div>
60-
61-
<h2 className="text-lg font-semibold text-fg-primary mb-3 pl-3 border-l-4 border-zinc-500">Data & Pickers</h2>
62-
<div className="mb-5 bg-surface-secondary rounded-xl shadow overflow-hidden border border-line">
63-
{/*<Item label="Table" desc="Data table with headers and rows" to="/shadcn/table" />*/}
64-
<Item label="Calendar & Date Picker" desc="Date selection components" to="/shadcn/calendar" />
65-
</div>
66-
67-
<h2 className="text-lg font-semibold text-fg-primary mb-3 pl-3 border-l-4 border-zinc-500">Menus & Overlays</h2>
68-
<div className="mb-5 bg-surface-secondary rounded-xl shadow overflow-hidden border border-line">
69-
<Item label="Dropdown Menu" desc="Action menu dropdowns" to="/shadcn/dropdown" />
70-
<Item label="Context Menu" desc="Right-click context menus" to="/shadcn/context-menu" />
71-
{/*<Item label="Popover & Tooltip" desc="Floating content and hints" to="/shadcn/popover" />*/}
72-
</div>
95+
{sections.map((section) => (
96+
<div key={section.title} className="mb-5">
97+
<h2 className="text-lg font-semibold text-fg-primary mb-3 pl-3 border-l-4 border-zinc-600">
98+
{section.title}
99+
</h2>
100+
<div className="bg-surface-secondary rounded-xl shadow overflow-hidden border border-line">
101+
{section.items.map((item) => (
102+
<Item key={item.to} {...item} />
103+
))}
104+
</div>
105+
</div>
106+
))}
73107
</div>
74108
</WebFListView>
75109
</div>

0 commit comments

Comments
 (0)