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