Modeling a "scroll to div" link in Sanity.io using a custom string component and a dropdown menu.
5 replies
Last updated: Jan 13, 2023
E
How would you model a link to a section within a page? Type "scroll to div" link.
Jan 13, 2023, 12:02 PM
E
One solution I'm thinking of is to create a custom string component, that fetches the modules of the current document, and lists them in a dropdown. When the user selects an entry the
_keygets stored. I can then use that in the frontend to link to the section.
Jan 13, 2023, 12:19 PM
E
But maybe something exists?
Jan 13, 2023, 12:19 PM
E
I did this. Works fine! 🙂
Jan 13, 2023, 2:09 PM
E
Not the most beautiful, but works!
Jan 13, 2023, 2:10 PM
I did something similar for selecting a section in a document you’re referencing in a V2 Studio (sorry I haven’t had a change to migrate it yet):
//schema { name: 'referenceField', title: 'Field within a Reference', description: 'This field uses the @sanity/client to allow you to indicate a specific field within a selected reference', type: 'object', fields: [ { name: 'page', title: 'Page', type: 'reference', to: [{ type: 'page' }], }, { name: 'section', title: 'Section', type: 'string', hidden: ({ document }) => !document.referenceField.page, inputComponent: ClientAsyncSelect, }, ], },
import React, { useState, useEffect } from 'react'; import { Card, Stack, Select } from '@sanity/ui'; import { FormField } from '@sanity/base/components'; import PatchEvent, { set, unset } from '@sanity/form-builder/PatchEvent'; import { useId } from '@reach/auto-id'; import { studioClient } from '../../lib/utils/studioClient'; const ClientAsyncSelect = React.forwardRef((props, ref) => { const [listItems, setListItems] = useState([]); const { type, // Schema information value, // Current field value readOnly, // Boolean if field is not editable markers, // Markers including validation rules presence, // Presence information for collaborative avatars compareValue, // Value to check for "edited" functionality onFocus, // Method to handle focus state onBlur, // Method to handle blur state onChange, // Method to handle patch events, parent, } = props; // Creates a change handler for patching data const handleChange = React.useCallback( // useCallback will help with performance event => { const inputValue = event.currentTarget.value; // get current value // if the value exists, set the data, if not, unset the data onChange(PatchEvent.from(inputValue ? set(inputValue) : unset())); }, [onChange] ); const inputId = useId(); useEffect(() => { const getSections = async () => { await studioClient .fetch(`*[_id == $id][0].sections[].title`, { id: parent.page._ref ? parent.page._ref : '', }) .then(setListItems); }; getSections(); }, []); return ( <FormField description={type.description} // Creates description from schema title={type.title} // Creates label from schema title __unstable_markers={markers} // Handles all markers including validation __unstable_presence={presence} // Handles presence avatars compareValue={compareValue} // Handles "edited" status inputId={inputId} // Allows the label to connect to the input field > <Card padding={0}> <Stack> <Select id={inputId} // A unique ID for this input fontSize={2} padding={[3, 3, 4]} space={[3, 3, 4]} value={value} // Current field value readOnly={readOnly} // If "readOnly" is defined make this field read only onFocus={onFocus} // Handles focus events onBlur={onBlur} // Handles blur events ref={ref} onChange={handleChange} // A function to call when the input value changes > <option value={''}>---</option> {listItems && listItems.map(item => ( <option key={item} value={item}> {item} </option> ))} </Select> </Stack> </Card> </FormField> ); }); export default ClientAsyncSelect;
Jan 13, 2023, 6:30 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.