sanity-plugin-internationalized-array 1.6.0 → 1.6.2
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 +30 -4
- package/lib/{src/index.d.ts → index.d.ts} +6 -1
- package/lib/index.esm.js +9483 -4
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +9483 -4
- package/lib/index.js.map +1 -1
- package/package.json +49 -37
- package/src/cache.ts +1 -0
- package/src/components/Feedback.tsx +4 -4
- package/src/components/InternationalizedArray.tsx +30 -17
- package/src/components/InternationalizedInput.tsx +35 -10
- package/src/components/Preload.tsx +6 -3
- package/src/components/getSelectedValue.ts +3 -1
- package/src/components/getToneFromValidation.ts +3 -1
- package/src/plugin.tsx +33 -24
- package/src/schema/array.ts +12 -7
- package/src/schema/object.ts +2 -8
- package/src/types.ts +7 -1
- package/src/components/Table.tsx +0 -88
package/package.json
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sanity-plugin-internationalized-array",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "Store localized fields in an array to save on attributes",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
7
7
|
"sanity-plugin"
|
|
8
8
|
],
|
|
9
|
-
"homepage": "https://github.com/
|
|
9
|
+
"homepage": "https://github.com/sanity-io/sanity-plugin-internationalized-array#readme",
|
|
10
10
|
"bugs": {
|
|
11
|
-
"url": "https://github.com/
|
|
11
|
+
"url": "https://github.com/sanity-io/sanity-plugin-internationalized-array/issues"
|
|
12
12
|
},
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
|
-
"url": "git@github.com:
|
|
15
|
+
"url": "git@github.com:sanity-io/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,63 +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",
|
|
53
55
|
"fast-deep-equal": "^3.1.3",
|
|
54
56
|
"lodash.get": "^4.4.2",
|
|
55
57
|
"suspend-react": "^0.0.8"
|
|
56
58
|
},
|
|
57
59
|
"devDependencies": {
|
|
58
|
-
"@commitlint/cli": "^17.
|
|
59
|
-
"@commitlint/config-conventional": "^17.
|
|
60
|
-
"@sanity/pkg-utils": "^
|
|
61
|
-
"@sanity/plugin-kit": "^
|
|
62
|
-
"@sanity/semantic-release-preset": "^
|
|
63
|
-
"@types/
|
|
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",
|
|
64
66
|
"@types/styled-components": "^5.1.26",
|
|
65
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
66
|
-
"@typescript-eslint/parser": "^5.
|
|
67
|
-
"eslint": "^8.
|
|
68
|
-
"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",
|
|
69
71
|
"eslint-config-sanity": "^6.0.0",
|
|
70
72
|
"eslint-plugin-prettier": "^4.2.1",
|
|
71
|
-
"eslint-plugin-react": "^7.
|
|
73
|
+
"eslint-plugin-react": "^7.32.2",
|
|
72
74
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
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",
|
|
77
81
|
"react": "^18",
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
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"
|
|
82
88
|
},
|
|
83
89
|
"peerDependencies": {
|
|
90
|
+
"@sanity/ui": "^1.2.2",
|
|
84
91
|
"react": "^18",
|
|
85
|
-
"sanity": "
|
|
86
|
-
"styled-components": "^5.
|
|
92
|
+
"sanity": "^3.0.0",
|
|
93
|
+
"styled-components": "^5.3.6"
|
|
87
94
|
},
|
|
88
95
|
"engines": {
|
|
89
96
|
"node": ">=14"
|
|
97
|
+
},
|
|
98
|
+
"sanityPlugin": {
|
|
99
|
+
"verifyPackage": {
|
|
100
|
+
"eslintImports": false
|
|
101
|
+
}
|
|
90
102
|
}
|
|
91
103
|
}
|
package/src/cache.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import React from 'react'
|
|
1
|
+
import {Card, Code, Stack, Text} from '@sanity/ui'
|
|
3
2
|
|
|
4
3
|
const schemaExample = {
|
|
5
4
|
languages: [
|
|
@@ -13,8 +12,9 @@ export default function Feedback() {
|
|
|
13
12
|
<Card tone="caution" border radius={2} padding={3}>
|
|
14
13
|
<Stack space={4}>
|
|
15
14
|
<Text>
|
|
16
|
-
An array of language objects must be passed into the
|
|
17
|
-
helper function, each with an
|
|
15
|
+
An array of language objects must be passed into the{' '}
|
|
16
|
+
<code>internationalizedArray</code> helper function, each with an{' '}
|
|
17
|
+
<code>id</code> and <code>title</code> field. Example:
|
|
18
18
|
</Text>
|
|
19
19
|
<Card padding={2} border radius={2}>
|
|
20
20
|
<Code size={1} language="javascript">
|
|
@@ -1,34 +1,37 @@
|
|
|
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,
|
|
10
13
|
useFormBuilder,
|
|
11
14
|
} from 'sanity'
|
|
12
|
-
import {Button, Grid, Stack, useToast} from '@sanity/ui'
|
|
13
|
-
import {AddIcon} from '@sanity/icons'
|
|
14
15
|
import {suspend} from 'suspend-react'
|
|
15
|
-
import equal from 'fast-deep-equal'
|
|
16
16
|
|
|
17
|
-
import
|
|
17
|
+
import {namespace, version} from '../cache'
|
|
18
|
+
import type {ArraySchemaWithLanguageOptions, Value} from '../types'
|
|
18
19
|
import Feedback from './Feedback'
|
|
20
|
+
import {getSelectedValue} from './getSelectedValue'
|
|
19
21
|
// TODO: Move this provider to the root component
|
|
20
22
|
import {LanguageProvider} from './languageContext'
|
|
21
|
-
import {namespace, version} from '../cache'
|
|
22
|
-
import {getSelectedValue} from './getSelectedValue'
|
|
23
23
|
|
|
24
24
|
export type InternationalizedArrayProps = ArrayOfObjectsInputProps<
|
|
25
25
|
Value,
|
|
26
26
|
ArraySchemaWithLanguageOptions
|
|
27
27
|
>
|
|
28
28
|
|
|
29
|
-
export default function InternationalizedArray(
|
|
29
|
+
export default function InternationalizedArray(
|
|
30
|
+
props: InternationalizedArrayProps
|
|
31
|
+
) {
|
|
30
32
|
const {members, value, schemaType, onChange} = props
|
|
31
|
-
const readOnly =
|
|
33
|
+
const readOnly =
|
|
34
|
+
typeof schemaType.readOnly === 'boolean' ? schemaType.readOnly : false
|
|
32
35
|
const {options} = schemaType
|
|
33
36
|
const toast = useToast()
|
|
34
37
|
const {value: document} = useFormBuilder()
|
|
@@ -161,13 +164,16 @@ export default function InternationalizedArray(props: InternationalizedArrayProp
|
|
|
161
164
|
}
|
|
162
165
|
|
|
163
166
|
return value
|
|
164
|
-
.map((v, vIndex) =>
|
|
167
|
+
.map((v, vIndex) =>
|
|
168
|
+
vIndex === languagesInUse.findIndex((l) => l.id === v._key) ? null : v
|
|
169
|
+
)
|
|
165
170
|
.filter(Boolean)
|
|
166
171
|
}, [value, languagesInUse])
|
|
167
172
|
|
|
168
173
|
const languagesAreValid = useMemo(
|
|
169
174
|
() =>
|
|
170
|
-
!languages?.length ||
|
|
175
|
+
!languages?.length ||
|
|
176
|
+
(languages?.length && languages.every((item) => item.id && item.title)),
|
|
171
177
|
[languages]
|
|
172
178
|
)
|
|
173
179
|
|
|
@@ -231,7 +237,10 @@ export default function InternationalizedArray(props: InternationalizedArrayProp
|
|
|
231
237
|
tone="primary"
|
|
232
238
|
mode="ghost"
|
|
233
239
|
fontSize={1}
|
|
234
|
-
disabled={
|
|
240
|
+
disabled={
|
|
241
|
+
readOnly ||
|
|
242
|
+
Boolean(value?.find((item) => item._key === language.id))
|
|
243
|
+
}
|
|
235
244
|
text={language.id.toUpperCase()}
|
|
236
245
|
icon={AddIcon}
|
|
237
246
|
onClick={() => handleAddLanguage(language.id)}
|
|
@@ -242,13 +251,17 @@ export default function InternationalizedArray(props: InternationalizedArrayProp
|
|
|
242
251
|
<Button
|
|
243
252
|
tone="primary"
|
|
244
253
|
mode="ghost"
|
|
245
|
-
disabled={
|
|
254
|
+
disabled={
|
|
255
|
+
readOnly || (value && value?.length >= languages?.length)
|
|
256
|
+
}
|
|
246
257
|
icon={AddIcon}
|
|
247
258
|
text={
|
|
248
259
|
// eslint-disable-next-line no-nested-ternary
|
|
249
260
|
value?.length
|
|
250
261
|
? `Add missing ${
|
|
251
|
-
languages.length - value.length === 1
|
|
262
|
+
languages.length - value.length === 1
|
|
263
|
+
? `language`
|
|
264
|
+
: `languages`
|
|
252
265
|
}`
|
|
253
266
|
: languages.length === 1
|
|
254
267
|
? `Add ${languages[0].title} Field`
|
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
import {ObjectItemProps, useFormValue} from 'sanity'
|
|
2
|
-
import React, {useCallback, useMemo} from 'react'
|
|
3
|
-
import {unset, set} from 'sanity'
|
|
4
|
-
import {Button, Flex, Label, MenuButton, Menu, MenuItem, Card, Spinner, Stack} from '@sanity/ui'
|
|
5
1
|
import {RemoveCircleIcon} from '@sanity/icons'
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
Card,
|
|
5
|
+
Flex,
|
|
6
|
+
Label,
|
|
7
|
+
Menu,
|
|
8
|
+
MenuButton,
|
|
9
|
+
MenuItem,
|
|
10
|
+
Spinner,
|
|
11
|
+
Stack,
|
|
12
|
+
} from '@sanity/ui'
|
|
13
|
+
import React, {useCallback, useMemo} from 'react'
|
|
14
|
+
import {ObjectItemProps, useFormValue} from 'sanity'
|
|
15
|
+
import {set, unset} from 'sanity'
|
|
6
16
|
|
|
7
17
|
import {getToneFromValidation} from './getToneFromValidation'
|
|
8
18
|
import {LanguageContext} from './languageContext'
|
|
@@ -13,13 +23,19 @@ type InternationalizedValue = {
|
|
|
13
23
|
value: string
|
|
14
24
|
}
|
|
15
25
|
|
|
16
|
-
export default function InternationalizedInput(
|
|
17
|
-
|
|
26
|
+
export default function InternationalizedInput(
|
|
27
|
+
props: ObjectItemProps<InternationalizedValue>
|
|
28
|
+
) {
|
|
29
|
+
const parentValue = useFormValue(
|
|
30
|
+
props.path.slice(0, -1)
|
|
31
|
+
) as InternationalizedValue[]
|
|
18
32
|
|
|
19
33
|
const inlineProps = {
|
|
20
34
|
...props.inputProps,
|
|
21
35
|
// This is the magic that makes inline editing work?
|
|
22
|
-
members: props.inputProps.members.filter(
|
|
36
|
+
members: props.inputProps.members.filter(
|
|
37
|
+
(m) => m.kind === 'field' && m.name === 'value'
|
|
38
|
+
),
|
|
23
39
|
// This just overrides the type
|
|
24
40
|
// TODO: Remove this as it shouldn't be necessary?
|
|
25
41
|
value: props.value as InternationalizedValue,
|
|
@@ -30,13 +46,22 @@ export default function InternationalizedInput(props: ObjectItemProps<Internatio
|
|
|
30
46
|
// The parent array contains the languages from the plugin config
|
|
31
47
|
const {languages} = React.useContext(LanguageContext)
|
|
32
48
|
|
|
33
|
-
const languageKeysInUse = useMemo(
|
|
34
|
-
|
|
49
|
+
const languageKeysInUse = useMemo(
|
|
50
|
+
() => parentValue?.map((v) => v._key) ?? [],
|
|
51
|
+
[parentValue]
|
|
52
|
+
)
|
|
53
|
+
const keyIsValid = languages?.length
|
|
54
|
+
? languages.find((l) => l.id === value._key)
|
|
55
|
+
: false
|
|
35
56
|
|
|
36
57
|
// Changes the key of this item, ideally to a valid language
|
|
37
58
|
const handleKeyChange = useCallback(
|
|
38
59
|
(languageId: string) => {
|
|
39
|
-
if (
|
|
60
|
+
if (
|
|
61
|
+
!value ||
|
|
62
|
+
!languages?.length ||
|
|
63
|
+
!languages.find((l) => l.id === languageId)
|
|
64
|
+
) {
|
|
40
65
|
return
|
|
41
66
|
}
|
|
42
67
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {peek, preload} from '../cache'
|
|
2
1
|
import {memo} from 'react'
|
|
3
|
-
import type {PluginConfig} from '../types'
|
|
4
2
|
import {useClient} from 'sanity'
|
|
5
3
|
|
|
4
|
+
import {peek, preload} from '../cache'
|
|
5
|
+
import type {PluginConfig} from '../types'
|
|
6
|
+
|
|
6
7
|
export default memo(function Preload(
|
|
7
8
|
props: Required<Pick<PluginConfig, 'apiVersion' | 'languages'>>
|
|
8
9
|
) {
|
|
@@ -10,7 +11,9 @@ export default memo(function Preload(
|
|
|
10
11
|
if (!Array.isArray(peek({}))) {
|
|
11
12
|
// eslint-disable-next-line require-await
|
|
12
13
|
preload(async () =>
|
|
13
|
-
Array.isArray(props.languages)
|
|
14
|
+
Array.isArray(props.languages)
|
|
15
|
+
? props.languages
|
|
16
|
+
: props.languages(client, {})
|
|
14
17
|
)
|
|
15
18
|
}
|
|
16
19
|
|
|
@@ -19,7 +19,9 @@ export const getSelectedValue = (
|
|
|
19
19
|
if (Array.isArray(value)) {
|
|
20
20
|
// If there are references in the array, ensure they have `_ref` set, otherwise they are considered empty and can safely be ignored
|
|
21
21
|
value = value.filter((item) =>
|
|
22
|
-
typeof item === 'object'
|
|
22
|
+
typeof item === 'object'
|
|
23
|
+
? item?._type === 'reference' && '_ref' in item
|
|
24
|
+
: true
|
|
23
25
|
)
|
|
24
26
|
}
|
|
25
27
|
selectedValue[key] = value
|
|
@@ -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
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
1
|
import {definePlugin} from 'sanity'
|
|
2
|
+
|
|
3
3
|
import Preload from './components/Preload'
|
|
4
4
|
import array from './schema/array'
|
|
5
5
|
import object from './schema/object'
|
|
@@ -10,29 +10,38 @@ const CONFIG_DEFAULT: PluginConfig = {
|
|
|
10
10
|
fieldTypes: [],
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export const internationalizedArray = definePlugin<PluginConfig>(
|
|
14
|
-
|
|
13
|
+
export const internationalizedArray = definePlugin<PluginConfig>(
|
|
14
|
+
(config = CONFIG_DEFAULT) => {
|
|
15
|
+
const {
|
|
16
|
+
apiVersion = '2022-11-27',
|
|
17
|
+
select,
|
|
18
|
+
languages,
|
|
19
|
+
fieldTypes,
|
|
20
|
+
} = {...CONFIG_DEFAULT, ...config}
|
|
15
21
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
return {
|
|
23
|
+
name: 'sanity-plugin-internationalized-array',
|
|
24
|
+
// If `languages` is a callback then let's preload it
|
|
25
|
+
studio: Array.isArray(languages)
|
|
26
|
+
? undefined
|
|
27
|
+
: {
|
|
28
|
+
components: {
|
|
29
|
+
layout: (props) => (
|
|
30
|
+
<>
|
|
31
|
+
<Preload apiVersion={apiVersion} languages={languages} />
|
|
32
|
+
{props.renderDefault(props)}
|
|
33
|
+
</>
|
|
34
|
+
),
|
|
35
|
+
},
|
|
29
36
|
},
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
schema: {
|
|
38
|
+
types: [
|
|
39
|
+
...fieldTypes.map((type) =>
|
|
40
|
+
array({type, apiVersion, select, languages})
|
|
41
|
+
),
|
|
42
|
+
...fieldTypes.map((type) => object({type})),
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
}
|
|
37
46
|
}
|
|
38
|
-
|
|
47
|
+
)
|
package/src/schema/array.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable no-nested-ternary */
|
|
2
2
|
import {defineField, type FieldDefinition, type Rule} from 'sanity'
|
|
3
|
-
import {peek} from '../cache'
|
|
4
3
|
|
|
4
|
+
import {peek} from '../cache'
|
|
5
5
|
import {createFieldName} from '../components/createFieldName'
|
|
6
6
|
import {getSelectedValue} from '../components/getSelectedValue'
|
|
7
7
|
import InternationalizedArray from '../components/InternationalizedArray'
|
|
@@ -24,14 +24,12 @@ export default (config: ArrayFactoryConfig): FieldDefinition<'array'> => {
|
|
|
24
24
|
name: arrayName,
|
|
25
25
|
title: 'Internationalized array',
|
|
26
26
|
type: 'array',
|
|
27
|
-
// TODO: Resolve this typing issue with the outer component
|
|
28
|
-
// @ts-ignore
|
|
29
27
|
components: {
|
|
30
28
|
input: InternationalizedArray,
|
|
31
29
|
},
|
|
32
30
|
options: {apiVersion, select, languages},
|
|
33
31
|
// TODO: Resolve this typing issue with the inner object
|
|
34
|
-
// @ts-
|
|
32
|
+
// @ts-expect-error
|
|
35
33
|
of: [
|
|
36
34
|
defineField({
|
|
37
35
|
...(typeof type === 'string' ? {} : type),
|
|
@@ -47,7 +45,9 @@ export default (config: ArrayFactoryConfig): FieldDefinition<'array'> => {
|
|
|
47
45
|
|
|
48
46
|
const selectedValue = getSelectedValue(select, context.document)
|
|
49
47
|
const client = context.getClient({apiVersion})
|
|
50
|
-
const contextLanguages: Language[] = Array.isArray(
|
|
48
|
+
const contextLanguages: Language[] = Array.isArray(
|
|
49
|
+
context?.type?.options?.languages
|
|
50
|
+
)
|
|
51
51
|
? context!.type!.options.languages
|
|
52
52
|
: Array.isArray(peek(selectedValue))
|
|
53
53
|
? peek(selectedValue)
|
|
@@ -55,12 +55,17 @@ export default (config: ArrayFactoryConfig): FieldDefinition<'array'> => {
|
|
|
55
55
|
|
|
56
56
|
if (value && value.length > contextLanguages.length) {
|
|
57
57
|
return `Cannot be more than ${
|
|
58
|
-
contextLanguages.length === 1
|
|
58
|
+
contextLanguages.length === 1
|
|
59
|
+
? `1 item`
|
|
60
|
+
: `${contextLanguages.length} items`
|
|
59
61
|
}`
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
const nonLanguageKeys = value?.length
|
|
63
|
-
? value.filter(
|
|
65
|
+
? value.filter(
|
|
66
|
+
(item) =>
|
|
67
|
+
!contextLanguages.find((language) => item._key === language.id)
|
|
68
|
+
)
|
|
64
69
|
: []
|
|
65
70
|
if (nonLanguageKeys.length) {
|
|
66
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
|
package/src/components/Table.tsx
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import styled, {css} from 'styled-components'
|
|
3
|
-
import {Box, BoxProps, Card, CardProps} from '@sanity/ui'
|
|
4
|
-
|
|
5
|
-
// Wrappers required because of bug with passing down "as" prop
|
|
6
|
-
// https://github.com/styled-components/styled-components/issues/2449
|
|
7
|
-
|
|
8
|
-
// Table
|
|
9
|
-
const TableWrapper = (props = {}) => {
|
|
10
|
-
return <Box as="table" {...props} />
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const StyledTable = styled(TableWrapper)(
|
|
14
|
-
() =>
|
|
15
|
-
css`
|
|
16
|
-
display: table;
|
|
17
|
-
width: 100%;
|
|
18
|
-
|
|
19
|
-
&:not([hidden]) {
|
|
20
|
-
display: table;
|
|
21
|
-
}
|
|
22
|
-
`
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
type TableProps = BoxProps & {
|
|
26
|
-
children: React.ReactNode
|
|
27
|
-
style?: React.CSSProperties
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function Table(props: TableProps) {
|
|
31
|
-
const {children, ...rest} = props
|
|
32
|
-
|
|
33
|
-
return <StyledTable {...rest}>{children}</StyledTable>
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Row
|
|
37
|
-
const RowWrapper = (props = {}) => {
|
|
38
|
-
return <Card as="tr" {...props} />
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const StyledRow = styled(RowWrapper)(
|
|
42
|
-
() =>
|
|
43
|
-
css`
|
|
44
|
-
display: table-row;
|
|
45
|
-
|
|
46
|
-
&:not([hidden]) {
|
|
47
|
-
display: table-row;
|
|
48
|
-
}
|
|
49
|
-
`
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
type TableRowProps = CardProps & {
|
|
53
|
-
children: React.ReactNode
|
|
54
|
-
style?: React.CSSProperties
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function TableRow(props: TableRowProps) {
|
|
58
|
-
const {children, ...rest} = props
|
|
59
|
-
|
|
60
|
-
return <StyledRow {...rest}>{children}</StyledRow>
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Cell
|
|
64
|
-
const CellWrapper = (props = {}) => {
|
|
65
|
-
return <Box as="td" {...props} />
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const StyledCell = styled(CellWrapper)(
|
|
69
|
-
() =>
|
|
70
|
-
css`
|
|
71
|
-
display: table-cell;
|
|
72
|
-
|
|
73
|
-
&:not([hidden]) {
|
|
74
|
-
display: table-cell;
|
|
75
|
-
}
|
|
76
|
-
`
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
type TableCellProps = BoxProps & {
|
|
80
|
-
children: React.ReactNode
|
|
81
|
-
style?: React.CSSProperties
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export function TableCell(props: TableCellProps) {
|
|
85
|
-
const {children, ...rest} = props
|
|
86
|
-
|
|
87
|
-
return <StyledCell {...rest}>{children}</StyledCell>
|
|
88
|
-
}
|