@firecms/core 3.1.0-canary.1df3b2c → 3.1.0-canary.501d471

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.
Files changed (246) hide show
  1. package/dist/components/EntityCollectionTable/internal/popup_field/useDraggable.d.ts +2 -2
  2. package/dist/components/EntityCollectionView/CollectionDataErrorBanner.d.ts +4 -0
  3. package/dist/components/EntityCollectionView/ViewModeToggle.d.ts +5 -10
  4. package/dist/components/ErrorBoundary.d.ts +4 -2
  5. package/dist/components/HomePage/DefaultHomePage.d.ts +0 -1
  6. package/dist/components/LanguageToggle.d.ts +1 -0
  7. package/dist/components/UnsavedChangesDialog.d.ts +1 -0
  8. package/dist/components/VirtualTable/VirtualTableHeader.d.ts +2 -1
  9. package/dist/components/VirtualTable/VirtualTableHeaderRow.d.ts +1 -1
  10. package/dist/components/VirtualTable/VirtualTableProps.d.ts +6 -1
  11. package/dist/components/VirtualTable/types.d.ts +1 -0
  12. package/dist/components/index.d.ts +1 -0
  13. package/dist/core/DrawerNavigationGroup.d.ts +2 -2
  14. package/dist/editor/components/SlashCommandMenu.d.ts +6 -0
  15. package/dist/editor/components/editor-bubble-item.d.ts +8 -0
  16. package/dist/editor/components/editor-bubble.d.ts +8 -0
  17. package/dist/editor/components/image-bubble.d.ts +5 -0
  18. package/dist/editor/components/index.d.ts +16 -0
  19. package/dist/editor/components/table-bubble.d.ts +5 -0
  20. package/dist/editor/editor.d.ts +30 -0
  21. package/dist/editor/extensions/HighlightDecorationExtension.d.ts +24 -0
  22. package/dist/editor/extensions/Image/index.d.ts +6 -0
  23. package/dist/editor/extensions/Image.d.ts +6 -0
  24. package/dist/editor/extensions/TextLoadingDecorationExtension.d.ts +16 -0
  25. package/dist/editor/extensions/clipboard.d.ts +7 -0
  26. package/dist/editor/extensions/custom-keymap.d.ts +1 -0
  27. package/dist/editor/extensions/drag-and-drop.d.ts +9 -0
  28. package/dist/editor/hooks/useProseMirror.d.ts +13 -0
  29. package/dist/editor/hooks/useProseMirrorContext.d.ts +9 -0
  30. package/dist/editor/index.d.ts +2 -0
  31. package/dist/editor/markdown.d.ts +5 -0
  32. package/dist/editor/nodeViews/ImageComponent.d.ts +3 -0
  33. package/dist/editor/nodeViews/ReactNodeView.d.ts +29 -0
  34. package/dist/editor/nodeViews/TaskItemComponent.d.ts +3 -0
  35. package/dist/editor/nodeViews/index.d.ts +6 -0
  36. package/dist/editor/plugins/index.d.ts +2 -0
  37. package/dist/editor/plugins/inputrules.d.ts +6 -0
  38. package/dist/editor/plugins/placeholderPlugin.d.ts +3 -0
  39. package/dist/editor/plugins/slashCommandPlugin.d.ts +12 -0
  40. package/dist/editor/schema.d.ts +2 -0
  41. package/dist/editor/selectors/ai-selector.d.ts +0 -0
  42. package/dist/editor/selectors/color-selector.d.ts +10 -0
  43. package/dist/editor/selectors/link-selector.d.ts +8 -0
  44. package/dist/editor/selectors/node-selector.d.ts +15 -0
  45. package/dist/editor/selectors/text-buttons.d.ts +1 -0
  46. package/dist/editor/types.d.ts +5 -0
  47. package/dist/editor/useProseMirror.d.ts +16 -0
  48. package/dist/editor/utils/prosemirror-utils.d.ts +6 -0
  49. package/dist/editor/utils/remove_classes.d.ts +1 -0
  50. package/dist/editor/utils/useDebouncedCallback.d.ts +1 -0
  51. package/dist/form/components/ErrorFocus.d.ts +1 -1
  52. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  53. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
  54. package/dist/hooks/index.d.ts +1 -0
  55. package/dist/hooks/useBuildNavigationController.d.ts +0 -1
  56. package/dist/hooks/useCollapsedGroups.d.ts +3 -3
  57. package/dist/hooks/useTranslation.d.ts +17 -0
  58. package/dist/i18n/FireCMSi18nProvider.d.ts +33 -0
  59. package/dist/index.d.ts +5 -0
  60. package/dist/index.es.js +29682 -18363
  61. package/dist/index.es.js.map +1 -1
  62. package/dist/index.umd.js +29681 -18382
  63. package/dist/index.umd.js.map +1 -1
  64. package/dist/internal/useRestoreScroll.d.ts +1 -1
  65. package/dist/locales/de.d.ts +2 -0
  66. package/dist/locales/en.d.ts +10 -0
  67. package/dist/locales/es.d.ts +10 -0
  68. package/dist/locales/fr.d.ts +2 -0
  69. package/dist/locales/hi.d.ts +2 -0
  70. package/dist/locales/it.d.ts +2 -0
  71. package/dist/locales/pt.d.ts +7 -0
  72. package/dist/types/analytics.d.ts +1 -1
  73. package/dist/types/collections.d.ts +46 -0
  74. package/dist/types/customization_controller.d.ts +2 -1
  75. package/dist/types/firecms.d.ts +2 -1
  76. package/dist/types/index.d.ts +1 -0
  77. package/dist/types/navigation.d.ts +2 -2
  78. package/dist/types/plugins.d.ts +23 -0
  79. package/dist/types/properties.d.ts +9 -8
  80. package/dist/types/storage.d.ts +1 -0
  81. package/dist/types/translations.d.ts +669 -0
  82. package/dist/util/entities.d.ts +1 -1
  83. package/dist/util/index.d.ts +1 -0
  84. package/dist/util/lazy_eager.d.ts +7 -0
  85. package/dist/util/objects.d.ts +1 -0
  86. package/dist/util/resolutions.d.ts +2 -2
  87. package/dist/util/useStorageUploadController.d.ts +10 -1
  88. package/package.json +49 -13
  89. package/src/app/Scaffold.tsx +7 -5
  90. package/src/components/AIIcon.tsx +3 -1
  91. package/src/components/ArrayContainer.tsx +6 -4
  92. package/src/components/ClearFilterSortButton.tsx +6 -3
  93. package/src/components/ConfirmationDialog.tsx +4 -2
  94. package/src/components/DeleteEntityDialog.tsx +10 -7
  95. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +9 -3
  96. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +6 -3
  97. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -1
  98. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -1
  99. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +3 -2
  100. package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +11 -11
  101. package/src/components/EntityCollectionView/BoardSortableList.tsx +3 -1
  102. package/src/components/EntityCollectionView/CollectionDataErrorBanner.tsx +43 -0
  103. package/src/components/EntityCollectionView/EntityBoardCard.tsx +1 -1
  104. package/src/components/EntityCollectionView/EntityCard.tsx +4 -0
  105. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +39 -46
  106. package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +17 -25
  107. package/src/components/EntityCollectionView/EntityCollectionView.tsx +71 -31
  108. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -3
  109. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +4 -2
  110. package/src/components/EntityCollectionView/FiltersDialog.tsx +8 -5
  111. package/src/components/EntityCollectionView/ViewModeToggle.tsx +37 -37
  112. package/src/components/EntityJsonPreview.tsx +2 -1
  113. package/src/components/EntityView.tsx +3 -2
  114. package/src/components/ErrorBoundary.tsx +27 -15
  115. package/src/components/HomePage/DefaultHomePage.tsx +19 -13
  116. package/src/components/HomePage/HomePageDnD.tsx +3 -1
  117. package/src/components/HomePage/NavigationGroup.tsx +3 -1
  118. package/src/components/HomePage/RenameGroupDialog.tsx +15 -13
  119. package/src/components/LanguageToggle.tsx +66 -0
  120. package/src/components/NotFoundPage.tsx +5 -3
  121. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +9 -7
  122. package/src/components/ReferenceWidget.tsx +3 -2
  123. package/src/components/SearchIconsView.tsx +3 -1
  124. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +11 -0
  125. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +15 -2
  126. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +11 -0
  127. package/src/components/UnsavedChangesDialog.tsx +6 -4
  128. package/src/components/VirtualTable/VirtualTable.performance.test.tsx +1 -0
  129. package/src/components/VirtualTable/VirtualTable.tsx +121 -116
  130. package/src/components/VirtualTable/VirtualTableHeader.tsx +59 -56
  131. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +9 -4
  132. package/src/components/VirtualTable/VirtualTableProps.tsx +7 -1
  133. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +3 -3
  134. package/src/components/VirtualTable/types.tsx +1 -0
  135. package/src/components/common/default_entity_actions.tsx +4 -0
  136. package/src/components/common/useDataSourceTableController.tsx +12 -4
  137. package/src/components/index.tsx +1 -0
  138. package/src/core/DefaultAppBar.tsx +15 -11
  139. package/src/core/DefaultDrawer.tsx +8 -2
  140. package/src/core/DrawerNavigationGroup.tsx +5 -3
  141. package/src/core/EntityEditView.tsx +54 -8
  142. package/src/core/EntityEditViewFormActions.tsx +24 -17
  143. package/src/core/EntitySidePanel.tsx +34 -30
  144. package/src/core/FireCMS.tsx +33 -6
  145. package/src/core/field_configs.tsx +18 -11
  146. package/src/editor/components/SlashCommandMenu.tsx +516 -0
  147. package/src/editor/components/editor-bubble-item.tsx +32 -0
  148. package/src/editor/components/editor-bubble.tsx +118 -0
  149. package/src/editor/components/image-bubble.tsx +156 -0
  150. package/src/editor/components/index.ts +14 -0
  151. package/src/editor/components/table-bubble.tsx +165 -0
  152. package/src/editor/editor.tsx +455 -0
  153. package/src/editor/extensions/HighlightDecorationExtension.ts +114 -0
  154. package/src/editor/extensions/Image/index.ts +133 -0
  155. package/src/editor/extensions/Image.ts +159 -0
  156. package/src/editor/extensions/TextLoadingDecorationExtension.tsx +107 -0
  157. package/src/editor/extensions/clipboard.ts +72 -0
  158. package/src/editor/extensions/custom-keymap.ts +24 -0
  159. package/src/editor/extensions/drag-and-drop.tsx +480 -0
  160. package/src/editor/hooks/useProseMirror.ts +124 -0
  161. package/src/editor/hooks/useProseMirrorContext.ts +15 -0
  162. package/src/editor/index.ts +2 -0
  163. package/src/editor/markdown.ts +172 -0
  164. package/src/editor/nodeViews/ImageComponent.tsx +20 -0
  165. package/src/editor/nodeViews/ReactNodeView.tsx +89 -0
  166. package/src/editor/nodeViews/TaskItemComponent.tsx +29 -0
  167. package/src/editor/nodeViews/index.ts +35 -0
  168. package/src/editor/plugins/index.ts +58 -0
  169. package/src/editor/plugins/inputrules.ts +82 -0
  170. package/src/editor/plugins/placeholderPlugin.ts +55 -0
  171. package/src/editor/plugins/slashCommandPlugin.ts +61 -0
  172. package/src/editor/schema.ts +240 -0
  173. package/src/editor/selectors/ai-selector.tsx +111 -0
  174. package/src/editor/selectors/color-selector.tsx +200 -0
  175. package/src/editor/selectors/link-selector.tsx +118 -0
  176. package/src/editor/selectors/node-selector.tsx +157 -0
  177. package/src/editor/selectors/text-buttons.tsx +86 -0
  178. package/src/editor/types.ts +6 -0
  179. package/src/editor/useProseMirror.ts +126 -0
  180. package/src/editor/utils/prosemirror-utils.ts +108 -0
  181. package/src/editor/utils/remove_classes.ts +17 -0
  182. package/src/editor/utils/useDebouncedCallback.ts +25 -0
  183. package/src/form/EntityForm.tsx +149 -67
  184. package/src/form/EntityFormActions.tsx +19 -12
  185. package/src/form/PropertyFieldBinding.tsx +10 -8
  186. package/src/form/components/ErrorFocus.tsx +3 -3
  187. package/src/form/components/LocalChangesMenu.tsx +13 -13
  188. package/src/form/components/StorageItemPreview.tsx +3 -2
  189. package/src/form/components/StorageUploadProgress.tsx +18 -3
  190. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +18 -5
  191. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +22 -9
  192. package/src/form/field_bindings/BlockFieldBinding.tsx +26 -9
  193. package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
  194. package/src/form/field_bindings/KeyValueFieldBinding.tsx +46 -24
  195. package/src/form/field_bindings/MapFieldBinding.tsx +27 -11
  196. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +74 -37
  197. package/src/form/field_bindings/MultiSelectFieldBinding.tsx +15 -1
  198. package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +25 -11
  199. package/src/form/field_bindings/ReferenceFieldBinding.tsx +25 -11
  200. package/src/form/field_bindings/RepeatFieldBinding.tsx +21 -6
  201. package/src/form/field_bindings/SelectFieldBinding.tsx +7 -5
  202. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +110 -92
  203. package/src/form/field_bindings/SwitchFieldBinding.tsx +31 -14
  204. package/src/form/field_bindings/TextFieldBinding.tsx +10 -7
  205. package/src/form/field_bindings/UserSelectFieldBinding.tsx +7 -5
  206. package/src/hooks/index.tsx +1 -0
  207. package/src/hooks/useBuildNavigationController.tsx +49 -22
  208. package/src/hooks/useCollapsedGroups.ts +7 -6
  209. package/src/hooks/useTranslation.ts +31 -0
  210. package/src/hooks/useValidateAuthenticator.tsx +1 -1
  211. package/src/i18n/FireCMSi18nProvider.tsx +160 -0
  212. package/src/index.ts +5 -0
  213. package/src/internal/useBuildDataSource.ts +1 -2
  214. package/src/internal/useBuildSideEntityController.tsx +22 -20
  215. package/src/locales/de.ts +718 -0
  216. package/src/locales/en.ts +730 -0
  217. package/src/locales/es.ts +730 -0
  218. package/src/locales/fr.ts +718 -0
  219. package/src/locales/hi.ts +718 -0
  220. package/src/locales/it.ts +718 -0
  221. package/src/locales/pt.ts +727 -0
  222. package/src/preview/PropertyPreview.tsx +4 -2
  223. package/src/preview/components/ReferencePreview.tsx +2 -1
  224. package/src/preview/components/UrlComponentPreview.tsx +4 -2
  225. package/src/preview/components/UserPreview.tsx +3 -1
  226. package/src/preview/property_previews/MapPropertyPreview.tsx +49 -27
  227. package/src/routes/FireCMSRoute.tsx +63 -54
  228. package/src/types/analytics.ts +10 -0
  229. package/src/types/collections.ts +49 -0
  230. package/src/types/customization_controller.tsx +2 -1
  231. package/src/types/firecms.tsx +2 -1
  232. package/src/types/index.ts +1 -0
  233. package/src/types/navigation.ts +2 -2
  234. package/src/types/plugins.tsx +26 -0
  235. package/src/types/properties.ts +12 -10
  236. package/src/types/storage.ts +2 -1
  237. package/src/types/translations.ts +752 -0
  238. package/src/util/entities.ts +1 -1
  239. package/src/util/index.ts +1 -0
  240. package/src/util/join_collections.ts +10 -8
  241. package/src/util/lazy_eager.tsx +33 -0
  242. package/src/util/objects.ts +15 -0
  243. package/src/util/previews.ts +2 -2
  244. package/src/util/property_utils.tsx +1 -1
  245. package/src/util/resolutions.ts +5 -3
  246. package/src/util/useStorageUploadController.tsx +23 -29
