🔮 Sanity Create is here. Writing is reinvented. Try now, no developer setup

How to display multiple fields in the same line for preview in Slack thread.

22 replies
Last updated: Jul 7, 2022
Hi everyone, is it possible to display multiple fields within the same line for
preview
?
The following is giving me an error:
Jul 6, 2022, 9:10 PM
Hi Andrew. You can, but you need to do the concatenation in the
prepare()
function. The
select
object is only to “gather” your fields.
Jul 6, 2022, 9:14 PM
Thanks Geoff, I was looking into that just now but am a bit confused about the syntax.What should I place in my
select
to get the desired result?

  preview: {
    select: {
      title: `name`,
      subtitle: "location",
    },
    prepare(selection) {
      const { location, duration, type } = selection;
      return {
        title: `${duration} | ${type} `,
        subtitle: `${location}`,
      };
    },
  },
Jul 6, 2022, 9:15 PM
Maybe something like:

preview: {
  select: {
    duration: 'duration',
    type: 'type',
    location: 'location',
  },
  prepare: ({duration, type, location}) => {
    return {
      title: `${duration} | ${type} `,
      subtitle: `${location}`,
    }
  }
}
Jul 6, 2022, 9:15 PM
Thanks, that works! Sort of..
my fields here are actually dropdowns, so the output of the code snippet you just sent selects their
value:
rather than their
title:
...
Jul 6, 2022, 9:17 PM
Is there a way to fetch the title field instead?
Jul 6, 2022, 9:17 PM
here's an example:
Jul 6, 2022, 9:18 PM
    {
      name: "type",
      title: "Statut",
      type: "string",
      options: {
        list: [
          { title: "Regulier", value: "regular" },
          { title: "Étudiant", value: "student" },
          { title: "Institution", value: "institution" },
        ],
        layout: "dropdown",
      },

Jul 6, 2022, 9:18 PM
user C
I had a similar dilemma and I think I had to change it from a string type to an object where both the title+value were stored
Jul 6, 2022, 10:18 PM
Thanks for clarifying that, Andrew. Only the
value
gets passed into
prepare()
(though ironically, if you don’t use
prepare()
then only the
title
gets passed in, but that won’t work in your case because you’re looking to modify the title line.
Therefore, I think the best approach is to establish your array of objects external to the schema, reference it in the schema, and then get the
title
value in the
prepare()
function. It might look something like:

const TYPES = [
  { title: "Regulier", value: "regular" },
  { title: "Étudiant", value: "student" },
  { title: "Institution", value: "institution" },
]

export default {
  // ...
  fields: [
    // ...
    {
      name: "type",
      title: "Statut",
      type: "string",
      options: {
        list: TYPES,
        layout: "dropdown",
      },
    }
  ],
  preview: {
    select: {
      duration: 'duration',
      type: 'type',
      location: 'location',
    },
    prepare: ({ duration, location, type }) => {
      const typeTitle = type ? TYPES.find(option => option.value === type).title : undefined
      return {
        title: `${duration} | ${typeTitle} `,
        subtitle: `${location}`,
      }
    }
  }
}
Jul 6, 2022, 10:26 PM
This has now been added to the docs .
Jul 6, 2022, 10:58 PM
Interesting solution, thanks Geoff! I'm going to look into integrating this shortly 🙂
Jul 6, 2022, 11:41 PM
Hi Geoff! This worked great, thank you!
is there any way to remove the media placeholder image here though?
Jul 7, 2022, 12:23 AM
Good to hear!
Yes, you can remove the icon by following RD’s advice in the snippet
here . The example is for array items but it works for documents, too. Essentially you’ll
import React from 'react'
and then use
media: <span />
in your preview. Not too long ago, a box shadow was added to preview icons; if you want to get rid of that, you can style your Studio by creating a
css
file somewhere in your Studio, adding some CSS to remove the box shadow, and then adding a part to your sanity.json file.


Your
sanityOverrides.css
file (call it whatever you want) might look like:


:global([data-ui='PaneItem'] *:not(svg) + span) {
  box-shadow: none !important;
}

And your sanity.json part might look like:

"parts": [
  ...OTHER PARTS...,
  {
    "implements": "part:@sanity/base/theme/variables/override-style",
    "path": "./path/to/sanityOverrides.css"
  }
]

You’ll need to restart your Sanity process after adding the part to sanity.json.
Jul 7, 2022, 3:03 AM
Instead of using
media: <span />
, try
media: <></>
. It looks like if you go that route, you don’t need to do any of the CSS overrides.
Jul 7, 2022, 3:08 AM
Hi again, that doesn't seem to work:
Jul 7, 2022, 5:05 PM
Did you import React?
Jul 7, 2022, 5:08 PM
I'm running Next, so that should be done automatically no?
Jul 7, 2022, 5:14 PM
ah actually nvm i'm using a monorepo so maybe not
Jul 7, 2022, 5:15 PM
that works but the text doesn't span the entire div here
Jul 7, 2022, 5:15 PM
versus, say, another schema type seen here
Jul 7, 2022, 5:16 PM
not a huge deal at all but just want to know why it's acting this way
Jul 7, 2022, 5:16 PM
To do that we essentially need to style an element based on its child, which isn’t yet possible in CSS outside of Safari Preview or using flags. Eventually :has() should let us do this (something like
[data-ui='PaneItem'] span[data-testid='Media']:not(:has(> svg))
would let us target the outer span and
display: none
), but for now you’d need to script it.
Jul 7, 2022, 6:28 PM

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?