| | |
| | | |
| | | 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 normally 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 thoughts, inventing the concept of JSX Components to solve the code duplication problem. |
| | | 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 thoughts, inventing the concept of JSX Components 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.** |
| | | |
| | | > [!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. |
| | | |
| | | ## 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 is a function that takes in a single optional parameter `opts` and returns a Quartz Component. The type of the parameters `ops` is defined by the interface `Options` which you as the component creator also decide. |
| | |
| | | } |
| | | |
| | | const defaultOptions: Options = { |
| | | favouriteNumber: 42 |
| | | favouriteNumber: 42, |
| | | } |
| | | |
| | | export default ((userOpts?: Options) => { |
| | | const opts = { ...userOpts, ...defaultOpts } |
| | | function YourComponent(props: QuartzComponentProps) { |
| | | if (opts.favouriteNumber < 0) { |
| | | return null |
| | | } |
| | | |
| | | if (opts.favouriteNumber < 0) { |
| | | return null |
| | | } |
| | | |
| | | return <p>My favourite number is {opts.favouriteNumber}</p> |
| | | } |
| | | |
| | |
| | | ``` |
| | | |
| | | ### Props |
| | | |
| | | The Quartz component itself (lines 11-17 highlighted above) looks like a React component. It takes in properties (sometimes called [props](https://react.dev/learn/passing-props-to-a-component)) and returns JSX. |
| | | |
| | | All Quartz components accept the same set of props which are defined in `QuartzComponentProps`: |
| | |
| | | ``` |
| | | |
| | | - `fileData`: Any metadata [[making plugins|plugins]] may have added to the current page. |
| | | - `fileData.slug`: slug of the current page. |
| | | - `fileData.frontmatter`: any frontmatter parsed. |
| | | - `fileData.slug`: slug of the current page. |
| | | - `fileData.frontmatter`: any frontmatter parsed. |
| | | - `cfg`: The `configuration` field in `quartz.config.ts`. |
| | | - `tree`: the resulting [HTML AST](https://github.com/syntax-tree/hast) after processing and transforming the file. This is useful if you'd like to render the content using [hast-util-to-jsx-runtime](https://github.com/syntax-tree/hast-util-to-jsx-runtime) (you can find an example of this in `quartz/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. |
| | |
| | | ``` |
| | | |
| | | > [!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. |
| | | > 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 |
| | | - listening for the nav event |
| | | - best practice: anything here should unmount any existing event handlers to prevent memory leaks |
| | | |
| | | - listening for the nav event |
| | | - best practice: anything here should unmount any existing event handlers to prevent memory leaks |
| | | |
| | | ### Using a Component |
| | | #### In a layout |
| | | #### In the configuration |
| | | |
| | | #### In a layout |
| | | |
| | | #### In the configuration |
| | | |
| | | > [!hint] |
| | | > Look in `quartz/components` for more examples of components in Quartz as reference for your own components! |