UNPKG

sanity-plugin-taxonomy-manager

Version:

Create and manage SKOS compliant taxonomies, thesauri, and classification schemes in Sanity Studio.

493 lines (474 loc) 16.3 kB
import type {ArrayFieldProps} from 'sanity' import type {FieldDefinition} from 'sanity' import {JSX} from 'react' import type {ObjectFieldProps} from 'sanity' import {Plugin as Plugin_2} from 'sanity' import type {Reference} from 'sanity' import type {SanityDocument} from 'sanity' import type {useClient} from 'sanity' /** * Input component that replaces Sanity's default array field input with a * hierarchical taxonomy tree browser. Studio users can browse taxonomy terms * organized in their scheme hierarchy and select terms to add to the array field. * * @remarks * - Must be used with a `schemeFilter` or `branchFilter` helper in the field's * `options.filter`. Rendering without a filter will display a configuration warning. * - Supports only **single-schema arrays** (i.e., `of: [{type: 'reference'}]`). Arrays * with multiple schema types will render a warning and fall back to the default input. * - Taxonomy selection is disabled when viewing the published perspective. * - When `browseOnly` is set in the filter configuration, Sanity's default search input * is suppressed and only the tree browser is available for term selection. * - When `expanded` is set in the filter configuration, the hierarchy tree loads open * by default instead of collapsed. * * @param props - Standard Sanity `ArrayFieldProps` extended with an optional * `embeddingsIndex` configuration object. * @param props.embeddingsIndex - Optional configuration for AI-assisted term * recommendations via a Sanity Embeddings Index. When provided, opening the tree * browser queries the specified index and annotates matching taxonomy terms with * a relevance score to help authors identify the most appropriate terms. * @param props.embeddingsIndex.indexName - The name of the Sanity Embeddings Index * to query. Must be an index that includes `skosConcept` documents. * @param props.embeddingsIndex.fieldReferences - An array of field names from the * current document whose values are concatenated and sent as the embeddings search * query. All listed fields must contain values when the tree browser is opened; * empty fields will display an error message in the tree view rather than scores. * @param props.embeddingsIndex.maxResults - Maximum number of semantically matching * terms to return from the embeddings index. Defaults to `3`. * * @example * Basic usage with a scheme filter: * ```js * import {ArrayHierarchyInput, schemeFilter} from 'sanity-plugin-taxonomy-manager' * * defineField({ * name: 'categories', * title: 'Categories', * type: 'array', * of: [ * { * type: 'reference', * to: {type: 'skosConcept'}, * options: { * filter: schemeFilter({schemeId: 'f3deba'}), * disableNew: true, * }, * }, * ], * components: {field: ArrayHierarchyInput}, * }) * ``` * * @example * Branch filter with tree expanded by default: * ```js * import {ArrayHierarchyInput, branchFilter} from 'sanity-plugin-taxonomy-manager' * * defineField({ * name: 'habitats', * title: 'Habitats', * type: 'array', * of: [ * { * type: 'reference', * to: {type: 'skosConcept'}, * options: { * filter: branchFilter({schemeId: 'cf76c1', branchId: '1e5e6c', expanded: true}), * disableNew: true, * }, * }, * ], * components: {field: ArrayHierarchyInput}, * }) * ``` * * @example * Browse-only mode (suppresses the default Sanity search input): * ```js * import {ArrayHierarchyInput, branchFilter} from 'sanity-plugin-taxonomy-manager' * * defineField({ * name: 'habitats', * title: 'Habitats', * type: 'array', * of: [ * { * type: 'reference', * to: {type: 'skosConcept'}, * options: { * filter: branchFilter({schemeId: 'cf76c1', branchId: '1e5e6c', browseOnly: true}), * disableNew: true, * }, * }, * ], * components: {field: ArrayHierarchyInput}, * }) * ``` * * @example * AI-assisted recommendations via an embeddings index: * ```jsx * import {ArrayHierarchyInput, branchFilter} from 'sanity-plugin-taxonomy-manager' * * defineField({ * name: 'categories', * title: 'Categories', * type: 'array', * of: [ * { * type: 'reference', * to: [{type: 'skosConcept'}], * options: { * filter: branchFilter({schemeId: 'f3deba', branchId: '25f826'}), * disableNew: true, * }, * }, * ], * components: { * field: (props) => ( * <ArrayHierarchyInput * {...props} * embeddingsIndex={{ * indexName: 'my-taxonomy-index', * fieldReferences: ['title', 'description'], * maxResults: 4, * }} * /> * ), * }, * }) * ``` * * @see {@link ReferenceHierarchyInput} for single-value `reference` fields * @see {@link schemeFilter} for filtering by a full concept scheme * @see {@link branchFilter} for filtering by a branch within a concept scheme */ export declare function ArrayHierarchyInput(props: ArrayHierarchyInputProps): JSX.Element declare type ArrayHierarchyInputProps = ArrayFieldProps & { embeddingsIndex?: EmbeddingsIndexConfig } /** * #### Reference Field Scheme & Branch Filter * A pluggable Function for Filtering to a Top Concept Branch within a SKOS Concept Scheme * @param {string} schemeId - The unique six character concept identifier for * the Concept Scheme to which you wish to filter. * @param {string} branchId - The unique six character concept identifier of * a branch. Child concepts will be returned. * @param {boolean} [expanded] - Set to `true` to display open hierarchy trees for * input components. Input component trees load closed by default. * @param {boolean} [browseOnly] - Set to `true` to hide the default Sanity search * input and display only the "Browse Taxonomy Tree" button for selecting terms. * @returns A reference type filter for the child concepts of the designated branch in the selected Concept Scheme * @example * ```ts * import { branchFilter } from 'sanity-plugin-taxonomy-manager' * ... * { * name: 'test', * type: 'array', * of: [ * { * type: 'reference', * to: {type: 'skosConcept'}, * options: { * filter: branchFilter({ * schemeId: 'a1b2c3', * branchId: 'd4e5f6', * expanded: true, // optional; defaults to false (closed tree) * browseOnly: true, // optional; hides search input * }), * disableNew: true, * }, * }, * ], * } * ``` */ export declare const branchFilter: ( options: BranchOptions, ) => ({ getClient, }: { getClient: (clientOptions: {apiVersion: string}) => ReturnType<typeof useClient> }) => Promise<BranchFilterResult> declare type BranchFilterResult = { filter: string params: { schemeId: string branchId: string concepts: string[] } expanded?: boolean browseOnly?: boolean } declare type BranchOptions = { schemeId: string branchId: string expanded?: boolean browseOnly?: boolean } declare interface ConceptSchemeDocument extends SanityDocument { displayed: { _id: string _type: 'skosConceptScheme' title?: string description?: string baseIri?: string schemeId?: string topConcepts?: Array<{ _key: string _ref: string _type: 'reference' }> concepts?: Array<{ _key: string _ref: string _type: 'reference' }> } } declare interface EmbeddingsIndexConfig { indexName: string fieldReferences: string[] maxResults?: number } declare interface EmbeddingsResult { score: number value: { documentId: string type: string } } declare type HierarchyInput = ObjectFieldProps<Reference> & { embeddingsIndex?: EmbeddingsIndexConfig } declare interface Options { baseUri?: string customConceptFields?: FieldDefinition[] customSchemeFields?: FieldDefinition[] ident?: { pattern?: string length?: number prefix?: string regenUi?: boolean } } /** * Input component that replaces Sanity's default reference field input with a * hierarchical taxonomy tree browser. Studio users can browse taxonomy terms * organized in their scheme hierarchy and select a single term for the field. * * @remarks * - Must be used with a `schemeFilter` or `branchFilter` helper in the field's * `options.filter`. Rendering without a filter will display a configuration warning. * - Taxonomy selection is disabled when viewing the published perspective. * - When `browseOnly` is set in the filter configuration, Sanity's default search input * is suppressed and only the tree browser is available for term selection. * - When `expanded` is set in the filter configuration, the hierarchy tree loads open * by default instead of collapsed. * * @param props - Standard Sanity `ObjectFieldProps<Reference>` extended with an optional * `embeddingsIndex` configuration object. * @param props.embeddingsIndex - Optional configuration for AI-assisted term * recommendations via a Sanity Embeddings Index. When provided, opening the tree * browser queries the specified index and annotates matching taxonomy terms with * a relevance score to help authors identify the most appropriate term. * @param props.embeddingsIndex.indexName - The name of the Sanity Embeddings Index * to query. Must be an index that includes `skosConcept` documents. * @param props.embeddingsIndex.fieldReferences - An array of field names from the * current document whose values are concatenated and sent as the embeddings search * query. All listed fields must contain values when the tree browser is opened; * empty fields will display an error message in the tree view rather than scores. * @param props.embeddingsIndex.maxResults - Maximum number of semantically matching * terms to return from the embeddings index. Defaults to `3`. * * @example * Basic usage with a scheme filter: * ```js * import {ReferenceHierarchyInput, schemeFilter} from 'sanity-plugin-taxonomy-manager' * * defineField({ * name: 'gradeLevel', * title: 'Grade Level', * type: 'reference', * to: {type: 'skosConcept'}, * options: { * filter: schemeFilter({schemeId: 'f3deba'}), * disableNew: true, * }, * components: {field: ReferenceHierarchyInput}, * }) * ``` * * @example * Branch filter with tree expanded by default: * ```js * import {ReferenceHierarchyInput, branchFilter} from 'sanity-plugin-taxonomy-manager' * * defineField({ * name: 'topics', * title: 'Topics', * type: 'reference', * to: {type: 'skosConcept'}, * options: { * filter: branchFilter({schemeId: 'cf76c1', branchId: '1e5e6c', expanded: true}), * disableNew: true, * }, * components: {field: ReferenceHierarchyInput}, * }) * ``` * * @example * Browse-only mode (suppresses the default Sanity search input): * ```js * import {ReferenceHierarchyInput, branchFilter} from 'sanity-plugin-taxonomy-manager' * * defineField({ * name: 'topics', * title: 'Topics', * type: 'reference', * to: {type: 'skosConcept'}, * options: { * filter: branchFilter({schemeId: 'cf76c1', branchId: '1e5e6c', browseOnly: true}), * disableNew: true, * }, * components: {field: ReferenceHierarchyInput}, * }) * ``` * * @example * AI-assisted recommendations via an embeddings index: * ```jsx * import {ReferenceHierarchyInput, schemeFilter} from 'sanity-plugin-taxonomy-manager' * * defineField({ * name: 'topics', * title: 'Topics', * type: 'reference', * to: [{type: 'skosConcept'}], * options: { * filter: schemeFilter({schemeId: 'f3deba'}), * disableNew: true, * }, * components: { * field: (props) => ( * <ReferenceHierarchyInput * {...props} * embeddingsIndex={{ * indexName: 'my-taxonomy-index', * fieldReferences: ['title', 'metaDescription'], * maxResults: 4, * }} * /> * ), * }, * }) * ``` * * @see {@link ArrayHierarchyInput} for multi-value `array` fields * @see {@link schemeFilter} for filtering by a full concept scheme * @see {@link branchFilter} for filtering by a branch within a concept scheme */ export declare function ReferenceHierarchyInput(props: HierarchyInput): JSX.Element /** * #### Reference Field Scheme Filter * Pluggable Function for Filtering to a Single SKOS Concept Scheme. * @param {string} schemeId - The unique six character concept identifier for * the Concept Scheme to which you wish to filter. * @param {boolean} [expanded] - Set to `true` to display open hierarchy trees for * input components. Input component trees load closed by default. * @param {boolean} [browseOnly] - Set to `true` to hide the default Sanity search * input and display only the "Browse Taxonomy Tree" button for selecting terms. * @returns A reference type filter for Concepts and Top Concepts in * the selected Concept Scheme test * @example * ```ts * import { schemeFilter } from 'sanity-plugin-taxonomy-manager' * ... * { * name: 'test', * type: 'array', * of: [ * { * type: 'reference', * to: {type: 'skosConcept'}, * options: { * filter: schemeFilter({ * schemeId: 'a1b2c3', * expanded: true, // optional; defaults to false (closed tree) * browseOnly: true, // optional; hides search input * }), * disableNew: true, * }, * }, * ], * } * ``` */ export declare const schemeFilter: ( options: SchemeOptions, ) => ({ getClient, }: { getClient: (clientOptions: {apiVersion: string}) => ReturnType<typeof useClient> }) => Promise<SchemeFilterResult> declare type SchemeFilterResult = { filter: string params: { schemeId: string concepts: string[] topConcepts: string[] } expanded?: boolean browseOnly?: boolean } declare type SchemeOptions = { schemeId: string expanded?: boolean browseOnly?: boolean } /** * #### Sanity Taxonomy Manager * Defines a Sanity plugin for managing SKOS compliant taxonomies in Sanity Studio. * #### Options * @param baseUri - The base URI to use for SKOS concepts and concept schemes. BaseURI should follow an IANA http/s scheme and should terminate with either a / or #. * @param customConceptFields - An array of additional fields to add to the skosConcept type. * @param customSchemeFields - An array of additional fields to add to the skosConceptScheme type. * #### Identifier Configuration * @param ident.pattern - The character set to use for identifiers (default: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'). * @param ident.length - The length of the generated identifier (default: 6). * @param ident.prefix - A prefix to prepend to generated identifiers, for example to use Wikidata style IDs like "Q27521" (default: ''). * @param ident.regenUi - Whether to display the "Create Unique Identifier" button in the UI by default. * @returns A Sanity plugin object. */ export declare const taxonomyManager: Plugin_2<Options | undefined> /** * #### Tree View Component Wrapper * This is the view component for the hierarchy tree. It is the * top level of concept scheme views and is passed into Desk * structure to render the primary view for taxonomy documents. * @param document - The document to render. * @param branchId - The branch ID to fetch concepts from. * @param inputComponent - Specifies whether the component is Studio input component, which will hide tree view controls and chrome. * @param selectConcept - The function to call when a concept is selected. */ export declare const TreeView: ({ document, branchId, inputComponent, selectConcept, expanded, conceptRecs, recsError, }: TreeViewProps) => JSX.Element declare interface TreeViewProps { document?: ConceptSchemeDocument branchId?: string | null selectConcept?: (conceptId: {_ref: string; _type: 'reference'; _originalId?: string}) => void inputComponent?: boolean expanded?: boolean conceptRecs?: EmbeddingsResult[] recsError?: string | null } export {}