* fix: async-mutex not exclusively locking correectly * fix: server-handler crash from filename (closes #386) * fix: typo in bootstrap-cli.mjs (#394) * fixed broken CJK links (#390) * fix: spa hijacks back button (closes #400) * fix: tag support for non-latin alphabets (fixes #398) * fix: properly lock across source and content refresh by sharing a mutex * fix: toc for cyrillic and other non-latin alphabets (closes #396) * fix: percent-encoding for files with %, contentIndex for non-latin chars (closes #397, closes #399) * version bump to 4.0.9 * fix(esbuild): conflict with esbuild-sass-plugin (#402) * deps: esbuild and esbuild-sass-plugin * deps: install exact * deps: native addons for lightningcss * fix: builds should no accumulate on repeated changes (closes #404) * Fix #403 by moving documentation to separate directory to avoid merge conflicts (#405) * fix: use proper full base for links.ts * docs: make incompability of trailing slashes clear * fix: text wrap in popover * docs: update `hosting.md` with Vercel hosting instructions (#406) * Update hosting.md with Vercel hosting instructions * Update docs/hosting.md Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * Update docs/hosting.md Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * Run npm run format --------- Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * format * Revert contentIndex to RSS 2.0 (#407) * docs: fix typo in `authoring content.md` (#408) * fix: lock to never read when site is building * feat: add defaultDateType config * version bump to 4.0.10 * fix: add better warning when defaultDateType is not set due to upgrade * fix: ensure recentnotes uses proper date * format * feat: reproducible build (#412) for sitemap, RSS and contentIndex.json. * style: integrate tertiary color to text-select (#413) * format, ensure ci runs on prs * feat(plugins): add toml support for frontmatter (#418) * feat(plugins): add toml support for frontmatter Currently frontmatter is expected to be yaml, with delimiter set to "---". This might not always be the case, for example ox-hugo(a hugo exporter for org-mode files) exports in toml format with the delimiter set to "+++" by default. With this change, the users will be able use frontmatter plugin to support this toml frontmatter format. Example usage: `Plugin.FrontMatter({delims: "+++", language: 'toml'})` - [0] https://ox-hugo.scripter.co/doc/org-meta-data-to-hugo-front-matter/ * fixup! feat(plugins): add toml support for frontmatter * feat(plugins): add OxHugoFlavouredMarkdown (#419) * feat(plugins): add OxHugoFlavouredMarkdown ox-hugo is an org exporter backend that exports org files to hugo-compatible markdown in an opinionated way. This plugin adds some tweaks to the generated markdown to make it compatible with quartz but the list of changes applied it is not extensive. In the future however, we could leapfrog ox-hugo altogether and create a quartz site directly out of org-roam files. That way we won't have to do all the ritual dancing that this plugin has to perform. See https://github.com/k2052/org-to-markdown * fix: add toml to remarkFrontmatter configuration * docs: add docs for OxHugoFlavouredMarkdown * fixup! docs: add docs for OxHugoFlavouredMarkdown * docs: simplify oxhugo page * style: fix mulitline callout styling * feat: support CLI arguments for `npx quartz create` (#421) * feat(cli): add new args for content + link resolve * feat(cli): validate cmd args * feat(cli): add chalk + error code to errors * feat(cli): support for setup/link via args * refactor(cli): use yargs choices instead of manual Scrap manual check if arguments are valid, use yargs "choices" field instead. * feat(cli): add in-dir argument+ handle errors add new "in-directory" argument, used if "setup" is "copy" or "symlink" to determine source. add error handling for invalid permutations of arguments or non existent path * feat(cli): dynamically use cli or provided args use "in-directory" arg as `originalFolder` if available, otherwise get it from manual cli process * run format * fix: use process.exit instead of return * refactor: split CommonArgv and CreateArgv * refactor(cli): rename create args, use ${} syntax * fix(cli): fix link resolution strategy arg * format * feat(consistency): allow partial cmd args * Fix search bar after navigate (#424) * fix: slugify tag on page before adding (closes #411) * cleanup: rework cli to allow invoking create and build outside of cli (#428) * refactor: move `bootstrap-cli.mjs` tp cli also update reference in docs * refactor(cli): move build handler to `cli-functions` * refactor(cli): move create to handler + helpers * refactor(cli): extract arg definitions * refactor: rename handlers and helpers * refactor(cli): move update, await handlers * refactor(cli): create constants, migrate to helpers * refactor(cli): migrate `restore` * refactor(cli): migrate `sync` * format * refactor(cli): remove old imports/functions * refactor(cli): remove unused imports + format * chore: remove old log statement * fix: fix imports, clean duplicate code * fix: relative import * fix: simplified cacheFile path * fix: update cacheFile import path * refactor: move bootstrap-cli to quartz * format * revert: revert path to bootstrap-cli * ci: re-run * ci: fix execution permission * feat: support configurable ws port and remote development (#429) Co-authored-by: Jeremy Press <jeremy@replit.com> Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * Fix typo :) (#430) * fix: correct graph labels for `index.md` nodes (#431) * feat: support kebab-case and nested tags in Obsidian-flavored Markdown tag-in-content parsing (#425) * enhancement: support kebab-case and nested tags in ofm transformer * update regex/capture groups to allow for (arbitrarily) nested values and tags of only -/_ * Update quartz/plugins/transformers/ofm.ts --------- Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * fix: aliasredirects not using full path, add permalink support * fix: regex for matching highlights (closes #437) (#438) * fix: regex for matching highlights * fix: regex for empty highlights * Adds Pelayo Arbues to showcase (#435) * feat: Implement search for tags (#436) * Quartz sync: Aug 29, 2023, 10:17 PM * style: add basic style to tags in search * feat: add SearchType + tags to search preview * feat: support multiple matches * style(search): add style to matching tags * feat(search): add content to preview for tag search * fix: only display tags on tag search * feat: support basic + tag search * refactor: extract common `fillDocument`, format * feat: add hotkey to search for tags * chore: remove logs * fix: dont render empty `<ul>` if tags not present * fix(search-tag): make case insensitive * refactor: clean `hideSearch` and `showSearch` * feat: trim content similar to `description.ts` * fix(search-tag): hotkey for windows * perf: re-use main index for tag search * fix(search): matches getting highlighted in title (#440) * feat: pluralize things in lists * fix: clipboard button visible in search (#445) * feat(search): add arrow key navigation (#442) * feat(search): add arrow navigation * chore: format * refactor: simplify arrow navigation * chore: remove comment * feat: rework arrow navigation to work without state * feat: make pressing enter work with arrow navigation * fix: remove unused css class * chore: correct comment * refactor(search): use optional chaining * feat(analytics): Support for Umami (#449) * docs: Make it clearer that wikilinks go to paths not page titles (#448) * docs: update `full-text-search.md` (#447) * fix: dont transform external links * feat: 404 page emitter * docs: correct field for ignorePatterns * fix: encodeuri for slugs in rss * fix: escape encoding for titles in rss * fix: links to index not showing in graph (closes #450) * typo (it's draft, not drafts) (#456) * fix: more lenient date parsing for templates * feat: plugin for remark-breaks (#467) * feat: plugin for remark-breaks * fix: update package-lock.json * fix: styling Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * Update linebreaks.ts * Update index.ts --------- Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * fix: callout parsing (#469) * feat: rss limit (closes #459) * fix: 404 page styling for nested pages (closes #458) * feat: rich html rss (closes #460) * feat: resolve block references in obsidian markdown * fix dont show html in search when rssFullHtml is true (closes #474) * feat: note transclusion (#475) * basic transclude * feat: note transclusion * feat: display tag in graph view (#466) * feat: tags in graph view * fix: revert changing graph forces * fix: run prettier * feat: implement file explorer component (closes #201) (#452) * feat: add basic explorer structure„ * feat: integrate new component/plugin * feat: add basic explorer structure * feat: add sort to FileNodes * style: improve style for explorer * refactor: remove unused explorer plugin * refactor: clean explorer structure, fix base (toc) * refactor: clean css, respect displayClass * style: add styling to chevron * refactor: clean up debug statements * refactor: remove unused import * fix: clicking folder icon sometimes turns invisible * refactor: clean css * feat(explorer): add config for title * feat: add config for folder click behavior * fix: `no-pointer` not being set for all elements new approach, have one `no-pointer` class, that removes pointer events and one `clickable` class on the svg and button (everything that can normally be clicked). then, find all children with `clickable` and toggle `no-pointer` * fix: bug where nested folders got incorrect height this fixes the bug where nested folders weren't calculating their total height correctly. done by adding class to main container of all children and calculating total * feat: introduce `folderDefaultState` config * feat: store depth for explorer nodes * feat: implement option for collapsed state + bug fixes folderBehavior: "link" still has bad styling, but major bugs with pointers fixed (not clean yet, but working) * fix: default folder icon rotation * fix: hitbox problem with folder links, fix style * fix: redirect url for nested folders * fix: inconsistent behavior with 'collapseFolders' opt * chore: add comments to `ExplorerNode` * feat: save explorer state to local storage (not clean) * feat: rework `getFolders()`, fix localstorage read + write * feat: set folder state from localStorage needs serious refactoring but functional (except folder icon orientation) * fix: folder icon orientation after local storage * feat: add config for `useSavedState` * refactor: clean `explorer.inline.ts` remove unused functions, comments, unused code, add types to EventHandler * refactor: clean explorer merge `isSvg` paths, remove console logs * refactor: add documentation, remove unused funcs * feat: rework folder collapse logic use grids instead of jank scuffed solution with calculating total heights * refactor: remove depth arg from insert * feat: restore collapse functionality to clicks allow folder icon + folder label to collapse folders again * refactor: remove `pointer-event` jank * feat: improve svg viewbox + remove unused props * feat: use css selector to toggle icon rework folder icon to work purely with css instead of JS manipulation * refactor: remove unused cfg * feat: move TOC to right sidebar * refactor: clean css * style: fix overflow + overflow margin * fix: use `resolveRelative` to resolve file paths * fix: `defaultFolderState` config option * refactor: rename import, rename `folderLi` + ul * fix: use `QuartzPluginData` type * docs: add explorer documentation * fix: use git dates by default, @napi/git is fast enough * Revert "fix: use git dates by default, @napi/git is fast enough" This reverts commit 5dcb7e83fc3c8383ebbc84aac4553df4ad3ef59a. * fix: umami analytics date attribute (#477) * fix: darkmode scroll bars (#480) * fix(slug): Handle question mark (#481) * feat(explorer): add config to support custom sort fn * feat: implement filter function for explorer * fix: use correct import for `QuartzPluginData` * feat(explorer): integrate filter option * feat(explorer): implement `map` fn argument Add a function for mapping over all FileNodes as an option for `Explorer` * fix: create deep copy of file passed into tree * feat: black magic add config for `order` array, which determines the order in which all passed config functions for explorer will get executed in. functions will now dynamically be called on `fileTree` via array accessor (e.g. fileTree["sort"].call(...)) with corresponding function from options being passed to call) * fix: display name for file nodes * fix(explorer): filter function in `ExplorerNode` * docs(explorer): write docs for new features * docs: fix intra page links * docs: fix examples * fix: bad visibility for last explorer item (#478) * fix: bad visibility for last explorer item * feat(explorer): add pseudo element for observer * docs: fix explorer example (#483) * feat: support changes in system theme (#484) * feat: support changes in system theme * fix: run prettier * fix: add content/.gitkeep * fix(nit): make defaultOptions on explorer not a function * fix: tag regex no longer includes purely numerical 'tags' (#485) * fix: tag regex no longer includes purely numerical 'tags' * fix: formatting * fix: use guard in findAndReplace() instead of expanding the regex * feat: Making Quartz available offline by making it a PWA (#465) * Adding PWA and chaching for offline aviability * renamed workbox config to fit Quartz' scheme * Documenting new configuration * Added missig umami documentation * Fixed formatting so the build passes, thank you prettier :) * specified caching strategies to improve performance * formatting... * fixing "404 manifest.json not found" on subdirectories by adding a / to manifestpath * turning it into a plugin * Removed Workbox-cli and updated @types/node * Added Serviceworkercode to offline.ts * formatting * Removing workbox from docs * applied suggestions * Removed path.join for sw path Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * Removed path.join for manifest path Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * Removing path module import * Added absolute path to manifests start_url and manifest "import" using baseUrl * Adding protocol to baseurl Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * Adding protocol to start_url too then * formatting... * Adding fallback page * Documenting offline plugin * formatting... * merge suggestion Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * merge suggestion Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * merge suggestion Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * merge suggestion Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * merge suggestion Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * merge suggestion Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * merge suggestion Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * merge suggestion Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * merge suggestion Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * merge suggestion Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * merge suggestion Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * merge suggestion Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * formatting... * Fixing manifest path, all these nits hiding the actual issues .-. * Offline fallback page through plugins, most things taken from 404 Plugin * adding Offline Plugin to config * formatting... * Turned offline off as default and removed offline.md --------- Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * docs: wording changes for offline support * docs: document enableToc * Revert "docs: wording changes for offline support" This reverts commit 52a172d1a4911080444ff797183e29ba8175741e. * Revert "feat: Making Quartz available offline by making it a PWA (#465)" This reverts commit d6301fae90d9f922618bf0f413e273156731eef7. * feat(explorer): improve accessibility and consistency (+ bug fix) (#488) * feat(consistency): use `all: unset` on button * style: improve accessibility and consistency for explorer * fix: localStorage bug with folder name changes * chore: bump quartz version * feat: display name for folders, expand explorer a little bit (#489) * feat: display name for folders, expand explorer a little bit * update docs * perf: memoize filetree computation (#490) * perf: memoize filetree computation * format * var -> let * docs(explorer): update default config + new example (#493) * fix(explorer): display names for folders without frontmatter (#494) * fix(explorer): display name for folders without `index` file * docs(explorer): add section for folder display names * fix(explorer): increase consistency, explicitly use font-family (#496) * fix(explorer): display name for folders without `index` file * docs(explorer): add section for folder display names * docs(explorer): fix broken wikilink * fix(consistency): explicitly set font + label/link fix Use consistent styling between folders with `folderClickBehavior: "link"` and `"collapse` * Update quartz/components/styles/explorer.scss Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * Update quartz/components/styles/explorer.scss Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> --------- Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * docs(showcase): fix pull request redirect link (#500) * feat: add warning for missing home page * feat: add warning for invalid date format * docs: Adds Vince Imbat to showcase (#501) * add site to showcase (#504) * fix: mermaid copy source position * fix: treat the 0 time as invalid too * npx quartz update * added content back --------- Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> Co-authored-by: Ikko Eltociear Ashimine <eltociear@gmail.com> Co-authored-by: 松浦 知也 Matsuura Tomoya <me@matsuuratomoya.com> Co-authored-by: Aaron Pham <29749331+aarnphm@users.noreply.github.com> Co-authored-by: kanpov <71177577+kanpov@users.noreply.github.com> Co-authored-by: Zane Helton <me@zaaane.com> Co-authored-by: bfahrenfort <59982409+bfahrenfort@users.noreply.github.com> Co-authored-by: Ben Schlegel <31989404+benschlegel@users.noreply.github.com> Co-authored-by: Zero King <l2dy@icloud.com> Co-authored-by: Hrishikesh Barman <geekodour@users.noreply.github.com> Co-authored-by: Jeremy Press <jeremypress1@gmail.com> Co-authored-by: Jeremy Press <jeremy@replit.com> Co-authored-by: Jeffrey Fabian <jeffrey.fabian61@gmail.com> Co-authored-by: Pelayo Arbués <gonzalezpelayo@gmail.com> Co-authored-by: Adam Brangenberg <adambrangenberg@proton.me> Co-authored-by: Dr Kim Foale <kim@gfsc.studio> Co-authored-by: Stefano Cecere <stefano.cecere@krur.com> Co-authored-by: Oskar Manhart <52569953+oskardotglobal@users.noreply.github.com> Co-authored-by: hcplantern <38579760+HCPlantern@users.noreply.github.com> Co-authored-by: Yuto Nagata <38714187+mouse484@users.noreply.github.com> Co-authored-by: Christian Gill <gillchristiang@gmail.com> Co-authored-by: Ben Schlegel <ben5.schlegel@gmail.com> Co-authored-by: David Fischer <david@konst.fish> Co-authored-by: rwutscher <richard.wutscher@gmail.com> Co-authored-by: Vince Imbat <96913392+vinceimbat@users.noreply.github.com> Co-authored-by: Chad Lee <git@chadly.net>
9.4 KiB
title |
---|
Creating your own Quartz components |
Warning
This guide assumes you have experience writing JavaScript and are familiar with TypeScript.
Normally on the web, we write layout code using HTML which looks something like the following:
<article>
<h1>An article header</h1>
<p>Some content</p>
</article>
This piece of HTML represents an article with a leading header that says "An article header" and a paragraph that contains the text "Some content". This is combined with CSS to style the page and JavaScript to add interactivity.
However, HTML doesn't let you create reusable templates. If you wanted to create a new page, you would need to copy and paste the above snippet and edit the header and content yourself. This isn't great if we have a lot of content on our site that shares a lot of similar layout. The smart people who created React also had similar complaints and invented the concept of Components -- JavaScript functions that return JSX -- to solve the code duplication problem.
In effect, components allow you to write a JavaScript function that takes some data and produces HTML as an output. While Quartz doesn't use React, it uses the same component concept to allow you to easily express layout templates in your Quartz site.
An Example Component
Constructor
Component files are written in .tsx
files that live in the quartz/components
folder. These are re-exported in quartz/components/index.ts
so you can use them in layouts and other components more easily.
Each component file should have a default export that satisfies the QuartzComponentConstructor
function signature. It's a function that takes in a single optional parameter opts
and returns a Quartz Component. The type of the parameters opts
is defined by the interface Options
which you as the component creator also decide.
In your component, you can use the values from the configuration option to change the rendering behaviour inside of your component. For example, the component in the code snippet below will not render if the favouriteNumber
option is below 0.
interface Options {
favouriteNumber: number
}
const defaultOptions: Options = {
favouriteNumber: 42,
}
export default ((userOpts?: Options) => {
const opts = { ...userOpts, ...defaultOpts }
function YourComponent(props: QuartzComponentProps) {
if (opts.favouriteNumber < 0) {
return null
}
return <p>My favourite number is {opts.favouriteNumber}</p>
}
return YourComponent
}) satisfies QuartzComponentConstructor
Props
The Quartz component itself (lines 11-17 highlighted above) looks like a React component. It takes in properties (sometimes called props) and returns JSX.
All Quartz components accept the same set of props:
// simplified for sake of demonstration
export type QuartzComponentProps = {
fileData: QuartzPluginData
cfg: GlobalConfiguration
tree: Node<QuartzPluginData>
allFiles: QuartzPluginData[]
displayClass?: "mobile-only" | "desktop-only"
}
fileData
: Any metadata making plugins may have added to the current page.fileData.slug
: slug of the current page.fileData.frontmatter
: any frontmatter parsed.
cfg
: Theconfiguration
field inquartz.config.ts
.tree
: the resulting HTML AST after processing and transforming the file. This is useful if you'd like to render the content using hast-util-to-jsx-runtime (you can find an example of this inquartz/components/pages/Content.tsx
).allFiles
: Metadata for all files that have been parsed. Useful for doing page listings or figuring out the overall site structure.displayClass
: a utility class that indicates a preference from the user about how to render it in a mobile or desktop setting. Helpful if you want to conditionally hide a component on mobile or desktop.
Styling
Quartz components can also define a .css
property on the actual function component which will get picked up by Quartz. This is expected to be a CSS string which can either be inlined or imported from a .scss
file.
Note that inlined styles must be plain vanilla CSS:
export default (() => {
function YourComponent() {
return <p class="red-text">Example Component</p>
}
YourComponent.css = `
p.red-text {
color: red;
}
`
return YourComponent
}) satisfies QuartzComponentConstructor
Imported styles, however, can be from SCSS files:
// assuming your stylesheet is in quartz/components/styles/YourComponent.scss
import styles from "./styles/YourComponent.scss"
export default (() => {
function YourComponent() {
return <p>Example Component</p>
}
YourComponent.css = styles
return YourComponent
}) satisfies QuartzComponentConstructor
Warning
Quartz does not use CSS modules so any styles you declare here apply globally. If you only want it to apply to your component, make sure you use specific class names and selectors.
Scripts and Interactivity
What about interactivity? Suppose you want to add an-click handler for example. Like the .css
property on the component, you can also declare .beforeDOMLoaded
and .afterDOMLoaded
properties that are strings that contain the script.
export default (() => {
function YourComponent() {
return <button id="btn">Click me</button>
}
YourComponent.beforeDOM = `
console.log("hello from before the page loads!")
`
YourComponent.afterDOM = `
document.getElementById('btn').onclick = () => {
alert('button clicked!')
}
`
return YourComponent
}) satisfies QuartzComponentConstructor
[!hint] For those coming from React, Quartz components are different from React components in that it only uses JSX for templating and layout. Hooks like
useEffect
,useState
, etc. are not rendered and other properties that accept functions likeonClick
handlers will not work. Instead, do it using a regular JS script that modifies the DOM element directly.
As the names suggest, the .beforeDOMLoaded
scripts are executed before the page is done loading so it doesn't have access to any elements on the page. This is mostly used to prefetch any critical data.
The .afterDOMLoaded
script executes once the page has been completely loaded. This is a good place to setup anything that should last for the duration of a site visit (e.g. getting something saved from local storage).
If you need to create an afterDOMLoaded
script that depends on page specific elements that may change when navigating to a new page, you can listen for the "nav"
event that gets fired whenever a page loads (which may happen on navigation if SPA Routing is enabled).
document.addEventListener("nav", () => {
// do page specific logic here
// e.g. attach event listeners
const toggleSwitch = document.querySelector("#switch") as HTMLInputElement
toggleSwitch.removeEventListener("change", switchTheme)
toggleSwitch.addEventListener("change", switchTheme)
})
It is best practice to also unmount any existing event handlers to prevent memory leaks.
Importing Code
Of course, it isn't always practical (nor desired!) to write your code as a string literal in the component.
Quartz supports importing component code through .inline.ts
files.
// @ts-ignore: typescript doesn't know about our inline bundling system
// so we need to silence the error
import script from "./scripts/graph.inline"
export default (() => {
function YourComponent() {
return <button id="btn">Click me</button>
}
YourComponent.afterDOM = script
return YourComponent
}) satisfies QuartzComponentConstructor
// any imports here are bundled for the browser
import * as d3 from "d3"
document.getElementById("btn").onclick = () => {
alert("button clicked!")
}
Additionally, like what is shown in the example above, you can import packages in .inline.ts
files. This will be bundled by Quartz and included in the actual script.
Using a Component
After creating your custom component, re-export it in quartz/components/index.ts
:
import ArticleTitle from "./ArticleTitle"
import Content from "./pages/Content"
import Darkmode from "./Darkmode"
import YourComponent from "./YourComponent"
export { ArticleTitle, Content, Darkmode, YourComponent }
Then, you can use it like any other component in quartz.layout.ts
via Component.YourComponent()
. See the configuration#Layout section for more details.
As Quartz components are just functions that return React components, you can compositionally use them in other Quartz components.
import YourComponent from "./YourComponent"
export default (() => {
function AnotherComponent(props: QuartzComponentProps) {
return (
<div>
<p>It's nested!</p>
<YourComponent {...props} />
</div>
)
}
return AnotherComponent
}) satisfies QuartzComponentConstructor
[!hint] Look in
quartz/components
for more examples of components in Quartz as reference for your own components!