sanity-plugin-internationalized-array 2.1.0 → 3.0.0-canary.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.
package/lib/index.js CHANGED
@@ -5,8 +5,7 @@ function _interopDefaultCompat(e) {
5
5
  return e && typeof e == "object" && "default" in e ? e : { default: e };
6
6
  }
7
7
  function _interopNamespaceCompat(e) {
8
- if (e && typeof e == "object" && "default" in e)
9
- return e;
8
+ if (e && typeof e == "object" && "default" in e) return e;
10
9
  var n = /* @__PURE__ */ Object.create(null);
11
10
  return e && Object.keys(e).forEach(function(k) {
12
11
  if (k !== "default") {
@@ -21,7 +20,7 @@ function _interopNamespaceCompat(e) {
21
20
  }), n.default = e, Object.freeze(n);
22
21
  }
23
22
  var suspend__namespace = /* @__PURE__ */ _interopNamespaceCompat(suspend), equal__default = /* @__PURE__ */ _interopDefaultCompat(equal), get__default = /* @__PURE__ */ _interopDefaultCompat(get);
24
- const namespace = "sanity-plugin-internationalized-array", version = "v0", preload = (fn) => suspend__namespace.preload(() => fn(), [version, namespace]), clear = () => suspend__namespace.clear([version, namespace]), peek = (selectedValue) => suspend__namespace.peek([version, namespace, selectedValue]), MAX_COLUMNS = 7, CONFIG_DEFAULT = {
23
+ const namespace = "sanity-plugin-internationalized-array", version = "v1", preload = (fn) => suspend__namespace.preload(() => fn(), [version, namespace]), clear = () => suspend__namespace.clear([version, namespace]), peek = (selectedValue) => suspend__namespace.peek([version, namespace, selectedValue]), MAX_COLUMNS = 7, CONFIG_DEFAULT = {
25
24
  languages: [],
26
25
  select: {},
27
26
  defaultLanguages: [],
@@ -32,11 +31,10 @@ const namespace = "sanity-plugin-internationalized-array", version = "v0", prelo
32
31
  }, getDocumentsToTranslate = (value, rootPath = []) => {
33
32
  if (Array.isArray(value)) {
34
33
  const arrayRootPath = [...rootPath], internationalizedValues = value.filter((item) => {
35
- if (Array.isArray(item))
36
- return !1;
34
+ if (Array.isArray(item)) return !1;
37
35
  if (typeof item == "object") {
38
- const type = item == null ? void 0 : item._type;
39
- return (type == null ? void 0 : type.startsWith("internationalizedArray")) && (type == null ? void 0 : type.endsWith("Value"));
36
+ const type = item?._type;
37
+ return type?.startsWith("internationalizedArray") && type?.endsWith("Value");
40
38
  }
41
39
  return !1;
42
40
  });
@@ -67,7 +65,7 @@ function AddButtons(props) {
67
65
  tone: "primary",
68
66
  mode: "ghost",
69
67
  fontSize: 1,
70
- disabled: readOnly || !!(value != null && value.find((item) => item._key === language.id)),
68
+ disabled: readOnly || !!value?.find((item) => item._key === language.id),
71
69
  text: language.id.toUpperCase(),
72
70
  icon: languages.length > MAX_COLUMNS ? void 0 : icons.AddIcon,
73
71
  value: language.id,
@@ -76,6 +74,7 @@ function AddButtons(props) {
76
74
  language.id
77
75
  )) }) : null;
78
76
  }
77
+ var AddButtons$1 = react.memo(AddButtons);
79
78
  function DocumentAddButtons(props) {
80
79
  const { filteredLanguages } = useInternationalizedArrayContext(), value = sanity.isSanityDocument(props.value) ? props.value : void 0, toast = ui.useToast(), { onChange } = structure.useDocumentPane(), documentsToTranslation = getDocumentsToTranslate(value, []), handleDocumentButtonClick = react.useCallback(
81
80
  async (event) => {
@@ -88,7 +87,7 @@ function DocumentAddButtons(props) {
88
87
  return;
89
88
  }
90
89
  const alreadyTranslated = documentsToTranslation.filter(
91
- (translation) => (translation == null ? void 0 : translation._key) === languageId
90
+ (translation) => translation?._key === languageId
92
91
  ), removeDuplicates = documentsToTranslation.reduce((filteredTranslations, translation) => alreadyTranslated.filter(
93
92
  (alreadyTranslation) => alreadyTranslation.pathString === translation.pathString
94
93
  ).length > 0 || filteredTranslations.filter(
@@ -123,7 +122,7 @@ function DocumentAddButtons(props) {
123
122
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
124
123
  /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, weight: "semibold", children: "Add translation to internationalized fields" }) }),
125
124
  /* @__PURE__ */ jsxRuntime.jsx(
126
- AddButtons,
125
+ AddButtons$1,
127
126
  {
128
127
  languages: filteredLanguages,
129
128
  readOnly: !1,
@@ -140,7 +139,7 @@ const getSelectedValue = (select, document) => {
140
139
  for (const [key, path] of Object.entries(selection)) {
141
140
  let value = get__default.default(document, path);
142
141
  Array.isArray(value) && (value = value.filter(
143
- (item) => typeof item == "object" ? (item == null ? void 0 : item._type) === "reference" && "_ref" in item : !0
142
+ (item) => typeof item == "object" ? item?._type === "reference" && "_ref" in item : !0
144
143
  )), selectedValue[key] = value;
145
144
  }
146
145
  return selectedValue;
@@ -153,7 +152,7 @@ function useInternationalizedArrayContext() {
153
152
  return react.useContext(InternationalizedArrayContext);
154
153
  }
155
154
  function InternationalizedArrayProvider(props) {
156
- const { internationalizedArray: internationalizedArray2 } = props, client = sanity.useClient({ apiVersion: internationalizedArray2.apiVersion }), workspace = sanity.useWorkspace(), { value: document } = sanity.useFormBuilder(), deferredDocument = react.useDeferredValue(document), selectedValue = react.useMemo(
155
+ const { internationalizedArray: internationalizedArray2 } = props, client = sanity.useClient({ apiVersion: internationalizedArray2.apiVersion }), workspace = sanity.useWorkspace(), { formState } = structure.useDocumentPane(), deferredDocument = react.useDeferredValue(formState?.value), selectedValue = react.useMemo(
157
156
  () => getSelectedValue(internationalizedArray2.select, deferredDocument),
158
157
  [internationalizedArray2.select, deferredDocument]
159
158
  ), languages = Array.isArray(internationalizedArray2.languages) ? internationalizedArray2.languages : suspend.suspend(
@@ -166,21 +165,14 @@ function InternationalizedArrayProvider(props) {
166
165
  return typeof documentType == "string" && languageFilterOptions.documentTypes.includes(documentType) ? languages.filter(
167
166
  (language) => selectedLanguageIds.includes(language.id)
168
167
  ) : languages;
169
- }, [deferredDocument, languageFilterOptions, languages, selectedLanguageIds]), showDocumentButtons = internationalizedArray2.buttonLocations.includes("document");
170
- return /* @__PURE__ */ jsxRuntime.jsx(
171
- InternationalizedArrayContext.Provider,
172
- {
173
- value: {
174
- ...internationalizedArray2,
175
- languages,
176
- filteredLanguages
177
- },
178
- children: showDocumentButtons ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 5, children: [
179
- /* @__PURE__ */ jsxRuntime.jsx(DocumentAddButtons, { value: props.value }),
180
- props.renderDefault(props)
181
- ] }) : props.renderDefault(props)
182
- }
168
+ }, [deferredDocument, languageFilterOptions, languages, selectedLanguageIds]), showDocumentButtons = internationalizedArray2.buttonLocations.includes("document"), context = react.useMemo(
169
+ () => ({ ...internationalizedArray2, languages, filteredLanguages }),
170
+ [filteredLanguages, internationalizedArray2, languages]
183
171
  );
172
+ return /* @__PURE__ */ jsxRuntime.jsx(InternationalizedArrayContext.Provider, { value: context, children: showDocumentButtons ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 5, children: [
173
+ /* @__PURE__ */ jsxRuntime.jsx(DocumentAddButtons, { value: props.value }),
174
+ props.renderDefault(props)
175
+ ] }) : props.renderDefault(props) });
184
176
  }
185
177
  var Preload = react.memo(function(props) {
186
178
  const client = sanity.useClient({ apiVersion: props.apiVersion });
@@ -193,7 +185,7 @@ function checkAllLanguagesArePresent(languages, value) {
193
185
  return languagesInUseIds.length === filteredLanguageIds.length && languagesInUseIds.every((l) => filteredLanguageIds.includes(l));
194
186
  }
195
187
  function createAddAllTitle(value, languages) {
196
- 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";
188
+ return value?.length ? `Add missing ${languages.length - value.length === 1 ? "language" : "languages"}` : languages.length === 1 ? `Add ${languages[0].title} Field` : "Add all languages";
197
189
  }
198
190
  function createValueSchemaTypeName(schemaType) {
199
191
  return `${schemaType.name}Value`;
@@ -210,11 +202,11 @@ function createAddLanguagePatches(config) {
210
202
  ...itemBase,
211
203
  _key: id
212
204
  })) : filteredLanguages.filter(
213
- (language) => value != null && value.length ? !value.find((v) => v._key === language.id) : !0
205
+ (language) => value?.length ? !value.find((v) => v._key === language.id) : !0
214
206
  ).map((language) => ({
215
207
  ...itemBase,
216
208
  _key: language.id
217
- })), languagesInUse = value != null && value.length ? value.map((v) => v) : [];
209
+ })), languagesInUse = value?.length ? value.map((v) => v) : [];
218
210
  return newItems.map((item) => {
219
211
  const languageIndex = languages.findIndex((l) => item._key === l.id), remainingLanguages = languages.slice(languageIndex + 1), nextLanguageIndex = languagesInUse.findIndex(
220
212
  (l) => (
@@ -232,7 +224,7 @@ function createAddLanguagePatches(config) {
232
224
  });
233
225
  }
234
226
  const createTranslateFieldActions = (fieldActionProps, { languages, filteredLanguages }) => languages.map((language) => {
235
- 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(() => {
227
+ const value = sanity.useFormValue(fieldActionProps.path), disabled = value && Array.isArray(value) ? !!value?.find((item) => item._key === language.id) : !1, hidden = !filteredLanguages.some((f) => f.id === language.id), { onChange } = structure.useDocumentPane(), onAction = react.useCallback(() => {
236
228
  const { schemaType, path } = fieldActionProps, addLanguageKeys = [language.id], patches = createAddLanguagePatches({
237
229
  addLanguageKeys,
238
230
  schemaType,
@@ -274,8 +266,7 @@ const createTranslateFieldActions = (fieldActionProps, { languages, filteredLang
274
266
  }, internationalizedArrayFieldAction = sanity.defineDocumentFieldAction({
275
267
  name: "internationalizedArray",
276
268
  useAction(fieldActionProps) {
277
- var _a, _b;
278
- const isInternationalizedArrayField = (_b = (_a = fieldActionProps == null ? void 0 : fieldActionProps.schemaType) == null ? void 0 : _a.type) == null ? void 0 : _b.name.startsWith(
269
+ const isInternationalizedArrayField = fieldActionProps?.schemaType?.type?.name.startsWith(
279
270
  "internationalizedArray"
280
271
  ), { languages, filteredLanguages } = useInternationalizedArrayContext(), translateFieldActions = createTranslateFieldActions(
281
272
  fieldActionProps,
@@ -352,10 +343,9 @@ function InternationalizedArray(props) {
352
343
  [languageFilterEnabled, members, languageFilterOptions, selectedLanguageIds]
353
344
  ), handleAddLanguage = react.useCallback(
354
345
  async (param) => {
355
- var _a;
356
- if (!(filteredLanguages != null && filteredLanguages.length))
346
+ if (!filteredLanguages?.length)
357
347
  return;
358
- const addLanguageKeys = Array.isArray(param) ? param : [(_a = param == null ? void 0 : param.currentTarget) == null ? void 0 : _a.value].filter(Boolean), patches = createAddLanguagePatches({
348
+ const addLanguageKeys = Array.isArray(param) ? param : [param?.currentTarget?.value].filter(Boolean), patches = createAddLanguagePatches({
359
349
  addLanguageKeys,
360
350
  schemaType,
361
351
  languages,
@@ -373,23 +363,23 @@ function InternationalizedArray(props) {
373
363
  };
374
364
  }, [defaultLanguages, documentCreatedAt, handleAddLanguage, value]);
375
365
  const handleRestoreOrder = react.useCallback(() => {
376
- if (!(value != null && value.length) || !(languages != null && languages.length))
366
+ if (!value?.length || !languages?.length)
377
367
  return;
378
368
  const updatedValue = value.reduce((acc, v) => {
379
- const newIndex = languages.findIndex((l) => l.id === (v == null ? void 0 : v._key));
369
+ const newIndex = languages.findIndex((l) => l.id === v?._key);
380
370
  return newIndex > -1 && (acc[newIndex] = v), acc;
381
371
  }, []).filter(Boolean);
382
- (value == null ? void 0 : value.length) !== updatedValue.length && toast.push({
372
+ value?.length !== updatedValue.length && toast.push({
383
373
  title: "There was an error reordering languages",
384
374
  status: "warning"
385
375
  }), onChange(sanity.set(updatedValue));
386
- }, [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(
387
- () => languages && languages.length > 1 ? languages.filter((l) => value == null ? void 0 : value.find((v) => v._key === l.id)) : [],
376
+ }, [toast, languages, onChange, value]), allKeysAreLanguages = react.useMemo(() => !value?.length || !languages?.length ? !0 : value?.every((v) => languages.find((l) => l?.id === v?._key)), [value, languages]), languagesInUse = react.useMemo(
377
+ () => languages && languages.length > 1 ? languages.filter((l) => value?.find((v) => v._key === l.id)) : [],
388
378
  [languages, value]
389
- ), languagesOutOfOrder = react.useMemo(() => !(value != null && value.length) || !languagesInUse.length ? [] : value.map(
379
+ ), languagesOutOfOrder = react.useMemo(() => !value?.length || !languagesInUse.length ? [] : value.map(
390
380
  (v, vIndex) => vIndex === languagesInUse.findIndex((l) => l.id === v._key) ? null : v
391
381
  ).filter(Boolean), [value, languagesInUse]), languagesAreValid = react.useMemo(
392
- () => !(languages != null && languages.length) || (languages == null ? void 0 : languages.length) && languages.every((item) => item.id && item.title),
382
+ () => !languages?.length || languages?.length && languages.every((item) => item.id && item.title),
393
383
  [languages]
394
384
  );
395
385
  react.useEffect(() => {
@@ -404,9 +394,9 @@ function InternationalizedArray(props) {
404
394
  const addButtonsAreVisible = (
405
395
  // Plugin was configured to display buttons here (default!)
406
396
  buttonLocations.includes("field") && // There's at least one language visible
407
- (filteredLanguages == null ? void 0 : filteredLanguages.length) > 0 && // Not every language has a value yet
397
+ filteredLanguages?.length > 0 && // Not every language has a value yet
408
398
  !allLanguagesArePresent
409
- ), fieldHasMembers = (members == null ? void 0 : members.length) > 0;
399
+ ), fieldHasMembers = members?.length > 0;
410
400
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 2, children: [
411
401
  fieldHasMembers ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: filteredMembers.map((member) => member.kind === "item" ? /* @__PURE__ */ react.createElement(
412
402
  sanity.ArrayOfObjectsItem,
@@ -419,7 +409,7 @@ function InternationalizedArray(props) {
419
409
  !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,
420
410
  addButtonsAreVisible ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 2, children: [
421
411
  /* @__PURE__ */ jsxRuntime.jsx(
422
- AddButtons,
412
+ AddButtons$1,
423
413
  {
424
414
  languages: filteredLanguages,
425
415
  value,
@@ -442,8 +432,7 @@ function InternationalizedArray(props) {
442
432
  ] });
443
433
  }
444
434
  function getLanguagesFieldOption(schemaType) {
445
- var _a;
446
- return schemaType ? ((_a = schemaType.options) == null ? void 0 : _a.languages) || getLanguagesFieldOption(schemaType.type) : void 0;
435
+ return schemaType ? schemaType.options?.languages || getLanguagesFieldOption(schemaType.type) : void 0;
447
436
  }
448
437
  var array = (config) => {
449
438
  const { apiVersion, select, languages, type } = config, typeName = typeof type == "string" ? type : type.name, arrayName = createFieldName(typeName), objectName = createFieldName(typeName, !0);
@@ -454,8 +443,12 @@ var array = (config) => {
454
443
  components: {
455
444
  input: InternationalizedArray
456
445
  },
457
- // These options are required for validation rules – not the custom input component
458
- options: { apiVersion, select, languages },
446
+ options: {
447
+ // @ts-expect-error - these options are required for validation rules – not the custom input component
448
+ apiVersion,
449
+ select,
450
+ languages
451
+ },
459
452
  of: [
460
453
  sanity.defineField({
461
454
  ...typeof type == "string" ? {} : type,
@@ -463,15 +456,16 @@ var array = (config) => {
463
456
  type: objectName
464
457
  })
465
458
  ],
459
+ // @ts-expect-error - fix typings
466
460
  validation: (rule) => rule.custom(async (value, context) => {
467
461
  if (!value)
468
462
  return !0;
469
463
  const selectedValue = getSelectedValue(select, context.document), client = context.getClient({ apiVersion });
470
464
  let contextLanguages = [];
471
- const languagesFieldOption = getLanguagesFieldOption(context == null ? void 0 : context.type);
465
+ const languagesFieldOption = getLanguagesFieldOption(context?.type);
472
466
  if (Array.isArray(languagesFieldOption) ? contextLanguages = languagesFieldOption : Array.isArray(peek(selectedValue)) ? contextLanguages = peek(selectedValue) || [] : typeof languagesFieldOption == "function" && (contextLanguages = await languagesFieldOption(client, selectedValue)), value && value.length > contextLanguages.length)
473
467
  return `Cannot be more than ${contextLanguages.length === 1 ? "1 item" : `${contextLanguages.length} items`}`;
474
- const nonLanguageKeys = value != null && value.length ? value.filter(
468
+ const nonLanguageKeys = value?.length ? value.filter(
475
469
  (item) => !contextLanguages.find((language) => item._key === language.id)
476
470
  ) : [];
477
471
  if (nonLanguageKeys.length)
@@ -479,10 +473,10 @@ var array = (config) => {
479
473
  message: "Array item keys must be valid languages registered to the field type",
480
474
  paths: nonLanguageKeys.map((item) => [{ _key: item._key }])
481
475
  };
482
- const valuesByLanguage = value != null && value.length ? value.filter((item) => !!(item != null && item._key)).reduce((acc, cur) => acc[cur._key] ? { ...acc, [cur._key]: [...acc[cur._key], cur] } : {
476
+ const valuesByLanguage = value?.length ? value.filter((item) => !!item?._key).reduce((acc, cur) => acc[cur._key] ? { ...acc, [cur._key]: [...acc[cur._key], cur] } : {
483
477
  ...acc,
484
478
  [cur._key]: [cur]
485
- }, {}) : {}, duplicateValues = Object.values(valuesByLanguage).filter((item) => (item == null ? void 0 : item.length) > 1).flat();
479
+ }, {}) : {}, duplicateValues = Object.values(valuesByLanguage).filter((item) => item?.length > 1).flat();
486
480
  return duplicateValues.length ? {
487
481
  message: "There can only be one field per language",
488
482
  paths: duplicateValues.map((item) => [{ _key: item._key }])
@@ -498,7 +492,7 @@ function InternationalizedField(props) {
498
492
  }) : props.children;
499
493
  }
500
494
  function getToneFromValidation(validations) {
501
- if (!(validations != null && validations.length))
495
+ if (!validations?.length)
502
496
  return;
503
497
  const validationLevels = validations.map((v) => v.level);
504
498
  if (validationLevels.includes("error"))
@@ -519,16 +513,12 @@ function InternationalizedInput(props) {
519
513
  // TODO: Remove this as it shouldn't be necessary?
520
514
  value: props.value
521
515
  }, { validation, value, onChange, readOnly } = inlineProps, { languages } = useInternationalizedArrayContext(), languageKeysInUse = react.useMemo(
522
- () => {
523
- var _a;
524
- return (_a = parentValue == null ? void 0 : parentValue.map((v) => v._key)) != null ? _a : [];
525
- },
516
+ () => parentValue?.map((v) => v._key) ?? [],
526
517
  [parentValue]
527
- ), keyIsValid = languages != null && languages.length ? languages.find((l) => l.id === value._key) : !1, handleKeyChange = react.useCallback(
518
+ ), keyIsValid = languages?.length ? languages.find((l) => l.id === value._key) : !1, handleKeyChange = react.useCallback(
528
519
  (event) => {
529
- var _a;
530
- const languageId = (_a = event == null ? void 0 : event.currentTarget) == null ? void 0 : _a.value;
531
- !value || !(languages != null && languages.length) || !languages.find((l) => l.id === languageId) || onChange([sanity.set(languageId, ["_key"])]);
520
+ const languageId = event?.currentTarget?.value;
521
+ !value || !languages?.length || !languages.find((l) => l.id === languageId) || onChange([sanity.set(languageId, ["_key"])]);
532
522
  },
533
523
  [onChange, value, languages]
534
524
  ), handleUnset = react.useCallback(() => {
@@ -576,9 +566,9 @@ var object = (config) => {
576
566
  title: `Internationalized array ${type}`,
577
567
  type: "object",
578
568
  components: {
569
+ // @ts-expect-error - fix typings
579
570
  item: InternationalizedInput
580
571
  },
581
- // @ts-expect-error - Address this typing issue with the inner object
582
572
  fields: [
583
573
  typeof type == "string" ? (
584
574
  // Define a simple field if all we have is the name as a string
@@ -664,10 +654,13 @@ const internationalizedArray = sanity.definePlugin((config) => {
664
654
  (field) => field.type.name
665
655
  ).some(
666
656
  (name) => name.startsWith("internationalizedArray")
667
- ) ? props.renderDefault(props) : InternationalizedArrayProvider({
668
- ...props,
669
- internationalizedArray: pluginConfig
670
- })
657
+ ) ? props.renderDefault(props) : /* @__PURE__ */ jsxRuntime.jsx(
658
+ InternationalizedArrayProvider,
659
+ {
660
+ ...props,
661
+ internationalizedArray: pluginConfig
662
+ }
663
+ )
671
664
  }
672
665
  },
673
666
  // Register custom schema types for the outer array and the inner object