Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing non-Sanity props to custom components #12

Open
rscheuer opened this issue Aug 4, 2022 · 2 comments
Open

Passing non-Sanity props to custom components #12

rscheuer opened this issue Aug 4, 2022 · 2 comments

Comments

@rscheuer
Copy link

rscheuer commented Aug 4, 2022

In the react docs, it seems possible to render custom components with external props, as seen here in the docs :

const components = {
  types: {
    code: props => (
      <pre data-language={props.node.language}>
        <code>{props.node.code}</code>
      </pre>
    )
  }
}

However, in the svelte implementation, the docs suggest that we just pass the name of the Svelte component in the serializer:

<script>
   let page={
      interviewName: "Ryan"
   }
</script>

<PortableText
    value={value}
    components={{
    types: {
        image: ImageBlock,
        doubleImage: DoubleImage,
        story: Story,
        interview: <InterviewItem name={page.interviewName} />,  // What I'd like to do.
    },
    marks: {
        link: Link,
    },
    block:{
        normal: ArticleText,
    }
    }}
/>

I'd like to be able to pass external props (in this case from the field's parent document) into a PortableText block. So far, I'm able to get by with Svelte stores, but it feels more like a workaround.

@multiplehats
Copy link

Running into the exact same "problem"! +1

@multiplehats
Copy link

multiplehats commented Aug 30, 2022

Actually @rscheuer , I just found out this is possible by first looking through the source code, and then the documentation.

See this reference: https://github.com/portabletext/svelte-portabletext/blob/35511cf7043aeb529bad8d2080c7e26b4241bca8/README.md#customizing-rendering

Here's my code:

<script lang="ts">
	import { PortableText } from '@portabletext/svelte';
	import type { InputValue } from '@portabletext/svelte/ptTypes';
	import Block from './Blocks/Block.svelte';
	import BlockImage from './Blocks/BlockImage.svelte';
	import BlockHeadings from './Blocks/BlockHeadings.svelte';
	import AnnotationLinkExternal from './Annotations/AnnotationLinkExternal.svelte';
	import AnnotationLinkInternal from './Annotations/AnnotationLinkInternal.svelte';
	import AnnotationLinkEmail from './Annotations/AnnotationLinkEmail.svelte';
	import NormalListItem from './ListItem/NormalListItem.svelte';

	export let blocks: InputValue;
	export let isBlog = false;
</script>

<div {...$$restProps}>
	<PortableText
		context={{ isBlog }}
		components={{
			types: {
				blockImage: BlockImage,
			},
			marks: {
				annotationLinkExternal: AnnotationLinkExternal,
				annotationLinkInternal: AnnotationLinkInternal,
				annotationLinkEmail: AnnotationLinkEmail,
			},
			listItem: {
				normal: NormalListItem,
			},
			block: {
				normal: Block,
				h2: BlockHeadings,
				h3: BlockHeadings,
				h4: BlockHeadings,
			},
		}}
		value={blocks}
	/>
</div>

Then in the Block.svelte, you can access portableText.

<script lang="ts">
	import type { BlockComponentProps } from '@portabletext/svelte';

	export let portableText: BlockComponentProps<{ _key: string; style: string }>;

	$: console.log(portableText,global.context.isBlog);
</script>

<p class="relative mb-3 text-lg font-normal leading-7"><slot /></p>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants