@sanity/language-filter 0.147.10-ts-client.1 → 1.0.0-firstpass-v3-impl.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 +122 -28
- package/lib/cjs/index.js +338 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/esm/index.js +329 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/types/index.d.ts +73 -0
- package/lib/types/index.d.ts.map +1 -0
- package/package.json +77 -27
- package/sanity.json +2 -10
- package/src/LanguageFilterMenuButton.tsx +128 -0
- package/src/LanguageFilterObjectInput.tsx +33 -0
- package/src/filterField.test.ts +91 -0
- package/src/filterField.ts +34 -0
- package/src/index.ts +26 -0
- package/src/plugin.tsx +67 -0
- package/src/types.ts +27 -0
- package/src/usePaneLanguages.ts +81 -0
- package/v2-incompatible.js +11 -0
- package/lib/SelectLanguage.js +0 -139
- package/lib/SelectLanguageProvider.js +0 -52
- package/lib/datastore.js +0 -48
- package/lib/filter-fields.js +0 -13
- package/lib/styles/SelectLanguage.css +0 -50
- package/src/SelectLanguage.js +0 -106
- package/src/SelectLanguageProvider.js +0 -28
- package/src/datastore.js +0 -42
- package/src/filter-fields.js +0 -1
- package/src/styles/SelectLanguage.css +0 -50
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,43 +1,137 @@
|
|
|
1
|
-
|
|
1
|
+
# @sanity/language-filter
|
|
2
|
+
|
|
3
|
+
> **NOTE**
|
|
4
|
+
>
|
|
5
|
+
> This is the **Sanity Studio v3 version** of @sanity/language-filter.
|
|
6
|
+
>
|
|
7
|
+
> For the v2 version, please refer to the [v2 version](https://github.com/sanity-io/sanity/tree/next/packages/%40sanity/language-filter).
|
|
8
|
+
|
|
9
|
+
# Field-level translation filter Plugin for Sanity.io
|
|
2
10
|
|
|
3
11
|
A Sanity plugin that supports filtering localized fields by language
|
|
4
12
|
|
|
5
|
-
|
|
13
|
+

|
|
6
14
|
|
|
7
|
-
|
|
15
|
+
## What this plugin solves
|
|
8
16
|
|
|
9
|
-
|
|
17
|
+
There are two popular methods of internationalization in Sanity Studio:
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
- **Field-level translation**
|
|
20
|
+
- A single document with many languages of content
|
|
21
|
+
- Achieved by mapping over languages on each field, to create an object
|
|
22
|
+
- Best for documents that have a mix of language-specific and common fields
|
|
23
|
+
- Not recommended for Portable Text
|
|
24
|
+
- **Document-level translation**
|
|
25
|
+
- A unique document version for every language
|
|
26
|
+
- Joined together by references and/or a predictable `_id`
|
|
27
|
+
- Best for documents that have unique, language-specific fields and no common content across languages
|
|
28
|
+
- Best for translating content using Portable Text
|
|
12
29
|
|
|
13
|
-
|
|
14
|
-
This config file needs to implement the part `part:@sanity/language-filter/config`, by adding the following lines to the `parts`-section of your `sanity.json`
|
|
30
|
+
This plugin adds features to the Studio to improve handling **field-level translations**.
|
|
15
31
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
32
|
+
- A "Filter Languages" button to show/hide fields in an object of language-specific fields
|
|
33
|
+
- Configuration to set "default" languages which are always visible
|
|
34
|
+
|
|
35
|
+
For **document-level translations** you should use the [@sanity/document-internationalization plugin](https://www.npmjs.com/package/@sanity/document-internationalization).
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
npm install --save @sanity/language-filter@studio-v3
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
or
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
yarn add @sanity/language-filter@studio-v3
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Usage
|
|
51
|
+
Add it as a plugin in sanity.config.ts (or .js), and configure it:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
import {createConfig} from 'sanity'
|
|
55
|
+
import {languageFilter} from '@sanity/language-filter'
|
|
56
|
+
|
|
57
|
+
export const createConfig({
|
|
58
|
+
//...
|
|
59
|
+
plugins: [
|
|
60
|
+
languageFilter({
|
|
61
|
+
supportedLanguages: [
|
|
62
|
+
{id: 'nb', title: 'Norwegian (Bokmål)'},
|
|
63
|
+
{id: 'nn', title: 'Norwegian (Nynorsk)'},
|
|
64
|
+
{id: 'en', title: 'English'},
|
|
65
|
+
{id: 'es', title: 'Spanish'},
|
|
66
|
+
{id: 'arb', title: 'Arabic'},
|
|
67
|
+
{id: 'pt', title: 'Portuguese'},
|
|
68
|
+
//...
|
|
69
|
+
],
|
|
70
|
+
// Select Norwegian (Bokmål) by default
|
|
71
|
+
defaultLanguages: ['nb'],
|
|
72
|
+
// Only show language filter for document type `page` (schemaType.name)
|
|
73
|
+
documentTypes: ['page'],
|
|
74
|
+
filterField: (enclosingType, field, selectedLanguageIds) =>
|
|
75
|
+
!enclosingType.name.startsWith('locale') || selectedLanguageIds.includes(field.name),
|
|
76
|
+
})
|
|
77
|
+
]
|
|
78
|
+
})
|
|
21
79
|
```
|
|
22
80
|
|
|
23
|
-
|
|
81
|
+
Config properties:
|
|
82
|
+
- `supportedLanguages` is an array of languages with `id` and `title`. If your localized fields are defined using our recommended way described here (https://www.sanity.io/docs/localization), you probably want to share this list of supported languages between this config and your schema.
|
|
83
|
+
- `defaultLanguages` (optional) is an array of strings where each entry must match an `id` from the `supportedLanguages` array. These languages will be listed by default and will not be possible to unselect. If no `defaultLanguages` is configured, all localized fields will be selected by default.
|
|
84
|
+
- `documentTypes` (optional) is an array of strings where each entry must match a `name` from your document schemas. If defined, this property will be used to conditionally show the language filter on specific document schema types. If undefined, the language filter will show on all document schema types.
|
|
85
|
+
- `filterField` (optional) is a function that must return true if the field should be displayed. It is passed the enclosing type (e.g the object type containing the localized fields, the field, and an array of the currently selected language ids.
|
|
86
|
+
This function is called for all fields and fieldsets in objects for documents that have language filter enabled.
|
|
87
|
+
_Default:_ `!enclosingType.name.startsWith('locale') || selectedLanguageIds.includes(field.name)`
|
|
88
|
+
|
|
89
|
+
## Changes in V3
|
|
90
|
+
|
|
91
|
+
### filterField
|
|
92
|
+
`filerField` will also be passed any fieldsets in the enclosing object, when present.
|
|
93
|
+
|
|
94
|
+
### documentTypes
|
|
95
|
+
Language filter can now be enabled/disabled directly from a schema, using `options.languageFilter: boolean`.
|
|
96
|
+
When `documentTypes` is omitted from plugin config, use `options.languageFilter: false` in a document-definition to hide the filter button.
|
|
97
|
+
When `documentTypes` is provided in plugin config, use `options.languageFilter: true` in a document-definition to show the filter button.
|
|
98
|
+
|
|
99
|
+
Example:
|
|
24
100
|
|
|
25
101
|
```js
|
|
26
|
-
export
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
{id: 'pt', title: 'Portuguese'}
|
|
35
|
-
//...
|
|
36
|
-
],
|
|
37
|
-
filterField: (enclosingType, field, selectedLanguageIds) =>
|
|
38
|
-
!enclosingType.name.startsWith('locale') || selectedLanguageIds.includes(field.name)
|
|
102
|
+
export const myDocumentSchema = {
|
|
103
|
+
type: 'document',
|
|
104
|
+
name: 'my-enabled-language-filter-document',
|
|
105
|
+
/** ... */
|
|
106
|
+
options: {
|
|
107
|
+
// show language filter for this document type, regardless of how documentTypes for the plugin is configured
|
|
108
|
+
languageFilter: true
|
|
109
|
+
}
|
|
39
110
|
}
|
|
40
111
|
```
|
|
41
112
|
|
|
42
|
-
|
|
43
|
-
|
|
113
|
+
### State management
|
|
114
|
+
Selected languages are now stored as `langs` url-param state; this allows users to copy paste
|
|
115
|
+
a url in the studio with the currently selected languages preselected.
|
|
116
|
+
|
|
117
|
+
Previously this state was stored in localstorage.
|
|
118
|
+
|
|
119
|
+
## License
|
|
120
|
+
|
|
121
|
+
MIT © Sanity.io
|
|
122
|
+
See LICENSE
|
|
123
|
+
|
|
124
|
+
## Develop
|
|
125
|
+
|
|
126
|
+
This plugin uses [@sanity/plugin-kit](https://github.com/sanity-io/plugin-kit)
|
|
127
|
+
with default configuration for build & watch scripts.
|
|
128
|
+
|
|
129
|
+
See [Testing a plugin in Sanity Studio](https://github.com/sanity-io/plugin-kit#testing-a-plugin-in-sanity-studio)
|
|
130
|
+
on how to run this plugin with hotreload in the studio.
|
|
131
|
+
|
|
132
|
+
### Release new version
|
|
133
|
+
|
|
134
|
+
Run ["CI & Release" workflow](https://github.com/sanity-io/language-filter/actions/workflows/main.yml).
|
|
135
|
+
Make sure to select the main branch and check "Release new version".
|
|
136
|
+
|
|
137
|
+
Semantic release will only release on configured branches, so it is safe to run release on any branch.
|
package/lib/cjs/index.js
ADDED
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
var $k7rGe$reactjsxruntime = require("react/jsx-runtime");
|
|
2
|
+
var $k7rGe$react = require("react");
|
|
3
|
+
var $k7rGe$sanity = require("sanity");
|
|
4
|
+
var $k7rGe$sanityform = require("sanity/form");
|
|
5
|
+
var $k7rGe$sanitydesk = require("sanity/desk");
|
|
6
|
+
var $k7rGe$sanityicons = require("@sanity/icons");
|
|
7
|
+
var $k7rGe$sanityui = require("@sanity/ui");
|
|
8
|
+
|
|
9
|
+
function $parcel$export(e, n, v, s) {
|
|
10
|
+
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
$parcel$export(module.exports, "languageFilter", () => $45e3093e7de8dca2$export$bae498c4212cce68);
|
|
14
|
+
$parcel$export(module.exports, "defaultFilterField", () => $f29012bc04d39674$export$373781be62a9896e);
|
|
15
|
+
$parcel$export(module.exports, "isLanguageFilterEnabled", () => $f29012bc04d39674$export$fe9baa09973dbf22);
|
|
16
|
+
$parcel$export(module.exports, "LanguageFilterObjectInput", () => $a0f4109b367c6ff0$export$7f9ce1f19dc34df5);
|
|
17
|
+
$parcel$export(module.exports, "LanguageFilterMenuButton", () => $4de932c0c6553dd2$export$85fc605f11895007);
|
|
18
|
+
$parcel$export(module.exports, "usePaneLanguages", () => $b7317e67f107ab55$export$cd56401a2a088ead);
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
// NOTE: use `+` instead of `,` since the desk tool URL format already uses comma
|
|
28
|
+
const $b7317e67f107ab55$var$LANG_ID_SEPARATOR = "+";
|
|
29
|
+
function $b7317e67f107ab55$export$cd56401a2a088ead(props) {
|
|
30
|
+
const { options: options } = props;
|
|
31
|
+
const { params: params , setParams: setParams } = (0, $k7rGe$sanitydesk.usePaneRouter)();
|
|
32
|
+
const { supportedLanguages: supportedLanguages , defaultLanguages: defaultLanguages } = options;
|
|
33
|
+
const selectableLanguages = (0, $k7rGe$react.useMemo)(()=>supportedLanguages.filter((lang)=>!defaultLanguages?.includes(lang.id)), [
|
|
34
|
+
supportedLanguages,
|
|
35
|
+
defaultLanguages
|
|
36
|
+
]);
|
|
37
|
+
const selectedLanguages = (0, $k7rGe$react.useMemo)(()=>{
|
|
38
|
+
if (params?.langs === "$none") return [];
|
|
39
|
+
if (params?.langs === "$all") return selectableLanguages.map((lang)=>lang.id);
|
|
40
|
+
return params?.langs?.split($b7317e67f107ab55$var$LANG_ID_SEPARATOR) || selectableLanguages.map((lang)=>lang.id);
|
|
41
|
+
}, [
|
|
42
|
+
params,
|
|
43
|
+
selectableLanguages
|
|
44
|
+
]);
|
|
45
|
+
const selectAll = (0, $k7rGe$react.useCallback)(()=>{
|
|
46
|
+
setParams({
|
|
47
|
+
...params,
|
|
48
|
+
langs: "$all"
|
|
49
|
+
});
|
|
50
|
+
}, [
|
|
51
|
+
params,
|
|
52
|
+
setParams
|
|
53
|
+
]);
|
|
54
|
+
const selectNone = (0, $k7rGe$react.useCallback)(()=>{
|
|
55
|
+
setParams({
|
|
56
|
+
...params,
|
|
57
|
+
langs: "$none"
|
|
58
|
+
});
|
|
59
|
+
}, [
|
|
60
|
+
params,
|
|
61
|
+
setParams
|
|
62
|
+
]);
|
|
63
|
+
const toggleLanguage = (0, $k7rGe$react.useCallback)((languageId)=>{
|
|
64
|
+
let lang = selectedLanguages;
|
|
65
|
+
if (lang.includes(languageId)) lang = lang.filter((l)=>l !== languageId);
|
|
66
|
+
else lang = [
|
|
67
|
+
...lang,
|
|
68
|
+
languageId
|
|
69
|
+
];
|
|
70
|
+
if (lang.length === 0) {
|
|
71
|
+
setParams({
|
|
72
|
+
...params,
|
|
73
|
+
langs: "$none"
|
|
74
|
+
}) // none
|
|
75
|
+
;
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (lang.length === selectableLanguages.length) {
|
|
79
|
+
setParams({
|
|
80
|
+
...params,
|
|
81
|
+
langs: "$all"
|
|
82
|
+
});
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
setParams({
|
|
86
|
+
...params,
|
|
87
|
+
langs: lang.join($b7317e67f107ab55$var$LANG_ID_SEPARATOR)
|
|
88
|
+
});
|
|
89
|
+
}, [
|
|
90
|
+
params,
|
|
91
|
+
selectableLanguages,
|
|
92
|
+
selectedLanguages,
|
|
93
|
+
setParams
|
|
94
|
+
]);
|
|
95
|
+
const visibleLanguages = (0, $k7rGe$react.useMemo)(()=>[
|
|
96
|
+
...defaultLanguages ?? [],
|
|
97
|
+
...selectedLanguages
|
|
98
|
+
], [
|
|
99
|
+
defaultLanguages,
|
|
100
|
+
selectedLanguages
|
|
101
|
+
]);
|
|
102
|
+
return {
|
|
103
|
+
visibleLanguages: visibleLanguages,
|
|
104
|
+
allSelected: selectedLanguages.length === selectableLanguages.length,
|
|
105
|
+
selectAll: selectAll,
|
|
106
|
+
selectNone: selectNone,
|
|
107
|
+
toggleLanguage: toggleLanguage
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
const $f29012bc04d39674$export$373781be62a9896e = (enclosingType, field, selectedLanguageIds)=>!enclosingType.name.startsWith("locale") || selectedLanguageIds.includes(field.name);
|
|
113
|
+
function $f29012bc04d39674$export$fe9baa09973dbf22(schemaType, options) {
|
|
114
|
+
const schemaFilter = $f29012bc04d39674$var$isDocument(schemaType) && schemaType?.options?.languageFilter;
|
|
115
|
+
const defaultEnabled = !options.documentTypes;
|
|
116
|
+
return !!(defaultEnabled && schemaFilter !== false || !defaultEnabled && schemaFilter || schemaType && options.documentTypes?.includes(schemaType.name));
|
|
117
|
+
}
|
|
118
|
+
function $f29012bc04d39674$var$isDocument(schemaType) {
|
|
119
|
+
return schemaType?.jsonType === "object" && $f29012bc04d39674$var$getRootType(schemaType).name === "document";
|
|
120
|
+
}
|
|
121
|
+
function $f29012bc04d39674$var$getRootType(schema) {
|
|
122
|
+
if (schema.type) return $f29012bc04d39674$var$getRootType(schema.type);
|
|
123
|
+
return schema;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
function $a0f4109b367c6ff0$export$7f9ce1f19dc34df5(props) {
|
|
128
|
+
const { members: membersProp , level: level , options: options , path: path , schemaType: schemaType , ...restProps } = props;
|
|
129
|
+
const { visibleLanguages: visibleLanguages } = (0, $b7317e67f107ab55$export$cd56401a2a088ead)({
|
|
130
|
+
options: options
|
|
131
|
+
});
|
|
132
|
+
const filterField = options.filterField ?? (0, $f29012bc04d39674$export$373781be62a9896e);
|
|
133
|
+
const members = (0, $k7rGe$react.useMemo)(()=>{
|
|
134
|
+
return membersProp.filter((member)=>member.kind === "field" && filterField(schemaType, member, visibleLanguages) || member.kind === "fieldSet" && filterField(schemaType, member.fieldSet, visibleLanguages));
|
|
135
|
+
}, [
|
|
136
|
+
schemaType,
|
|
137
|
+
membersProp,
|
|
138
|
+
filterField,
|
|
139
|
+
visibleLanguages
|
|
140
|
+
]);
|
|
141
|
+
return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityform.ObjectInput), {
|
|
142
|
+
...restProps,
|
|
143
|
+
level: level,
|
|
144
|
+
members: members,
|
|
145
|
+
path: path,
|
|
146
|
+
schemaType: schemaType
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
function $4de932c0c6553dd2$export$85fc605f11895007(props) {
|
|
157
|
+
const { options: options } = props;
|
|
158
|
+
const defaultLanguages = options.supportedLanguages.filter((l)=>options.defaultLanguages?.includes(l.id));
|
|
159
|
+
const languageOptions = options.supportedLanguages.filter((l)=>!options.defaultLanguages?.includes(l.id));
|
|
160
|
+
const [open, setOpen] = (0, $k7rGe$react.useState)(false);
|
|
161
|
+
const { visibleLanguages: visibleLanguages , allSelected: allSelected , selectAll: selectAll , selectNone: selectNone , toggleLanguage: toggleLanguage } = (0, $b7317e67f107ab55$export$cd56401a2a088ead)({
|
|
162
|
+
options: options
|
|
163
|
+
});
|
|
164
|
+
const [button, setButton] = (0, $k7rGe$react.useState)(null);
|
|
165
|
+
const [popover, setPopover] = (0, $k7rGe$react.useState)(null);
|
|
166
|
+
const handleToggleAll = (0, $k7rGe$react.useCallback)((event)=>{
|
|
167
|
+
const checked = event.currentTarget.checked;
|
|
168
|
+
if (checked) selectAll();
|
|
169
|
+
else selectNone();
|
|
170
|
+
}, [
|
|
171
|
+
selectAll,
|
|
172
|
+
selectNone
|
|
173
|
+
]);
|
|
174
|
+
const handleClick = (0, $k7rGe$react.useCallback)(()=>setOpen((o)=>!o), []);
|
|
175
|
+
const handleClickOutside = (0, $k7rGe$react.useCallback)(()=>setOpen(false), []);
|
|
176
|
+
(0, $k7rGe$sanityui.useClickOutside)(handleClickOutside, [
|
|
177
|
+
button,
|
|
178
|
+
popover
|
|
179
|
+
]);
|
|
180
|
+
const content = /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Box), {
|
|
181
|
+
overflow: "auto",
|
|
182
|
+
padding: 1,
|
|
183
|
+
children: [
|
|
184
|
+
defaultLanguages.length > 0 && /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Card), {
|
|
185
|
+
radius: 2,
|
|
186
|
+
tone: "primary",
|
|
187
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Stack), {
|
|
188
|
+
padding: 2,
|
|
189
|
+
space: 3,
|
|
190
|
+
children: [
|
|
191
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Text), {
|
|
192
|
+
size: 1,
|
|
193
|
+
weight: "semibold",
|
|
194
|
+
children: [
|
|
195
|
+
"Default language",
|
|
196
|
+
defaultLanguages.length > 1 && /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$reactjsxruntime.Fragment), {
|
|
197
|
+
children: "s"
|
|
198
|
+
})
|
|
199
|
+
]
|
|
200
|
+
}),
|
|
201
|
+
defaultLanguages.map((l)=>/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Text), {
|
|
202
|
+
children: l.title
|
|
203
|
+
}, l.id))
|
|
204
|
+
]
|
|
205
|
+
})
|
|
206
|
+
}),
|
|
207
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Stack), {
|
|
208
|
+
marginTop: 3,
|
|
209
|
+
padding: 2,
|
|
210
|
+
space: 2,
|
|
211
|
+
children: [
|
|
212
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
|
|
213
|
+
paddingBottom: 1,
|
|
214
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Text), {
|
|
215
|
+
size: 1,
|
|
216
|
+
weight: "semibold",
|
|
217
|
+
children: "Show translations"
|
|
218
|
+
})
|
|
219
|
+
}),
|
|
220
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Card), {
|
|
221
|
+
as: "label",
|
|
222
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Flex), {
|
|
223
|
+
align: "center",
|
|
224
|
+
gap: 2,
|
|
225
|
+
children: [
|
|
226
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Checkbox), {
|
|
227
|
+
checked: allSelected,
|
|
228
|
+
name: "_allSelected",
|
|
229
|
+
onChange: handleToggleAll
|
|
230
|
+
}),
|
|
231
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
|
|
232
|
+
flex: 1,
|
|
233
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Text), {
|
|
234
|
+
muted: !allSelected,
|
|
235
|
+
weight: "semibold",
|
|
236
|
+
children: "All translations"
|
|
237
|
+
})
|
|
238
|
+
})
|
|
239
|
+
]
|
|
240
|
+
})
|
|
241
|
+
}),
|
|
242
|
+
languageOptions.map((lang)=>/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)($4de932c0c6553dd2$var$LanguageFilterOption, {
|
|
243
|
+
id: lang.id,
|
|
244
|
+
onToggle: toggleLanguage,
|
|
245
|
+
selected: visibleLanguages.includes(lang.id),
|
|
246
|
+
title: lang.title
|
|
247
|
+
}, lang.id))
|
|
248
|
+
]
|
|
249
|
+
})
|
|
250
|
+
]
|
|
251
|
+
});
|
|
252
|
+
return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Popover), {
|
|
253
|
+
constrainSize: true,
|
|
254
|
+
content: content,
|
|
255
|
+
open: open,
|
|
256
|
+
portal: true,
|
|
257
|
+
ref: setPopover,
|
|
258
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Button), {
|
|
259
|
+
icon: (0, $k7rGe$sanityicons.TranslateIcon),
|
|
260
|
+
text: `Filter languages (${visibleLanguages.length}/${options.supportedLanguages.length})`,
|
|
261
|
+
mode: "bleed",
|
|
262
|
+
onClick: handleClick,
|
|
263
|
+
ref: setButton,
|
|
264
|
+
selected: open
|
|
265
|
+
})
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
function $4de932c0c6553dd2$var$LanguageFilterOption(props) {
|
|
269
|
+
const { id: id , onToggle: onToggle , selected: selected , title: title } = props;
|
|
270
|
+
const handleChange = (0, $k7rGe$react.useCallback)(()=>{
|
|
271
|
+
onToggle(id);
|
|
272
|
+
}, [
|
|
273
|
+
id,
|
|
274
|
+
onToggle
|
|
275
|
+
]);
|
|
276
|
+
return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Card), {
|
|
277
|
+
as: "label",
|
|
278
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Flex), {
|
|
279
|
+
align: "center",
|
|
280
|
+
gap: 2,
|
|
281
|
+
children: [
|
|
282
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Checkbox), {
|
|
283
|
+
checked: selected,
|
|
284
|
+
name: `language-${id}`,
|
|
285
|
+
onChange: handleChange
|
|
286
|
+
}),
|
|
287
|
+
/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
|
|
288
|
+
flex: 1,
|
|
289
|
+
children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Text), {
|
|
290
|
+
muted: !selected,
|
|
291
|
+
children: title
|
|
292
|
+
})
|
|
293
|
+
})
|
|
294
|
+
]
|
|
295
|
+
})
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
const $45e3093e7de8dca2$export$bae498c4212cce68 = (0, $k7rGe$sanity.createPlugin)((options)=>{
|
|
302
|
+
const RenderLanguageFilter = ()=>{
|
|
303
|
+
return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $4de932c0c6553dd2$export$85fc605f11895007), {
|
|
304
|
+
options: options
|
|
305
|
+
});
|
|
306
|
+
};
|
|
307
|
+
return {
|
|
308
|
+
name: "@sanity/language-filter",
|
|
309
|
+
document: {
|
|
310
|
+
unstable_languageFilter: (prev, { schemaType: schemaType , schema: schema })=>{
|
|
311
|
+
if ((0, $f29012bc04d39674$export$fe9baa09973dbf22)(schema.get(schemaType), options)) return [
|
|
312
|
+
...prev,
|
|
313
|
+
RenderLanguageFilter
|
|
314
|
+
];
|
|
315
|
+
return prev;
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
form: {
|
|
319
|
+
renderInput (props, next) {
|
|
320
|
+
const enabled = (0, $f29012bc04d39674$export$fe9baa09973dbf22)(props.schemaType, options);
|
|
321
|
+
if (enabled && props.schemaType.jsonType === "object") return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $a0f4109b367c6ff0$export$7f9ce1f19dc34df5), {
|
|
322
|
+
...props,
|
|
323
|
+
options: options
|
|
324
|
+
});
|
|
325
|
+
return next(props);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","sources":["src/index.ts","src/plugin.tsx","src/LanguageFilterObjectInput.tsx","src/usePaneLanguages.ts","src/filterField.ts","src/LanguageFilterMenuButton.tsx"],"sourcesContent":["/**\n * Plugin function\n */\nexport {languageFilter} from './plugin'\n\nexport {defaultFilterField, isLanguageFilterEnabled} from './filterField'\n\nexport type {\n LanguageFilterConfig,\n LanguageFilterSchema,\n LanguageFilterOptions,\n FilterFieldFunction,\n Language,\n} from './types'\n\nexport {\n LanguageFilterObjectInput,\n type LanguageFilterObjectInputProps,\n} from './LanguageFilterObjectInput'\n\nexport {\n LanguageFilterMenuButton,\n type LanguageFilterMenuButtonProps,\n} from './LanguageFilterMenuButton'\n\nexport {usePaneLanguages} from './usePaneLanguages'\n","import React from 'react'\nimport {_DocumentLanguageFilterComponent, createPlugin, ObjectInputProps} from 'sanity'\nimport {LanguageFilterObjectInput} from './LanguageFilterObjectInput'\nimport {LanguageFilterMenuButton} from './LanguageFilterMenuButton'\nimport {LanguageFilterConfig} from './types'\nimport {isLanguageFilterEnabled} from './filterField'\n\n/**\n * ## Usage in sanity.config.ts (or .js)\n *\n * ```\n * import {createConfig} from 'sanity'\n * import {languageFilter} from '@sanity/language-filter'\n *\n * export const createConfig({\n * /...\n * plugins: [\n * languageFilter({\n * supportedLanguages: [\n * {id: 'nb', title: 'Norwegian (Bokmål)'},\n * {id: 'nn', title: 'Norwegian (Nynorsk)'},\n * {id: 'en', title: 'English'},\n * {id: 'es', title: 'Spanish'},\n * {id: 'arb', title: 'Arabic'},\n * {id: 'pt', title: 'Portuguese'},\n * //...\n * ],\n * // Select Norwegian (Bokmål) by default\n * defaultLanguages: ['nb'],\n * // Only show language filter for document type `page` (schemaType.name)\n * // Can also enable via document-options: options.languageFilter: true\n * documentTypes: ['page'],\n * // default filter function shown\n * filterField: (enclosingType, field, selectedLanguageIds) =>\n * !enclosingType.name.startsWith('locale') || selectedLanguageIds.includes(field.name),\n * })\n * ]\n * })\n * ```\n */\nexport const languageFilter = createPlugin<LanguageFilterConfig>((options) => {\n const RenderLanguageFilter: _DocumentLanguageFilterComponent = () => {\n return <LanguageFilterMenuButton options={options} />\n }\n\n return {\n name: '@sanity/language-filter',\n document: {\n unstable_languageFilter: (prev, {schemaType, schema}) => {\n if (isLanguageFilterEnabled(schema.get(schemaType), options)) {\n return [...prev, RenderLanguageFilter]\n }\n return prev\n },\n },\n\n form: {\n renderInput(props, next) {\n const enabled = isLanguageFilterEnabled(props.schemaType, options)\n if (enabled && props.schemaType.jsonType === 'object') {\n return <LanguageFilterObjectInput {...(props as ObjectInputProps)} options={options} />\n }\n return next(props)\n },\n },\n }\n})\n","import React, {useMemo} from 'react'\nimport {ObjectInputProps, ObjectMember} from 'sanity'\nimport {ObjectInput} from 'sanity/form'\nimport {usePaneLanguages} from './usePaneLanguages'\nimport {LanguageFilterConfig} from './types'\nimport {defaultFilterField} from './filterField'\n\nexport type LanguageFilterObjectInputProps = {options: LanguageFilterConfig} & ObjectInputProps\n\nexport function LanguageFilterObjectInput(props: LanguageFilterObjectInputProps) {\n const {members: membersProp, level, options, path, schemaType, ...restProps} = props\n const {visibleLanguages} = usePaneLanguages({options})\n\n const filterField = options.filterField ?? defaultFilterField\n\n const members: ObjectMember[] = useMemo(() => {\n return membersProp.filter(\n (member) =>\n (member.kind === 'field' && filterField(schemaType, member, visibleLanguages)) ||\n (member.kind === 'fieldSet' && filterField(schemaType, member.fieldSet, visibleLanguages))\n )\n }, [schemaType, membersProp, filterField, visibleLanguages])\n\n return (\n <ObjectInput\n {...restProps}\n level={level}\n members={members}\n path={path}\n schemaType={schemaType}\n />\n )\n}\n","import {useCallback, useMemo} from 'react'\nimport {usePaneRouter} from 'sanity/desk'\nimport {LanguageFilterConfig} from './types'\n\n// NOTE: use `+` instead of `,` since the desk tool URL format already uses comma\nconst LANG_ID_SEPARATOR = '+'\n\nexport function usePaneLanguages(props: {options: LanguageFilterConfig}): {\n visibleLanguages: string[]\n allSelected: boolean\n selectAll: () => void\n selectNone: () => void\n toggleLanguage: (languageId: string) => void\n} {\n const {options} = props\n const {params, setParams} = usePaneRouter()\n const {supportedLanguages, defaultLanguages} = options\n\n const selectableLanguages = useMemo(\n () => supportedLanguages.filter((lang) => !defaultLanguages?.includes(lang.id)),\n [supportedLanguages, defaultLanguages]\n )\n\n const selectedLanguages = useMemo(() => {\n if (params?.langs === '$none') {\n return []\n }\n\n if (params?.langs === '$all') {\n return selectableLanguages.map((lang) => lang.id)\n }\n\n return params?.langs?.split(LANG_ID_SEPARATOR) || selectableLanguages.map((lang) => lang.id)\n }, [params, selectableLanguages])\n\n const selectAll = useCallback(() => {\n setParams({...params, langs: '$all'})\n }, [params, setParams])\n\n const selectNone = useCallback(() => {\n setParams({...params, langs: '$none'})\n }, [params, setParams])\n\n const toggleLanguage = useCallback(\n (languageId: string) => {\n let lang = selectedLanguages\n\n if (lang.includes(languageId)) {\n lang = lang.filter((l) => l !== languageId)\n } else {\n lang = [...lang, languageId]\n }\n\n if (lang.length === 0) {\n setParams({...params, langs: '$none'}) // none\n return\n }\n\n if (lang.length === selectableLanguages.length) {\n setParams({...params, langs: '$all'})\n return\n }\n\n setParams({...params, langs: lang.join(LANG_ID_SEPARATOR)})\n },\n [params, selectableLanguages, selectedLanguages, setParams]\n )\n\n const visibleLanguages = useMemo(\n () => [...(defaultLanguages ?? []), ...selectedLanguages],\n [defaultLanguages, selectedLanguages]\n )\n\n return {\n visibleLanguages,\n allSelected: selectedLanguages.length === selectableLanguages.length,\n selectAll,\n selectNone,\n toggleLanguage,\n }\n}\n","import type {SchemaType} from 'sanity'\nimport {FilterFieldFunction, LanguageFilterConfig, LanguageFilterSchema} from './types'\n\nexport const defaultFilterField: FilterFieldFunction = (\n enclosingType,\n field,\n selectedLanguageIds\n) => !enclosingType.name.startsWith('locale') || selectedLanguageIds.includes(field.name)\n\nexport function isLanguageFilterEnabled(\n schemaType: SchemaType | undefined,\n options: LanguageFilterConfig\n): boolean {\n const schemaFilter =\n isDocument(schemaType) && (schemaType as LanguageFilterSchema)?.options?.languageFilter\n const defaultEnabled = !options.documentTypes\n\n return !!(\n (defaultEnabled && schemaFilter !== false) ||\n (!defaultEnabled && schemaFilter) ||\n (schemaType && options.documentTypes?.includes(schemaType.name))\n )\n}\n\nfunction isDocument(schemaType?: SchemaType) {\n return schemaType?.jsonType === 'object' && getRootType(schemaType).name === 'document'\n}\n\nfunction getRootType(schema: SchemaType): SchemaType {\n if (schema.type) {\n return getRootType(schema.type)\n }\n return schema\n}\n","import {TranslateIcon} from '@sanity/icons'\nimport {Box, Button, Card, Checkbox, Flex, Popover, Stack, Text, useClickOutside} from '@sanity/ui'\nimport React, {FormEvent, useCallback, useState} from 'react'\nimport {usePaneLanguages} from './usePaneLanguages'\nimport {LanguageFilterConfig} from './types'\n\nexport interface LanguageFilterMenuButtonProps {\n options: LanguageFilterConfig\n}\n\nexport function LanguageFilterMenuButton(props: LanguageFilterMenuButtonProps) {\n const {options} = props\n const defaultLanguages = options.supportedLanguages.filter((l) =>\n options.defaultLanguages?.includes(l.id)\n )\n const languageOptions = options.supportedLanguages.filter(\n (l) => !options.defaultLanguages?.includes(l.id)\n )\n const [open, setOpen] = useState(false)\n const {visibleLanguages, allSelected, selectAll, selectNone, toggleLanguage} = usePaneLanguages({\n options,\n })\n const [button, setButton] = useState<HTMLElement | null>(null)\n const [popover, setPopover] = useState<HTMLElement | null>(null)\n\n const handleToggleAll = useCallback(\n (event: FormEvent<HTMLInputElement>) => {\n const checked = event.currentTarget.checked\n\n if (checked) {\n selectAll()\n } else {\n selectNone()\n }\n },\n [selectAll, selectNone]\n )\n\n const handleClick = useCallback(() => setOpen((o) => !o), [])\n\n const handleClickOutside = useCallback(() => setOpen(false), [])\n\n useClickOutside(handleClickOutside, [button, popover])\n\n const content = (\n <Box overflow=\"auto\" padding={1}>\n {defaultLanguages.length > 0 && (\n <Card radius={2} tone=\"primary\">\n <Stack padding={2} space={3}>\n <Text size={1} weight=\"semibold\">\n Default language{defaultLanguages.length > 1 && <>s</>}\n </Text>\n\n {defaultLanguages.map((l) => (\n <Text key={l.id}>{l.title}</Text>\n ))}\n </Stack>\n </Card>\n )}\n\n <Stack marginTop={3} padding={2} space={2}>\n <Box paddingBottom={1}>\n <Text size={1} weight=\"semibold\">\n Show translations\n </Text>\n </Box>\n\n <Card as=\"label\">\n <Flex align=\"center\" gap={2}>\n <Checkbox checked={allSelected} name=\"_allSelected\" onChange={handleToggleAll} />\n <Box flex={1}>\n <Text muted={!allSelected} weight=\"semibold\">\n All translations\n </Text>\n </Box>\n </Flex>\n </Card>\n\n {languageOptions.map((lang) => (\n <LanguageFilterOption\n id={lang.id}\n key={lang.id}\n onToggle={toggleLanguage}\n selected={visibleLanguages.includes(lang.id)}\n title={lang.title}\n />\n ))}\n </Stack>\n </Box>\n )\n\n return (\n <Popover constrainSize content={content} open={open} portal ref={setPopover}>\n <Button\n icon={TranslateIcon}\n text={`Filter languages (${visibleLanguages.length}/${options.supportedLanguages.length})`}\n mode=\"bleed\"\n onClick={handleClick}\n ref={setButton}\n selected={open}\n />\n </Popover>\n )\n}\n\nfunction LanguageFilterOption(props: {\n id: string\n onToggle: (id: string) => void\n selected: boolean\n title: string\n}) {\n const {id, onToggle, selected, title} = props\n\n const handleChange = useCallback(() => {\n onToggle(id)\n }, [id, onToggle])\n\n return (\n <Card as=\"label\">\n <Flex align=\"center\" gap={2}>\n <Checkbox checked={selected} name={`language-${id}`} onChange={handleChange} />\n <Box flex={1}>\n <Text muted={!selected}>{title}</Text>\n </Box>\n </Flex>\n </Card>\n )\n}\n"],"names":[],"version":3,"file":"index.js.map","sourceRoot":"../../"}
|