sanity-plugin-internationalized-array 0.0.7 → 1.1.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/LICENSE +1 -1
- package/README.md +82 -32
- package/lib/cjs/index.js +487 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/esm/index.js +480 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/types/index.d.ts +12 -0
- package/lib/types/index.d.ts.map +1 -0
- package/package.json +50 -36
- package/sanity.json +7 -6
- package/src/components/Feedback.tsx +27 -0
- package/src/components/InternationalizedArrayInput.tsx +222 -0
- package/src/{LanguageArray → components}/Table.tsx +0 -0
- package/src/components/createFieldName.ts +20 -0
- package/src/components/getToneFromValidation.ts +18 -0
- package/src/index.ts +1 -3
- package/src/plugin.tsx +23 -0
- package/src/schema/array.ts +69 -0
- package/src/schema/object.ts +29 -0
- package/src/types.ts +19 -9
- package/v2-incompatible.js +11 -0
- package/lib/LanguageArray/Table.js +0 -88
- package/lib/LanguageArray/Table.js.map +0 -1
- package/lib/LanguageArray/ValueInput.js +0 -17
- package/lib/LanguageArray/ValueInput.js.map +0 -1
- package/lib/LanguageArray/index.js +0 -253
- package/lib/LanguageArray/index.js.map +0 -1
- package/lib/hooks/useUnsetInputComponent.js +0 -32
- package/lib/hooks/useUnsetInputComponent.js.map +0 -1
- package/lib/index.js +0 -13
- package/lib/index.js.map +0 -1
- package/lib/internationalizedArray.js +0 -105
- package/lib/internationalizedArray.js.map +0 -1
- package/lib/types.js +0 -2
- package/lib/types.js.map +0 -1
- package/migrations/transformObjectToArray.js +0 -94
- package/src/LanguageArray/ValueInput.tsx +0 -6
- package/src/LanguageArray/index.tsx +0 -311
- package/src/hooks/useUnsetInputComponent.tsx +0 -17
- package/src/internationalizedArray.ts +0 -84
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,48 +1,98 @@
|
|
|
1
1
|
# sanity-plugin-internationalized-array
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> NOTE This is for the Studio v3 version of the plugin
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
A helper function that renders a custom input component for writing localized fields of content into an array.
|
|
6
6
|
|
|
7
|
-

