How to render a custom component for a document list in Sanity.io

4 replies
Last updated: Oct 16, 2023
Hi all. I have a question about editing a document in a new pane from a custom component. I have setup the custom component in the following (simplified) desk structure:
S.list()
    .title('Content')
    .items([
      S.listItem().title('Page tree').child(
        S.component(CustomComponent).id('CustomComponent').title('Custom component'),
      ),
...
In this view I have a listening query for a set of documents and want to render those as buttons with links to open the target document in a new pane.
I have tried:

<IntentLink />
from
usePaneRouter
• The same approach as is done in
Documents Pane plugin • The same approach as is done in
Document internationalization plugin I keep getting a warning that the desk structure child was not found, but I cannot (or do not know how to) express a specific document type as a child of the structure, as it can be multiple types. This works:

S.component(CustomComponent).id('CustomComponent').title('Custom component').child(S.document().schemaType('typeA')),
but only (correctly) for a document of
typeA
and not
typeB
I want similar behaviour for panes as is done in the
documentList
.
Does anyone have experience doing this and/or can help with this? Thanks!
Oct 9, 2023, 6:25 AM
It’ll probably be best if you define your structure and your views separately. First, your
listItem
structure would need to look like this:
S.listItem()
   .title('Page Tree')
   .child(
      S.documentList()
        .title('Page Tree')
        .filter(`_type in [<your-types>]`)
        ),
Then, you’d define a
document node resolver to handle your views and return the component there:
return S.document().views([
      S.view.form(),
 S.view.component(CustomComponent).title('Custom Component')
    ])
Oct 10, 2023, 5:07 PM
Thank you for taking the time to answer this! It's unfortunately not exactly what I was looking for. In my case the 'Custom Component' is actually a component to render multiple documents of multiple schema types (a page tree to be more concrete). As I understand it the
document.views
can be a way of adding components on the document level and is rendered like a tab (like the iframe preview plugin), while I want it to replace the behaviour of the default
documentList
component. This is what led me to believe I need to add it as a component in the structure.
Do you have any tips for this?
Oct 11, 2023, 6:30 AM
This plugin (which has custom components for list items) is probably the closest to what you’re looking for. However, the Structure Builder API is for rendering lists of documents and a component cannot be a child of a list. If you just want a visual representation of your page tree, it’ll be easier to just create a separate plugin where you’re not bound by those rules.
Oct 12, 2023, 6:00 PM
Oh my, this is it! Thank you so much for pointing me to this plugin. The solution I was looking for was the following, if anyone might run into this question as well:

S.listItem()
        .title("Page tree")
        .child(
          Object.assign(S.documentList().filter('_type in ["homePage","contentPage"]').title("Page tree").serialize(), {
            __preserveInstance: true,
            key: 'pageTree',
            id: 'pageTree',
            type: 'component',
            component: PageTreeView,
          }),
        ),
Apparently it is possible to render a custom component for a
documentList
like this. Internally it will still be a document list and it is handled accordingly, resulting in the expected behaviour of the pane router 👍
Oct 16, 2023, 6:19 AM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?