sanity-plugin-internationalized-array 3.2.1 → 4.0.0

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.
Files changed (43) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -34
  3. package/{lib → dist}/index.d.ts +41 -61
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +882 -0
  6. package/dist/index.js.map +1 -0
  7. package/package.json +37 -75
  8. package/lib/index.d.mts +0 -149
  9. package/lib/index.esm.js +0 -933
  10. package/lib/index.esm.js.map +0 -1
  11. package/lib/index.js +0 -942
  12. package/lib/index.js.map +0 -1
  13. package/lib/index.mjs +0 -933
  14. package/lib/index.mjs.map +0 -1
  15. package/sanity.json +0 -8
  16. package/src/cache.ts +0 -148
  17. package/src/components/AddButtons.tsx +0 -60
  18. package/src/components/DocumentAddButtons.tsx +0 -183
  19. package/src/components/Feedback.tsx +0 -28
  20. package/src/components/InternationalizedArray.tsx +0 -286
  21. package/src/components/InternationalizedArrayContext.tsx +0 -136
  22. package/src/components/InternationalizedField.tsx +0 -57
  23. package/src/components/InternationalizedInput.tsx +0 -257
  24. package/src/components/Preload.tsx +0 -31
  25. package/src/components/createFieldName.ts +0 -20
  26. package/src/components/getSelectedValue.ts +0 -31
  27. package/src/components/getToneFromValidation.ts +0 -20
  28. package/src/constants.ts +0 -18
  29. package/src/fieldActions/index.ts +0 -138
  30. package/src/index.ts +0 -3
  31. package/src/plugin.tsx +0 -87
  32. package/src/schema/array.ts +0 -148
  33. package/src/schema/object.ts +0 -36
  34. package/src/types.ts +0 -135
  35. package/src/utils/checkAllLanguagesArePresent.ts +0 -14
  36. package/src/utils/createAddAllTitle.ts +0 -16
  37. package/src/utils/createAddLanguagePatches.ts +0 -84
  38. package/src/utils/createValueSchemaTypeName.ts +0 -5
  39. package/src/utils/flattenSchemaType.ts +0 -63
  40. package/src/utils/getDocumentsToTranslate.ts +0 -66
  41. package/src/utils/getLanguageDisplay.ts +0 -13
  42. package/src/utils/getLanguagesFieldOption.ts +0 -16
  43. package/v2-incompatible.js +0 -11
