Skip to content

Commit 2517a76

Browse files
fern-supportnikhiltidke101bc-devrev
authored
Testing header footer (#266)
* more spacing * added search * another test * e * trying margin bottom * added search bar * testing header spacing * test * 60px * to body * sidebar fix * e * testing change * try * trial * e * sidebar contain * fix * adjust height * e * more body space * longer sidebar? * minor fix * try * trial * redo * check * sticky * e * e * e * try? * revert * e * updated css * Remove margin from footer component styles --------- Co-authored-by: Nikhil Tidke <[email protected]> Co-authored-by: Ben Colborn <[email protected]>
1 parent f675482 commit 2517a76

File tree

4 files changed

+95
-29
lines changed

4 files changed

+95
-29
lines changed

custom-implementation/src/components/footer.css

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
}
66

77
.custom-footer * {
8-
margin: 0;
98
padding: 0;
109
border: 0;
1110
}

custom-implementation/src/components/header.css

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
.custom-header {
22
z-index: 60;
3-
margin-bottom: 4rem;
43
}
54

65
.custom-header nav a {

custom-implementation/src/main.css

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,22 @@
1616
@media (min-width: 1024px) {
1717
display: block; /* Show the wrapper on screens larger than 1024px */
1818
}
19-
}
19+
}
20+
21+
/* Constrain sidebar within fern-body but account for header
22+
.fern-sidebar-fixed {
23+
position: absolute !important;
24+
} */
25+
26+
#fern-docs {
27+
margin: 64px 0px !important; /* Push content below header */
28+
}
29+
30+
#fern-toc {
31+
margin: 64px 0px!important; /* Push TOC below header */
32+
}
33+
34+
#fern-sidebar {
35+
margin: 32px 0px !important; /* Push TOC and sidebar below header */
36+
}
37+

custom-implementation/src/main.tsx

Lines changed: 76 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ const FERN_CONTENT_WRAPPER_ID = 'fern-header-content-wrapper'
1616
const DEVREV_CONTENT_WRAPPER_ID = 'devrev-header-content-wrapper'
1717
const FERN_HEADER_CONTAINER_ID = 'fern-header'
1818