|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
```
|
|
12
|
-
|
|
12
|
+
npm install --save sanity-plugin-internationalized-array@studio-v3
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
or
|
|
16
16
|
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
```
|
|
18
|
+
yarn add sanity-plugin-internationalized-array-v3@studio-v3
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage (simple)
|
|
22
|
+
|
|
23
|
+
Add it as a plugin in sanity.config.ts (or .js):
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import {createConfig} from 'sanity'
|
|
27
|
+
import {internationalizedArray} from 'sanity-plugin-internationalized-array'
|
|
28
|
+
|
|
29
|
+
export const createConfig({
|
|
30
|
+
// ...
|
|
31
|
+
plugins: [
|
|
27
32
|
internationalizedArray({
|
|
28
|
-
// Required, the `name` of the outer array
|
|
29
|
-
name: "greeting",
|
|
30
|
-
// Required, the `type` of the inner field
|
|
31
|
-
// One of: string | text | number | boolean
|
|
32
|
-
type: "string",
|
|
33
|
-
// Required, must be an array of objects
|
|
34
33
|
languages: [
|
|
35
|
-
{
|
|
36
|
-
{
|
|
34
|
+
{id: 'en', title: 'English'},
|
|
35
|
+
{id: 'fr', title: 'French'}
|
|
37
36
|
],
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
};
|
|
37
|
+
fieldTypes: ['string'],
|
|
38
|
+
})
|
|
39
|
+
]
|
|
40
|
+
})
|
|
43
41
|
```
|
|
44
42
|
|
|
45
|
-
This will
|
|
43
|
+
This will register two new fields to the schema, based on the settings passed into `fieldTypes`:
|
|
44
|
+
|
|
45
|
+
- `internationalizedArrayString` an array field of:
|
|
46
|
+
- `internationalizedArrayStringValue` an object field, with a single `string` field inside called `value`
|
|
47
|
+
|
|
48
|
+
You can pass in more registered schema type names to generate more internationalized arrays. Use them in your schema like this:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
defineField({
|
|
52
|
+
name: 'greeting',
|
|
53
|
+
type: 'internationalizedArrayString',
|
|
54
|
+
}),
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Usage (advanced)
|
|
58
|
+
|
|
59
|
+
For more control over the `value` field, you can pass a schema definition into the `fieldTypes` array.
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import {createConfig} from 'sanity'
|
|
63
|
+
import {internationalizedArray} from 'sanity-plugin-internationalized-array'
|
|
64
|
+
|
|
65
|
+
export const createConfig({
|
|
66
|
+
// ...
|
|
67
|
+
plugins: [
|
|
68
|
+
internationalizedArray({
|
|
69
|
+
languages: [
|
|
70
|
+
{id: 'en', title: 'English'},
|
|
71
|
+
{id: 'fr', title: 'French'}
|
|
72
|
+
],
|
|
73
|
+
fieldTypes: [
|
|
74
|
+
defineField({
|
|
75
|
+
name: 'featuredProduct',
|
|
76
|
+
type: 'reference',
|
|
77
|
+
to: [{type: 'product'}]
|
|
78
|
+
hidden: (({document}) => !document?.title)
|
|
79
|
+
})
|
|
80
|
+
],
|
|
81
|
+
})
|
|
82
|
+
]
|
|
83
|
+
})
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
This would also create two new fields in your schema.
|
|
87
|
+
|
|
88
|
+
- `internationalizedArrayFeaturedProduct` an array field of:
|
|
89
|
+
- `internationalizedArrayFeaturedProductValue` an object field, with a single `string` field inside called `value`
|
|
90
|
+
|
|
91
|
+
Note that the `name` key in the field gets rewritten to `value` and is instead used to name the object field.
|
|
92
|
+
|
|
93
|
+
## Shape of stored data
|
|
94
|
+
|
|
95
|
+
The custom input contains buttons which will add new array items with the language as the `_key` value. Data returned from this array will look like this:
|
|
46
96
|
|
|
47
97
|
```json
|
|
48
98
|
"greeting": [
|
|
@@ -51,6 +101,8 @@ This will create an Array field where `string` fields can be added with the name
|
|
|
51
101
|
]
|
|
52
102
|
```
|
|
53
103
|
|
|
104
|
+
## Querying data
|
|
105
|
+
|
|
54
106
|
Using GROQ filters you can query for a specific language key like so:
|
|
55
107
|
|
|
56
108
|
```js
|
|
@@ -67,7 +119,7 @@ Follow the instructions inside the script and set the `_type` and field name you
|
|
|
67
119
|
|
|
68
120
|
Please take a backup first!
|
|
69
121
|
|
|
70
|
-
### Why store
|
|
122
|
+
### Why store localized field data like this?
|
|
71
123
|
|
|
72
124
|
The most popular way to store field-level translated content is in an object using the method prescribed in [@sanity/language-filter](https://www.npmjs.com/package/@sanity/language-filter). This works well and creates tidy object structures, but also create a unique field path for every unique field name, multiplied by the number of languages in your dataset.
|
|
73
125
|
|
|
@@ -105,7 +157,5 @@ greeting[].value
|
|
|
105
157
|
|
|
106
158
|
By using this plugin you can safely extend the number of languages without adding any additional query paths.
|
|
107
159
|
|
|
108
|
-
## License
|
|
109
|
-
|
|
110
160
|
MIT © Simeon Griggs
|
|
111
161
|
See LICENSE
|
package/lib/cjs/index.js
ADDED
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
var $k7rGe$sanity = require("sanity");
|
|
2
|
+
var $k7rGe$reactjsxruntime = require("react/jsx-runtime");
|
|
3
|
+
var $k7rGe$react = require("react");
|
|
4
|
+
var $k7rGe$sanityform = require("sanity/form");
|
|
5
|
+
var $k7rGe$sanityui = require("@sanity/ui");
|
|
6
|
+
var $k7rGe$sanityicons = require("@sanity/icons");
|
|
7
|
+
var $k7rGe$styledcomponents = require("styled-components");
|
|
8
|
+
|
|
9
|
+
function $parcel$export(e, n, v, s) {
|
|
10
|
+
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
|
|
11
|
+
}
|
|
12
|
+
function $parcel$interopDefault(a) {
|
|
13
|
+
return a && a.__esModule ? a.default : a;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
$parcel$export(module.exports, "internationalizedArray", () => $45e3093e7de8dca2$export$bec7eb13daf35f0e);
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
function $a0eca5cb1c058e2c$export$8a7688a96d852767(string) {
|
|
20
|
+
return string.replace(/-([a-z])/g, (g)=>g[1].toUpperCase());
|
|
21
|
+
}
|
|
22
|
+
function $a0eca5cb1c058e2c$export$348afa8c9ff47183(string) {
|
|
23
|
+
return string.split(` `).map((word)=>word.charAt(0).toUpperCase() + word.slice(1)).join(` `);
|
|
24
|
+
}
|
|
25
|
+
function $a0eca5cb1c058e2c$export$26c6f48841fe1a8a(string) {
|
|
26
|
+
return $a0eca5cb1c058e2c$export$348afa8c9ff47183($a0eca5cb1c058e2c$export$8a7688a96d852767(string));
|
|
27
|
+
}
|
|
28
|
+
function $a0eca5cb1c058e2c$export$ab1ce2a474f41f52(name, addValue = false) {
|
|
29
|
+
return addValue ? [
|
|
30
|
+
`internationalizedArray`,
|
|
31
|
+
$a0eca5cb1c058e2c$export$26c6f48841fe1a8a(name),
|
|
32
|
+
`Value`
|
|
33
|
+
].join(``) : [
|
|
34
|
+
`internationalizedArray`,
|
|
35
|
+
$a0eca5cb1c058e2c$export$26c6f48841fe1a8a(name)
|
|
36
|
+
].join(``);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
// Wrappers required because of bug with passing down "as" prop
|
|
49
|
+
// https://github.com/styled-components/styled-components/issues/2449
|
|
50
|
+
// Table
|
|
51
|
+
const $acfbfc6ee2363807$var$TableWrapper = (props = {})=>{
|
|
52
|
+
return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
|
|
53
|
+
as: "table",
|
|
54
|
+
...props
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
const $acfbfc6ee2363807$var$StyledTable = (0, ($parcel$interopDefault($k7rGe$styledcomponents)))($acfbfc6ee2363807$var$TableWrapper)(()=>(0, $k7rGe$styledcomponents.css)`
|
|
58
|
+
display: table;
|
|
59
|
+
width: 100%;
|
|
60
|
+
|
|
61
|
+
&:not([hidden]) {
|
|
62
|
+
display: table;
|
|
63
|
+
}
|
|
64
|
+
`);
|
|
65
|
+
function $acfbfc6ee2363807$export$54ec01a60f47d33d(props) {
|
|
66
|
+
const { children: children , ...rest } = props;
|
|
67
|
+
return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)($acfbfc6ee2363807$var$StyledTable, {
|
|
68
|
+
...rest,
|
|
69
|
+
children: children
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
// Row
|
|
73
|
+
const $acfbfc6ee2363807$var$RowWrapper = (props = {})=>{
|
|
74
|
+
return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Card), {
|
|
75
|
+
as: "tr",
|
|
76
|
+
...props
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
const $acfbfc6ee2363807$var$StyledRow = (0, ($parcel$interopDefault($k7rGe$styledcomponents)))($acfbfc6ee2363807$var$RowWrapper)(()=>(0, $k7rGe$styledcomponents.css)`
|
|
80
|
+
display: table-row;
|
|
81
|
+
|
|
82
|
+
&:not([hidden]) {
|
|
83
|
+
display: table-row;
|
|
84
|
+
}
|
|
85
|
+
`);
|
|
86
|
+
function $acfbfc6ee2363807$export$b05581f4e764e162(props) {
|
|
87
|
+
const { children: children , ...rest } = props;
|
|
88
|
+
return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)($acfbfc6ee2363807$var$StyledRow, {
|
|
89
|
+
...rest,
|
|
90
|
+
children: children
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// Cell
|
|
94
|
+
const $acfbfc6ee2363807$var$CellWrapper = (props = {})=>{
|
|
95
|
+
return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
|
|
96
|
+
as: "td",
|
|
97
|
+
...props
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
const $acfbfc6ee2363807$var$StyledCell = (0, ($parcel$interopDefault($k7rGe$styledcomponents)))($acfbfc6ee2363807$var$CellWrapper)(()=>(0, $k7rGe$styledcomponents.css)`
|
|
101
|
+
display: table-cell;
|
|
102
|
+
|
|
103
|
+
&:not([hidden]) {
|
|
104
|
+
display: table-cell;
|
|
105
|
+
}
|
|
106
|
+
`);
|
|
107
|
+
function $acfbfc6ee2363807$export$1e4baea7053fc0e3(props) {
|
|
108
|
+
const { children: children , ...rest } = props;
|
|
109
|
+
return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)($acfbfc6ee2363807$var$StyledCell, {
|
|
110
|
+
...rest,
|
|
111
|
+
children: children
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
const $aaf4d804384afd00$var$schemaExample = {
|
|
121
|
+
languages: [
|
|
122
|
+
{
|
|
123
|
+
id: "en",
|
|
124
|
+
title: "English"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
id: "no",
|
|
128
|
+
title: "Norsk"
|
|
129
|
+
},
|
|
130
|
+
]
|
|
131
|
+
};
|
|
132
|
+
function $aaf4d804384afd00$export$2e2bcd8739ae039() {
|
|
133
|
+
return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Card), {
|
|
134
|
+
tone: "caution",
|
|
135
|
+
border: true,
|
|
136
|
+
radius: 2,
|
|
137
|
+
padding: 3,
|
|
138
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Stack), {
|
|
139
|
+
space: 4,
|
|
140
|
+
children: [
|
|
141
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Text), {
|
|
142
|
+
children: [
|
|
143
|
+
"An array of language objects must be passed into the ",
|
|
144
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)("code", {
|
|
145
|
+
children: "internationalizedArray"
|
|
146
|
+
}),
|
|
147
|
+
" ",
|
|
148
|
+
"helper function, each with an ",
|
|
149
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)("code", {
|
|
150
|
+
children: "id"
|
|
151
|
+
}),
|
|
152
|
+
" and ",
|
|
153
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)("code", {
|
|
154
|
+
children: "title"
|
|
155
|
+
}),
|
|
156
|
+
" field. Example:"
|
|
157
|
+
]
|
|
158
|
+
}),
|
|
159
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Card), {
|
|
160
|
+
padding: 2,
|
|
161
|
+
border: true,
|
|
162
|
+
radius: 2,
|
|
163
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Code), {
|
|
164
|
+
size: 1,
|
|
165
|
+
language: "javascript",
|
|
166
|
+
children: JSON.stringify($aaf4d804384afd00$var$schemaExample, null, 2)
|
|
167
|
+
})
|
|
168
|
+
})
|
|
169
|
+
]
|
|
170
|
+
})
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
function $6a9b28384eb7074d$export$16423358d6ebe294(validations) {
|
|
176
|
+
if (!validations.length) return `default`;
|
|
177
|
+
const validationLevels = validations.map((v)=>v.level);
|
|
178
|
+
if (validationLevels.includes("error")) return `critical`;
|
|
179
|
+
else if (validationLevels.includes("warning")) return `caution`;
|
|
180
|
+
return `default`;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
function $7e790a73eaf2b445$export$2e2bcd8739ae039(props) {
|
|
185
|
+
const { members: members , value: value , schemaType: schemaType , onChange: onChange } = props;
|
|
186
|
+
const readOnly = typeof schemaType.readOnly === "boolean" ? schemaType.readOnly : false;
|
|
187
|
+
const { options: options } = schemaType;
|
|
188
|
+
const languages = (0, $k7rGe$react.useMemo)(()=>options?.languages ?? [], [
|
|
189
|
+
options
|
|
190
|
+
]);
|
|
191
|
+
const handleAddLanguage = (0, $k7rGe$react.useCallback)((languageId)=>{
|
|
192
|
+
// Create new items
|
|
193
|
+
const newItems = languageId ? [
|
|
194
|
+
{
|
|
195
|
+
_key: languageId
|
|
196
|
+
}
|
|
197
|
+
] : languages.filter((language)=>value?.length ? !value.find((v)=>v._key === language.id) : true).map((language)=>({
|
|
198
|
+
_key: language.id
|
|
199
|
+
}));
|
|
200
|
+
// Insert new items in the correct order
|
|
201
|
+
const languagesInUse = value?.length ? value.map((v)=>v) : [];
|
|
202
|
+
const insertions = newItems.map((item)=>{
|
|
203
|
+
// What's the original index of this language?
|
|
204
|
+
const languageIndex = languages.findIndex((l)=>item._key === l.id);
|
|
205
|
+
// What languages are there beyond that index?
|
|
206
|
+
const remainingLanguages = languages.slice(languageIndex + 1);
|
|
207
|
+
// So what is the index in the current value array of the next language in the language array?
|
|
208
|
+
const nextLanguageIndex = languagesInUse.findIndex((l)=>// eslint-disable-next-line max-nested-callbacks
|
|
209
|
+
remainingLanguages.find((r)=>r.id === l._key));
|
|
210
|
+
// Keep local state up to date incase multiple insertions are being made
|
|
211
|
+
if (nextLanguageIndex < 0) languagesInUse.push(item);
|
|
212
|
+
else languagesInUse.splice(nextLanguageIndex, 0, item);
|
|
213
|
+
return nextLanguageIndex < 0 ? (0, $k7rGe$sanityform.insert)([
|
|
214
|
+
item
|
|
215
|
+
], "after", [
|
|
216
|
+
nextLanguageIndex
|
|
217
|
+
]) : (0, $k7rGe$sanityform.insert)([
|
|
218
|
+
item
|
|
219
|
+
], "before", [
|
|
220
|
+
nextLanguageIndex
|
|
221
|
+
]);
|
|
222
|
+
});
|
|
223
|
+
onChange([
|
|
224
|
+
(0, $k7rGe$sanityform.setIfMissing)([]),
|
|
225
|
+
...insertions
|
|
226
|
+
]);
|
|
227
|
+
}, [
|
|
228
|
+
languages,
|
|
229
|
+
onChange,
|
|
230
|
+
value
|
|
231
|
+
]);
|
|
232
|
+
const handleUnsetByKey = (0, $k7rGe$react.useCallback)((_key)=>{
|
|
233
|
+
onChange((0, $k7rGe$sanityform.unset)([
|
|
234
|
+
{
|
|
235
|
+
_key: _key
|
|
236
|
+
}
|
|
237
|
+
]));
|
|
238
|
+
}, [
|
|
239
|
+
onChange
|
|
240
|
+
]);
|
|
241
|
+
// TODO: This is lazy, reordering and re-setting the whole array – it could be surgical
|
|
242
|
+
const handleRestoreOrder = (0, $k7rGe$react.useCallback)(()=>{
|
|
243
|
+
if (!value?.length) return;
|
|
244
|
+
// Create a new value array in the correct order
|
|
245
|
+
// This would also strip out values that don't have a language as the key
|
|
246
|
+
const updatedValue = value.reduce((acc, v)=>{
|
|
247
|
+
const newIndex = languages.findIndex((l)=>l.id === v?._key);
|
|
248
|
+
if (newIndex) acc[newIndex] = v;
|
|
249
|
+
return acc;
|
|
250
|
+
}, []).filter(Boolean);
|
|
251
|
+
onChange((0, $k7rGe$sanityform.set)(updatedValue));
|
|
252
|
+
}, [
|
|
253
|
+
languages,
|
|
254
|
+
onChange,
|
|
255
|
+
value
|
|
256
|
+
]);
|
|
257
|
+
const allKeysAreLanguages = (0, $k7rGe$react.useMemo)(()=>{
|
|
258
|
+
return value?.every((v)=>languages.find((l)=>l?.id === v?._key));
|
|
259
|
+
}, [
|
|
260
|
+
value,
|
|
261
|
+
languages
|
|
262
|
+
]);
|
|
263
|
+
// Check languages are in the correct order
|
|
264
|
+
const languagesOutOfOrder = (0, $k7rGe$react.useMemo)(()=>{
|
|
265
|
+
if (!value?.length) return [];
|
|
266
|
+
const languagesInUse = languages.filter((l)=>value.find((v)=>v._key === l.id));
|
|
267
|
+
return value.map((v, vIndex)=>vIndex === languagesInUse.findIndex((l)=>l.id === v._key) ? null : v).filter(Boolean);
|
|
268
|
+
}, [
|
|
269
|
+
value,
|
|
270
|
+
languages
|
|
271
|
+
]);
|
|
272
|
+
const languagesAreValid = (0, $k7rGe$react.useMemo)(()=>!languages?.length || languages?.length && languages.every((item)=>item.id && item.title), [
|
|
273
|
+
languages
|
|
274
|
+
]);
|
|
275
|
+
if (!languagesAreValid) return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $aaf4d804384afd00$export$2e2bcd8739ae039), {});
|
|
276
|
+
return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Stack), {
|
|
277
|
+
space: 2,
|
|
278
|
+
children: [
|
|
279
|
+
members?.length > 0 ? /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $acfbfc6ee2363807$export$54ec01a60f47d33d), {
|
|
280
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)("tbody", {
|
|
281
|
+
children: members.map((member)=>/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $acfbfc6ee2363807$export$b05581f4e764e162), {
|
|
282
|
+
tone: member?.item?.validation?.length > 0 ? (0, $6a9b28384eb7074d$export$16423358d6ebe294)(member.item.validation) : undefined,
|
|
283
|
+
children: [
|
|
284
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $acfbfc6ee2363807$export$1e4baea7053fc0e3), {
|
|
285
|
+
style: {
|
|
286
|
+
verticalAlign: "bottom"
|
|
287
|
+
},
|
|
288
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
|
|
289
|
+
paddingY: 3,
|
|
290
|
+
paddingRight: 2,
|
|
291
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Label), {
|
|
292
|
+
muted: true,
|
|
293
|
+
size: 1,
|
|
294
|
+
children: member.key
|
|
295
|
+
})
|
|
296
|
+
})
|
|
297
|
+
}),
|
|
298
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $acfbfc6ee2363807$export$1e4baea7053fc0e3), {
|
|
299
|
+
paddingRight: 2,
|
|
300
|
+
style: {
|
|
301
|
+
width: `100%`
|
|
302
|
+
},
|
|
303
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityform.MemberItem), {
|
|
304
|
+
...props,
|
|
305
|
+
member: member
|
|
306
|
+
})
|
|
307
|
+
}),
|
|
308
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $acfbfc6ee2363807$export$1e4baea7053fc0e3), {
|
|
309
|
+
style: {
|
|
310
|
+
verticalAlign: "bottom"
|
|
311
|
+
},
|
|
312
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Flex), {
|
|
313
|
+
align: "center",
|
|
314
|
+
justify: "flex-end",
|
|
315
|
+
gap: 3,
|
|
316
|
+
children: [
|
|
317
|
+
member?.item?.validation?.length > 0 ? /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
|
|
318
|
+
paddingLeft: 2,
|
|
319
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityform.FormFieldValidationStatus), {
|
|
320
|
+
validation: member.item.validation
|
|
321
|
+
})
|
|
322
|
+
}) : null,
|
|
323
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Button), {
|
|
324
|
+
mode: "ghost",
|
|
325
|
+
icon: (0, $k7rGe$sanityicons.RemoveIcon),
|
|
326
|
+
tone: "critical",
|
|
327
|
+
disabled: typeof readOnly === "boolean" ? readOnly : false,
|
|
328
|
+
onClick: ()=>handleUnsetByKey(member.key)
|
|
329
|
+
})
|
|
330
|
+
]
|
|
331
|
+
})
|
|
332
|
+
})
|
|
333
|
+
]
|
|
334
|
+
}, member.key))
|
|
335
|
+
})
|
|
336
|
+
}) : null,
|
|
337
|
+
languagesOutOfOrder.length > 0 && allKeysAreLanguages ? /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Button), {
|
|
338
|
+
tone: "caution",
|
|
339
|
+
icon: (0, $k7rGe$sanityicons.RestoreIcon),
|
|
340
|
+
onClick: ()=>handleRestoreOrder(),
|
|
341
|
+
text: "Restore order of languages"
|
|
342
|
+
}) : null,
|
|
343
|
+
languages?.length > 0 ? /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Stack), {
|
|
344
|
+
space: 2,
|
|
345
|
+
children: [
|
|
346
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Grid), {
|
|
347
|
+
columns: Math.min(languages.length, 5),
|
|
348
|
+
gap: 2,
|
|
349
|
+
children: languages.map((language)=>/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Button), {
|
|
350
|
+
tone: "primary",
|
|
351
|
+
mode: "ghost",
|
|
352
|
+
fontSize: 1,
|
|
353
|
+
disabled: readOnly || Boolean(value?.find((item)=>item._key === language.id)),
|
|
354
|
+
text: language.id.toUpperCase(),
|
|
355
|
+
icon: (0, $k7rGe$sanityicons.AddIcon),
|
|
356
|
+
onClick: ()=>handleAddLanguage(language.id)
|
|
357
|
+
}, language.id))
|
|
358
|
+
}),
|
|
359
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Button), {
|
|
360
|
+
tone: "primary",
|
|
361
|
+
mode: "ghost",
|
|
362
|
+
disabled: readOnly || value && value?.length >= languages?.length,
|
|
363
|
+
icon: (0, $k7rGe$sanityicons.AddIcon),
|
|
364
|
+
text: value?.length ? `Add missing languages` : `Add all languages`,
|
|
365
|
+
onClick: ()=>handleAddLanguage()
|
|
366
|
+
})
|
|
367
|
+
]
|
|
368
|
+
}) : null
|
|
369
|
+
]
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
var $0437df2e2e149362$export$2e2bcd8739ae039 = (config)=>{
|
|
375
|
+
const { languages: languages , type: type } = config;
|
|
376
|
+
const typeName = typeof type === `string` ? type : type.name;
|
|
377
|
+
const arrayName = (0, $a0eca5cb1c058e2c$export$ab1ce2a474f41f52)(typeName);
|
|
378
|
+
const objectName = (0, $a0eca5cb1c058e2c$export$ab1ce2a474f41f52)(typeName, true);
|
|
379
|
+
return (0, $k7rGe$sanity.defineField)({
|
|
380
|
+
name: arrayName,
|
|
381
|
+
title: "Internationalized array",
|
|
382
|
+
type: "array",
|
|
383
|
+
components: {
|
|
384
|
+
input: (0, $7e790a73eaf2b445$export$2e2bcd8739ae039)
|
|
385
|
+
},
|
|
386
|
+
options: {
|
|
387
|
+
languages: languages
|
|
388
|
+
},
|
|
389
|
+
of: [
|
|
390
|
+
(0, $k7rGe$sanity.defineField)({
|
|
391
|
+
name: objectName,
|
|
392
|
+
type: objectName
|
|
393
|
+
})
|
|
394
|
+
],
|
|
395
|
+
validation: (rule)=>rule.max(languages?.length).custom((value, context)=>{
|
|
396
|
+
const { languages: contextLanguages } = context?.type?.options ?? {};
|
|
397
|
+
const nonLanguageKeys = value?.length ? value.filter((item)=>!contextLanguages.find((language)=>item._key === language.id)) : [];
|
|
398
|
+
if (nonLanguageKeys.length) return {
|
|
399
|
+
message: `Array item keys must be valid languages registered to the field type`,
|
|
400
|
+
paths: nonLanguageKeys.map((item)=>[
|
|
401
|
+
{
|
|
402
|
+
_key: item._key
|
|
403
|
+
}
|
|
404
|
+
])
|
|
405
|
+
};
|
|
406
|
+
const valuesByLanguage = value?.length ? value.filter((item)=>Boolean(item?._key)).reduce((acc, cur)=>{
|
|
407
|
+
if (acc[cur._key]) return {
|
|
408
|
+
...acc,
|
|
409
|
+
[cur._key]: [
|
|
410
|
+
...acc[cur._key],
|
|
411
|
+
cur
|
|
412
|
+
]
|
|
413
|
+
};
|
|
414
|
+
return {
|
|
415
|
+
...acc,
|
|
416
|
+
[cur._key]: [
|
|
417
|
+
cur
|
|
418
|
+
]
|
|
419
|
+
};
|
|
420
|
+
}, {}) : {};
|
|
421
|
+
const duplicateValues = Object.values(valuesByLanguage).filter((item)=>item?.length > 1).flat();
|
|
422
|
+
if (duplicateValues.length) return {
|
|
423
|
+
message: "There can only be one field per language",
|
|
424
|
+
paths: duplicateValues.map((item)=>[
|
|
425
|
+
{
|
|
426
|
+
_key: item._key
|
|
427
|
+
}
|
|
428
|
+
])
|
|
429
|
+
};
|
|
430
|
+
return true;
|
|
431
|
+
})
|
|
432
|
+
});
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
var $f727fb16d5d00f8f$export$2e2bcd8739ae039 = (config)=>{
|
|
439
|
+
const { type: type } = config;
|
|
440
|
+
const typeName = typeof type === `string` ? type : type.name;
|
|
441
|
+
const objectName = (0, $a0eca5cb1c058e2c$export$ab1ce2a474f41f52)(typeName, true);
|
|
442
|
+
return (0, $k7rGe$sanity.defineField)({
|
|
443
|
+
name: objectName,
|
|
444
|
+
title: `Internationalized array ${type}`,
|
|
445
|
+
type: "object",
|
|
446
|
+
fields: [
|
|
447
|
+
typeof type === `string` ? (0, $k7rGe$sanity.defineField)({
|
|
448
|
+
name: "value",
|
|
449
|
+
type: type
|
|
450
|
+
}) : {
|
|
451
|
+
...type,
|
|
452
|
+
name: "value"
|
|
453
|
+
},
|
|
454
|
+
]
|
|
455
|
+
});
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
const $45e3093e7de8dca2$var$CONFIG_DEFAULT = {
|
|
460
|
+
languages: [],
|
|
461
|
+
fieldTypes: []
|
|
462
|
+
};
|
|
463
|
+
const $45e3093e7de8dca2$export$bec7eb13daf35f0e = (0, $k7rGe$sanity.createPlugin)((config = $45e3093e7de8dca2$var$CONFIG_DEFAULT)=>{
|
|
464
|
+
const { languages: languages , fieldTypes: fieldTypes } = {
|
|
465
|
+
...$45e3093e7de8dca2$var$CONFIG_DEFAULT,
|
|
466
|
+
...config
|
|
467
|
+
};
|
|
468
|
+
return {
|
|
469
|
+
name: "sanity-plugin-internationalized-array",
|
|
470
|
+
schema: {
|
|
471
|
+
types: [
|
|
472
|
+
...fieldTypes.map((type)=>(0, $0437df2e2e149362$export$2e2bcd8739ae039)({
|
|
473
|
+
type: type,
|
|
474
|
+
languages: languages
|
|
475
|
+
})),
|
|
476
|
+
...fieldTypes.map((type)=>(0, $f727fb16d5d00f8f$export$2e2bcd8739ae039)({
|
|
477
|
+
type: type
|
|
478
|
+
})),
|
|
479
|
+
]
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
//# sourceMappingURL=index.js.map
|