Skip to content

Commit 1494340

Browse files
committed
UI: Drop fumadocs-core/hide-if-empty usage
1 parent 601e917 commit 1494340

File tree

7 files changed

+201
-92
lines changed

7 files changed

+201
-92
lines changed

.changeset/calm-parents-dream.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'fumadocs-ui': patch
3+
---
4+
5+
Drop `fumadocs-core/hide-if-empty` usage, prefer user-side component overrides for precise control
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: Hello World
3+
description: |
4+
Your first `document`
5+
```ts
6+
console.log("Hello World")
7+
```
8+
---
9+
10+
Hey there! fsd asfd sdfsfda
11+
sfd
12+
13+
fdsa ff dsaf sdf sda fasd fsd
14+
15+
## Heading
16+
17+
Hello World dsasfdafsd
18+
19+
<Cards>
20+
<Card title="Learn more about Next.js" href="https://nextjs.org/docs" />
21+
<Card title="Learn more about Fumadocs" href="https://fumadocs.dev" />
22+
</Cards>
23+
24+
### Heading
25+
26+
#### Heading
27+
28+
| Head | Description |
29+
| ------------------------------- | ----------------------------------- |
30+
| `hello` | Hello World |
31+
| very **important** | Hey |
32+
| _Surprisingly_ | Fumadocs |
33+
| very long text that looks weird | hello world hello world hello world |
34+
35+
<include>./test.mdx</include>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"root": true
3+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
title: Test
3+
description: A document to test Fumadocs
4+
---
5+
6+
Hey there!
7+
8+
## Cards
9+
10+
<Cards>
11+
<Card title="Learn more about Next.js" href="https://nextjs.org/docs" />
12+
<Card title="Learn more about Fumadocs" href="https://fumadocs.dev" />
13+
</Cards>
14+
15+
### CodeBlock
16+
17+
```js
18+
console.log('Hello World');
19+
```
20+
21+
#### List
22+
23+
- Hello
24+
- World

packages/core/src/hide-if-empty.tsx

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,28 @@ function isEmpty(node: HTMLElement) {
4949
return true;
5050
}
5151

52+
function disableAnimation() {
53+
const css = document.createElement('style');
54+
const nonce = document.currentScript?.nonce;
55+
if (nonce) css.setAttribute('nonce', nonce);
56+
css.appendChild(
57+
document.createTextNode(
58+
`*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}`,
59+
),
60+
);
61+
document.head.appendChild(css);
62+
63+
return () => {
64+
// Force restyle
65+
(() => window.getComputedStyle(document.body))();
66+
67+
// Wait for next tick before removing
68+
setTimeout(() => {
69+
document.head.removeChild(css);
70+
}, 1);
71+
};
72+
}
73+
5274
/**
5375
* The built-in CSS `:empty` selector cannot detect if the children is hidden, classes such as `md:hidden` causes it to fail.
5476
* This component is an enhancement to `empty:hidden` to fix the issue described above.
@@ -80,10 +102,10 @@ export function HideIfEmpty<Props extends HTMLAttributes<HTMLElement>>({
80102

81103
const init = (id: string) => {
82104
const element = getElement(id);
83-
if (element) element.hidden = isEmpty(element);
84-
85-
const script = document.currentScript;
86-
if (script) script.parentNode?.removeChild(script);
105+
if (element) {
106+
disableAnimation();
107+
element.hidden = isEmpty(element);
108+
}
87109
};
88110

89111
return (
@@ -93,14 +115,13 @@ export function HideIfEmpty<Props extends HTMLAttributes<HTMLElement>>({
93115
data-fd-if-empty={id}
94116
hidden={empty ?? false}
95117
/>
96-
{empty === undefined && (
97-
<script
98-
nonce={nonce}
99-
dangerouslySetInnerHTML={{
100-
__html: `{${getElement};${isEmpty};(${init})("${id}")}`,
101-
}}
102-
/>
103-
)}
118+
<script
119+
suppressHydrationWarning
120+
nonce={nonce}
121+
dangerouslySetInnerHTML={{
122+
__html: `{${getElement};${isEmpty};${disableAnimation};(${init})("${id}")}`,
123+
}}
124+
/>
104125
</>
105126
);
106127
}

packages/ui/src/layouts/docs/index.tsx

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import {
3131
type BaseLayoutProps,
3232
BaseLinkItem,
3333
getLinks,
34-
type IconItemType,
3534
type LinkItemType,
3635
} from '@/layouts/shared';
3736
import {
@@ -52,7 +51,6 @@ import {
5251
LargeSearchToggle,
5352
SearchToggle,
5453
} from '@/components/layout/search-toggle';
55-
import { HideIfEmpty } from 'fumadocs-core/hide-if-empty';
5654
import {
5755
getSidebarTabs,
5856
type GetSidebarTabsOptions,
@@ -138,9 +136,7 @@ export function DocsLayout({
138136
} = sidebarProps;
139137
if (component) return component;
140138

141-
const iconLinks = links.filter(
142-
(item): item is IconItemType => item.type === 'icon',
143-
);
139+
const iconLinks = links.filter((item) => item.type === 'icon');
144140

145141
const viewport = (
146142
<SidebarViewport>
@@ -244,32 +240,40 @@ export function DocsLayout({
244240
{banner}
245241
</SidebarHeader>
246242
{viewport}
247-
<HideIfEmpty as={SidebarFooter}>
248-
<div className="flex text-fd-muted-foreground items-center empty:hidden">
249-
{i18n ? (
250-
<LanguageToggle>
251-
<Languages className="size-4.5" />
252-
</LanguageToggle>
253-
) : null}
254-
{iconLinks.map((item, i) => (
255-
<BaseLinkItem
256-
key={i}
257-
item={item}
258-
className={cn(
259-
buttonVariants({ size: 'icon-sm', color: 'ghost' }),
260-
)}
261-
aria-label={item.label}
262-
>
263-
{item.icon}
264-
</BaseLinkItem>
265-
))}
266-
{themeSwitch.enabled !== false &&
267-
(themeSwitch.component ?? (
268-
<ThemeToggle className="ms-auto p-0" mode={themeSwitch.mode} />
243+
{(i18n ||
244+
iconLinks.length > 0 ||
245+
themeSwitch?.enabled !== false ||
246+
footer) && (
247+
<SidebarFooter>
248+
<div className="flex text-fd-muted-foreground items-center empty:hidden">
249+
{i18n && (
250+
<LanguageToggle>
251+
<Languages className="size-4.5" />
252+
</LanguageToggle>
253+
)}
254+
{iconLinks.map((item, i) => (
255+
<BaseLinkItem
256+
key={i}
257+
item={item}
258+
className={cn(
259+
buttonVariants({ size: 'icon-sm', color: 'ghost' }),
260+
)}
261+
aria-label={item.label}
262+
>
263+
{item.icon}
264+
</BaseLinkItem>
269265
))}
270-
</div>
271-
{footer}
272-
</HideIfEmpty>
266+
{themeSwitch.enabled !== false &&
267+
(themeSwitch.component ?? (
268+
<ThemeToggle
269+
className="ms-auto p-0"
270+
mode={themeSwitch.mode}
271+
/>
272+
))}
273+
</div>
274+
{footer}
275+
</SidebarFooter>
276+
)}
273277
</SidebarContent>
274278
);
275279

0 commit comments

Comments
 (0)