Plugins

Component

This plugin adds support for mapping certain elements to components inside the editor.

Installation

npm i @cartamd/plugin-component

Usage

Mapping components

The first thing to do is to map certain elements(nodes) to their corresponding components. For example, if you want to use a custom renderer for images:

<!-- Image.svelte -->
<script>
	export let src;
	export let alt;
</script>

<!-- Your custom component... -->
<img {src} {alt} />
import { Carta } from 'carta-md';
import { component } from '@cartamd/plugin-component';
import { svelte, initializeComponents } from '@cartamd/plugin-component/svelte';
import Image from './Image.svelte';

const mapped = [svelte('img', Image) /* other components ... */];

const carta = new Carta({
	extensions: [component(mapped, initializeComponents)]
	// ...
});

You can use custom logic when selecting which nodes to map:

import { svelteCustom } from '@cartamd/plugin-component/svelte';
import MyComponent from '...';

const mapped = [
	svelteCustom(
		'my-component-id',
		(node) => {
			// Do something with the node to determine whether to replace it
		},
		MyComponent
	) /* other components ... */
];

Using <slot />

To render children, you need to use a custom <Slot /> component:

<!-- Heading.svelte -->
<script>
	import { Slot } from '@cartamd/plugin-component/svelte';
</script>

<h1>
	<Slot />
</h1>

Usage with pre-rendering

When pre-rendering content on the server (using the <PreRendered> component), the components will not be mounted by default. You need to use the initializeComponents function yourself.

<script>
	import { initializeComponents } from '@cartamd/plugin-component/svelte';
	import { onMount } from 'svelte';
	// ...

	export let data;

	let container;

	// Needs access to the mapped components
	const mapped = [
		/* ... */
	];

	onMount(() => {
		initializeComponents(mapped, container);
	});
</script>

<div bind:this={container}>
	<PreRendered html={data.html} />
</div>

Limitations

  • During server-side rendering, embedded styles for the mapped components are not added to the bundle. Use a dedicated stylesheet instead.
  • <svelte:head> is not available during server-side rendering.
Handmade by Davide