19+
// ADD GUARDS: Track what's already been rendered
20+
let headerRendered = false
21+
let footerRendered = false
22+
let sidenavRendered = false
23+
1924
const render = async () => {
2025
if (typeof window === 'undefined') {
2126
return
@@ -28,7 +33,9 @@ const render = async () => {
2833

2934
const theme = document.getElementsByTagName('html')[0].getAttribute('class')
3035

31-
if (!document.getElementById('sidenav-header-wrapper') && sidenav) {
36+
if (!sidenavRendered && !document.getElementById('sidenav-header-wrapper') && sidenav) {
37+
sidenavRendered = true
38+
3239
const sidenavHeaderWrapper = document.createElement('div')
3340
sidenavHeaderWrapper.setAttribute('id', 'sidenav-header-wrapper')
3441
sidenav.appendChild(sidenavHeaderWrapper)
@@ -51,7 +58,11 @@ const render = async () => {
5158
const fernHeaderId = document.getElementById(FERN_CONTENT_WRAPPER_ID)
5259
const devrevHeaderId = document.getElementById(DEVREV_CONTENT_WRAPPER_ID)
5360

54-
if (!fernHeaderId && !devrevHeaderId) {
61+
// GUARD: Only render header once
62+
if (!headerRendered && !fernHeaderId && !devrevHeaderId) {
63+
console.log('DEBUG: Rendering header...')
64+
headerRendered = true
65+
5566
// Main Container
5667
const fernHeaderContainer = document.createElement('div')
5768
fernHeaderContainer.setAttribute('id', FERN_HEADER_CONTAINER_ID)
@@ -83,7 +94,7 @@ const render = async () => {
8394
document.body.appendChild(fernHeaderContainer)
8495
}
8596

86-
// Updated to createRoot - callback handling changed
97+
// Render header component
8798
const headerRoot = ReactDOM.createRoot(devrevContentWrapper)
8899
headerRoot.render(
89100
React.createElement(Header, {
@@ -95,19 +106,27 @@ const render = async () => {
95106
// Make header visible immediately
96107
setTimeout(() => {
97108
const header = document.getElementById(FERN_HEADER_CONTAINER_ID)
98-
if (header) header.style.display = 'block'
109+
if (header) {
110+
header.style.display = 'block'
111+
}
99112
}, 0)
100113
}
101114

115+
// GUARD: Only render footer once
102116
const footerElement = document.getElementById('fern-footer')
103-
if (footerElement) {
117+
if (!footerRendered && footerElement && !footerElement.hasAttribute('data-footer-rendered')) {
118+
footerRendered = true
119+
footerElement.setAttribute('data-footer-rendered', 'true')
120+
104121
const footerRoot = ReactDOM.createRoot(footerElement)
105-
footerRoot.render(React.createElement(Footer, { ...data.footer }))
122+
footerRoot.render(React.createElement(Footer,{ ...data.footer }))
106123

107124
// Make footer visible immediately
108125
setTimeout(() => {
109126
const footer = document.getElementById('fern-footer')
110-
if (footer) footer.style.display = 'block'
127+
if (footer) {
128+
footer.style.display = 'block'
129+
}
111130
}, 0)
112131
}
113132

@@ -149,35 +168,66 @@ const render = async () => {
149168
}
150169

151170
let observations = 0
171+
let isInitialized = false
172+
173+
// BETTER INITIALIZATION: Only run once
174+
const initialize = async () => {
175+
if (isInitialized) {
176+
return
177+
}
178+
isInitialized = true
179+
180+
await render()
181+
setupMutationObserver()
182+
}
152183

153184
if (document.readyState === 'loading') {
154-
document.addEventListener('DOMContentLoaded', async () => {
155-
await render()
156-
setupMutationObserver()
157-
})
185+
document.addEventListener('DOMContentLoaded', initialize)
158186
} else {
159-
// DOM is already ready, run immediately
160-
render().then(() => {
161-
setupMutationObserver()
162-
})
187+
// Use a small delay to ensure app router has finished initial render
188+
setTimeout(initialize, 50)
163189
}
164190

165191
function setupMutationObserver() {
166-
new MutationObserver(async (e, o) => {
167-
await render()
168-
for (const item of e) {
169-
if (item.target instanceof HTMLElement) {
170-
const target = item.target
192+
console.log('DEBUG: Setting up mutation observer')
193+
194+
new MutationObserver(async (mutations, observer) => {
195+
// LESS AGGRESSIVE: Only re-render in specific cases
196+
let shouldRender = false
197+
198+
for (const mutation of mutations) {
199+
if (mutation.target instanceof HTMLElement) {
200+
const target = mutation.target
201+
202+
// Only re-render if fern-header or fern-footer are added/removed
171203
if (target.id === 'fern-header' || target.id === 'fern-footer') {
172-
if (observations < 3) {
173-
// react hydration will trigger a mutation event
174-
observations++
175-
} else {
176-
o.disconnect()
177-
}
204+
console.log(`DEBUG: ${target.id} changed, triggering re-render`)
205+
shouldRender = true
178206
break
179207
}
208+
209+
// Check if fern-footer was added to DOM
210+
if (mutation.type === 'childList') {
211+
for (const node of Array.from(mutation.addedNodes)) {
212+
if (node instanceof HTMLElement && node.id === 'fern-footer') {
213+
console.log('DEBUG: fern-footer added to DOM, triggering re-render')
214+
shouldRender = true
215+
break
216+
}
217+
}
218+
}
180219
}
181220
}
221+
222+
if (shouldRender && observations < 3) {
223+
observations++
224+
console.log(`DEBUG: Re-rendering (${observations}/3)`)
225+
await render()
226+
} else if (observations >= 3) {
227+
console.log('DEBUG: Max observations reached, disconnecting observer')
228+
observer.disconnect()
229+
} else {
230+
console.log('DEBUG: DOM change detected but no re-render needed')
231+
}
182232
}).observe(document.body, { childList: true, subtree: true })
183233
}

0 commit comments

Comments
 (0)