diff --git a/README.md b/README.md index 19c1cc90..7f28d8a4 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ All new rewrite exclusively for Sanity Studio v3 - [Basic configuration](#basic-configuration) - [Advanced configuration](#advanced-configuration) - [Language field](#language-field) + - [Excluding fields](#excluding-fields) - [Querying translations](#querying-translations) - [Querying with GROQ](#querying-with-groq) - [Querying with GraphQL](#querying-with-graphql) @@ -154,7 +155,7 @@ export const createConfig({ ### Language field -The schema types that use document internationalization must also have a `string` field type with the same name configured in the `languageField` setting. Unless you want content creators to be able to change the language of a document, you may hide or disable this field since the plugin will handle writing patches to it. +The schema types that use document internationalization must also have a `string` field type with the same path name configured in the `languageField` setting. Unless you want content creators to be able to change the language of a document, you may hide or disable this field since the plugin will handle writing patches to it. ```ts // ./schema/lesson.ts @@ -166,7 +167,44 @@ defineField({ type: 'string', readOnly: true, hidden: true, -}) +}), + +// Nested value paths name are also possible e.g: +{ + name: 'option' + type: 'object', + fields: [ + // ...other fields + // languageField: 'option.language' + defineField({ + name: 'language', + type: 'string', + readOnly: true, + hidden: true, + }), + ], +}, + +// or in array... +{ + name: 'options', + type: 'array', + of: [ + name: 'option' + type: 'object', + fields: [ + // languageField: 'options[0].language' + defineField({ + name: 'language', + type: 'string', + readOnly: true, + hidden: true, + }), + // ...other fields + ], + ], +} + ``` ### Excluding fields diff --git a/package-lock.json b/package-lock.json index 92656861..5fe504e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@sanity/incompatible-plugin": "^1.0.4", "@sanity/ui": "^2.1.0", "@sanity/uuid": "^3.0.2", + "just-safe-get": "^4.2.0", "sanity-plugin-internationalized-array": "^2.0.0", "sanity-plugin-utils": "^1.6.4" }, @@ -13025,6 +13026,11 @@ "node": ">=4.0" } }, + "node_modules/just-safe-get": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/just-safe-get/-/just-safe-get-4.2.0.tgz", + "integrity": "sha512-+tS4Bvgr/FnmYxOGbwziJ8I2BFk+cP1gQHm6rm7zo61w1SbxBwWGEq/Ryy9Gb6bvnloPq6pz7Bmm4a0rjTNlXA==" + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", diff --git a/package.json b/package.json index f598a223..c956d0cc 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "@sanity/incompatible-plugin": "^1.0.4", "@sanity/ui": "^2.1.0", "@sanity/uuid": "^3.0.2", + "just-safe-get": "^4.2.0", "sanity-plugin-internationalized-array": "^2.0.0", "sanity-plugin-utils": "^1.6.4" }, diff --git a/src/actions/DeleteTranslationAction.tsx b/src/actions/DeleteTranslationAction.tsx index a2b0968d..11a83a08 100644 --- a/src/actions/DeleteTranslationAction.tsx +++ b/src/actions/DeleteTranslationAction.tsx @@ -1,5 +1,6 @@ import {TrashIcon} from '@sanity/icons' import {type ButtonTone, useToast} from '@sanity/ui' +import get from 'just-safe-get' import {useCallback, useState} from 'react' import { type DocumentActionComponent, @@ -20,7 +21,7 @@ export const DeleteTranslationAction: DocumentActionComponent = (props) => { const [isDialogOpen, setDialogOpen] = useState(false) const [translations, setTranslations] = useState([]) const onClose = useCallback(() => setDialogOpen(false), []) - const documentLanguage = doc ? doc[languageField] : null + const documentLanguage = doc ? get(doc, languageField) : null const toast = useToast() const client = useClient({apiVersion: API_VERSION}) diff --git a/src/badges/index.tsx b/src/badges/index.tsx index 436c4a98..8efe1564 100644 --- a/src/badges/index.tsx +++ b/src/badges/index.tsx @@ -1,3 +1,4 @@ +import get from 'just-safe-get' import type {DocumentBadgeDescription, DocumentBadgeProps} from 'sanity' import {useDocumentInternationalizationContext} from '../components/DocumentInternationalizationContext' @@ -8,7 +9,7 @@ export function LanguageBadge( const source = props?.draft || props?.published const {languageField, supportedLanguages} = useDocumentInternationalizationContext() - const languageId = source?.[languageField] + const languageId = source ? get(source, languageField) : null if (!languageId) { return null diff --git a/src/components/DocumentInternationalizationMenu.tsx b/src/components/DocumentInternationalizationMenu.tsx index ee935cc8..ba9a050a 100644 --- a/src/components/DocumentInternationalizationMenu.tsx +++ b/src/components/DocumentInternationalizationMenu.tsx @@ -10,6 +10,7 @@ import { useClickOutside, } from '@sanity/ui' import {uuid} from '@sanity/uuid' +import get from 'just-safe-get' import {type FormEvent, useCallback, useMemo, useState} from 'react' import {useEditState} from 'sanity' @@ -71,7 +72,7 @@ export function DocumentInternationalizationMenu( const documentIsInOneMetadataDocument = useMemo(() => { return Array.isArray(data) && data.length <= 1 }, [data]) - const sourceLanguageId = source?.[languageField] as string | undefined + const sourceLanguageId = source ? get(source, languageField) : undefined const sourceLanguageIsValid = supportedLanguages.some( (l) => l.id === sourceLanguageId )