sanity-plugin-internationalized-array 4.0.4 → 4.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -3
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/cache.ts","../src/plugin.tsx","../src/constants.ts"],"mappings":";;KAEY,QAAA;EACV,EAAA,EAAI,IAAA,CAAK,4BAAA;EACT,KAAA;AAAA;AAAA,KAGU,WAAA;AAAA,KAEA,WAAA;EACV,IAAA;EACA,IAAA,EAAM,WAAA;EACN,SAAA,EAAW,QAAA;EACX,KAAA;EACA,KAAA;EACA,MAAA;EACA,QAAA;EACA,UAAA,GAAa,IAAA,GAAO,IAAA;EACpB,KAAA;IAAA,CAAU,GAAA;IAAuB,OAAA;MAAA,CAAW,GAAA;IAAA;EAAA;AAAA;;;;KAMlC,KAAA;EACV,IAAA;EACA,KAAA;AAAA;AAAA,iBAGc,gCAAA,CACd,IAAA,WACC,IAAA,IAAQ,0BAAA;AAAA,KAIC,0BAAA;EACV,IAAA;EACA,KAAA,GAAQ,CAAA;EAvBR;;;EA2BA,KAAA;AAAA;AAAA,KAGU,gBAAA,IACV,MAAA,EAAQ,YAAA,EACR,aAAA,EAAe,MAAA,sBACZ,OAAA,CAAQ,QAAA;AAAA,KAED,eAAA;AAAA,KAEA,YAAA;EAjCuB;;;;EAsCjC,UAAA;EAhCe;;;;AAKjB;;;;;;;;EAwCE,MAAA,GAAS,MAAA;EAlCC;;;;;;;;;;;AASZ;;;;;;;;;;;;;;;;EAqDE,SAAA,EAAW,QAAA,KAAa,gBAAA;EAhDd;;;;;AAEZ;;;EAuDE,gBAAA;EATW;;;;;;;;;;;;;;;;;;;;;;;EAkCX,UAAA,YAAsB,kBAAA,GAAqB,eAAA;EAyBG;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/cache.ts","../src/plugin.tsx","../src/constants.ts"],"mappings":";;KAEY,QAAA;EACV,EAAA,EAAI,IAAA,CAAK,4BAAA;EACT,KAAA;AAAA;AAAA,KAGU,WAAA;AAAA,KAEA,WAAA;EACV,IAAA;EACA,IAAA,EAAM,WAAA;EACN,SAAA,EAAW,QAAA;EACX,KAAA;EACA,KAAA;EACA,MAAA;EACA,QAAA;EACA,UAAA,GAAa,IAAA,GAAO,IAAA;EACpB,KAAA;IAAA,CAAU,GAAA;IAAuB,OAAA;MAAA,CAAW,GAAA;IAAA;EAAA;AAAA;;;;KAMlC,KAAA;EACV,IAAA;EACA,KAAA;AAAA;AAAA,iBAGc,gCAAA,CACd,IAAA,WACC,IAAA,IAAQ,0BAAA;AAAA,KAIC,0BAAA;EACV,IAAA;EACA,KAAA,GAAQ,CAAA;EAvBR;;;EA2BA,KAAA;AAAA;AAAA,KAGU,gBAAA,IACV,MAAA,EAAQ,YAAA,EACR,aAAA,EAAe,MAAA,sBACZ,OAAA,CAAQ,QAAA;AAAA,KAED,eAAA;AAAA,KAEA,YAAA;EAjCuB;;;;EAsCjC,UAAA;EAhCe;;;;AAKjB;;;;;;;;EAwCE,MAAA,GAAS,MAAA;EAlCC;;;;;;;;;;;AASZ;;;;;;;;;;;;;;;;EAqDE,SAAA,EAAW,QAAA,KAAa,gBAAA;EAhDd;;;;;AAEZ;;;EAuDE,gBAAA;EATW;;;;;;;;;;;;;;;;;;;;;;;EAkCX,UAAA,YAAsB,kBAAA,GAAqB,eAAA;EAyBG;;AC/HhD;;ED2GE,eAAA;ECzGD;;;ACnBD;EFiIE,YAAA;;;;;EAKA,eAAA,GAAkB,eAAA;EG1I8B;;;;;;;;;EHoJhD,sBAAA,IAA0B,YAAA;AAAA;AAAA,cC/Hf,KAAA;AAAA,cCjBA,sBAAA,EAAsB,MAAA,CAAA,MAAA,CAAA,YAAA;;;AFVnC;;;;cGMa,mBAAA"}
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { createContext, useContext, useDeferredValue, use, useCallback, useEffec
|
|
|
9
9
|
import get from "lodash-es/get.js";
|
|
10
10
|
import camelCase from "lodash-es/camelCase.js";
|
|
11
11
|
import upperFirst from "lodash-es/upperFirst.js";
|
|
12
|
-
const namespace = "sanity-plugin-internationalized-array",
|
|
12
|
+
const namespace = "sanity-plugin-internationalized-array", functionKeyCache = /* @__PURE__ */ new WeakMap(), promiseCache = /* @__PURE__ */ new Map(), functionCache = /* @__PURE__ */ new Map();
|
|
13
13
|
function stringifyCacheKey(key) {
|
|
14
14
|
return JSON.stringify(key);
|
|
15
15
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/cache.ts","../src/constants.ts","../src/utils/getDocumentsToTranslate.ts","../src/utils/getLanguageDisplay.ts","../src/components/getSelectedValue.ts","../src/components/InternationalizedArrayContext.tsx","../src/components/AddButtons.tsx","../src/components/DocumentAddButtons.tsx","../src/components/InternationalizedArrayFormInput.tsx","../src/utils/hasInternationalizedArrayField.ts","../src/components/InternationalizedArrayLayout.tsx","../src/components/Preload.tsx","../src/utils/checkAllLanguagesArePresent.ts","../src/utils/createAddAllTitle.ts","../src/types.ts","../src/utils/createAddLanguagePatches.ts","../src/fieldActions/index.ts","../src/components/createFieldName.ts","../src/components/Feedback.tsx","../src/components/InternationalizedArray.tsx","../src/utils/getLanguagesFieldOption.ts","../src/schema/array.ts","../src/components/getToneFromValidation.ts","../src/components/InternationalizedInput.tsx","../src/schema/object.ts","../src/plugin.tsx"],"sourcesContent":["import type {Language, LanguageCallback} from './types'\n\nexport const namespace = 'sanity-plugin-internationalized-array'\n\nexport const version = 'v1'\n\n// Simple in-memory cache for validation functions that run outside React context\nconst validationCache = new Map<string, Language[]>()\n\n// Cache for function references to enable sharing between same functions\nconst functionCache = new Map<string, Language[]>()\n\n// Cache for function keys to avoid recalculating them\nconst functionKeyCache = new WeakMap<LanguageCallback, string>()\n\n// Cache for React.use promises\nconst promiseCache = new Map<string, Promise<Language[]>>()\n\n// Helper to create a cache key string from an array\nfunction stringifyCacheKey(key: unknown[]): string {\n return JSON.stringify(key)\n}\n\n// Preloading: store promises in cache for React.use\nexport const preload = (fn: () => Promise<Language[]>) => {\n const key = stringifyCacheKey([version, namespace])\n if (!promiseCache.has(key)) {\n promiseCache.set(key, fn())\n }\n}\n\n// Enhanced preload function that can use custom cache keys\nexport const preloadWithKey = (fn: () => Promise<Language[]>, key: (string | number)[]) => {\n const keyStr = stringifyCacheKey(key)\n if (!promiseCache.has(keyStr)) {\n promiseCache.set(keyStr, fn())\n }\n}\n\n// Cache busting: clear all promise caches\nexport const clear = () => {\n promiseCache.clear()\n}\n\n// Peeking into entries outside of suspense\nexport const peek = (selectedValue: Record<string, unknown>) => {\n const key = stringifyCacheKey([version, namespace, selectedValue])\n const promise = promiseCache.get(key)\n if (promise) {\n // Check if promise is resolved\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const status = (promise as any)._status\n if (status === 'fulfilled') {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return (promise as any)._value as Language[] | undefined\n }\n }\n return undefined\n}\n\n// Helper function to create a stable cache key that matches the component's key structure\nexport const createCacheKey = (selectedValue: Record<string, unknown>, workspaceId?: string) => {\n const selectedValueHash = JSON.stringify(selectedValue)\n return workspaceId\n ? [version, namespace, selectedValueHash, workspaceId]\n : [version, namespace, selectedValueHash]\n}\n\n// Enhanced peek function that can work with workspace context\nexport const peekWithWorkspace = (selectedValue: Record<string, unknown>, workspaceId?: string) => {\n const key = stringifyCacheKey(createCacheKey(selectedValue, workspaceId))\n const promise = promiseCache.get(key)\n if (promise) {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const status = (promise as any)._status\n if (status === 'fulfilled') {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return (promise as any)._value as Language[] | undefined\n }\n }\n return undefined\n}\n\n// Create or get cached promise for React.use\nexport const createOrGetPromise = (\n fn: () => Promise<Language[]>,\n key: (string | number | Record<string, unknown>)[],\n): Promise<Language[]> => {\n const keyStr = stringifyCacheKey(key)\n if (promiseCache.has(keyStr)) {\n return promiseCache.get(keyStr)!\n }\n const promise = fn()\n promiseCache.set(keyStr, promise)\n return promise\n}\n\n// Generate a unique key for a function reference (cached for performance)\nexport const getFunctionKey = (fn: LanguageCallback): string => {\n // Check if we already have a cached key for this function\n const cachedKey = functionKeyCache.get(fn)\n if (cachedKey) {\n return cachedKey\n }\n\n // Create a hash for functions (only when needed)\n const fnStr = fn.toString()\n let hash = 0\n // Only hash the first 100 characters for performance\n const maxLength = Math.min(fnStr.length, 100)\n for (let i = 0; i < maxLength; i++) {\n const char = fnStr.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash &= hash // Convert to 32-bit integer\n }\n const key = `anonymous_${Math.abs(hash)}`\n functionKeyCache.set(fn, key)\n return key\n}\n\n// Create a cache key that includes function identity\nexport const createFunctionCacheKey = (\n fn: LanguageCallback,\n selectedValue: Record<string, unknown>,\n workspaceId?: string,\n): string => {\n const functionKey = getFunctionKey(fn)\n const selectedValueHash = JSON.stringify(selectedValue)\n return workspaceId\n ? `${functionKey}:${selectedValueHash}:${workspaceId}`\n : `${functionKey}:${selectedValueHash}`\n}\n\n// Cache for validation functions with function awareness\nexport const getValidationCache = (key: string): Language[] | undefined => {\n return validationCache.get(key)\n}\n\nexport const setValidationCache = (key: string, languages: Language[]): void => {\n validationCache.set(key, languages)\n}\n\nexport const clearValidationCache = (): void => {\n validationCache.clear()\n}\n\n// Function-aware cache operations\nexport const getFunctionCache = (\n fn: LanguageCallback,\n selectedValue: Record<string, unknown>,\n workspaceId?: string,\n): Language[] | undefined => {\n const key = createFunctionCacheKey(fn, selectedValue, workspaceId)\n return functionCache.get(key)\n}\n\nexport const setFunctionCache = (\n fn: LanguageCallback,\n selectedValue: Record<string, unknown>,\n languages: Language[],\n workspaceId?: string,\n): void => {\n const key = createFunctionCacheKey(fn, selectedValue, workspaceId)\n functionCache.set(key, languages)\n}\n\nexport const clearFunctionCache = (): void => {\n functionCache.clear()\n}\n\n// Clear function key cache as well\nexport const clearAllCaches = (): void => {\n functionCache.clear()\n promiseCache.clear()\n // Note: WeakMap doesn't have a clear method, but it will be garbage collected\n // when the function references are no longer held\n}\n\n// Check if two functions are the same reference\nexport const isSameFunction = (fn1: LanguageCallback, fn2: LanguageCallback): boolean => {\n return fn1 === fn2 || getFunctionKey(fn1) === getFunctionKey(fn2)\n}\n","import type {PluginConfig} from './types'\n\n/**\n * The field name used to identify the language of an internationalized array item.\n *\n * In v4.x this was '_key', in v5+ this will be 'language'.\n * Having this as a constant makes the codebase easier to maintain.\n */\nexport const LANGUAGE_FIELD_NAME = '_key' as const\n\nexport const MAX_COLUMNS = {\n codeOnly: 5,\n titleOnly: 4,\n titleAndCode: 3,\n}\n\nexport const CONFIG_DEFAULT: Required<PluginConfig> = {\n languages: [],\n select: {},\n defaultLanguages: [],\n fieldTypes: [],\n apiVersion: '2025-10-15',\n buttonLocations: ['field'],\n buttonAddAll: true,\n languageDisplay: 'codeOnly',\n includeForDocumentType: (documentType) => documentType !== 'translation.metadata',\n}\n","import type {SanityDocument} from 'sanity'\n\nexport interface DocumentsToTranslate {\n path: (string | number)[]\n pathString: string\n _key: string\n _type: string\n [key: string]: unknown\n}\n\n/**\n * Recursively traverses a Sanity document (or any nested value) and collects\n * all internationalized array items found within it.\n *\n * An item is considered an internationalized array value when its `_type`\n * starts with `\"internationalizedArray\"` and ends with `\"Value\"`.\n *\n * The function walks through objects and arrays, skipping keys that start\n * with `_` (internal Sanity fields like `_id`, `_type`, `_rev`). Each\n * returned item includes the original properties plus `path` (array of\n * segments) and `pathString` (dot-joined) indicating where it was found.\n */\nexport const getDocumentsToTranslate = (\n // oxlint-disable-next-line typescript-eslint/no-redundant-type-constituents\n value: SanityDocument | unknown,\n rootPath: (string | number)[] = [],\n): DocumentsToTranslate[] => {\n if (Array.isArray(value)) {\n const arrayRootPath = [...rootPath]\n\n // if item contains internationalized return array\n const internationalizedValues = value.filter((item) => {\n if (Array.isArray(item)) return false\n\n if (typeof item === 'object') {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const type = item?._type as string | undefined\n return type?.startsWith('internationalizedArray') && type?.endsWith('Value')\n }\n return false\n })\n\n if (internationalizedValues.length > 0) {\n return internationalizedValues.map((internationalizedValue) => {\n return Object.assign({}, internationalizedValue, {\n path: arrayRootPath,\n pathString: arrayRootPath.join('.'),\n })\n })\n }\n\n if (value.length > 0) {\n return value.flatMap((item, index) =>\n getDocumentsToTranslate(item, [...arrayRootPath, index]),\n )\n }\n\n return []\n }\n if (typeof value === 'object' && value) {\n const startsWithUnderscoreRegex = /^_/\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const itemKeys = Object.keys(value).filter(\n (key) => !key.match(startsWithUnderscoreRegex),\n ) as (keyof typeof value)[]\n\n return itemKeys.flatMap((item) => {\n const selectedValue = value[item] as unknown\n const path = [...rootPath, item]\n return getDocumentsToTranslate(selectedValue, path)\n })\n }\n return []\n}\n","import type {LanguageDisplay} from '../types'\n\n/**\n * Formats a language label for display in buttons and field headers\n * based on the configured `languageDisplay` mode:\n *\n * - `'codeOnly'` -> uppercase code, e.g. `\"EN\"`\n * - `'titleOnly'` -> title as-is, e.g. `\"English\"`\n * - `'titleAndCode'` -> title with uppercase code, e.g. `\"English (EN)\"`\n *\n * Falls back to `title` for any unrecognized display mode.\n */\nexport function getLanguageDisplay(\n languageDisplay: LanguageDisplay,\n title: string,\n code: string,\n): string {\n if (languageDisplay === 'codeOnly') return code.toUpperCase()\n if (languageDisplay === 'titleOnly') return title\n if (languageDisplay === 'titleAndCode') return `${title} (${code.toUpperCase()})`\n return title\n}\n","import get from 'lodash-es/get.js'\n\n/**\n * Extracts a subset of values from a Sanity document based on a `select`\n * mapping (as configured in the plugin's `select` option).\n *\n * Each key in `select` becomes a key in the returned object, with its value\n * resolved from the document using the corresponding dot-path (via lodash `get`).\n *\n * Array values are filtered to remove incomplete references (objects with\n * `_type: 'reference'` but no `_ref`), since those represent empty reference\n * fields that should be ignored.\n *\n * Returns an empty object when either `select` or `document` is undefined.\n */\nexport const getSelectedValue = (\n select: Record<string, string> | undefined,\n document:\n | {\n [x: string]: unknown\n }\n | undefined,\n): Record<string, unknown> => {\n if (!select || !document) {\n return {}\n }\n\n const selection: Record<string, string> = select || {}\n const selectedValue: Record<string, unknown> = {}\n for (const [key, path] of Object.entries(selection)) {\n let value = get(document, path)\n if (Array.isArray(value)) {\n // If there are references in the array, ensure they have `_ref` set, otherwise they are considered empty and can safely be ignored\n value = value.filter((item) =>\n typeof item === 'object' ? item?._type === 'reference' && '_ref' in item : true,\n )\n }\n selectedValue[key] = value\n }\n\n return selectedValue\n}\n","import {useLanguageFilterStudioContext} from '@sanity/language-filter'\nimport type React from 'react'\nimport {createContext, use, useContext, useDeferredValue, useMemo} from 'react'\nimport {useClient, useWorkspace} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport {createCacheKey, createOrGetPromise, setFunctionCache} from '../cache'\nimport {CONFIG_DEFAULT} from '../constants'\nimport type {Language, PluginConfig} from '../types'\nimport {getSelectedValue} from './getSelectedValue'\n\n// This provider makes the plugin config available to all components in the document form\n// But with languages resolved and filtered languages updated base on @sanity/language-filter\n\nexport type InternationalizedArrayContextProps = Required<PluginConfig> & {\n languages: Language[]\n filteredLanguages: Language[]\n}\n\nexport const InternationalizedArrayContext = createContext<InternationalizedArrayContextProps>({\n ...CONFIG_DEFAULT,\n languages: [],\n filteredLanguages: [],\n})\n\nexport function useInternationalizedArrayContext(): InternationalizedArrayContextProps {\n return useContext(InternationalizedArrayContext)\n}\n\ntype InternationalizedArrayProviderProps = {\n internationalizedArray: Required<PluginConfig>\n documentType: string\n}\n\nexport function InternationalizedArrayProvider(\n props: React.PropsWithChildren<InternationalizedArrayProviderProps>,\n): React.ReactElement {\n const {internationalizedArray, documentType} = props\n\n const client = useClient({apiVersion: internationalizedArray.apiVersion})\n const workspace = useWorkspace()\n const {formState} = useDocumentPane()\n const deferredDocument = useDeferredValue(formState?.value)\n const selectedValue = useMemo(\n () => getSelectedValue(internationalizedArray.select, deferredDocument),\n [internationalizedArray.select, deferredDocument],\n )\n\n // Use a stable workspace identifier to prevent unnecessary re-renders\n const workspaceId = useMemo(() => {\n // Use workspace name if available, otherwise create a stable hash\n if (workspace?.name) {\n return workspace.name\n }\n // Create a stable hash from workspace properties that matter for caching\n const workspaceKey = {\n name: workspace?.name,\n title: workspace?.title,\n // Add other stable properties as needed\n }\n return JSON.stringify(workspaceKey)\n }, [workspace])\n\n // Memoize the cache key to prevent expensive JSON.stringify calls\n const cacheKey = useMemo(\n () => createCacheKey(selectedValue, workspaceId),\n [selectedValue, workspaceId],\n )\n\n // Fetch or return languages\n const languagesPromise = useMemo(() => {\n if (Array.isArray(internationalizedArray.languages)) {\n return null // Return null for synchronous arrays\n }\n\n // Create or get cached promise for React.use\n return createOrGetPromise(async () => {\n if (typeof internationalizedArray.languages === 'function') {\n const result = await internationalizedArray.languages(client, selectedValue)\n // Populate function cache for use outside React context\n setFunctionCache(internationalizedArray.languages, selectedValue, result, workspaceId)\n return result\n }\n return internationalizedArray.languages\n }, cacheKey)\n }, [internationalizedArray, client, selectedValue, workspaceId, cacheKey])\n\n // Use React.use to handle the promise with Suspense, or return array directly\n const languages = languagesPromise\n ? use(languagesPromise)\n : // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n (internationalizedArray.languages as Language[])\n\n // Filter out some languages if language filter is enabled\n const {selectedLanguageIds, options: languageFilterOptions} = useLanguageFilterStudioContext()\n\n const filteredLanguages = useMemo(() => {\n const languageFilterEnabled = languageFilterOptions.documentTypes.includes(documentType)\n\n return languageFilterEnabled\n ? languages.filter((language) => selectedLanguageIds.includes(language.id))\n : languages\n }, [documentType, languageFilterOptions, languages, selectedLanguageIds])\n\n const context = useMemo(\n () => ({...internationalizedArray, languages, filteredLanguages}),\n [filteredLanguages, internationalizedArray, languages],\n )\n\n return (\n <InternationalizedArrayContext.Provider value={context}>\n {props.children}\n </InternationalizedArrayContext.Provider>\n )\n}\n","import {AddIcon} from '@sanity/icons'\nimport {Button, Grid} from '@sanity/ui'\n\nimport {MAX_COLUMNS} from '../constants'\nimport {getLanguageDisplay} from '../utils/getLanguageDisplay'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\ntype AddButtonsProps = {\n readOnly: boolean\n handleClick: (languageId: string) => void\n // Keys of languages that are already in use\n languagesInUse: string[]\n}\n\n/**\n * Renders a grid of \"add language\" buttons — one per configured language.\n *\n * Returns `null` when the `languages` array is empty.\n *\n * Each button is disabled when:\n * - `readOnly` is `true`, or\n * - the language already exists in the current `value` array\n * (matched via `LANGUAGE_FIELD_NAME`).\n *\n * The button label is formatted according to the `languageDisplay` setting\n * from the plugin context (e.g. code-only, title-only, or both).\n * An `AddIcon` is shown unless there are more languages than fit in one row\n * and the display mode is `'codeOnly'`.\n */\nfunction AddButtons(props: AddButtonsProps) {\n const {readOnly, languagesInUse, handleClick} = props\n const {languageDisplay, filteredLanguages: languages} = useInternationalizedArrayContext()\n\n if (!languages.length) return null\n\n return (\n <Grid columns={Math.min(languages.length, MAX_COLUMNS[languageDisplay])} gap={2}>\n {languages.map((language) => {\n const languageTitle: string = getLanguageDisplay(\n languageDisplay,\n language.title,\n language.id,\n )\n return (\n <Button\n key={language.id}\n tone=\"primary\"\n mode=\"ghost\"\n fontSize={1}\n data-testid={`add-${language.id}`}\n disabled={readOnly || languagesInUse.includes(language.id)}\n text={languageTitle}\n // Only show plus icon if there's one row or less AND only showing codes\n icon={\n languages.length > MAX_COLUMNS[languageDisplay] && languageDisplay === 'codeOnly'\n ? undefined\n : AddIcon\n }\n value={language.id}\n onClick={() => handleClick(language.id)}\n />\n )\n })}\n </Grid>\n )\n}\n\nexport default AddButtons\n","import {Box, Stack, Text, useToast} from '@sanity/ui'\nimport {type ReactElement, useCallback} from 'react'\nimport {\n type FormInsertPatch,\n type FormSetIfMissingPatch,\n insert,\n isSanityDocument,\n PatchEvent,\n setIfMissing,\n useGetFormValue,\n useSchema,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport type {DocumentsToTranslate} from '../utils/getDocumentsToTranslate'\nimport {getDocumentsToTranslate} from '../utils/getDocumentsToTranslate'\nimport AddButtons from './AddButtons'\n\n/**\n * Document-level \"add translation\" panel that appears outside individual\n * internationalized array fields (when `buttonLocations` includes `'document'`).\n *\n * Renders a heading and a row of per-language buttons. When a language button\n * is clicked the component:\n *\n * 1. Scans the current document for all internationalized array fields\n * using `getDocumentsToTranslate`.\n * 2. Filters out fields that already contain a translation for the selected\n * language, and deduplicates by field path.\n * 3. Shows an error toast if no eligible fields remain.\n * 4. Creates `setIfMissing` + `insert` patches to add the new language\n * entry to each eligible field, dispatching them via `onChange`.\n *\n * For Portable Text and other array-based value fields, the initial value\n * is set to an empty array (`[]`) rather than `undefined`.\n */\nexport default function DocumentAddButtons(): ReactElement {\n const getFormValue = useGetFormValue()\n\n const toast = useToast()\n const {onChange} = useDocumentPane()\n const schema = useSchema()\n\n // Helper function to determine if a field should be initialized as an array\n const getInitialValueForType = useCallback(\n (typeName: string): unknown => {\n if (!typeName) return undefined\n\n // Extract the base type name from internationalized array type\n // e.g., \"internationalizedArrayBodyValue\" -> \"body\"\n const match = typeName.match(/^internationalizedArray(.+)Value$/)\n if (!match || !match[1]) return undefined\n\n const baseTypeName = match[1].charAt(0).toLowerCase() + match[1].slice(1)\n\n // Check if it's a known array-based type (Portable Text fields)\n const arrayBasedTypes = new Set(['body', 'htmlContent', 'blockContent', 'portableText'])\n if (arrayBasedTypes.has(baseTypeName)) {\n return []\n }\n\n // Try to look up the schema type to determine if it's an array\n const schemaType = schema.get(typeName)\n if (schemaType && 'fields' in schemaType) {\n // Check if this is an object type with a 'value' field\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const fields = schemaType.fields as Array<{\n name: string\n type?: {jsonType?: string; name?: string; type?: string; of?: unknown}\n }>\n const valueField = fields.find((f) => f.name === 'value')\n if (valueField) {\n const fieldType = valueField.type\n // Check if the value field is an array type\n if (\n fieldType?.jsonType === 'array' ||\n fieldType?.name === 'array' ||\n fieldType?.type === 'array' ||\n fieldType?.of !== undefined ||\n (fieldType?.name && arrayBasedTypes.has(fieldType.name))\n ) {\n return []\n }\n }\n }\n\n return undefined\n },\n [schema],\n )\n\n const handleDocumentButtonClick = useCallback(\n async (languageId: string) => {\n const value = getFormValue([])\n if (!isSanityDocument(value)) {\n toast.push({\n status: 'error',\n title: 'No document value found',\n })\n return\n }\n const documentsToTranslation = getDocumentsToTranslate(value, [])\n\n const alreadyTranslated = documentsToTranslation.filter(\n (translation) => translation?.[LANGUAGE_FIELD_NAME] === languageId,\n )\n const removeDuplicates = documentsToTranslation.reduce<DocumentsToTranslate[]>(\n (filteredTranslations, translation) => {\n if (\n alreadyTranslated.filter(\n (alreadyTranslation) => alreadyTranslation.pathString === translation.pathString,\n ).length > 0\n ) {\n return filteredTranslations\n }\n const translationAlreadyExists = filteredTranslations.filter(\n (filteredTranslation) => filteredTranslation.path === translation.path,\n )\n\n if (translationAlreadyExists.length > 0) {\n return filteredTranslations\n }\n filteredTranslations.push(translation)\n return filteredTranslations\n },\n [],\n )\n if (removeDuplicates.length === 0) {\n toast.push({\n status: 'error',\n title: 'No internationalizedArray fields found in document root',\n })\n return\n }\n\n // Write a new patch for each empty field\n const patches: (FormSetIfMissingPatch | FormInsertPatch)[] = []\n\n for (const toTranslate of removeDuplicates) {\n const path = toTranslate.path\n\n // Get the appropriate initial value for this field type\n const initialValue = getInitialValueForType(toTranslate._type)\n\n const ifMissing = setIfMissing([], path)\n const insertValue = insert(\n [\n {\n [LANGUAGE_FIELD_NAME]: languageId,\n _type: toTranslate._type,\n value: initialValue, // Use the determined initial value instead of undefined\n },\n ],\n 'after',\n [...path, -1],\n )\n patches.push(ifMissing)\n patches.push(insertValue)\n }\n\n onChange(PatchEvent.from(patches.flat()))\n },\n [getInitialValueForType, onChange, toast, getFormValue],\n )\n return (\n <Stack space={3}>\n <Box>\n <Text size={1} weight=\"semibold\">\n Add translation to internationalized fields\n </Text>\n </Box>\n <AddButtons readOnly={false} handleClick={handleDocumentButtonClick} languagesInUse={[]} />\n </Stack>\n )\n}\n","import {Stack} from '@sanity/ui'\nimport type {ObjectInputProps} from 'sanity'\n\nimport type {PluginConfig} from '../types'\nimport DocumentAddButtons from './DocumentAddButtons'\n\n/**\n * An input component for the root object of an internationalized array.\n * It renders the document add buttons if the buttonLocations include 'document'.\n */\nexport function InternationalizedArrayFormInput(\n props: ObjectInputProps & {pluginConfig: PluginConfig},\n) {\n const showDocumentButtons = props.pluginConfig?.buttonLocations?.includes('document')\n\n if (showDocumentButtons) {\n return (\n <Stack space={5}>\n <DocumentAddButtons />\n {props.renderDefault(props)}\n </Stack>\n )\n }\n return props.renderDefault(props)\n}\n","import {isDocumentSchemaType, type ObjectField, type SchemaType} from 'sanity'\n\n/**\n * Returns true when a document schema contains any field (including nested\n * object/array item fields) whose type name starts with `internationalizedArray`.\n *\n * Traversal short-circuits on first match to avoid unnecessary work.\n */\nexport function hasInternationalizedArrayField(schemaType: SchemaType): boolean {\n if (!isDocumentSchemaType(schemaType)) {\n return false\n }\n\n return hasInternationalizedArrayInFields(schemaType.fields)\n}\n\nfunction hasInternationalizedArrayInFields(fields: ObjectField[]): boolean {\n for (const field of fields) {\n if (field.type.name.startsWith('internationalizedArray')) {\n return true\n }\n\n if (field.type.jsonType === 'object' && hasInternationalizedArrayInFields(field.type.fields)) {\n return true\n }\n\n if (field.type.jsonType === 'array' && field.type.of.length > 0) {\n for (const item of field.type.of) {\n if (\n 'name' in item &&\n typeof item.name === 'string' &&\n item.name.startsWith('internationalizedArray')\n ) {\n return true\n }\n\n if ('fields' in item && Array.isArray(item.fields)) {\n if (hasInternationalizedArrayInFields(item.fields)) {\n return true\n }\n }\n }\n }\n }\n\n return false\n}\n","import {useSchema, type DocumentLayoutProps} from 'sanity'\n\nimport type {PluginConfig} from '../types'\nimport {hasInternationalizedArrayField} from '../utils/hasInternationalizedArrayField'\nimport {InternationalizedArrayProvider} from './InternationalizedArrayContext'\n\nexport function InternationalizedArrayLayout(\n props: DocumentLayoutProps & {pluginConfig: Required<PluginConfig>},\n) {\n const schema = useSchema()\n const schemaType = schema.get(props.documentType)\n\n if (!schemaType) {\n console.error(`Schema type not found: ${props.documentType}`)\n return props.renderDefault(props)\n }\n\n const hasInternationalizedArray = hasInternationalizedArrayField(schemaType)\n if (hasInternationalizedArray && props.pluginConfig.includeForDocumentType(props.documentType)) {\n return (\n <InternationalizedArrayProvider\n internationalizedArray={props.pluginConfig}\n documentType={props.documentType}\n >\n {props.renderDefault(props)}\n </InternationalizedArrayProvider>\n )\n }\n\n return props.renderDefault(props)\n}\n","import {useClient} from 'sanity'\n\nimport {createCacheKey, peek, preloadWithKey, setFunctionCache} from '../cache'\nimport type {PluginConfig} from '../types'\n\nexport default function Preload(props: Required<Pick<PluginConfig, 'apiVersion' | 'languages'>>) {\n const client = useClient({apiVersion: props.apiVersion})\n\n // Use the same cache key structure as the main component\n // This should match the main component when selectedValue is empty\n const cacheKey = createCacheKey({})\n\n if (!Array.isArray(peek({}))) {\n preloadWithKey(async () => {\n if (Array.isArray(props.languages)) {\n return props.languages\n }\n const result = await props.languages(client, {})\n // Populate function cache for sharing with other components\n // Use the same key structure as the main component\n setFunctionCache(props.languages, {}, result)\n return result\n }, cacheKey)\n }\n\n return null\n}\n","import {LANGUAGE_FIELD_NAME} from '../constants'\nimport type {Language, InternationalizedArrayItem} from '../types'\n\n/**\n * Checks whether every language in the provided list has a corresponding entry\n * in the value array. It extracts language IDs from value items using\n * `LANGUAGE_FIELD_NAME` and compares them against the expected language IDs.\n *\n * Returns `true` only when the value array length matches the number of unique\n * languages and every value language ID is found in the languages list\n * (order does not matter). The length check ensures duplicates in value are\n * correctly rejected.\n */\nexport function checkAllLanguagesArePresent(\n languages: Language[],\n value: InternationalizedArrayItem[] | undefined,\n): boolean {\n const filteredLanguageIds = new Set(languages.map((l) => l.id))\n const languagesInUseIds = value ? value.map((v) => v[LANGUAGE_FIELD_NAME]) : []\n\n if (languagesInUseIds.length !== filteredLanguageIds.size) return false\n if (new Set(languagesInUseIds).size !== languagesInUseIds.length) return false\n return languagesInUseIds.every((key) => filteredLanguageIds.has(key))\n}\n","import type {Language, InternationalizedArrayItem} from '../types'\n\n/**\n * Generates the label text for the \"add all / add missing languages\" button.\n *\n * - When there is no existing value: returns `\"Add {title} Field\"` for a\n * single language, or `\"Add all languages\"` for multiple.\n * - When some values already exist: returns `\"Add missing language\"` (singular)\n * or `\"Add missing languages\"` (plural) depending on how many are left.\n */\nexport function createAddAllTitle(\n value: InternationalizedArrayItem[] | undefined,\n languages: Language[],\n): string {\n if (value?.length) {\n return `Add missing ${languages.length - value.length === 1 ? `language` : `languages`}`\n }\n\n return languages.length === 1 && languages[0]\n ? `Add ${languages[0].title} Field`\n : `Add all languages`\n}\n","import type {FieldDefinition, Rule, RuleTypeConstraint, SanityClient} from 'sanity'\n\nexport type Language = {\n id: Intl.UnicodeBCP47LocaleIdentifier\n title: string\n}\n\nexport type AllowedType = 'string' | 'number' | 'boolean' | 'text' | 'reference'\n\nexport type ArrayConfig = {\n name: string\n type: AllowedType\n languages: Language[]\n title?: string\n group?: string\n hidden?: boolean | (() => boolean)\n readOnly?: boolean | (() => boolean)\n validation?: Rule | Rule[]\n field?: {[key: string]: unknown; options: {[key: string]: unknown}}\n}\n\n/**\n * @deprecated Use InternationalizedArrayItem instead\n */\nexport type Value = {\n _key: string\n value?: unknown\n}\n\nexport function isInternationalizedArrayItemType(\n type: string,\n): type is InternationalizedArrayItem['_type'] {\n return type.startsWith('internationalizedArray') && type.endsWith('Value')\n}\n\nexport type InternationalizedArrayItem<T = unknown> = {\n _key: string\n value?: T\n /**\n * string that starts with \"internationalizedArray\" and ends with \"Value\"\n */\n _type: `internationalizedArray${string}Value`\n}\n\nexport type LanguageCallback = (\n client: SanityClient,\n selectedValue: Record<string, unknown>,\n) => Promise<Language[]>\n\nexport type LanguageDisplay = 'titleOnly' | 'codeOnly' | 'titleAndCode'\n\nexport type PluginConfig = {\n /**\n * https://www.sanity.io/docs/api-versioning\n * @defaultValue '2025-10-15'\n */\n apiVersion?: string\n /**\n * Specify fields that should be available in the language callback:\n * ```tsx\n * {\n * select: {\n * markets: 'markets'\n * },\n * languages: (client, {markets}) =>\n * query.fetch(groq`*[_type == \"language\" && market in $markets]{id,title}`, {markets})\n * }\n * ```\n */\n select?: Record<string, string>\n /**\n * You can give it an array of language definitions:\n * ```tsx\n * {\n * languages: [\n * {id: 'en', title: 'English'},\n * {id: 'fr', title: 'French'}\n * ]\n * }\n * ```\n * You can load them async by passing a function that returns a promise:\n * ```tsx\n * {\n * languages: async () => {\n * const response = await fetch('https://example.com/languages')\n * return response.json()\n * }\n * }\n * ```\n * You can query your dataset for languages::\n * ```tsx\n * {\n * languages: (client) =>\n * query.fetch(groq`*[_type == \"language\"]{id,title}`)\n * }\n * ```\n */\n languages: Language[] | LanguageCallback\n /**\n * You can specify a list of language IDs that should be pre-filled when creating a new document\n * ```tsx\n * {\n * defaultLanguages: ['en']\n * }\n * ```\n */\n defaultLanguages?: string[]\n /**\n * Can be a string matching core field types, as well as custom ones:\n * ```tsx\n * {\n * fieldTypes: [\n * \"date\", \"datetime\", \"file\", \"image\", \"number\", \"string\", \"text\", \"url\"\n * ]\n * }\n * ```\n * You can also define a type directly:\n * ```tsx\n * {\n * fieldTypes: [\n * defineField({\n * name: 'featuredProduct',\n * type: 'reference',\n * to: [{type: 'product'}]\n * hidden: (({document}) => !document?.title)\n * })\n * ]\n * }\n * ```\n */\n // oxlint-disable-next-line typescript-eslint/no-redundant-type-constituents\n fieldTypes: (string | RuleTypeConstraint | FieldDefinition)[]\n /**\n * Locations where the \"+ EN\" add language buttons are visible\n * @defaultValue ['field']\n * */\n buttonLocations?: ('field' | 'unstable__fieldAction' | 'document')[]\n /**\n * Show or hide the \"Add missing languages\" button\n * @defaultValue true\n * */\n buttonAddAll?: boolean\n /**\n * How to display the languages on buttons and fields\n * @defaultValue 'code'\n * */\n languageDisplay?: LanguageDisplay\n /**\n * @internal\n * Function to determine if the plugin layout and root input should be included for a given document type.\n * @defaultValue (documentType) => documentType !== 'translation.metadata'\n * @example\n * {\n * includeForDocumentType: (documentType) => documentType === 'translation.metadata'\n * }\n */\n includeForDocumentType?: (documentType: string) => boolean\n}\n","import {type FormInsertPatch, insert, type Path} from 'sanity'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport {\n type Language,\n type InternationalizedArrayItem,\n isInternationalizedArrayItemType,\n} from '../types'\n\ntype AddConfig = {\n // New keys to add to the field\n addLanguageKeys: string[]\n // Schema of the current field\n schemaTypeName: string\n // All languages registered in the plugin\n languages: Language[]\n // Languages that are currently visible\n filteredLanguages: Language[]\n // Current value of the internationalizedArray field\n value?: InternationalizedArrayItem[]\n // Path to this item\n path?: Path\n}\n\n/**\n * Creates an array of Sanity `FormInsertPatch` objects that add new language\n * entries to an internationalized array field.\n *\n * If `addLanguageKeys` is provided, patches are created for those specific\n * language IDs. Otherwise, patches are created for all filtered languages\n * that are not already present in the current `value` array, for example when adding all missing languages.\n *\n * Each new item is assigned the correct `_type` (derived from the schema)\n * and the language identifier via `LANGUAGE_FIELD_NAME`.\n *\n * Insertions are ordered to maintain the same sequence as the master\n * `languages` list: each new item is inserted before the next existing\n * language in the value array, or appended at the end if no subsequent\n * language exists.\n */\nexport function createAddLanguagePatches(config: AddConfig): FormInsertPatch[] {\n const {addLanguageKeys, schemaTypeName, languages, filteredLanguages, value, path = []} = config\n\n const type = `${schemaTypeName}Value`\n if (!isInternationalizedArrayItemType(type)) {\n throw new Error(`Invalid internationalized array type: ${type}`)\n }\n const itemBase = {_type: type}\n\n // Create new items\n const getNewItems = () => {\n if (Array.isArray(addLanguageKeys) && addLanguageKeys.length > 0) {\n return addLanguageKeys\n .filter((id) => {\n if (value?.length) {\n // Check if the language is already in the value and filter it out if it exists to avoid duplicates\n return !value.find((v) => v[LANGUAGE_FIELD_NAME] === id)\n }\n return true\n })\n .map((id) => Object.assign({}, itemBase, {[LANGUAGE_FIELD_NAME]: id}))\n }\n\n return filteredLanguages\n .filter((language) => {\n return value?.length ? !value.find((v) => v[LANGUAGE_FIELD_NAME] === language.id) : true\n })\n .map((language) => Object.assign({}, itemBase, {[LANGUAGE_FIELD_NAME]: language.id}))\n }\n const newItems = getNewItems()\n\n // Insert new items in the correct order\n const languagesInUse = value?.length ? value.map((v) => v) : []\n\n const insertions = newItems.map((item) => {\n // What's the original index of this language?\n const itemLanguage = item[LANGUAGE_FIELD_NAME]\n const languageIndex = languages.findIndex((l) => itemLanguage === l.id)\n\n // What languages are there beyond that index?\n const remainingLanguages = languages.slice(languageIndex + 1)\n\n // So what is the index in the current value array of the next language in the language array?\n const nextLanguageIndex = languagesInUse.findIndex((l) =>\n remainingLanguages.find((r) => r.id === l[LANGUAGE_FIELD_NAME]),\n )\n\n // Keep local state up to date incase multiple insertions are being made\n if (nextLanguageIndex < 0) {\n languagesInUse.push(item)\n } else {\n languagesInUse.splice(nextLanguageIndex, 0, item)\n }\n\n return nextLanguageIndex < 0\n ? // No next language (-1), add to end of array\n insert([item], 'after', [...path, nextLanguageIndex])\n : // Next language found, insert before that\n insert([item], 'before', [...path, nextLanguageIndex])\n })\n\n return insertions\n}\n","import {AddIcon, TranslateIcon} from '@sanity/icons'\nimport {useCallback} from 'react'\nimport {\n defineDocumentFieldAction,\n type DocumentFieldActionItem,\n type DocumentFieldActionProps,\n PatchEvent,\n setIfMissing,\n useFormValue,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport {useInternationalizedArrayContext} from '../components/InternationalizedArrayContext'\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport type {Language, InternationalizedArrayItem} from '../types'\nimport {checkAllLanguagesArePresent} from '../utils/checkAllLanguagesArePresent'\nimport {createAddAllTitle} from '../utils/createAddAllTitle'\nimport {createAddLanguagePatches} from '../utils/createAddLanguagePatches'\n\nconst createTranslateFieldActions: (\n fieldActionProps: DocumentFieldActionProps,\n context: {\n languages: Language[]\n filteredLanguages: Language[]\n },\n) => DocumentFieldActionItem[] = (fieldActionProps, {languages, filteredLanguages}) =>\n languages.map((language) => {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const value = useFormValue(fieldActionProps.path) as InternationalizedArrayItem[]\n const disabled =\n value && Array.isArray(value)\n ? Boolean(value?.find((item) => item[LANGUAGE_FIELD_NAME] === language.id))\n : false\n const hidden = !filteredLanguages.some((f) => f.id === language.id)\n\n const {onChange} = useDocumentPane()\n\n const onAction = useCallback(() => {\n const {schemaType, path} = fieldActionProps\n\n const addLanguageKeys = [language.id]\n const patches = createAddLanguagePatches({\n addLanguageKeys,\n schemaTypeName: schemaType.name,\n languages,\n filteredLanguages,\n value,\n path,\n })\n\n onChange(PatchEvent.from([setIfMissing([], path), ...patches]))\n }, [language.id, value, onChange])\n\n return {\n type: 'action',\n icon: AddIcon,\n onAction,\n title: language.title,\n hidden,\n disabled,\n }\n })\n\nconst AddMissingTranslationsFieldAction: (\n fieldActionProps: DocumentFieldActionProps,\n context: {\n languages: Language[]\n filteredLanguages: Language[]\n },\n) => DocumentFieldActionItem = (fieldActionProps, {languages, filteredLanguages}) => {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const value = useFormValue(fieldActionProps.path) as InternationalizedArrayItem[]\n const disabled = value && value.length === filteredLanguages.length\n const hidden = checkAllLanguagesArePresent(filteredLanguages, value)\n\n const {onChange} = useDocumentPane()\n\n const onAction = useCallback(() => {\n const {schemaType, path} = fieldActionProps\n\n const addLanguageKeys: string[] = []\n const patches = createAddLanguagePatches({\n addLanguageKeys,\n schemaTypeName: schemaType.name,\n languages,\n filteredLanguages,\n value,\n path,\n })\n\n onChange(PatchEvent.from([setIfMissing([], path), ...patches]))\n }, [fieldActionProps, filteredLanguages, languages, onChange, value])\n\n return {\n type: 'action',\n icon: AddIcon,\n onAction,\n title: createAddAllTitle(value, filteredLanguages),\n disabled,\n hidden,\n }\n}\n\nexport const internationalizedArrayFieldAction = defineDocumentFieldAction({\n name: 'internationalizedArray',\n useAction(fieldActionProps) {\n const isInternationalizedArrayField =\n fieldActionProps?.schemaType?.type?.name.startsWith('internationalizedArray')\n const {languages, filteredLanguages} = useInternationalizedArrayContext()\n\n const translateFieldActions = createTranslateFieldActions(fieldActionProps, {\n languages,\n filteredLanguages,\n })\n\n return {\n type: 'group',\n icon: TranslateIcon,\n title: 'Add Translation',\n renderAsButton: true,\n children: isInternationalizedArrayField\n ? [\n ...translateFieldActions,\n AddMissingTranslationsFieldAction(fieldActionProps, {\n languages,\n filteredLanguages,\n }),\n ]\n : [],\n hidden: !isInternationalizedArrayField,\n }\n },\n})\n","import camelCase from 'lodash-es/camelCase.js'\nimport upperFirst from 'lodash-es/upperFirst.js'\n\n/**\n * Converts a string to PascalCase (e.g. `\"my-field\"` -> `\"MyField\"`).\n */\nexport function pascalCase(string: string): string {\n return upperFirst(camelCase(string))\n}\n\n/**\n * Generates the schema type name for an internationalized array field.\n *\n * - Without the value suffix: `\"internationalizedArray{PascalName}\"`\n * (used for the outer array type)\n * - With the value suffix: `\"internationalizedArray{PascalName}Value\"`\n * (used for the inner object type that wraps each language entry)\n *\n * For example, `createFieldName('block-content', true)` returns\n * `\"internationalizedArrayBlockContentValue\"`.\n */\nexport function createFieldName(name: string, addValue = false): string {\n return addValue\n ? [`internationalizedArray`, pascalCase(name), `Value`].join(``)\n : [`internationalizedArray`, pascalCase(name)].join(``)\n}\n","import {Card, Code, Stack, Text} from '@sanity/ui'\nimport type React from 'react'\n\nconst schemaExample = {\n languages: [\n {id: 'en', title: 'English'},\n {id: 'no', title: 'Norsk'},\n ],\n}\n\nexport default function Feedback(): React.ReactElement {\n return (\n <Card tone=\"caution\" border radius={2} padding={3}>\n <Stack space={4}>\n <Text>\n An array of language objects must be passed into the <code>internationalizedArray</code>{' '}\n helper function, each with an <code>id</code> and <code>title</code> field. Example:\n </Text>\n <Card padding={2} border radius={2}>\n <Code size={1} language=\"javascript\">\n {JSON.stringify(schemaExample, null, 2)}\n </Code>\n </Card>\n </Stack>\n </Card>\n )\n}\n","import {AddIcon} from '@sanity/icons'\nimport {useLanguageFilterStudioContext} from '@sanity/language-filter'\nimport {Button, Card, Stack, Text, useToast} from '@sanity/ui'\nimport type React from 'react'\nimport {useCallback, useEffect, useMemo} from 'react'\nimport {\n type ArrayOfObjectsInputProps,\n ArrayOfObjectsItem,\n MemberItemError,\n set,\n setIfMissing,\n useFormValue,\n useGetFormValue,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport type {InternationalizedArrayItem} from '../types'\nimport {checkAllLanguagesArePresent} from '../utils/checkAllLanguagesArePresent'\nimport {createAddAllTitle} from '../utils/createAddAllTitle'\nimport {createAddLanguagePatches} from '../utils/createAddLanguagePatches'\nimport AddButtons from './AddButtons'\nimport Feedback from './Feedback'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\n/**\n * Main array input component for internationalized array fields.\n *\n * Replaces the default Sanity array input and manages the full lifecycle of\n * language entries:\n *\n * - **Language filter integration**: When `@sanity/language-filter` is active\n * for the current document type, array members are filtered to only show\n * languages matching the user's selection.\n * - **Adding languages**: Exposes per-language buttons and an \"Add all / Add\n * missing languages\" button (controlled by `buttonAddAll` and\n * `buttonLocations` config). Dispatches `setIfMissing` + `insert` patches.\n * - **Default languages**: Automatically adds entries for languages listed in\n * `defaultLanguages` when a document is first created or when those entries\n * are missing.\n * - **Ordering**: Detects when value items are out of order relative to the\n * master `languages` list and automatically re-sorts them.\n * - **Validation**: Shows a `<Feedback>` component if the languages\n * configuration is invalid (e.g. missing `id` or `title`).\n * - **Empty state**: Displays a \"no translations\" message when the field has\n * no entries and the add buttons are not visible.\n */\nexport default function InternationalizedArray(\n props: ArrayOfObjectsInputProps,\n): React.ReactElement {\n const {members, value: _value, schemaType, onChange, readOnly: documentReadOnly} = props\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion\n const value = _value as InternationalizedArrayItem[]\n const readOnly = typeof schemaType.readOnly === 'boolean' ? schemaType.readOnly : false\n const toast = useToast()\n\n const getFormValue = useGetFormValue()\n const {languages, filteredLanguages, defaultLanguages, buttonAddAll, buttonLocations} =\n useInternationalizedArrayContext()\n\n // Support updating the UI if languageFilter is installed\n const {selectedLanguageIds, options: languageFilterOptions} = useLanguageFilterStudioContext()\n const documentType = useFormValue(['_type'])\n const languageFilterEnabled =\n typeof documentType === 'string' && languageFilterOptions.documentTypes.includes(documentType)\n\n const filteredMembers = useMemo(\n () =>\n languageFilterEnabled\n ? members.filter((member) => {\n // This member is the outer object created by the plugin\n // Satisfy TS\n if (member.kind !== 'item') {\n return false\n }\n\n // This is the inner \"value\" field member created by this plugin\n const valueMember = member.item.members[0]\n\n // Satisfy TS\n if (!valueMember || valueMember.kind !== 'field') {\n return false\n }\n\n return languageFilterOptions.filterField(\n member.item.schemaType,\n valueMember,\n selectedLanguageIds,\n )\n })\n : members,\n [languageFilterEnabled, members, languageFilterOptions, selectedLanguageIds],\n )\n\n const handleAddLanguages = useCallback(\n (addLanguageKeys: string[] | string) => {\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion\n const formValue = getFormValue(props.path) as InternationalizedArrayItem[]\n if (!filteredLanguages?.length) {\n return\n }\n\n const patches = createAddLanguagePatches({\n addLanguageKeys: Array.isArray(addLanguageKeys) ? addLanguageKeys : [addLanguageKeys],\n schemaTypeName: schemaType.name,\n languages,\n filteredLanguages,\n value: formValue,\n })\n\n onChange([setIfMissing([]), ...patches])\n },\n [filteredLanguages, languages, onChange, schemaType, getFormValue, props.path],\n )\n\n const {isDeleting} = useDocumentPane()\n\n // Create a stable dependency string that only changes when language keys change\n const languageKeysFromValue = value\n ?.map((v) => v[LANGUAGE_FIELD_NAME] ?? v._key)\n .filter(Boolean)\n .join(',')\n\n const addedLanguages = useMemo(() => {\n const languageKeys = languageKeysFromValue?.split(',') || []\n if (!languageKeys?.length) return []\n if (!languages?.length) return []\n\n return languages.filter((l) => languageKeys?.find((key) => key === l.id)).map((l) => l.id)\n }, [languageKeysFromValue, languages])\n\n useEffect(() => {\n const hasAddedDefaultLanguages = defaultLanguages\n .filter((language) => languages.find((l) => l.id === language))\n .every((language) => addedLanguages.includes(language))\n\n if (!isDeleting && !hasAddedDefaultLanguages) {\n const languagesToAdd = defaultLanguages\n .filter((language) => !addedLanguages.includes(language))\n .filter((language) => languages.find((l) => l.id === language))\n // Account for strict mode by scheduling the update\n const timeout = setTimeout(() => {\n if (!documentReadOnly) handleAddLanguages(languagesToAdd)\n })\n return () => clearTimeout(timeout)\n }\n return undefined\n }, [\n isDeleting,\n handleAddLanguages,\n defaultLanguages,\n addedLanguages,\n languages,\n documentReadOnly,\n ])\n\n // NOTE: This is reordering and re-setting the whole array, it could be surgical\n const handleRestoreOrder = useCallback(() => {\n if (!value?.length || !languages?.length) {\n return\n }\n\n // Create a new value array in the correct order\n // This would also strip out values that don't have a language as the key\n const updatedValue = value\n .reduce((acc, v) => {\n const newIndex = languages.findIndex((l) => l.id === v?.[LANGUAGE_FIELD_NAME])\n\n if (newIndex > -1) {\n acc[newIndex] = v\n }\n\n return acc\n }, [] as InternationalizedArrayItem[])\n .filter(Boolean)\n\n if (value?.length !== updatedValue.length) {\n toast.push({\n title: 'There was an error reordering languages',\n status: 'warning',\n })\n }\n\n onChange(set(updatedValue))\n }, [toast, languages, onChange, value])\n\n const allKeysAreLanguages = useMemo(() => {\n if (!value?.length || !languages?.length) {\n return true\n }\n\n return value?.every((v) => languages.find((l) => l?.id === v?.[LANGUAGE_FIELD_NAME]))\n }, [value, languages])\n\n const languagesOutOfOrder = useMemo(() => {\n if (!value?.length || !addedLanguages.length) {\n return []\n }\n\n return value\n .map((v, vIndex) =>\n vIndex === addedLanguages.findIndex((language) => language === v[LANGUAGE_FIELD_NAME])\n ? null\n : v,\n )\n .filter(Boolean)\n }, [value, addedLanguages])\n\n const languagesAreValid = useMemo(\n () =>\n !languages?.length || (languages?.length && languages.every((item) => item.id && item.title)),\n [languages],\n )\n\n // Automatically restore order of fields\n useEffect(() => {\n if (languagesOutOfOrder.length > 0 && allKeysAreLanguages && !documentReadOnly) {\n handleRestoreOrder()\n }\n }, [languagesOutOfOrder, allKeysAreLanguages, handleRestoreOrder, documentReadOnly])\n\n // compare value keys with possible languages\n const allLanguagesArePresent = useMemo(\n () => checkAllLanguagesArePresent(filteredLanguages, value),\n [filteredLanguages, value],\n )\n const addAllMissingLanguages = useCallback(() => {\n handleAddLanguages(filteredLanguages.map((language) => language.id))\n }, [filteredLanguages, handleAddLanguages])\n\n if (!languagesAreValid) {\n return <Feedback />\n }\n\n const addButtonsAreVisible =\n // Plugin was configured to display buttons here (default!)\n buttonLocations.includes('field') &&\n // There's at least one language visible\n filteredLanguages?.length > 0 &&\n // Not every language has a value yet\n !allLanguagesArePresent\n const fieldHasMembers = members?.length > 0\n const addAllTitle = createAddAllTitle(value, filteredLanguages)\n\n return (\n <Stack space={2}>\n {filteredMembers.map((member) => {\n if (member.kind === 'item') {\n return <ArrayOfObjectsItem {...props} key={member.key} member={member} />\n }\n return <MemberItemError key={member.key} member={member} />\n })}\n\n {/* Give some feedback in the UI so the field doesn't look \"missing\" */}\n {!addButtonsAreVisible && !fieldHasMembers ? (\n <Card border tone=\"transparent\" padding={3} radius={2}>\n <Text size={1}>This internationalized field currently has no translations.</Text>\n </Card>\n ) : null}\n\n {addButtonsAreVisible ? (\n <Stack space={2}>\n <AddButtons\n languagesInUse={addedLanguages}\n readOnly={readOnly}\n handleClick={handleAddLanguages}\n />\n {buttonAddAll ? (\n <Button\n tone=\"primary\"\n mode=\"ghost\"\n data-testid=\"add-all-languages\"\n disabled={readOnly || allLanguagesArePresent}\n icon={AddIcon}\n text={addAllTitle}\n onClick={addAllMissingLanguages}\n />\n ) : null}\n </Stack>\n ) : null}\n </Stack>\n )\n}\n","import type {SchemaType} from 'sanity'\n\nimport type {ArrayFieldOptions} from '../schema/array'\n\nexport function getLanguagesFieldOption(\n schemaType: SchemaType | undefined,\n): ArrayFieldOptions['languages'] | undefined {\n if (!schemaType) {\n return undefined\n }\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const languagesOption = (schemaType.options as ArrayFieldOptions)?.languages\n if (languagesOption) {\n return languagesOption\n }\n return getLanguagesFieldOption(schemaType.type)\n}\n","import {defineField, type FieldDefinition, type FieldProps, type Rule} from 'sanity'\n\nimport {getFunctionCache, peek, setFunctionCache} from '../cache'\nimport {createFieldName} from '../components/createFieldName'\nimport {getSelectedValue} from '../components/getSelectedValue'\nimport InternationalizedArray from '../components/InternationalizedArray'\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport type {Language, LanguageCallback, InternationalizedArrayItem} from '../types'\nimport {getLanguagesFieldOption} from '../utils/getLanguagesFieldOption'\n\ntype ArrayFactoryConfig = {\n apiVersion: string\n select?: Record<string, string>\n languages: Language[] | LanguageCallback\n defaultLanguages?: string[]\n type: string | FieldDefinition\n}\n\nexport type ArrayFieldOptions = Pick<ArrayFactoryConfig, 'apiVersion' | 'select' | 'languages'>\n\nexport default (config: ArrayFactoryConfig) => {\n const {apiVersion, select, languages, type} = config\n const typeName = typeof type === `string` ? type : type.name\n const arrayName = createFieldName(typeName)\n const objectName = createFieldName(typeName, true)\n\n return defineField({\n name: arrayName,\n title: 'Internationalized array',\n type: 'array',\n components: {\n field: (props: FieldProps) =>\n props.renderDefault({\n ...props,\n // Reset the level to avoid nested styling\n level: 0,\n }),\n input: InternationalizedArray,\n },\n options: {\n // @ts-expect-error - these options are required for validation rules – not the custom input component\n apiVersion,\n select,\n languages,\n },\n of: [\n defineField({\n ...(typeof type === 'string' ? {} : type),\n name: objectName,\n type: objectName,\n }),\n ],\n // @ts-expect-error - fix typings\n validation: (rule: Rule) =>\n rule.custom<InternationalizedArrayItem[]>(async (value, context) => {\n if (!value || value.length === 0) {\n return true\n }\n\n // Early return for simple cases to avoid expensive operations\n if (value.length === 1 && !value[0]?.[LANGUAGE_FIELD_NAME]) {\n return true\n }\n\n const selectedValue = getSelectedValue(select, context.document)\n const client = context.getClient({apiVersion})\n\n let contextLanguages: Language[] = []\n const languagesFieldOption = getLanguagesFieldOption(context?.type)\n\n if (Array.isArray(languagesFieldOption)) {\n contextLanguages = languagesFieldOption\n } else if (Array.isArray(peek(selectedValue))) {\n contextLanguages = peek(selectedValue) || []\n } else if (typeof languagesFieldOption === 'function') {\n // Try to get from function cache first (if it's the same function as the component)\n const cachedLanguages = getFunctionCache(languagesFieldOption, selectedValue)\n\n if (Array.isArray(cachedLanguages)) {\n contextLanguages = cachedLanguages\n } else {\n // Try suspend cache as fallback\n const suspendCachedLanguages = peek(selectedValue)\n if (Array.isArray(suspendCachedLanguages)) {\n contextLanguages = suspendCachedLanguages\n } else {\n // Only make the async call if we don't have cached data\n contextLanguages = await languagesFieldOption(client, selectedValue)\n // Cache the result for future validation calls\n setFunctionCache(languagesFieldOption, selectedValue, contextLanguages)\n }\n }\n }\n\n if (value && value.length > contextLanguages.length) {\n return `Cannot be more than ${\n contextLanguages.length === 1 ? `1 item` : `${contextLanguages.length} items`\n }`\n }\n\n // Create a Set for faster language ID lookups\n const languageIds = new Set(contextLanguages.map((lang) => lang.id))\n\n // Check for invalid language keys\n const nonLanguageKeys = value.filter(\n (item) => item?.[LANGUAGE_FIELD_NAME] && !languageIds.has(item[LANGUAGE_FIELD_NAME]),\n )\n if (nonLanguageKeys.length) {\n return {\n message: `Array item keys must be valid languages registered to the field type`,\n paths: nonLanguageKeys.map((item) => [{_key: item._key}]),\n }\n }\n\n // Check for duplicate language keys (more efficient)\n const seenLanguages = new Set<string>()\n const duplicateValues: InternationalizedArrayItem[] = []\n\n for (const item of value) {\n if (item?.[LANGUAGE_FIELD_NAME]) {\n if (seenLanguages.has(item[LANGUAGE_FIELD_NAME])) {\n duplicateValues.push(item)\n } else {\n seenLanguages.add(item[LANGUAGE_FIELD_NAME])\n }\n }\n }\n\n if (duplicateValues.length) {\n return {\n message: 'There can only be one field per language',\n paths: duplicateValues.map((item) => [{_key: item._key}]),\n }\n }\n\n return true\n }),\n })\n}\n","import type {CardTone} from '@sanity/ui'\nimport type {FormNodeValidation} from 'sanity'\n\n/**\n * Maps an array of Sanity form validation entries to a `@sanity/ui` `CardTone`\n * for visual feedback on internationalized array items.\n *\n * - Returns `'critical'` if any validation has `level: 'error'`\n * - Returns `'caution'` if any validation has `level: 'warning'` (and no errors)\n * - Returns `undefined` otherwise (no tone applied)\n *\n * Error level always takes precedence over warning.\n */\nexport function getToneFromValidation(validations: FormNodeValidation[]): CardTone | undefined {\n if (!validations?.length) {\n return undefined\n }\n\n const validationLevels = new Set(validations.map((v) => v.level))\n\n if (validationLevels.has('error')) {\n return `critical`\n } else if (validationLevels.has('warning')) {\n return `caution`\n }\n\n return undefined\n}\n","import {RemoveCircleIcon} from '@sanity/icons'\nimport {\n Box,\n Button,\n Card,\n Flex,\n Label,\n Menu,\n MenuButton,\n MenuItem,\n Spinner,\n Stack,\n Text,\n Tooltip,\n} from '@sanity/ui'\nimport type React from 'react'\nimport {type ReactNode, useCallback, useMemo} from 'react'\nimport {type FormPatch, type ObjectItemProps, PatchEvent, type Path, useFormValue} from 'sanity'\nimport {set, unset} from 'sanity'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport type {InternationalizedArrayItem} from '../types'\nimport {getLanguageDisplay} from '../utils/getLanguageDisplay'\nimport {getToneFromValidation} from './getToneFromValidation'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\nfunction ChangeLanguageButton(props: {\n value: InternationalizedArrayItem\n path: Path\n onChange: (patch: FormPatch[] | PatchEvent | FormPatch) => void\n}): ReactNode {\n const {value, onChange, path} = props\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const parentValue = useFormValue(path.slice(0, -1)) as InternationalizedArrayItem[]\n const {languages} = useInternationalizedArrayContext()\n\n const languageKeysInUse = useMemo(\n () => parentValue?.map((v) => v[LANGUAGE_FIELD_NAME]) ?? [],\n [parentValue],\n )\n\n // Changes the key of this item, ideally to a valid language\n const handleKeyChange = (event: React.MouseEvent<HTMLButtonElement>): void => {\n const languageId = event?.currentTarget?.value\n\n if (!value || !languages?.length || !languages.find((l) => l.id === languageId)) {\n return\n }\n\n onChange([set(languageId, [LANGUAGE_FIELD_NAME])])\n }\n\n return (\n <MenuButton\n button={<Button fontSize={1} text={`Change \"${value[LANGUAGE_FIELD_NAME]}\"`} />}\n id={`${value[LANGUAGE_FIELD_NAME]}-change-key`}\n menu={\n <Menu>\n {languages.map((lang) => (\n <MenuItem\n disabled={languageKeysInUse.includes(lang.id)}\n fontSize={1}\n key={lang.id}\n text={lang.id.toLocaleUpperCase()}\n value={lang.id}\n // @ts-expect-error - fix typings\n onClick={handleKeyChange}\n />\n ))}\n </Menu>\n }\n popover={{portal: true}}\n />\n )\n}\n\nfunction RemoveButton({\n isDefault,\n readOnly,\n onChange,\n}: {\n isDefault: boolean\n readOnly: boolean\n onChange: (patch: FormPatch[] | PatchEvent | FormPatch) => void\n}): ReactNode {\n // Removes this item from the array\n const handleUnset = (): void => {\n onChange(unset())\n }\n\n return (\n <Tooltip\n animate\n disabled={!isDefault}\n content={\n <Text muted size={1}>\n Can't remove default language\n </Text>\n }\n fallbackPlacements={['right', 'left']}\n placement=\"top\"\n portal\n >\n <span>\n <Button\n mode=\"bleed\"\n icon={RemoveCircleIcon}\n tone=\"critical\"\n disabled={readOnly || isDefault}\n onClick={handleUnset}\n />\n </span>\n </Tooltip>\n )\n}\n\n/**\n * Renders a single row of an internationalized array: a language label (or\n * \"Change\" menu for invalid keys), the value input, and a remove button.\n *\n * Key behaviours:\n * - Wraps `onChange` to intercept paste operations into empty Portable Text\n * fields, ensuring `setIfMissing` and correct path prefixing.\n * - Detects items needing migration (missing `LANGUAGE_FIELD_NAME`) and hides\n * the language label in that state.\n * - Shows a `MenuButton` with available languages when the current key is\n * not a valid language.\n * - Disables the remove button for languages listed in `defaultLanguages`.\n * - Shows a `Spinner` when languages have not been loaded yet.\n * - Applies a `CardTone` based on validation state via `getToneFromValidation`.\n */\nexport default function InternationalizedInput(\n props: ObjectItemProps<InternationalizedArrayItem>,\n): ReactNode {\n // Extract the original onChange to avoid dependency issues\n const originalOnChange = props.inputProps.onChange\n\n // Create a wrapped onChange handler to intercept patches for paste operations\n const wrappedOnChange = useCallback(\n (patches: unknown) => {\n // Ensure patches is an array before proceeding with paste logic\n // For single patch operations (like unset), pass through directly\n if (!Array.isArray(patches)) {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return originalOnChange(patches as Parameters<typeof originalOnChange>[0])\n }\n\n // Check if this is a paste operation into an empty or uninitialized Portable Text field\n const valueField = props.value?.value\n const isEmptyOrUndefined =\n valueField === undefined ||\n valueField === null ||\n (Array.isArray(valueField) && valueField.length === 0)\n\n if (isEmptyOrUndefined) {\n // Check for insert patches that are trying to operate on a non-existent structure\n const hasProblematicInsert = patches.some((patch: {type?: string; path?: unknown[]}) => {\n // Ensure patch exists and has required properties\n if (!patch || typeof patch !== 'object') {\n return false\n }\n\n // Look for insert patches targeting the value field or direct array index\n if (\n patch.type === 'insert' &&\n patch.path &&\n Array.isArray(patch.path) &&\n patch.path.length > 0\n ) {\n // The path might be ['value', index] or just [index] depending on context\n const isTargetingValue = patch.path[0] === 'value' || typeof patch.path[0] === 'number'\n return isTargetingValue\n }\n return false\n })\n\n if (hasProblematicInsert) {\n // First, ensure the value field exists as an empty array if it doesn't\n const initPatch =\n valueField === undefined ? {type: 'setIfMissing', path: ['value'], value: []} : null\n\n // Transform the patches to ensure they work with the nested structure\n const fixedPatches = patches.map(\n (patch: {type?: string; path?: unknown[]; [key: string]: unknown}) => {\n // Ensure patch exists and has required properties\n if (!patch || typeof patch !== 'object') {\n return patch\n }\n\n if (patch.type === 'insert' && patch.path && Array.isArray(patch.path)) {\n // Ensure the path is correct for the nested structure\n const fixedPath = patch.path[0] === 'value' ? patch.path : ['value', ...patch.path]\n const fixedPatch = {...patch, path: fixedPath}\n return fixedPatch\n }\n return patch\n },\n )\n\n // If we need to initialize the field, include that patch first\n const allPatches = initPatch ? [initPatch, ...fixedPatches] : fixedPatches\n\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return originalOnChange(allPatches as Parameters<typeof originalOnChange>[0])\n }\n }\n\n // For all other cases, pass through unchanged\n return originalOnChange(patches as Parameters<typeof originalOnChange>[0])\n },\n [originalOnChange, props.value?.value],\n )\n\n const inlineProps = useMemo(\n () => ({\n ...props.inputProps,\n members: props.inputProps.members.filter((m) => m.kind === 'field' && m.name === 'value'),\n value: props.value,\n // Use our wrapped onChange handler\n onChange: wrappedOnChange,\n }),\n [props.inputProps, props.value, wrappedOnChange],\n )\n\n const {validation, value, readOnly} = inlineProps\n\n // The parent array contains the languages from the plugin config\n const {languages, languageDisplay, defaultLanguages} = useInternationalizedArrayContext()\n\n const keyIsValid = languages?.length\n ? languages.find((l) => l.id === value[LANGUAGE_FIELD_NAME])\n : false\n\n if (!languages) {\n return <Spinner />\n }\n\n const language = languages.find((l) => l.id === value[LANGUAGE_FIELD_NAME])\n const languageTitle: string =\n keyIsValid && language ? getLanguageDisplay(languageDisplay, language.title, language.id) : ''\n\n const isDefault = defaultLanguages.includes(value[LANGUAGE_FIELD_NAME])\n\n return (\n <Card paddingTop={2} tone={getToneFromValidation(validation)}>\n <Stack space={2}>\n {keyIsValid ? (\n <Label muted size={1}>\n {languageTitle}\n </Label>\n ) : (\n <ChangeLanguageButton value={value} path={props.path} onChange={originalOnChange} />\n )}\n <Flex align=\"center\" gap={2}>\n <Box flex={1}>{props.inputProps.renderInput(inlineProps)}</Box>\n <RemoveButton\n isDefault={isDefault}\n readOnly={Boolean(readOnly)}\n onChange={originalOnChange}\n />\n </Flex>\n </Stack>\n </Card>\n )\n}\n","import {defineField, type FieldDefinition, type FieldProps} from 'sanity'\n\nimport {createFieldName} from '../components/createFieldName'\nimport InternationalizedInput from '../components/InternationalizedInput'\nimport {LANGUAGE_FIELD_NAME} from '../constants'\n\ntype ObjectFactoryConfig = {\n type: string | FieldDefinition\n}\n\nexport default (config: ObjectFactoryConfig) => {\n const {type} = config\n const typeName = typeof type === `string` ? type : type.name\n const objectName = createFieldName(typeName, true)\n\n return defineField({\n name: objectName,\n title: `Internationalized array ${typeName}`,\n type: 'object',\n components: {\n // @ts-expect-error - fix typings\n item: InternationalizedInput,\n field: (props: FieldProps) =>\n props.renderDefault({\n ...props,\n // Reset the level to avoid nested styling\n level: 0,\n }),\n },\n fields: [\n defineField({\n ...(typeof type === 'string' ? {type} : type),\n name: 'value',\n components: {\n field: (props: FieldProps) => props.renderDefault({...props, title: ''}),\n },\n }),\n ],\n preview: {\n select: {\n title: 'value',\n subtitle: LANGUAGE_FIELD_NAME,\n },\n },\n })\n}\n","import {definePlugin, isObjectInputProps} from 'sanity'\n\nimport {InternationalizedArrayFormInput} from './components/InternationalizedArrayFormInput'\nimport {InternationalizedArrayLayout} from './components/InternationalizedArrayLayout'\nimport Preload from './components/Preload'\nimport {CONFIG_DEFAULT} from './constants'\nimport {internationalizedArrayFieldAction} from './fieldActions'\nimport array from './schema/array'\nimport object from './schema/object'\nimport type {PluginConfig} from './types'\nimport {hasInternationalizedArrayField} from './utils/hasInternationalizedArrayField'\n\nexport const internationalizedArray = definePlugin<PluginConfig>((config) => {\n const pluginConfig = {...CONFIG_DEFAULT, ...config}\n const {\n apiVersion = '2025-10-15',\n select,\n languages,\n fieldTypes,\n defaultLanguages,\n buttonLocations,\n } = pluginConfig\n\n return {\n name: 'sanity-plugin-internationalized-array',\n // Preload languages for use throughout the Studio\n studio: Array.isArray(languages)\n ? undefined\n : {\n components: {\n layout: (props) => (\n <>\n <Preload apiVersion={apiVersion} languages={languages} />\n {props.renderDefault(props)}\n </>\n ),\n },\n },\n // Optional: render \"add language\" buttons as field actions\n document: {\n components: {\n unstable_layout: (props) => (\n <InternationalizedArrayLayout {...props} pluginConfig={pluginConfig} />\n ),\n },\n unstable_fieldActions: buttonLocations.includes('unstable__fieldAction')\n ? (prev) => [...prev, internationalizedArrayFieldAction]\n : undefined,\n },\n // Wrap document editor with a language provider\n form: {\n components: {\n input: (props) => {\n const isRootInput = props.id === 'root' && isObjectInputProps(props)\n\n if (!isRootInput) {\n return props.renderDefault(props)\n }\n\n const hasInternationalizedArray = hasInternationalizedArrayField(props.schemaType)\n\n if (\n hasInternationalizedArray &&\n pluginConfig.includeForDocumentType(props.schemaType.name)\n ) {\n return <InternationalizedArrayFormInput {...props} pluginConfig={pluginConfig} />\n }\n return props.renderDefault(props)\n },\n },\n },\n // Register custom schema types for the outer array and the inner object\n schema: {\n types: [\n ...fieldTypes.map((type) => array({type, apiVersion, select, languages, defaultLanguages})),\n ...fieldTypes.map((type) => object({type})),\n ],\n },\n }\n})\n"],"names":["namespace","functionCache","Map","functionKeyCache","WeakMap","promiseCache","stringifyCacheKey","key","JSON","stringify","preloadWithKey","fn","keyStr","has","set","clear","peek","selectedValue","version","promise","get","_status","_value","createCacheKey","workspaceId","selectedValueHash","createOrGetPromise","getFunctionKey","cachedKey","fnStr","toString","hash","maxLength","Math","min","length","i","char","charCodeAt","abs","createFunctionCacheKey","functionKey","getFunctionCache","setFunctionCache","languages","LANGUAGE_FIELD_NAME","MAX_COLUMNS","codeOnly","titleOnly","titleAndCode","CONFIG_DEFAULT","select","defaultLanguages","fieldTypes","apiVersion","buttonLocations","buttonAddAll","languageDisplay","includeForDocumentType","documentType","getDocumentsToTranslate","value","rootPath","Array","isArray","arrayRootPath","internationalizedValues","filter","item","type","_type","startsWith","endsWith","map","internationalizedValue","Object","assign","path","pathString","join","flatMap","index","startsWithUnderscoreRegex","keys","match","getLanguageDisplay","title","code","toUpperCase","getSelectedValue","document","selection","entries","InternationalizedArrayContext","createContext","filteredLanguages","useInternationalizedArrayContext","useContext","InternationalizedArrayProvider","props","$","_c","internationalizedArray","t0","client","useClient","workspace","useWorkspace","formState","useDocumentPane","deferredDocument","useDeferredValue","t1","t2","bb0","name","t3","t4","t5","cacheKey","bb1","result","t6","languagesPromise","use","selectedLanguageIds","options","languageFilterOptions","useLanguageFilterStudioContext","documentTypes","includes","languageFilterEnabled","language","id","t7","context","t8","children","AddButtons","readOnly","languagesInUse","handleClick","languageTitle","undefined","AddIcon","DocumentAddButtons","getFormValue","useGetFormValue","toast","useToast","onChange","schema","useSchema","typeName","baseTypeName","charAt","toLowerCase","slice","arrayBasedTypes","Set","schemaType","valueField","fields","find","_temp","fieldType","jsonType","of","getInitialValueForType","languageId","isSanityDocument","push","status","documentsToTranslation","alreadyTranslated","translation","removeDuplicates","reduce","filteredTranslations","translation_0","alreadyTranslation","filteredTranslation","patches","toTranslate","initialValue","ifMissing","setIfMissing","insertValue","insert","PatchEvent","from","flat","handleDocumentButtonClick","Symbol","for","f","InternationalizedArrayFormInput","pluginConfig","renderDefault","hasInternationalizedArrayField","isDocumentSchemaType","hasInternationalizedArrayInFields","field","InternationalizedArrayLayout","console","error","Preload","checkAllLanguagesArePresent","filteredLanguageIds","l","languagesInUseIds","v","size","every","createAddAllTitle","isInternationalizedArrayItemType","createAddLanguagePatches","config","addLanguageKeys","schemaTypeName","Error","itemBase","newItems","itemLanguage","languageIndex","findIndex","remainingLanguages","nextLanguageIndex","r","splice","createTranslateFieldActions","fieldActionProps","useFormValue","disabled","Boolean","hidden","some","onAction","useCallback","icon","AddMissingTranslationsFieldAction","internationalizedArrayFieldAction","defineDocumentFieldAction","useAction","isInternationalizedArrayField","translateFieldActions","TranslateIcon","renderAsButton","pascalCase","string","upperFirst","camelCase","createFieldName","addValue","schemaExample","Feedback","InternationalizedArray","members","documentReadOnly","member","kind","valueMember","filterField","filteredMembers","formValue","handleAddLanguages","isDeleting","languageKeysFromValue","languageKeys","split","_temp2","addedLanguages","hasAddedDefaultLanguages","l_1","language_0","languagesToAdd","language_1","language_2","l_2","timeout","setTimeout","clearTimeout","useEffect","updatedValue","acc","v_0","newIndex","l_3","handleRestoreOrder","t9","t10","v_1","l_4","allKeysAreLanguages","bb2","t11","t12","v_2","vIndex","language_3","languagesOutOfOrder","languagesAreValid","_temp3","t13","allLanguagesArePresent","t14","_temp4","addAllMissingLanguages","t15","addButtonsAreVisible","fieldHasMembers","t16","addAllTitle","t17","t18","member_0","t19","t20","language_4","l_0","_key","getLanguagesFieldOption","arrayName","objectName","defineField","components","level","input","validation","rule","custom","getClient","contextLanguages","languagesFieldOption","cachedLanguages","suspendCachedLanguages","languageIds","lang","nonLanguageKeys","message","paths","seenLanguages","duplicateValues","add","getToneFromValidation","validations","validationLevels","ChangeLanguageButton","parentValue","languageKeysInUse","event","currentTarget","handleKeyChange","toLocaleUpperCase","portal","RemoveButton","isDefault","unset","handleUnset","RemoveCircleIcon","InternationalizedInput","originalOnChange","inputProps","initPatch","fixedPatches","allPatches","wrappedOnChange","inlineProps","keyIsValid","renderInput","m","patch_0","patch","fixedPath","preview","subtitle","definePlugin","studio","layout","unstable_layout","unstable_fieldActions","prev","form","isObjectInputProps","types","array","object"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/cache.ts","../src/constants.ts","../src/utils/getDocumentsToTranslate.ts","../src/utils/getLanguageDisplay.ts","../src/components/getSelectedValue.ts","../src/components/InternationalizedArrayContext.tsx","../src/components/AddButtons.tsx","../src/components/DocumentAddButtons.tsx","../src/components/InternationalizedArrayFormInput.tsx","../src/utils/hasInternationalizedArrayField.ts","../src/components/InternationalizedArrayLayout.tsx","../src/components/Preload.tsx","../src/utils/checkAllLanguagesArePresent.ts","../src/utils/createAddAllTitle.ts","../src/types.ts","../src/utils/createAddLanguagePatches.ts","../src/fieldActions/index.ts","../src/components/createFieldName.ts","../src/components/Feedback.tsx","../src/components/InternationalizedArray.tsx","../src/utils/getLanguagesFieldOption.ts","../src/schema/array.ts","../src/components/getToneFromValidation.ts","../src/components/InternationalizedInput.tsx","../src/schema/object.ts","../src/plugin.tsx"],"sourcesContent":["import type {Language, LanguageCallback} from './types'\n\nconst namespace = 'sanity-plugin-internationalized-array'\n\nconst version = 'v1'\n\n// Cache for function keys to avoid recalculating them\nconst functionKeyCache = new WeakMap<LanguageCallback, string>()\n\n// Cache for React.use promises\nconst promiseCache = new Map<string, Promise<Language[]>>()\n\n// Cache for function references to enable sharing between same functions\nconst functionCache = new Map<string, Language[]>()\n\n// Helper to create a cache key string from an array\nfunction stringifyCacheKey(key: unknown[]): string {\n return JSON.stringify(key)\n}\n\n// Enhanced preload function that can use custom cache keys\nexport const preloadWithKey = (fn: () => Promise<Language[]>, key: (string | number)[]) => {\n const keyStr = stringifyCacheKey(key)\n if (!promiseCache.has(keyStr)) {\n promiseCache.set(keyStr, fn())\n }\n}\n\n// Cache busting: clear all promise caches\nexport const clear = () => {\n promiseCache.clear()\n}\n\n// Peeking into entries outside of suspense\nexport const peek = (selectedValue: Record<string, unknown>) => {\n const key = stringifyCacheKey([version, namespace, selectedValue])\n const promise = promiseCache.get(key)\n if (promise) {\n // Check if promise is resolved\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const status = (promise as any)._status\n if (status === 'fulfilled') {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return (promise as any)._value as Language[] | undefined\n }\n }\n return undefined\n}\n\n// Helper function to create a stable cache key that matches the component's key structure\nexport const createCacheKey = (selectedValue: Record<string, unknown>, workspaceId?: string) => {\n const selectedValueHash = JSON.stringify(selectedValue)\n return workspaceId\n ? [version, namespace, selectedValueHash, workspaceId]\n : [version, namespace, selectedValueHash]\n}\n\n// Create or get cached promise for React.use\nexport const createOrGetPromise = (\n fn: () => Promise<Language[]>,\n key: (string | number | Record<string, unknown>)[],\n): Promise<Language[]> => {\n const keyStr = stringifyCacheKey(key)\n if (promiseCache.has(keyStr)) {\n return promiseCache.get(keyStr)!\n }\n const promise = fn()\n promiseCache.set(keyStr, promise)\n return promise\n}\n\n// Generate a unique key for a function reference (cached for performance)\nconst getFunctionKey = (fn: LanguageCallback): string => {\n // Check if we already have a cached key for this function\n const cachedKey = functionKeyCache.get(fn)\n if (cachedKey) {\n return cachedKey\n }\n\n // Create a hash for functions (only when needed)\n const fnStr = fn.toString()\n let hash = 0\n // Only hash the first 100 characters for performance\n const maxLength = Math.min(fnStr.length, 100)\n for (let i = 0; i < maxLength; i++) {\n const char = fnStr.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash &= hash // Convert to 32-bit integer\n }\n const key = `anonymous_${Math.abs(hash)}`\n functionKeyCache.set(fn, key)\n return key\n}\n\n// Create a cache key that includes function identity\nconst createFunctionCacheKey = (\n fn: LanguageCallback,\n selectedValue: Record<string, unknown>,\n workspaceId?: string,\n): string => {\n const functionKey = getFunctionKey(fn)\n const selectedValueHash = JSON.stringify(selectedValue)\n return workspaceId\n ? `${functionKey}:${selectedValueHash}:${workspaceId}`\n : `${functionKey}:${selectedValueHash}`\n}\n\n// Function-aware cache operations\nexport const getFunctionCache = (\n fn: LanguageCallback,\n selectedValue: Record<string, unknown>,\n workspaceId?: string,\n): Language[] | undefined => {\n const key = createFunctionCacheKey(fn, selectedValue, workspaceId)\n return functionCache.get(key)\n}\n\nexport const setFunctionCache = (\n fn: LanguageCallback,\n selectedValue: Record<string, unknown>,\n languages: Language[],\n workspaceId?: string,\n): void => {\n const key = createFunctionCacheKey(fn, selectedValue, workspaceId)\n functionCache.set(key, languages)\n}\n","import type {PluginConfig} from './types'\n\n/**\n * The field name used to identify the language of an internationalized array item.\n *\n * In v4.x this was '_key', in v5+ this will be 'language'.\n * Having this as a constant makes the codebase easier to maintain.\n */\nexport const LANGUAGE_FIELD_NAME = '_key' as const\n\nexport const MAX_COLUMNS = {\n codeOnly: 5,\n titleOnly: 4,\n titleAndCode: 3,\n}\n\nexport const CONFIG_DEFAULT: Required<PluginConfig> = {\n languages: [],\n select: {},\n defaultLanguages: [],\n fieldTypes: [],\n apiVersion: '2025-10-15',\n buttonLocations: ['field'],\n buttonAddAll: true,\n languageDisplay: 'codeOnly',\n includeForDocumentType: (documentType) => documentType !== 'translation.metadata',\n}\n","import type {SanityDocument} from 'sanity'\n\nexport interface DocumentsToTranslate {\n path: (string | number)[]\n pathString: string\n _key: string\n _type: string\n [key: string]: unknown\n}\n\n/**\n * Recursively traverses a Sanity document (or any nested value) and collects\n * all internationalized array items found within it.\n *\n * An item is considered an internationalized array value when its `_type`\n * starts with `\"internationalizedArray\"` and ends with `\"Value\"`.\n *\n * The function walks through objects and arrays, skipping keys that start\n * with `_` (internal Sanity fields like `_id`, `_type`, `_rev`). Each\n * returned item includes the original properties plus `path` (array of\n * segments) and `pathString` (dot-joined) indicating where it was found.\n */\nexport const getDocumentsToTranslate = (\n // oxlint-disable-next-line typescript-eslint/no-redundant-type-constituents\n value: SanityDocument | unknown,\n rootPath: (string | number)[] = [],\n): DocumentsToTranslate[] => {\n if (Array.isArray(value)) {\n const arrayRootPath = [...rootPath]\n\n // if item contains internationalized return array\n const internationalizedValues = value.filter((item) => {\n if (Array.isArray(item)) return false\n\n if (typeof item === 'object') {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const type = item?._type as string | undefined\n return type?.startsWith('internationalizedArray') && type?.endsWith('Value')\n }\n return false\n })\n\n if (internationalizedValues.length > 0) {\n return internationalizedValues.map((internationalizedValue) => {\n return Object.assign({}, internationalizedValue, {\n path: arrayRootPath,\n pathString: arrayRootPath.join('.'),\n })\n })\n }\n\n if (value.length > 0) {\n return value.flatMap((item, index) =>\n getDocumentsToTranslate(item, [...arrayRootPath, index]),\n )\n }\n\n return []\n }\n if (typeof value === 'object' && value) {\n const startsWithUnderscoreRegex = /^_/\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const itemKeys = Object.keys(value).filter(\n (key) => !key.match(startsWithUnderscoreRegex),\n ) as (keyof typeof value)[]\n\n return itemKeys.flatMap((item) => {\n const selectedValue = value[item] as unknown\n const path = [...rootPath, item]\n return getDocumentsToTranslate(selectedValue, path)\n })\n }\n return []\n}\n","import type {LanguageDisplay} from '../types'\n\n/**\n * Formats a language label for display in buttons and field headers\n * based on the configured `languageDisplay` mode:\n *\n * - `'codeOnly'` -> uppercase code, e.g. `\"EN\"`\n * - `'titleOnly'` -> title as-is, e.g. `\"English\"`\n * - `'titleAndCode'` -> title with uppercase code, e.g. `\"English (EN)\"`\n *\n * Falls back to `title` for any unrecognized display mode.\n */\nexport function getLanguageDisplay(\n languageDisplay: LanguageDisplay,\n title: string,\n code: string,\n): string {\n if (languageDisplay === 'codeOnly') return code.toUpperCase()\n if (languageDisplay === 'titleOnly') return title\n if (languageDisplay === 'titleAndCode') return `${title} (${code.toUpperCase()})`\n return title\n}\n","import get from 'lodash-es/get.js'\n\n/**\n * Extracts a subset of values from a Sanity document based on a `select`\n * mapping (as configured in the plugin's `select` option).\n *\n * Each key in `select` becomes a key in the returned object, with its value\n * resolved from the document using the corresponding dot-path (via lodash `get`).\n *\n * Array values are filtered to remove incomplete references (objects with\n * `_type: 'reference'` but no `_ref`), since those represent empty reference\n * fields that should be ignored.\n *\n * Returns an empty object when either `select` or `document` is undefined.\n */\nexport const getSelectedValue = (\n select: Record<string, string> | undefined,\n document:\n | {\n [x: string]: unknown\n }\n | undefined,\n): Record<string, unknown> => {\n if (!select || !document) {\n return {}\n }\n\n const selection: Record<string, string> = select || {}\n const selectedValue: Record<string, unknown> = {}\n for (const [key, path] of Object.entries(selection)) {\n let value = get(document, path)\n if (Array.isArray(value)) {\n // If there are references in the array, ensure they have `_ref` set, otherwise they are considered empty and can safely be ignored\n value = value.filter((item) =>\n typeof item === 'object' ? item?._type === 'reference' && '_ref' in item : true,\n )\n }\n selectedValue[key] = value\n }\n\n return selectedValue\n}\n","import {useLanguageFilterStudioContext} from '@sanity/language-filter'\nimport type React from 'react'\nimport {createContext, use, useContext, useDeferredValue, useMemo} from 'react'\nimport {useClient, useWorkspace} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport {createCacheKey, createOrGetPromise, setFunctionCache} from '../cache'\nimport {CONFIG_DEFAULT} from '../constants'\nimport type {Language, PluginConfig} from '../types'\nimport {getSelectedValue} from './getSelectedValue'\n\n// This provider makes the plugin config available to all components in the document form\n// But with languages resolved and filtered languages updated base on @sanity/language-filter\n\nexport type InternationalizedArrayContextProps = Required<PluginConfig> & {\n languages: Language[]\n filteredLanguages: Language[]\n}\n\nconst InternationalizedArrayContext = createContext<InternationalizedArrayContextProps>({\n ...CONFIG_DEFAULT,\n languages: [],\n filteredLanguages: [],\n})\n\nexport function useInternationalizedArrayContext(): InternationalizedArrayContextProps {\n return useContext(InternationalizedArrayContext)\n}\n\ntype InternationalizedArrayProviderProps = {\n internationalizedArray: Required<PluginConfig>\n documentType: string\n}\n\nexport function InternationalizedArrayProvider(\n props: React.PropsWithChildren<InternationalizedArrayProviderProps>,\n): React.ReactElement {\n const {internationalizedArray, documentType} = props\n\n const client = useClient({apiVersion: internationalizedArray.apiVersion})\n const workspace = useWorkspace()\n const {formState} = useDocumentPane()\n const deferredDocument = useDeferredValue(formState?.value)\n const selectedValue = useMemo(\n () => getSelectedValue(internationalizedArray.select, deferredDocument),\n [internationalizedArray.select, deferredDocument],\n )\n\n // Use a stable workspace identifier to prevent unnecessary re-renders\n const workspaceId = useMemo(() => {\n // Use workspace name if available, otherwise create a stable hash\n if (workspace?.name) {\n return workspace.name\n }\n // Create a stable hash from workspace properties that matter for caching\n const workspaceKey = {\n name: workspace?.name,\n title: workspace?.title,\n // Add other stable properties as needed\n }\n return JSON.stringify(workspaceKey)\n }, [workspace])\n\n // Memoize the cache key to prevent expensive JSON.stringify calls\n const cacheKey = useMemo(\n () => createCacheKey(selectedValue, workspaceId),\n [selectedValue, workspaceId],\n )\n\n // Fetch or return languages\n const languagesPromise = useMemo(() => {\n if (Array.isArray(internationalizedArray.languages)) {\n return null // Return null for synchronous arrays\n }\n\n // Create or get cached promise for React.use\n return createOrGetPromise(async () => {\n if (typeof internationalizedArray.languages === 'function') {\n const result = await internationalizedArray.languages(client, selectedValue)\n // Populate function cache for use outside React context\n setFunctionCache(internationalizedArray.languages, selectedValue, result, workspaceId)\n return result\n }\n return internationalizedArray.languages\n }, cacheKey)\n }, [internationalizedArray, client, selectedValue, workspaceId, cacheKey])\n\n // Use React.use to handle the promise with Suspense, or return array directly\n const languages = languagesPromise\n ? use(languagesPromise)\n : // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n (internationalizedArray.languages as Language[])\n\n // Filter out some languages if language filter is enabled\n const {selectedLanguageIds, options: languageFilterOptions} = useLanguageFilterStudioContext()\n\n const filteredLanguages = useMemo(() => {\n const languageFilterEnabled = languageFilterOptions.documentTypes.includes(documentType)\n\n return languageFilterEnabled\n ? languages.filter((language) => selectedLanguageIds.includes(language.id))\n : languages\n }, [documentType, languageFilterOptions, languages, selectedLanguageIds])\n\n const context = useMemo(\n () => ({...internationalizedArray, languages, filteredLanguages}),\n [filteredLanguages, internationalizedArray, languages],\n )\n\n return (\n <InternationalizedArrayContext.Provider value={context}>\n {props.children}\n </InternationalizedArrayContext.Provider>\n )\n}\n","import {AddIcon} from '@sanity/icons'\nimport {Button, Grid} from '@sanity/ui'\n\nimport {MAX_COLUMNS} from '../constants'\nimport {getLanguageDisplay} from '../utils/getLanguageDisplay'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\ntype AddButtonsProps = {\n readOnly: boolean\n handleClick: (languageId: string) => void\n // Keys of languages that are already in use\n languagesInUse: string[]\n}\n\n/**\n * Renders a grid of \"add language\" buttons — one per configured language.\n *\n * Returns `null` when the `languages` array is empty.\n *\n * Each button is disabled when:\n * - `readOnly` is `true`, or\n * - the language already exists in the current `value` array\n * (matched via `LANGUAGE_FIELD_NAME`).\n *\n * The button label is formatted according to the `languageDisplay` setting\n * from the plugin context (e.g. code-only, title-only, or both).\n * An `AddIcon` is shown unless there are more languages than fit in one row\n * and the display mode is `'codeOnly'`.\n */\nfunction AddButtons(props: AddButtonsProps) {\n const {readOnly, languagesInUse, handleClick} = props\n const {languageDisplay, filteredLanguages: languages} = useInternationalizedArrayContext()\n\n if (!languages.length) return null\n\n return (\n <Grid columns={Math.min(languages.length, MAX_COLUMNS[languageDisplay])} gap={2}>\n {languages.map((language) => {\n const languageTitle: string = getLanguageDisplay(\n languageDisplay,\n language.title,\n language.id,\n )\n return (\n <Button\n key={language.id}\n tone=\"primary\"\n mode=\"ghost\"\n fontSize={1}\n data-testid={`add-${language.id}`}\n disabled={readOnly || languagesInUse.includes(language.id)}\n text={languageTitle}\n // Only show plus icon if there's one row or less AND only showing codes\n icon={\n languages.length > MAX_COLUMNS[languageDisplay] && languageDisplay === 'codeOnly'\n ? undefined\n : AddIcon\n }\n value={language.id}\n onClick={() => handleClick(language.id)}\n />\n )\n })}\n </Grid>\n )\n}\n\nexport default AddButtons\n","import {Box, Stack, Text, useToast} from '@sanity/ui'\nimport {type ReactElement, useCallback} from 'react'\nimport {\n type FormInsertPatch,\n type FormSetIfMissingPatch,\n insert,\n isSanityDocument,\n PatchEvent,\n setIfMissing,\n useGetFormValue,\n useSchema,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport type {DocumentsToTranslate} from '../utils/getDocumentsToTranslate'\nimport {getDocumentsToTranslate} from '../utils/getDocumentsToTranslate'\nimport AddButtons from './AddButtons'\n\n/**\n * Document-level \"add translation\" panel that appears outside individual\n * internationalized array fields (when `buttonLocations` includes `'document'`).\n *\n * Renders a heading and a row of per-language buttons. When a language button\n * is clicked the component:\n *\n * 1. Scans the current document for all internationalized array fields\n * using `getDocumentsToTranslate`.\n * 2. Filters out fields that already contain a translation for the selected\n * language, and deduplicates by field path.\n * 3. Shows an error toast if no eligible fields remain.\n * 4. Creates `setIfMissing` + `insert` patches to add the new language\n * entry to each eligible field, dispatching them via `onChange`.\n *\n * For Portable Text and other array-based value fields, the initial value\n * is set to an empty array (`[]`) rather than `undefined`.\n */\nexport default function DocumentAddButtons(): ReactElement {\n const getFormValue = useGetFormValue()\n\n const toast = useToast()\n const {onChange} = useDocumentPane()\n const schema = useSchema()\n\n // Helper function to determine if a field should be initialized as an array\n const getInitialValueForType = useCallback(\n (typeName: string): unknown => {\n if (!typeName) return undefined\n\n // Extract the base type name from internationalized array type\n // e.g., \"internationalizedArrayBodyValue\" -> \"body\"\n const match = typeName.match(/^internationalizedArray(.+)Value$/)\n if (!match || !match[1]) return undefined\n\n const baseTypeName = match[1].charAt(0).toLowerCase() + match[1].slice(1)\n\n // Check if it's a known array-based type (Portable Text fields)\n const arrayBasedTypes = new Set(['body', 'htmlContent', 'blockContent', 'portableText'])\n if (arrayBasedTypes.has(baseTypeName)) {\n return []\n }\n\n // Try to look up the schema type to determine if it's an array\n const schemaType = schema.get(typeName)\n if (schemaType && 'fields' in schemaType) {\n // Check if this is an object type with a 'value' field\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const fields = schemaType.fields as Array<{\n name: string\n type?: {jsonType?: string; name?: string; type?: string; of?: unknown}\n }>\n const valueField = fields.find((f) => f.name === 'value')\n if (valueField) {\n const fieldType = valueField.type\n // Check if the value field is an array type\n if (\n fieldType?.jsonType === 'array' ||\n fieldType?.name === 'array' ||\n fieldType?.type === 'array' ||\n fieldType?.of !== undefined ||\n (fieldType?.name && arrayBasedTypes.has(fieldType.name))\n ) {\n return []\n }\n }\n }\n\n return undefined\n },\n [schema],\n )\n\n const handleDocumentButtonClick = useCallback(\n async (languageId: string) => {\n const value = getFormValue([])\n if (!isSanityDocument(value)) {\n toast.push({\n status: 'error',\n title: 'No document value found',\n })\n return\n }\n const documentsToTranslation = getDocumentsToTranslate(value, [])\n\n const alreadyTranslated = documentsToTranslation.filter(\n (translation) => translation?.[LANGUAGE_FIELD_NAME] === languageId,\n )\n const removeDuplicates = documentsToTranslation.reduce<DocumentsToTranslate[]>(\n (filteredTranslations, translation) => {\n if (\n alreadyTranslated.filter(\n (alreadyTranslation) => alreadyTranslation.pathString === translation.pathString,\n ).length > 0\n ) {\n return filteredTranslations\n }\n const translationAlreadyExists = filteredTranslations.filter(\n (filteredTranslation) => filteredTranslation.path === translation.path,\n )\n\n if (translationAlreadyExists.length > 0) {\n return filteredTranslations\n }\n filteredTranslations.push(translation)\n return filteredTranslations\n },\n [],\n )\n if (removeDuplicates.length === 0) {\n toast.push({\n status: 'error',\n title: 'No internationalizedArray fields found in document root',\n })\n return\n }\n\n // Write a new patch for each empty field\n const patches: (FormSetIfMissingPatch | FormInsertPatch)[] = []\n\n for (const toTranslate of removeDuplicates) {\n const path = toTranslate.path\n\n // Get the appropriate initial value for this field type\n const initialValue = getInitialValueForType(toTranslate._type)\n\n const ifMissing = setIfMissing([], path)\n const insertValue = insert(\n [\n {\n [LANGUAGE_FIELD_NAME]: languageId,\n _type: toTranslate._type,\n value: initialValue, // Use the determined initial value instead of undefined\n },\n ],\n 'after',\n [...path, -1],\n )\n patches.push(ifMissing)\n patches.push(insertValue)\n }\n\n onChange(PatchEvent.from(patches.flat()))\n },\n [getInitialValueForType, onChange, toast, getFormValue],\n )\n return (\n <Stack space={3}>\n <Box>\n <Text size={1} weight=\"semibold\">\n Add translation to internationalized fields\n </Text>\n </Box>\n <AddButtons readOnly={false} handleClick={handleDocumentButtonClick} languagesInUse={[]} />\n </Stack>\n )\n}\n","import {Stack} from '@sanity/ui'\nimport type {ObjectInputProps} from 'sanity'\n\nimport type {PluginConfig} from '../types'\nimport DocumentAddButtons from './DocumentAddButtons'\n\n/**\n * An input component for the root object of an internationalized array.\n * It renders the document add buttons if the buttonLocations include 'document'.\n */\nexport function InternationalizedArrayFormInput(\n props: ObjectInputProps & {pluginConfig: PluginConfig},\n) {\n const showDocumentButtons = props.pluginConfig?.buttonLocations?.includes('document')\n\n if (showDocumentButtons) {\n return (\n <Stack space={5}>\n <DocumentAddButtons />\n {props.renderDefault(props)}\n </Stack>\n )\n }\n return props.renderDefault(props)\n}\n","import {isDocumentSchemaType, type ObjectField, type SchemaType} from 'sanity'\n\n/**\n * Returns true when a document schema contains any field (including nested\n * object/array item fields) whose type name starts with `internationalizedArray`.\n *\n * Traversal short-circuits on first match to avoid unnecessary work.\n */\nexport function hasInternationalizedArrayField(schemaType: SchemaType): boolean {\n if (!isDocumentSchemaType(schemaType)) {\n return false\n }\n\n return hasInternationalizedArrayInFields(schemaType.fields)\n}\n\nfunction hasInternationalizedArrayInFields(fields: ObjectField[]): boolean {\n for (const field of fields) {\n if (field.type.name.startsWith('internationalizedArray')) {\n return true\n }\n\n if (field.type.jsonType === 'object' && hasInternationalizedArrayInFields(field.type.fields)) {\n return true\n }\n\n if (field.type.jsonType === 'array' && field.type.of.length > 0) {\n for (const item of field.type.of) {\n if (\n 'name' in item &&\n typeof item.name === 'string' &&\n item.name.startsWith('internationalizedArray')\n ) {\n return true\n }\n\n if ('fields' in item && Array.isArray(item.fields)) {\n if (hasInternationalizedArrayInFields(item.fields)) {\n return true\n }\n }\n }\n }\n }\n\n return false\n}\n","import {useSchema, type DocumentLayoutProps} from 'sanity'\n\nimport type {PluginConfig} from '../types'\nimport {hasInternationalizedArrayField} from '../utils/hasInternationalizedArrayField'\nimport {InternationalizedArrayProvider} from './InternationalizedArrayContext'\n\nexport function InternationalizedArrayLayout(\n props: DocumentLayoutProps & {pluginConfig: Required<PluginConfig>},\n) {\n const schema = useSchema()\n const schemaType = schema.get(props.documentType)\n\n if (!schemaType) {\n console.error(`Schema type not found: ${props.documentType}`)\n return props.renderDefault(props)\n }\n\n const hasInternationalizedArray = hasInternationalizedArrayField(schemaType)\n if (hasInternationalizedArray && props.pluginConfig.includeForDocumentType(props.documentType)) {\n return (\n <InternationalizedArrayProvider\n internationalizedArray={props.pluginConfig}\n documentType={props.documentType}\n >\n {props.renderDefault(props)}\n </InternationalizedArrayProvider>\n )\n }\n\n return props.renderDefault(props)\n}\n","import {useClient} from 'sanity'\n\nimport {createCacheKey, peek, preloadWithKey, setFunctionCache} from '../cache'\nimport type {PluginConfig} from '../types'\n\nexport default function Preload(props: Required<Pick<PluginConfig, 'apiVersion' | 'languages'>>) {\n const client = useClient({apiVersion: props.apiVersion})\n\n // Use the same cache key structure as the main component\n // This should match the main component when selectedValue is empty\n const cacheKey = createCacheKey({})\n\n if (!Array.isArray(peek({}))) {\n preloadWithKey(async () => {\n if (Array.isArray(props.languages)) {\n return props.languages\n }\n const result = await props.languages(client, {})\n // Populate function cache for sharing with other components\n // Use the same key structure as the main component\n setFunctionCache(props.languages, {}, result)\n return result\n }, cacheKey)\n }\n\n return null\n}\n","import {LANGUAGE_FIELD_NAME} from '../constants'\nimport type {Language, InternationalizedArrayItem} from '../types'\n\n/**\n * Checks whether every language in the provided list has a corresponding entry\n * in the value array. It extracts language IDs from value items using\n * `LANGUAGE_FIELD_NAME` and compares them against the expected language IDs.\n *\n * Returns `true` only when the value array length matches the number of unique\n * languages and every value language ID is found in the languages list\n * (order does not matter). The length check ensures duplicates in value are\n * correctly rejected.\n */\nexport function checkAllLanguagesArePresent(\n languages: Language[],\n value: InternationalizedArrayItem[] | undefined,\n): boolean {\n const filteredLanguageIds = new Set(languages.map((l) => l.id))\n const languagesInUseIds = value ? value.map((v) => v[LANGUAGE_FIELD_NAME]) : []\n\n if (languagesInUseIds.length !== filteredLanguageIds.size) return false\n if (new Set(languagesInUseIds).size !== languagesInUseIds.length) return false\n return languagesInUseIds.every((key) => filteredLanguageIds.has(key))\n}\n","import type {Language, InternationalizedArrayItem} from '../types'\n\n/**\n * Generates the label text for the \"add all / add missing languages\" button.\n *\n * - When there is no existing value: returns `\"Add {title} Field\"` for a\n * single language, or `\"Add all languages\"` for multiple.\n * - When some values already exist: returns `\"Add missing language\"` (singular)\n * or `\"Add missing languages\"` (plural) depending on how many are left.\n */\nexport function createAddAllTitle(\n value: InternationalizedArrayItem[] | undefined,\n languages: Language[],\n): string {\n if (value?.length) {\n return `Add missing ${languages.length - value.length === 1 ? `language` : `languages`}`\n }\n\n return languages.length === 1 && languages[0]\n ? `Add ${languages[0].title} Field`\n : `Add all languages`\n}\n","import type {FieldDefinition, Rule, RuleTypeConstraint, SanityClient} from 'sanity'\n\nexport type Language = {\n id: Intl.UnicodeBCP47LocaleIdentifier\n title: string\n}\n\nexport type AllowedType = 'string' | 'number' | 'boolean' | 'text' | 'reference'\n\nexport type ArrayConfig = {\n name: string\n type: AllowedType\n languages: Language[]\n title?: string\n group?: string\n hidden?: boolean | (() => boolean)\n readOnly?: boolean | (() => boolean)\n validation?: Rule | Rule[]\n field?: {[key: string]: unknown; options: {[key: string]: unknown}}\n}\n\n/**\n * @deprecated Use InternationalizedArrayItem instead\n */\nexport type Value = {\n _key: string\n value?: unknown\n}\n\nexport function isInternationalizedArrayItemType(\n type: string,\n): type is InternationalizedArrayItem['_type'] {\n return type.startsWith('internationalizedArray') && type.endsWith('Value')\n}\n\nexport type InternationalizedArrayItem<T = unknown> = {\n _key: string\n value?: T\n /**\n * string that starts with \"internationalizedArray\" and ends with \"Value\"\n */\n _type: `internationalizedArray${string}Value`\n}\n\nexport type LanguageCallback = (\n client: SanityClient,\n selectedValue: Record<string, unknown>,\n) => Promise<Language[]>\n\nexport type LanguageDisplay = 'titleOnly' | 'codeOnly' | 'titleAndCode'\n\nexport type PluginConfig = {\n /**\n * https://www.sanity.io/docs/api-versioning\n * @defaultValue '2025-10-15'\n */\n apiVersion?: string\n /**\n * Specify fields that should be available in the language callback:\n * ```tsx\n * {\n * select: {\n * markets: 'markets'\n * },\n * languages: (client, {markets}) =>\n * query.fetch(groq`*[_type == \"language\" && market in $markets]{id,title}`, {markets})\n * }\n * ```\n */\n select?: Record<string, string>\n /**\n * You can give it an array of language definitions:\n * ```tsx\n * {\n * languages: [\n * {id: 'en', title: 'English'},\n * {id: 'fr', title: 'French'}\n * ]\n * }\n * ```\n * You can load them async by passing a function that returns a promise:\n * ```tsx\n * {\n * languages: async () => {\n * const response = await fetch('https://example.com/languages')\n * return response.json()\n * }\n * }\n * ```\n * You can query your dataset for languages::\n * ```tsx\n * {\n * languages: (client) =>\n * query.fetch(groq`*[_type == \"language\"]{id,title}`)\n * }\n * ```\n */\n languages: Language[] | LanguageCallback\n /**\n * You can specify a list of language IDs that should be pre-filled when creating a new document\n * ```tsx\n * {\n * defaultLanguages: ['en']\n * }\n * ```\n */\n defaultLanguages?: string[]\n /**\n * Can be a string matching core field types, as well as custom ones:\n * ```tsx\n * {\n * fieldTypes: [\n * \"date\", \"datetime\", \"file\", \"image\", \"number\", \"string\", \"text\", \"url\"\n * ]\n * }\n * ```\n * You can also define a type directly:\n * ```tsx\n * {\n * fieldTypes: [\n * defineField({\n * name: 'featuredProduct',\n * type: 'reference',\n * to: [{type: 'product'}]\n * hidden: (({document}) => !document?.title)\n * })\n * ]\n * }\n * ```\n */\n // oxlint-disable-next-line typescript-eslint/no-redundant-type-constituents\n fieldTypes: (string | RuleTypeConstraint | FieldDefinition)[]\n /**\n * Locations where the \"+ EN\" add language buttons are visible\n * @defaultValue ['field']\n * */\n buttonLocations?: ('field' | 'unstable__fieldAction' | 'document')[]\n /**\n * Show or hide the \"Add missing languages\" button\n * @defaultValue true\n * */\n buttonAddAll?: boolean\n /**\n * How to display the languages on buttons and fields\n * @defaultValue 'code'\n * */\n languageDisplay?: LanguageDisplay\n /**\n * @internal\n * Function to determine if the plugin layout and root input should be included for a given document type.\n * @defaultValue (documentType) => documentType !== 'translation.metadata'\n * @example\n * {\n * includeForDocumentType: (documentType) => documentType === 'translation.metadata'\n * }\n */\n includeForDocumentType?: (documentType: string) => boolean\n}\n","import {type FormInsertPatch, insert, type Path} from 'sanity'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport {\n type Language,\n type InternationalizedArrayItem,\n isInternationalizedArrayItemType,\n} from '../types'\n\ntype AddConfig = {\n // New keys to add to the field\n addLanguageKeys: string[]\n // Schema of the current field\n schemaTypeName: string\n // All languages registered in the plugin\n languages: Language[]\n // Languages that are currently visible\n filteredLanguages: Language[]\n // Current value of the internationalizedArray field\n value?: InternationalizedArrayItem[]\n // Path to this item\n path?: Path\n}\n\n/**\n * Creates an array of Sanity `FormInsertPatch` objects that add new language\n * entries to an internationalized array field.\n *\n * If `addLanguageKeys` is provided, patches are created for those specific\n * language IDs. Otherwise, patches are created for all filtered languages\n * that are not already present in the current `value` array, for example when adding all missing languages.\n *\n * Each new item is assigned the correct `_type` (derived from the schema)\n * and the language identifier via `LANGUAGE_FIELD_NAME`.\n *\n * Insertions are ordered to maintain the same sequence as the master\n * `languages` list: each new item is inserted before the next existing\n * language in the value array, or appended at the end if no subsequent\n * language exists.\n */\nexport function createAddLanguagePatches(config: AddConfig): FormInsertPatch[] {\n const {addLanguageKeys, schemaTypeName, languages, filteredLanguages, value, path = []} = config\n\n const type = `${schemaTypeName}Value`\n if (!isInternationalizedArrayItemType(type)) {\n throw new Error(`Invalid internationalized array type: ${type}`)\n }\n const itemBase = {_type: type}\n\n // Create new items\n const getNewItems = () => {\n if (Array.isArray(addLanguageKeys) && addLanguageKeys.length > 0) {\n return addLanguageKeys\n .filter((id) => {\n if (value?.length) {\n // Check if the language is already in the value and filter it out if it exists to avoid duplicates\n return !value.find((v) => v[LANGUAGE_FIELD_NAME] === id)\n }\n return true\n })\n .map((id) => Object.assign({}, itemBase, {[LANGUAGE_FIELD_NAME]: id}))\n }\n\n return filteredLanguages\n .filter((language) => {\n return value?.length ? !value.find((v) => v[LANGUAGE_FIELD_NAME] === language.id) : true\n })\n .map((language) => Object.assign({}, itemBase, {[LANGUAGE_FIELD_NAME]: language.id}))\n }\n const newItems = getNewItems()\n\n // Insert new items in the correct order\n const languagesInUse = value?.length ? value.map((v) => v) : []\n\n const insertions = newItems.map((item) => {\n // What's the original index of this language?\n const itemLanguage = item[LANGUAGE_FIELD_NAME]\n const languageIndex = languages.findIndex((l) => itemLanguage === l.id)\n\n // What languages are there beyond that index?\n const remainingLanguages = languages.slice(languageIndex + 1)\n\n // So what is the index in the current value array of the next language in the language array?\n const nextLanguageIndex = languagesInUse.findIndex((l) =>\n remainingLanguages.find((r) => r.id === l[LANGUAGE_FIELD_NAME]),\n )\n\n // Keep local state up to date incase multiple insertions are being made\n if (nextLanguageIndex < 0) {\n languagesInUse.push(item)\n } else {\n languagesInUse.splice(nextLanguageIndex, 0, item)\n }\n\n return nextLanguageIndex < 0\n ? // No next language (-1), add to end of array\n insert([item], 'after', [...path, nextLanguageIndex])\n : // Next language found, insert before that\n insert([item], 'before', [...path, nextLanguageIndex])\n })\n\n return insertions\n}\n","import {AddIcon, TranslateIcon} from '@sanity/icons'\nimport {useCallback} from 'react'\nimport {\n defineDocumentFieldAction,\n type DocumentFieldActionItem,\n type DocumentFieldActionProps,\n PatchEvent,\n setIfMissing,\n useFormValue,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport {useInternationalizedArrayContext} from '../components/InternationalizedArrayContext'\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport type {Language, InternationalizedArrayItem} from '../types'\nimport {checkAllLanguagesArePresent} from '../utils/checkAllLanguagesArePresent'\nimport {createAddAllTitle} from '../utils/createAddAllTitle'\nimport {createAddLanguagePatches} from '../utils/createAddLanguagePatches'\n\nconst createTranslateFieldActions: (\n fieldActionProps: DocumentFieldActionProps,\n context: {\n languages: Language[]\n filteredLanguages: Language[]\n },\n) => DocumentFieldActionItem[] = (fieldActionProps, {languages, filteredLanguages}) =>\n languages.map((language) => {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const value = useFormValue(fieldActionProps.path) as InternationalizedArrayItem[]\n const disabled =\n value && Array.isArray(value)\n ? Boolean(value?.find((item) => item[LANGUAGE_FIELD_NAME] === language.id))\n : false\n const hidden = !filteredLanguages.some((f) => f.id === language.id)\n\n const {onChange} = useDocumentPane()\n\n const onAction = useCallback(() => {\n const {schemaType, path} = fieldActionProps\n\n const addLanguageKeys = [language.id]\n const patches = createAddLanguagePatches({\n addLanguageKeys,\n schemaTypeName: schemaType.name,\n languages,\n filteredLanguages,\n value,\n path,\n })\n\n onChange(PatchEvent.from([setIfMissing([], path), ...patches]))\n }, [language.id, value, onChange])\n\n return {\n type: 'action',\n icon: AddIcon,\n onAction,\n title: language.title,\n hidden,\n disabled,\n }\n })\n\nconst AddMissingTranslationsFieldAction: (\n fieldActionProps: DocumentFieldActionProps,\n context: {\n languages: Language[]\n filteredLanguages: Language[]\n },\n) => DocumentFieldActionItem = (fieldActionProps, {languages, filteredLanguages}) => {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const value = useFormValue(fieldActionProps.path) as InternationalizedArrayItem[]\n const disabled = value && value.length === filteredLanguages.length\n const hidden = checkAllLanguagesArePresent(filteredLanguages, value)\n\n const {onChange} = useDocumentPane()\n\n const onAction = useCallback(() => {\n const {schemaType, path} = fieldActionProps\n\n const addLanguageKeys: string[] = []\n const patches = createAddLanguagePatches({\n addLanguageKeys,\n schemaTypeName: schemaType.name,\n languages,\n filteredLanguages,\n value,\n path,\n })\n\n onChange(PatchEvent.from([setIfMissing([], path), ...patches]))\n }, [fieldActionProps, filteredLanguages, languages, onChange, value])\n\n return {\n type: 'action',\n icon: AddIcon,\n onAction,\n title: createAddAllTitle(value, filteredLanguages),\n disabled,\n hidden,\n }\n}\n\nexport const internationalizedArrayFieldAction = defineDocumentFieldAction({\n name: 'internationalizedArray',\n useAction(fieldActionProps) {\n const isInternationalizedArrayField =\n fieldActionProps?.schemaType?.type?.name.startsWith('internationalizedArray')\n const {languages, filteredLanguages} = useInternationalizedArrayContext()\n\n const translateFieldActions = createTranslateFieldActions(fieldActionProps, {\n languages,\n filteredLanguages,\n })\n\n return {\n type: 'group',\n icon: TranslateIcon,\n title: 'Add Translation',\n renderAsButton: true,\n children: isInternationalizedArrayField\n ? [\n ...translateFieldActions,\n AddMissingTranslationsFieldAction(fieldActionProps, {\n languages,\n filteredLanguages,\n }),\n ]\n : [],\n hidden: !isInternationalizedArrayField,\n }\n },\n})\n","import camelCase from 'lodash-es/camelCase.js'\nimport upperFirst from 'lodash-es/upperFirst.js'\n\n/**\n * Converts a string to PascalCase (e.g. `\"my-field\"` -> `\"MyField\"`).\n */\nexport function pascalCase(string: string): string {\n return upperFirst(camelCase(string))\n}\n\n/**\n * Generates the schema type name for an internationalized array field.\n *\n * - Without the value suffix: `\"internationalizedArray{PascalName}\"`\n * (used for the outer array type)\n * - With the value suffix: `\"internationalizedArray{PascalName}Value\"`\n * (used for the inner object type that wraps each language entry)\n *\n * For example, `createFieldName('block-content', true)` returns\n * `\"internationalizedArrayBlockContentValue\"`.\n */\nexport function createFieldName(name: string, addValue = false): string {\n return addValue\n ? [`internationalizedArray`, pascalCase(name), `Value`].join(``)\n : [`internationalizedArray`, pascalCase(name)].join(``)\n}\n","import {Card, Code, Stack, Text} from '@sanity/ui'\nimport type React from 'react'\n\nconst schemaExample = {\n languages: [\n {id: 'en', title: 'English'},\n {id: 'no', title: 'Norsk'},\n ],\n}\n\nexport default function Feedback(): React.ReactElement {\n return (\n <Card tone=\"caution\" border radius={2} padding={3}>\n <Stack space={4}>\n <Text>\n An array of language objects must be passed into the <code>internationalizedArray</code>{' '}\n helper function, each with an <code>id</code> and <code>title</code> field. Example:\n </Text>\n <Card padding={2} border radius={2}>\n <Code size={1} language=\"javascript\">\n {JSON.stringify(schemaExample, null, 2)}\n </Code>\n </Card>\n </Stack>\n </Card>\n )\n}\n","import {AddIcon} from '@sanity/icons'\nimport {useLanguageFilterStudioContext} from '@sanity/language-filter'\nimport {Button, Card, Stack, Text, useToast} from '@sanity/ui'\nimport type React from 'react'\nimport {useCallback, useEffect, useMemo} from 'react'\nimport {\n type ArrayOfObjectsInputProps,\n ArrayOfObjectsItem,\n MemberItemError,\n set,\n setIfMissing,\n useFormValue,\n useGetFormValue,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport type {InternationalizedArrayItem} from '../types'\nimport {checkAllLanguagesArePresent} from '../utils/checkAllLanguagesArePresent'\nimport {createAddAllTitle} from '../utils/createAddAllTitle'\nimport {createAddLanguagePatches} from '../utils/createAddLanguagePatches'\nimport AddButtons from './AddButtons'\nimport Feedback from './Feedback'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\n/**\n * Main array input component for internationalized array fields.\n *\n * Replaces the default Sanity array input and manages the full lifecycle of\n * language entries:\n *\n * - **Language filter integration**: When `@sanity/language-filter` is active\n * for the current document type, array members are filtered to only show\n * languages matching the user's selection.\n * - **Adding languages**: Exposes per-language buttons and an \"Add all / Add\n * missing languages\" button (controlled by `buttonAddAll` and\n * `buttonLocations` config). Dispatches `setIfMissing` + `insert` patches.\n * - **Default languages**: Automatically adds entries for languages listed in\n * `defaultLanguages` when a document is first created or when those entries\n * are missing.\n * - **Ordering**: Detects when value items are out of order relative to the\n * master `languages` list and automatically re-sorts them.\n * - **Validation**: Shows a `<Feedback>` component if the languages\n * configuration is invalid (e.g. missing `id` or `title`).\n * - **Empty state**: Displays a \"no translations\" message when the field has\n * no entries and the add buttons are not visible.\n */\nexport default function InternationalizedArray(\n props: ArrayOfObjectsInputProps,\n): React.ReactElement {\n const {members, value: _value, schemaType, onChange, readOnly: documentReadOnly} = props\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion\n const value = _value as InternationalizedArrayItem[]\n const readOnly = typeof schemaType.readOnly === 'boolean' ? schemaType.readOnly : false\n const toast = useToast()\n\n const getFormValue = useGetFormValue()\n const {languages, filteredLanguages, defaultLanguages, buttonAddAll, buttonLocations} =\n useInternationalizedArrayContext()\n\n // Support updating the UI if languageFilter is installed\n const {selectedLanguageIds, options: languageFilterOptions} = useLanguageFilterStudioContext()\n const documentType = useFormValue(['_type'])\n const languageFilterEnabled =\n typeof documentType === 'string' && languageFilterOptions.documentTypes.includes(documentType)\n\n const filteredMembers = useMemo(\n () =>\n languageFilterEnabled\n ? members.filter((member) => {\n // This member is the outer object created by the plugin\n // Satisfy TS\n if (member.kind !== 'item') {\n return false\n }\n\n // This is the inner \"value\" field member created by this plugin\n const valueMember = member.item.members[0]\n\n // Satisfy TS\n if (!valueMember || valueMember.kind !== 'field') {\n return false\n }\n\n return languageFilterOptions.filterField(\n member.item.schemaType,\n valueMember,\n selectedLanguageIds,\n )\n })\n : members,\n [languageFilterEnabled, members, languageFilterOptions, selectedLanguageIds],\n )\n\n const handleAddLanguages = useCallback(\n (addLanguageKeys: string[] | string) => {\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion\n const formValue = getFormValue(props.path) as InternationalizedArrayItem[]\n if (!filteredLanguages?.length) {\n return\n }\n\n const patches = createAddLanguagePatches({\n addLanguageKeys: Array.isArray(addLanguageKeys) ? addLanguageKeys : [addLanguageKeys],\n schemaTypeName: schemaType.name,\n languages,\n filteredLanguages,\n value: formValue,\n })\n\n onChange([setIfMissing([]), ...patches])\n },\n [filteredLanguages, languages, onChange, schemaType, getFormValue, props.path],\n )\n\n const {isDeleting} = useDocumentPane()\n\n // Create a stable dependency string that only changes when language keys change\n const languageKeysFromValue = value\n ?.map((v) => v[LANGUAGE_FIELD_NAME] ?? v._key)\n .filter(Boolean)\n .join(',')\n\n const addedLanguages = useMemo(() => {\n const languageKeys = languageKeysFromValue?.split(',') || []\n if (!languageKeys?.length) return []\n if (!languages?.length) return []\n\n return languages.filter((l) => languageKeys?.find((key) => key === l.id)).map((l) => l.id)\n }, [languageKeysFromValue, languages])\n\n useEffect(() => {\n const hasAddedDefaultLanguages = defaultLanguages\n .filter((language) => languages.find((l) => l.id === language))\n .every((language) => addedLanguages.includes(language))\n\n if (!isDeleting && !hasAddedDefaultLanguages) {\n const languagesToAdd = defaultLanguages\n .filter((language) => !addedLanguages.includes(language))\n .filter((language) => languages.find((l) => l.id === language))\n // Account for strict mode by scheduling the update\n const timeout = setTimeout(() => {\n if (!documentReadOnly) handleAddLanguages(languagesToAdd)\n })\n return () => clearTimeout(timeout)\n }\n return undefined\n }, [\n isDeleting,\n handleAddLanguages,\n defaultLanguages,\n addedLanguages,\n languages,\n documentReadOnly,\n ])\n\n // NOTE: This is reordering and re-setting the whole array, it could be surgical\n const handleRestoreOrder = useCallback(() => {\n if (!value?.length || !languages?.length) {\n return\n }\n\n // Create a new value array in the correct order\n // This would also strip out values that don't have a language as the key\n const updatedValue = value\n .reduce((acc, v) => {\n const newIndex = languages.findIndex((l) => l.id === v?.[LANGUAGE_FIELD_NAME])\n\n if (newIndex > -1) {\n acc[newIndex] = v\n }\n\n return acc\n }, [] as InternationalizedArrayItem[])\n .filter(Boolean)\n\n if (value?.length !== updatedValue.length) {\n toast.push({\n title: 'There was an error reordering languages',\n status: 'warning',\n })\n }\n\n onChange(set(updatedValue))\n }, [toast, languages, onChange, value])\n\n const allKeysAreLanguages = useMemo(() => {\n if (!value?.length || !languages?.length) {\n return true\n }\n\n return value?.every((v) => languages.find((l) => l?.id === v?.[LANGUAGE_FIELD_NAME]))\n }, [value, languages])\n\n const languagesOutOfOrder = useMemo(() => {\n if (!value?.length || !addedLanguages.length) {\n return []\n }\n\n return value\n .map((v, vIndex) =>\n vIndex === addedLanguages.findIndex((language) => language === v[LANGUAGE_FIELD_NAME])\n ? null\n : v,\n )\n .filter(Boolean)\n }, [value, addedLanguages])\n\n const languagesAreValid = useMemo(\n () =>\n !languages?.length || (languages?.length && languages.every((item) => item.id && item.title)),\n [languages],\n )\n\n // Automatically restore order of fields\n useEffect(() => {\n if (languagesOutOfOrder.length > 0 && allKeysAreLanguages && !documentReadOnly) {\n handleRestoreOrder()\n }\n }, [languagesOutOfOrder, allKeysAreLanguages, handleRestoreOrder, documentReadOnly])\n\n // compare value keys with possible languages\n const allLanguagesArePresent = useMemo(\n () => checkAllLanguagesArePresent(filteredLanguages, value),\n [filteredLanguages, value],\n )\n const addAllMissingLanguages = useCallback(() => {\n handleAddLanguages(filteredLanguages.map((language) => language.id))\n }, [filteredLanguages, handleAddLanguages])\n\n if (!languagesAreValid) {\n return <Feedback />\n }\n\n const addButtonsAreVisible =\n // Plugin was configured to display buttons here (default!)\n buttonLocations.includes('field') &&\n // There's at least one language visible\n filteredLanguages?.length > 0 &&\n // Not every language has a value yet\n !allLanguagesArePresent\n const fieldHasMembers = members?.length > 0\n const addAllTitle = createAddAllTitle(value, filteredLanguages)\n\n return (\n <Stack space={2}>\n {filteredMembers.map((member) => {\n if (member.kind === 'item') {\n return <ArrayOfObjectsItem {...props} key={member.key} member={member} />\n }\n return <MemberItemError key={member.key} member={member} />\n })}\n\n {/* Give some feedback in the UI so the field doesn't look \"missing\" */}\n {!addButtonsAreVisible && !fieldHasMembers ? (\n <Card border tone=\"transparent\" padding={3} radius={2}>\n <Text size={1}>This internationalized field currently has no translations.</Text>\n </Card>\n ) : null}\n\n {addButtonsAreVisible ? (\n <Stack space={2}>\n <AddButtons\n languagesInUse={addedLanguages}\n readOnly={readOnly}\n handleClick={handleAddLanguages}\n />\n {buttonAddAll ? (\n <Button\n tone=\"primary\"\n mode=\"ghost\"\n data-testid=\"add-all-languages\"\n disabled={readOnly || allLanguagesArePresent}\n icon={AddIcon}\n text={addAllTitle}\n onClick={addAllMissingLanguages}\n />\n ) : null}\n </Stack>\n ) : null}\n </Stack>\n )\n}\n","import type {SchemaType} from 'sanity'\n\nimport type {ArrayFieldOptions} from '../schema/array'\n\nexport function getLanguagesFieldOption(\n schemaType: SchemaType | undefined,\n): ArrayFieldOptions['languages'] | undefined {\n if (!schemaType) {\n return undefined\n }\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const languagesOption = (schemaType.options as ArrayFieldOptions)?.languages\n if (languagesOption) {\n return languagesOption\n }\n return getLanguagesFieldOption(schemaType.type)\n}\n","import {defineField, type FieldDefinition, type FieldProps, type Rule} from 'sanity'\n\nimport {getFunctionCache, peek, setFunctionCache} from '../cache'\nimport {createFieldName} from '../components/createFieldName'\nimport {getSelectedValue} from '../components/getSelectedValue'\nimport InternationalizedArray from '../components/InternationalizedArray'\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport type {Language, LanguageCallback, InternationalizedArrayItem} from '../types'\nimport {getLanguagesFieldOption} from '../utils/getLanguagesFieldOption'\n\ntype ArrayFactoryConfig = {\n apiVersion: string\n select?: Record<string, string>\n languages: Language[] | LanguageCallback\n defaultLanguages?: string[]\n type: string | FieldDefinition\n}\n\nexport type ArrayFieldOptions = Pick<ArrayFactoryConfig, 'apiVersion' | 'select' | 'languages'>\n\nexport default (config: ArrayFactoryConfig) => {\n const {apiVersion, select, languages, type} = config\n const typeName = typeof type === `string` ? type : type.name\n const arrayName = createFieldName(typeName)\n const objectName = createFieldName(typeName, true)\n\n return defineField({\n name: arrayName,\n title: 'Internationalized array',\n type: 'array',\n components: {\n field: (props: FieldProps) =>\n props.renderDefault({\n ...props,\n // Reset the level to avoid nested styling\n level: 0,\n }),\n input: InternationalizedArray,\n },\n options: {\n // @ts-expect-error - these options are required for validation rules – not the custom input component\n apiVersion,\n select,\n languages,\n },\n of: [\n defineField({\n ...(typeof type === 'string' ? {} : type),\n name: objectName,\n type: objectName,\n }),\n ],\n // @ts-expect-error - fix typings\n validation: (rule: Rule) =>\n rule.custom<InternationalizedArrayItem[]>(async (value, context) => {\n if (!value || value.length === 0) {\n return true\n }\n\n // Early return for simple cases to avoid expensive operations\n if (value.length === 1 && !value[0]?.[LANGUAGE_FIELD_NAME]) {\n return true\n }\n\n const selectedValue = getSelectedValue(select, context.document)\n const client = context.getClient({apiVersion})\n\n let contextLanguages: Language[] = []\n const languagesFieldOption = getLanguagesFieldOption(context?.type)\n\n if (Array.isArray(languagesFieldOption)) {\n contextLanguages = languagesFieldOption\n } else if (Array.isArray(peek(selectedValue))) {\n contextLanguages = peek(selectedValue) || []\n } else if (typeof languagesFieldOption === 'function') {\n // Try to get from function cache first (if it's the same function as the component)\n const cachedLanguages = getFunctionCache(languagesFieldOption, selectedValue)\n\n if (Array.isArray(cachedLanguages)) {\n contextLanguages = cachedLanguages\n } else {\n // Try suspend cache as fallback\n const suspendCachedLanguages = peek(selectedValue)\n if (Array.isArray(suspendCachedLanguages)) {\n contextLanguages = suspendCachedLanguages\n } else {\n // Only make the async call if we don't have cached data\n contextLanguages = await languagesFieldOption(client, selectedValue)\n // Cache the result for future validation calls\n setFunctionCache(languagesFieldOption, selectedValue, contextLanguages)\n }\n }\n }\n\n if (value && value.length > contextLanguages.length) {\n return `Cannot be more than ${\n contextLanguages.length === 1 ? `1 item` : `${contextLanguages.length} items`\n }`\n }\n\n // Create a Set for faster language ID lookups\n const languageIds = new Set(contextLanguages.map((lang) => lang.id))\n\n // Check for invalid language keys\n const nonLanguageKeys = value.filter(\n (item) => item?.[LANGUAGE_FIELD_NAME] && !languageIds.has(item[LANGUAGE_FIELD_NAME]),\n )\n if (nonLanguageKeys.length) {\n return {\n message: `Array item keys must be valid languages registered to the field type`,\n paths: nonLanguageKeys.map((item) => [{_key: item._key}]),\n }\n }\n\n // Check for duplicate language keys (more efficient)\n const seenLanguages = new Set<string>()\n const duplicateValues: InternationalizedArrayItem[] = []\n\n for (const item of value) {\n if (item?.[LANGUAGE_FIELD_NAME]) {\n if (seenLanguages.has(item[LANGUAGE_FIELD_NAME])) {\n duplicateValues.push(item)\n } else {\n seenLanguages.add(item[LANGUAGE_FIELD_NAME])\n }\n }\n }\n\n if (duplicateValues.length) {\n return {\n message: 'There can only be one field per language',\n paths: duplicateValues.map((item) => [{_key: item._key}]),\n }\n }\n\n return true\n }),\n })\n}\n","import type {CardTone} from '@sanity/ui'\nimport type {FormNodeValidation} from 'sanity'\n\n/**\n * Maps an array of Sanity form validation entries to a `@sanity/ui` `CardTone`\n * for visual feedback on internationalized array items.\n *\n * - Returns `'critical'` if any validation has `level: 'error'`\n * - Returns `'caution'` if any validation has `level: 'warning'` (and no errors)\n * - Returns `undefined` otherwise (no tone applied)\n *\n * Error level always takes precedence over warning.\n */\nexport function getToneFromValidation(validations: FormNodeValidation[]): CardTone | undefined {\n if (!validations?.length) {\n return undefined\n }\n\n const validationLevels = new Set(validations.map((v) => v.level))\n\n if (validationLevels.has('error')) {\n return `critical`\n } else if (validationLevels.has('warning')) {\n return `caution`\n }\n\n return undefined\n}\n","import {RemoveCircleIcon} from '@sanity/icons'\nimport {\n Box,\n Button,\n Card,\n Flex,\n Label,\n Menu,\n MenuButton,\n MenuItem,\n Spinner,\n Stack,\n Text,\n Tooltip,\n} from '@sanity/ui'\nimport type React from 'react'\nimport {type ReactNode, useCallback, useMemo} from 'react'\nimport {type FormPatch, type ObjectItemProps, PatchEvent, type Path, useFormValue} from 'sanity'\nimport {set, unset} from 'sanity'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport type {InternationalizedArrayItem} from '../types'\nimport {getLanguageDisplay} from '../utils/getLanguageDisplay'\nimport {getToneFromValidation} from './getToneFromValidation'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\nfunction ChangeLanguageButton(props: {\n value: InternationalizedArrayItem\n path: Path\n onChange: (patch: FormPatch[] | PatchEvent | FormPatch) => void\n}): ReactNode {\n const {value, onChange, path} = props\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const parentValue = useFormValue(path.slice(0, -1)) as InternationalizedArrayItem[]\n const {languages} = useInternationalizedArrayContext()\n\n const languageKeysInUse = useMemo(\n () => parentValue?.map((v) => v[LANGUAGE_FIELD_NAME]) ?? [],\n [parentValue],\n )\n\n // Changes the key of this item, ideally to a valid language\n const handleKeyChange = (event: React.MouseEvent<HTMLButtonElement>): void => {\n const languageId = event?.currentTarget?.value\n\n if (!value || !languages?.length || !languages.find((l) => l.id === languageId)) {\n return\n }\n\n onChange([set(languageId, [LANGUAGE_FIELD_NAME])])\n }\n\n return (\n <MenuButton\n button={<Button fontSize={1} text={`Change \"${value[LANGUAGE_FIELD_NAME]}\"`} />}\n id={`${value[LANGUAGE_FIELD_NAME]}-change-key`}\n menu={\n <Menu>\n {languages.map((lang) => (\n <MenuItem\n disabled={languageKeysInUse.includes(lang.id)}\n fontSize={1}\n key={lang.id}\n text={lang.id.toLocaleUpperCase()}\n value={lang.id}\n // @ts-expect-error - fix typings\n onClick={handleKeyChange}\n />\n ))}\n </Menu>\n }\n popover={{portal: true}}\n />\n )\n}\n\nfunction RemoveButton({\n isDefault,\n readOnly,\n onChange,\n}: {\n isDefault: boolean\n readOnly: boolean\n onChange: (patch: FormPatch[] | PatchEvent | FormPatch) => void\n}): ReactNode {\n // Removes this item from the array\n const handleUnset = (): void => {\n onChange(unset())\n }\n\n return (\n <Tooltip\n animate\n disabled={!isDefault}\n content={\n <Text muted size={1}>\n Can't remove default language\n </Text>\n }\n fallbackPlacements={['right', 'left']}\n placement=\"top\"\n portal\n >\n <span>\n <Button\n mode=\"bleed\"\n icon={RemoveCircleIcon}\n tone=\"critical\"\n disabled={readOnly || isDefault}\n onClick={handleUnset}\n />\n </span>\n </Tooltip>\n )\n}\n\n/**\n * Renders a single row of an internationalized array: a language label (or\n * \"Change\" menu for invalid keys), the value input, and a remove button.\n *\n * Key behaviours:\n * - Wraps `onChange` to intercept paste operations into empty Portable Text\n * fields, ensuring `setIfMissing` and correct path prefixing.\n * - Detects items needing migration (missing `LANGUAGE_FIELD_NAME`) and hides\n * the language label in that state.\n * - Shows a `MenuButton` with available languages when the current key is\n * not a valid language.\n * - Disables the remove button for languages listed in `defaultLanguages`.\n * - Shows a `Spinner` when languages have not been loaded yet.\n * - Applies a `CardTone` based on validation state via `getToneFromValidation`.\n */\nexport default function InternationalizedInput(\n props: ObjectItemProps<InternationalizedArrayItem>,\n): ReactNode {\n // Extract the original onChange to avoid dependency issues\n const originalOnChange = props.inputProps.onChange\n\n // Create a wrapped onChange handler to intercept patches for paste operations\n const wrappedOnChange = useCallback(\n (patches: unknown) => {\n // Ensure patches is an array before proceeding with paste logic\n // For single patch operations (like unset), pass through directly\n if (!Array.isArray(patches)) {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return originalOnChange(patches as Parameters<typeof originalOnChange>[0])\n }\n\n // Check if this is a paste operation into an empty or uninitialized Portable Text field\n const valueField = props.value?.value\n const isEmptyOrUndefined =\n valueField === undefined ||\n valueField === null ||\n (Array.isArray(valueField) && valueField.length === 0)\n\n if (isEmptyOrUndefined) {\n // Check for insert patches that are trying to operate on a non-existent structure\n const hasProblematicInsert = patches.some((patch: {type?: string; path?: unknown[]}) => {\n // Ensure patch exists and has required properties\n if (!patch || typeof patch !== 'object') {\n return false\n }\n\n // Look for insert patches targeting the value field or direct array index\n if (\n patch.type === 'insert' &&\n patch.path &&\n Array.isArray(patch.path) &&\n patch.path.length > 0\n ) {\n // The path might be ['value', index] or just [index] depending on context\n const isTargetingValue = patch.path[0] === 'value' || typeof patch.path[0] === 'number'\n return isTargetingValue\n }\n return false\n })\n\n if (hasProblematicInsert) {\n // First, ensure the value field exists as an empty array if it doesn't\n const initPatch =\n valueField === undefined ? {type: 'setIfMissing', path: ['value'], value: []} : null\n\n // Transform the patches to ensure they work with the nested structure\n const fixedPatches = patches.map(\n (patch: {type?: string; path?: unknown[]; [key: string]: unknown}) => {\n // Ensure patch exists and has required properties\n if (!patch || typeof patch !== 'object') {\n return patch\n }\n\n if (patch.type === 'insert' && patch.path && Array.isArray(patch.path)) {\n // Ensure the path is correct for the nested structure\n const fixedPath = patch.path[0] === 'value' ? patch.path : ['value', ...patch.path]\n const fixedPatch = {...patch, path: fixedPath}\n return fixedPatch\n }\n return patch\n },\n )\n\n // If we need to initialize the field, include that patch first\n const allPatches = initPatch ? [initPatch, ...fixedPatches] : fixedPatches\n\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return originalOnChange(allPatches as Parameters<typeof originalOnChange>[0])\n }\n }\n\n // For all other cases, pass through unchanged\n return originalOnChange(patches as Parameters<typeof originalOnChange>[0])\n },\n [originalOnChange, props.value?.value],\n )\n\n const inlineProps = useMemo(\n () => ({\n ...props.inputProps,\n members: props.inputProps.members.filter((m) => m.kind === 'field' && m.name === 'value'),\n value: props.value,\n // Use our wrapped onChange handler\n onChange: wrappedOnChange,\n }),\n [props.inputProps, props.value, wrappedOnChange],\n )\n\n const {validation, value, readOnly} = inlineProps\n\n // The parent array contains the languages from the plugin config\n const {languages, languageDisplay, defaultLanguages} = useInternationalizedArrayContext()\n\n const keyIsValid = languages?.length\n ? languages.find((l) => l.id === value[LANGUAGE_FIELD_NAME])\n : false\n\n if (!languages) {\n return <Spinner />\n }\n\n const language = languages.find((l) => l.id === value[LANGUAGE_FIELD_NAME])\n const languageTitle: string =\n keyIsValid && language ? getLanguageDisplay(languageDisplay, language.title, language.id) : ''\n\n const isDefault = defaultLanguages.includes(value[LANGUAGE_FIELD_NAME])\n\n return (\n <Card paddingTop={2} tone={getToneFromValidation(validation)}>\n <Stack space={2}>\n {keyIsValid ? (\n <Label muted size={1}>\n {languageTitle}\n </Label>\n ) : (\n <ChangeLanguageButton value={value} path={props.path} onChange={originalOnChange} />\n )}\n <Flex align=\"center\" gap={2}>\n <Box flex={1}>{props.inputProps.renderInput(inlineProps)}</Box>\n <RemoveButton\n isDefault={isDefault}\n readOnly={Boolean(readOnly)}\n onChange={originalOnChange}\n />\n </Flex>\n </Stack>\n </Card>\n )\n}\n","import {defineField, type FieldDefinition, type FieldProps} from 'sanity'\n\nimport {createFieldName} from '../components/createFieldName'\nimport InternationalizedInput from '../components/InternationalizedInput'\nimport {LANGUAGE_FIELD_NAME} from '../constants'\n\ntype ObjectFactoryConfig = {\n type: string | FieldDefinition\n}\n\nexport default (config: ObjectFactoryConfig) => {\n const {type} = config\n const typeName = typeof type === `string` ? type : type.name\n const objectName = createFieldName(typeName, true)\n\n return defineField({\n name: objectName,\n title: `Internationalized array ${typeName}`,\n type: 'object',\n components: {\n // @ts-expect-error - fix typings\n item: InternationalizedInput,\n field: (props: FieldProps) =>\n props.renderDefault({\n ...props,\n // Reset the level to avoid nested styling\n level: 0,\n }),\n },\n fields: [\n defineField({\n ...(typeof type === 'string' ? {type} : type),\n name: 'value',\n components: {\n field: (props: FieldProps) => props.renderDefault({...props, title: ''}),\n },\n }),\n ],\n preview: {\n select: {\n title: 'value',\n subtitle: LANGUAGE_FIELD_NAME,\n },\n },\n })\n}\n","import {definePlugin, isObjectInputProps} from 'sanity'\n\nimport {InternationalizedArrayFormInput} from './components/InternationalizedArrayFormInput'\nimport {InternationalizedArrayLayout} from './components/InternationalizedArrayLayout'\nimport Preload from './components/Preload'\nimport {CONFIG_DEFAULT} from './constants'\nimport {internationalizedArrayFieldAction} from './fieldActions'\nimport array from './schema/array'\nimport object from './schema/object'\nimport type {PluginConfig} from './types'\nimport {hasInternationalizedArrayField} from './utils/hasInternationalizedArrayField'\n\nexport const internationalizedArray = definePlugin<PluginConfig>((config) => {\n const pluginConfig = {...CONFIG_DEFAULT, ...config}\n const {\n apiVersion = '2025-10-15',\n select,\n languages,\n fieldTypes,\n defaultLanguages,\n buttonLocations,\n } = pluginConfig\n\n return {\n name: 'sanity-plugin-internationalized-array',\n // Preload languages for use throughout the Studio\n studio: Array.isArray(languages)\n ? undefined\n : {\n components: {\n layout: (props) => (\n <>\n <Preload apiVersion={apiVersion} languages={languages} />\n {props.renderDefault(props)}\n </>\n ),\n },\n },\n // Optional: render \"add language\" buttons as field actions\n document: {\n components: {\n unstable_layout: (props) => (\n <InternationalizedArrayLayout {...props} pluginConfig={pluginConfig} />\n ),\n },\n unstable_fieldActions: buttonLocations.includes('unstable__fieldAction')\n ? (prev) => [...prev, internationalizedArrayFieldAction]\n : undefined,\n },\n // Wrap document editor with a language provider\n form: {\n components: {\n input: (props) => {\n const isRootInput = props.id === 'root' && isObjectInputProps(props)\n\n if (!isRootInput) {\n return props.renderDefault(props)\n }\n\n const hasInternationalizedArray = hasInternationalizedArrayField(props.schemaType)\n\n if (\n hasInternationalizedArray &&\n pluginConfig.includeForDocumentType(props.schemaType.name)\n ) {\n return <InternationalizedArrayFormInput {...props} pluginConfig={pluginConfig} />\n }\n return props.renderDefault(props)\n },\n },\n },\n // Register custom schema types for the outer array and the inner object\n schema: {\n types: [\n ...fieldTypes.map((type) => array({type, apiVersion, select, languages, defaultLanguages})),\n ...fieldTypes.map((type) => object({type})),\n ],\n },\n }\n})\n"],"names":["namespace","functionKeyCache","WeakMap","promiseCache","Map","functionCache","stringifyCacheKey","key","JSON","stringify","preloadWithKey","fn","keyStr","has","set","clear","peek","selectedValue","version","promise","get","_status","_value","createCacheKey","workspaceId","selectedValueHash","createOrGetPromise","getFunctionKey","cachedKey","fnStr","toString","hash","maxLength","Math","min","length","i","char","charCodeAt","abs","createFunctionCacheKey","functionKey","getFunctionCache","setFunctionCache","languages","LANGUAGE_FIELD_NAME","MAX_COLUMNS","codeOnly","titleOnly","titleAndCode","CONFIG_DEFAULT","select","defaultLanguages","fieldTypes","apiVersion","buttonLocations","buttonAddAll","languageDisplay","includeForDocumentType","documentType","getDocumentsToTranslate","value","rootPath","Array","isArray","arrayRootPath","internationalizedValues","filter","item","type","_type","startsWith","endsWith","map","internationalizedValue","Object","assign","path","pathString","join","flatMap","index","startsWithUnderscoreRegex","keys","match","getLanguageDisplay","title","code","toUpperCase","getSelectedValue","document","selection","entries","InternationalizedArrayContext","createContext","filteredLanguages","useInternationalizedArrayContext","useContext","InternationalizedArrayProvider","props","$","_c","internationalizedArray","t0","client","useClient","workspace","useWorkspace","formState","useDocumentPane","deferredDocument","useDeferredValue","t1","t2","bb0","name","t3","t4","t5","cacheKey","bb1","result","t6","languagesPromise","use","selectedLanguageIds","options","languageFilterOptions","useLanguageFilterStudioContext","documentTypes","includes","languageFilterEnabled","language","id","t7","context","t8","children","AddButtons","readOnly","languagesInUse","handleClick","languageTitle","undefined","AddIcon","DocumentAddButtons","getFormValue","useGetFormValue","toast","useToast","onChange","schema","useSchema","typeName","baseTypeName","charAt","toLowerCase","slice","arrayBasedTypes","Set","schemaType","valueField","fields","find","_temp","fieldType","jsonType","of","getInitialValueForType","languageId","isSanityDocument","push","status","documentsToTranslation","alreadyTranslated","translation","removeDuplicates","reduce","filteredTranslations","translation_0","alreadyTranslation","filteredTranslation","patches","toTranslate","initialValue","ifMissing","setIfMissing","insertValue","insert","PatchEvent","from","flat","handleDocumentButtonClick","Symbol","for","f","InternationalizedArrayFormInput","pluginConfig","renderDefault","hasInternationalizedArrayField","isDocumentSchemaType","hasInternationalizedArrayInFields","field","InternationalizedArrayLayout","console","error","Preload","checkAllLanguagesArePresent","filteredLanguageIds","l","languagesInUseIds","v","size","every","createAddAllTitle","isInternationalizedArrayItemType","createAddLanguagePatches","config","addLanguageKeys","schemaTypeName","Error","itemBase","newItems","itemLanguage","languageIndex","findIndex","remainingLanguages","nextLanguageIndex","r","splice","createTranslateFieldActions","fieldActionProps","useFormValue","disabled","Boolean","hidden","some","onAction","useCallback","icon","AddMissingTranslationsFieldAction","internationalizedArrayFieldAction","defineDocumentFieldAction","useAction","isInternationalizedArrayField","translateFieldActions","TranslateIcon","renderAsButton","pascalCase","string","upperFirst","camelCase","createFieldName","addValue","schemaExample","Feedback","InternationalizedArray","members","documentReadOnly","member","kind","valueMember","filterField","filteredMembers","formValue","handleAddLanguages","isDeleting","languageKeysFromValue","languageKeys","split","_temp2","addedLanguages","hasAddedDefaultLanguages","l_1","language_0","languagesToAdd","language_1","language_2","l_2","timeout","setTimeout","clearTimeout","useEffect","updatedValue","acc","v_0","newIndex","l_3","handleRestoreOrder","t9","t10","v_1","l_4","allKeysAreLanguages","bb2","t11","t12","v_2","vIndex","language_3","languagesOutOfOrder","languagesAreValid","_temp3","t13","allLanguagesArePresent","t14","_temp4","addAllMissingLanguages","t15","addButtonsAreVisible","fieldHasMembers","t16","addAllTitle","t17","t18","member_0","t19","t20","language_4","l_0","_key","getLanguagesFieldOption","arrayName","objectName","defineField","components","level","input","validation","rule","custom","getClient","contextLanguages","languagesFieldOption","cachedLanguages","suspendCachedLanguages","languageIds","lang","nonLanguageKeys","message","paths","seenLanguages","duplicateValues","add","getToneFromValidation","validations","validationLevels","ChangeLanguageButton","parentValue","languageKeysInUse","event","currentTarget","handleKeyChange","toLocaleUpperCase","portal","RemoveButton","isDefault","unset","handleUnset","RemoveCircleIcon","InternationalizedInput","originalOnChange","inputProps","initPatch","fixedPatches","allPatches","wrappedOnChange","inlineProps","keyIsValid","renderInput","m","patch_0","patch","fixedPath","preview","subtitle","definePlugin","studio","layout","unstable_layout","unstable_fieldActions","prev","form","isObjectInputProps","types","array","object"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sanity-plugin-internationalized-array",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.5",
|
|
4
4
|
"description": "Store localized fields in an array to save on attributes",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -30,11 +30,10 @@
|
|
|
30
30
|
"@sanity/icons": "^3.7.4",
|
|
31
31
|
"@sanity/language-filter": "^4.0.6",
|
|
32
32
|
"@sanity/ui": "^3.1.13",
|
|
33
|
-
"fast-deep-equal": "^3.1.3",
|
|
34
33
|
"lodash-es": "^4.17.23"
|
|
35
34
|
},
|
|
36
35
|
"devDependencies": {
|
|
37
|
-
"@sanity/pkg-utils": "^10.4.
|
|
36
|
+
"@sanity/pkg-utils": "^10.4.7",
|
|
38
37
|
"@testing-library/jest-dom": "^6.9.1",
|
|
39
38
|
"@testing-library/react": "^16.3.2",
|
|
40
39
|
"@types/lodash-es": "^4.17.12",
|