@@ -11,9 +11,14 @@ import {
11
11
  useAuthController,
12
12
  useStorageSource
13
13
  } from "../../index";
14
- import { cls, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundMixin } from "@firecms/ui";
15
- import { FireCMSEditor, FireCMSEditorProps } from "@firecms/editor";
14
+ import { cls, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundMixin, IconButton, CloseIcon } from "@firecms/ui";
15
+ import type { FireCMSEditorProps } from "../../editor";
16
16
  import { resolveProperty, resolveStorageFilenameString, resolveStoragePathString } from "../../util";
17
+ import { isImageFile, resizeImage } from "../../util/useStorageUploadController";
18
+ import { lazyEager } from "../../util/lazy_eager";
19
+ import { CircularProgressCenter } from "../../components/CircularProgressCenter";
20
+
21
+ const FireCMSEditor = lazyEager<typeof import("../../editor/editor")["FireCMSEditor"]>(() => import("../../editor/editor"), "FireCMSEditor");
17
22
 
18
23
  interface MarkdownEditorFieldProps {
19
24
  highlight?: { from: number, to: number };
@@ -50,22 +55,22 @@ export function MarkdownEditorFieldBinding({
50
55
  const internalValue = useRef<string | null>(value);
51
56
 
52
57
  const onContentChange = useCallback((content: string) => {
53
- if (content === value || (value === null && content === "")) {
58
+ if (content === value || ((value === null || value === undefined) && content === "")) {
54
59
  return;
55
60
  }
56
61
  internalValue.current = content;
57
62
  setValue(content);
58
- }, [setValue]);
63
+ }, [setValue, value]);
59
64
 
60
65
  useEffect(() => {
61
66
  if (internalValue.current !== value) {
62
67
  internalValue.current = value;
63
- setFieldVersion(fieldVersion + 1);
68
+ setFieldVersion(v => v + 1);
64
69
  }
65
70
  }, [value]);
66
71
 
67
72
  const resolvedProperty = resolveProperty({
68
- propertyOrBuilder: property as PropertyOrBuilder,
73
+ propertyOrBuilder: property as PropertyOrBuilder<string>,
69
74
  values: entityValues,
70
75
  authController
71
76
  }) as ResolvedStringProperty | ResolvedArrayProperty<string[]>;
@@ -112,42 +117,74 @@ export function MarkdownEditorFieldBinding({
112
117
  // Extract markdown config from property - can be boolean or object
113
118
  const markdownConfig = typeof property.markdown === 'object' ? property.markdown : undefined;
114
119
 
115
- const editor = <FireCMSEditor
116
- content={value}
117
- onMarkdownContentChange={onContentChange}
118
- version={context.formex.version + fieldVersion}
119
- highlight={highlight}
120
- disabled={disabled}
121
- markdownConfig={markdownConfig}
122
- handleImageUpload={async (file: File) => {
123
- const storagePath = storagePathBuilder(file);
124
- const fileName = await fileNameBuilder(file);
125
- const result = await storageSource.uploadFile({
126
- file,
127
- fileName,
128
- path: storagePath,
129
- });
130
- const downloadConfig = await storageSource.getDownloadURL(result.path);
131
- const url = downloadConfig.url;
132
- if (!url) {
133
- throw new Error("Error uploading image");
134
- }
135
- return url;
136
- }}
137
- {...editorProps}
138
- />;
120
+ const handleImageUpload = async (file: File) => {
121
+ const imageResize = storage?.imageResize;
122
+ const legacyCompression = storage?.imageCompression;
123
+ if ((imageResize || legacyCompression) && isImageFile(file)) {
124
+ file = await resizeImage(file, imageResize, legacyCompression);
125
+ }
126
+
127
+ const storagePath = storagePathBuilder(file);
128
+ const fileName = await fileNameBuilder(file);
129
+ const result = await storageSource.uploadFile({
130
+ file,
131
+ fileName,
132
+ path: storagePath,
133
+ });
134
+ const downloadConfig = await storageSource.getDownloadURL(result.path);
135
+ const url = downloadConfig.url;
136
+ if (!url) {
137
+ throw new Error("Error uploading image");
138
+ }
139
+ return url;
140
+ };
141
+
142
+ const editor = (
143
+ <React.Suspense fallback={<CircularProgressCenter />}>
144
+ <FireCMSEditor
145
+ key={context.formex.version + fieldVersion}
146
+ content={value}
147
+ onMarkdownContentChange={onContentChange}
148
+ version={context.formex.version + fieldVersion}
149
+ highlight={highlight}
150
+ disabled={disabled}
151
+ markdownConfig={markdownConfig}
152
+ handleImageUpload={handleImageUpload}
153
+ {...editorProps}
154
+ />
155
+ </React.Suspense>
156
+ );
139
157
 
140
158
  if (minimalistView)
141
- return editor;
159
+ return (
160
+ <>
161
+ {editor}
162
+ </>
163
+ );
142
164
 
143
165
  return (
144
166
  <>
145
- <LabelWithIconAndTooltip
146
- propertyKey={propertyKey}
147
- icon={getIconForProperty(property, "small")}
148
- required={property.validation?.required}
149
- title={property.name}
150
- className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"} />
167
+ <div className="flex items-center w-full">
168
+ <LabelWithIconAndTooltip
169
+ propertyKey={propertyKey}
170
+ icon={getIconForProperty(property, "small")}
171
+ required={property.validation?.required}
172
+ title={property.name}
173
+ className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"} />
174
+ <div className="flex-grow"/>
175
+ {(property.nullable || property.clearable) && !disabled && (
176
+ <IconButton
177
+ size="small"
178
+ onClick={(e) => {
179
+ e.stopPropagation();
180
+ e.preventDefault();
181
+ setValue(null);
182
+ }}
183
+ >
184
+ <CloseIcon size={"small"}/>
185
+ </IconButton>
186
+ )}
187
+ </div>
151
188
  <div
152
189
  className={cls("rounded-md", fieldBackgroundMixin, disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin)}>
153
190
  {editor}
@@ -4,7 +4,7 @@ import { EnumType, FieldProps, ResolvedProperty } from "../../types";
4
4
  import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
5
5
  import { EnumValuesChip } from "../../preview";
6
6
  import { enumToObjectEntries, getIconForProperty, getLabelOrConfigFrom } from "../../util";
7
- import { CloseIcon, MultiSelect, MultiSelectItem } from "@firecms/ui";
7
+ import { CloseIcon, MultiSelect, MultiSelectItem, IconButton } from "@firecms/ui";
8
8
  import { useClearRestoreValue } from "../useClearRestoreValue";
9
9
 
10
10
  /**
@@ -93,6 +93,20 @@ export function MultiSelectFieldBinding({
93
93
  required={property.validation?.required}
94
94
  title={property.name}
95
95
  className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
96
+ endAdornment={
97
+ (property.nullable || property.clearable) && !disabled && value !== null && value !== undefined ? (
98
+ <IconButton
99
+ size="small"
100
+ onClick={(e) => {
101
+ e.stopPropagation();
102
+ e.preventDefault();
103
+ setValue(null);
104
+ }}
105
+ >
106
+ <CloseIcon size={"small"}/>
107
+ </IconButton>
108
+ ) : undefined
109
+ }
96
110
  onValueChange={(updatedValue: string[]) => {
97
111
  let newValue: EnumType[] | null;
98
112
  if (of && (of as ResolvedProperty)?.dataType === "number") {
@@ -8,7 +8,7 @@ import { ReferencePreview } from "../../preview";
8
8
  import { getIconForProperty, IconForView } from "../../util";
9
9
  import { useClearRestoreValue } from "../useClearRestoreValue";
10
10
  import { EntityPreviewContainer } from "../../components/EntityPreview";
11
- import { cls } from "@firecms/ui";
11
+ import { cls, IconButton, CloseIcon } from "@firecms/ui";
12
12
 
13
13
  /**
14
14
  * Field that opens a reference selection dialog and stores the entity ID as a string.
@@ -98,16 +98,30 @@ function ReferenceAsStringFieldBindingInternal({
98
98
 
99
99
  {collection && <>
100
100
 
101
- {referenceValue && <ReferencePreview
102
- disabled={!path}
103
- previewProperties={property.reference?.previewProperties}
104
- hover={!disabled}
105
- size={size}
106
- onClick={disabled || isSubmitting ? undefined : onEntryClick}
107
- reference={referenceValue}
108
- includeEntityLink={property.reference?.includeEntityLink}
109
- includeId={property.reference?.includeId}
110
- />}
101
+ {referenceValue && <div className="flex items-center gap-2">
102
+ <ReferencePreview
103
+ disabled={!path}
104
+ previewProperties={property.reference?.previewProperties}
105
+ hover={!disabled}
106
+ size={size}
107
+ onClick={disabled || isSubmitting ? undefined : onEntryClick}
108
+ reference={referenceValue}
109
+ includeEntityLink={property.reference?.includeEntityLink}
110
+ includeId={property.reference?.includeId}
111
+ />
112
+ {(property.nullable || property.clearable) && !disabled && (
113
+ <IconButton
114
+ size="small"
115
+ onClick={(e) => {
116
+ e.stopPropagation();
117
+ e.preventDefault();
118
+ setValue(null);
119
+ }}
120
+ >
121
+ <CloseIcon size={"small"}/>
122
+ </IconButton>
123
+ )}
124
+ </div>}
111
125
 
112
126
  {!value && <div className="justify-center text-left">
113
127
  <EntityPreviewContainer
@@ -9,7 +9,7 @@ import { EmptyValue, ReferencePreview } from "../../preview";
9
9
  import { getIconForProperty, getReferenceFrom, IconForView } from "../../util";
10
10
  import { useClearRestoreValue } from "../useClearRestoreValue";
11
11
  import { EntityPreviewContainer } from "../../components/EntityPreview";
12
- import { cls } from "@firecms/ui";
12
+ import { cls, IconButton, CloseIcon } from "@firecms/ui";
13
13
 
14
14
  /**
15
15
  * Field that opens a reference selection dialog.
@@ -97,16 +97,30 @@ function ReferenceFieldBindingInternal({
97
97
 
98
98
  {collection && <>
99
99
 
100
- {value && <ReferencePreview
101
- disabled={!property.path}
102
- previewProperties={property.previewProperties}
103
- hover={!disabled}
104
- size={size}
105
- onClick={disabled || isSubmitting ? undefined : onEntryClick}
106
- reference={value}
107
- includeEntityLink={property.includeEntityLink}
108
- includeId={property.includeId}
109
- />}
100
+ {value && <div className="flex items-center gap-2">
101
+ <ReferencePreview
102
+ disabled={!property.path}
103
+ previewProperties={property.previewProperties}
104
+ hover={!disabled}
105
+ size={size}
106
+ onClick={disabled || isSubmitting ? undefined : onEntryClick}
107
+ reference={value}
108
+ includeEntityLink={property.includeEntityLink}
109
+ includeId={property.includeId}
110
+ />
111
+ {(property.nullable || property.clearable) && !disabled && (
112
+ <IconButton
113
+ size="small"
114
+ onClick={(e) => {
115
+ e.stopPropagation();
116
+ e.preventDefault();
117
+ setValue(null);
118
+ }}
119
+ >
120
+ <CloseIcon size={"small"}/>
121
+ </IconButton>
122
+ )}
123
+ </div>}
110
124
 
111
125
  {!value && <div className="justify-center text-left">
112
126
  <EntityPreviewContainer className={cls("px-6 h-16 text-sm font-medium flex items-center gap-6",
@@ -4,9 +4,10 @@ import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
4
4
  import { ArrayContainer, ArrayEntryParams, ErrorBoundary } from "../../components";
5
5
  import { getArrayResolvedProperties, getDefaultValueFor, getIconForProperty, mergeDeep } from "../../util";
6
6
  import { PropertyFieldBinding } from "../PropertyFieldBinding";
7
- import { ExpandablePanel, Typography } from "@firecms/ui";
7
+ import { ExpandablePanel, Typography, IconButton, CloseIcon } from "@firecms/ui";
8
8
  import { useClearRestoreValue } from "../useClearRestoreValue";
9
9
  import { useAuthController } from "../../hooks";
10
+ import { useTranslation } from "../../hooks/useTranslation";
10
11
 
11
12
  /**
12
13
  * Generic array field that allows reordering and renders the child property
@@ -34,6 +35,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
34
35
 
35
36
  const authController = useAuthController();
36
37
  const minimalistView = minimalistViewProp || property.minimalistView;
38
+ const { t } = useTranslation();
37
39
 
38
40
  if (!property.of)
39
41
  throw Error("RepeatFieldBinding misconfiguration. Property `of` not set");
@@ -87,7 +89,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
87
89
  const canAddElements = !property.disabled && !isSubmitting && !disabled && (property.canAddElements || property.canAddElements === undefined);
88
90
  const sortable = property.sortable === undefined ? true : property.sortable;
89
91
  const arrayContainer = <ArrayContainer droppableId={propertyKey}
90
- addLabel={property.name ? "Add entry to " + property.name : "Add entry"}
92
+ addLabel={property.name ? t("add_to_field", { fieldName: property.name }) : t("add_entry")}
91
93
  value={value}
92
94
  buildEntry={buildEntry}
93
95
  onInternalIdAdded={setLastAddedId}
@@ -99,15 +101,28 @@ export function RepeatFieldBinding<T extends Array<any>>({
99
101
  className={property.widthPercentage !== undefined ? "mt-8" : undefined}
100
102
  />;
101
103
 
102
- const title = (<>
104
+ const title = (<div className="flex items-center w-full">
103
105
  <LabelWithIconAndTooltip
104
106
  propertyKey={propertyKey}
105
107
  icon={getIconForProperty(property, "small")}
106
108
  required={property.validation?.required}
107
109
  title={property.name}
108
- className={"h-8 flex flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
109
- {Array.isArray(value) && <Typography variant={"caption"} className={"px-4"}>({value.length})</Typography>}
110
- </>);
110
+ className={"text-text-secondary dark:text-text-secondary-dark"}/>
111
+ {Array.isArray(value) && <span className={"text-sm text-text-secondary dark:text-text-secondary-dark ml-1"}>({value.length})</span>}
112
+ <div className="flex-grow"/>
113
+ {(property.nullable || property.clearable) && !disabled && (
114
+ <IconButton
115
+ size="small"
116
+ onClick={(e) => {
117
+ e.stopPropagation();
118
+ e.preventDefault();
119
+ setValue(null);
120
+ }}
121
+ >
122
+ <CloseIcon size={"small"}/>
123
+ </IconButton>
124
+ )}
125
+ </div>);
111
126
 
112
127
  return (
113
128
 
@@ -66,11 +66,13 @@ export function SelectFieldBinding<T extends EnumType>({
66
66
  />
67
67
  </PropertyIdCopyTooltip>}
68
68
  endAdornment={
69
- property.clearable && !disabled && <IconButton
70
- size="small"
71
- onClick={handleClearClick}>
72
- <CloseIcon size={"small"}/>
73
- </IconButton>
69
+ (property.nullable || property.clearable) && !disabled && value !== null && value !== undefined ? (
70
+ <IconButton
71
+ size="small"
72
+ onClick={handleClearClick}>
73
+ <CloseIcon size={"small"}/>
74
+ </IconButton>
75
+ ) : undefined
74
76
  }
75
77
  onValueChange={(updatedValue: string) => {
76
78
  const newValue = updatedValue