sanity-plugin-link-field
Version:
A custom Link field for Sanity Studio
193 lines (169 loc) • 4.42 kB
text/typescript
import {ComponentType} from 'react'
import type {
BaseSchemaDefinition,
CurrentUser,
ObjectInputProps,
ObjectSchemaType,
Path,
PreviewConfig,
ReferenceFilterOptions,
SanityDocument,
} from 'sanity'
export interface CustomizableLink {
parameters?: string
anchor?: string
blank?: boolean
}
export interface InternalLink extends CustomizableLink {
type: 'internal'
internalLink?: {
_type: string
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any
}
}
export interface ExternalLink extends CustomizableLink {
type: 'external'
url?: string
}
export interface EmailLink {
type: 'email'
email?: string
}
export interface PhoneLink {
type: 'phone'
phone?: string
}
export interface CustomLink extends CustomizableLink {
type: string
value?: string
}
export type LinkValue = {
_key?: string
_type?: 'link'
text?: string
} & (InternalLink | ExternalLink | EmailLink | PhoneLink | CustomLink)
export interface LinkType {
title: string
value: string
icon: ComponentType
}
export interface CustomLinkTypeOptions {
title: string
value: string
}
export interface CustomLinkType extends LinkType {
options:
| CustomLinkTypeOptions[]
| ((
document: SanityDocument,
fieldPath: Path,
user: CurrentUser | null,
) => Promise<CustomLinkTypeOptions[]>)
description?: string
}
/**
* Global options for the link field plugin
*
* @todo: Should be overridable on the field level
*/
export interface LinkFieldPluginOptions {
/**
* An array of schema types that should be allowed in internal links.
* @defaultValue ['page']
*/
linkableSchemaTypes: string[]
/**
* Custom filter options passed to the reference input component for internal links.
* Use it to filter the documents that should be available for linking, eg. by locale.
*
* @see https://www.sanity.io/docs/reference-type#1ecd78ab1655
* @defaultValue undefined
*/
referenceFilterOptions?: ReferenceFilterOptions
/**
* Make internal links use weak references
* @see https://www.sanity.io/docs/reference-type#f45f659e7b28
* @defaultValue false
*/
weakReferences?: boolean
/** Override the descriptions of the different subfields. */
descriptions?: {
internal?: string
external?: string
email?: string
phone?: string
text?: string
blank?: string
advanced?: string
parameters?: string
anchor?: string
}
/**
* Whether the user should be able to set custom URL parameters for internal and external links.
* @defaultValue true
*/
enableLinkParameters?: boolean
/**
* Whether the user should be able to set custom anchors (URL fragments) for internal and external links.
* @defaultValue true
*/
enableAnchorLinks?: boolean
/**
* Any custom link types that should be available in the dropdown.
*
* This can be used to allow users to link to pre-defined routes that don't exist within Sanity,
* such as hardcoded routes in the frontend application, or dynamic content that is pulled in
* from an external system.
*
* The options can be either an array of objects, or a function that, given the current document
* and link field, returns an array of options. This can be used to dynamically fetch options.
*
* @defaultValue []
*
* @example
* ```ts
* customLinkTypes: [
* {
* title: 'Archive Page',
* value: 'archive',
* icon: OlistIcon,
* options: [
* {
* title: 'Blog',
* value: '/blog'
* },
* {
* title: 'News',
* value: '/news'
* }
* ]
* }
* ]
* ```
*/
customLinkTypes?: CustomLinkType[]
icon?: BaseSchemaDefinition['icon']
preview?: PreviewConfig
}
/**
* Options for an individual link field
*/
export interface LinkFieldOptions {
/**
* Whether the link should include an optional field for setting the link text/label.
* @defaultValue false
*/
enableText?: boolean
/**
* The label for the text input field, if enabled using the `enableText` option.
* @defaultValue Text
*/
textLabel?: string
}
export type LinkSchemaType = Omit<ObjectSchemaType, 'options'> & {
options?: LinkFieldOptions
}
export type LinkInputProps = ObjectInputProps<LinkValue, LinkSchemaType> & {
customLinkTypes: CustomLinkType[]
}