@firecms/core 3.0.0-beta.14 → 3.0.0-beta.15

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 (85) hide show
  1. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +2 -1
  2. package/dist/components/HomePage/DefaultHomePage.d.ts +2 -15
  3. package/dist/components/HomePage/HomePageDnD.d.ts +76 -0
  4. package/dist/components/HomePage/NavigationCard.d.ts +3 -1
  5. package/dist/components/HomePage/NavigationCardBinding.d.ts +3 -2
  6. package/dist/components/HomePage/NavigationGroup.d.ts +7 -1
  7. package/dist/components/HomePage/RenameGroupDialog.d.ts +9 -0
  8. package/dist/core/EntityEditView.d.ts +3 -0
  9. package/dist/core/EntityEditViewFormActions.d.ts +1 -1
  10. package/dist/core/field_configs.d.ts +1 -1
  11. package/dist/form/EntityForm.d.ts +2 -1
  12. package/dist/form/EntityFormActions.d.ts +6 -2
  13. package/dist/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +9 -0
  14. package/dist/form/index.d.ts +1 -0
  15. package/dist/hooks/useBuildNavigationController.d.ts +51 -2
  16. package/dist/index.es.js +2184 -1052
  17. package/dist/index.es.js.map +1 -1
  18. package/dist/index.umd.js +2181 -1049
  19. package/dist/index.umd.js.map +1 -1
  20. package/dist/types/analytics.d.ts +1 -1
  21. package/dist/types/collections.d.ts +8 -2
  22. package/dist/types/customization_controller.d.ts +8 -0
  23. package/dist/types/entity_actions.d.ts +46 -6
  24. package/dist/types/firecms.d.ts +8 -0
  25. package/dist/types/navigation.d.ts +21 -5
  26. package/dist/types/plugins.d.ts +20 -1
  27. package/dist/types/properties.d.ts +7 -0
  28. package/dist/types/property_config.d.ts +1 -1
  29. package/dist/types/side_entity_controller.d.ts +4 -0
  30. package/dist/util/icons.d.ts +2 -2
  31. package/dist/util/navigation_from_path.d.ts +4 -0
  32. package/dist/util/resolutions.d.ts +2 -1
  33. package/package.json +5 -5
  34. package/src/components/ConfirmationDialog.tsx +1 -0
  35. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +6 -0
  36. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +25 -3
  37. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +2 -2
  38. package/src/components/EntityCollectionView/EntityCollectionView.tsx +7 -4
  39. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +3 -2
  40. package/src/components/FireCMSLogo.tsx +7 -51
  41. package/src/components/HomePage/DefaultHomePage.tsx +491 -157
  42. package/src/components/HomePage/FavouritesView.tsx +3 -3
  43. package/src/components/HomePage/HomePageDnD.tsx +599 -0
  44. package/src/components/HomePage/NavigationCard.tsx +47 -38
  45. package/src/components/HomePage/NavigationCardBinding.tsx +10 -6
  46. package/src/components/HomePage/NavigationGroup.tsx +63 -29
  47. package/src/components/HomePage/RenameGroupDialog.tsx +117 -0
  48. package/src/components/UnsavedChangesDialog.tsx +6 -2
  49. package/src/components/common/default_entity_actions.tsx +25 -9
  50. package/src/components/common/useDataSourceTableController.tsx +2 -2
  51. package/src/core/DefaultDrawer.tsx +8 -8
  52. package/src/core/DrawerNavigationItem.tsx +1 -1
  53. package/src/core/EntityEditView.tsx +41 -6
  54. package/src/core/EntityEditViewFormActions.tsx +154 -29
  55. package/src/core/EntitySidePanel.tsx +5 -2
  56. package/src/core/FireCMS.tsx +2 -0
  57. package/src/core/field_configs.tsx +15 -1
  58. package/src/form/EntityForm.tsx +36 -4
  59. package/src/form/EntityFormActions.tsx +51 -9
  60. package/src/form/components/StorageItemPreview.tsx +1 -1
  61. package/src/form/components/StorageUploadProgress.tsx +3 -3
  62. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +4 -2
  63. package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +135 -0
  64. package/src/form/field_bindings/RepeatFieldBinding.tsx +0 -1
  65. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +12 -17
  66. package/src/form/index.tsx +1 -0
  67. package/src/hooks/useBuildNavigationController.tsx +273 -84
  68. package/src/internal/useBuildSideEntityController.tsx +7 -4
  69. package/src/preview/PropertyPreview.tsx +14 -0
  70. package/src/routes/FireCMSRoute.tsx +3 -3
  71. package/src/types/analytics.ts +3 -0
  72. package/src/types/collections.ts +8 -2
  73. package/src/types/customization_controller.tsx +9 -0
  74. package/src/types/entity_actions.tsx +57 -6
  75. package/src/types/firecms.tsx +9 -0
  76. package/src/types/navigation.ts +28 -6
  77. package/src/types/plugins.tsx +24 -1
  78. package/src/types/properties.ts +8 -0
  79. package/src/types/property_config.tsx +1 -0
  80. package/src/types/side_entity_controller.tsx +5 -0
  81. package/src/util/icons.tsx +22 -7
  82. package/src/util/join_collections.ts +3 -1
  83. package/src/util/navigation_from_path.ts +15 -5
  84. package/src/util/navigation_utils.ts +2 -2
  85. package/src/util/resolutions.ts +13 -1
