sanity-plugin-internationalized-array 1.8.0 → 1.9.1
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/README.md +24 -9
- package/lib/index.d.ts +2 -2
- package/lib/index.esm.js +8 -6
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +8 -6
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/AddButtons.tsx +39 -0
- package/src/components/DocumentAddButtons.tsx +112 -0
- package/src/components/InternationalizedArray.tsx +19 -30
- package/src/components/InternationalizedArrayContext.tsx +17 -2
- package/src/fieldActions/index.ts +2 -2
- package/src/plugin.tsx +3 -3
- package/src/types.ts +2 -2
- package/src/utils/createAddLanguagePatches.ts +2 -1
- package/src/utils/createValueSchemaTypeName.ts +5 -0
- package/src/utils/flattenSchemaType.ts +59 -0
package/README.md
CHANGED
|
@@ -53,10 +53,14 @@ The above config will also create an empty array item in new documents for each
|
|
|
53
53
|
You can pass in more registered schema-type names to generate more internationalized arrays. Use them in your schema like this:
|
|
54
54
|
|
|
55
55
|
```ts
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
// For example, in postType.ts
|
|
57
|
+
|
|
58
|
+
fields: [
|
|
59
|
+
defineField({
|
|
60
|
+
name: 'greeting',
|
|
61
|
+
type: 'internationalizedArrayString',
|
|
62
|
+
}),
|
|
63
|
+
]
|
|
60
64
|
```
|
|
61
65
|
|
|
62
66
|
## Loading languages
|
|
@@ -107,7 +111,11 @@ languages: async (client, {market = ``}) => {
|
|
|
107
111
|
|
|
108
112
|
## Configuring the "Add translation" buttons
|
|
109
113
|
|
|
110
|
-
The "Add translation" buttons can be positioned
|
|
114
|
+
The "Add translation" buttons can be positioned in one or multiple locations by configuring `buttonLocations`:
|
|
115
|
+
|
|
116
|
+
- `field` (default) Below the internationalized array field
|
|
117
|
+
- `unstable__fieldAction` Inside a Field Action (currently unstable)
|
|
118
|
+
- `document` Above the document fields, these buttons will add a new language item to every internationalized array field that can be found at the **root of the document**. Nested internationalized arrays are not yet supported.
|
|
111
119
|
|
|
112
120
|
The "Add all languages" button can be hidden with `buttonAddAll`.
|
|
113
121
|
|
|
@@ -120,7 +128,7 @@ import {internationalizedArray} from 'sanity-plugin-internationalized-array'
|
|
|
120
128
|
plugins: [
|
|
121
129
|
internationalizedArray({
|
|
122
130
|
// ...other config
|
|
123
|
-
buttonLocations: ['field', 'unstable__fieldAction'] // default ['field']
|
|
131
|
+
buttonLocations: ['field', 'unstable__fieldAction', 'document'], // default ['field']
|
|
124
132
|
buttonAddAll: false // default true
|
|
125
133
|
})
|
|
126
134
|
]
|
|
@@ -225,6 +233,7 @@ Configure both plugins in your sanity.config.ts file:
|
|
|
225
233
|
```ts
|
|
226
234
|
// ./sanity.config.ts
|
|
227
235
|
|
|
236
|
+
import {defineConfig, isKeySegment} from 'sanity'
|
|
228
237
|
import {languageFilter} from '@sanity/language-filter'
|
|
229
238
|
|
|
230
239
|
export default defineConfig({
|
|
@@ -243,9 +252,15 @@ export default defineConfig({
|
|
|
243
252
|
enclosingType.name.startsWith('internationalizedArray') &&
|
|
244
253
|
'kind' in member
|
|
245
254
|
) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
255
|
+
// Get last two segments of the field's path
|
|
256
|
+
const pathEnd = member.field.path.slice(-2)
|
|
257
|
+
// If the second-last segment is a _key, and the last segment is `value`,
|
|
258
|
+
// It's an internationalized array value
|
|
259
|
+
// And the array _key is the language of the field
|
|
260
|
+
const language =
|
|
261
|
+
pathEnd[1] === 'value' && isKeySegment(pathEnd[0])
|
|
262
|
+
? pathEnd[0]._key
|
|
263
|
+
: null
|
|
249
264
|
|
|
250
265
|
return language ? selectedLanguageIds.includes(language) : false
|
|
251
266
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -126,12 +126,12 @@ export declare type PluginConfig = {
|
|
|
126
126
|
* Locations where the "+ EN" add language buttons are visible
|
|
127
127
|
* @defaultValue ['field']
|
|
128
128
|
* */
|
|
129
|
-
buttonLocations
|
|
129
|
+
buttonLocations?: ('field' | 'unstable__fieldAction' | 'document')[]
|
|
130
130
|
/**
|
|
131
131
|
* Show or hide the "Add missing languages" button
|
|
132
132
|
* @defaultValue true
|
|
133
133
|
* */
|
|
134
|
-
buttonAddAll
|
|
134
|
+
buttonAddAll?: boolean
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
export declare type Value = {
|
package/lib/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import*as suspend from'suspend-react';import{suspend as suspend$1}from'suspend-react';import{jsx,jsxs,Fragment}from'react/jsx-runtime';import{useClient,useFormBuilder,
|
|
1
|
+
import*as suspend from'suspend-react';import{suspend as suspend$1}from'suspend-react';import{jsx,jsxs,Fragment}from'react/jsx-runtime';import{isSanityDocument,setIfMissing,insert,PatchEvent,useClient,useFormBuilder,defineDocumentFieldAction,useFormValue,set,ArrayOfObjectsItem,defineField,unset,isDocumentSchemaType,isArraySchemaType,definePlugin,isObjectInputProps}from'sanity';import{useLanguageFilterStudioContext}from'@sanity/language-filter';import{Grid,Button,useToast,Stack,Box,Text,Card,Code,Spinner,Label,MenuButton,Menu,MenuItem,Flex}from'@sanity/ui';import equal from'fast-deep-equal';import{useMemo,useCallback,createContext,useContext,useDeferredValue,memo,useEffect}from'react';import{useDocumentPane}from'sanity/desk';import{AddIcon,TranslateIcon,RemoveCircleIcon}from'@sanity/icons';const namespace="sanity-plugin-internationalized-array";const version="v0";const preload=fn=>suspend.preload(()=>fn(),[version,namespace]);const clear=()=>suspend.clear([version,namespace]);const peek=selectedValue=>suspend.peek([version,namespace,selectedValue]);const MAX_COLUMNS=7;const CONFIG_DEFAULT={languages:[],select:{},defaultLanguages:[],fieldTypes:[],apiVersion:"2022-11-27",buttonLocations:["field"],buttonAddAll:true};function createValueSchemaTypeName(schemaType){return"".concat(schemaType.name,"Value");}function AddButtons(props){const{languages,readOnly,value,onClick}=props;return languages.length>0?/* @__PURE__ */jsx(Grid,{columns:Math.min(languages.length,MAX_COLUMNS),gap:2,children:languages.map(language=>/* @__PURE__ */jsx(Button,{tone:"primary",mode:"ghost",fontSize:1,disabled:readOnly||Boolean(value==null?void 0:value.find(item=>item._key===language.id)),text:language.id.toUpperCase(),icon:languages.length>MAX_COLUMNS?void 0:AddIcon,value:language.id,onClick},language.id))}):null;}function DocumentAddButtons(props){const{filteredLanguages}=useInternationalizedArrayContext();const{fields}=props.schemaType;const value=isSanityDocument(props.value)?props.value:void 0;const toast=useToast();const{onChange}=useDocumentPane();const internationalizedArrayFields=useMemo(()=>fields.filter(field=>field.type.name.startsWith("internationalizedArray")),[fields]);const handleDocumentButtonClick=useCallback(event=>{const languageId=event.currentTarget.value;if(!languageId){toast.push({status:"error",title:"No language selected"});return;}if(internationalizedArrayFields.length===0){toast.push({status:"error",title:"No internationalizedArray fields found in document root"});return;}const emptyLanguageFields=internationalizedArrayFields.filter(field=>{const fieldValue=value==null?void 0:value[field.name];const fieldValueLanguage=fieldValue&&Array.isArray(fieldValue)?fieldValue.find(v=>v._key===languageId):void 0;return!fieldValueLanguage;});const patches=emptyLanguageFields.map(field=>{const fieldKey=field.name;return[setIfMissing([],[fieldKey]),insert([{_key:languageId,_type:createValueSchemaTypeName(field.type)}],"after",[fieldKey,-1])];}).flat();onChange(PatchEvent.from(patches));},[internationalizedArrayFields,onChange,toast,value]);return/* @__PURE__ */jsxs(Stack,{space:3,children:[/* @__PURE__ */jsx(Box,{children:/* @__PURE__ */jsx(Text,{size:1,weight:"semibold",children:"Add translation to internationalized fields"})}),/* @__PURE__ */jsx(AddButtons,{languages:filteredLanguages,readOnly:false,value:void 0,onClick:handleDocumentButtonClick})]});}var commonjsGlobal=typeof globalThis!=='undefined'?globalThis:typeof window!=='undefined'?window:typeof global!=='undefined'?global:typeof self!=='undefined'?self:{};var lodash={exports:{}};/**
|
|
2
2
|
* @license
|
|
3
3
|
* Lodash <https://lodash.com/>
|
|
4
4
|
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
|
@@ -9468,18 +9468,18 @@ if(freeModule){// Export for Node.js.
|
|
|
9468
9468
|
(freeModule.exports=_)._=_;// Export for CommonJS support.
|
|
9469
9469
|
freeExports._=_;}else{// Export to the global object.
|
|
9470
9470
|
root._=_;}}).call(commonjsGlobal);})(lodash,lodash.exports);var lodashExports=lodash.exports;const getSelectedValue=(select,document)=>{if(!select||!document){return{};}const selection=select||{};const selectedValue={};for(const[key,path]of Object.entries(selection)){let value=lodashExports.get(document,path);if(Array.isArray(value)){value=value.filter(item=>typeof item==="object"?(item==null?void 0:item._type)==="reference"&&"_ref"in item:true);}selectedValue[key]=value;}return selectedValue;};const InternationalizedArrayContext=createContext({...CONFIG_DEFAULT,languages:[],filteredLanguages:[]});function useInternationalizedArrayContext(){return useContext(InternationalizedArrayContext);}function InternationalizedArrayProvider(props){const{internationalizedArray}=props;const client=useClient({apiVersion:internationalizedArray.apiVersion});const{value:document}=useFormBuilder();const deferredDocument=useDeferredValue(document);const selectedValue=useMemo(()=>getSelectedValue(internationalizedArray.select,deferredDocument),[internationalizedArray.select,deferredDocument]);const languages=Array.isArray(internationalizedArray.languages)?internationalizedArray.languages:suspend$1(// eslint-disable-next-line require-await
|
|
9471
|
-
async()=>{if(typeof internationalizedArray.languages==="function"){return internationalizedArray.languages(client,selectedValue);}return internationalizedArray.languages;},[version,namespace],{equal});const{selectedLanguageIds,options:languageFilterOptions}=useLanguageFilterStudioContext();const filteredLanguages=useMemo(()=>{const documentType=deferredDocument?deferredDocument._type:void 0;const languageFilterEnabled=typeof documentType==="string"&&languageFilterOptions.documentTypes.includes(documentType);return languageFilterEnabled?languages.filter(language=>selectedLanguageIds.includes(language.id)):languages;},[deferredDocument,languageFilterOptions,languages,selectedLanguageIds]);return/* @__PURE__ */jsx(InternationalizedArrayContext.Provider,{value:{...internationalizedArray,languages,filteredLanguages},children:props.renderDefault(props)});}var Preload=memo(function Preload(props){const client=useClient({apiVersion:props.apiVersion});if(!Array.isArray(peek({}))){preload(async()=>Array.isArray(props.languages)?props.languages:props.languages(client,{}));}return null;});function checkAllLanguagesArePresent(languages,value){const filteredLanguageIds=languages.map(l=>l.id);const languagesInUseIds=value?value.map(v=>v._key):[];return languagesInUseIds.length===filteredLanguageIds.length&&languagesInUseIds.every(l=>filteredLanguageIds.includes(l));}function createAddAllTitle(value,languages){if(value==null?void 0:value.length){return"Add missing ".concat(languages.length-value.length===1?"language":"languages");}return languages.length===1?"Add ".concat(languages[0].title," Field"):"Add all languages";}function createAddLanguagePatches(config){const{addLanguageKeys,schemaType,languages,filteredLanguages,value,path=[]}=config;const itemBase={_type:
|
|
9471
|
+
async()=>{if(typeof internationalizedArray.languages==="function"){return internationalizedArray.languages(client,selectedValue);}return internationalizedArray.languages;},[version,namespace,selectedValue],{equal});const{selectedLanguageIds,options:languageFilterOptions}=useLanguageFilterStudioContext();const filteredLanguages=useMemo(()=>{const documentType=deferredDocument?deferredDocument._type:void 0;const languageFilterEnabled=typeof documentType==="string"&&languageFilterOptions.documentTypes.includes(documentType);return languageFilterEnabled?languages.filter(language=>selectedLanguageIds.includes(language.id)):languages;},[deferredDocument,languageFilterOptions,languages,selectedLanguageIds]);const showDocumentButtons=internationalizedArray.buttonLocations.includes("document");return/* @__PURE__ */jsx(InternationalizedArrayContext.Provider,{value:{...internationalizedArray,languages,filteredLanguages},children:showDocumentButtons?/* @__PURE__ */jsxs(Stack,{space:5,children:[/* @__PURE__ */jsx(DocumentAddButtons,{schemaType:props.schemaType,value:props.value}),props.renderDefault(props)]}):props.renderDefault(props)});}var Preload=memo(function Preload(props){const client=useClient({apiVersion:props.apiVersion});if(!Array.isArray(peek({}))){preload(async()=>Array.isArray(props.languages)?props.languages:props.languages(client,{}));}return null;});function checkAllLanguagesArePresent(languages,value){const filteredLanguageIds=languages.map(l=>l.id);const languagesInUseIds=value?value.map(v=>v._key):[];return languagesInUseIds.length===filteredLanguageIds.length&&languagesInUseIds.every(l=>filteredLanguageIds.includes(l));}function createAddAllTitle(value,languages){if(value==null?void 0:value.length){return"Add missing ".concat(languages.length-value.length===1?"language":"languages");}return languages.length===1?"Add ".concat(languages[0].title," Field"):"Add all languages";}function createAddLanguagePatches(config){const{addLanguageKeys,schemaType,languages,filteredLanguages,value,path=[]}=config;const itemBase={_type:createValueSchemaTypeName(schemaType)};const newItems=Array.isArray(addLanguageKeys)&&addLanguageKeys.length>0?// Just one for this language
|
|
9472
9472
|
addLanguageKeys.map(id=>({...itemBase,_key:id})):// Or one for every missing language
|
|
9473
9473
|
filteredLanguages.filter(language=>(value==null?void 0:value.length)?!value.find(v=>v._key===language.id):true).map(language=>({...itemBase,_key:language.id}));const languagesInUse=(value==null?void 0:value.length)?value.map(v=>v):[];const insertions=newItems.map(item=>{const languageIndex=languages.findIndex(l=>item._key===l.id);const remainingLanguages=languages.slice(languageIndex+1);const nextLanguageIndex=languagesInUse.findIndex(l=>// eslint-disable-next-line max-nested-callbacks
|
|
9474
9474
|
remainingLanguages.find(r=>r.id===l._key));if(nextLanguageIndex<0){languagesInUse.push(item);}else{languagesInUse.splice(nextLanguageIndex,0,item);}return nextLanguageIndex<0?// No next language (-1), add to end of array
|
|
9475
9475
|
insert([item],"after",[...path,nextLanguageIndex]):// Next language found, insert before that
|
|
9476
|
-
insert([item],"before",[...path,nextLanguageIndex]);});return insertions;}const createTranslateFieldActions=(fieldActionProps,_ref)=>{let{languages,filteredLanguages}=_ref;return languages.map(language=>{const value=useFormValue(fieldActionProps.path);const disabled=value&&Array.isArray(value)?Boolean(value==null?void 0:value.find(item=>item._key===language.id)):
|
|
9476
|
+
insert([item],"before",[...path,nextLanguageIndex]);});return insertions;}const createTranslateFieldActions=(fieldActionProps,_ref)=>{let{languages,filteredLanguages}=_ref;return languages.map(language=>{const value=useFormValue(fieldActionProps.path);const disabled=value&&Array.isArray(value)?Boolean(value==null?void 0:value.find(item=>item._key===language.id)):false;const hidden=!filteredLanguages.some(f=>f.id===language.id);const{onChange}=useDocumentPane();const onAction=useCallback(()=>{const{schemaType,path}=fieldActionProps;const addLanguageKeys=[language.id];const patches=createAddLanguagePatches({addLanguageKeys,schemaType,languages,filteredLanguages,value,path});onChange(PatchEvent.from([setIfMissing([],path),...patches]));},[language.id,value,onChange]);return{type:"action",icon:AddIcon,onAction,title:language.id.toLocaleUpperCase(),hidden,disabled};});};const AddMissingTranslationsFieldAction=(fieldActionProps,_ref2)=>{let{languages,filteredLanguages}=_ref2;const value=useFormValue(fieldActionProps.path);const disabled=value&&value.length===filteredLanguages.length;const hidden=checkAllLanguagesArePresent(filteredLanguages,value);const{onChange}=useDocumentPane();const onAction=useCallback(()=>{const{schemaType,path}=fieldActionProps;const addLanguageKeys=[];const patches=createAddLanguagePatches({addLanguageKeys,schemaType,languages,filteredLanguages,value,path});onChange(PatchEvent.from([setIfMissing([],path),...patches]));},[fieldActionProps,filteredLanguages,languages,onChange,value]);return{type:"action",icon:AddIcon,onAction,title:createAddAllTitle(value,filteredLanguages),disabled,hidden};};const internationalizedArrayFieldAction=defineDocumentFieldAction({name:"internationalizedArray",useAction(fieldActionProps){var _a,_b;const isInternationalizedArrayField=(_b=(_a=fieldActionProps==null?void 0:fieldActionProps.schemaType)==null?void 0:_a.type)==null?void 0:_b.name.startsWith("internationalizedArray");const{languages,filteredLanguages}=useInternationalizedArrayContext();const translateFieldActions=createTranslateFieldActions(fieldActionProps,{languages,filteredLanguages});return{type:"group",icon:TranslateIcon,title:"Add Translation",renderAsButton:true,children:isInternationalizedArrayField?[...translateFieldActions,AddMissingTranslationsFieldAction(fieldActionProps,{languages,filteredLanguages})]:[],hidden:!isInternationalizedArrayField};}});function camelCase(string){return string.replace(/-([a-z])/g,g=>g[1].toUpperCase());}function titleCase(string){return string.split(" ").map(word=>word.charAt(0).toUpperCase()+word.slice(1)).join(" ");}function pascalCase(string){return titleCase(camelCase(string));}function createFieldName(name){let addValue=arguments.length>1&&arguments[1]!==undefined?arguments[1]:false;return addValue?["internationalizedArray",pascalCase(name),"Value"].join(""):["internationalizedArray",pascalCase(name)].join("");}const schemaExample={languages:[{id:"en",title:"English"},{id:"no",title:"Norsk"}]};function Feedback(){return/* @__PURE__ */jsx(Card,{tone:"caution",border:true,radius:2,padding:3,children:/* @__PURE__ */jsxs(Stack,{space:4,children:[/* @__PURE__ */jsxs(Text,{children:["An array of language objects must be passed into the"," ",/* @__PURE__ */jsx("code",{children:"internationalizedArray"})," helper function, each with an"," ",/* @__PURE__ */jsx("code",{children:"id"})," and ",/* @__PURE__ */jsx("code",{children:"title"})," field. Example:"]}),/* @__PURE__ */jsx(Card,{padding:2,border:true,radius:2,children:/* @__PURE__ */jsx(Code,{size:1,language:"javascript",children:JSON.stringify(schemaExample,null,2)})})]})});}function InternationalizedArray(props){const{members,value,schemaType,onChange}=props;const readOnly=typeof schemaType.readOnly==="boolean"?schemaType.readOnly:false;const toast=useToast();const{languages,filteredLanguages,defaultLanguages,buttonAddAll,buttonLocations}=useInternationalizedArrayContext();const{selectedLanguageIds,options:languageFilterOptions}=useLanguageFilterStudioContext();const documentType=useFormValue(["_type"]);const languageFilterEnabled=typeof documentType==="string"&&languageFilterOptions.documentTypes.includes(documentType);const filteredMembers=useMemo(()=>languageFilterEnabled?members.filter(member=>{if(member.kind!=="item"){return false;}const valueMember=member.item.members[0];if(valueMember.kind!=="field"){return false;}return languageFilterOptions.filterField(member.item.schemaType,valueMember,selectedLanguageIds);}):members,[languageFilterEnabled,members,languageFilterOptions,selectedLanguageIds]);const handleAddLanguage=useCallback(param=>{var _a;if(!(filteredLanguages==null?void 0:filteredLanguages.length)){return;}const addLanguageKeys=Array.isArray(param)?param:[(_a=param==null?void 0:param.currentTarget)==null?void 0:_a.value].filter(Boolean);const patches=createAddLanguagePatches({addLanguageKeys,schemaType,languages,filteredLanguages,value});onChange([setIfMissing([]),...patches]);},[filteredLanguages,languages,onChange,schemaType,value]);const documentCreatedAt=useFormValue(["_createdAt"]);if(// Array field is empty
|
|
9477
9477
|
!value&&// Document form is in "not yet created" state
|
|
9478
9478
|
!documentCreatedAt&&// Plugin config included default languages
|
|
9479
9479
|
defaultLanguages&&(defaultLanguages==null?void 0:defaultLanguages.length)>0){handleAddLanguage(defaultLanguages);}const handleRestoreOrder=useCallback(()=>{if(!(value==null?void 0:value.length)||!(languages==null?void 0:languages.length)){return;}const updatedValue=value.reduce((acc,v)=>{const newIndex=languages.findIndex(l=>l.id===(v==null?void 0:v._key));if(newIndex>-1){acc[newIndex]=v;}return acc;},[]).filter(Boolean);if((value==null?void 0:value.length)!==updatedValue.length){toast.push({title:"There was an error reordering languages",status:"warning"});}onChange(set(updatedValue));},[toast,languages,onChange,value]);const allKeysAreLanguages=useMemo(()=>{if(!(value==null?void 0:value.length)||!(languages==null?void 0:languages.length)){return true;}return value==null?void 0:value.every(v=>languages.find(l=>(l==null?void 0:l.id)===(v==null?void 0:v._key)));},[value,languages]);const languagesInUse=useMemo(()=>languages&&languages.length>1?languages.filter(l=>value==null?void 0:value.find(v=>v._key===l.id)):[],[languages,value]);const languagesOutOfOrder=useMemo(()=>{if(!(value==null?void 0:value.length)||!languagesInUse.length){return[];}return value.map((v,vIndex)=>vIndex===languagesInUse.findIndex(l=>l.id===v._key)?null:v).filter(Boolean);},[value,languagesInUse]);const languagesAreValid=useMemo(()=>!(languages==null?void 0:languages.length)||(languages==null?void 0:languages.length)&&languages.every(item=>item.id&&item.title),[languages]);useEffect(()=>{if(languagesOutOfOrder.length>0&&allKeysAreLanguages){handleRestoreOrder();}},[languagesOutOfOrder,allKeysAreLanguages,handleRestoreOrder]);const allLanguagesArePresent=useMemo(()=>checkAllLanguagesArePresent(filteredLanguages,value),[filteredLanguages,value]);if(!languagesAreValid){return/* @__PURE__ */jsx(Feedback,{});}const addButtonsAreVisible=// Plugin was configured to display buttons here (default!)
|
|
9480
9480
|
buttonLocations.includes("field")&&// There's at least one language visible
|
|
9481
9481
|
(filteredLanguages==null?void 0:filteredLanguages.length)>0&&// Not every language has a value yet
|
|
9482
|
-
!allLanguagesArePresent;return/* @__PURE__ */jsxs(Stack,{space:2,children:[
|
|
9482
|
+
!allLanguagesArePresent;const fieldHasMembers=(members==null?void 0:members.length)>0;return/* @__PURE__ */jsxs(Stack,{space:2,children:[fieldHasMembers?/* @__PURE__ */jsx(Fragment,{children:filteredMembers.map(member=>{if(member.kind==="item"){return/* @__PURE__ */jsx(ArrayOfObjectsItem,{member,renderItem:props.renderItem,renderField:props.renderField,renderInput:props.renderInput,renderPreview:props.renderPreview},member.key);}return null;})}):null,!addButtonsAreVisible&&!fieldHasMembers?/* @__PURE__ */jsx(Card,{border:true,tone:"transparent",padding:3,radius:2,children:/* @__PURE__ */jsx(Text,{size:1,children:"This internationalized field currently has no translations."})}):null,addButtonsAreVisible?/* @__PURE__ */jsxs(Stack,{space:2,children:[/* @__PURE__ */jsx(AddButtons,{languages:filteredLanguages,value,readOnly,onClick:handleAddLanguage}),buttonAddAll?/* @__PURE__ */jsx(Button,{tone:"primary",mode:"ghost",disabled:readOnly||allLanguagesArePresent,icon:AddIcon,text:createAddAllTitle(value,filteredLanguages),onClick:handleAddLanguage}):null]}):null]});}var array=config=>{const{apiVersion,select,languages,type}=config;const typeName=typeof type==="string"?type:type.name;const arrayName=createFieldName(typeName);const objectName=createFieldName(typeName,true);return defineField({name:arrayName,title:"Internationalized array",type:"array",components:{input:InternationalizedArray},// These options are required for validation rules – not the custom input component
|
|
9483
9483
|
options:{apiVersion,select,languages},// TODO: Resolve this typing issue with the inner object
|
|
9484
9484
|
// @ts-expect-error
|
|
9485
9485
|
of:[defineField({...(typeof type==="string"?{}:type),name:objectName,type:objectName})],validation:rule=>rule.custom(async(value,context)=>{var _a,_b,_c;if(!value){return true;}const selectedValue=getSelectedValue(select,context.document);const client=context.getClient({apiVersion});const contextLanguages=Array.isArray((_b=(_a=context==null?void 0:context.type)==null?void 0:_a.options)==null?void 0:_b.languages)?context.type.options.languages:Array.isArray(peek(selectedValue))?peek(selectedValue):await((_c=context==null?void 0:context.type)==null?void 0:_c.options.languages(client,selectedValue));if(value&&value.length>contextLanguages.length){return"Cannot be more than ".concat(contextLanguages.length===1?"1 item":"".concat(contextLanguages.length," items"));}const nonLanguageKeys=(value==null?void 0:value.length)?value.filter(item=>!contextLanguages.find(language=>item._key===language.id)):[];if(nonLanguageKeys.length){return{message:"Array item keys must be valid languages registered to the field type",paths:nonLanguageKeys.map(item=>[{_key:item._key}])};}const valuesByLanguage=(value==null?void 0:value.length)?value.filter(item=>Boolean(item==null?void 0:item._key)).reduce((acc,cur)=>{if(acc[cur._key]){return{...acc,[cur._key]:[...acc[cur._key],cur]};}return{...acc,[cur._key]:[cur]};},{}):{};const duplicateValues=Object.values(valuesByLanguage).filter(item=>(item==null?void 0:item.length)>1).flat();if(duplicateValues.length){return{message:"There can only be one field per language",paths:duplicateValues.map(item=>[{_key:item._key}])};}return true;})});};function InternationalizedField(props){if(props.schemaType.name==="reference"&&props.value){return props.renderDefault({...props,title:"",level:0});}return props.children;}function getToneFromValidation(validations){if(!(validations==null?void 0:validations.length)){return void 0;}const validationLevels=validations.map(v=>v.level);if(validationLevels.includes("error")){return"critical";}else if(validationLevels.includes("warning")){return"caution";}return void 0;}function InternationalizedInput(props){const parentValue=useFormValue(props.path.slice(0,-1));const inlineProps={...props.inputProps,// This is the magic that makes inline editing work?
|
|
@@ -9491,9 +9491,11 @@ fields:[typeof type==="string"?// Define a simple field if all we have is the na
|
|
|
9491
9491
|
defineField({name:"value",type,components:{// TODO: Address this typing issue with the inner object
|
|
9492
9492
|
// @ts-expect-error
|
|
9493
9493
|
field:InternationalizedField}}):// Pass in the configured options, but overwrite the name
|
|
9494
|
-
{...type,name:"value",components:{field:InternationalizedField}}],preview:{select:{title:"value",subtitle:"_key"}}});};
|
|
9494
|
+
{...type,name:"value",components:{field:InternationalizedField}}],preview:{select:{title:"value",subtitle:"_key"}}});};function flattenSchemaType(schemaType){if(!isDocumentSchemaType(schemaType)){console.error("Schema type is not a document");return[];}return extractInnerFields(schemaType.fields,[],3);}function extractInnerFields(fields,path,maxDepth){if(path.length>=maxDepth){return[];}return fields.reduce((acc,field)=>{const thisFieldWithPath={path:[...path,field.name],...field};if(field.type.jsonType==="object"){const innerFields=extractInnerFields(field.type.fields,[...path,field.name],maxDepth);return[...acc,thisFieldWithPath,...innerFields];}else if(field.type.jsonType==="array"&&isArraySchemaType(field)){const innerFields=extractInnerFields(// TODO: Fix TS assertion for array fields
|
|
9495
|
+
// @ts-expect-error
|
|
9496
|
+
field.type.of,[...path,field.name],maxDepth);return[...acc,thisFieldWithPath,...innerFields];}return[...acc,thisFieldWithPath];},[]);}const internationalizedArray=definePlugin(config=>{const pluginConfig={...CONFIG_DEFAULT,...config};const{apiVersion="2022-11-27",select,languages,fieldTypes,defaultLanguages,buttonLocations}=pluginConfig;return{name:"sanity-plugin-internationalized-array",// Preload languages for use throughout the Studio
|
|
9495
9497
|
studio:Array.isArray(languages)?void 0:{components:{layout:props=>/* @__PURE__ */jsxs(Fragment,{children:[/* @__PURE__ */jsx(Preload,{apiVersion,languages}),props.renderDefault(props)]})}},// Optional: render "add language" buttons as field actions
|
|
9496
9498
|
document:{unstable_fieldActions:buttonLocations.includes("unstable__fieldAction")?prev=>[...prev,internationalizedArrayFieldAction]:void 0},// Wrap document editor with a language provider
|
|
9497
|
-
form:{components:{input:props=>{const isRootInput=props.id==="root"&&isObjectInputProps(props);if(!isRootInput){return props.renderDefault(props);}const
|
|
9499
|
+
form:{components:{input:props=>{const isRootInput=props.id==="root"&&isObjectInputProps(props);if(!isRootInput){return props.renderDefault(props);}const flatFieldTypeNames=flattenSchemaType(props.schemaType).map(field=>field.type.name);const hasInternationalizedArray=flatFieldTypeNames.some(name=>name.startsWith("internationalizedArray"));if(!hasInternationalizedArray){return props.renderDefault(props);}return InternationalizedArrayProvider({...props,internationalizedArray:pluginConfig});}}},// Register custom schema types for the outer array and the inner object
|
|
9498
9500
|
schema:{types:[...fieldTypes.map(type=>array({type,apiVersion,select,languages,defaultLanguages})),...fieldTypes.map(type=>object({type}))]}};});export{clear,internationalizedArray};
|
|
9499
9501
|
//# sourceMappingURL=index.esm.js.map
|