sanity-plugin-internationalized-array 1.5.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +26 -0
- package/lib/{src/index.d.ts → index.d.ts} +29 -4
- package/lib/index.esm.js +9489 -1
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +9489 -1
- package/lib/index.js.map +1 -1
- package/package.json +48 -33
- package/src/cache.ts +3 -1
- package/src/components/InternationalizedArray.tsx +48 -22
- package/src/components/Preload.tsx +2 -2
- package/src/components/Table.tsx +1 -1
- package/src/components/getSelectedValue.ts +31 -0
- package/src/components/getToneFromValidation.ts +3 -1
- package/src/plugin.tsx +2 -2
- package/src/schema/array.ts +23 -15
- package/src/schema/object.ts +2 -8
- package/src/types.ts +29 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sanity-plugin-internationalized-array",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "Store localized fields in an array to save on attributes",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
"url": "git@github.com:SimeonGriggs/sanity-plugin-internationalized-array.git"
|
|
16
16
|
},
|
|
17
17
|
"license": "MIT",
|
|
18
|
-
"author": "
|
|
18
|
+
"author": "Sanity.io <hello@sanity.io>",
|
|
19
19
|
"exports": {
|
|
20
20
|
".": {
|
|
21
|
-
"types": "./lib/
|
|
21
|
+
"types": "./lib/index.d.ts",
|
|
22
22
|
"source": "./src/index.ts",
|
|
23
|
-
"import": "./lib/index.esm.js",
|
|
24
23
|
"require": "./lib/index.js",
|
|
24
|
+
"import": "./lib/index.esm.js",
|
|
25
25
|
"default": "./lib/index.esm.js"
|
|
26
26
|
},
|
|
27
27
|
"./package.json": "./package.json"
|
|
@@ -29,60 +29,75 @@
|
|
|
29
29
|
"main": "./lib/index.js",
|
|
30
30
|
"module": "./lib/index.esm.js",
|
|
31
31
|
"source": "./src/index.ts",
|
|
32
|
-
"types": "./lib/
|
|
32
|
+
"types": "./lib/index.d.ts",
|
|
33
33
|
"files": [
|
|
34
|
-
"src",
|
|
35
34
|
"lib",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
35
|
+
"sanity.json",
|
|
36
|
+
"src",
|
|
37
|
+
"v2-incompatible.js"
|
|
38
38
|
],
|
|
39
39
|
"scripts": {
|
|
40
40
|
"prebuild": "npm run clean && plugin-kit verify-package --silent && pkg-utils",
|
|
41
|
-
"build": "pkg-utils build",
|
|
41
|
+
"build": "run-s clean && plugin-kit verify-package --silent && pkg-utils build --strict && pkg-utils --strict",
|
|
42
42
|
"clean": "rimraf lib",
|
|
43
|
+
"format": "prettier --write --cache --ignore-unknown .",
|
|
43
44
|
"link-watch": "plugin-kit link-watch",
|
|
44
45
|
"lint": "eslint .",
|
|
46
|
+
"lint:fix": "eslint . --fix",
|
|
45
47
|
"prepare": "husky install",
|
|
46
|
-
"prepublishOnly": "
|
|
47
|
-
"watch": "pkg-utils watch"
|
|
48
|
+
"prepublishOnly": "run-s build",
|
|
49
|
+
"watch": "pkg-utils watch --strict"
|
|
48
50
|
},
|
|
49
51
|
"dependencies": {
|
|
50
|
-
"@sanity/icons": "^2.
|
|
52
|
+
"@sanity/icons": "^2.2.2",
|
|
51
53
|
"@sanity/incompatible-plugin": "^1.0.4",
|
|
52
|
-
"@sanity/ui": "^1.
|
|
54
|
+
"@sanity/ui": "^1.2.2",
|
|
55
|
+
"fast-deep-equal": "^3.1.3",
|
|
56
|
+
"lodash.get": "^4.4.2",
|
|
53
57
|
"suspend-react": "^0.0.8"
|
|
54
58
|
},
|
|
55
59
|
"devDependencies": {
|
|
56
|
-
"@commitlint/cli": "^17.
|
|
57
|
-
"@commitlint/config-conventional": "^17.
|
|
58
|
-
"@sanity/pkg-utils": "^
|
|
59
|
-
"@sanity/plugin-kit": "^
|
|
60
|
-
"@sanity/semantic-release-preset": "^
|
|
60
|
+
"@commitlint/cli": "^17.4.4",
|
|
61
|
+
"@commitlint/config-conventional": "^17.4.4",
|
|
62
|
+
"@sanity/pkg-utils": "^2.2.4",
|
|
63
|
+
"@sanity/plugin-kit": "^3.1.4",
|
|
64
|
+
"@sanity/semantic-release-preset": "^4.0.1",
|
|
65
|
+
"@types/react": "^18.0.27",
|
|
61
66
|
"@types/styled-components": "^5.1.26",
|
|
62
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
63
|
-
"@typescript-eslint/parser": "^5.
|
|
64
|
-
"eslint": "^8.
|
|
65
|
-
"eslint-config-prettier": "^8.
|
|
67
|
+
"@typescript-eslint/eslint-plugin": "^5.51.0",
|
|
68
|
+
"@typescript-eslint/parser": "^5.51.0",
|
|
69
|
+
"eslint": "^8.33.0",
|
|
70
|
+
"eslint-config-prettier": "^8.6.0",
|
|
66
71
|
"eslint-config-sanity": "^6.0.0",
|
|
67
72
|
"eslint-plugin-prettier": "^4.2.1",
|
|
68
|
-
"eslint-plugin-react": "^7.
|
|
73
|
+
"eslint-plugin-react": "^7.32.2",
|
|
69
74
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
75
|
+
"eslint-plugin-simple-import-sort": "^10.0.0",
|
|
76
|
+
"husky": "^8.0.3",
|
|
77
|
+
"lint-staged": "^13.2.0",
|
|
78
|
+
"npm-run-all": "^4.1.5",
|
|
79
|
+
"prettier": "^2.8.4",
|
|
80
|
+
"prettier-plugin-packagejson": "^2.4.2",
|
|
74
81
|
"react": "^18",
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
82
|
+
"react-dom": "^18",
|
|
83
|
+
"react-is": "^18",
|
|
84
|
+
"rimraf": "^4.1.2",
|
|
85
|
+
"sanity": "^3.3.1",
|
|
86
|
+
"semantic-release": "^20.1.0",
|
|
87
|
+
"typescript": "^4.9.5"
|
|
79
88
|
},
|
|
80
89
|
"peerDependencies": {
|
|
90
|
+
"@sanity/ui": "^1.2.2",
|
|
81
91
|
"react": "^18",
|
|
82
|
-
"sanity": "
|
|
83
|
-
"styled-components": "^5.
|
|
92
|
+
"sanity": "^3.0.0",
|
|
93
|
+
"styled-components": "^5.3.6"
|
|
84
94
|
},
|
|
85
95
|
"engines": {
|
|
86
96
|
"node": ">=14"
|
|
97
|
+
},
|
|
98
|
+
"sanityPlugin": {
|
|
99
|
+
"verifyPackage": {
|
|
100
|
+
"eslintImports": false
|
|
101
|
+
}
|
|
87
102
|
}
|
|
88
103
|
}
|
package/src/cache.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
2
2
|
|
|
3
3
|
import * as suspend from 'suspend-react'
|
|
4
|
+
|
|
4
5
|
import type {Language} from './types'
|
|
5
6
|
|
|
6
7
|
export const namespace = 'sanity-plugin-internationalized-array'
|
|
@@ -15,4 +16,5 @@ export const preload = (fn: () => Promise<Language[]>) =>
|
|
|
15
16
|
export const clear = () => suspend.clear([version, namespace])
|
|
16
17
|
|
|
17
18
|
// https://github.com/pmndrs/suspend-react#peeking-into-entries-outside-of-suspense
|
|
18
|
-
export const peek = (
|
|
19
|
+
export const peek = (selectedValue: Record<string, unknown>) =>
|
|
20
|
+
suspend.peek([version, namespace, selectedValue]) as Language[] | undefined
|
|
@@ -1,45 +1,61 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {AddIcon} from '@sanity/icons'
|
|
2
|
+
import {Button, Grid, Stack, useToast} from '@sanity/ui'
|
|
3
|
+
import equal from 'fast-deep-equal'
|
|
4
|
+
import {useCallback, useDeferredValue, useEffect, useMemo} from 'react'
|
|
2
5
|
import {
|
|
6
|
+
ArrayOfObjectsInputProps,
|
|
7
|
+
ArrayOfObjectsItem,
|
|
8
|
+
ArrayOfObjectsItemMember,
|
|
3
9
|
insert,
|
|
4
10
|
set,
|
|
5
11
|
setIfMissing,
|
|
6
|
-
ArrayOfObjectsItemMember,
|
|
7
|
-
ArrayOfObjectsItem,
|
|
8
|
-
ArrayOfObjectsInputProps,
|
|
9
12
|
useClient,
|
|
13
|
+
useFormBuilder,
|
|
10
14
|
} from 'sanity'
|
|
11
|
-
import {Button, Grid, Stack, useToast} from '@sanity/ui'
|
|
12
|
-
import {AddIcon} from '@sanity/icons'
|
|
13
15
|
import {suspend} from 'suspend-react'
|
|
14
16
|
|
|
15
|
-
import
|
|
17
|
+
import {namespace, version} from '../cache'
|
|
18
|
+
import type {ArraySchemaWithLanguageOptions, Value} from '../types'
|
|
16
19
|
import Feedback from './Feedback'
|
|
20
|
+
import {getSelectedValue} from './getSelectedValue'
|
|
17
21
|
// TODO: Move this provider to the root component
|
|
18
22
|
import {LanguageProvider} from './languageContext'
|
|
19
|
-
import {namespace, version} from '../cache'
|
|
20
23
|
|
|
21
24
|
export type InternationalizedArrayProps = ArrayOfObjectsInputProps<
|
|
22
25
|
Value,
|
|
23
26
|
ArraySchemaWithLanguageOptions
|
|
24
27
|
>
|
|
25
28
|
|
|
26
|
-
export default function InternationalizedArray(
|
|
29
|
+
export default function InternationalizedArray(
|
|
30
|
+
props: InternationalizedArrayProps
|
|
31
|
+
) {
|
|
27
32
|
const {members, value, schemaType, onChange} = props
|
|
28
|
-
const readOnly =
|
|
33
|
+
const readOnly =
|
|
34
|
+
typeof schemaType.readOnly === 'boolean' ? schemaType.readOnly : false
|
|
29
35
|
const {options} = schemaType
|
|
30
36
|
const toast = useToast()
|
|
37
|
+
const {value: document} = useFormBuilder()
|
|
38
|
+
const deferredDocument = useDeferredValue(document)
|
|
39
|
+
const selectedValue = useMemo(
|
|
40
|
+
() => getSelectedValue(options.select, deferredDocument),
|
|
41
|
+
[options.select, deferredDocument]
|
|
42
|
+
)
|
|
31
43
|
|
|
32
44
|
const {apiVersion} = options
|
|
33
45
|
const client = useClient({apiVersion})
|
|
34
46
|
const languages = Array.isArray(options.languages)
|
|
35
47
|
? options.languages
|
|
36
|
-
:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
48
|
+
: suspend(
|
|
49
|
+
// eslint-disable-next-line require-await
|
|
50
|
+
async () => {
|
|
51
|
+
if (typeof options.languages === 'function') {
|
|
52
|
+
return options.languages(client, selectedValue)
|
|
53
|
+
}
|
|
54
|
+
return options.languages
|
|
55
|
+
},
|
|
56
|
+
[version, namespace, selectedValue],
|
|
57
|
+
{equal}
|
|
58
|
+
)
|
|
43
59
|
|
|
44
60
|
const handleAddLanguage = useCallback(
|
|
45
61
|
(languageId?: string) => {
|
|
@@ -148,13 +164,16 @@ export default function InternationalizedArray(props: InternationalizedArrayProp
|
|
|
148
164
|
}
|
|
149
165
|
|
|
150
166
|
return value
|
|
151
|
-
.map((v, vIndex) =>
|
|
167
|
+
.map((v, vIndex) =>
|
|
168
|
+
vIndex === languagesInUse.findIndex((l) => l.id === v._key) ? null : v
|
|
169
|
+
)
|
|
152
170
|
.filter(Boolean)
|
|
153
171
|
}, [value, languagesInUse])
|
|
154
172
|
|
|
155
173
|
const languagesAreValid = useMemo(
|
|
156
174
|
() =>
|
|
157
|
-
!languages?.length ||
|
|
175
|
+
!languages?.length ||
|
|
176
|
+
(languages?.length && languages.every((item) => item.id && item.title)),
|
|
158
177
|
[languages]
|
|
159
178
|
)
|
|
160
179
|
|
|
@@ -218,7 +237,10 @@ export default function InternationalizedArray(props: InternationalizedArrayProp
|
|
|
218
237
|
tone="primary"
|
|
219
238
|
mode="ghost"
|
|
220
239
|
fontSize={1}
|
|
221
|
-
disabled={
|
|
240
|
+
disabled={
|
|
241
|
+
readOnly ||
|
|
242
|
+
Boolean(value?.find((item) => item._key === language.id))
|
|
243
|
+
}
|
|
222
244
|
text={language.id.toUpperCase()}
|
|
223
245
|
icon={AddIcon}
|
|
224
246
|
onClick={() => handleAddLanguage(language.id)}
|
|
@@ -229,13 +251,17 @@ export default function InternationalizedArray(props: InternationalizedArrayProp
|
|
|
229
251
|
<Button
|
|
230
252
|
tone="primary"
|
|
231
253
|
mode="ghost"
|
|
232
|
-
disabled={
|
|
254
|
+
disabled={
|
|
255
|
+
readOnly || (value && value?.length >= languages?.length)
|
|
256
|
+
}
|
|
233
257
|
icon={AddIcon}
|
|
234
258
|
text={
|
|
235
259
|
// eslint-disable-next-line no-nested-ternary
|
|
236
260
|
value?.length
|
|
237
261
|
? `Add missing ${
|
|
238
|
-
languages.length - value.length === 1
|
|
262
|
+
languages.length - value.length === 1
|
|
263
|
+
? `language`
|
|
264
|
+
: `languages`
|
|
239
265
|
}`
|
|
240
266
|
: languages.length === 1
|
|
241
267
|
? `Add ${languages[0].title} Field`
|
|
@@ -7,10 +7,10 @@ export default memo(function Preload(
|
|
|
7
7
|
props: Required<Pick<PluginConfig, 'apiVersion' | 'languages'>>
|
|
8
8
|
) {
|
|
9
9
|
const client = useClient({apiVersion: props.apiVersion})
|
|
10
|
-
if (!Array.isArray(peek())) {
|
|
10
|
+
if (!Array.isArray(peek({}))) {
|
|
11
11
|
// eslint-disable-next-line require-await
|
|
12
12
|
preload(async () =>
|
|
13
|
-
Array.isArray(props.languages) ? props.languages : props.languages(client)
|
|
13
|
+
Array.isArray(props.languages) ? props.languages : props.languages(client, {})
|
|
14
14
|
)
|
|
15
15
|
}
|
|
16
16
|
|
package/src/components/Table.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import {Box, BoxProps, Card, CardProps} from '@sanity/ui'
|
|
1
2
|
import React from 'react'
|
|
2
3
|
import styled, {css} from 'styled-components'
|
|
3
|
-
import {Box, BoxProps, Card, CardProps} from '@sanity/ui'
|
|
4
4
|
|
|
5
5
|
// Wrappers required because of bug with passing down "as" prop
|
|
6
6
|
// https://github.com/styled-components/styled-components/issues/2449
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {get} from 'lodash'
|
|
2
|
+
|
|
3
|
+
export const getSelectedValue = (
|
|
4
|
+
select: Record<string, string> | undefined,
|
|
5
|
+
document:
|
|
6
|
+
| {
|
|
7
|
+
[x: string]: unknown
|
|
8
|
+
}
|
|
9
|
+
| undefined
|
|
10
|
+
): Record<string, unknown> => {
|
|
11
|
+
if (!select || !document) {
|
|
12
|
+
return {}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const selection: Record<string, string> = select || {}
|
|
16
|
+
const selectedValue: Record<string, unknown> = {}
|
|
17
|
+
for (const [key, path] of Object.entries(selection)) {
|
|
18
|
+
let value = get(document, path)
|
|
19
|
+
if (Array.isArray(value)) {
|
|
20
|
+
// If there are references in the array, ensure they have `_ref` set, otherwise they are considered empty and can safely be ignored
|
|
21
|
+
value = value.filter((item) =>
|
|
22
|
+
typeof item === 'object'
|
|
23
|
+
? item?._type === 'reference' && '_ref' in item
|
|
24
|
+
: true
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
selectedValue[key] = value
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return selectedValue
|
|
31
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {CardTone} from '@sanity/ui'
|
|
2
2
|
import {FormNodeValidation} from 'sanity'
|
|
3
3
|
|
|
4
|
-
export function getToneFromValidation(
|
|
4
|
+
export function getToneFromValidation(
|
|
5
|
+
validations: FormNodeValidation[]
|
|
6
|
+
): CardTone | undefined {
|
|
5
7
|
if (!validations?.length) {
|
|
6
8
|
return undefined
|
|
7
9
|
}
|
package/src/plugin.tsx
CHANGED
|
@@ -11,7 +11,7 @@ const CONFIG_DEFAULT: PluginConfig = {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export const internationalizedArray = definePlugin<PluginConfig>((config = CONFIG_DEFAULT) => {
|
|
14
|
-
const {apiVersion = '2022-11-27', languages, fieldTypes} = {...CONFIG_DEFAULT, ...config}
|
|
14
|
+
const {apiVersion = '2022-11-27', select, languages, fieldTypes} = {...CONFIG_DEFAULT, ...config}
|
|
15
15
|
|
|
16
16
|
return {
|
|
17
17
|
name: 'sanity-plugin-internationalized-array',
|
|
@@ -30,7 +30,7 @@ export const internationalizedArray = definePlugin<PluginConfig>((config = CONFI
|
|
|
30
30
|
},
|
|
31
31
|
schema: {
|
|
32
32
|
types: [
|
|
33
|
-
...fieldTypes.map((type) => array({type, apiVersion, languages})),
|
|
33
|
+
...fieldTypes.map((type) => array({type, apiVersion, select, languages})),
|
|
34
34
|
...fieldTypes.map((type) => object({type})),
|
|
35
35
|
],
|
|
36
36
|
},
|
package/src/schema/array.ts
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
/* eslint-disable no-nested-ternary */
|
|
2
|
-
import {defineField, type FieldDefinition, type Rule
|
|
3
|
-
import {peek} from '../cache'
|
|
2
|
+
import {defineField, type FieldDefinition, type Rule} from 'sanity'
|
|
4
3
|
|
|
4
|
+
import {peek} from '../cache'
|
|
5
5
|
import {createFieldName} from '../components/createFieldName'
|
|
6
|
+
import {getSelectedValue} from '../components/getSelectedValue'
|
|
6
7
|
import InternationalizedArray from '../components/InternationalizedArray'
|
|
7
|
-
import {Language, Value} from '../types'
|
|
8
|
+
import {Language, LanguageCallback, Value} from '../types'
|
|
8
9
|
|
|
9
10
|
type ArrayFactoryConfig = {
|
|
10
11
|
apiVersion: string
|
|
11
|
-
|
|
12
|
+
select?: Record<string, string>
|
|
13
|
+
languages: Language[] | LanguageCallback
|
|
12
14
|
type: string | FieldDefinition
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
export default (config: ArrayFactoryConfig): FieldDefinition<'array'> => {
|
|
16
|
-
const {apiVersion, languages, type} = config
|
|
18
|
+
const {apiVersion, select, languages, type} = config
|
|
17
19
|
const typeName = typeof type === `string` ? type : type.name
|
|
18
20
|
const arrayName = createFieldName(typeName)
|
|
19
21
|
const objectName = createFieldName(typeName, true)
|
|
@@ -22,14 +24,12 @@ export default (config: ArrayFactoryConfig): FieldDefinition<'array'> => {
|
|
|
22
24
|
name: arrayName,
|
|
23
25
|
title: 'Internationalized array',
|
|
24
26
|
type: 'array',
|
|
25
|
-
// TODO: Resolve this typing issue with the outer component
|
|
26
|
-
// @ts-ignore
|
|
27
27
|
components: {
|
|
28
28
|
input: InternationalizedArray,
|
|
29
29
|
},
|
|
30
|
-
options: {apiVersion, languages},
|
|
30
|
+
options: {apiVersion, select, languages},
|
|
31
31
|
// TODO: Resolve this typing issue with the inner object
|
|
32
|
-
// @ts-
|
|
32
|
+
// @ts-expect-error
|
|
33
33
|
of: [
|
|
34
34
|
defineField({
|
|
35
35
|
...(typeof type === 'string' ? {} : type),
|
|
@@ -43,21 +43,29 @@ export default (config: ArrayFactoryConfig): FieldDefinition<'array'> => {
|
|
|
43
43
|
return true
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
const selectedValue = getSelectedValue(select, context.document)
|
|
46
47
|
const client = context.getClient({apiVersion})
|
|
47
|
-
const contextLanguages: Language[] = Array.isArray(
|
|
48
|
+
const contextLanguages: Language[] = Array.isArray(
|
|
49
|
+
context?.type?.options?.languages
|
|
50
|
+
)
|
|
48
51
|
? context!.type!.options.languages
|
|
49
|
-
: Array.isArray(peek())
|
|
50
|
-
? peek()
|
|
51
|
-
: await context?.type?.options.languages(client)
|
|
52
|
+
: Array.isArray(peek(selectedValue))
|
|
53
|
+
? peek(selectedValue)
|
|
54
|
+
: await context?.type?.options.languages(client, selectedValue)
|
|
52
55
|
|
|
53
56
|
if (value && value.length > contextLanguages.length) {
|
|
54
57
|
return `Cannot be more than ${
|
|
55
|
-
contextLanguages.length === 1
|
|
58
|
+
contextLanguages.length === 1
|
|
59
|
+
? `1 item`
|
|
60
|
+
: `${contextLanguages.length} items`
|
|
56
61
|
}`
|
|
57
62
|
}
|
|
58
63
|
|
|
59
64
|
const nonLanguageKeys = value?.length
|
|
60
|
-
? value.filter(
|
|
65
|
+
? value.filter(
|
|
66
|
+
(item) =>
|
|
67
|
+
!contextLanguages.find((language) => item._key === language.id)
|
|
68
|
+
)
|
|
61
69
|
: []
|
|
62
70
|
if (nonLanguageKeys.length) {
|
|
63
71
|
return {
|
package/src/schema/object.ts
CHANGED
|
@@ -17,26 +17,20 @@ export default (config: ObjectFactoryConfig): FieldDefinition<'object'> => {
|
|
|
17
17
|
name: objectName,
|
|
18
18
|
title: `Internationalized array ${type}`,
|
|
19
19
|
type: 'object',
|
|
20
|
-
// TODO: Resolve this typing issue with the return type
|
|
21
|
-
// @ts-ignore
|
|
22
20
|
components: {
|
|
23
|
-
// TODO: Resolve this typing issue with the outer component
|
|
24
|
-
// @ts-ignore
|
|
25
21
|
item: InternationalizedInput,
|
|
26
22
|
},
|
|
27
23
|
// TODO: Address this typing issue with the inner object
|
|
28
|
-
// @ts-
|
|
24
|
+
// @ts-expect-error
|
|
29
25
|
fields: [
|
|
30
26
|
typeof type === `string`
|
|
31
27
|
? // Define a simple field if all we have is the name as a string
|
|
32
28
|
defineField({
|
|
33
29
|
name: 'value',
|
|
34
30
|
type,
|
|
35
|
-
// TODO: Address this typing issue with components on a dynamic `type`
|
|
36
|
-
// @ts-ignore
|
|
37
31
|
components: {
|
|
38
32
|
// TODO: Address this typing issue with the inner object
|
|
39
|
-
// @ts-
|
|
33
|
+
// @ts-expect-error
|
|
40
34
|
field: InternationalizedField,
|
|
41
35
|
},
|
|
42
36
|
})
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
ArraySchemaType,
|
|
3
|
+
FieldDefinition,
|
|
4
|
+
Rule,
|
|
5
|
+
RuleTypeConstraint,
|
|
6
|
+
SanityClient,
|
|
7
|
+
} from 'sanity'
|
|
2
8
|
|
|
3
9
|
export type Language = {
|
|
4
10
|
id: Intl.UnicodeBCP47LocaleIdentifier
|
|
@@ -24,12 +30,30 @@ export type Value = {
|
|
|
24
30
|
value?: string
|
|
25
31
|
}
|
|
26
32
|
|
|
33
|
+
export type LanguageCallback = (
|
|
34
|
+
client: SanityClient,
|
|
35
|
+
selectedValue: Record<string, unknown>
|
|
36
|
+
) => Promise<Language[]>
|
|
37
|
+
|
|
27
38
|
export type PluginConfig = {
|
|
28
39
|
/**
|
|
29
40
|
* https://www.sanity.io/docs/api-versioning
|
|
30
41
|
* @defaultValue '2022-11-27'
|
|
31
42
|
*/
|
|
32
43
|
apiVersion?: string
|
|
44
|
+
/**
|
|
45
|
+
* Specify fields that should be available in the language callback:
|
|
46
|
+
* ```tsx
|
|
47
|
+
* {
|
|
48
|
+
* select: {
|
|
49
|
+
* markets: 'markets'
|
|
50
|
+
* },
|
|
51
|
+
* languages: (client, {markets}) =>
|
|
52
|
+
* query.fetch(groq`*[_type == "language" && market in $markets]{id,title}`, {markets})
|
|
53
|
+
* }
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
select?: Record<string, string>
|
|
33
57
|
/**
|
|
34
58
|
* You can give it an array of language definitions:
|
|
35
59
|
* ```tsx
|
|
@@ -57,7 +81,7 @@ export type PluginConfig = {
|
|
|
57
81
|
* }
|
|
58
82
|
* ```
|
|
59
83
|
*/
|
|
60
|
-
languages: Language[] |
|
|
84
|
+
languages: Language[] | LanguageCallback
|
|
61
85
|
/**
|
|
62
86
|
* Can be a string matching core field types, as well as custom ones:
|
|
63
87
|
* ```tsx
|
|
@@ -81,12 +105,13 @@ export type PluginConfig = {
|
|
|
81
105
|
* }
|
|
82
106
|
* ```
|
|
83
107
|
*/
|
|
84
|
-
fieldTypes: (string | RuleTypeConstraint)[]
|
|
108
|
+
fieldTypes: (string | RuleTypeConstraint | FieldDefinition)[]
|
|
85
109
|
}
|
|
86
110
|
|
|
87
111
|
export type ArraySchemaWithLanguageOptions = ArraySchemaType & {
|
|
88
112
|
options: {
|
|
89
|
-
|
|
113
|
+
select?: Record<string, string>
|
|
114
|
+
languages: Language[] | LanguageCallback
|
|
90
115
|
apiVersion: string
|
|
91
116
|
}
|
|
92
117
|
}
|