@@ -1,10 +1,19 @@
1
1
  import React from "react";
2
- import { Entity, EntityAction, FireCMSContext, ResolvedEntityCollection, SideEntityController } from "../types";
2
+ import {
3
+ Entity,
4
+ EntityAction,
5
+ FireCMSContext,
6
+ FormContext,
7
+ ResolvedEntityCollection,
8
+ SideEntityController
9
+ } from "../types";
3
10
  import { Button, cls, defaultBorderMixin, DialogActions, IconButton, LoadingButton, Typography } from "@firecms/ui";
4
11
  import { FormexController } from "@firecms/formex";
5
12
  import { useFireCMSContext, useSideEntityController } from "../hooks";
6
13
 
7
14
  export interface EntityFormActionsProps {
15
+ fullPath: string;
16
+ fullIdPath?: string;
8
17
  collection: ResolvedEntityCollection;
9
18
  path: string;
10
19
  entity?: Entity;
@@ -16,9 +25,13 @@ export interface EntityFormActionsProps {
16
25
  pluginActions: React.ReactNode[];
17
26
  openEntityMode: "side_panel" | "full_screen";
18
27
  showDefaultActions?: boolean;
28
+ navigateBack: () => void;
29
+ formContext: FormContext
19
30
  }
20
31
 
21
32
  export function EntityFormActions({
33
+ fullPath,
34
+ fullIdPath,
22
35
  collection,
23
36
  entity,
24
37
  layout,
@@ -27,7 +40,9 @@ export function EntityFormActions({
27
40
  disabled,
28
41
  status,
29
42
  pluginActions,
30
- openEntityMode
43
+ openEntityMode,
44
+ navigateBack,
45
+ formContext
31
46
  }: EntityFormActionsProps) {
32
47
 
33
48
  const context = useFireCMSContext();
@@ -35,6 +50,8 @@ export function EntityFormActions({
35
50
 
36
51
  return layout === "bottom"
37
52
  ? buildBottomActions({
53
+ fullPath,
54
+ fullIdPath,
38
55
  savingError,
39
56
  entity,
40
57
  collection,
@@ -44,9 +61,13 @@ export function EntityFormActions({
44
61
  disabled,
45
62
  status,
46
63
  pluginActions,
47
- openEntityMode
64
+ openEntityMode,
65
+ navigateBack,
66
+ formContext
48
67
  })
49
68
  : buildSideActions({
69
+ fullPath,
70
+ fullIdPath,
50
71
  savingError,
51
72
  entity,
52
73
  collection,
@@ -56,11 +77,15 @@ export function EntityFormActions({
56
77
  disabled,
57
78
  status,
58
79
  pluginActions,
59
- openEntityMode
80
+ openEntityMode,
81
+ navigateBack,
82
+ formContext
60
83
  });
61
84
  }
62
85
 
63
86
  type ActionsViewProps<M extends object> = {
87
+ fullPath: string,
88
+ fullIdPath?: string,
64
89
  savingError: Error | undefined,
65
90
  entity: Entity<M> | undefined,
66
91
  formActions?: EntityAction[],
@@ -72,11 +97,15 @@ type ActionsViewProps<M extends object> = {
72
97
  status: "new" | "existing" | "copy",
73
98
  pluginActions?: React.ReactNode[],
74
99
  openEntityMode: "side_panel" | "full_screen";
100
+ navigateBack: () => void;
101
+ formContext: FormContext
75
102
  };
76
103
 
77
104
  function buildBottomActions<M extends object>({
78
105
  savingError,
79
106
  entity,
107
+ fullPath,
108
+ fullIdPath,
80
109
  formActions,
81
110
  collection,
82
111
  context,
@@ -85,7 +114,9 @@ function buildBottomActions<M extends object>({
85
114
  disabled,
86
115
  status,
87
116
  pluginActions,
88
- openEntityMode
117
+ openEntityMode,
118
+ navigateBack,
119
+ formContext
89
120
  }: ActionsViewProps<M>) {
90
121
 
91
122
  return <DialogActions position={"absolute"}>
@@ -103,12 +134,16 @@ function buildBottomActions<M extends object>({
103
134
  event.stopPropagation();
104
135
  if (entity)
105
136
  action.onClick({
137
+ view: "form",
106
138
  entity,
107
- fullPath: collection.path,
139
+ fullPath: fullPath ?? collection.path,
140
+ fullIdPath: fullIdPath ?? collection.id,
108
141
  collection: collection,
109
142
  context,
110
143
  sideEntityController,
111
- openEntityMode: openEntityMode
144
+ openEntityMode: openEntityMode,
145
+ navigateBack,
146
+ formContext
112
147
  });
113
148
  }}>
114
149
  {action.icon}
@@ -116,10 +151,14 @@ function buildBottomActions<M extends object>({
116
151
  ))}
117
152
  </div>}
118
153
  {pluginActions}
119
- <Button variant="text" disabled={disabled || isSubmitting} type="reset">
154
+ <Button variant="text" disabled={disabled || isSubmitting}
155
+ color={"primary"}
156
+ type="reset">
120
157
  {status === "existing" ? "Discard" : "Clear"}
121
158
  </Button>
122
- <Button variant={"filled"} color="primary" type="submit"
159
+ <Button variant={"filled"}
160
+ color="primary"
161
+ type="submit"
123
162
  disabled={disabled || isSubmitting}>
124
163
  {status === "existing" && "Save"}
125
164
  {status === "copy" && "Create copy"}
@@ -133,6 +172,9 @@ function buildSideActions<M extends object>({
133
172
  savingError,
134
173
  entity,
135
174
  formActions,
175
+ fullPath,
176
+ fullIdPath,
177
+ openEntityMode,
136
178
  collection,
137
179
  context,
138
180
  sideEntityController,
@@ -30,7 +30,7 @@ export function StorageItemPreview({
30
30
 
31
31
  return (
32
32
  <div className={cls(paperMixin,
33
- "relative m-4 border-box flex items-center justify-center",
33
+ "relative border-box flex items-center justify-center",
34
34
  size === "large" ? "min-w-[220px] min-h-[220px] max-w-[220px]" : "min-w-[118px] min-h-[118px] max-w-[118px]",
35
35
  className)}>
36
36
 
@@ -79,7 +79,7 @@ export function StorageUploadProgress({
79
79
  }, [entry.file, entry.fileName, upload]);
80
80
 
81
81
  if (simple) {
82
- return <div className={`m-4 w-${imageSize} h-${imageSize}`}>
82
+ return <div className={`w-${imageSize} h-${imageSize}`}>
83
83
 
84
84
  {loading && <Skeleton className={`w-${imageSize} h-${imageSize}`}/>}
85
85
 
@@ -88,11 +88,11 @@ export function StorageUploadProgress({
88
88
  return (
89
89
 
90
90
  <div className={cls(paperMixin,
91
- "relative m-4 border-box flex items-center justify-center",
91
+ "p-4 relative border-box flex items-center justify-center",
92
92
  `min-w-[${imageSize}px] min-h-[${imageSize}px]`)}>
93
93
 
94
94
  {loading &&
95
- <Skeleton className="m-4 w-full h-full"/>}
95
+ <Skeleton className="w-full h-full"/>}
96
96
 
97
97
  {error && <ErrorView title={"Error uploading file"}
98
98
  error={error}/>}
@@ -46,11 +46,13 @@ export function MarkdownEditorFieldBinding({
46
46
  const entityId = context.entityId;
47
47
  const path = context.path;
48
48
 
49
- // const fieldVersion = useRef(0);
50
49
  const [fieldVersion, setFieldVersion] = useState(0);
51
- const internalValue = useRef(value);
50
+ const internalValue = useRef<string | null>(value);
52
51
 
53
52
  const onContentChange = useCallback((content: string) => {
53
+ if (content === value || (value === null && content === "")) {
54
+ return;
55
+ }
54
56
  internalValue.current = content;
55
57
  setValue(content);
56
58
  }, [setValue]);
@@ -0,0 +1,135 @@
1
+ import React, { useCallback, useMemo } from "react";
2
+ import { Entity, EntityCollection, EntityReference, FieldProps } from "../../types";
3
+ import { useNavigationController, useReferenceDialog } from "../../hooks";
4
+ import { ReadOnlyFieldBinding } from "./ReadOnlyFieldBinding";
5
+ import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
6
+ import { ErrorView } from "../../components";
7
+ import { ReferencePreview } from "../../preview";
8
+ import { getIconForProperty, IconForView } from "../../util";
9
+ import { useClearRestoreValue } from "../useClearRestoreValue";
10
+ import { EntityPreviewContainer } from "../../components/EntityPreview";
11
+ import { cls } from "@firecms/ui";
12
+
13
+ /**
14
+ * Field that opens a reference selection dialog and stores the entity ID as a string.
15
+ *
16
+ * This is one of the internal components that get mapped natively inside forms
17
+ * and tables to the specified properties.
18
+ * @group Form fields
19
+ */
20
+ export function ReferenceAsStringFieldBinding(props: FieldProps<string>) {
21
+ if (typeof props.property.reference?.path !== "string") {
22
+ return <ReadOnlyFieldBinding {...props}/>;
23
+ }
24
+
25
+ return <ReferenceAsStringFieldBindingInternal {...props}/>;
26
+ }
27
+
28
+ function ReferenceAsStringFieldBindingInternal({
29
+ propertyKey,
30
+ value,
31
+ setValue,
32
+ error,
33
+ showError,
34
+ isSubmitting,
35
+ disabled,
36
+ minimalistView,
37
+ property,
38
+ includeDescription,
39
+ size = "medium"
40
+ }: FieldProps<string>) {
41
+ if (!property.reference?.path) {
42
+ throw new Error("Property path is required for ReferenceAsStringFieldBinding");
43
+ }
44
+
45
+ useClearRestoreValue({
46
+ property,
47
+ value,
48
+ setValue
49
+ });
50
+
51
+ const navigationController = useNavigationController();
52
+ const path = property.reference.path;
53
+ const collection: EntityCollection | undefined = useMemo(() => {
54
+ return path ? navigationController.getCollection(path) : undefined;
55
+ }, [path]);
56
+
57
+ const referenceValue: EntityReference | undefined = useMemo(() => {
58
+ if (value && path) {
59
+ return new EntityReference(value, path);
60
+ }
61
+ return undefined;
62
+ }, [value, path]);
63
+
64
+ if (!collection) {
65
+ throw Error(`Couldn't find the corresponding collection for the path: ${path}`);
66
+ }
67
+
68
+ const onSingleEntitySelected = useCallback((e: Entity<any> | null) => {
69
+ setValue(e ? e.id : null);
70
+ }, [setValue]);
71
+
72
+ const referenceDialogController = useReferenceDialog({
73
+ multiselect: false,
74
+ path: path,
75
+ collection,
76
+ onSingleEntitySelected,
77
+ selectedEntityIds: value ? [value] : undefined,
78
+ forceFilter: property.reference.forceFilter
79
+ }
80
+ );
81
+
82
+ const onEntryClick = (e: React.SyntheticEvent) => {
83
+ e.preventDefault();
84
+ referenceDialogController.open();
85
+ };
86
+
87
+ return (
88
+ <>
89
+ {!minimalistView && <LabelWithIconAndTooltip
90
+ propertyKey={propertyKey}
91
+ icon={getIconForProperty(property, "small")}
92
+ required={property.validation?.required}
93
+ title={property.name}
94
+ className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
95
+
96
+ {!collection && <ErrorView
97
+ error={"The specified collection does not exist. Check console"}/>}
98
+
99
+ {collection && <>
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
+ />}
111
+
112
+ {!value && <div className="justify-center text-left">
113
+ <EntityPreviewContainer
114
+ className={cls("px-6 h-16 text-sm font-medium flex items-center gap-6",
115
+ disabled || isSubmitting
116
+ ? "text-surface-accent-500"
117
+ : "cursor-pointer text-surface-accent-700 dark:text-surface-accent-300 hover:bg-surface-accent-50 dark:hover:bg-surface-800 group-hover:bg-surface-accent-50 dark:group-hover:bg-surface-800")}
118
+ onClick={onEntryClick}
119
+ size={"medium"}>
120
+ <IconForView collectionOrView={collection}
121
+ className={"text-surface-300 dark:text-surface-600"}/>
122
+ {`Edit ${property.name}`.toUpperCase()}
123
+ </EntityPreviewContainer>
124
+ </div>}
125
+ </>}
126
+
127
+ <FieldHelperText includeDescription={includeDescription}
128
+ showError={showError}
129
+ error={error}
130
+ disabled={disabled}
131
+ property={property}/>
132
+
133
+ </>
134
+ );
135
+ }
@@ -79,7 +79,6 @@ export function RepeatFieldBinding<T extends Array<any>>({
79
79
  minimalistView: false,
80
80
  autoFocus: internalId === lastAddedId,
81
81
  };
82
- console.debug("Building entry for", index, fieldProps);
83
82
  return <ErrorBoundary>
84
83
  <PropertyFieldBinding {...fieldProps} index={index}/>
85
84
  </ErrorBoundary>;
@@ -114,7 +114,7 @@ export function StorageUploadFieldBinding({
114
114
  icon={getIconForProperty(property, "small")}
115
115
  required={property.validation?.required}
116
116
  title={property.name}
117
- className={"h-8text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
117
+ className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
118
118
 
119
119
  <StorageUpload
120
120
  value={internalValue}
@@ -157,13 +157,11 @@ function SortableStorageItem({
157
157
  id,
158
158
  entry,
159
159
  property,
160
- name,
161
160
  metadata,
162
161
  storagePathBuilder,
163
162
  onFileUploadComplete,
164
163
  onClear,
165
164
  disabled,
166
- isSortable // This prop might be redundant if SortableContext is always used for multiple items
167
165
  }: SortableStorageItemProps) {
168
166
 
169
167
  const {
@@ -178,8 +176,7 @@ function SortableStorageItem({
178
176
  const style: React.CSSProperties = {
179
177
  transform: CSS.Transform.toString(transform),
180
178
  transition,
181
- zIndex: isDragging ? 100 : undefined, // Higher z-index when dragging
182
- opacity: isDragging ? 0.8 : 1 // Slight opacity for dragged item
179
+ zIndex: isDragging ? 100 : undefined
183
180
  };
184
181
 
185
182
  const getImageSizeNumber = (previewSize: PreviewSize): number => {
@@ -187,9 +184,9 @@ function SortableStorageItem({
187
184
  case "small":
188
185
  return 40;
189
186
  case "medium":
190
- return 118; // As per original logic for multiple items
187
+ return 118;
191
188
  case "large":
192
- return 220; // As per original logic for single item
189
+ return 220;
193
190
  default:
194
191
  return 118;
195
192
  }
@@ -225,7 +222,7 @@ function SortableStorageItem({
225
222
  style={style}
226
223
  {...attributes}
227
224
  {...listeners}
228
- className={cls("rounded-md m-1")} // Added margin for spacing between items
225
+ className={cls("rounded-md m-1")}
229
226
  tabIndex={-1}
230
227
  >
231
228
  {child}
@@ -247,11 +244,11 @@ function FileDropComponent({
247
244
  onFileUploadComplete,
248
245
  name,
249
246
  helpText,
250
- isDndItemDragging // New prop to disable dropzone when internal D&D is active
247
+ isDndItemDragging
251
248
  }: {
252
249
  storage: StorageConfig,
253
250
  disabled: boolean,
254
- onFilesAdded: (acceptedFiles: File[]) => Promise<void>, // useStorageUploadController returns Promise<void>
251
+ onFilesAdded: (acceptedFiles: File[]) => Promise<void>,
255
252
  multipleFilesSupported: boolean,
256
253
  autoFocus: boolean,
257
254
  internalValue: StorageFieldItem[],
@@ -278,7 +275,7 @@ function FileDropComponent({
278
275
  ...acc,
279
276
  [ext]: []
280
277
  }), {}) : undefined,
281
- disabled: disabled || isDndItemDragging, // Disable if form field is disabled OR an internal item is being dragged
278
+ disabled: disabled || isDndItemDragging,
282
279
  noDragEventsBubbling: true,
283
280
  maxSize: storage.maxSize,
284
281
  onDrop: onFilesAdded,
@@ -311,7 +308,7 @@ function FileDropComponent({
311
308
  disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,
312
309
  disabled ? "text-surface-accent-600 dark:text-surface-accent-500" : "",
313
310
  dropZoneClasses,
314
- multipleFilesSupported && internalValue.length === 0 && "flex", // Keep flex for empty state centering
311
+ multipleFilesSupported && internalValue.length ? "" : "flex",
315
312
  {
316
313
  [nonActiveDropClasses]: !isDragActive,
317
314
  [activeDropClasses]: isDragActive, // OS file drag active
@@ -321,11 +318,9 @@ function FileDropComponent({
321
318
  })}
322
319
  >
323
320
  <div
324
- className={cls("flex items-center p-1 no-scrollbar",
325
- multipleFilesSupported && internalValue.length ? "flex-row overflow-x-auto" : "flex-col", // flex-col for single or empty
326
- internalValue.length === 0 && "min-h-[250px] justify-center", // Centering for empty dropzone
327
- multipleFilesSupported && internalValue.length > 0 && "min-h-[180px]", // Min height for multiple items
328
- !multipleFilesSupported && internalValue.length > 0 && "min-h-[250px]" // Min height for single item
321
+ className={cls("flex items-center p-1 px-4 no-scrollbar",
322
+ multipleFilesSupported && internalValue.length ? "overflow-auto" : "",
323
+ multipleFilesSupported && internalValue.length ? "min-h-[180px]" : "min-h-[250px]"
329
324
  )}
330
325
  >
331
326
  <input
@@ -8,6 +8,7 @@ export { TextFieldBinding } from "./field_bindings/TextFieldBinding";
8
8
  export { SwitchFieldBinding } from "./field_bindings/SwitchFieldBinding";
9
9
  export { DateTimeFieldBinding } from "./field_bindings/DateTimeFieldBinding";
10
10
  export { ReferenceFieldBinding } from "./field_bindings/ReferenceFieldBinding";
11
+ export { ReferenceAsStringFieldBinding } from "./field_bindings/ReferenceAsStringFieldBinding";
11
12
  export { MapFieldBinding } from "./field_bindings/MapFieldBinding";
12
13
  export { KeyValueFieldBinding } from "./field_bindings/KeyValueFieldBinding";
13
14
  export { RepeatFieldBinding } from "./field_bindings/RepeatFieldBinding";