fix notes

This commit is contained in:
Jacky Zhao 2023-08-07 23:57:24 -07:00
parent 533d68e642
commit 09d4eb0684
4 changed files with 22 additions and 17 deletions

View file

@ -1,4 +1,3 @@
public public
node_modules node_modules
.quartz-cache .quartz-cache
**/*.md

View file

@ -16,15 +16,17 @@ Normally on the web, we write layout code using HTML which looks something like
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. 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.** 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] > [!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. > 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 ## An Example Component
### Constructor ### 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. 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. 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.
@ -37,16 +39,16 @@ interface Options {
} }
const defaultOptions: Options = { const defaultOptions: Options = {
favouriteNumber: 42 favouriteNumber: 42,
} }
export default ((userOpts?: Options) => { export default ((userOpts?: Options) => {
const opts = { ...userOpts, ...defaultOpts } const opts = { ...userOpts, ...defaultOpts }
function YourComponent(props: QuartzComponentProps) { function YourComponent(props: QuartzComponentProps) {
if (opts.favouriteNumber < 0) { if (opts.favouriteNumber < 0) {
return null return null
} }
return <p>My favourite number is {opts.favouriteNumber}</p> return <p>My favourite number is {opts.favouriteNumber}</p>
} }
@ -55,6 +57,7 @@ export default ((userOpts?: Options) => {
``` ```
### Props ### 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. 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`: All Quartz components accept the same set of props which are defined in `QuartzComponentProps`:
@ -71,14 +74,15 @@ export type QuartzComponentProps = {
``` ```
- `fileData`: Any metadata [[making plugins|plugins]] may have added to the current page. - `fileData`: Any metadata [[making plugins|plugins]] may have added to the current page.
- `fileData.slug`: slug of the current page. - `fileData.slug`: slug of the current page.
- `fileData.frontmatter`: any frontmatter parsed. - `fileData.frontmatter`: any frontmatter parsed.
- `cfg`: The `configuration` field in `quartz.config.ts`. - `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`). - `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. - `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. - `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 ### 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. 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. Note that inlined styles **must** be plain vanilla CSS.
@ -116,15 +120,18 @@ export default (() => {
``` ```
> [!warning] > [!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 ### 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 ### Using a Component
#### In a layout
#### In the configuration
#### In a layout
#### In the configuration
> [!hint] > [!hint]
> Look in `quartz/components` for more examples of components in Quartz as reference for your own components! > Look in `quartz/components` for more examples of components in Quartz as reference for your own components!

View file

@ -11,7 +11,7 @@ It would be silly to type these all as `string` and call it a day as it's pretty
Luckily, we can mimic nominal typing using [brands](https://www.typescriptlang.org/play#example/nominal-typing). Luckily, we can mimic nominal typing using [brands](https://www.typescriptlang.org/play#example/nominal-typing).
```typescript ```typescript
// instead of // instead of
type ClientSlug = string type ClientSlug = string
// we do // we do
@ -21,7 +21,7 @@ type ClientSlug = string & { __brand: "client" }
const slug: ClientSlug = "some random slug" const slug: ClientSlug = "some random slug"
``` ```
While this prevents most typing mistakes *within* our nominal typing system (e.g. mistaking a server slug for a client slug), it doesn't prevent us from *accidentally* mistaking a string for a client slug when we forcibly cast it. While this prevents most typing mistakes _within_ our nominal typing system (e.g. mistaking a server slug for a client slug), it doesn't prevent us from _accidentally_ mistaking a string for a client slug when we forcibly cast it.
Thus, we still need to be careful when casting from a string to one of these nominal types in the 'entrypoints', illustrated with hexagon shapes in the diagram below. Thus, we still need to be careful when casting from a string to one of these nominal types in the 'entrypoints', illustrated with hexagon shapes in the diagram below.

View file

@ -42,7 +42,6 @@ ul,
hyphens: auto; hyphens: auto;
} }
.math { .math {
font-size: 1.1rem; font-size: 1.1rem;
&.math-display { &.math-display {