|
| 1 | +--- |
| 2 | +title: Svelte example |
| 3 | +author: James Goldie, 360info |
| 4 | +date: last-modified |
| 5 | +filters: |
| 6 | + - sverto |
| 7 | +sverto: |
| 8 | + use: |
| 9 | + - Circles.svelte |
| 10 | + - Test.svelte |
| 11 | +--- |
| 12 | + |
| 13 | +Here's an example of how to use the included example Svelte component, `Circles.svelte`. There are six steps: |
| 14 | + |
| 15 | +### 1. Install Sverto |
| 16 | + |
| 17 | +```bash |
| 18 | +quarto add jimjam-slam/sverto |
| 19 | +``` |
| 20 | + |
| 21 | +### 2. Add Sverto to your document |
| 22 | + |
| 23 | +In the document frontmatter: |
| 24 | + |
| 25 | +```yaml |
| 26 | +--- |
| 27 | +# filters: |
| 28 | +# - sverto |
| 29 | +--- |
| 30 | +``` |
| 31 | + |
| 32 | +#### (For projects only: use the sverto project type) |
| 33 | + |
| 34 | +In `_quarto.yml`: |
| 35 | + |
| 36 | + |
| 37 | +```yaml |
| 38 | +project: |
| 39 | + type: sverto |
| 40 | +``` |
| 41 | +
|
| 42 | +### 3. Create a place for your visual to live |
| 43 | +
|
| 44 | +We need to create an instance of our imported component, but---unlike a typical OJS block---Svelte components put the visual itself somewhere else in the document. |
| 45 | +
|
| 46 | +Create an empty div in your document and give it an #id with the hashtag. This will be the "target" in the next step, when we bring the component to life, or _instantiate_ it: |
| 47 | +
|
| 48 | +```markdown |
| 49 | +:::{#mycircles} |
| 50 | +::: |
| 51 | +``` |
| 52 | +
|
| 53 | +:::{#mycircles} |
| 54 | +::: |
| 55 | +
|
| 56 | +:::{.callout-tip} |
| 57 | +This block can go anywhere in your document! Feel free to put it well after the following steps, where you actually want your visualisation to appear. |
| 58 | +::: |
| 59 | +
|
| 60 | +:::{.callout-tip} |
| 61 | +If you know how how to use CSS, you can target `#mycircles` to position or size your visualisation as you'd like. |
| 62 | +::: |
| 63 | + |
| 64 | +### 4. Instantiate your component |
| 65 | + |
| 66 | +Bring your component to life by creating an instance of it with `new [Component Name].default()`. This function takes an object as an argument with two properties: |
| 67 | + |
| 68 | +- `target` is the place your visual will go. Use the `document.querySelector` to point it to the empty block we just made above, `#mycricles`. |
| 69 | +- `props`: is an object where we pass props, or properties, to the component. This will vary depending on how the component is written: the one included as an example with this package, `Circles.svelte`, requires a prop called `data`. |
| 70 | + |
| 71 | +Here's how we instantiate `Circles.svelte`: |
| 72 | + |
| 73 | +```{ojs} |
| 74 | +myCircles = new Circles.default({ |
| 75 | + target: document.querySelector("#mycircles"), |
| 76 | + props: { |
| 77 | + data: [5, 15, 25, 17, 8] |
| 78 | + } |
| 79 | +}); |
| 80 | +``` |
| 81 | + |
| 82 | +::: {.callout-important} |
| 83 | +If you're creating a visual that will react in response to changing OJS (for example, some data that you've calculated in your document, or the value of an Observable Input), **do not put that data here.** |
| 84 | + |
| 85 | +If you put changing data here, the Svelte component will rebuild from scratch every time the data changes, and it will not animate. |
| 86 | + |
| 87 | +Instead, we're going to take advantage of Svelte's own reactivity in the next step. |
| 88 | +::: |
| 89 | + |
| 90 | +### 5. Update your component |
| 91 | + |
| 92 | +Now the fun part - updating our visual when our document changes. It's as simple as referring to the prop using `componentInstance.propName =`. |
| 93 | + |
| 94 | +For example, here are three datasets and an Observable Inputs dropdown menu that lets you select one of three datasets: |
| 95 | + |
| 96 | +```{ojs} |
| 97 | +// here are some datasets... |
| 98 | +allDatasets = new Map([ |
| 99 | + ["Dataset A", [5, 15, 25, 17, 8]], |
| 100 | + ["Dataset B", [25, 5, 5]], |
| 101 | + ["Dataset C", [12, 5, 8, 21, 5]] |
| 102 | + ]); |
| 103 | +``` |
| 104 | + |
| 105 | +```{ojs} |
| 106 | +viewof selectedDataset = |
| 107 | + Inputs.select(allDatasets, { label: "Selected dataset" }); |
| 108 | +``` |
| 109 | + |
| 110 | +Now we can update the prop `data` of the visual `myCircles` using: |
| 111 | + |
| 112 | +```{ojs} |
| 113 | +myCircles.data = selectedDataset |
| 114 | +``` |
| 115 | + |
| 116 | +You can't see anything here, but if we scroll back up to where we added the empty `#mycircles` block, you can see it transition whenever we select a new dataset! |
| 117 | + |
| 118 | +:::{.callout-tip} |
| 119 | +You can put `#mycircles` wherever you want in the document - it doesn't have to be in order! |
| 120 | +::: |
| 121 | + |
| 122 | +### 6. Render the project |
| 123 | + |
| 124 | +Render your Quarto project as you normally would, with commands like `quarto run` and `quarto preview`. |
| 125 | + |
| 126 | +:::{.callout-note} |
| 127 | +You'll probably get the warning `OJS block count mismatch. Line number reporting is likely to be wrong` when rendering. |
| 128 | + |
| 129 | +That's because of what we're doing under the hood to bring the Svelte files in. It won't stop your project from working, but be aware of it if you are referring to line numbers in code blocks! |
| 130 | +::: |
| 131 | + |
| 132 | +And there you go! 🚀 |
| 133 | + |
| 134 | +For more help writing Svelte components, check out the [Svelte tutorial](https://svelte.dev/tutorial/basics). |
0 commit comments