package/lib/index.esm.js DELETED
@@ -1,933 +0,0 @@
1
- import * as suspend from "suspend-react";
2
- import { suspend as suspend$1 } from "suspend-react";
3
- import { jsx, jsxs, Fragment } from "react/jsx-runtime";
4
- import { isSanityDocument, useSchema, setIfMissing, insert, PatchEvent, useClient, useWorkspace, defineDocumentFieldAction, useFormValue, set, ArrayOfObjectsItem, MemberItemError, defineField, unset, isDocumentSchemaType, definePlugin, isObjectInputProps } from "sanity";
5
- import { useLanguageFilterStudioContext } from "@sanity/language-filter";
6
- import { Grid, Button, useToast, Stack, Box, Text, Card, Code, Spinner, Label, MenuButton, Menu, MenuItem, Flex, Tooltip } from "@sanity/ui";
7
- import equal from "fast-deep-equal";
8
- import { memo, useCallback, createContext, useContext, useDeferredValue, useMemo, useEffect, createElement } from "react";
9
- import { useDocumentPane } from "sanity/structure";
10
- import { AddIcon, TranslateIcon, RemoveCircleIcon } from "@sanity/icons";
11
- import get from "lodash/get.js";
12
- const namespace = "sanity-plugin-internationalized-array", version = "v1", functionCache = /* @__PURE__ */ new Map(), functionKeyCache = /* @__PURE__ */ new WeakMap(), preloadWithKey = (fn, key) => suspend.preload(() => fn(), key), clear = () => suspend.clear([version, namespace]), peek = (selectedValue) => suspend.peek([version, namespace, selectedValue]), createCacheKey = (selectedValue, workspaceId) => {
13
- const selectedValueHash = JSON.stringify(selectedValue);
14
- return workspaceId ? [version, namespace, selectedValueHash, workspaceId] : [version, namespace, selectedValueHash];
15
- }, getFunctionKey = (fn) => {
16
- const cachedKey = functionKeyCache.get(fn);
17
- if (cachedKey)
18
- return cachedKey;
19
- const fnStr = fn.toString();
20
- let hash = 0;
21
- const maxLength = Math.min(fnStr.length, 100);
22
- for (let i = 0; i < maxLength; i++) {
23
- const char = fnStr.charCodeAt(i);
24
- hash = (hash << 5) - hash + char, hash &= hash;
25
- }
26
- const key = `anonymous_${Math.abs(hash)}`;
27
- return functionKeyCache.set(fn, key), key;
28
- }, createFunctionCacheKey = (fn, selectedValue, workspaceId) => {
29
- const functionKey = getFunctionKey(fn), selectedValueHash = JSON.stringify(selectedValue);
30
- return workspaceId ? `${functionKey}:${selectedValueHash}:${workspaceId}` : `${functionKey}:${selectedValueHash}`;
31
- }, getFunctionCache = (fn, selectedValue, workspaceId) => {
32
- const key = createFunctionCacheKey(fn, selectedValue, workspaceId);
33
- return functionCache.get(key);
34
- }, setFunctionCache = (fn, selectedValue, languages, workspaceId) => {
35
- const key = createFunctionCacheKey(fn, selectedValue, workspaceId);
36
- functionCache.set(key, languages);
37
- }, MAX_COLUMNS = {
38
- codeOnly: 5,
39
- titleOnly: 4,
40
- titleAndCode: 3
41
- }, CONFIG_DEFAULT = {
42
- languages: [],
43
- select: {},
44
- defaultLanguages: [],
45
- fieldTypes: [],
46
- apiVersion: "2025-10-15",
47
- buttonLocations: ["field"],
48
- buttonAddAll: !0,
49
- languageDisplay: "codeOnly"
50
- };
51
- var __defProp$9 = Object.defineProperty, __defProps$8 = Object.defineProperties, __getOwnPropDescs$8 = Object.getOwnPropertyDescriptors, __getOwnPropSymbols$9 = Object.getOwnPropertySymbols, __hasOwnProp$9 = Object.prototype.hasOwnProperty, __propIsEnum$9 = Object.prototype.propertyIsEnumerable, __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues$9 = (a, b) => {
52
- for (var prop in b || (b = {}))
53
- __hasOwnProp$9.call(b, prop) && __defNormalProp$9(a, prop, b[prop]);
54
- if (__getOwnPropSymbols$9)
55
- for (var prop of __getOwnPropSymbols$9(b))
56
- __propIsEnum$9.call(b, prop) && __defNormalProp$9(a, prop, b[prop]);
57
- return a;
58
- }, __spreadProps$8 = (a, b) => __defProps$8(a, __getOwnPropDescs$8(b));
59
- const getDocumentsToTranslate = (value, rootPath = []) => {
60
- if (Array.isArray(value)) {
61
- const arrayRootPath = [...rootPath], internationalizedValues = value.filter((item) => {
62
- if (Array.isArray(item)) return !1;
63
- if (typeof item == "object") {
64
- const type = item == null ? void 0 : item._type;
65
- return (type == null ? void 0 : type.startsWith("internationalizedArray")) && (type == null ? void 0 : type.endsWith("Value"));
66
- }
67
- return !1;
68
- });
69
- return internationalizedValues.length > 0 ? internationalizedValues.map((internationalizedValue) => __spreadProps$8(__spreadValues$9({}, internationalizedValue), {
70
- path: arrayRootPath,
71
- pathString: arrayRootPath.join(".")
72
- })) : value.length > 0 ? value.map(
73
- (item, index) => getDocumentsToTranslate(item, [...arrayRootPath, index])
74
- ).flat() : [];
75
- }
76
- if (typeof value == "object" && value) {
77
- const startsWithUnderscoreRegex = /^_/;
78
- return Object.keys(value).filter(
79
- (key) => !key.match(startsWithUnderscoreRegex)
80
- ).map((item) => {
81
- const selectedValue = value[item], path = [...rootPath, item];
82
- return getDocumentsToTranslate(selectedValue, path);
83
- }).flat();
84
- }
85
- return [];
86
- };
87
- function getLanguageDisplay(languageDisplay, title, code) {
88
- return languageDisplay === "codeOnly" ? code.toUpperCase() : languageDisplay === "titleOnly" ? title : languageDisplay === "titleAndCode" ? `${title} (${code.toUpperCase()})` : title;
89
- }
90
- function AddButtons(props) {
91
- const { languages, readOnly, value, onClick } = props, { languageDisplay } = useInternationalizedArrayContext();
92
- return languages.length > 0 ? /* @__PURE__ */ jsx(
93
- Grid,
94
- {
95
- columns: Math.min(languages.length, MAX_COLUMNS[languageDisplay]),
96
- gap: 2,
97
- children: languages.map((language) => {
98
- const languageTitle = getLanguageDisplay(
99
- languageDisplay,
100
- language.title,
101
- language.id
102
- );
103
- return /* @__PURE__ */ jsx(
104
- Button,
105
- {
106
- tone: "primary",
107
- mode: "ghost",
108
- fontSize: 1,
109
- disabled: readOnly || !!(value != null && value.find((item) => item._key === language.id)),
110
- text: languageTitle,
111
- icon: languages.length > MAX_COLUMNS[languageDisplay] && languageDisplay === "codeOnly" ? void 0 : AddIcon,
112
- value: language.id,
113
- onClick
114
- },
115
- language.id
116
- );
117
- })
118
- }
119
- ) : null;
120
- }
121
- var AddButtons$1 = memo(AddButtons);
122
- function DocumentAddButtons(props) {
123
- const { filteredLanguages } = useInternationalizedArrayContext(), value = isSanityDocument(props.value) ? props.value : void 0, toast = useToast(), { onChange } = useDocumentPane(), schema = useSchema(), documentsToTranslation = getDocumentsToTranslate(value, []), getInitialValueForType = useCallback(
124
- (typeName) => {
125
- var _a;
126
- if (!typeName) return;
127
- const match = typeName.match(/^internationalizedArray(.+)Value$/);
128
- if (!match) return;
129
- const baseTypeName = match[1].charAt(0).toLowerCase() + match[1].slice(1), arrayBasedTypes = [
130
- "body",
131
- "htmlContent",
132
- "blockContent",
133
- "portableText"
134
- ];
135
- if (arrayBasedTypes.includes(baseTypeName))
136
- return [];
137
- try {
138
- const schemaType = schema.get(typeName);
139
- if (schemaType) {
140
- const valueField = (_a = schemaType == null ? void 0 : schemaType.fields) == null ? void 0 : _a.find(
141
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
142
- (f) => f.name === "value"
143
- );
144
- if (valueField) {
145
- const fieldType = valueField.type;
146
- if ((fieldType == null ? void 0 : fieldType.jsonType) === "array" || (fieldType == null ? void 0 : fieldType.name) === "array" || (fieldType == null ? void 0 : fieldType.type) === "array" || (fieldType == null ? void 0 : fieldType.of) !== void 0 || arrayBasedTypes.includes(fieldType == null ? void 0 : fieldType.name))
147
- return [];
148
- }
149
- }
150
- } catch (error) {
151
- console.warn(
152
- "Could not determine field type from schema:",
153
- typeName,
154
- error
155
- );
156
- }
157
- },
158
- [schema]
159
- ), handleDocumentButtonClick = useCallback(
160
- async (event) => {
161
- const languageId = event.currentTarget.value;
162
- if (!languageId) {
163
- toast.push({
164
- status: "error",
165
- title: "No language selected"
166
- });
167
- return;
168
- }
169
- const alreadyTranslated = documentsToTranslation.filter(
170
- (translation) => (translation == null ? void 0 : translation._key) === languageId
171
- ), removeDuplicates = documentsToTranslation.reduce((filteredTranslations, translation) => alreadyTranslated.filter(
172
- (alreadyTranslation) => alreadyTranslation.pathString === translation.pathString
173
- ).length > 0 || filteredTranslations.filter(
174
- (filteredTranslation) => filteredTranslation.path === translation.path
175
- ).length > 0 ? filteredTranslations : [...filteredTranslations, translation], []);
176
- if (removeDuplicates.length === 0) {
177
- toast.push({
178
- status: "error",
179
- title: "No internationalizedArray fields found in document root"
180
- });
181
- return;
182
- }
183
- const patches = [];
184
- for (const toTranslate of removeDuplicates) {
185
- const path = toTranslate.path, initialValue = getInitialValueForType(toTranslate._type), ifMissing = setIfMissing([], path), insertValue = insert(
186
- [
187
- {
188
- _key: languageId,
189
- _type: toTranslate._type,
190
- value: initialValue
191
- // Use the determined initial value instead of undefined
192
- }
193
- ],
194
- "after",
195
- [...path, -1]
196
- );
197
- patches.push(ifMissing), patches.push(insertValue);
198
- }
199
- onChange(PatchEvent.from(patches.flat()));
200
- },
201
- [documentsToTranslation, getInitialValueForType, onChange, toast]
202
- );
203
- return /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
204
- /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { size: 1, weight: "semibold", children: "Add translation to internationalized fields" }) }),
205
- /* @__PURE__ */ jsx(
206
- AddButtons$1,
207
- {
208
- languages: filteredLanguages,
209
- readOnly: !1,
210
- value: void 0,
211
- onClick: handleDocumentButtonClick
212
- }
213
- )
214
- ] });
215
- }
216
- const getSelectedValue = (select, document) => {
217
- if (!select || !document)
218
- return {};
219
- const selection = select || {}, selectedValue = {};
220
- for (const [key, path] of Object.entries(selection)) {
221
- let value = get(document, path);
222
- Array.isArray(value) && (value = value.filter(
223
- (item) => typeof item == "object" ? (item == null ? void 0 : item._type) === "reference" && "_ref" in item : !0
224
- )), selectedValue[key] = value;
225
- }
226
- return selectedValue;
227
- };
228
- var __defProp$8 = Object.defineProperty, __defProps$7 = Object.defineProperties, __getOwnPropDescs$7 = Object.getOwnPropertyDescriptors, __getOwnPropSymbols$8 = Object.getOwnPropertySymbols, __hasOwnProp$8 = Object.prototype.hasOwnProperty, __propIsEnum$8 = Object.prototype.propertyIsEnumerable, __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues$8 = (a, b) => {
229
- for (var prop in b || (b = {}))
230
- __hasOwnProp$8.call(b, prop) && __defNormalProp$8(a, prop, b[prop]);
231
- if (__getOwnPropSymbols$8)
232
- for (var prop of __getOwnPropSymbols$8(b))
233
- __propIsEnum$8.call(b, prop) && __defNormalProp$8(a, prop, b[prop]);
234
- return a;
235
- }, __spreadProps$7 = (a, b) => __defProps$7(a, __getOwnPropDescs$7(b));
236
- const InternationalizedArrayContext = createContext(__spreadProps$7(__spreadValues$8({}, CONFIG_DEFAULT), {
237
- languages: [],
238
- filteredLanguages: []
239
- }));
240
- function useInternationalizedArrayContext() {
241
- return useContext(InternationalizedArrayContext);
242
- }
243
- function InternationalizedArrayProvider(props) {
244
- const { internationalizedArray: internationalizedArray2 } = props, client = useClient({ apiVersion: internationalizedArray2.apiVersion }), workspace = useWorkspace(), { formState } = useDocumentPane(), deferredDocument = useDeferredValue(formState == null ? void 0 : formState.value), selectedValue = useMemo(
245
- () => getSelectedValue(internationalizedArray2.select, deferredDocument),
246
- [internationalizedArray2.select, deferredDocument]
247
- ), workspaceId = useMemo(() => {
248
- if (workspace != null && workspace.name)
249
- return workspace.name;
250
- const workspaceKey = {
251
- name: workspace == null ? void 0 : workspace.name,
252
- title: workspace == null ? void 0 : workspace.title
253
- // Add other stable properties as needed
254
- };
255
- return JSON.stringify(workspaceKey);
256
- }, [workspace]), cacheKey = useMemo(
257
- () => createCacheKey(selectedValue, workspaceId),
258
- [selectedValue, workspaceId]
259
- ), languages = Array.isArray(internationalizedArray2.languages) ? internationalizedArray2.languages : suspend$1(
260
- // eslint-disable-next-line require-await
261
- async () => {
262
- if (typeof internationalizedArray2.languages == "function") {
263
- const result = await internationalizedArray2.languages(
264
- client,
265
- selectedValue
266
- );
267
- return setFunctionCache(
268
- internationalizedArray2.languages,
269
- selectedValue,
270
- result,
271
- workspaceId
272
- ), result;
273
- }
274
- return internationalizedArray2.languages;
275
- },
276
- cacheKey,
277
- { equal }
278
- ), { selectedLanguageIds, options: languageFilterOptions } = useLanguageFilterStudioContext(), filteredLanguages = useMemo(() => {
279
- const documentType = deferredDocument ? deferredDocument._type : void 0;
280
- return typeof documentType == "string" && languageFilterOptions.documentTypes.includes(documentType) ? languages.filter(
281
- (language) => selectedLanguageIds.includes(language.id)
282
- ) : languages;
283
- }, [deferredDocument, languageFilterOptions, languages, selectedLanguageIds]), showDocumentButtons = internationalizedArray2.buttonLocations.includes("document"), context = useMemo(
284
- () => __spreadProps$7(__spreadValues$8({}, internationalizedArray2), { languages, filteredLanguages }),
285
- [filteredLanguages, internationalizedArray2, languages]
286
- );
287
- return /* @__PURE__ */ jsx(InternationalizedArrayContext.Provider, { value: context, children: showDocumentButtons ? /* @__PURE__ */ jsxs(Stack, { space: 5, children: [
288
- /* @__PURE__ */ jsx(DocumentAddButtons, { value: props.value }),
289
- props.renderDefault(props)
290
- ] }) : props.renderDefault(props) });
291
- }
292
- var __defProp$7 = Object.defineProperty, __defProps$6 = Object.defineProperties, __getOwnPropDescs$6 = Object.getOwnPropertyDescriptors, __getOwnPropSymbols$7 = Object.getOwnPropertySymbols, __hasOwnProp$7 = Object.prototype.hasOwnProperty, __propIsEnum$7 = Object.prototype.propertyIsEnumerable, __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues$7 = (a, b) => {
293
- for (var prop in b || (b = {}))
294
- __hasOwnProp$7.call(b, prop) && __defNormalProp$7(a, prop, b[prop]);
295
- if (__getOwnPropSymbols$7)
296
- for (var prop of __getOwnPropSymbols$7(b))
297
- __propIsEnum$7.call(b, prop) && __defNormalProp$7(a, prop, b[prop]);
298
- return a;
299
- }, __spreadProps$6 = (a, b) => __defProps$6(a, __getOwnPropDescs$6(b));
300
- function InternationalizedField(props) {
301
- const { languages } = useInternationalizedArrayContext(), customProps = useMemo(() => {
302
- var _a;
303
- const pathSegment = props.path.slice(0, -1)[1], languageId = typeof pathSegment == "object" && "_key" in pathSegment ? pathSegment._key : void 0, hasValidLanguageId = languageId ? languages.some((l) => l.id === languageId) : !1, shouldHideTitle = ((_a = props.title) == null ? void 0 : _a.toLowerCase()) === "value" && hasValidLanguageId;
304
- return __spreadProps$6(__spreadValues$7({}, props), {
305
- title: shouldHideTitle ? "" : props.title
306
- });
307
- }, [props, languages]);
308
- return customProps.schemaType.name.startsWith("internationalizedArray") ? customProps.schemaType.name === "reference" && customProps.value ? customProps.renderDefault(__spreadProps$6(__spreadValues$7({}, customProps), {
309
- title: "",
310
- level: 0
311
- // Reset the level to avoid nested styling
312
- })) : customProps.schemaType.name === "string" || customProps.schemaType.name === "number" || customProps.schemaType.name === "text" ? customProps.children : customProps.renderDefault(__spreadProps$6(__spreadValues$7({}, customProps), {
313
- level: 0
314
- // Reset the level to avoid nested styling
315
- })) : customProps.renderDefault(customProps);
316
- }
317
- var Preload = memo(function(props) {
318
- const client = useClient({ apiVersion: props.apiVersion }), cacheKey = createCacheKey({});
319
- return Array.isArray(peek({})) || preloadWithKey(async () => {
320
- if (Array.isArray(props.languages))
321
- return props.languages;
322
- const result = await props.languages(client, {});
323
- return setFunctionCache(props.languages, {}, result), result;
324
- }, cacheKey), null;
325
- });
326
- function checkAllLanguagesArePresent(languages, value) {
327
- const filteredLanguageIds = languages.map((l) => l.id), languagesInUseIds = value ? value.map((v) => v._key) : [];
328
- return languagesInUseIds.length === filteredLanguageIds.length && languagesInUseIds.every((l) => filteredLanguageIds.includes(l));
329
- }
330
- function createAddAllTitle(value, languages) {
331
- return value != null && value.length ? `Add missing ${languages.length - value.length === 1 ? "language" : "languages"}` : languages.length === 1 ? `Add ${languages[0].title} Field` : "Add all languages";
332
- }
333
- function createValueSchemaTypeName(schemaType) {
334
- return `${schemaType.name}Value`;
335
- }
336
- var __defProp$6 = Object.defineProperty, __defProps$5 = Object.defineProperties, __getOwnPropDescs$5 = Object.getOwnPropertyDescriptors, __getOwnPropSymbols$6 = Object.getOwnPropertySymbols, __hasOwnProp$6 = Object.prototype.hasOwnProperty, __propIsEnum$6 = Object.prototype.propertyIsEnumerable, __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues$6 = (a, b) => {
337
- for (var prop in b || (b = {}))
338
- __hasOwnProp$6.call(b, prop) && __defNormalProp$6(a, prop, b[prop]);
339
- if (__getOwnPropSymbols$6)
340
- for (var prop of __getOwnPropSymbols$6(b))
341
- __propIsEnum$6.call(b, prop) && __defNormalProp$6(a, prop, b[prop]);
342
- return a;
343
- }, __spreadProps$5 = (a, b) => __defProps$5(a, __getOwnPropDescs$5(b));
344
- function createAddLanguagePatches(config) {
345
- const {
346
- addLanguageKeys,
347
- schemaType,
348
- languages,
349
- filteredLanguages,
350
- value,
351
- path = []
352
- } = config, itemBase = { _type: createValueSchemaTypeName(schemaType) }, newItems = Array.isArray(addLanguageKeys) && addLanguageKeys.length > 0 ? addLanguageKeys.map((id) => __spreadProps$5(__spreadValues$6({}, itemBase), {
353
- _key: id
354
- })) : filteredLanguages.filter(
355
- (language) => value != null && value.length ? !value.find((v) => v._key === language.id) : !0
356
- ).map((language) => __spreadProps$5(__spreadValues$6({}, itemBase), {
357
- _key: language.id
358
- })), languagesInUse = value != null && value.length ? value.map((v) => v) : [];
359
- return newItems.map((item) => {
360
- const languageIndex = languages.findIndex((l) => item._key === l.id), remainingLanguages = languages.slice(languageIndex + 1), nextLanguageIndex = languagesInUse.findIndex(
361
- (l) => (
362
- // eslint-disable-next-line max-nested-callbacks
363
- remainingLanguages.find((r) => r.id === l._key)
364
- )
365
- );
366
- return nextLanguageIndex < 0 ? languagesInUse.push(item) : languagesInUse.splice(nextLanguageIndex, 0, item), nextLanguageIndex < 0 ? (
367
- // No next language (-1), add to end of array
368
- insert([item], "after", [...path, nextLanguageIndex])
369
- ) : (
370
- // Next language found, insert before that
371
- insert([item], "before", [...path, nextLanguageIndex])
372
- );
373
- });
374
- }
375
- const createTranslateFieldActions = (fieldActionProps, { languages, filteredLanguages }) => languages.map((language) => {
376
- const value = useFormValue(fieldActionProps.path), disabled = value && Array.isArray(value) ? !!(value != null && value.find((item) => item._key === language.id)) : !1, hidden = !filteredLanguages.some((f) => f.id === language.id), { onChange } = useDocumentPane(), onAction = useCallback(() => {
377
- const { schemaType, path } = fieldActionProps, addLanguageKeys = [language.id], patches = createAddLanguagePatches({
378
- addLanguageKeys,
379
- schemaType,
380
- languages,
381
- filteredLanguages,
382
- value,
383
- path
384
- });
385
- onChange(PatchEvent.from([setIfMissing([], path), ...patches]));
386
- }, [language.id, value, onChange]);
387
- return {
388
- type: "action",
389
- icon: AddIcon,
390
- onAction,
391
- title: language.title,
392
- hidden,
393
- disabled
394
- };
395
- }), AddMissingTranslationsFieldAction = (fieldActionProps, { languages, filteredLanguages }) => {
396
- const value = useFormValue(fieldActionProps.path), disabled = value && value.length === filteredLanguages.length, hidden = checkAllLanguagesArePresent(filteredLanguages, value), { onChange } = useDocumentPane(), onAction = useCallback(() => {
397
- const { schemaType, path } = fieldActionProps, patches = createAddLanguagePatches({
398
- addLanguageKeys: [],
399
- schemaType,
400
- languages,
401
- filteredLanguages,
402
- value,
403
- path
404
- });
405
- onChange(PatchEvent.from([setIfMissing([], path), ...patches]));
406
- }, [fieldActionProps, filteredLanguages, languages, onChange, value]);
407
- return {
408
- type: "action",
409
- icon: AddIcon,
410
- onAction,
411
- title: createAddAllTitle(value, filteredLanguages),
412
- disabled,
413
- hidden
414
- };
415
- }, internationalizedArrayFieldAction = defineDocumentFieldAction({
416
- name: "internationalizedArray",
417
- useAction(fieldActionProps) {
418
- var _a, _b;
419
- const isInternationalizedArrayField = (_b = (_a = fieldActionProps == null ? void 0 : fieldActionProps.schemaType) == null ? void 0 : _a.type) == null ? void 0 : _b.name.startsWith(
420
- "internationalizedArray"
421
- ), { languages, filteredLanguages } = useInternationalizedArrayContext(), translateFieldActions = createTranslateFieldActions(
422
- fieldActionProps,
423
- { languages, filteredLanguages }
424
- );
425
- return {
426
- type: "group",
427
- icon: TranslateIcon,
428
- title: "Add Translation",
429
- renderAsButton: !0,
430
- children: isInternationalizedArrayField ? [
431
- ...translateFieldActions,
432
- AddMissingTranslationsFieldAction(fieldActionProps, {
433
- languages,
434
- filteredLanguages
435
- })
436
- ] : [],
437
- hidden: !isInternationalizedArrayField
438
- };
439
- }
440
- });
441
- function camelCase(string) {
442
- return string.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
443
- }
444
- function titleCase(string) {
445
- return string.split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
446
- }
447
- function pascalCase(string) {
448
- return titleCase(camelCase(string));
449
- }
450
- function createFieldName(name, addValue = !1) {
451
- return addValue ? ["internationalizedArray", pascalCase(name), "Value"].join("") : ["internationalizedArray", pascalCase(name)].join("");
452
- }
453
- const schemaExample = {
454
- languages: [
455
- { id: "en", title: "English" },
456
- { id: "no", title: "Norsk" }
457
- ]
458
- };
459
- function Feedback() {
460
- return /* @__PURE__ */ jsx(Card, { tone: "caution", border: !0, radius: 2, padding: 3, children: /* @__PURE__ */ jsxs(Stack, { space: 4, children: [
461
- /* @__PURE__ */ jsxs(Text, { children: [
462
- "An array of language objects must be passed into the",
463
- " ",
464
- /* @__PURE__ */ jsx("code", { children: "internationalizedArray" }),
465
- " helper function, each with an",
466
- " ",
467
- /* @__PURE__ */ jsx("code", { children: "id" }),
468
- " and ",
469
- /* @__PURE__ */ jsx("code", { children: "title" }),
470
- " field. Example:"
471
- ] }),
472
- /* @__PURE__ */ jsx(Card, { padding: 2, border: !0, radius: 2, children: /* @__PURE__ */ jsx(Code, { size: 1, language: "javascript", children: JSON.stringify(schemaExample, null, 2) }) })
473
- ] }) });
474
- }
475
- var __defProp$5 = Object.defineProperty, __defProps$4 = Object.defineProperties, __getOwnPropDescs$4 = Object.getOwnPropertyDescriptors, __getOwnPropSymbols$5 = Object.getOwnPropertySymbols, __hasOwnProp$5 = Object.prototype.hasOwnProperty, __propIsEnum$5 = Object.prototype.propertyIsEnumerable, __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues$5 = (a, b) => {
476
- for (var prop in b || (b = {}))
477
- __hasOwnProp$5.call(b, prop) && __defNormalProp$5(a, prop, b[prop]);
478
- if (__getOwnPropSymbols$5)
479
- for (var prop of __getOwnPropSymbols$5(b))
480
- __propIsEnum$5.call(b, prop) && __defNormalProp$5(a, prop, b[prop]);
481
- return a;
482
- }, __spreadProps$4 = (a, b) => __defProps$4(a, __getOwnPropDescs$4(b));
483
- function InternationalizedArray(props) {
484
- const {
485
- members,
486
- value,
487
- schemaType,
488
- onChange,
489
- readOnly: documentReadOnly
490
- } = props, readOnly = typeof schemaType.readOnly == "boolean" ? schemaType.readOnly : !1, toast = useToast(), {
491
- languages,
492
- filteredLanguages,
493
- defaultLanguages,
494
- buttonAddAll,
495
- buttonLocations
496
- } = useInternationalizedArrayContext(), { selectedLanguageIds, options: languageFilterOptions } = useLanguageFilterStudioContext(), documentType = useFormValue(["_type"]), languageFilterEnabled = typeof documentType == "string" && languageFilterOptions.documentTypes.includes(documentType), filteredMembers = useMemo(
497
- () => languageFilterEnabled ? members.filter((member) => {
498
- if (member.kind !== "item")
499
- return !1;
500
- const valueMember = member.item.members[0];
501
- return valueMember.kind !== "field" ? !1 : languageFilterOptions.filterField(
502
- member.item.schemaType,
503
- valueMember,
504
- selectedLanguageIds
505
- );
506
- }) : members,
507
- [languageFilterEnabled, members, languageFilterOptions, selectedLanguageIds]
508
- ), handleAddLanguage = useCallback(
509
- async (param) => {
510
- var _a;
511
- if (!(filteredLanguages != null && filteredLanguages.length))
512
- return;
513
- const addLanguageKeys = Array.isArray(param) ? param : [(_a = param == null ? void 0 : param.currentTarget) == null ? void 0 : _a.value].filter(Boolean), patches = createAddLanguagePatches({
514
- addLanguageKeys,
515
- schemaType,
516
- languages,
517
- filteredLanguages,
518
- value
519
- });
520
- onChange([setIfMissing([]), ...patches]);
521
- },
522
- [filteredLanguages, languages, onChange, schemaType, value]
523
- ), { isDeleting } = useDocumentPane(), addedLanguages = members.map(({ key }) => key), hasAddedDefaultLanguages = defaultLanguages.filter((language) => languages.find((l) => l.id === language)).every((language) => addedLanguages.includes(language));
524
- useEffect(() => {
525
- if (!isDeleting && !hasAddedDefaultLanguages) {
526
- const languagesToAdd = defaultLanguages.filter((language) => !addedLanguages.includes(language)).filter((language) => languages.find((l) => l.id === language)), timeout = setTimeout(() => {
527
- documentReadOnly || handleAddLanguage(languagesToAdd);
528
- });
529
- return () => clearTimeout(timeout);
530
- }
531
- }, [
532
- isDeleting,
533
- hasAddedDefaultLanguages,
534
- handleAddLanguage,
535
- defaultLanguages,
536
- addedLanguages,
537
- languages,
538
- documentReadOnly
539
- ]);
540
- const handleRestoreOrder = useCallback(() => {
541
- if (!(value != null && value.length) || !(languages != null && languages.length))
542
- return;
543
- const updatedValue = value.reduce((acc, v) => {
544
- const newIndex = languages.findIndex((l) => l.id === (v == null ? void 0 : v._key));
545
- return newIndex > -1 && (acc[newIndex] = v), acc;
546
- }, []).filter(Boolean);
547
- (value == null ? void 0 : value.length) !== updatedValue.length && toast.push({
548
- title: "There was an error reordering languages",
549
- status: "warning"
550
- }), onChange(set(updatedValue));
551
- }, [toast, languages, onChange, value]), allKeysAreLanguages = useMemo(() => !(value != null && value.length) || !(languages != null && languages.length) ? !0 : value == null ? void 0 : value.every((v) => languages.find((l) => (l == null ? void 0 : l.id) === (v == null ? void 0 : v._key))), [value, languages]), languagesInUse = useMemo(
552
- () => languages && languages.length > 1 ? languages.filter((l) => value == null ? void 0 : value.find((v) => v._key === l.id)) : [],
553
- [languages, value]
554
- ), languagesOutOfOrder = useMemo(() => !(value != null && value.length) || !languagesInUse.length ? [] : value.map(
555
- (v, vIndex) => vIndex === languagesInUse.findIndex((l) => l.id === v._key) ? null : v
556
- ).filter(Boolean), [value, languagesInUse]), languagesAreValid = useMemo(
557
- () => !(languages != null && languages.length) || (languages == null ? void 0 : languages.length) && languages.every((item) => item.id && item.title),
558
- [languages]
559
- );
560
- useEffect(() => {
561
- languagesOutOfOrder.length > 0 && allKeysAreLanguages && handleRestoreOrder();
562
- }, [languagesOutOfOrder, allKeysAreLanguages, handleRestoreOrder]);
563
- const allLanguagesArePresent = useMemo(
564
- () => checkAllLanguagesArePresent(filteredLanguages, value),
565
- [filteredLanguages, value]
566
- );
567
- if (!languagesAreValid)
568
- return /* @__PURE__ */ jsx(Feedback, {});
569
- const addButtonsAreVisible = (
570
- // Plugin was configured to display buttons here (default!)
571
- buttonLocations.includes("field") && // There's at least one language visible
572
- (filteredLanguages == null ? void 0 : filteredLanguages.length) > 0 && // Not every language has a value yet
573
- !allLanguagesArePresent
574
- ), fieldHasMembers = (members == null ? void 0 : members.length) > 0;
575
- return /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
576
- fieldHasMembers ? /* @__PURE__ */ jsx(Fragment, { children: filteredMembers.map((member) => member.kind === "item" ? /* @__PURE__ */ createElement(
577
- ArrayOfObjectsItem,
578
- __spreadProps$4(__spreadValues$5({}, props), {
579
- key: member.key,
580
- member
581
- })
582
- ) : /* @__PURE__ */ jsx(MemberItemError, { member }, member.key)) }) : null,
583
- !addButtonsAreVisible && !fieldHasMembers ? /* @__PURE__ */ jsx(Card, { border: !0, tone: "transparent", padding: 3, radius: 2, children: /* @__PURE__ */ jsx(Text, { size: 1, children: "This internationalized field currently has no translations." }) }) : null,
584
- addButtonsAreVisible ? /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
585
- /* @__PURE__ */ jsx(
586
- AddButtons$1,
587
- {
588
- languages: filteredLanguages,
589
- value,
590
- readOnly,
591
- onClick: handleAddLanguage
592
- }
593
- ),
594
- buttonAddAll ? /* @__PURE__ */ jsx(
595
- Button,
596
- {
597
- tone: "primary",
598
- mode: "ghost",
599
- disabled: readOnly || allLanguagesArePresent,
600
- icon: AddIcon,
601
- text: createAddAllTitle(value, filteredLanguages),
602
- onClick: handleAddLanguage
603
- }
604
- ) : null
605
- ] }) : null
606
- ] });
607
- }
608
- function getLanguagesFieldOption(schemaType) {
609
- var _a;
610
- return schemaType ? ((_a = schemaType.options) == null ? void 0 : _a.languages) || getLanguagesFieldOption(schemaType.type) : void 0;
611
- }
612
- var __defProp$4 = Object.defineProperty, __defProps$3 = Object.defineProperties, __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors, __getOwnPropSymbols$4 = Object.getOwnPropertySymbols, __hasOwnProp$4 = Object.prototype.hasOwnProperty, __propIsEnum$4 = Object.prototype.propertyIsEnumerable, __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues$4 = (a, b) => {
613
- for (var prop in b || (b = {}))
614
- __hasOwnProp$4.call(b, prop) && __defNormalProp$4(a, prop, b[prop]);
615
- if (__getOwnPropSymbols$4)
616
- for (var prop of __getOwnPropSymbols$4(b))
617
- __propIsEnum$4.call(b, prop) && __defNormalProp$4(a, prop, b[prop]);
618
- return a;
619
- }, __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b)), array = (config) => {
620
- const { apiVersion, select, languages, type } = config, typeName = typeof type == "string" ? type : type.name, arrayName = createFieldName(typeName), objectName = createFieldName(typeName, !0);
621
- return defineField({
622
- name: arrayName,
623
- title: "Internationalized array",
624
- type: "array",
625
- components: {
626
- input: InternationalizedArray
627
- },
628
- options: {
629
- // @ts-expect-error - these options are required for validation rules – not the custom input component
630
- apiVersion,
631
- select,
632
- languages
633
- },
634
- of: [
635
- defineField(__spreadProps$3(__spreadValues$4({}, typeof type == "string" ? {} : type), {
636
- name: objectName,
637
- type: objectName
638
- }))
639
- ],
640
- // @ts-expect-error - fix typings
641
- validation: (rule) => rule.custom(async (value, context) => {
642
- var _a;
643
- if (!value || value.length === 0 || value.length === 1 && !((_a = value[0]) != null && _a._key))
644
- return !0;
645
- const selectedValue = getSelectedValue(select, context.document), client = context.getClient({ apiVersion });
646
- let contextLanguages = [];
647
- const languagesFieldOption = getLanguagesFieldOption(context == null ? void 0 : context.type);
648
- if (Array.isArray(languagesFieldOption))
649
- contextLanguages = languagesFieldOption;
650
- else if (Array.isArray(peek(selectedValue)))
651
- contextLanguages = peek(selectedValue) || [];
652
- else if (typeof languagesFieldOption == "function") {
653
- const cachedLanguages = getFunctionCache(
654
- languagesFieldOption,
655
- selectedValue
656
- );
657
- if (Array.isArray(cachedLanguages))
658
- contextLanguages = cachedLanguages;
659
- else {
660
- const suspendCachedLanguages = peek(selectedValue);
661
- Array.isArray(suspendCachedLanguages) ? contextLanguages = suspendCachedLanguages : (contextLanguages = await languagesFieldOption(
662
- client,
663
- selectedValue
664
- ), setFunctionCache(
665
- languagesFieldOption,
666
- selectedValue,
667
- contextLanguages
668
- ));
669
- }
670
- }
671
- if (value && value.length > contextLanguages.length)
672
- return `Cannot be more than ${contextLanguages.length === 1 ? "1 item" : `${contextLanguages.length} items`}`;
673
- const languageIds = new Set(contextLanguages.map((lang) => lang.id)), nonLanguageKeys = value.filter(
674
- (item) => (item == null ? void 0 : item._key) && !languageIds.has(item._key)
675
- );
676
- if (nonLanguageKeys.length)
677
- return {
678
- message: "Array item keys must be valid languages registered to the field type",
679
- paths: nonLanguageKeys.map((item) => [{ _key: item._key }])
680
- };
681
- const seenKeys = /* @__PURE__ */ new Set(), duplicateValues = [];
682
- for (const item of value)
683
- item != null && item._key && (seenKeys.has(item._key) ? duplicateValues.push(item) : seenKeys.add(item._key));
684
- return duplicateValues.length ? {
685
- message: "There can only be one field per language",
686
- paths: duplicateValues.map((item) => [{ _key: item._key }])
687
- } : !0;
688
- })
689
- });
690
- };
691
- function getToneFromValidation(validations) {
692
- if (!(validations != null && validations.length))
693
- return;
694
- const validationLevels = validations.map((v) => v.level);
695
- if (validationLevels.includes("error"))
696
- return "critical";
697
- if (validationLevels.includes("warning"))
698
- return "caution";
699
- }
700
- var __defProp$3 = Object.defineProperty, __defProps$2 = Object.defineProperties, __getOwnPropDescs$2 = Object.getOwnPropertyDescriptors, __getOwnPropSymbols$3 = Object.getOwnPropertySymbols, __hasOwnProp$3 = Object.prototype.hasOwnProperty, __propIsEnum$3 = Object.prototype.propertyIsEnumerable, __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues$3 = (a, b) => {
701
- for (var prop in b || (b = {}))
702
- __hasOwnProp$3.call(b, prop) && __defNormalProp$3(a, prop, b[prop]);
703
- if (__getOwnPropSymbols$3)
704
- for (var prop of __getOwnPropSymbols$3(b))
705
- __propIsEnum$3.call(b, prop) && __defNormalProp$3(a, prop, b[prop]);
706
- return a;
707
- }, __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
708
- function InternationalizedInput(props) {
709
- const parentValue = useFormValue(
710
- props.path.slice(0, -1)
711
- ), originalOnChange = props.inputProps.onChange, wrappedOnChange = useCallback(
712
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
713
- (patches) => {
714
- var _a;
715
- if (!Array.isArray(patches))
716
- return originalOnChange(patches);
717
- const valueField = (_a = props.value) == null ? void 0 : _a.value;
718
- if ((valueField == null || Array.isArray(valueField) && valueField.length === 0) && patches.some((patch) => !patch || typeof patch != "object" ? !1 : patch.type === "insert" && patch.path && Array.isArray(patch.path) && patch.path.length > 0 ? patch.path[0] === "value" || typeof patch.path[0] == "number" : !1)) {
719
- const initPatch = valueField === void 0 ? { type: "setIfMissing", path: ["value"], value: [] } : null, fixedPatches = patches.map((patch) => {
720
- if (!patch || typeof patch != "object")
721
- return patch;
722
- if (patch.type === "insert" && patch.path && Array.isArray(patch.path)) {
723
- const fixedPath = patch.path[0] === "value" ? patch.path : ["value", ...patch.path];
724
- return __spreadProps$2(__spreadValues$3({}, patch), { path: fixedPath });
725
- }
726
- return patch;
727
- }), allPatches = initPatch ? [initPatch, ...fixedPatches] : fixedPatches;
728
- return originalOnChange(allPatches);
729
- }
730
- return originalOnChange(patches);
731
- },
732
- [props.value, originalOnChange]
733
- ), inlineProps = __spreadProps$2(__spreadValues$3({}, props.inputProps), {
734
- // This is the magic that makes inline editing work?
735
- members: props.inputProps.members.filter(
736
- (m) => m.kind === "field" && m.name === "value"
737
- ),
738
- // This just overrides the type
739
- // Remove this as it shouldn't be necessary?
740
- value: props.value,
741
- // Use our wrapped onChange handler
742
- onChange: wrappedOnChange
743
- }), { validation, value, onChange, readOnly } = inlineProps, { languages, languageDisplay, defaultLanguages } = useInternationalizedArrayContext(), languageKeysInUse = useMemo(
744
- () => {
745
- var _a;
746
- return (_a = parentValue == null ? void 0 : parentValue.map((v) => v._key)) != null ? _a : [];
747
- },
748
- [parentValue]
749
- ), keyIsValid = languages != null && languages.length ? languages.find((l) => l.id === value._key) : !1, handleKeyChange = useCallback(
750
- (event) => {
751
- var _a;
752
- const languageId = (_a = event == null ? void 0 : event.currentTarget) == null ? void 0 : _a.value;
753
- !value || !(languages != null && languages.length) || !languages.find((l) => l.id === languageId) || onChange([set(languageId, ["_key"])]);
754
- },
755
- [onChange, value, languages]
756
- ), handleUnset = useCallback(() => {
757
- onChange(unset());
758
- }, [onChange]);
759
- if (!languages)
760
- return /* @__PURE__ */ jsx(Spinner, {});
761
- const language = languages.find((l) => l.id === value._key), languageTitle = keyIsValid && language ? getLanguageDisplay(languageDisplay, language.title, language.id) : "", isDefault = defaultLanguages.includes(value._key), removeButton = /* @__PURE__ */ jsx(
762
- Button,
763
- {
764
- mode: "bleed",
765
- icon: RemoveCircleIcon,
766
- tone: "critical",
767
- disabled: readOnly || isDefault,
768
- onClick: handleUnset
769
- }
770
- );
771
- return /* @__PURE__ */ jsx(Card, { paddingTop: 2, tone: getToneFromValidation(validation), children: /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
772
- /* @__PURE__ */ jsx(Card, { tone: "inherit", children: keyIsValid ? /* @__PURE__ */ jsx(Label, { muted: !0, size: 1, children: languageTitle }) : /* @__PURE__ */ jsx(
773
- MenuButton,
774
- {
775
- button: /* @__PURE__ */ jsx(Button, { fontSize: 1, text: `Change "${value._key}"` }),
776
- id: `${value._key}-change-key`,
777
- menu: /* @__PURE__ */ jsx(Menu, { children: languages.map((lang) => /* @__PURE__ */ jsx(
778
- MenuItem,
779
- {
780
- disabled: languageKeysInUse.includes(lang.id),
781
- fontSize: 1,
782
- text: lang.id.toLocaleUpperCase(),
783
- value: lang.id,
784
- onClick: handleKeyChange
785
- },
786
- lang.id
787
- )) }),
788
- popover: { portal: !0 }
789
- }
790
- ) }),
791
- /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
792
- /* @__PURE__ */ jsx(Card, { flex: 1, tone: "inherit", children: props.inputProps.renderInput(inlineProps) }),
793
- /* @__PURE__ */ jsx(Card, { tone: "inherit", children: isDefault ? /* @__PURE__ */ jsx(
794
- Tooltip,
795
- {
796
- content: /* @__PURE__ */ jsx(Text, { muted: !0, size: 1, children: "Can't remove default language" }),
797
- fallbackPlacements: ["right", "left"],
798
- placement: "top",
799
- portal: !0,
800
- children: /* @__PURE__ */ jsx("span", { children: removeButton })
801
- }
802
- ) : removeButton })
803
- ] })
804
- ] }) });
805
- }
806
- var __defProp$2 = Object.defineProperty, __defProps$1 = Object.defineProperties, __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors, __getOwnPropSymbols$2 = Object.getOwnPropertySymbols, __hasOwnProp$2 = Object.prototype.hasOwnProperty, __propIsEnum$2 = Object.prototype.propertyIsEnumerable, __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues$2 = (a, b) => {
807
- for (var prop in b || (b = {}))
808
- __hasOwnProp$2.call(b, prop) && __defNormalProp$2(a, prop, b[prop]);
809
- if (__getOwnPropSymbols$2)
810
- for (var prop of __getOwnPropSymbols$2(b))
811
- __propIsEnum$2.call(b, prop) && __defNormalProp$2(a, prop, b[prop]);
812
- return a;
813
- }, __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b)), object = (config) => {
814
- const { type } = config, typeName = typeof type == "string" ? type : type.name, objectName = createFieldName(typeName, !0);
815
- return defineField({
816
- name: objectName,
817
- title: `Internationalized array ${type}`,
818
- type: "object",
819
- components: {
820
- // @ts-expect-error - fix typings
821
- item: InternationalizedInput
822
- },
823
- fields: [
824
- defineField(__spreadProps$1(__spreadValues$2({}, typeof type == "string" ? { type } : type), {
825
- name: "value"
826
- }))
827
- ],
828
- preview: {
829
- select: {
830
- title: "value",
831
- subtitle: "_key"
832
- }
833
- }
834
- });
835
- }, __defProp$1 = Object.defineProperty, __getOwnPropSymbols$1 = Object.getOwnPropertySymbols, __hasOwnProp$1 = Object.prototype.hasOwnProperty, __propIsEnum$1 = Object.prototype.propertyIsEnumerable, __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues$1 = (a, b) => {
836
- for (var prop in b || (b = {}))
837
- __hasOwnProp$1.call(b, prop) && __defNormalProp$1(a, prop, b[prop]);
838
- if (__getOwnPropSymbols$1)
839
- for (var prop of __getOwnPropSymbols$1(b))
840
- __propIsEnum$1.call(b, prop) && __defNormalProp$1(a, prop, b[prop]);
841
- return a;
842
- };
843
- function flattenSchemaType(schemaType) {
844
- return isDocumentSchemaType(schemaType) ? extractInnerFields(schemaType.fields, [], 3) : (console.error("Schema type is not a document"), []);
845
- }
846
- function extractInnerFields(fields, path, maxDepth) {
847
- return path.length >= maxDepth ? [] : fields.reduce((acc, field) => {
848
- const thisFieldWithPath = __spreadValues$1({ path: [...path, field.name] }, field);
849
- if (field.type.jsonType === "object") {
850
- const innerFields = extractInnerFields(
851
- field.type.fields,
852
- [...path, field.name],
853
- maxDepth
854
- );
855
- return [...acc, thisFieldWithPath, ...innerFields];
856
- } else if (field.type.jsonType === "array" && field.type.of.length && field.type.of.some((item) => "fields" in item)) {
857
- const innerFields = field.type.of.flatMap(
858
- (innerField) => extractInnerFields(
859
- // @ts-expect-error - Fix TS assertion for array fields
860
- innerField.fields,
861
- [...path, field.name],
862
- maxDepth
863
- )
864
- );
865
- return [...acc, thisFieldWithPath, ...innerFields];
866
- }
867
- return [...acc, thisFieldWithPath];
868
- }, []);
869
- }
870
- var __defProp = Object.defineProperty, __defProps = Object.defineProperties, __getOwnPropDescs = Object.getOwnPropertyDescriptors, __getOwnPropSymbols = Object.getOwnPropertySymbols, __hasOwnProp = Object.prototype.hasOwnProperty, __propIsEnum = Object.prototype.propertyIsEnumerable, __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues = (a, b) => {
871
- for (var prop in b || (b = {}))
872
- __hasOwnProp.call(b, prop) && __defNormalProp(a, prop, b[prop]);
873
- if (__getOwnPropSymbols)
874
- for (var prop of __getOwnPropSymbols(b))
875
- __propIsEnum.call(b, prop) && __defNormalProp(a, prop, b[prop]);
876
- return a;
877
- }, __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
878
- const internationalizedArray = definePlugin((config) => {
879
- const pluginConfig = __spreadValues(__spreadValues({}, CONFIG_DEFAULT), config), {
880
- apiVersion = "2025-10-15",
881
- select,
882
- languages,
883
- fieldTypes,
884
- defaultLanguages,
885
- buttonLocations
886
- } = pluginConfig;
887
- return {
888
- name: "sanity-plugin-internationalized-array",
889
- // Preload languages for use throughout the Studio
890
- studio: Array.isArray(languages) ? void 0 : {
891
- components: {
892
- layout: (props) => /* @__PURE__ */ jsxs(Fragment, { children: [
893
- /* @__PURE__ */ jsx(Preload, { apiVersion, languages }),
894
- props.renderDefault(props)
895
- ] })
896
- }
897
- },
898
- // Optional: render "add language" buttons as field actions
899
- document: {
900
- unstable_fieldActions: buttonLocations.includes("unstable__fieldAction") ? (prev) => [...prev, internationalizedArrayFieldAction] : void 0
901
- },
902
- // Wrap document editor with a language provider
903
- form: {
904
- components: {
905
- field: (props) => /* @__PURE__ */ jsx(InternationalizedField, __spreadValues({}, props)),
906
- input: (props) => !(props.id === "root" && isObjectInputProps(props)) || !flattenSchemaType(props.schemaType).map(
907
- (field) => field.type.name
908
- ).some(
909
- (name) => name.startsWith("internationalizedArray")
910
- ) ? props.renderDefault(props) : /* @__PURE__ */ jsx(
911
- InternationalizedArrayProvider,
912
- __spreadProps(__spreadValues({}, props), {
913
- internationalizedArray: pluginConfig
914
- })
915
- )
916
- }
917
- },
918
- // Register custom schema types for the outer array and the inner object
919
- schema: {
920
- types: [
921
- ...fieldTypes.map(
922
- (type) => array({ type, apiVersion, select, languages, defaultLanguages })
923
- ),
924
- ...fieldTypes.map((type) => object({ type }))
925
- ]
926
- }
927
- };
928
- });
929
- export {
930
- clear,
931
- internationalizedArray
932
- };
933
- //# sourceMappingURL=index.esm.js.map