@sanity/language-filter 2.31.2-performance-opts.9 → 3.0.0-v3-studio.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2016 - 2022 Sanity.io
3
+ Copyright (c) 2022 Sanity.io
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,3 +1,11 @@
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
+
1
9
  # Field-level translation filter Plugin for Sanity.io
2
10
 
3
11
  A Sanity plugin that supports filtering localized fields by language
@@ -26,50 +34,105 @@ This plugin adds features to the Studio to improve handling **field-level transl
26
34
 
27
35
  For **document-level translations** you should use the [@sanity/document-internationalization plugin](https://www.npmjs.com/package/@sanity/document-internationalization).
28
36
 
37
+
29
38
  ## Installation
30
39
 
31
40
  ```
32
- sanity install @sanity/language-filter
41
+ npm install --save @sanity/language-filter@studio-v3
33
42
  ```
34
43
 
35
- Installing with `sanity install` updates your `sanity.json` to include this plugin. If installing with npm or yarn, ensure your `plugins` array includes `@sanity/language-filter`.
36
-
37
- ### Add config file
44
+ or
38
45
 
39
- In order to know what languages are supported, this plugin needs to be set up with a config file that exports a few options.
46
+ ```
47
+ yarn add @sanity/language-filter@studio-v3
48
+ ```
40
49
 
41
- 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`
50
+ ## Usage
51
+ Add it as a plugin in sanity.config.ts (or .js), and configure it:
42
52
 
43
- ```json
44
- {
45
- "name": "part:@sanity/language-filter/config",
46
- "path": "./parts/languageFilterConfig.js"
47
- }
48
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
+ })
79
+ ```
80
+
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 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
+ ### documentTypes
92
+ Language filter can now be enabled/disabled directly from a schema, using `options.languageFilter: boolean`.
93
+ When `documentTypes` is omitted from plugin config, use `options.languageFilter: false` in a document-definition to hide the filter button.
94
+ When `documentTypes` is provided in plugin config, use `options.languageFilter: true` in a document-definition to show the filter button.
49
95
 
50
- Here's an example `languageFilterConfig.js` file:
96
+ Example:
51
97
 
52
98
  ```js
