@sanity/language-filter 3.1.0 → 3.1.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/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  A Sanity plugin that supports filtering localized fields by language
9
9
 
10
- ![Language Filter UI](https://user-images.githubusercontent.com/9684022/150549913-68f1b7c7-3305-48b4-b72b-41b95e82450c.gif)
10
+ ![Language Filter UI](https://github.com/sanity-io/language-filter/assets/9684022/a48fe4b7-975b-424d-9740-386f09ed9cd8)
11
11
 
12
12
  ## What this plugin solves
13
13
 
@@ -31,7 +31,6 @@ This plugin adds features to the Studio to improve handling **field-level transl
31
31
 
32
32
  For **document-level translations** you should use the [@sanity/document-internationalization plugin](https://www.npmjs.com/package/@sanity/document-internationalization).
33
33
 
34
-
35
34
  ## Installation
36
35
 
37
36
  ```
@@ -45,6 +44,7 @@ yarn add @sanity/language-filter
45
44
  ```
46
45
 
47
46
  ## Usage
47
+
48
48
  Add it as a plugin in sanity.config.ts (or .js), and configure it:
49
49
 
50
50
  ```
@@ -76,16 +76,18 @@ Add it as a plugin in sanity.config.ts (or .js), and configure it:
76
76
  ```
77
77
 
78
78
  Config properties:
79
+
79
80
  - `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.
80
81
  - `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.
81
82
  - `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.
82
83
  - `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.
83
- This function is called for all fields and in objects for documents that have language filter enabled.
84
- _Default:_ `!enclosingType.name.startsWith('locale') || selectedLanguageIds.includes(field.name)`
84
+ This function is called for all fields and in objects for documents that have language filter enabled.
85
+ _Default:_ `!enclosingType.name.startsWith('locale') || selectedLanguageIds.includes(field.name)`
85
86
 
86
87
  ## Changes in V3
87
88
 
88
89
  ### documentTypes
90
+
89
91
  Language filter can now be enabled/disabled directly from a schema, using `options.languageFilter: boolean`.
90
92
  When `documentTypes` is omitted from plugin config, use `options.languageFilter: false` in a document-definition to hide the filter button.
91
93
  When `documentTypes` is provided in plugin config, use `options.languageFilter: true` in a document-definition to show the filter button.
@@ -99,12 +101,13 @@ export const myDocumentSchema = {
99
101
  /** ... */
100
102
  options: {
101
103
  // show language filter for this document type, regardless of how documentTypes for the plugin is configured
102
- languageFilter: true
103
- }
104
+ languageFilter: true,
105
+ },
104
106
  }
105
107
  ```
106
108
 
107
109
  ### State management
110
+
108
111
  Selected languages are now stored as `langs` url-param state; this allows users to copy paste
109
112
  a url in the studio with the currently selected languages preselected.
110
113
 
package/lib/index.esm.js CHANGED
@@ -1 +1 @@
1
- var e;const t=["members","schemaType","renderDefault"];function n(e,t){if(null==e)return{};var n,r,l=function(e,t){if(null==e)return{};var n,r,l={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}import{jsx as o,jsxs as a,Fragment as c}from"react/jsx-runtime";import{useFormValue as u,TextWithTone as s,definePlugin as d,isObjectSchemaType as g}from"sanity";import{useState as f,createContext as p,useMemo as m,useContext as h,useCallback as y}from"react";import{Box as b,useClickOutside as v,Card as O,Stack as L,Text as j,Button as S,Flex as w,TextInput as T,Popover as P,Badge as x}from"@sanity/ui";import D from"styled-components";import{EyeClosedIcon as I,EyeOpenIcon as k,TranslateIcon as C,CheckmarkCircleIcon as N,CircleIcon as z}from"@sanity/icons";const A=(e,t,n)=>!e.name.startsWith("locale")||n.includes(t.name);function F(e,t){var n,r;const l=function(e){return"object"===(null==e?void 0:e.jsonType)&&"document"===E(e).name}(e)&&(null==(n=null==e?void 0:e.options)?void 0:n.languageFilter),i=!t.documentTypes;return!!(i&&!1!==l||!i&&l||e&&(null==(r=t.documentTypes)?void 0:r.includes(e.name)))}function E(e){return e.type?E(e.type):e}const J="@sanity/plugin/language-filter/selected-languages";function _(e){let{supportedLanguages:t,defaultLanguages:n}=e;return t.filter((e=>!(null==n?void 0:n.includes(e.id))))}function B(e){return f((()=>function(e){const t=_(e).map((e=>e.id));let n=t;try{const e=window.localStorage.getItem(J);e&&(n=JSON.parse(e))}catch(e){}var r;return r=t,n=n.filter((e=>r.includes(e))),n}(e)))}const H={options:{supportedLanguages:[],defaultLanguages:[],documentTypes:[],filterField:A},selectedLanguageIds:[],setSelectedLanguageIds:()=>console.error("LanguageFilterStudioContext not initialized")},W=p(H);function q(){return h(W)}function G(e){const{members:r,schemaType:i,renderDefault:o}=e,a=n(e,t),{selectedLanguageIds:c,options:u}=q(),{filterField:s}=u,d=m((()=>r.filter((e=>"field"===e.kind&&s(i,e,c)||"fieldSet"===e.kind)).map((e=>"fieldSet"===e.kind?l(l({},e),{},{fieldSet:l(l({},e.fieldSet),{},{members:e.fieldSet.members.filter((e=>"field"===e.kind&&s(i,e,c)))})}):e))),[i,r,s,c]);return o(l(l({},a),{},{members:d,schemaType:i,renderDefault:o}))}function K(){const{selectedLanguageIds:e,setSelectedLanguageIds:t,options:n}=q(),{defaultLanguages:r}=n,l=m((()=>_(n)),[n]),i=y((e=>{var n;t(e),n=e,window.localStorage.setItem(J,JSON.stringify(n))}),[t]),o=y((()=>i(l.map((e=>e.id)))),[i,l]),a=y((()=>{i([])}),[i]),c=y((t=>{let n=e;n=n.includes(t)?n.filter((e=>e!==t)):[...n,t],i(n)}),[i,e]);return{activeLanguages:m((()=>[...null!=r?r:[],...e]),[r,e]),allSelected:e.length===l.length,selectAll:o,selectNone:a,toggleLanguage:c}}const M=D(b)(e||(Q=["\n max-height: calc(100vh - 200px);\n"],R||(R=Q.slice(0)),e=Object.freeze(Object.defineProperties(Q,{raw:{value:Object.freeze(R)}}))));var Q,R;function U(e){const{options:t}=e,n=t.supportedLanguages.filter((e=>{var n;return null==(n=t.defaultLanguages)?void 0:n.includes(e.id)})),r=t.supportedLanguages.filter((e=>{var n;return!(null==(n=t.defaultLanguages)?void 0:n.includes(e.id))})),[l,i]=f(!1),{activeLanguages:u,allSelected:d,selectAll:g,selectNone:p,toggleLanguage:m}=K(),[h,x]=f(null),[D,N]=f(null),z=y((e=>{"ALL"===e.currentTarget.value?g():p()}),[g,p]),A=y((()=>i((e=>!e))),[]),F=y((()=>i(!1)),[]);v(F,[h,D]);const E=t.supportedLanguages.length,[J,_]=f(""),B=y((e=>{e.currentTarget.value?_(e.currentTarget.value):_("")}),[]),H=a(M,{overflow:"auto",padding:1,children:[n.length>0&&o(O,{radius:2,children:a(L,{padding:2,space:3,children:[o(b,{paddingBottom:2,children:a(j,{size:1,weight:"semibold",children:["Default language",n.length>1&&o(c,{children:"s"})]})}),n.map((e=>o(j,{children:e.title},e.id)))]})}),a(L,{padding:1,space:1,children:[o(S,{mode:"bleed",onClick:z,justify:"flex-start",value:d?"NONE":"ALL",disabled:!!J,children:a(w,{gap:3,align:"center",children:[o(j,{size:2,children:d?o(s,{tone:"primary",children:o(I,{})}):o(k,{})}),o(b,{flex:1,children:o(j,{children:d?"Hide All":"Show All"})})]})}),o(O,{borderTop:!0}),E>4?o(T,{onChange:B,value:J,placeholder:"Filter languages"}):null,r.filter((e=>!J||e.title.toLowerCase().includes(J.toLowerCase()))).map((e=>o(V,{id:e.id,onToggle:m,selected:u.includes(e.id),title:e.title},e.id)))]})]}),W=u.length===E?"Showing all":"Showing ".concat(u.length," / ").concat(E);return o(P,{content:H,open:l,portal:!0,ref:N,children:o(S,{text:W,icon:C,mode:"bleed",onClick:A,ref:x,selected:l})})}function V(e){const{id:t,onToggle:n,selected:r,title:l}=e,i=y((()=>{n(t)}),[t,n]);return o(S,{mode:"bleed",onClick:i,justify:"flex-start",children:a(w,{gap:3,align:"center",children:[o(j,{size:2,children:r?o(s,{tone:"positive",children:o(N,{})}):o(z,{})}),o(b,{flex:1,children:o(j,{children:l})}),o(x,{children:t})]})})}const X=d((e=>{const t=()=>o(U,{options:e}),n=l(l({},H.options),e);return{name:"@sanity/language-filter",studio:{components:{layout:e=>function(e){const t=m((()=>l(l({},H.options),e.options)),[e.options]),[n,r]=B(t);return o(W.Provider,{value:{options:t,selectedLanguageIds:n,setSelectedLanguageIds:r},children:e.renderDefault(e)})}(l(l({},e),{},{options:n}))}},document:{unstable_languageFilter:(n,r)=>{let{schemaType:l,schema:i}=r;return F(i.get(l),e)?[...n,t]:n}},form:{components:{input:e=>"root"!==e.id&&g(e.schemaType)?function(e){const{options:t}=q(),n=u(["_type"]),{documentTypes:r}=t;return"string"==typeof n&&r.includes(n)?o(G,l({},e)):e.renderDefault(e)}(e):e.renderDefault(e)}}}}));export{A as defaultFilterField,F as isLanguageFilterEnabled,X as languageFilter,q as useLanguageFilterStudioContext};//# sourceMappingURL=index.esm.js.map
1
+ var e;const t=["members","schemaType","renderDefault"];function n(e,t){if(null==e)return{};var n,r,l=function(e,t){if(null==e)return{};var n,r,l={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}import{jsx as o,jsxs as a,Fragment as u}from"react/jsx-runtime";import{useFormValue as c,TextWithTone as s,definePlugin as d,isObjectSchemaType as g}from"sanity";import{useState as f,createContext as p,useMemo as m,useContext as y,useCallback as h}from"react";import{Box as b,useClickOutside as v,Stack as O,Card as L,Button as j,Flex as S,Text as w,TextInput as T,Popover as P,Badge as x}from"@sanity/ui";import D from"styled-components";import{EyeClosedIcon as I,EyeOpenIcon as k,TranslateIcon as C,CheckmarkCircleIcon as N,CircleIcon as F}from"@sanity/icons";const z=(e,t,n)=>!e.name.startsWith("locale")||n.includes(t.name);function A(e,t){var n,r;const l=function(e){return"object"===(null==e?void 0:e.jsonType)&&"document"===E(e).name}(e)&&(null==(n=null==e?void 0:e.options)?void 0:n.languageFilter),i=!t.documentTypes;return!!(i&&!1!==l||!i&&l||e&&(null==(r=t.documentTypes)?void 0:r.includes(e.name)))}function E(e){return e.type?E(e.type):e}const J="@sanity/plugin/language-filter/selected-languages";function _(e){const t=H(e).map((e=>e.id));let n=t;try{const e=window.localStorage.getItem(J);e&&(n=JSON.parse(e))}catch(e){}var r;return r=t,n=n.filter((e=>r.includes(e))),n}function H(e){let{supportedLanguages:t,defaultLanguages:n}=e;return t.filter((e=>!(null==n?void 0:n.includes(e.id))))}const W={options:{supportedLanguages:[],defaultLanguages:[],documentTypes:[],filterField:z},selectedLanguageIds:[],setSelectedLanguageIds:()=>console.error("LanguageFilterStudioContext not initialized")},q=p(W);function B(e){const t=m((()=>l(l({},W.options),e.options)),[e.options]),[n,r]=function(e){return f((()=>{var t;return[...null!=(t=e.defaultLanguages)?t:[],..._(e)]}))}(t);return o(q.Provider,{value:{options:t,selectedLanguageIds:n,setSelectedLanguageIds:r},children:e.renderDefault(e)})}function G(){return y(q)}function K(e){const{members:r,schemaType:i,renderDefault:o}=e,a=n(e,t),{selectedLanguageIds:u,options:c}=G(),{filterField:s}=c,d=m((()=>r.filter((e=>"field"===e.kind&&s(i,e,u)||"fieldSet"===e.kind)).map((e=>"fieldSet"===e.kind?l(l({},e),{},{fieldSet:l(l({},e.fieldSet),{},{members:e.fieldSet.members.filter((e=>"field"===e.kind&&s(i,e,u)))})}):e))),[i,r,s,u]);return o(l(l({},a),{},{members:d,schemaType:i,renderDefault:o}))}const M=e=>Array.from(new Set(e));function Q(){const{selectedLanguageIds:e,setSelectedLanguageIds:t,options:n}=G(),{defaultLanguages:r=[]}=n,l=m((()=>H(n)),[n]),i=h((e=>{var n;t(M([...r,...e])),n=M([...r,...e]),window.localStorage.setItem(J,JSON.stringify(n))}),[r,t]),o=h((()=>i(l.map((e=>e.id)))),[i,l]),a=h((()=>{i(r)}),[r,i]),u=h((t=>{let n=e;n=n.includes(t)?n.filter((e=>e!==t)):M([...n,t]),i(n)}),[i,e]);return{activeLanguages:m((()=>M([...null!=r?r:[],...e])),[r,e]),allSelected:e.length===l.length+r.length,selectAll:o,selectNone:a,toggleLanguage:u}}const R=D(b)(e||(U=["\n max-height: calc(100vh - 200px);\n"],V||(V=U.slice(0)),e=Object.freeze(Object.defineProperties(U,{raw:{value:Object.freeze(V)}}))));var U,V;function X(e){const{options:t}=e,n=t.supportedLanguages.filter((e=>{var n;return null==(n=t.defaultLanguages)?void 0:n.includes(e.id)})),r=t.supportedLanguages.filter((e=>{var n;return!(null==(n=t.defaultLanguages)?void 0:n.includes(e.id))})),[l,i]=f(!1),{activeLanguages:c,allSelected:d,selectAll:g,selectNone:p,toggleLanguage:m}=Q(),[y,x]=f(null),[D,N]=f(null),F=h((e=>{"ALL"===e.currentTarget.value?g():p()}),[g,p]),z=h((()=>i((e=>!e))),[]),A=h((()=>i(!1)),[]);v(A,[y,D]);const E=t.supportedLanguages.length,[J,_]=f(""),H=h((e=>{e.currentTarget.value?_(e.currentTarget.value):_("")}),[]),W=o(R,{overflow:"auto",children:a(O,{padding:1,space:1,children:[n.length>0&&a(u,{children:[n.map((e=>o(Y,{id:e.id,title:e.title,selected:!0},e.id))),o(L,{borderTop:!0})]}),o(j,{mode:"bleed",onClick:F,justify:"flex-start",value:d?"NONE":"ALL",disabled:!!J,children:a(S,{gap:3,align:"center",children:[o(w,{size:2,children:d?o(s,{tone:"primary",children:o(I,{})}):o(k,{})}),o(b,{flex:1,children:o(w,{children:d?"Hide all":"Show all"})})]})}),o(L,{borderTop:!0}),E>4?o(T,{onChange:H,value:J,placeholder:"Filter languages"}):null,r.filter((e=>!J||e.title.toLowerCase().includes(J.toLowerCase()))).map((e=>o(Y,{id:e.id,onToggle:m,selected:c.includes(e.id),title:e.title},e.id)))]})}),q=c.length===E?"Showing all":"Showing ".concat(c.length," / ").concat(E);return o(P,{content:W,open:l,portal:!0,ref:N,children:o(j,{text:q,icon:C,mode:"bleed",onClick:z,ref:x,selected:l})})}function Y(e){const{id:t,onToggle:n,selected:r,title:l}=e,i=h((()=>{n&&n(t)}),[t,n]),u=!n;return o(j,{mode:"bleed",onClick:i,justify:"flex-start",disabled:u,children:a(S,{gap:3,align:"center",children:[o(w,{size:2,children:r?o(s,{tone:u?"default":"positive",children:o(N,{})}):o(F,{})}),o(b,{flex:1,children:o(w,{children:l})}),o(x,{children:t})]})})}const Z=d((e=>{const t=()=>o(X,{options:e}),n=l(l({},W.options),e);return{name:"@sanity/language-filter",studio:{components:{layout:e=>B(l(l({},e),{},{options:n}))}},document:{unstable_languageFilter:(n,r)=>{let{schemaType:l,schema:i}=r;return A(i.get(l),e)?[...n,t]:n}},form:{components:{input:e=>"root"!==e.id&&g(e.schemaType)?function(e){const{options:t}=G(),n=c(["_type"]),{documentTypes:r}=t;return"string"==typeof n&&r.includes(n)?o(K,l({},e)):e.renderDefault(e)}(e):e.renderDefault(e)}}}}));export{z as defaultFilterField,A as isLanguageFilterEnabled,Z as languageFilter,G as useLanguageFilterStudioContext};//# sourceMappingURL=index.esm.js.map
package/lib/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e;const t=["members","schemaType","renderDefault"];function n(e,t){if(null==e)return{};var n,r,l=function(e,t){if(null==e)return{};var n,r,l={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.defineProperty(exports,"__esModule",{value:!0});var o=require("react/jsx-runtime"),s=require("sanity"),a=require("react"),u=require("@sanity/ui"),c=require("styled-components"),d=require("@sanity/icons");function g(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var p=g(c);const f=(e,t,n)=>!e.name.startsWith("locale")||n.includes(t.name);function m(e,t){var n,r;const l=function(e){return"object"===(null==e?void 0:e.jsonType)&&"document"===x(e).name}(e)&&(null==(n=null==e?void 0:e.options)?void 0:n.languageFilter),i=!t.documentTypes;return!!(i&&!1!==l||!i&&l||e&&(null==(r=t.documentTypes)?void 0:r.includes(e.name)))}function x(e){return e.type?x(e.type):e}const j="@sanity/plugin/language-filter/selected-languages";function b(e){let{supportedLanguages:t,defaultLanguages:n}=e;return t.filter((e=>!(null==n?void 0:n.includes(e.id))))}function h(e){return a.useState((()=>function(e){const t=b(e).map((e=>e.id));let n=t;try{const e=window.localStorage.getItem(j);e&&(n=JSON.parse(e))}catch(e){}var r;return r=t,n=n.filter((e=>r.includes(e))),n}(e)))}const y={options:{supportedLanguages:[],defaultLanguages:[],documentTypes:[],filterField:f},selectedLanguageIds:[],setSelectedLanguageIds:()=>console.error("LanguageFilterStudioContext not initialized")},v=a.createContext(y);function O(){return a.useContext(v)}function S(e){const{members:r,schemaType:i,renderDefault:o}=e,s=n(e,t),{selectedLanguageIds:u,options:c}=O(),{filterField:d}=c,g=a.useMemo((()=>r.filter((e=>"field"===e.kind&&d(i,e,u)||"fieldSet"===e.kind)).map((e=>"fieldSet"===e.kind?l(l({},e),{},{fieldSet:l(l({},e.fieldSet),{},{members:e.fieldSet.members.filter((e=>"field"===e.kind&&d(i,e,u)))})}):e))),[i,r,d,u]);return o(l(l({},s),{},{members:g,schemaType:i,renderDefault:o}))}function L(){const{selectedLanguageIds:e,setSelectedLanguageIds:t,options:n}=O(),{defaultLanguages:r}=n,l=a.useMemo((()=>b(n)),[n]),i=a.useCallback((e=>{var n;t(e),n=e,window.localStorage.setItem(j,JSON.stringify(n))}),[t]),o=a.useCallback((()=>i(l.map((e=>e.id)))),[i,l]),s=a.useCallback((()=>{i([])}),[i]),u=a.useCallback((t=>{let n=e;n=n.includes(t)?n.filter((e=>e!==t)):[...n,t],i(n)}),[i,e]);return{activeLanguages:a.useMemo((()=>[...null!=r?r:[],...e]),[r,e]),allSelected:e.length===l.length,selectAll:o,selectNone:s,toggleLanguage:u}}const T=p.default(u.Box)(e||(C=["\n max-height: calc(100vh - 200px);\n"],k||(k=C.slice(0)),e=Object.freeze(Object.defineProperties(C,{raw:{value:Object.freeze(k)}}))));var C,k;function w(e){const{options:t}=e,n=t.supportedLanguages.filter((e=>{var n;return null==(n=t.defaultLanguages)?void 0:n.includes(e.id)})),r=t.supportedLanguages.filter((e=>{var n;return!(null==(n=t.defaultLanguages)?void 0:n.includes(e.id))})),[l,i]=a.useState(!1),{activeLanguages:c,allSelected:g,selectAll:p,selectNone:f,toggleLanguage:m}=L(),[x,j]=a.useState(null),[b,h]=a.useState(null),y=a.useCallback((e=>{"ALL"===e.currentTarget.value?p():f()}),[p,f]),v=a.useCallback((()=>i((e=>!e))),[]),O=a.useCallback((()=>i(!1)),[]);u.useClickOutside(O,[x,b]);const S=t.supportedLanguages.length,[C,k]=a.useState(""),w=a.useCallback((e=>{e.currentTarget.value?k(e.currentTarget.value):k("")}),[]),I=o.jsxs(T,{overflow:"auto",padding:1,children:[n.length>0&&o.jsx(u.Card,{radius:2,children:o.jsxs(u.Stack,{padding:2,space:3,children:[o.jsx(u.Box,{paddingBottom:2,children:o.jsxs(u.Text,{size:1,weight:"semibold",children:["Default language",n.length>1&&o.jsx(o.Fragment,{children:"s"})]})}),n.map((e=>o.jsx(u.Text,{children:e.title},e.id)))]})}),o.jsxs(u.Stack,{padding:1,space:1,children:[o.jsx(u.Button,{mode:"bleed",onClick:y,justify:"flex-start",value:g?"NONE":"ALL",disabled:!!C,children:o.jsxs(u.Flex,{gap:3,align:"center",children:[o.jsx(u.Text,{size:2,children:g?o.jsx(s.TextWithTone,{tone:"primary",children:o.jsx(d.EyeClosedIcon,{})}):o.jsx(d.EyeOpenIcon,{})}),o.jsx(u.Box,{flex:1,children:o.jsx(u.Text,{children:g?"Hide All":"Show All"})})]})}),o.jsx(u.Card,{borderTop:!0}),S>4?o.jsx(u.TextInput,{onChange:w,value:C,placeholder:"Filter languages"}):null,r.filter((e=>!C||e.title.toLowerCase().includes(C.toLowerCase()))).map((e=>o.jsx(P,{id:e.id,onToggle:m,selected:c.includes(e.id),title:e.title},e.id)))]})]}),F=c.length===S?"Showing all":"Showing ".concat(c.length," / ").concat(S);return o.jsx(u.Popover,{content:I,open:l,portal:!0,ref:h,children:o.jsx(u.Button,{text:F,icon:d.TranslateIcon,mode:"bleed",onClick:v,ref:j,selected:l})})}function P(e){const{id:t,onToggle:n,selected:r,title:l}=e,i=a.useCallback((()=>{n(t)}),[t,n]);return o.jsx(u.Button,{mode:"bleed",onClick:i,justify:"flex-start",children:o.jsxs(u.Flex,{gap:3,align:"center",children:[o.jsx(u.Text,{size:2,children:r?o.jsx(s.TextWithTone,{tone:"positive",children:o.jsx(d.CheckmarkCircleIcon,{})}):o.jsx(d.CircleIcon,{})}),o.jsx(u.Box,{flex:1,children:o.jsx(u.Text,{children:l})}),o.jsx(u.Badge,{children:t})]})})}const I=s.definePlugin((e=>{const t=()=>o.jsx(w,{options:e}),n=l(l({},y.options),e);return{name:"@sanity/language-filter",studio:{components:{layout:e=>function(e){const t=a.useMemo((()=>l(l({},y.options),e.options)),[e.options]),[n,r]=h(t);return o.jsx(v.Provider,{value:{options:t,selectedLanguageIds:n,setSelectedLanguageIds:r},children:e.renderDefault(e)})}(l(l({},e),{},{options:n}))}},document:{unstable_languageFilter:(n,r)=>{let{schemaType:l,schema:i}=r;return m(i.get(l),e)?[...n,t]:n}},form:{components:{input:e=>"root"!==e.id&&s.isObjectSchemaType(e.schemaType)?function(e){const{options:t}=O(),n=s.useFormValue(["_type"]),{documentTypes:r}=t;return"string"==typeof n&&r.includes(n)?o.jsx(S,l({},e)):e.renderDefault(e)}(e):e.renderDefault(e)}}}}));exports.defaultFilterField=f,exports.isLanguageFilterEnabled=m,exports.languageFilter=I,exports.useLanguageFilterStudioContext=O;//# sourceMappingURL=index.js.map
1
+ "use strict";var e;const t=["members","schemaType","renderDefault"];function n(e,t){if(null==e)return{};var n,r,l=function(e,t){if(null==e)return{};var n,r,l={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.defineProperty(exports,"__esModule",{value:!0});var i=require("react/jsx-runtime"),a=require("sanity"),s=require("react"),u=require("@sanity/ui"),c=require("styled-components"),d=require("@sanity/icons");function g(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var f=g(c);const p=(e,t,n)=>!e.name.startsWith("locale")||n.includes(t.name);function m(e,t){var n,r;const l=function(e){return"object"===(null==e?void 0:e.jsonType)&&"document"===x(e).name}(e)&&(null==(n=null==e?void 0:e.options)?void 0:n.languageFilter),o=!t.documentTypes;return!!(o&&!1!==l||!o&&l||e&&(null==(r=t.documentTypes)?void 0:r.includes(e.name)))}function x(e){return e.type?x(e.type):e}const b="@sanity/plugin/language-filter/selected-languages";function j(e){const t=y(e).map((e=>e.id));let n=t;try{const e=window.localStorage.getItem(b);e&&(n=JSON.parse(e))}catch(e){}var r;return r=t,n=n.filter((e=>r.includes(e))),n}function y(e){let{supportedLanguages:t,defaultLanguages:n}=e;return t.filter((e=>!(null==n?void 0:n.includes(e.id))))}const h={options:{supportedLanguages:[],defaultLanguages:[],documentTypes:[],filterField:p},selectedLanguageIds:[],setSelectedLanguageIds:()=>console.error("LanguageFilterStudioContext not initialized")},v=s.createContext(h);function O(e){const t=s.useMemo((()=>l(l({},h.options),e.options)),[e.options]),[n,r]=function(e){return s.useState((()=>{var t;return[...null!=(t=e.defaultLanguages)?t:[],...j(e)]}))}(t);return i.jsx(v.Provider,{value:{options:t,selectedLanguageIds:n,setSelectedLanguageIds:r},children:e.renderDefault(e)})}function S(){return s.useContext(v)}function L(e){const{members:r,schemaType:o,renderDefault:i}=e,a=n(e,t),{selectedLanguageIds:u,options:c}=S(),{filterField:d}=c,g=s.useMemo((()=>r.filter((e=>"field"===e.kind&&d(o,e,u)||"fieldSet"===e.kind)).map((e=>"fieldSet"===e.kind?l(l({},e),{},{fieldSet:l(l({},e.fieldSet),{},{members:e.fieldSet.members.filter((e=>"field"===e.kind&&d(o,e,u)))})}):e))),[o,r,d,u]);return i(l(l({},a),{},{members:g,schemaType:o,renderDefault:i}))}const T=e=>Array.from(new Set(e));function C(){const{selectedLanguageIds:e,setSelectedLanguageIds:t,options:n}=S(),{defaultLanguages:r=[]}=n,l=s.useMemo((()=>y(n)),[n]),o=s.useCallback((e=>{var n;t(T([...r,...e])),n=T([...r,...e]),window.localStorage.setItem(b,JSON.stringify(n))}),[r,t]),i=s.useCallback((()=>o(l.map((e=>e.id)))),[o,l]),a=s.useCallback((()=>{o(r)}),[r,o]),u=s.useCallback((t=>{let n=e;n=n.includes(t)?n.filter((e=>e!==t)):T([...n,t]),o(n)}),[o,e]);return{activeLanguages:s.useMemo((()=>T([...null!=r?r:[],...e])),[r,e]),allSelected:e.length===l.length+r.length,selectAll:i,selectNone:a,toggleLanguage:u}}const w=f.default(u.Box)(e||(k=["\n max-height: calc(100vh - 200px);\n"],P||(P=k.slice(0)),e=Object.freeze(Object.defineProperties(k,{raw:{value:Object.freeze(P)}}))));var k,P;function I(e){const{options:t}=e,n=t.supportedLanguages.filter((e=>{var n;return null==(n=t.defaultLanguages)?void 0:n.includes(e.id)})),r=t.supportedLanguages.filter((e=>{var n;return!(null==(n=t.defaultLanguages)?void 0:n.includes(e.id))})),[l,o]=s.useState(!1),{activeLanguages:c,allSelected:g,selectAll:f,selectNone:p,toggleLanguage:m}=C(),[x,b]=s.useState(null),[j,y]=s.useState(null),h=s.useCallback((e=>{"ALL"===e.currentTarget.value?f():p()}),[f,p]),v=s.useCallback((()=>o((e=>!e))),[]),O=s.useCallback((()=>o(!1)),[]);u.useClickOutside(O,[x,j]);const S=t.supportedLanguages.length,[L,T]=s.useState(""),k=s.useCallback((e=>{e.currentTarget.value?T(e.currentTarget.value):T("")}),[]),P=i.jsx(w,{overflow:"auto",children:i.jsxs(u.Stack,{padding:1,space:1,children:[n.length>0&&i.jsxs(i.Fragment,{children:[n.map((e=>i.jsx(F,{id:e.id,title:e.title,selected:!0},e.id))),i.jsx(u.Card,{borderTop:!0})]}),i.jsx(u.Button,{mode:"bleed",onClick:h,justify:"flex-start",value:g?"NONE":"ALL",disabled:!!L,children:i.jsxs(u.Flex,{gap:3,align:"center",children:[i.jsx(u.Text,{size:2,children:g?i.jsx(a.TextWithTone,{tone:"primary",children:i.jsx(d.EyeClosedIcon,{})}):i.jsx(d.EyeOpenIcon,{})}),i.jsx(u.Box,{flex:1,children:i.jsx(u.Text,{children:g?"Hide all":"Show all"})})]})}),i.jsx(u.Card,{borderTop:!0}),S>4?i.jsx(u.TextInput,{onChange:k,value:L,placeholder:"Filter languages"}):null,r.filter((e=>!L||e.title.toLowerCase().includes(L.toLowerCase()))).map((e=>i.jsx(F,{id:e.id,onToggle:m,selected:c.includes(e.id),title:e.title},e.id)))]})}),I=c.length===S?"Showing all":"Showing ".concat(c.length," / ").concat(S);return i.jsx(u.Popover,{content:P,open:l,portal:!0,ref:y,children:i.jsx(u.Button,{text:I,icon:d.TranslateIcon,mode:"bleed",onClick:v,ref:b,selected:l})})}function F(e){const{id:t,onToggle:n,selected:r,title:l}=e,o=s.useCallback((()=>{n&&n(t)}),[t,n]),c=!n;return i.jsx(u.Button,{mode:"bleed",onClick:o,justify:"flex-start",disabled:c,children:i.jsxs(u.Flex,{gap:3,align:"center",children:[i.jsx(u.Text,{size:2,children:r?i.jsx(a.TextWithTone,{tone:c?"default":"positive",children:i.jsx(d.CheckmarkCircleIcon,{})}):i.jsx(d.CircleIcon,{})}),i.jsx(u.Box,{flex:1,children:i.jsx(u.Text,{children:l})}),i.jsx(u.Badge,{children:t})]})})}const D=a.definePlugin((e=>{const t=()=>i.jsx(I,{options:e}),n=l(l({},h.options),e);return{name:"@sanity/language-filter",studio:{components:{layout:e=>O(l(l({},e),{},{options:n}))}},document:{unstable_languageFilter:(n,r)=>{let{schemaType:l,schema:o}=r;return m(o.get(l),e)?[...n,t]:n}},form:{components:{input:e=>"root"!==e.id&&a.isObjectSchemaType(e.schemaType)?function(e){const{options:t}=S(),n=a.useFormValue(["_type"]),{documentTypes:r}=t;return"string"==typeof n&&r.includes(n)?i.jsx(L,l({},e)):e.renderDefault(e)}(e):e.renderDefault(e)}}}}));exports.defaultFilterField=p,exports.isLanguageFilterEnabled=m,exports.languageFilter=D,exports.useLanguageFilterStudioContext=S;//# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/language-filter",
3
- "version": "3.1.0",
3
+ "version": "3.1.2",
4
4
  "description": "A Sanity plugin that supports filtering localized fields by language",
5
5
  "homepage": "https://github.com/sanity-io/language-filter#readme",
6
6
  "bugs": {
@@ -78,24 +78,17 @@ export function LanguageFilterMenuButton(props: LanguageFilterMenuButtonProps) {
78
78
  }, [])
79
79
 
80
80
  const content = (
81
- <StyledBox overflow="auto" padding={1}>
82
- {defaultLanguages.length > 0 && (
83
- <Card radius={2}>
84
- <Stack padding={2} space={3}>
85
- <Box paddingBottom={2}>
86
- <Text size={1} weight="semibold">
87
- Default language{defaultLanguages.length > 1 && <>s</>}
88
- </Text>
89
- </Box>
90
-
81
+ <StyledBox overflow="auto">
82
+ <Stack padding={1} space={1}>
83
+ {defaultLanguages.length > 0 && (
84
+ <>
91
85
  {defaultLanguages.map((l) => (
92
- <Text key={l.id}>{l.title}</Text>
86
+ <LanguageFilterOption key={l.id} id={l.id} title={l.title} selected />
93
87
  ))}
94
- </Stack>
95
- </Card>
96
- )}
88
+ <Card borderTop />
89
+ </>
90
+ )}
97
91
 
98
- <Stack padding={1} space={1}>
99
92
  <Button
100
93
  mode="bleed"
101
94
  onClick={handleToggleAll}
@@ -114,7 +107,7 @@ export function LanguageFilterMenuButton(props: LanguageFilterMenuButtonProps) {
114
107
  )}
115
108
  </Text>
116
109
  <Box flex={1}>
117
- <Text>{allSelected ? `Hide All` : `Show All`}</Text>
110
+ <Text>{allSelected ? `Hide all` : `Show all`}</Text>
118
111
  </Box>
119
112
  </Flex>
120
113
  </Button>
@@ -165,22 +158,27 @@ export function LanguageFilterMenuButton(props: LanguageFilterMenuButtonProps) {
165
158
 
166
159
  function LanguageFilterOption(props: {
167
160
  id: string
168
- onToggle: (id: string) => void
169
161
  selected: boolean
170
162
  title: string
163
+ // eslint-disable-next-line react/require-default-props
164
+ onToggle?: (id: string) => void
171
165
  }) {
172
166
  const {id, onToggle, selected, title} = props
173
167
 
174
168
  const handleChange = useCallback(() => {
175
- onToggle(id)
169
+ if (onToggle) {
170
+ onToggle(id)
171
+ }
176
172
  }, [id, onToggle])
177
173
 
174
+ const disabled = !onToggle
175
+
178
176
  return (
179
- <Button mode="bleed" onClick={handleChange} justify="flex-start">
177
+ <Button mode="bleed" onClick={handleChange} justify="flex-start" disabled={disabled}>
180
178
  <Flex gap={3} align="center">
181
179
  <Text size={2}>
182
180
  {selected ? (
183
- <TextWithTone tone="positive">
181
+ <TextWithTone tone={disabled ? 'default' : 'positive'}>
184
182
  <CheckmarkCircleIcon />
185
183
  </TextWithTone>
186
184
  ) : (
@@ -3,6 +3,8 @@ import {useCallback, useMemo} from 'react'
3
3
  import {getSelectableLanguages, persistLanguageIds} from './useSelectedLanguageIds'
4
4
  import {useLanguageFilterStudioContext} from './LanguageFilterStudioContext'
5
5
 
6
+ const unique = (arr: string[]) => Array.from(new Set(arr))
7
+
6
8
  export function usePaneLanguages(): {
7
9
  activeLanguages: string[]
8
10
  allSelected: boolean
@@ -11,16 +13,16 @@ export function usePaneLanguages(): {
11
13
  toggleLanguage: (languageId: string) => void
12
14
  } {
13
15
  const {selectedLanguageIds, setSelectedLanguageIds, options} = useLanguageFilterStudioContext()
14
- const {defaultLanguages} = options
16
+ const {defaultLanguages = []} = options
15
17
 
16
18
  const selectableLanguages = useMemo(() => getSelectableLanguages(options), [options])
17
19
 
18
20
  const updateSelectedIds = useCallback(
19
21
  (ids: string[]) => {
20
- setSelectedLanguageIds(ids)
21
- persistLanguageIds(ids)
22
+ setSelectedLanguageIds(unique([...defaultLanguages, ...ids]))
23
+ persistLanguageIds(unique([...defaultLanguages, ...ids]))
22
24
  },
23
- [setSelectedLanguageIds]
25
+ [defaultLanguages, setSelectedLanguageIds]
24
26
  )
25
27
 
26
28
  const selectAll = useCallback(
@@ -29,8 +31,8 @@ export function usePaneLanguages(): {
29
31
  )
30
32
 
31
33
  const selectNone = useCallback(() => {
32
- updateSelectedIds([])
33
- }, [updateSelectedIds])
34
+ updateSelectedIds(defaultLanguages)
35
+ }, [defaultLanguages, updateSelectedIds])
34
36
 
35
37
  const toggleLanguage = useCallback(
36
38
  (languageId: string) => {
@@ -39,7 +41,7 @@ export function usePaneLanguages(): {
39
41
  if (lang.includes(languageId)) {
40
42
  lang = lang.filter((l) => l !== languageId)
41
43
  } else {
42
- lang = [...lang, languageId]
44
+ lang = unique([...lang, languageId])
43
45
  }
44
46
 
45
47
  updateSelectedIds(lang)
@@ -48,13 +50,14 @@ export function usePaneLanguages(): {
48
50
  )
49
51
 
50
52
  const activeLanguages = useMemo(
51
- () => [...(defaultLanguages ?? []), ...selectedLanguageIds],
53
+ () => unique([...(defaultLanguages ?? []), ...selectedLanguageIds]),
52
54
  [defaultLanguages, selectedLanguageIds]
53
55
  )
54
56
 
55
57
  return {
56
58
  activeLanguages,
57
- allSelected: selectedLanguageIds.length === selectableLanguages.length,
59
+ allSelected:
60
+ selectedLanguageIds.length === selectableLanguages.length + defaultLanguages.length,
58
61
  selectAll,
59
62
  selectNone,
60
63
  toggleLanguage,
@@ -36,5 +36,5 @@ export function getSelectableLanguages({
36
36
  export function useSelectedLanguageIds(
37
37
  options: LanguageFilterConfig
38
38
  ): [string[], (ids: string[]) => void] {
39
- return useState(() => getPersistedLanguageIds(options))
39
+ return useState(() => [...(options.defaultLanguages ?? []), ...getPersistedLanguageIds(options)])
40
40
  }