@firecms/core 3.0.0-beta.7 → 3.0.0-beta.9

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 (216) hide show
  1. package/dist/app/AppBar.d.ts +12 -0
  2. package/dist/app/Drawer.d.ts +17 -0
  3. package/dist/app/Scaffold.d.ts +30 -0
  4. package/dist/app/index.d.ts +4 -0
  5. package/dist/app/useApp.d.ts +16 -0
  6. package/dist/components/ArrayContainer.d.ts +2 -1
  7. package/dist/components/CircularProgressCenter.d.ts +1 -1
  8. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +0 -1
  9. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +1 -1
  10. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
  11. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +1 -1
  12. package/dist/components/EntityPreview.d.ts +1 -1
  13. package/dist/components/ErrorView.d.ts +1 -1
  14. package/dist/components/HomePage/DefaultHomePage.d.ts +1 -1
  15. package/dist/components/HomePage/NavigationCardBinding.d.ts +1 -1
  16. package/dist/components/PropertyIdCopyTooltip.d.ts +8 -0
  17. package/dist/components/VirtualTable/VirtualTableProps.d.ts +14 -6
  18. package/dist/components/common/useColumnsIds.d.ts +2 -1
  19. package/dist/components/index.d.ts +2 -1
  20. package/dist/{components/FireCMSAppBar.d.ts → core/DefaultAppBar.d.ts} +3 -8
  21. package/dist/core/DefaultDrawer.d.ts +19 -0
  22. package/dist/core/DrawerNavigationItem.d.ts +2 -1
  23. package/dist/core/EntityEditView.d.ts +18 -4
  24. package/dist/core/FireCMS.d.ts +1 -1
  25. package/dist/core/NavigationRoutes.d.ts +2 -2
  26. package/dist/core/index.d.ts +2 -2
  27. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  28. package/dist/form/components/FieldHelperText.d.ts +3 -3
  29. package/dist/form/components/FormikArrayContainer.d.ts +2 -1
  30. package/dist/form/components/LabelWithIcon.d.ts +1 -1
  31. package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
  32. package/dist/form/components/StorageItemPreview.d.ts +4 -4
  33. package/dist/form/components/index.d.ts +1 -0
  34. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  35. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  36. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  37. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  38. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  39. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +11 -0
  40. package/dist/form/field_bindings/{MultiSelectBinding.d.ts → MultiSelectFieldBinding.d.ts} +1 -1
  41. package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
  42. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  43. package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
  44. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +3 -5
  45. package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
  46. package/dist/form/index.d.ts +3 -5
  47. package/dist/form/useClearRestoreValue.d.ts +2 -2
  48. package/dist/hooks/useProjectLog.d.ts +2 -2
  49. package/dist/index.d.ts +1 -0
  50. package/dist/index.es.js +14434 -11300
  51. package/dist/index.es.js.map +1 -1
  52. package/dist/index.umd.js +19987 -587
  53. package/dist/index.umd.js.map +1 -1
  54. package/dist/preview/PropertyPreviewProps.d.ts +6 -1
  55. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  56. package/dist/preview/components/ReferencePreview.d.ts +1 -1
  57. package/dist/preview/components/StorageThumbnail.d.ts +2 -1
  58. package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
  59. package/dist/types/auth.d.ts +2 -2
  60. package/dist/types/collections.d.ts +26 -3
  61. package/dist/types/datasource.d.ts +53 -30
  62. package/dist/types/entities.d.ts +1 -0
  63. package/dist/types/entity_overrides.d.ts +2 -2
  64. package/dist/types/fields.d.ts +47 -41
  65. package/dist/types/navigation.d.ts +1 -0
  66. package/dist/types/plugins.d.ts +11 -3
  67. package/dist/types/properties.d.ts +25 -20
  68. package/dist/types/side_dialogs_controller.d.ts +10 -0
  69. package/dist/types/storage.d.ts +75 -0
  70. package/dist/util/entities.d.ts +1 -1
  71. package/dist/util/icon_list.d.ts +5 -1
  72. package/dist/util/icons.d.ts +3 -2
  73. package/dist/util/index.d.ts +1 -0
  74. package/dist/util/plurals.d.ts +0 -2
  75. package/dist/util/property_utils.d.ts +1 -1
  76. package/dist/util/resolutions.d.ts +15 -1
  77. package/dist/util/storage.d.ts +23 -2
  78. package/dist/util/useStorageUploadController.d.ts +3 -3
  79. package/package.json +18 -29
  80. package/src/app/AppBar.tsx +18 -0
  81. package/src/app/Drawer.tsx +25 -0
  82. package/src/{core → app}/Scaffold.tsx +71 -122
  83. package/src/app/index.ts +4 -0
  84. package/src/app/useApp.tsx +32 -0
  85. package/src/components/ArrayContainer.tsx +15 -10
  86. package/src/components/CircularProgressCenter.tsx +1 -1
  87. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +11 -18
  88. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +2 -2
  89. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +4 -2
  90. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +21 -14
  91. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +12 -4
  92. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +17 -19
  93. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +19 -7
  94. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +5 -6
  95. package/src/components/EntityCollectionView/EntityCollectionView.tsx +33 -29
  96. package/src/components/EntityCollectionView/useSelectionController.tsx +19 -7
  97. package/src/components/EntityPreview.tsx +30 -31
  98. package/src/components/ErrorView.tsx +1 -1
  99. package/src/components/HomePage/DefaultHomePage.tsx +24 -18
  100. package/src/components/HomePage/NavigationCardBinding.tsx +1 -1
  101. package/src/components/HomePage/SmallNavigationCard.tsx +1 -2
  102. package/src/components/PropertyIdCopyTooltip.tsx +48 -0
  103. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +7 -6
  104. package/src/components/SearchIconsView.tsx +5 -2
  105. package/src/components/SelectableTable/SelectableTable.tsx +2 -4
  106. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +1 -1
  107. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +54 -7
  108. package/src/components/VirtualTable/VirtualTable.tsx +36 -10
  109. package/src/components/VirtualTable/VirtualTableCell.tsx +1 -9
  110. package/src/components/VirtualTable/VirtualTableProps.tsx +17 -8
  111. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +3 -3
  112. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +2 -1
  113. package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +2 -1
  114. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +14 -28
  115. package/src/components/common/useColumnsIds.tsx +13 -0
  116. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +12 -12
  117. package/src/components/common/useTableSearchHelper.ts +53 -12
  118. package/src/components/index.tsx +2 -1
  119. package/src/contexts/DialogsProvider.tsx +2 -2
  120. package/src/{components/FireCMSAppBar.tsx → core/DefaultAppBar.tsx} +28 -30
  121. package/src/core/DefaultDrawer.tsx +183 -0
  122. package/src/core/DrawerNavigationItem.tsx +31 -27
  123. package/src/core/EntityEditView.tsx +712 -145
  124. package/src/core/EntitySidePanel.tsx +0 -1
  125. package/src/core/FireCMS.tsx +2 -2
  126. package/src/core/NavigationRoutes.tsx +4 -4
  127. package/src/core/SideDialogs.tsx +1 -0
  128. package/src/core/field_configs.tsx +5 -5
  129. package/src/core/index.tsx +2 -2
  130. package/src/form/PropertyFieldBinding.tsx +53 -19
  131. package/src/form/components/CustomIdField.tsx +4 -2
  132. package/src/form/components/FieldHelperText.tsx +4 -4
  133. package/src/form/components/FormikArrayContainer.tsx +4 -1
  134. package/src/form/components/LabelWithIcon.tsx +27 -19
  135. package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
  136. package/src/form/components/StorageItemPreview.tsx +20 -10
  137. package/src/form/components/StorageUploadProgress.tsx +0 -1
  138. package/src/form/components/index.tsx +1 -0
  139. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +26 -15
  140. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +28 -25
  141. package/src/form/field_bindings/BlockFieldBinding.tsx +13 -11
  142. package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -14
  143. package/src/form/field_bindings/KeyValueFieldBinding.tsx +48 -42
  144. package/src/form/field_bindings/MapFieldBinding.tsx +17 -17
  145. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +150 -0
  146. package/src/form/field_bindings/{MultiSelectBinding.tsx → MultiSelectFieldBinding.tsx} +25 -20
  147. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +9 -14
  148. package/src/form/field_bindings/ReferenceFieldBinding.tsx +27 -18
  149. package/src/form/field_bindings/RepeatFieldBinding.tsx +32 -19
  150. package/src/form/field_bindings/SelectFieldBinding.tsx +17 -10
  151. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +33 -43
  152. package/src/form/field_bindings/SwitchFieldBinding.tsx +9 -5
  153. package/src/form/field_bindings/TextFieldBinding.tsx +26 -23
  154. package/src/form/index.tsx +4 -9
  155. package/src/form/useClearRestoreValue.tsx +2 -2
  156. package/src/form/validation.ts +1 -17
  157. package/src/hooks/data/delete.ts +2 -1
  158. package/src/hooks/data/save.ts +5 -2
  159. package/src/hooks/data/useDataSource.tsx +11 -3
  160. package/src/hooks/useBuildNavigationController.tsx +10 -3
  161. package/src/hooks/useProjectLog.tsx +18 -7
  162. package/src/index.ts +1 -0
  163. package/src/internal/useBuildDataSource.ts +69 -74
  164. package/src/internal/useBuildSideDialogsController.tsx +1 -0
  165. package/src/internal/useBuildSideEntityController.tsx +17 -4
  166. package/src/internal/useUnsavedChangesDialog.tsx +3 -1
  167. package/src/preview/PropertyPreview.tsx +7 -4
  168. package/src/preview/PropertyPreviewProps.tsx +7 -1
  169. package/src/preview/components/BooleanPreview.tsx +1 -1
  170. package/src/preview/components/EnumValuesChip.tsx +1 -1
  171. package/src/preview/components/ImagePreview.tsx +24 -34
  172. package/src/preview/components/ReferencePreview.tsx +2 -12
  173. package/src/preview/components/StorageThumbnail.tsx +5 -1
  174. package/src/preview/components/UrlComponentPreview.tsx +44 -11
  175. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
  176. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +1 -1
  177. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +1 -1
  178. package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -2
  179. package/src/preview/property_previews/ArrayPropertyPreview.tsx +1 -1
  180. package/src/preview/property_previews/MapPropertyPreview.tsx +1 -1
  181. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +2 -2
  182. package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
  183. package/src/preview/util.ts +2 -2
  184. package/src/types/auth.tsx +2 -2
  185. package/src/types/collections.ts +29 -4
  186. package/src/types/customization_controller.tsx +0 -1
  187. package/src/types/datasource.ts +62 -43
  188. package/src/types/entities.ts +2 -0
  189. package/src/types/entity_overrides.tsx +2 -2
  190. package/src/types/fields.tsx +51 -45
  191. package/src/types/navigation.ts +1 -0
  192. package/src/types/plugins.tsx +12 -3
  193. package/src/types/properties.ts +25 -19
  194. package/src/types/side_dialogs_controller.tsx +13 -0
  195. package/src/types/storage.ts +82 -0
  196. package/src/util/entities.ts +5 -4
  197. package/src/util/icon_list.ts +14 -9
  198. package/src/util/icons.tsx +8 -2
  199. package/src/util/index.ts +1 -0
  200. package/src/util/objects.ts +17 -7
  201. package/src/util/permissions.ts +1 -0
  202. package/src/util/plurals.ts +0 -2
  203. package/src/util/property_utils.tsx +1 -1
  204. package/src/util/references.ts +3 -0
  205. package/src/util/resolutions.ts +43 -11
  206. package/src/util/storage.ts +79 -21
  207. package/src/util/useStorageUploadController.tsx +33 -7
  208. package/dist/components/PropertyIdCopyTooltipContent.d.ts +0 -3
  209. package/dist/core/Drawer.d.ts +0 -16
  210. package/dist/core/Scaffold.d.ts +0 -51
  211. package/dist/form/EntityForm.d.ts +0 -77
  212. package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
  213. package/src/components/PropertyIdCopyTooltipContent.tsx +0 -27
  214. package/src/core/Drawer.tsx +0 -139
  215. package/src/form/EntityForm.tsx +0 -736
  216. package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -695