53
- export default {
54
- supportedLanguages: [
55
- {id: 'nb', title: 'Norwegian (Bokmål)'},
56
- {id: 'nn', title: 'Norwegian (Nynorsk)'},
57
- {id: 'en', title: 'English'},
58
- {id: 'es', title: 'Spanish'},
59
- {id: 'arb', title: 'Arabic'},
60
- {id: 'pt', title: 'Portuguese'},
61
- //...
62
- ],
63
- // Select Norwegian (Bokmål) by default
64
- defaultLanguages: ['nb'],
65
- // Only show language filter for document type `page` (schemaType.name)
66
- documentTypes: ['page'],
67
- filterField: (enclosingType, field, selectedLanguageIds) =>
68
- !enclosingType.name.startsWith('locale') || selectedLanguageIds.includes(field.name),
99
+ export const myDocumentSchema = {
100
+ type: 'document',
101
+ name: 'my-enabled-language-filter-document',
102
+ /** ... */
103
+ options: {
104
+ // show language filter for this document type, regardless of how documentTypes for the plugin is configured
105
+ languageFilter: true
106
+ }
69
107
  }
70
108
  ```
71
109
 
72
- - `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.
73
- - `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.
74
- - `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.
75
- - `filterField` 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.
110
+ ### State management
111
+ Selected languages are now stored as `langs` url-param state; this allows users to copy paste
112
+ a url in the studio with the currently selected languages preselected.
113
+
114
+ Previously this state was stored in localstorage.
115
+
116
+ ## License
117
+
118
+ MIT © Sanity.io
119
+ See LICENSE
120
+
121
+ ## Develop
122
+
123
+ This plugin uses [@sanity/plugin-kit](https://github.com/sanity-io/plugin-kit)
124
+ with default configuration for build & watch scripts.
125
+
126
+ See [Testing a plugin in Sanity Studio](https://github.com/sanity-io/plugin-kit#testing-a-plugin-in-sanity-studio)
127
+ on how to run this plugin with hotreload in the studio.
128
+
129
+ ### Release new version
130
+
131
+ Run ["CI & Release" workflow](https://github.com/sanity-io/language-filter/actions/workflows/main.yml).
132
+ Make sure to select the main branch and check "Release new version".
133
+
134
+ Semantic release will only release on configured branches, so it is safe to run release on any branch.
135
+
136
+ Note: main branch is configured to release a studio-v3 tagged version of the plugin.
137
+ To make semantic-release happy, the branch "semver-main-placeholder" is regarded as the non-prerelease branch,
138
+ but it is unused. The v2 version lives in the sanity mono-repo.
@@ -0,0 +1,438 @@
1
+ var $k7rGe$reactjsxruntime = require("react/jsx-runtime");
2
+ var $k7rGe$react = require("react");
3
+ var $k7rGe$sanity = require("sanity");
4
+ var $k7rGe$sanityui = require("@sanity/ui");
5
+
6
+ function $parcel$export(e, n, v, s) {
7
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
8
+ }
9
+
10
+ $parcel$export(module.exports, "languageFilter", () => $45e3093e7de8dca2$export$bae498c4212cce68);
11
+ $parcel$export(module.exports, "defaultFilterField", () => $f29012bc04d39674$export$373781be62a9896e);
12
+ $parcel$export(module.exports, "isLanguageFilterEnabled", () => $f29012bc04d39674$export$fe9baa09973dbf22);
13
+
14
+
15
+
16
+
17
+
18
+ const $f29012bc04d39674$export$373781be62a9896e = (enclosingType, field, selectedLanguageIds)=>!enclosingType.name.startsWith("locale") || selectedLanguageIds.includes(field.name);
19
+ function $f29012bc04d39674$export$fe9baa09973dbf22(schemaType, options) {
20
+ const schemaFilter = $f29012bc04d39674$var$isDocument(schemaType) && schemaType?.options?.languageFilter;
21
+ const defaultEnabled = !options.documentTypes;
22
+ return !!(defaultEnabled && schemaFilter !== false || !defaultEnabled && schemaFilter || schemaType && options.documentTypes?.includes(schemaType.name));
23
+ }
24
+ function $f29012bc04d39674$var$isDocument(schemaType) {
25
+ return schemaType?.jsonType === "object" && $f29012bc04d39674$var$getRootType(schemaType).name === "document";
26
+ }
27
+ function $f29012bc04d39674$var$getRootType(schema) {
28
+ if (schema.type) return $f29012bc04d39674$var$getRootType(schema.type);
29
+ return schema;
30
+ }
31
+
32
+
33
+
34
+
35
+ const $bb26db9356030deb$var$LanguageFilterContext = /*#__PURE__*/ (0, $k7rGe$react.createContext)(undefined);
36
+ function $bb26db9356030deb$export$f00537e9911d9516({ options: options , enabled: enabled , children: children }) {
37
+ const value = (0, $k7rGe$react.useMemo)(()=>({
38
+ options: options,
39
+ enabled: enabled
40
+ }), [
41
+ options,
42
+ enabled
43
+ ]);
44
+ return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)($bb26db9356030deb$var$LanguageFilterContext.Provider, {
45
+ value: value,
46
+ children: children
47
+ });
48
+ }
49
+ function $bb26db9356030deb$export$d5c74ca916607f46() {
50
+ const value = (0, $k7rGe$react.useContext)($bb26db9356030deb$var$LanguageFilterContext);
51
+ if (!value) throw new Error("LanguageFilterContext is missing");
52
+ return value;
53
+ }
54
+
55
+
56
+
57
+ const $fe597f02a0bccb26$var$storageKey = "@sanity/plugin/language-filter/selected-languages";
58
+ function $fe597f02a0bccb26$export$f21c039050fb95eb(options) {
59
+ const selectableLangs = $fe597f02a0bccb26$export$76676750ed98bafe(options).map((l)=>l.id);
60
+ let selected = selectableLangs;
61
+ try {
62
+ const persistedValue = window.localStorage.getItem($fe597f02a0bccb26$var$storageKey);
63
+ if (persistedValue) selected = JSON.parse(persistedValue);
64
+ } catch (err) {} // eslint-disable-line no-empty
65
+ // constrain persisted/selected languages to the ones currently supported
66
+ selected = $fe597f02a0bccb26$var$intersection(selected, selectableLangs);
67
+ return selected;
68
+ }
69
+ function $fe597f02a0bccb26$export$833b55f5102c4e70(languageIds) {
70
+ window.localStorage.setItem($fe597f02a0bccb26$var$storageKey, JSON.stringify(languageIds));
71
+ }
72
+ function $fe597f02a0bccb26$var$intersection(array1, array2) {
73
+ return array1.filter((value)=>array2.includes(value));
74
+ }
75
+ function $fe597f02a0bccb26$export$76676750ed98bafe({ supportedLanguages: supportedLanguages , defaultLanguages: defaultLanguages }) {
76
+ return supportedLanguages.filter((lang)=>!defaultLanguages?.includes(lang.id));
77
+ }
78
+ function $fe597f02a0bccb26$export$b484a630b97f9ca3(options) {
79
+ return (0, $k7rGe$react.useState)(()=>$fe597f02a0bccb26$export$f21c039050fb95eb(options));
80
+ }
81
+
82
+
83
+ function $a0f4109b367c6ff0$export$7f9ce1f19dc34df5(props) {
84
+ const { options: options , enabled: enabled } = (0, $bb26db9356030deb$export$d5c74ca916607f46)();
85
+ const { next: next , subscribeSelectedIds: subscribeSelectedIds , ...restProps } = props;
86
+ if (!enabled || !options) return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$reactjsxruntime.Fragment), {
87
+ children: next(restProps)
88
+ });
89
+ return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)($a0f4109b367c6ff0$var$FilteredObjectInput, {
90
+ ...restProps,
91
+ next: next,
92
+ options: options,
93
+ subscribeSelectedIds: subscribeSelectedIds
94
+ });
95
+ }
96
+ function $a0f4109b367c6ff0$var$FilteredObjectInput(props) {
97
+ const { members: membersProp , options: options , schemaType: schemaType , next: next , subscribeSelectedIds: subscribeSelectedIds , ...restProps } = props;
98
+ const [selectedIds, setSelectedIds] = (0, $fe597f02a0bccb26$export$b484a630b97f9ca3)(options);
99
+ (0, $k7rGe$react.useEffect)(()=>{
100
+ const unsubscribe = subscribeSelectedIds(setSelectedIds);
101
+ return ()=>unsubscribe();
102
+ }, [
103
+ subscribeSelectedIds,
104
+ setSelectedIds
105
+ ]);
106
+ const activeLanguages = (0, $k7rGe$react.useMemo)(()=>[
107
+ ...options.defaultLanguages ?? [],
108
+ ...selectedIds
109
+ ], [
110
+ options.defaultLanguages,
111
+ selectedIds
112
+ ]);
113
+ const filterField = options.filterField ?? (0, $f29012bc04d39674$export$373781be62a9896e);
114
+ const members = (0, $k7rGe$react.useMemo)(()=>{
115
+ return membersProp.filter((member)=>{
116
+ return member.kind === "field" && filterField(schemaType, member, activeLanguages) || member.kind === "fieldSet";
117
+ }).map((member)=>{
118
+ if (member.kind === "fieldSet") return {
119
+ ...member,
120
+ fieldSet: {
121
+ ...member.fieldSet,
122
+ members: member.fieldSet.members.filter((fieldsetMember)=>{
123
+ return fieldsetMember.kind === "field" && filterField(schemaType, fieldsetMember, activeLanguages);
124
+ })
125
+ }
126
+ };
127
+ return member;
128
+ });
129
+ }, [
130
+ schemaType,
131
+ membersProp,
132
+ filterField,
133
+ activeLanguages
134
+ ]);
135
+ return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$reactjsxruntime.Fragment), {
136
+ children: next({
137
+ ...restProps,
138
+ members: members,
139
+ schemaType: schemaType
140
+ })
141
+ });
142
+ }
143
+
144
+
145
+
146
+
147
+
148
+
149
+
150
+ function $b7317e67f107ab55$export$cd56401a2a088ead(props) {
151
+ const { options: options , onSelectedIdsChange: onSelectedIdsChange } = props;
152
+ const { defaultLanguages: defaultLanguages } = options;
153
+ const [selectedIds, setSelectedIds] = (0, $fe597f02a0bccb26$export$b484a630b97f9ca3)(options);
154
+ const selectableLanguages = (0, $k7rGe$react.useMemo)(()=>(0, $fe597f02a0bccb26$export$76676750ed98bafe)(options), [
155
+ options
156
+ ]);
157
+ const updateSelectedIds = (0, $k7rGe$react.useCallback)((ids)=>{
158
+ setSelectedIds(ids);
159
+ (0, $fe597f02a0bccb26$export$833b55f5102c4e70)(ids);
160
+ onSelectedIdsChange(ids);
161
+ }, [
162
+ onSelectedIdsChange,
163
+ setSelectedIds
164
+ ]);
165
+ const selectAll = (0, $k7rGe$react.useCallback)(()=>updateSelectedIds(selectableLanguages.map((l)=>l.id)), [
166
+ updateSelectedIds,
167
+ selectableLanguages
168
+ ]);
169
+ const selectNone = (0, $k7rGe$react.useCallback)(()=>{
170
+ updateSelectedIds([]);
171
+ }, [
172
+ updateSelectedIds
173
+ ]);
174
+ const toggleLanguage = (0, $k7rGe$react.useCallback)((languageId)=>{
175
+ let lang = selectedIds;
176
+ if (lang.includes(languageId)) lang = lang.filter((l)=>l !== languageId);
177
+ else lang = [
178
+ ...lang,
179
+ languageId
180
+ ];
181
+ updateSelectedIds(lang);
182
+ }, [
183
+ updateSelectedIds,
184
+ selectedIds
185
+ ]);
186
+ const activeLanguages = (0, $k7rGe$react.useMemo)(()=>[
187
+ ...defaultLanguages ?? [],
188
+ ...selectedIds
189
+ ], [
190
+ defaultLanguages,
191
+ selectedIds
192
+ ]);
193
+ return {
194
+ activeLanguages: activeLanguages,
195
+ allSelected: selectedIds.length === selectableLanguages.length,
196
+ selectAll: selectAll,
197
+ selectNone: selectNone,
198
+ toggleLanguage: toggleLanguage
199
+ };
200
+ }
201
+
202
+
203
+ function $4de932c0c6553dd2$export$85fc605f11895007(props) {
204
+ const { options: options , onSelectedIdsChange: onSelectedIdsChange } = props;
205
+ const defaultLanguages = options.supportedLanguages.filter((l)=>options.defaultLanguages?.includes(l.id));
206
+ const languageOptions = options.supportedLanguages.filter((l)=>!options.defaultLanguages?.includes(l.id));
207
+ const [open, setOpen] = (0, $k7rGe$react.useState)(false);
208
+ const { activeLanguages: activeLanguages , allSelected: allSelected , selectAll: selectAll , selectNone: selectNone , toggleLanguage: toggleLanguage } = (0, $b7317e67f107ab55$export$cd56401a2a088ead)({
209
+ options: options,
210
+ onSelectedIdsChange: onSelectedIdsChange
211
+ });
212
+ const [button, setButton] = (0, $k7rGe$react.useState)(null);
213
+ const [popover, setPopover] = (0, $k7rGe$react.useState)(null);
214
+ const handleToggleAll = (0, $k7rGe$react.useCallback)((event)=>{
215
+ const checked = event.currentTarget.checked;
216
+ if (checked) selectAll();
217
+ else selectNone();
218
+ }, [
219
+ selectAll,
220
+ selectNone
221
+ ]);
222
+ const handleClick = (0, $k7rGe$react.useCallback)(()=>setOpen((o)=>!o), []);
223
+ const handleClickOutside = (0, $k7rGe$react.useCallback)(()=>setOpen(false), []);
224
+ (0, $k7rGe$sanityui.useClickOutside)(handleClickOutside, [
225
+ button,
226
+ popover
227
+ ]);
228
+ const content = /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Box), {
229
+ overflow: "auto",
230
+ padding: 1,
231
+ children: [
232
+ defaultLanguages.length > 0 && /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Card), {
233
+ radius: 2,
234
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Stack), {
235
+ padding: 2,
236
+ space: 3,
237
+ children: [
238
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
239
+ paddingBottom: 2,
240
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Text), {
241
+ size: 1,
242
+ weight: "semibold",
243
+ children: [
244
+ "Default language",
245
+ defaultLanguages.length > 1 && /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$reactjsxruntime.Fragment), {
246
+ children: "s"
247
+ })
248
+ ]
249
+ })
250
+ }),
251
+ defaultLanguages.map((l)=>/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Text), {
252
+ children: l.title
253
+ }, l.id))
254
+ ]
255
+ })
256
+ }),
257
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Stack), {
258
+ marginTop: 3,
259
+ padding: 2,
260
+ space: 2,
261
+ children: [
262
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
263
+ paddingBottom: 2,
264
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Text), {
265
+ size: 1,
266
+ weight: "semibold",
267
+ children: "Show translations"
268
+ })
269
+ }),
270
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Card), {
271
+ as: "label",
272
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Flex), {
273
+ align: "center",
274
+ gap: 2,
275
+ children: [
276
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Checkbox), {
277
+ checked: allSelected,
278
+ name: "_allSelected",
279
+ onChange: handleToggleAll
280
+ }),
281
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
282
+ flex: 1,
283
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Text), {
284
+ muted: !allSelected,
285
+ weight: "semibold",
286
+ children: "All translations"
287
+ })
288
+ })
289
+ ]
290
+ })
291
+ }),
292
+ languageOptions.map((lang)=>/*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)($4de932c0c6553dd2$var$LanguageFilterOption, {
293
+ id: lang.id,
294
+ onToggle: toggleLanguage,
295
+ selected: activeLanguages.includes(lang.id),
296
+ title: lang.title
297
+ }, lang.id))
298
+ ]
299
+ })
300
+ ]
301
+ });
302
+ const langCount = options.supportedLanguages.length;
303
+ return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Popover), {
304
+ content: content,
305
+ open: open,
306
+ portal: true,
307
+ ref: setPopover,
308
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Button), {
309
+ text: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Flex), {
310
+ gap: 1,
311
+ children: [
312
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
313
+ children: "Filter languages:"
314
+ }),
315
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Flex), {
316
+ gap: 1,
317
+ justify: "space-around",
318
+ children: [
319
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Flex), {
320
+ style: {
321
+ width: `${Math.floor(Math.log10(langCount) + 1)}ch`
322
+ },
323
+ justify: "flex-end",
324
+ children: activeLanguages.length
325
+ }),
326
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
327
+ children: "/"
328
+ }),
329
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
330
+ children: langCount
331
+ })
332
+ ]
333
+ })
334
+ ]
335
+ }),
336
+ mode: "bleed",
337
+ onClick: handleClick,
338
+ ref: setButton,
339
+ selected: open
340
+ })
341
+ });
342
+ }
343
+ function $4de932c0c6553dd2$var$LanguageFilterOption(props) {
344
+ const { id: id , onToggle: onToggle , selected: selected , title: title } = props;
345
+ const handleChange = (0, $k7rGe$react.useCallback)(()=>{
346
+ onToggle(id);
347
+ }, [
348
+ id,
349
+ onToggle
350
+ ]);
351
+ return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Card), {
352
+ as: "label",
353
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Flex), {
354
+ align: "center",
355
+ gap: 2,
356
+ children: [
357
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Checkbox), {
358
+ checked: selected,
359
+ name: `language-${id}`,
360
+ onChange: handleChange
361
+ }),
362
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
363
+ flex: 1,
364
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Text), {
365
+ muted: !selected,
366
+ children: title
367
+ })
368
+ })
369
+ ]
370
+ })
371
+ });
372
+ }
373
+
374
+
375
+
376
+
377
+ function $a3222324b33f4bdf$export$de189c01fb1f896d() {
378
+ const subs = [];
379
+ const onSelectedIdsChange = (ids)=>{
380
+ subs.forEach((s)=>s(ids));
381
+ };
382
+ const subscribeSelectedIds = (subscription)=>{
383
+ subs.push(subscription);
384
+ return ()=>{
385
+ subs.splice(subs.indexOf(subscription), 1);
386
+ };
387
+ };
388
+ return {
389
+ onSelectedIdsChange: onSelectedIdsChange,
390
+ subscribeSelectedIds: subscribeSelectedIds
391
+ };
392
+ }
393
+
394
+
395
+ const $45e3093e7de8dca2$export$bae498c4212cce68 = (0, $k7rGe$sanity.createPlugin)((options)=>{
396
+ const { onSelectedIdsChange: onSelectedIdsChange , subscribeSelectedIds: subscribeSelectedIds } = (0, $a3222324b33f4bdf$export$de189c01fb1f896d)();
397
+ const RenderLanguageFilter = ()=>{
398
+ return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $4de932c0c6553dd2$export$85fc605f11895007), {
399
+ options: options,
400
+ onSelectedIdsChange: onSelectedIdsChange
401
+ });
402
+ };
403
+ return {
404
+ name: "@sanity/language-filter",
405
+ document: {
406
+ unstable_languageFilter: (prev, { schemaType: schemaType , schema: schema })=>{
407
+ if ((0, $f29012bc04d39674$export$fe9baa09973dbf22)(schema.get(schemaType), options)) return [
408
+ ...prev,
409
+ RenderLanguageFilter
410
+ ];
411
+ return prev;
412
+ }
413
+ },
414
+ form: {
415
+ renderInput (props, next) {
416
+ const enabled = (0, $f29012bc04d39674$export$fe9baa09973dbf22)(props.schemaType, options);
417
+ // will only be considered enabled for document, so this is only done once
418
+ if (enabled) return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $bb26db9356030deb$export$f00537e9911d9516), {
419
+ enabled: enabled,
420
+ options: options,
421
+ children: next(props)
422
+ });
423
+ if (props.schemaType.jsonType === "object") return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $a0f4109b367c6ff0$export$7f9ce1f19dc34df5), {
424
+ ...props,
425
+ next: next,
426
+ subscribeSelectedIds: subscribeSelectedIds
427
+ });
428
+ return undefined;
429
+ }
430
+ }
431
+ };
432
+ });
433
+
434
+
435
+
436
+
437
+
438
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"mappings":"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","sources":["src/index.ts","src/plugin.tsx","src/LanguageFilterObjectInput.tsx","src/filterField.ts","src/LanguageFilterContext.tsx","src/useSelectedLanguageIds.ts","src/LanguageFilterMenuButton.tsx","src/usePaneLanguages.ts","src/languageSubscription.ts"],"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","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'\nimport {LanguageFilterProvider} from './LanguageFilterContext'\nimport {createSelectedLanguageIdsBus} from './languageSubscription'\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 {onSelectedIdsChange, subscribeSelectedIds} = createSelectedLanguageIdsBus()\n\n const RenderLanguageFilter: _DocumentLanguageFilterComponent = () => {\n return <LanguageFilterMenuButton options={options} onSelectedIdsChange={onSelectedIdsChange} />\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 // will only be considered enabled for document, so this is only done once\n if (enabled) {\n return (\n <LanguageFilterProvider enabled={enabled} options={options}>\n {next(props)}\n </LanguageFilterProvider>\n )\n }\n if (props.schemaType.jsonType === 'object') {\n return (\n <LanguageFilterObjectInput\n {...(props as ObjectInputProps)}\n next={next}\n subscribeSelectedIds={subscribeSelectedIds}\n />\n )\n }\n\n return undefined\n },\n },\n }\n})\n","import React, {useEffect, useMemo} from 'react'\nimport {ObjectInputProps, ObjectMember, RenderInputCallback} from 'sanity'\nimport {LanguageFilterConfig} from './types'\nimport {defaultFilterField} from './filterField'\nimport {useLanguageFilterContext} from './LanguageFilterContext'\nimport {useSelectedLanguageIds} from './useSelectedLanguageIds'\n\nexport type LanguageFilterObjectInputProps = {\n options: LanguageFilterConfig\n next: RenderInputCallback\n /**\n * We need a way to communicate state changes between the pane menu and input components.\n * LanguageFilter button lives outside the input-render tree, so Context is out.\n * This is a workaround for that.\n */\n subscribeSelectedIds: (callback: (ids: string[]) => void) => () => void\n} & ObjectInputProps\n\nexport function LanguageFilterObjectInput(\n props: ObjectInputProps & {\n next: RenderInputCallback\n subscribeSelectedIds: (callback: (ids: string[]) => void) => () => void\n }\n) {\n const {options, enabled} = useLanguageFilterContext()\n const {next, subscribeSelectedIds, ...restProps} = props\n if (!enabled || !options) {\n return <>{next(restProps)}</>\n }\n return (\n <FilteredObjectInput\n {...restProps}\n next={next}\n options={options}\n subscribeSelectedIds={subscribeSelectedIds}\n />\n )\n}\n\nfunction FilteredObjectInput(props: LanguageFilterObjectInputProps) {\n const {\n members: membersProp,\n options,\n schemaType,\n next,\n subscribeSelectedIds,\n ...restProps\n } = props\n const [selectedIds, setSelectedIds] = useSelectedLanguageIds(options)\n\n useEffect(() => {\n const unsubscribe = subscribeSelectedIds(setSelectedIds)\n return () => unsubscribe()\n }, [subscribeSelectedIds, setSelectedIds])\n\n const activeLanguages = useMemo(\n () => [...(options.defaultLanguages ?? []), ...selectedIds],\n [options.defaultLanguages, selectedIds]\n )\n\n const filterField = options.filterField ?? defaultFilterField\n\n const members: ObjectMember[] = useMemo(() => {\n return membersProp\n .filter((member) => {\n return (\n (member.kind === 'field' && filterField(schemaType, member, activeLanguages)) ||\n member.kind === 'fieldSet'\n )\n })\n .map((member) => {\n if (member.kind === 'fieldSet') {\n return {\n ...member,\n fieldSet: {\n ...member.fieldSet,\n members: member.fieldSet.members.filter((fieldsetMember) => {\n return (\n fieldsetMember.kind === 'field' &&\n filterField(schemaType, fieldsetMember, activeLanguages)\n )\n }),\n },\n }\n }\n return member\n })\n }, [schemaType, membersProp, filterField, activeLanguages])\n\n return <>{next({...restProps, members, schemaType})}</>\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 React, {createContext, PropsWithChildren, useContext, useMemo} from 'react'\nimport {LanguageFilterConfig} from './types'\n\nexport interface LanguageFilterContextValue {\n // eslint-disable-next-line react/require-default-props\n options: LanguageFilterConfig\n // eslint-disable-next-line react/require-default-props\n enabled: boolean\n}\n\nconst LanguageFilterContext = createContext<LanguageFilterContextValue | undefined>(undefined)\n\nexport function LanguageFilterProvider({\n options,\n enabled,\n children,\n}: PropsWithChildren<\n Omit<LanguageFilterContextValue, 'selectedLanguageIds' | 'setSelectedLanguageIds'>\n>) {\n const value = useMemo(() => ({options, enabled}), [options, enabled])\n return <LanguageFilterContext.Provider value={value}>{children}</LanguageFilterContext.Provider>\n}\n\nexport function useLanguageFilterContext() {\n const value = useContext(LanguageFilterContext)\n if (!value) {\n throw new Error('LanguageFilterContext is missing')\n }\n return value\n}\n","import {Language, LanguageFilterConfig} from './types'\nimport {useState} from 'react'\nconst storageKey = '@sanity/plugin/language-filter/selected-languages'\n\nexport function getPersistedLanguageIds(options: LanguageFilterConfig): string[] {\n const selectableLangs = getSelectableLanguages(options).map((l) => l.id)\n\n let selected: string[] = selectableLangs\n try {\n const persistedValue = window.localStorage.getItem(storageKey)\n if (persistedValue) {\n selected = JSON.parse(persistedValue)\n }\n } catch (err) {} // eslint-disable-line no-empty\n\n // constrain persisted/selected languages to the ones currently supported\n selected = intersection(selected, selectableLangs)\n return selected\n}\n\nexport function persistLanguageIds(languageIds: string[]): void {\n window.localStorage.setItem(storageKey, JSON.stringify(languageIds))\n}\n\nfunction intersection(array1: string[], array2: string[]) {\n return array1.filter((value) => array2.includes(value))\n}\n\nexport function getSelectableLanguages({\n supportedLanguages,\n defaultLanguages,\n}: LanguageFilterConfig): Language[] {\n return supportedLanguages.filter((lang) => !defaultLanguages?.includes(lang.id))\n}\n\nexport function useSelectedLanguageIds(\n options: LanguageFilterConfig\n): [string[], (ids: string[]) => void] {\n return useState(() => getPersistedLanguageIds(options))\n}\n","import {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 onSelectedIdsChange: (ids: string[]) => void\n}\n\nexport function LanguageFilterMenuButton(props: LanguageFilterMenuButtonProps) {\n const {options, onSelectedIdsChange} = props\n\n const defaultLanguages = options.supportedLanguages.filter((l) =>\n options.defaultLanguages?.includes(l.id)\n )\n\n const languageOptions = options.supportedLanguages.filter(\n (l) => !options.defaultLanguages?.includes(l.id)\n )\n const [open, setOpen] = useState(false)\n const {activeLanguages, allSelected, selectAll, selectNone, toggleLanguage} = usePaneLanguages({\n options,\n onSelectedIdsChange,\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}>\n <Stack padding={2} space={3}>\n <Box paddingBottom={2}>\n <Text size={1} weight=\"semibold\">\n Default language{defaultLanguages.length > 1 && <>s</>}\n </Text>\n </Box>\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={2}>\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={activeLanguages.includes(lang.id)}\n title={lang.title}\n />\n ))}\n </Stack>\n </Box>\n )\n\n const langCount = options.supportedLanguages.length\n return (\n <Popover content={content} open={open} portal ref={setPopover}>\n <Button\n text={\n <Flex gap={1}>\n <Box>Filter languages:</Box>\n <Flex gap={1} justify=\"space-around\">\n <Flex\n style={{width: `${Math.floor(Math.log10(langCount) + 1)}ch`}}\n justify=\"flex-end\"\n >\n {activeLanguages.length}\n </Flex>\n <Box>/</Box>\n <Box>{langCount}</Box>\n </Flex>\n </Flex>\n }\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","import {useCallback, useMemo} from 'react'\nimport {LanguageFilterConfig} from './types'\nimport {\n getSelectableLanguages,\n persistLanguageIds,\n useSelectedLanguageIds,\n} from './useSelectedLanguageIds'\n\nexport interface UsePaneLanguagesParams {\n options: LanguageFilterConfig\n /**\n * We need a way to communicate state changes between the pane menu and input components.\n * LanguageFilter button lives outside the input-render tree, so Context is out.\n * This is a workaround for that.\n */\n onSelectedIdsChange: (ids: string[]) => void\n}\n\nexport function usePaneLanguages(props: UsePaneLanguagesParams): {\n activeLanguages: string[]\n allSelected: boolean\n selectAll: () => void\n selectNone: () => void\n toggleLanguage: (languageId: string) => void\n} {\n const {options, onSelectedIdsChange} = props\n const {defaultLanguages} = options\n\n const [selectedIds, setSelectedIds] = useSelectedLanguageIds(options)\n\n const selectableLanguages = useMemo(() => getSelectableLanguages(options), [options])\n\n const updateSelectedIds = useCallback(\n (ids: string[]) => {\n setSelectedIds(ids)\n persistLanguageIds(ids)\n onSelectedIdsChange(ids)\n },\n [onSelectedIdsChange, setSelectedIds]\n )\n\n const selectAll = useCallback(\n () => updateSelectedIds(selectableLanguages.map((l) => l.id)),\n [updateSelectedIds, selectableLanguages]\n )\n\n const selectNone = useCallback(() => {\n updateSelectedIds([])\n }, [updateSelectedIds])\n\n const toggleLanguage = useCallback(\n (languageId: string) => {\n let lang = selectedIds\n\n if (lang.includes(languageId)) {\n lang = lang.filter((l) => l !== languageId)\n } else {\n lang = [...lang, languageId]\n }\n\n updateSelectedIds(lang)\n },\n [updateSelectedIds, selectedIds]\n )\n\n const activeLanguages = useMemo(\n () => [...(defaultLanguages ?? []), ...selectedIds],\n [defaultLanguages, selectedIds]\n )\n\n return {\n activeLanguages,\n allSelected: selectedIds.length === selectableLanguages.length,\n selectAll,\n selectNone,\n toggleLanguage,\n }\n}\n","export type LanguageSubscription = (ids: string[]) => void\nexport type Unsubscribe = () => void\nexport type LanguageSubscribe = (subscription: LanguageSubscription) => Unsubscribe\n\nexport interface SelectedLanguageIdsBus {\n onSelectedIdsChange: (ids: string[]) => void\n subscribeSelectedIds: LanguageSubscribe\n}\n\n/**\n * We need a way to communicate state changes between the pane menu and input components.\n * LanguageFilter button lives outside the input-render tree, so Context is out.\n * This is a workaround for that.\n */\nexport function createSelectedLanguageIdsBus(): SelectedLanguageIdsBus {\n const subs: LanguageSubscription[] = []\n\n const onSelectedIdsChange = (ids: string[]) => {\n subs.forEach((s) => s(ids))\n }\n const subscribeSelectedIds = (subscription: LanguageSubscription) => {\n subs.push(subscription)\n return () => {\n subs.splice(subs.indexOf(subscription), 1)\n }\n }\n\n return {\n onSelectedIdsChange,\n subscribeSelectedIds,\n }\n}\n"],"names":[],"version":3,"file":"index.js.map","sourceRoot":"../../"}