1
0
Fork 0
freesewing/sites/dev/docs/howtos/code/create-snippet/readme.mdx
Joost De Cock ab3204f9f1 chore: Port FreeSewing.dev to docusaurus
The replaces the NextJS site powering FreeSewing.dev with a Docusaurus
setup. It's part of my efforts to simplify FreeSewing's setup so we can
focus on our core value proposition.
2024-09-28 13:13:48 +02:00

127 lines
3.6 KiB
Text

---
title: Creating a new snippet to be used in your design
---
Snippets are typically added by plugins. If you have your own snippet you want
to use, you can add it to your design by loading it in an ad-hoc plugin.
Here's how to do that:
## Define the snippet
First thing to do is define the snippet. A snippet will end up in the [SVG
defs](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs) element
where it can be referenced via [the SVG use
tag](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use).
So your snippet should be SVG content that can be referenced with a single ID.
That ID will also be the name of the snippet. Let's say we want to add `smiley`
then we would create it like this:
```mjs
const smiley = `
<g id="smiley">
<circle cx="-4" cy="4" r="1" style="fill: var(--pattern-mark)"></circle>
<circle cx="4" cy="4" r="1" style="fill: var(--pattern-mark)"></circle>
<path d="M -8,6 C -8,18 8,18 8,6" style="stroke: var(--pattern-mark); fill: none;"></path>
</g>
`
```
If you're curious, it will end up looking like this:
![Preview of our snippet](smiley.png)
:::warning
##### Avoid self-closing tags
Avoid using self-closing tags in your SVG defs definitions.
While this will work fine in actual SVG:
```svg
<circle cx="-4" cy="4" r="1" />
```
Make sure to explicitly close the tag in your defs:
```svg
<circle cx="-4" cy="4" r="1"></circle>
```
:::
## Load the plugin
In your part config, we are going to add an ad-hoc plugin to our `plugins` key
and load the snippet into the defs section of our SVG document:
```mjs
plugins: [{
name: 'smiley-snippet-plugin',
version: '1.0.0',
hooks: {
preRender: [
function(svg) {
svg.defs.setIfUnset( 'smiley', smiley)
}
]
}
}],
```
## Styling snippets
Styling snippets is something that can be frustrating if you are not familiar with
how they are rendered under the hood. The SVG `use` tag creates a so-called
*shadow-dom*, and styles will behave something different in that shadowy realm.
For example, you can't just slap [one of our CSS classes](/reference/css) on it
and call it a day, that won't be enough.
You can of course provide inline styles, but now your snippet can't be themed
which is a big no-no for sites like FreeSewing.org that let users pick different
themes.
As you can see in the example, we used CSS vars, as these do work well in the
shadow-dom and support theming. You don't have to follow this approach, but we
do recommend it.
## Supporting scale
If you're looking to _do things right_ there is one more thing to take into account:
FreeSewing's [scale setting](/reference/settings/scale).
Snippets won't auto-magically adapt to the different scale, so to make that happen we
have to make a few small changes.
First, adapt the defs definition and make it a method that accepts the current scale as a parameter.
We then simply apply a transform and scale the snippet accordingly:
```mjs
const smiley = (scale) => `
<g id="smiley" transform="scale(${scale})">
<circle cx="-4" cy="4" r="1" style="fill: var(--pattern-mark)"></circle>
<circle cx="4" cy="4" r="1" style="fill: var(--pattern-mark)"></circle>
<path d="M -8,6 C -8,18 8,18 8,6" style="stroke: var(--pattern-mark); fill: none;"></path>
</g>
`
```
Then adapt the lifecycle hook method to load the def by calling the method and passing the current scale:
```mjs
plugins: [{
name: 'smiley-snippet-plugin',
version: '1.0.0',
hooks: {
preRender: [
function(svg) {
svg.defs.setIfUnset(
'smiley', smiley(svg.pattern.settings[0].scale)
)
}
]
}
}],
```