@@ -79,7 +79,6 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
79
79
  <ErrorBoundary>
80
80
  <EntityEditView
81
81
  {...props}
82
- formWidth={props.width}
83
82
  collection={collection}
84
83
  parentCollectionIds={parentCollectionIds}
85
84
  onValuesAreModified={onValuesAreModified}
@@ -28,7 +28,7 @@ import { useProjectLog } from "../hooks/useProjectLog";
28
28
  *
29
29
  * You only need to use this component if you are building a custom app.
30
30
  *
31
- * @constructor
31
+
32
32
  * @group Core
33
33
  */
34
34
  export function FireCMS<UserType extends User, EC extends EntityCollection>(props: FireCMSProps<UserType, EC>) {
@@ -82,7 +82,7 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
82
82
  onAnalyticsEvent
83
83
  }), []);
84
84
 
85
- const accessResponse = useProjectLog(authController, plugins);
85
+ const accessResponse = useProjectLog(authController, dataSourceDelegate, plugins);
86
86
 
87
87
  if (navigationController.navigationLoadingError) {
88
88
  return (
@@ -15,7 +15,7 @@ export type NavigationRoutesProps = {
15
15
  */
16
16
  homePage?: React.ReactNode;
17
17
 
18
- customRoutes?: React.ReactNode[]
18
+ children?: React.ReactNode | React.ReactNode[]
19
19
 
20
20
  };
21
21
 
@@ -25,13 +25,13 @@ export type NavigationRoutesProps = {
25
25
  * or the home route) related to a {@link NavigationController}.
26
26
  * This component needs a parent {@link FireCMS}
27
27
  *
28
- * @constructor
28
+
29
29
  * @group Components
30
30
  */
31
31
  export const NavigationRoutes = React.memo<NavigationRoutesProps>(
32
32
  function NavigationRoutes({
33
33
  homePage = <DefaultHomePage/>,
34
- customRoutes
34
+ children
35
35
  }: NavigationRoutesProps) {
36
36
 
37
37
  const location = useLocation();
@@ -111,7 +111,7 @@ export const NavigationRoutes = React.memo<NavigationRoutesProps>(
111
111
 
112
112
  {notFoundRoute}
113
113
 
114
- {customRoutes}
114
+ {children}
115
115
 
116
116
  </Routes>
117
117
  );
@@ -126,6 +126,7 @@ function SideDialogView({
126
126
  <Sheet
127
127
  open={Boolean(panel)}
128
128
  onOpenChange={(open) => !open && onCloseRequest()}
129
+ title={"Side dialog " + panel?.key}
129
130
  >
130
131
  {panel &&
131
132
  <div
@@ -8,8 +8,8 @@ import {
8
8
  DateTimeFieldBinding,
9
9
  KeyValueFieldBinding,
10
10
  MapFieldBinding,
11
- MarkdownFieldBinding,
12
- MultiSelectBinding,
11
+ MarkdownEditorFieldBinding,
12
+ MultiSelectFieldBinding,
13
13
  ReferenceFieldBinding,
14
14
  RepeatFieldBinding,
15
15
  SelectFieldBinding,
@@ -77,7 +77,7 @@ export const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {
77
77
  property: {
78
78
  dataType: "string",
79
79
  markdown: true,
80
- Field: MarkdownFieldBinding
80
+ Field: MarkdownEditorFieldBinding
81
81
  }
82
82
  },
83
83
  url: {
@@ -139,7 +139,7 @@ export const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {
139
139
  dataType: "string",
140
140
  enumValues: [],
141
141
  },
142
- Field: MultiSelectBinding
142
+ Field: MultiSelectFieldBinding
143
143
  }
144
144
  },
145
145
  number_input: {
@@ -177,7 +177,7 @@ export const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {
177
177
  dataType: "number",
178
178
  enumValues: [],
179
179
  },
180
- Field: MultiSelectBinding
180
+ Field: MultiSelectFieldBinding
181
181
  }
182
182
  },
183
183
  file_upload: {
@@ -1,8 +1,8 @@
1
1
  export * from "./FireCMS";
2
2
 
3
- export * from "./Scaffold";
3
+ export * from "../app/Scaffold";
4
4
 
5
- export * from "./Drawer";
5
+ export * from "./DefaultDrawer";
6
6
  export * from "./DrawerNavigationItem";
7
7
 
8
8
  export * from "./field_configs";
@@ -51,6 +51,13 @@ export const PropertyFieldBinding = React.memo(PropertyFieldBindingInternal, (a:
51
51
  if (a.propertyKey !== b.propertyKey) {
52
52
  return false;
53
53
  }
54
+ if (a.index !== b.index) {
55
+ return false;
56
+ }
57
+
58
+ if (a.size !== b.size) {
59
+ return false;
60
+ }
54
61
  const aIsBuilder = isPropertyBuilder(a.property) || a.property.fromBuilder;
55
62
  const bIsBuilder = isPropertyBuilder(b.property) || b.property.fromBuilder;
56
63
 
@@ -75,16 +82,18 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
75
82
  includeDescription,
76
83
  underlyingValueHasChanged,
77
84
  disabled,
78
- tableMode,
79
85
  partOfArray,
80
- partOfBlock,
86
+ minimalistView,
81
87
  autoFocus,
88
+ index,
89
+ size
82
90
  }: PropertyFieldBindingProps<T, M>): ReactElement<PropertyFieldBindingProps<T, M>> {
83
91
 
84
92
  const customizationController = useCustomizationController();
85
93
 
86
94
  return (
87
95
  <Field
96
+ key={propertyKey}
88
97
  name={propertyKey}
89
98
  >
90
99
  {(fieldProps) => {
@@ -96,7 +105,8 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
96
105
  values: fieldProps.form.values,
97
106
  path: context.path,
98
107
  entityId: context.entityId,
99
- fields: customizationController.propertyConfigs
108
+ fields: customizationController.propertyConfigs,
109
+ index
100
110
  });
101
111
 
102
112
  if (resolvedProperty === null || isHidden(resolvedProperty)) {
@@ -110,15 +120,22 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
110
120
  } else {
111
121
  const propertyConfig = getFieldConfig(resolvedProperty, customizationController.propertyConfigs);
112
122
  if (!propertyConfig) {
113
- console.log("INTERNAL: Could not find field config for property", { propertyKey, resolvedProperty, fields: customizationController.propertyConfigs, propertyConfig });
123
+ console.log("INTERNAL: Could not find field config for property", {
124
+ propertyKey,
125
+ resolvedProperty,
126
+ fields: customizationController.propertyConfigs,
127
+ propertyConfig
128
+ });
114
129
  throw new Error(`INTERNAL: Could not find field config for property ${propertyKey}`);
115
130
  }
116
131
  const configProperty = resolveProperty({
132
+ propertyKey,
117
133
  propertyOrBuilder: propertyConfig.property,
118
134
  values: fieldProps.form.values,
119
135
  path: context.path,
120
136
  entityId: context.entityId,
121
- fields: customizationController.propertyConfigs
137
+ fields: customizationController.propertyConfigs,
138
+ index
122
139
  });
123
140
  Component = configProperty.Field as ComponentType<FieldProps<T>>;
124
141
  }
@@ -137,10 +154,10 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
137
154
  underlyingValueHasChanged,
138
155
  context,
139
156
  disabled,
140
- tableMode,
141
157
  partOfArray,
142
- partOfBlock,
143
- autoFocus
158
+ minimalistView,
159
+ autoFocus,
160
+ size
144
161
  };
145
162
 
146
163
  return <FieldInternal
@@ -167,12 +184,12 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
167
184
  property,
168
185
  includeDescription,
169
186
  underlyingValueHasChanged,
170
- tableMode,
171
187
  partOfArray,
172
- partOfBlock,
188
+ minimalistView,
173
189
  autoFocus,
174
190
  context,
175
- disabled
191
+ disabled,
192
+ size
176
193
  },
177
194
  fieldProps
178
195
  }:
@@ -194,7 +211,14 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
194
211
  (fieldProps.form.submitCount > 0 || property.validation?.unique) &&
195
212
  (!Array.isArray(error) || !!error.filter((e: any) => !!e).length);
196
213
 
197
- const WrappedComponent: ComponentType<FieldProps<T, any, M>> | null = useWrappedComponent(context.path, context.collection, propertyKey, property, Component, plugins);
214
+ const WrappedComponent: ComponentType<FieldProps<T, any, M>> | null = useWrappedComponent({
215
+ path: context.path,
216
+ collection: context.collection,
217
+ propertyKey: propertyKey,
218
+ property: property,
219
+ Component: Component,
220
+ plugins: plugins
221
+ });
198
222
  const UsedComponent: ComponentType<FieldProps<T>> = WrappedComponent ?? Component;
199
223
 
200
224
  const isSubmitting = fieldProps.form.isSubmitting;
@@ -212,7 +236,6 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
212
236
  const cmsFieldProps: FieldProps<T, CustomProps, M> = {
213
237
  propertyKey,
214
238
  value: value as T,
215
- // initialValue,
216
239
  setValue,
217
240
  setFieldValue,
218
241
  error,
@@ -223,12 +246,12 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
223
246
  property: property as ResolvedProperty<T>,
224
247
  disabled: disabled ?? false,
225
248
  underlyingValueHasChanged: underlyingValueHasChanged ?? false,
226
- tableMode: tableMode ?? false,
227
249
  partOfArray: partOfArray ?? false,
228
- partOfBlock: partOfBlock ?? false,
250
+ minimalistView: minimalistView ?? false,
229
251
  autoFocus: autoFocus ?? false,
230
252
  customProps: customFieldProps,
231
- context
253
+ context,
254
+ size
232
255
  };
233
256
 
234
257
  return (
@@ -264,13 +287,24 @@ const shouldPropertyReRender = (property: PropertyOrBuilder | ResolvedProperty,
264
287
  }
265
288
  }
266
289
 
267
- function useWrappedComponent<T extends CMSType = CMSType, M extends Record<string, any> = any>(
268
- path: string,
269
- collection: EntityCollection<M>,
290
+ interface UseWrappedComponentParams<T extends CMSType = CMSType, M extends Record<string, any> = any> {
291
+ path?: string,
292
+ collection?: EntityCollection<M>,
270
293
  propertyKey: string,
271
294
  property: ResolvedProperty<T>,
272
295
  Component: ComponentType<FieldProps<T, any, M>>,
273
296
  plugins?: FireCMSPlugin[]
297
+ }
298
+
299
+ function useWrappedComponent<T extends CMSType = CMSType, M extends Record<string, any> = any>(
300
+ {
301
+ path,
302
+ collection,
303
+ propertyKey,
304
+ property,
305
+ Component,
306
+ plugins
307
+ }: UseWrappedComponentParams<T, M>
274
308
  ): ComponentType<FieldProps<T, any, M>> | null {
275
309
 
276
310
  const wrapperRef = useRef<ComponentType<FieldProps<T, any, M>> | null>((() => {
@@ -68,7 +68,8 @@ export function CustomIdField<M extends Record<string, any>>({
68
68
  ? (
69
69
  <>
70
70
 
71
- <Tooltip title={"Copy"}>
71
+ <Tooltip title={"Copy"}
72
+ asChild={true}>
72
73
  <IconButton onClick={(e) => copy(entity.id)}
73
74
  aria-label="copy-id">
74
75
  <ContentCopyIcon size={"small"}/>
@@ -76,7 +77,8 @@ export function CustomIdField<M extends Record<string, any>>({
76
77
  </Tooltip>
77
78
 
78
79
  {customizationController?.entityLinkBuilder &&
79
- <Tooltip title={"Open in the console"}>
80
+ <Tooltip title={"Open in the console"}
81
+ asChild={true}>
80
82
  <IconButton component={"a"}
81
83
  href={customizationController.entityLinkBuilder({ entity })}
82
84
  rel="noopener noreferrer"
@@ -1,4 +1,4 @@
1
- import { ResolvedProperty } from "../../types";
1
+ import { Property, ResolvedProperty } from "../../types";
2
2
  import { IconButton, InfoIcon, Tooltip, Typography } from "@firecms/ui";
3
3
 
4
4
  /**
@@ -13,8 +13,8 @@ export function FieldHelperText({
13
13
  disabled
14
14
  }: {
15
15
  error?: string,
16
- showError: boolean,
17
- property: ResolvedProperty,
16
+ showError?: boolean,
17
+ property: ResolvedProperty | Property,
18
18
  includeDescription?: boolean,
19
19
  disabled?: boolean,
20
20
  }
@@ -44,7 +44,7 @@ export function FieldHelperText({
44
44
  {property.longDescription &&
45
45
  <Tooltip title={property.longDescription}
46
46
  side="bottom"
47
- >
47
+ asChild={true}>
48
48
  <IconButton
49
49
  size={"small"}
50
50
  className="self-start">
@@ -12,6 +12,7 @@ interface ArrayContainerProps<T> {
12
12
  includeAddButton?: boolean;
13
13
  newDefaultEntry?: T | null;
14
14
  setFieldValue: (field: string, value: any, shouldValidate?: boolean | undefined) => void;
15
+ className?: string;
15
16
  }
16
17
 
17
18
  /**
@@ -27,7 +28,8 @@ export function FormikArrayContainer<T>({
27
28
  onInternalIdAdded,
28
29
  includeAddButton,
29
30
  newDefaultEntry = null,
30
- setFieldValue
31
+ setFieldValue,
32
+ className
31
33
  }: ArrayContainerProps<T>) {
32
34
 
33
35
  return <ArrayContainer droppableId={name}
@@ -39,6 +41,7 @@ export function FormikArrayContainer<T>({
39
41
  onInternalIdAdded={onInternalIdAdded}
40
42
  includeAddButton={includeAddButton}
41
43
  newDefaultEntry={newDefaultEntry}
44
+ className={className}
42
45
  onValueChange={(value) => setFieldValue(name, value)}
43
46
  />;
44
47
  }
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, { forwardRef } from "react";
2
2
 
3
3
  interface LabelWithIconProps {
4
4
  icon: React.ReactNode;
@@ -12,22 +12,30 @@ interface LabelWithIconProps {
12
12
  * Render the label of with an icon and the title of a property
13
13
  * @group Form custom fields
14
14
  */
15
- export function LabelWithIcon({
16
- icon,
17
- title,
18
- small,
19
- className,
20
- required
21
- }: LabelWithIconProps) {
22
- return (
23
- <span
24
- className={`inline-flex items-center my-0.5 ${small ? "gap-1" : "gap-2"} ${className ?? ""}`}>
25
-
26
- {icon}
27
-
28
- <span
29
- className={`text-start font-medium text-${small ? "base" : "sm"} origin-top-left transform ${small ? "translate-x-2 scale-75" : ""}`}>{(title ?? "") + (required ? " *" : "")}</span>
30
-
15
+ export const LabelWithIcon = forwardRef<HTMLDivElement, LabelWithIconProps>(
16
+ ({
17
+ icon,
18
+ title,
19
+ small,
20
+ className,
21
+ required
22
+ }, ref) => {
23
+ return (
24
+ <div
25
+ ref={ref}
26
+ className={`inline-flex items-center my-0.5 ${small ? "gap-1" : "gap-2"} ${className ?? ""}`}
27
+ >
28
+ {icon}
29
+ <span
30
+ className={`text-start font-medium text-${small ? "base" : "sm"} origin-top-left transform ${
31
+ small ? "translate-x-2 scale-75" : ""
32
+ }`}
33
+ >
34
+ {(title ?? "") + (required ? " *" : "")}
31
35
  </span>
32
- );
33
- }
36
+ </div>
37
+ );
38
+ }
39
+ );
40
+
41
+ LabelWithIcon.displayName = "LabelWithIcon";
@@ -0,0 +1,28 @@
1
+ import React from "react";
2
+ import { LabelWithIcon } from "./LabelWithIcon";
3
+ import { PropertyIdCopyTooltip } from "../../components/PropertyIdCopyTooltip";
4
+
5
+ interface LabelWithIconAndTooltip {
6
+ icon: React.ReactNode;
7
+ title?: string;
8
+ small?: boolean;
9
+ className?: string;
10
+ required?: boolean;
11
+ propertyKey: string
12
+ }
13
+
14
+ /**
15
+ * Render the label of with an icon and the title of a property
16
+ * @group Form custom fields
17
+ */
18
+ export function LabelWithIconAndTooltip({
19
+ propertyKey,
20
+ className,
21
+ ...props
22
+ }: LabelWithIconAndTooltip) {
23
+ return (
24
+ <PropertyIdCopyTooltip propertyKey={propertyKey} className={className}>
25
+ <LabelWithIcon {...props}/>
26
+ </PropertyIdCopyTooltip>
27
+ );
28
+ }
@@ -1,43 +1,45 @@
1
1
  import React from "react";
2
2
 
3
- import { Entity, EntityCollection, ResolvedStringProperty } from "../../types";
3
+ import { ResolvedStringProperty } from "../../types";
4
4
  import { PreviewSize, PropertyPreview } from "../../preview";
5
5
 
6
- import { cls, IconButton, paperMixin, RemoveIcon, Tooltip } from "@firecms/ui";
6
+ import { cls, DescriptionIcon, IconButton, paperMixin, RemoveIcon, Tooltip } from "@firecms/ui";
7
7
  import { ErrorBoundary } from "../../components";
8
8
 
9
9
  interface StorageItemPreviewProps {
10
10
  name: string;
11
11
  property: ResolvedStringProperty;
12
12
  value: string,
13
- entity: Entity<any>,
14
13
  onRemove: (value: string) => void;
15
14
  size: PreviewSize;
16
15
  disabled: boolean;
17
- collection: EntityCollection;
16
+ placeholder?: boolean;
17
+ className?: string;
18
18
  }
19
19
 
20
20
  export function StorageItemPreview({
21
21
  name,
22
22
  property,
23
23
  value,
24
- entity,
25
24
  onRemove,
26
25
  disabled,
27
26
  size,
28
- collection
27
+ placeholder,
28
+ className
29
29
  }: StorageItemPreviewProps) {
30
30
 
31
31
  return (
32
32
  <div className={cls(paperMixin,
33
33
  "relative m-4 border-box flex items-center justify-center",
34
- size === "medium" ? "min-w-[220px] min-h-[220px] max-w-[220px]" : "min-w-[118px] min-h-[118px] max-w-[118px]")}>
34
+ size === "medium" ? "min-w-[220px] min-h-[220px] max-w-[220px]" : "min-w-[118px] min-h-[118px] max-w-[118px]",
35
+ className)}>
35
36
 
36
- {!disabled &&
37
+ {!placeholder && !disabled &&
37
38
  <div
38
39
  className="absolute rounded-full -top-2 -right-2 z-10 bg-white dark:bg-gray-900">
39
40
 
40
41
  <Tooltip
42
+ asChild={true}
41
43
  title="Remove">
42
44
  <IconButton
43
45
  size={"small"}
@@ -51,16 +53,24 @@ export function StorageItemPreview({
51
53
  </div>
52
54
  }
53
55
 
54
- {value &&
56
+ {!placeholder && value &&
55
57
  <ErrorBoundary>
56
58
  <PropertyPreview propertyKey={name}
57
59
  value={value}
58
60
  property={property}
59
- // entity={entity}
61
+ interactive={false}
60
62
  size={size}/>
61
63
  </ErrorBoundary>
62
64
  }
63
65
 
66
+ {placeholder &&
67
+ <div
68
+ onClick={(e) => e.stopPropagation()}
69
+ className="flex flex-col items-center justify-center w-full h-full">
70
+ <DescriptionIcon className="text-gray-700 dark:text-gray-300"/>
71
+ </div>
72
+ }
73
+
64
74
 
65
75
  </div>
66
76
  );
@@ -4,7 +4,6 @@ import { useSnackbarController, useStorageSource } from "../../hooks";
4
4
  import { StorageFieldItem } from "../../util/useStorageUploadController";
5
5
  import { ErrorView } from "../../components";
6
6
  import { cls, paperMixin, Skeleton } from "@firecms/ui";
7
- import { EntityCollection, StorageSource } from "../../types";
8
7
 
9
8
  export interface StorageUploadItemProps {
10
9
  storagePath: string;
@@ -1,3 +1,4 @@
1
1
  export * from "./FormikArrayContainer";
2
2
  export * from "./FieldHelperText";
3
3
  export * from "./LabelWithIcon";
4
+ export * from "./LabelWithIconAndTooltip";
@@ -1,9 +1,9 @@
1
1
  import React from "react";
2
2
  import { FieldProps } from "../../types";
3
- import { FieldHelperText, LabelWithIcon } from "../components";
3
+ import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
4
4
  import { PropertyFieldBinding } from "../PropertyFieldBinding";
5
- import { ExpandablePanel } from "@firecms/ui";
6
- import { getIconForProperty } from "../../util";
5
+ import { ExpandablePanel, Typography } from "@firecms/ui";
6
+ import { getArrayResolvedProperties, getIconForProperty } from "../../util";
7
7
  import { useClearRestoreValue } from "../useClearRestoreValue";
8
8
 
9
9
  /**
@@ -20,7 +20,7 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
20
20
  showError,
21
21
  isSubmitting,
22
22
  setValue,
23
- tableMode,
23
+ minimalistView,
24
24
  property,
25
25
  includeDescription,
26
26
  underlyingValueHasChanged,
@@ -28,8 +28,15 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
28
28
  disabled
29
29
  }: FieldProps<T, any, any>) {
30
30
 
31
- if (!Array.isArray(property.resolvedProperties))
32
- throw Error("ArrayCustomShapedFieldBinding misconfiguration. Property `of` not set");
31
+ let resolvedProperties = "resolvedProperties" in property ? property.resolvedProperties : undefined;
32
+ if (!resolvedProperties) {
33
+ resolvedProperties = getArrayResolvedProperties({
34
+ propertyValue: value,
35
+ propertyKey,
36
+ property,
37
+ ignoreMissingFields: false
38
+ })
39
+ }
33
40
 
34
41
  const expanded = property.expanded === undefined ? true : property.expanded;
35
42
 
@@ -39,12 +46,17 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
39
46
  setValue
40
47
  });
41
48
 
42
- const title = <LabelWithIcon icon={getIconForProperty(property, "small")}
43
- required={property.validation?.required}
44
- className={"text-text-secondary dark:text-text-secondary-dark"}
45
- title={property.name}/>;
49
+ const title = (<>
50
+ <LabelWithIconAndTooltip
51
+ propertyKey={propertyKey}
52
+ icon={getIconForProperty(property, "small")}
53
+ required={property.validation?.required}
54
+ title={property.name}
55
+ className={"flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
56
+ {Array.isArray(value) && <Typography variant={"caption"} className={"px-4"}>({value.length})</Typography>}
57
+ </>);
46
58
 
47
- const body = property.resolvedProperties.map((childProperty, index) => {
59
+ const body = resolvedProperties.map((childProperty, index) => {
48
60
  const fieldProps = {
49
61
  propertyKey: `${propertyKey}[${index}]`,
50
62
  disabled,
@@ -52,9 +64,8 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
52
64
  includeDescription,
53
65
  underlyingValueHasChanged,
54
66
  context,
55
- tableMode: false,
56
67
  partOfArray: true,
57
- partOfBlock: false,
68
+ minimalistView: false,
58
69
  autoFocus: false
59
70
  };
60
71
  return <div key={`custom_shaped_array_${index}`} className="pb-4">
@@ -66,14 +77,14 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
66
77
 
67
78
  <>
68
79
 
69
- {!tableMode &&
80
+ {!minimalistView &&
70
81
  <ExpandablePanel initiallyExpanded={expanded}
71
82
  title={title}
72
83
  className={"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2"}>
73
84
  {body}
74
85
  </ExpandablePanel>}
75
86
 
76
- {tableMode && body}
87
+ {minimalistView && body}
77
88
 
78
89
  <FieldHelperText includeDescription={includeDescription}
79
90
  showError={showError}