feat: conditional render component

This commit is contained in:
Jacky Zhao 2025-03-23 17:34:14 -07:00
parent 4e74d11b1a
commit aaa5c8e8e4
5 changed files with 50 additions and 2 deletions

View file

@ -60,3 +60,25 @@ The `DesktopOnly` component is the counterpart to `MobileOnly`. It makes its chi
```typescript ```typescript
Component.DesktopOnly(Component.TableOfContents()) Component.DesktopOnly(Component.TableOfContents())
``` ```
## `ConditionalRender` Component
The `ConditionalRender` component is a wrapper that conditionally renders its child component based on a provided condition function. This is useful for creating dynamic layouts where components should only appear under certain conditions.
```typescript
type ConditionalRenderConfig = {
component: QuartzComponent
condition: (props: QuartzComponentProps) => boolean
}
```
### Example Usage
```typescript
Component.ConditionalRender({
component: Component.Search(),
condition: (props) => props.displayClass !== "fullpage",
})
```
This example would only render the Search component when the page is not in fullpage mode.

View file

@ -17,7 +17,10 @@ export const sharedPageComponents: SharedLayout = {
// components for pages that display a single page (e.g. a single note) // components for pages that display a single page (e.g. a single note)
export const defaultContentPageLayout: PageLayout = { export const defaultContentPageLayout: PageLayout = {
beforeBody: [ beforeBody: [
Component.Breadcrumbs(), Component.ConditionalRender({
component: Component.Breadcrumbs(),
condition: (page) => page.fileData.slug !== "index",
}),
Component.ArticleTitle(), Component.ArticleTitle(),
Component.ContentMeta(), Component.ContentMeta(),
Component.TagList(), Component.TagList(),

View file

@ -21,7 +21,6 @@ import { getStaticResourcesFromPlugins } from "./plugins"
import { randomIdNonSecure } from "./util/random" import { randomIdNonSecure } from "./util/random"
import { ChangeEvent } from "./plugins/types" import { ChangeEvent } from "./plugins/types"
import { minimatch } from "minimatch" import { minimatch } from "minimatch"
import { FileTrieNode } from "./util/fileTrie"
type ContentMap = Map< type ContentMap = Map<
FilePath, FilePath,

View file

@ -0,0 +1,22 @@
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types"
type ConditionalRenderConfig = {
component: QuartzComponent
condition: (props: QuartzComponentProps) => boolean
}
export default ((config: ConditionalRenderConfig) => {
const ConditionalRender: QuartzComponent = (props: QuartzComponentProps) => {
if (config.condition(props)) {
return <config.component {...props} />
}
return null
}
ConditionalRender.afterDOMLoaded = config.component.afterDOMLoaded
ConditionalRender.beforeDOMLoaded = config.component.beforeDOMLoaded
ConditionalRender.css = config.component.css
return ConditionalRender
}) satisfies QuartzComponentConstructor<ConditionalRenderConfig>

View file

@ -21,6 +21,7 @@ import RecentNotes from "./RecentNotes"
import Breadcrumbs from "./Breadcrumbs" import Breadcrumbs from "./Breadcrumbs"
import Comments from "./Comments" import Comments from "./Comments"
import Flex from "./Flex" import Flex from "./Flex"
import ConditionalRender from "./ConditionalRender"
export { export {
ArticleTitle, ArticleTitle,
@ -46,4 +47,5 @@ export {
Breadcrumbs, Breadcrumbs,
Comments, Comments,
Flex, Flex,
ConditionalRender,
} }