Skip to content

Commit cce720c

Browse files
committed
arch: shared footer/header
1 parent a286b37 commit cce720c

File tree

17 files changed

+1096
-1710
lines changed

17 files changed

+1096
-1710
lines changed

SHARED_COMPONENTS_ARCHITECTURE.md

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# Shared Components Architecture
2+
3+
This document explains how the shared Header and Footer components work across both the Docusaurus documentation site and standalone interactive applications.
4+
5+
## 🎯 **Overview**
6+
7+
The system uses a **dual-mode approach** where the same underlying configuration and components serve both:
8+
1. **Docusaurus Documentation Site** (`cortexjs.io`)
9+
2. **Standalone Interactive Apps** (`editor.mathlive.io`, `calculator.mathlive.io`, etc.)
10+
11+
## 📁 **File Structure**
12+
13+
```
14+
src/
15+
├── shared/ # Shared component library
16+
│ ├── components/
17+
│ │ ├── Header.jsx # Standalone header component
18+
│ │ ├── Header.css # Unified styling
19+
│ │ ├── Footer.jsx # Standalone footer component
20+
│ │ ├── Footer.css # Footer styling
21+
│ │ └── index.js # Component exports
22+
│ ├── config/
23+
│ │ └── navigation.json # Single source of truth for navigation
24+
│ ├── styles/
25+
│ │ └── variables.css # Shared CSS variables
26+
│ └── utils/
27+
│ └── docusaurus-config.js # Config converter for Docusaurus
28+
└── theme/ # Docusaurus theme overrides
29+
├── Navbar/
30+
│ └── index.js # Wraps Docusaurus navbar
31+
└── Footer/
32+
└── index.js # Wraps Docusaurus footer
33+
```
34+
35+
## 🔄 **How It Works**
36+
37+
### **1. Configuration Source**
38+
39+
All navigation configuration comes from `src/shared/config/navigation.json`:
40+
41+
```json
42+
{
43+
"navbar": {
44+
"title": "MathLive",
45+
"items": [
46+
{
47+
"type": "docSidebar",
48+
"sidebarId": "docSidebar",
49+
"label": "Mathfield"
50+
},
51+
{
52+
"label": "Compute Engine",
53+
"href": "/compute-engine"
54+
},
55+
{
56+
"type": "dropdown",
57+
"label": "Tools",
58+
"items": [
59+
{ "label": "LaTeX Editor", "href": "https://editor.mathlive.io" },
60+
{ "label": "Calculator", "href": "https://calculator.mathlive.io" }
61+
]
62+
}
63+
]
64+
}
65+
}
66+
```
67+
68+
### **2. Docusaurus Integration**
69+
70+
**Files involved:**
71+
- `src/theme/Navbar/index.js` - Theme override that wraps original navbar with `.shared-header`
72+
- `src/theme/Footer/index.js` - Theme override that wraps original footer with `.shared-footer`
73+
- `src/shared/utils/docusaurus-config.js` - Converts JSON config to Docusaurus format
74+
- `docusaurus.config.ts` - Uses `getDocusaurusNavbarConfig()`
75+
76+
**Flow:**
77+
1. `docusaurus.config.ts` calls `getDocusaurusNavbarConfig()`
78+
2. Utility function reads `navigation.json` and converts to Docusaurus format
79+
3. Docusaurus renders its native navbar/footer with our config
80+
4. Theme overrides wrap with `.shared-header`/`.shared-footer` classes
81+
5. Shared CSS applies to both implementations
82+
83+
### **3. Standalone Applications**
84+
85+
**Files involved:**
86+
- `src/shared/components/Header.jsx` - Standalone header component
87+
- `src/shared/components/Footer.jsx` - Standalone footer component
88+
89+
**Flow:**
90+
1. Components directly import and read `navigation.json`
91+
2. **Content filtering** happens based on `standalone` prop
92+
3. Components render using Docusaurus CSS classes
93+
4. Components wrap themselves with `.shared-header`/`.shared-footer` classes
94+
5. Same CSS applies as in Docusaurus case
95+
96+
## 🎛️ **Content Filtering Logic**
97+
98+
The standalone header modifies navigation content in three ways:
99+
100+
### **1. Filter Out docSidebar Items**
101+
```javascript
102+
// In Header.jsx line 10-12
103+
const filteredItems = standalone
104+
? navbar.items.filter(item => item.type !== 'docSidebar') // Remove "Mathfield"
105+
: navbar.items;
106+
```
107+
108+
### **2. Add "Documentation" Link**
109+
```javascript
110+
// In Header.jsx lines 43-47
111+
{standalone && (
112+
<a href="/" className="navbar__item navbar__link">
113+
Documentation
114+
</a>
115+
)}
116+
```
117+
118+
### **3. Convert docSidebar to Regular Links**
119+
```javascript
120+
// In Header.jsx lines 98-103
121+
if (item.type === 'docSidebar' && standalone) {
122+
return (
123+
<a href="/mathfield" className="navbar__item navbar__link">
124+
{item.label} // Converts to regular link instead of sidebar trigger
125+
</a>
126+
);
127+
}
128+
```
129+
130+
## 🎨 **Styling Strategy**
131+
132+
### **Unified CSS Classes**
133+
Both Docusaurus and standalone components use **identical CSS classes**:
134+
135+
**Header:**
136+
- `.navbar`, `.navbar__item`, `.navbar__link`
137+
- `.dropdown`, `.dropdown__menu`, `.dropdown__link`
138+
- `.navbar__brand`, `.navbar__logo`
139+
140+
**Footer:**
141+
- `.footer`, `.footer--dark`, `.footer__links`
142+
- `.footer__title`, `.footer__link-item`, `.footer__copyright`
143+
- `.container`, `.row`, `.col`
144+
145+
### **Styling Files**
146+
- `src/shared/styles/variables.css` - Shared CSS custom properties
147+
- `src/shared/components/Header.css` - Component-specific styles
148+
- `src/shared/components/Footer.css` - Footer styles
149+
150+
### **Benefits**
151+
-**Visual Consistency**: Both implementations look identical
152+
-**Single Maintenance**: One set of styles to maintain
153+
-**Theme Compatibility**: Inherits Docusaurus dark mode, etc.
154+
155+
## 📱 **Usage Examples**
156+
157+
### **In Docusaurus** (Automatic)
158+
```javascript
159+
// docusaurus.config.ts
160+
navbar: getDocusaurusNavbarConfig(),
161+
footer: getDocusaurusFooterConfig(),
162+
```
163+
164+
### **In Standalone Apps**
165+
```javascript
166+
import { Header, Footer } from '../shared/components';
167+
168+
function App() {
169+
return (
170+
<>
171+
<Header currentApp="editor" standalone={true} />
172+
<main>
173+
{/* Your interactive app content */}
174+
</main>
175+
<Footer />
176+
</>
177+
);
178+
}
179+
```
180+
181+
## 🔧 **Development Workflow**
182+
183+
### **Adding Navigation Items**
184+
1. Edit `src/shared/config/navigation.json`
185+
2. Changes automatically apply to both Docusaurus and standalone apps
186+
3. No code changes needed in most cases
187+
188+
### **Styling Changes**
189+
1. Edit CSS files in `src/shared/components/` or `src/shared/styles/`
190+
2. Changes apply to both implementations
191+
3. Test using `/shared-components-preview` page
192+
193+
### **Adding New Interactive Apps**
194+
1. Add entry to Tools dropdown in `navigation.json`
195+
2. Create new React app using shared components
196+
3. Deploy to appropriate subdomain
197+
198+
## 🚀 **Deployment Strategy**
199+
200+
### **Documentation Site**
201+
- Built with Docusaurus to `submodules/cortex-js.github.io/`
202+
- Deployed to GitHub Pages at `cortexjs.io`
203+
204+
### **Interactive Apps**
205+
- Each app builds independently using shared components
206+
- Deploy to subdomains via Cloudflare routing:
207+
- `editor.mathlive.io``/apps/editor/`
208+
- `calculator.mathlive.io``/apps/calculator/`
209+
- etc.
210+
211+
## 🐛 **Troubleshooting**
212+
213+
### **"Cannot read properties of null" errors**
214+
- Usually caused by replacing Docusaurus navbar completely
215+
- Solution: Use wrapper approach in theme overrides
216+
217+
### **Styling Inconsistencies**
218+
- Check that both implementations use same CSS classes
219+
- Verify shared variables are imported properly
220+
221+
### **Navigation Not Updating**
222+
- Clear Docusaurus cache: `npm run clear`
223+
- Check `navigation.json` syntax
224+
- Verify `getDocusaurusNavbarConfig()` is called in config
225+
226+
## 📈 **Future Enhancements**
227+
228+
1. **Authentication Integration**: Add user login state to shared header
229+
2. **Dynamic Configuration**: Load navigation from API or CMS
230+
3. **Analytics Integration**: Track navigation usage across apps
231+
4. **A/B Testing**: Test different navigation structures
232+
5. **Internationalization**: Multi-language support for navigation

0 commit comments

Comments
 (0)