sanity-plugin-internationalized-array 3.0.3 → 3.1.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.
@@ -108,19 +108,24 @@ export default function InternationalizedArray(
108
108
  const {isDeleting} = useDocumentPane()
109
109
 
110
110
  const addedLanguages = members.map(({key}) => key)
111
- const hasAddedDefaultLanguages = defaultLanguages.every((language) =>
112
- addedLanguages.includes(language)
113
- )
111
+ const hasAddedDefaultLanguages = defaultLanguages
112
+ .filter((language) => languages.find((l) => l.id === language))
113
+ .every((language) => addedLanguages.includes(language))
114
114
 
115
115
  useEffect(() => {
116
116
  if (!isDeleting && !hasAddedDefaultLanguages) {
117
- handleAddLanguage(defaultLanguages)
117
+ const languagesToAdd = defaultLanguages
118
+ .filter((language) => !addedLanguages.includes(language))
119
+ .filter((language) => languages.find((l) => l.id === language))
120
+ handleAddLanguage(languagesToAdd)
118
121
  }
119
122
  }, [
120
123
  isDeleting,
121
124
  hasAddedDefaultLanguages,
122
125
  handleAddLanguage,
123
126
  defaultLanguages,
127
+ addedLanguages,
128
+ languages,
124
129
  ])
125
130
 
126
131
  // TODO: This is reordering and re-setting the whole array, it could be surgical
@@ -9,12 +9,15 @@ import {
9
9
  MenuItem,
10
10
  Spinner,
11
11
  Stack,
12
+ Text,
13
+ Tooltip,
12
14
  } from '@sanity/ui'
13
15
  import type React from 'react'
14
16
  import {useCallback, useMemo} from 'react'
15
17
  import {type ObjectItemProps, useFormValue} from 'sanity'
16
18
  import {set, unset} from 'sanity'
17
19
 
20
+ import {getLanguageDisplay} from '../utils/getLanguageDisplay'
18
21
  import {getToneFromValidation} from './getToneFromValidation'
19
22
  import {useInternationalizedArrayContext} from './InternationalizedArrayContext'
20
23
 
@@ -45,7 +48,8 @@ export default function InternationalizedInput(
45
48
  const {validation, value, onChange, readOnly} = inlineProps
46
49
 
47
50
  // The parent array contains the languages from the plugin config
48
- const {languages} = useInternationalizedArrayContext()
51
+ const {languages, languageDisplay, defaultLanguages} =
52
+ useInternationalizedArrayContext()
49
53
 
50
54
  const languageKeysInUse = useMemo(
51
55
  () => parentValue?.map((v) => v._key) ?? [],
@@ -82,13 +86,31 @@ export default function InternationalizedInput(
82
86
  return <Spinner />
83
87
  }
84
88
 
89
+ const language = languages.find((l) => l.id === value._key)
90
+ const languageTitle: string =
91
+ keyIsValid && language
92
+ ? getLanguageDisplay(languageDisplay, language.title, language.id)
93
+ : ''
94
+
95
+ const isDefault = defaultLanguages.includes(value._key)
96
+
97
+ const removeButton = (
98
+ <Button
99
+ mode="bleed"
100
+ icon={RemoveCircleIcon}
101
+ tone="critical"
102
+ disabled={readOnly || isDefault}
103
+ onClick={handleUnset}
104
+ />
105
+ )
106
+
85
107
  return (
86
108
  <Card paddingTop={2} tone={getToneFromValidation(validation)}>
87
109
  <Stack space={2}>
88
110
  <Card tone="inherit">
89
111
  {keyIsValid ? (
90
112
  <Label muted size={1}>
91
- {value._key}
113
+ {languageTitle}
92
114
  </Label>
93
115
  ) : (
94
116
  <MenuButton
@@ -96,13 +118,13 @@ export default function InternationalizedInput(
96
118
  id={`${value._key}-change-key`}
97
119
  menu={
98
120
  <Menu>
99
- {languages.map((language) => (
121
+ {languages.map((lang) => (
100
122
  <MenuItem
101
- disabled={languageKeysInUse.includes(language.id)}
123
+ disabled={languageKeysInUse.includes(lang.id)}
102
124
  fontSize={1}
103
- key={language.id}
104
- text={language.id.toLocaleUpperCase()}
105
- value={language.id}
125
+ key={lang.id}
126
+ text={lang.id.toLocaleUpperCase()}
127
+ value={lang.id}
106
128
  // @ts-expect-error - fix typings
107
129
  onClick={handleKeyChange}
108
130
  />
@@ -119,13 +141,22 @@ export default function InternationalizedInput(
119
141
  </Card>
120
142
 
121
143
  <Card tone="inherit">
122
- <Button
123
- mode="bleed"
124
- icon={RemoveCircleIcon}
125
- tone="critical"
126
- disabled={readOnly}
127
- onClick={handleUnset}
128
- />
144
+ {isDefault ? (
145
+ <Tooltip
146
+ content={
147
+ <Text muted size={1}>
148
+ Can&apos;t remove default language
149
+ </Text>
150
+ }
151
+ fallbackPlacements={['right', 'left']}
152
+ placement="top"
153
+ portal
154
+ >
155
+ <span>{removeButton}</span>
156
+ </Tooltip>
157
+ ) : (
158
+ removeButton
159
+ )}
129
160
  </Card>
130
161
  </Flex>
131
162
  </Stack>
package/src/constants.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  import {PluginConfig} from './types'
2
2
 
3
- export const MAX_COLUMNS = 7
3
+ export const MAX_COLUMNS = {
4
+ codeOnly: 5,
5
+ titleOnly: 4,
6
+ titleAndCode: 3,
7
+ }
4
8
 
5
9
  export const CONFIG_DEFAULT: Required<PluginConfig> = {
6
10
  languages: [],
@@ -10,4 +14,5 @@ export const CONFIG_DEFAULT: Required<PluginConfig> = {
10
14
  apiVersion: '2022-11-27',
11
15
  buttonLocations: ['field'],
12
16
  buttonAddAll: true,
17
+ languageDisplay: 'codeOnly',
13
18
  }
package/src/types.ts CHANGED
@@ -35,6 +35,8 @@ export type LanguageCallback = (
35
35
  selectedValue: Record<string, unknown>
36
36
  ) => Promise<Language[]>
37
37
 
38
+ export type LanguageDisplay = 'titleOnly' | 'codeOnly' | 'titleAndCode'
39
+
38
40
  export type PluginConfig = {
39
41
  /**
40
42
  * https://www.sanity.io/docs/api-versioning
@@ -125,4 +127,9 @@ export type PluginConfig = {
125
127
  * @defaultValue true
126
128
  * */
127
129
  buttonAddAll?: boolean
130
+ /**
131
+ * How to display the languages on buttons and fields
132
+ * @defaultValue 'code'
133
+ * */
134
+ languageDisplay?: LanguageDisplay
128
135
  }
@@ -0,0 +1,13 @@
1
+ import {LanguageDisplay} from '../types'
2
+
3
+ export function getLanguageDisplay(
4
+ languageDisplay: LanguageDisplay,
5
+ title: string,
6
+ code: string
7
+ ): string {
8
+ if (languageDisplay === 'codeOnly') return code.toUpperCase()
9
+ if (languageDisplay === 'titleOnly') return title
10
+ if (languageDisplay === 'titleAndCode')
11
+ return `${title} (${code.toUpperCase()})`
12
+ return title
13
+ }