Skip to content

Commit 594c743

Browse files
committed
simplify
1 parent aa43267 commit 594c743

File tree

11 files changed

+134
-400
lines changed

11 files changed

+134
-400
lines changed

app/README.md

Lines changed: 35 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ When you add a component to the registry, it automatically appears in:
5454

5555
## Adding a New Component Demo
5656

57+
To add a new component to the demo app, follow these **3 simple steps**:
58+
5759
### Step 1: Add Demo Data
5860

5961
In `src/demo/demoData.ts`, add your demo data:
@@ -75,15 +77,23 @@ export const myNewComponentDemoVariation = {
7577
};
7678
```
7779

80+
**Important:** Always add `as const` to the `component` property.
81+
7882
### Step 2: Register in Component Registry
7983

80-
In `src/config/componentRegistry.ts`, add an entry to the `componentRegistry` array:
84+
In `src/config/componentRegistry.ts`:
85+
86+
1. **Import your demo data** at the top:
87+
```typescript
88+
import { myNewComponentDemo, myNewComponentDemoVariation } from "../demo/demoData";
89+
```
8190

91+
2. **Add an entry** to the `componentRegistry` array:
8292
```typescript
8393
{
84-
id: "mynewcomponent", // Unique ID
94+
id: "mynewcomponent", // Unique ID (used in URL and componentMap)
8595
name: "MyNewComponent", // Display name
86-
path: "/mynewcomponent", // Route path
96+
path: "/component/mynewcomponent", // Route path (must follow /component/:id pattern)
8797
sourceUrl: "https://github.com/RedHat-UX/next-gen-ui-react/blob/main/src/components/MyNewComponent.tsx",
8898
componentImportPath: "@local-lib/components/MyNewComponent",
8999
examples: [
@@ -93,73 +103,37 @@ In `src/config/componentRegistry.ts`, add an entry to the `componentRegistry` ar
93103
}
94104
```
95105

96-
### Step 3: Create Component Page
106+
### Step 3: Map Component in ComponentDemo
97107

98-
Create `src/pages/MyNewComponent.tsx`:
108+
In `src/pages/ComponentDemo.tsx`:
99109

110+
1. **Import your component** at the top:
100111
```typescript
101112
import MyNewComponent from "@local-lib/components/MyNewComponent";
102-
import {
103-
CodeBlock,
104-
CodeBlockCode,
105-
Content,
106-
ContentVariants,
107-
Divider,
108-
} from "@patternfly/react-core";
109-
110-
import { myNewComponentDemo, myNewComponentDemoVariation } from "../demo/demoData";
111-
112-
export default function MyNewComponentPage() {
113-
return (
114-
<div>
115-
{/* First Example */}
116-
<Content component={ContentVariants.h3}>Basic Example</Content>
117-
<MyNewComponent {...myNewComponentDemo} />
118-
<Content component={ContentVariants.h4} style={{ marginTop: 16 }}>
119-
Props
120-
</Content>
121-
<CodeBlock>
122-
<CodeBlockCode>
123-
{JSON.stringify(myNewComponentDemo, null, 2)}
124-
</CodeBlockCode>
125-
</CodeBlock>
126-
127-
{/* Divider between examples */}
128-
<Divider style={{ marginTop: 32, marginBottom: 32 }} />
129-
130-
{/* Second Example */}
131-
<Content component={ContentVariants.h3}>Variation</Content>
132-
<MyNewComponent {...myNewComponentDemoVariation} />
133-
<Content component={ContentVariants.h4} style={{ marginTop: 16 }}>
134-
Props
135-
</Content>
136-
<CodeBlock>
137-
<CodeBlockCode>
138-
{JSON.stringify(myNewComponentDemoVariation, null, 2)}
139-
</CodeBlockCode>
140-
</CodeBlock>
141-
</div>
142-
);
143-
}
144113
```
145114

146-
### Step 4: Add Route
147-
148-
In `src/App.tsx`, import and add the route:
149-
115+
2. **Add it to the `componentMap`**:
150116
```typescript
151-
// Add import
152-
import MyNewComponentPage from "./pages/MyNewComponent";
153-
154-
// Add route in the Routes section
155-
<Route path="/mynewcomponent" element={<MyNewComponentPage />} />
117+
const componentMap: Record<string, React.ComponentType<Record<string, unknown>>> = {
118+
// ... existing components
119+
mynewcomponent: MyNewComponent, // key must match the id from registry
120+
};
156121
```
157122

158-
**That's it!** The component will automatically appear in:
159-
- Sidebar navigation
160-
- Home page links
161-
- Page title header
162-
- Source code link
123+
**That's it!** 🎉 The component will now **automatically**:
124+
- ✅ Appear in the sidebar navigation
125+
- ✅ Have its own page at `/component/mynewcomponent`
126+
- ✅ Display all examples with their props
127+
- ✅ Show page title and "View Source" link
128+
- ✅ Include dividers between examples
129+
130+
### Architecture Benefits
131+
132+
This design uses a **component registry pattern** that:
133+
- Eliminates the need to create individual page files
134+
- Automatically generates navigation and routes
135+
- Makes it easy to add multiple examples per component
136+
- Keeps all configuration centralized
163137

164138
## Project Structure
165139

app/src/App.tsx

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,8 @@ import { BrowserRouter, Routes, Route, useLocation } from "react-router-dom";
2020

2121
import { getComponentByPath } from "./config/componentRegistry";
2222
import Sidebar from "./layout/Sidebar";
23-
import DynamicComponentsPage from "./pages/DynamicComponents";
24-
import ErrorPlaceholderPage from "./pages/ErrorPlaceholder";
23+
import ComponentDemo from "./pages/ComponentDemo";
2524
import Home from "./pages/Home";
26-
import ImageComponentPage from "./pages/ImageComponent";
27-
import OneCardWrapperPage from "./pages/OneCardWrapper";
28-
import SetOfCardsWrapperPage from "./pages/SetOfCardsWrapper";
29-
import TableWrapperPage from "./pages/TableWrapper";
30-
import VideoPlayerWrapperPage from "./pages/VideoPlayerWrapper";
3125

3226
function AppContent() {
3327
const location = useLocation();
@@ -73,7 +67,7 @@ function AppContent() {
7367
rel="noopener noreferrer"
7468
aria-label="View source on GitHub"
7569
>
76-
<GithubIcon size="lg" />
70+
<GithubIcon />
7771
</Button>
7872
</ToolbarItem>
7973
</ToolbarGroup>
@@ -129,13 +123,7 @@ function AppContent() {
129123
<div id={mainContainerId} tabIndex={-1}>
130124
<Routes>
131125
<Route path="/" element={<Home />} />
132-
<Route path="/dynamic" element={<DynamicComponentsPage />} />
133-
<Route path="/error" element={<ErrorPlaceholderPage />} />
134-
<Route path="/image" element={<ImageComponentPage />} />
135-
<Route path="/onecard" element={<OneCardWrapperPage />} />
136-
<Route path="/setofcards" element={<SetOfCardsWrapperPage />} />
137-
<Route path="/table" element={<TableWrapperPage />} />
138-
<Route path="/video" element={<VideoPlayerWrapperPage />} />
126+
<Route path="/component/:componentId" element={<ComponentDemo />} />
139127
</Routes>
140128
</div>
141129
</PageSection>

app/src/config/componentRegistry.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export const componentRegistry: ComponentConfig[] = [
3737
{
3838
id: "dynamic",
3939
name: "DynamicComponents",
40-
path: "/dynamic",
40+
path: "/component/dynamic",
4141
sourceUrl:
4242
"https://github.com/RedHat-UX/next-gen-ui-react/blob/main/src/components/DynamicComponents.tsx",
4343
componentImportPath: "@local-lib/components/DynamicComponents",
@@ -50,7 +50,7 @@ export const componentRegistry: ComponentConfig[] = [
5050
{
5151
id: "error",
5252
name: "ErrorPlaceholder",
53-
path: "/error",
53+
path: "/component/error",
5454
sourceUrl:
5555
"https://github.com/RedHat-UX/next-gen-ui-react/blob/main/src/components/ErrorPlaceholder.tsx",
5656
componentImportPath: "@local-lib/components/ErrorPlaceholder",
@@ -68,7 +68,7 @@ export const componentRegistry: ComponentConfig[] = [
6868
{
6969
id: "image",
7070
name: "ImageComponent",
71-
path: "/image",
71+
path: "/component/image",
7272
sourceUrl:
7373
"https://github.com/RedHat-UX/next-gen-ui-react/blob/main/src/components/ImageComponent.tsx",
7474
componentImportPath: "@local-lib/components/ImageComponent",
@@ -80,7 +80,7 @@ export const componentRegistry: ComponentConfig[] = [
8080
{
8181
id: "onecard",
8282
name: "OneCardWrapper",
83-
path: "/onecard",
83+
path: "/component/onecard",
8484
sourceUrl:
8585
"https://github.com/RedHat-UX/next-gen-ui-react/blob/main/src/components/OneCardWrapper.tsx",
8686
componentImportPath: "@local-lib/components/OneCardWrapper",
@@ -93,7 +93,7 @@ export const componentRegistry: ComponentConfig[] = [
9393
{
9494
id: "setofcards",
9595
name: "SetOfCardsWrapper",
96-
path: "/setofcards",
96+
path: "/component/setofcards",
9797
sourceUrl:
9898
"https://github.com/RedHat-UX/next-gen-ui-react/blob/main/src/components/SetOfCardsWrapper.tsx",
9999
componentImportPath: "@local-lib/components/SetOfCardsWrapper",
@@ -105,7 +105,7 @@ export const componentRegistry: ComponentConfig[] = [
105105
{
106106
id: "table",
107107
name: "TableWrapper",
108-
path: "/table",
108+
path: "/component/table",
109109
sourceUrl:
110110
"https://github.com/RedHat-UX/next-gen-ui-react/blob/main/src/components/TableWrapper.tsx",
111111
componentImportPath: "@local-lib/components/TableWrapper",
@@ -117,7 +117,7 @@ export const componentRegistry: ComponentConfig[] = [
117117
{
118118
id: "video",
119119
name: "VideoPlayerWrapper",
120-
path: "/video",
120+
path: "/component/video",
121121
sourceUrl:
122122
"https://github.com/RedHat-UX/next-gen-ui-react/blob/main/src/components/VideoPlayerWrapper.tsx",
123123
componentImportPath: "@local-lib/components/VideoPlayerWrapper",

app/src/pages/ComponentDemo.tsx

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
2+
import DynamicComponents from "@local-lib/components/DynamicComponents";
3+
import ErrorPlaceholder from "@local-lib/components/ErrorPlaceholder";
4+
import ImageComponent from "@local-lib/components/ImageComponent";
5+
import OneCardWrapper from "@local-lib/components/OneCardWrapper";
6+
import SetOfCardsWrapper from "@local-lib/components/SetOfCardsWrapper";
7+
import TableWrapper from "@local-lib/components/TableWrapper";
8+
import VideoPlayerWrapper from "@local-lib/components/VideoPlayerWrapper";
9+
import {
10+
CodeBlock,
11+
CodeBlockCode,
12+
Content,
13+
ContentVariants,
14+
Divider,
15+
} from "@patternfly/react-core";
16+
import { useParams } from "react-router-dom";
17+
18+
import { getComponentById } from "../config/componentRegistry";
19+
20+
// Map component IDs to their actual React components
21+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
22+
const componentMap: Record<string, React.ComponentType<any>> = {
23+
dynamic: DynamicComponents,
24+
error: ErrorPlaceholder,
25+
image: ImageComponent,
26+
onecard: OneCardWrapper,
27+
setofcards: SetOfCardsWrapper,
28+
table: TableWrapper,
29+
video: VideoPlayerWrapper,
30+
};
31+
32+
export default function ComponentDemo() {
33+
const { componentId } = useParams<{ componentId: string }>();
34+
35+
if (!componentId) {
36+
return <div>Component not found</div>;
37+
}
38+
39+
const config = getComponentById(componentId);
40+
41+
if (!config) {
42+
return (
43+
<div>
44+
<Content component={ContentVariants.h3}>Component not found</Content>
45+
<p>The component "{componentId}" does not exist in the registry.</p>
46+
</div>
47+
);
48+
}
49+
50+
const Component = componentMap[componentId];
51+
52+
if (!Component) {
53+
return (
54+
<div>
55+
<Content component={ContentVariants.h3}>Component not mapped</Content>
56+
<p>
57+
The component "{componentId}" exists in the registry but is not mapped
58+
in ComponentDemo.tsx.
59+
</p>
60+
</div>
61+
);
62+
}
63+
64+
return (
65+
<div>
66+
{config.examples.map((example, index) => (
67+
<div key={index}>
68+
{index > 0 && <Divider style={{ marginTop: 32, marginBottom: 32 }} />}
69+
70+
<Content component={ContentVariants.h3}>{example.title}</Content>
71+
72+
{/* Render the component with its data */}
73+
{componentId === "dynamic" ? (
74+
<Component config={example.data as Record<string, unknown>} />
75+
) : (
76+
<Component {...(example.data as Record<string, unknown>)} />
77+
)}
78+
79+
<Content component={ContentVariants.h4} style={{ marginTop: 16 }}>
80+
Props
81+
</Content>
82+
<CodeBlock>
83+
<CodeBlockCode>{JSON.stringify(example.data, null, 2)}</CodeBlockCode>
84+
</CodeBlock>
85+
</div>
86+
))}
87+
</div>
88+
);
89+
}

app/src/pages/DynamicComponents.tsx

Lines changed: 0 additions & 55 deletions
This file was deleted.

0 commit comments

Comments
 (0)