@firecms/core 3.0.0-beta.10 → 3.0.0-beta.12

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 (267) hide show
  1. package/dist/components/ArrayContainer.d.ts +22 -6
  2. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +2 -1
  3. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  4. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +17 -3
  5. package/dist/components/EntityCollectionTable/index.d.ts +1 -1
  6. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +6 -3
  7. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +4 -0
  8. package/dist/components/PropertyIdCopyTooltip.d.ts +1 -1
  9. package/dist/components/SelectableTable/SelectableTable.d.ts +12 -2
  10. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +1 -1
  11. package/dist/components/UnsavedChangesDialog.d.ts +8 -0
  12. package/dist/components/VirtualTable/VirtualTableProps.d.ts +13 -0
  13. package/dist/components/common/default_entity_actions.d.ts +0 -2
  14. package/dist/components/common/index.d.ts +1 -1
  15. package/dist/components/common/useColumnsIds.d.ts +1 -0
  16. package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +10 -2
  17. package/dist/components/common/useDebouncedCallback.d.ts +1 -0
  18. package/dist/components/common/useScrollRestoration.d.ts +14 -0
  19. package/dist/contexts/BreacrumbsContext.d.ts +8 -0
  20. package/dist/core/EntityEditView.d.ts +30 -22
  21. package/dist/core/EntityEditViewFormActions.d.ts +2 -0
  22. package/dist/core/FireCMS.d.ts +1 -1
  23. package/dist/core/FireCMSRouter.d.ts +4 -0
  24. package/dist/core/NavigationRoutes.d.ts +0 -1
  25. package/dist/core/SideDialogs.d.ts +4 -2
  26. package/dist/core/index.d.ts +2 -1
  27. package/dist/form/EntityForm.d.ts +45 -0
  28. package/dist/form/EntityFormActions.d.ts +17 -0
  29. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  30. package/dist/form/components/FormEntry.d.ts +6 -0
  31. package/dist/form/components/FormLayout.d.ts +5 -0
  32. package/dist/form/components/index.d.ts +2 -1
  33. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  34. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  35. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  36. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  37. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
  38. package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +2 -2
  39. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  40. package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -2
  41. package/dist/form/index.d.ts +16 -16
  42. package/dist/hooks/data/delete.d.ts +4 -4
  43. package/dist/hooks/data/save.d.ts +3 -3
  44. package/dist/hooks/data/useCollectionFetch.d.ts +1 -1
  45. package/dist/hooks/data/useEntityFetch.d.ts +4 -3
  46. package/dist/hooks/useAuthController.d.ts +1 -1
  47. package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
  48. package/dist/hooks/useBuildNavigationController.d.ts +7 -4
  49. package/dist/hooks/useFireCMSContext.d.ts +1 -1
  50. package/dist/hooks/useModeController.d.ts +1 -2
  51. package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
  52. package/dist/hooks/useValidateAuthenticator.d.ts +3 -3
  53. package/dist/index.es.js +17032 -12909
  54. package/dist/index.es.js.map +1 -1
  55. package/dist/index.umd.js +17019 -12898
  56. package/dist/index.umd.js.map +1 -1
  57. package/dist/internal/useBuildSideEntityController.d.ts +2 -2
  58. package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
  59. package/dist/preview/PropertyPreviewProps.d.ts +1 -1
  60. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  61. package/dist/preview/util.d.ts +3 -3
  62. package/dist/routes/CustomCMSRoute.d.ts +4 -0
  63. package/dist/routes/FireCMSRoute.d.ts +1 -0
  64. package/dist/routes/HomePageRoute.d.ts +3 -0
  65. package/dist/types/auth.d.ts +7 -9
  66. package/dist/types/collections.d.ts +44 -23
  67. package/dist/types/datasource.d.ts +2 -6
  68. package/dist/types/dialogs_controller.d.ts +7 -3
  69. package/dist/types/entities.d.ts +1 -1
  70. package/dist/types/entity_actions.d.ts +14 -4
  71. package/dist/types/entity_callbacks.d.ts +16 -16
  72. package/dist/types/export_import.d.ts +4 -4
  73. package/dist/types/fields.d.ts +27 -4
  74. package/dist/types/firecms.d.ts +2 -2
  75. package/dist/types/firecms_context.d.ts +1 -1
  76. package/dist/types/navigation.d.ts +29 -12
  77. package/dist/types/permissions.d.ts +4 -4
  78. package/dist/types/plugins.d.ts +9 -8
  79. package/dist/types/properties.d.ts +18 -3
  80. package/dist/types/property_config.d.ts +0 -2
  81. package/dist/types/side_entity_controller.d.ts +6 -1
  82. package/dist/types/user.d.ts +1 -0
  83. package/dist/util/builders.d.ts +3 -3
  84. package/dist/util/entities.d.ts +1 -1
  85. package/dist/util/entity_actions.d.ts +2 -0
  86. package/dist/util/entity_cache.d.ts +23 -0
  87. package/dist/util/icon_synonyms.d.ts +0 -1
  88. package/dist/util/icons.d.ts +3 -1
  89. package/dist/util/index.d.ts +1 -0
  90. package/dist/util/navigation_from_path.d.ts +6 -1
  91. package/dist/util/navigation_utils.d.ts +12 -1
  92. package/dist/util/objects.d.ts +1 -0
  93. package/dist/util/permissions.d.ts +4 -4
  94. package/dist/util/property_utils.d.ts +2 -2
  95. package/dist/util/resolutions.d.ts +12 -7
  96. package/package.json +129 -125
  97. package/src/app/Scaffold.tsx +4 -4
  98. package/src/components/ArrayContainer.tsx +115 -34
  99. package/src/components/CircularProgressCenter.tsx +1 -1
  100. package/src/components/ConfirmationDialog.tsx +2 -2
  101. package/src/components/DeleteEntityDialog.tsx +10 -19
  102. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +44 -20
  103. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +23 -17
  104. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +20 -3
  105. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +6 -4
  106. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +8 -9
  107. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +5 -11
  108. package/src/components/EntityCollectionTable/index.tsx +1 -1
  109. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -3
  110. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +5 -5
  111. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +2 -2
  112. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +77 -73
  113. package/src/components/EntityCollectionView/EntityCollectionView.tsx +90 -49
  114. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -2
  115. package/src/components/EntityCollectionView/useSelectionController.tsx +5 -4
  116. package/src/components/EntityPreview.tsx +39 -30
  117. package/src/components/EntityView.tsx +5 -5
  118. package/src/components/ErrorView.tsx +3 -3
  119. package/src/components/HomePage/DefaultHomePage.tsx +1 -0
  120. package/src/components/HomePage/FavouritesView.tsx +6 -11
  121. package/src/components/HomePage/NavigationCard.tsx +1 -1
  122. package/src/components/HomePage/NavigationCardBinding.tsx +4 -9
  123. package/src/components/HomePage/NavigationGroup.tsx +1 -1
  124. package/src/components/NotFoundPage.tsx +2 -2
  125. package/src/components/PropertyConfigBadge.tsx +1 -1
  126. package/src/components/PropertyIdCopyTooltip.tsx +3 -4
  127. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +13 -8
  128. package/src/components/SelectableTable/SelectableTable.tsx +20 -5
  129. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +4 -2
  130. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +10 -8
  131. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +7 -5
  132. package/src/components/UnsavedChangesDialog.tsx +42 -0
  133. package/src/components/VirtualTable/VirtualTable.tsx +19 -2
  134. package/src/components/VirtualTable/VirtualTableHeader.tsx +8 -8
  135. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
  136. package/src/components/VirtualTable/VirtualTableProps.tsx +15 -0
  137. package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
  138. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
  139. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +1 -1
  140. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +2 -0
  141. package/src/components/common/default_entity_actions.tsx +26 -37
  142. package/src/components/common/index.ts +1 -1
  143. package/src/components/common/useColumnsIds.tsx +1 -1
  144. package/src/components/common/useDataSourceTableController.tsx +420 -0
  145. package/src/components/common/useDebouncedCallback.tsx +20 -0
  146. package/src/components/common/useScrollRestoration.tsx +68 -0
  147. package/src/contexts/BreacrumbsContext.tsx +38 -0
  148. package/src/contexts/DialogsProvider.tsx +3 -2
  149. package/src/contexts/ModeController.tsx +1 -3
  150. package/src/contexts/SnackbarProvider.tsx +2 -0
  151. package/src/core/DefaultAppBar.tsx +56 -25
  152. package/src/core/DefaultDrawer.tsx +11 -9
  153. package/src/core/DrawerNavigationItem.tsx +4 -4
  154. package/src/core/EntityEditView.tsx +282 -1006
  155. package/src/core/EntityEditViewFormActions.tsx +199 -0
  156. package/src/core/EntitySidePanel.tsx +85 -15
  157. package/src/core/FireCMS.tsx +12 -9
  158. package/src/core/FireCMSRouter.tsx +17 -0
  159. package/src/core/NavigationRoutes.tsx +23 -32
  160. package/src/core/SideDialogs.tsx +21 -12
  161. package/src/core/field_configs.tsx +4 -4
  162. package/src/core/index.tsx +4 -2
  163. package/src/form/EntityForm.tsx +774 -0
  164. package/src/form/EntityFormActions.tsx +169 -0
  165. package/src/form/PropertyFieldBinding.tsx +39 -30
  166. package/src/form/components/CustomIdField.tsx +2 -0
  167. package/src/form/components/FormEntry.tsx +22 -0
  168. package/src/form/components/FormLayout.tsx +16 -0
  169. package/src/form/components/LabelWithIcon.tsx +6 -3
  170. package/src/form/components/StorageItemPreview.tsx +3 -3
  171. package/src/form/components/StorageUploadProgress.tsx +1 -1
  172. package/src/form/components/index.tsx +2 -1
  173. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +7 -6
  174. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +20 -12
  175. package/src/form/field_bindings/BlockFieldBinding.tsx +45 -25
  176. package/src/form/field_bindings/DateTimeFieldBinding.tsx +2 -1
  177. package/src/form/field_bindings/KeyValueFieldBinding.tsx +10 -7
  178. package/src/form/field_bindings/MapFieldBinding.tsx +69 -52
  179. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +9 -6
  180. package/src/form/field_bindings/MultiSelectFieldBinding.tsx +1 -1
  181. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -2
  182. package/src/form/field_bindings/ReferenceFieldBinding.tsx +5 -5
  183. package/src/form/field_bindings/RepeatFieldBinding.tsx +30 -22
  184. package/src/form/field_bindings/SelectFieldBinding.tsx +6 -5
  185. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +7 -5
  186. package/src/form/field_bindings/SwitchFieldBinding.tsx +26 -25
  187. package/src/form/field_bindings/TextFieldBinding.tsx +4 -3
  188. package/src/form/index.tsx +16 -32
  189. package/src/form/validation.ts +12 -6
  190. package/src/hooks/data/delete.ts +4 -4
  191. package/src/hooks/data/save.ts +8 -9
  192. package/src/hooks/data/useCollectionFetch.tsx +3 -3
  193. package/src/hooks/data/useEntityFetch.tsx +10 -6
  194. package/src/hooks/useAuthController.tsx +1 -1
  195. package/src/hooks/useBreadcrumbsController.tsx +31 -0
  196. package/src/hooks/useBuildModeController.tsx +15 -28
  197. package/src/hooks/useBuildNavigationController.tsx +74 -29
  198. package/src/hooks/useFireCMSContext.tsx +5 -5
  199. package/src/hooks/useLargeLayout.tsx +0 -35
  200. package/src/hooks/useModeController.tsx +1 -2
  201. package/src/hooks/useResolvedNavigationFrom.tsx +9 -11
  202. package/src/hooks/useValidateAuthenticator.tsx +3 -3
  203. package/src/internal/useBuildDataSource.ts +1 -1
  204. package/src/internal/useBuildSideDialogsController.tsx +3 -2
  205. package/src/internal/useBuildSideEntityController.tsx +124 -83
  206. package/src/internal/useUnsavedChangesDialog.tsx +127 -93
  207. package/src/preview/PropertyPreview.tsx +11 -11
  208. package/src/preview/PropertyPreviewProps.tsx +1 -1
  209. package/src/preview/components/BooleanPreview.tsx +1 -1
  210. package/src/preview/components/EmptyValue.tsx +1 -1
  211. package/src/preview/components/EnumValuesChip.tsx +1 -1
  212. package/src/preview/components/ImagePreview.tsx +5 -6
  213. package/src/preview/components/UrlComponentPreview.tsx +20 -21
  214. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
  215. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +2 -2
  216. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +2 -2
  217. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +1 -1
  218. package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -2
  219. package/src/preview/property_previews/ArrayPropertyPreview.tsx +2 -2
  220. package/src/preview/property_previews/MapPropertyPreview.tsx +7 -6
  221. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +12 -12
  222. package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
  223. package/src/preview/util.ts +10 -10
  224. package/src/routes/CustomCMSRoute.tsx +21 -0
  225. package/src/routes/FireCMSRoute.tsx +235 -0
  226. package/src/routes/HomePageRoute.tsx +17 -0
  227. package/src/types/auth.tsx +8 -12
  228. package/src/types/collections.ts +52 -26
  229. package/src/types/datasource.ts +2 -6
  230. package/src/types/dialogs_controller.tsx +7 -3
  231. package/src/types/entities.ts +1 -1
  232. package/src/types/entity_actions.tsx +16 -4
  233. package/src/types/entity_callbacks.ts +18 -18
  234. package/src/types/export_import.ts +4 -4
  235. package/src/types/fields.tsx +33 -4
  236. package/src/types/firecms.tsx +2 -2
  237. package/src/types/firecms_context.tsx +1 -1
  238. package/src/types/navigation.ts +36 -16
  239. package/src/types/permissions.ts +5 -5
  240. package/src/types/plugins.tsx +9 -8
  241. package/src/types/properties.ts +21 -3
  242. package/src/types/property_config.tsx +0 -2
  243. package/src/types/side_dialogs_controller.tsx +2 -0
  244. package/src/types/side_entity_controller.tsx +6 -1
  245. package/src/types/user.ts +2 -0
  246. package/src/util/builders.ts +10 -8
  247. package/src/util/entities.ts +3 -1
  248. package/src/util/entity_actions.ts +28 -0
  249. package/src/util/entity_cache.ts +204 -0
  250. package/src/util/icon_list.ts +1 -0
  251. package/src/util/icon_synonyms.ts +0 -1
  252. package/src/util/icons.tsx +12 -8
  253. package/src/util/index.ts +1 -0
  254. package/src/util/join_collections.ts +3 -0
  255. package/src/util/navigation_from_path.ts +13 -6
  256. package/src/util/navigation_utils.ts +53 -1
  257. package/src/util/objects.ts +24 -1
  258. package/src/util/parent_references_from_path.ts +3 -3
  259. package/src/util/permissions.ts +8 -8
  260. package/src/util/property_utils.tsx +10 -3
  261. package/src/util/references.ts +8 -2
  262. package/src/util/resolutions.ts +34 -13
  263. package/src/util/useStorageUploadController.tsx +40 -22
  264. package/dist/form/components/FormikArrayContainer.d.ts +0 -19
  265. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -236
  266. package/src/form/components/FormikArrayContainer.tsx +0 -47
  267. /package/src/util/{common.tsx → common.ts} +0 -0
package/package.json CHANGED
@@ -1,131 +1,135 @@
1
1
  {
2
- "name": "@firecms/core",
3
- "type": "module",
4
- "version": "3.0.0-beta.10",
5
- "description": "Awesome Firebase/Firestore-based headless open-source CMS",
6
- "funding": {
7
- "url": "https://github.com/sponsors/firecmsco"
2
+ "name": "@firecms/core",
3
+ "type": "module",
4
+ "version": "3.0.0-beta.12",
5
+ "description": "Awesome Firebase/Firestore-based headless open-source CMS",
6
+ "funding": {
7
+ "url": "https://github.com/sponsors/firecmsco"
8
+ },
9
+ "author": "FireCMS",
10
+ "license": "MIT",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/firecmsco/firecms.git",
14
+ "directory": "packages/firecms_core"
15
+ },
16
+ "main": "./dist/index.umd.js",
17
+ "module": "./dist/index.es.js",
18
+ "types": "./dist/index.d.ts",
19
+ "source": "src/index.ts",
20
+ "engines": {
21
+ "node": ">=14"
22
+ },
23
+ "keywords": [
24
+ "firebase",
25
+ "cms",
26
+ "admin",
27
+ "admin panel",
28
+ "firebase panel",
29
+ "firestore",
30
+ "headless",
31
+ "headless cms",
32
+ "content manager"
33
+ ],
34
+ "scripts": {
35
+ "watch": "vite build --watch",
36
+ "build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
37
+ "prepublishOnly": "run-s build",
38
+ "createTag": "PACKAGE_VERSION=$(cat package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]') && git tag v$PACKAGE_VERSION && git push --tags",
39
+ "test:lint": "eslint \"src/**\" --quiet",
40
+ "test": "jest",
41
+ "clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f",
42
+ "generateIcons": "ts-node --esm src/icons/generateIcons.ts"
43
+ },
44
+ "exports": {
45
+ ".": {
46
+ "import": "./dist/index.es.js",
47
+ "require": "./dist/index.umd.js",
48
+ "types": "./dist/index.d.ts"
8
49
  },
9
- "author": "FireCMS",
10
- "license": "MIT",
11
- "repository": "git@github.com:FireCMSco/firecms.git",
12
- "main": "./dist/index.umd.js",
13
- "module": "./dist/index.es.js",
14
- "types": "./dist/index.d.ts",
15
- "source": "src/index.ts",
16
- "engines": {
17
- "node": ">=14"
50
+ "./package.json": "./package.json"
51
+ },
52
+ "dependencies": {
53
+ "@firecms/editor": "^3.0.0-beta.12",
54
+ "@firecms/formex": "^3.0.0-beta.12",
55
+ "@firecms/ui": "^3.0.0-beta.12",
56
+ "@hello-pangea/dnd": "^17.0.0",
57
+ "@radix-ui/react-portal": "^1.1.3",
58
+ "clsx": "^2.1.1",
59
+ "date-fns": "^3.6.0",
60
+ "fuse.js": "^7.0.0",
61
+ "history": "^5.3.0",
62
+ "markdown-it": "^14.1.0",
63
+ "notistack": "^3.0.2",
64
+ "object-hash": "^3.0.0",
65
+ "react-dropzone": "^14.3.5",
66
+ "react-fast-compare": "^3.2.2",
67
+ "react-image-file-resizer": "^0.4.8",
68
+ "react-transition-group": "^4.4.5",
69
+ "react-use-measure": "^2.1.1",
70
+ "react-window": "^1.8.11",
71
+ "yup": "^0.32.11"
72
+ },
73
+ "peerDependencies": {
74
+ "react": ">=18.0.0",
75
+ "react-dom": ">=18.0.0",
76
+ "react-router": "^6.28.0",
77
+ "react-router-dom": "^6.28.0"
78
+ },
79
+ "devDependencies": {
80
+ "@jest/globals": "^29.7.0",
81
+ "@testing-library/react": "^16.2.0",
82
+ "@testing-library/user-event": "^14.6.1",
83
+ "@types/jest": "^29.5.14",
84
+ "@types/node": "^20.17.14",
85
+ "@types/object-hash": "^3.0.6",
86
+ "@types/react": "^18.3.18",
87
+ "@types/react-dom": "^18.3.0",
88
+ "@types/react-measure": "^2.0.12",
89
+ "@vitejs/plugin-react": "^4.3.4",
90
+ "babel-plugin-react-compiler": "beta",
91
+ "cross-env": "^7.0.3",
92
+ "eslint-plugin-react-compiler": "beta",
93
+ "jest": "^29.7.0",
94
+ "npm-run-all": "^4.1.5",
95
+ "react-router": "^6.28.2",
96
+ "react-router-dom": "^6.28.2",
97
+ "ts-jest": "^29.2.5",
98
+ "ts-node": "^10.9.2",
99
+ "tsd": "^0.31.2",
100
+ "typescript": "^5.7.3",
101
+ "vite": "^5.4.14"
102
+ },
103
+ "files": [
104
+ "dist",
105
+ "src"
106
+ ],
107
+ "gitHead": "8de3edb4560643922fe44e9c357985f64c3951c1",
108
+ "publishConfig": {
109
+ "access": "public"
110
+ },
111
+ "eslintConfig": {
112
+ "extends": [
113
+ "react-app",
114
+ "react-app/jest"
115
+ ]
116
+ },
117
+ "jest": {
118
+ "transform": {
119
+ "^.+\\.tsx?$": "ts-jest"
18
120
  },
19
- "keywords": [
20
- "firebase",
21
- "cms",
22
- "admin",
23
- "admin panel",
24
- "firebase panel",
25
- "firestore",
26
- "headless",
27
- "headless cms",
28
- "content manager"
121
+ "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
122
+ "moduleFileExtensions": [
123
+ "ts",
124
+ "tsx",
125
+ "js",
126
+ "jsx",
127
+ "json",
128
+ "node"
29
129
  ],
30
- "scripts": {
31
- "watch": "vite build --watch",
32
- "build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
33
- "prepublishOnly": "run-s build",
34
- "createTag": "PACKAGE_VERSION=$(cat package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]') && git tag v$PACKAGE_VERSION && git push --tags",
35
- "test:lint": "eslint \"src/**\" --quiet",
36
- "test": "jest",
37
- "clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f",
38
- "generateIcons": "ts-node --esm src/icons/generateIcons.ts"
39
- },
40
- "exports": {
41
- ".": {
42
- "import": "./dist/index.es.js",
43
- "require": "./dist/index.umd.js",
44
- "types": "./dist/index.d.ts"
45
- },
46
- "./package.json": "./package.json"
47
- },
48
- "dependencies": {
49
- "@firecms/editor": "^3.0.0-beta.10",
50
- "@firecms/formex": "^3.0.0-beta.10",
51
- "@firecms/ui": "^3.0.0-beta.10",
52
- "@hello-pangea/dnd": "^17.0.0",
53
- "@radix-ui/react-portal": "^1.1.2",
54
- "clsx": "^2.1.1",
55
- "date-fns": "^3.6.0",
56
- "fuse.js": "^7.0.0",
57
- "history": "^5.3.0",
58
- "markdown-it": "^14.1.0",
59
- "notistack": "^3.0.1",
60
- "object-hash": "^3.0.0",
61
- "react-dropzone": "^14.2.9",
62
- "react-fast-compare": "^3.2.2",
63
- "react-image-file-resizer": "^0.4.8",
64
- "react-transition-group": "^4.4.5",
65
- "react-use-measure": "^2.1.1",
66
- "react-window": "^1.8.10",
67
- "yup": "^0.32.11"
68
- },
69
- "peerDependencies": {
70
- "firebase": "^10.5.2",
71
- "react": "^18.3.1",
72
- "react-dom": "^18.3.1",
73
- "react-router": "^6.25.1",
74
- "react-router-dom": "^6.25.1"
75
- },
76
- "devDependencies": {
77
- "@jest/globals": "^29.7.0",
78
- "@testing-library/react": "^16.0.1",
79
- "@testing-library/user-event": "^14.5.2",
80
- "@types/jest": "^29.5.13",
81
- "@types/node": "^20.16.11",
82
- "@types/object-hash": "^3.0.6",
83
- "@types/react": "^18.3.11",
84
- "@types/react-dom": "^18.3.0",
85
- "@types/react-measure": "^2.0.12",
86
- "@vitejs/plugin-react": "^4.3.2",
87
- "cross-env": "^7.0.3",
88
- "firebase": "^10.14.0",
89
- "jest": "^29.7.0",
90
- "npm-run-all": "^4.1.5",
91
- "react-router": "^6.26.2",
92
- "react-router-dom": "^6.26.2",
93
- "ts-jest": "^29.2.5",
94
- "ts-node": "^10.9.2",
95
- "tsd": "^0.31.2",
96
- "typescript": "^5.6.3",
97
- "vite": "^5.4.8"
98
- },
99
- "files": [
100
- "dist",
101
- "src"
102
- ],
103
- "gitHead": "f844c3f86094efec6c33313c3f106f30cdcd309f",
104
- "publishConfig": {
105
- "access": "public"
106
- },
107
- "eslintConfig": {
108
- "extends": [
109
- "react-app",
110
- "react-app/jest"
111
- ]
112
- },
113
- "jest": {
114
- "transform": {
115
- "^.+\\.tsx?$": "ts-jest"
116
- },
117
- "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
118
- "moduleFileExtensions": [
119
- "ts",
120
- "tsx",
121
- "js",
122
- "jsx",
123
- "json",
124
- "node"
125
- ],
126
- "testEnvironment": "node",
127
- "moduleNameMapper": {
128
- "\\.(css|less)$": "<rootDir>/test/__mocks__/styleMock.js"
129
- }
130
+ "testEnvironment": "node",
131
+ "moduleNameMapper": {
132
+ "\\.(css|less)$": "<rootDir>/test/__mocks__/styleMock.js"
130
133
  }
134
+ }
131
135
  }
@@ -91,7 +91,7 @@ export const Scaffold = React.memo<PropsWithChildren<ScaffoldProps>>(
91
91
  autoOpenDrawer
92
92
  }}>
93
93
  <div
94
- className={cls("flex h-screen w-screen bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white overflow-hidden", className)}
94
+ className={cls("flex h-screen w-screen bg-surface-50 dark:bg-surface-900 text-surface-900 dark:text-white overflow-hidden", className)}
95
95
  style={{
96
96
  paddingTop: "env(safe-area-inset-top)",
97
97
  paddingLeft: "env(safe-area-inset-left)",
@@ -168,7 +168,7 @@ function DrawerWrapper(props: {
168
168
  sideOffset={12}
169
169
  asChild={true}>
170
170
  <div
171
- className="ml-2 fixed top-1 left-2 sm:top-2 sm:left-3 !bg-gray-50 dark:!bg-gray-900 rounded-full w-fit z-20">
171
+ className="ml-2 fixed top-1 left-2 sm:top-2 sm:left-2 !bg-surface-50 dark:!bg-surface-900 rounded-full w-fit z-20">
172
172
  <IconButton
173
173
  color="inherit"
174
174
  aria-label="Open menu"
@@ -209,7 +209,7 @@ function DrawerWrapper(props: {
209
209
  aria-label="Open drawer"
210
210
  onClick={() => props.setDrawerOpen(true)}
211
211
  size="large"
212
- className="absolute sm:top-2 sm:left-5 top-1 left-2"
212
+ className="absolute sm:top-2 sm:left-4 top-1 left-2"
213
213
  >
214
214
  <MenuIcon/>
215
215
  </IconButton>
@@ -217,7 +217,7 @@ function DrawerWrapper(props: {
217
217
  transparent={true}
218
218
  open={props.open}
219
219
  onOpenChange={props.setDrawerOpen}
220
- title={"Navigaion drawer"}
220
+ title={"Navigation drawer"}
221
221
  overlayClassName={"bg-white bg-opacity-80"}
222
222
  >
223
223
  {innerDrawer}
@@ -6,10 +6,12 @@ import { getHashValue } from "../util";
6
6
  import {
7
7
  AddIcon,
8
8
  Button,
9
+ cls,
9
10
  ContentCopyIcon,
10
- fieldBackgroundHoverMixin,
11
11
  HandleIcon,
12
12
  IconButton,
13
+ KeyboardArrowDownIcon,
14
+ KeyboardArrowUpIcon,
13
15
  Menu,
14
16
  MenuItem,
15
17
  RemoveIcon,
@@ -17,11 +19,21 @@ import {
17
19
  useOutsideAlerter
18
20
  } from "@firecms/ui";
19
21
 
20
- interface ArrayContainerProps<T> {
22
+ export type ArrayEntryParams = {
23
+ index: number,
24
+ internalId: number,
25
+ isDragging: boolean,
26
+ storedProps?: object,
27
+ storeProps: (props: object) => void
28
+ };
29
+
30
+ export type ArrayEntryBuilder = (params: ArrayEntryParams) => React.ReactNode;
31
+
32
+ export interface ArrayContainerProps<T> {
21
33
  droppableId: string;
22
34
  value: T[];
23
35
  addLabel: string;
24
- buildEntry: (index: number, internalId: number) => React.ReactNode;
36
+ buildEntry: ArrayEntryBuilder;
25
37
  disabled?: boolean;
26
38
  size?: "small" | "medium";
27
39
  onInternalIdAdded?: (id: number) => void;
@@ -29,6 +41,8 @@ interface ArrayContainerProps<T> {
29
41
  newDefaultEntry: T;
30
42
  onValueChange: (value: T[]) => void,
31
43
  className?: string;
44
+ min?: number;
45
+ max?: number;
32
46
  }
33
47
 
34
48
  const buildIdsMap = (value: any[]) =>
@@ -55,7 +69,9 @@ export function ArrayContainer<T>({
55
69
  includeAddButton,
56
70
  newDefaultEntry,
57
71
  onValueChange,
58
- className
72
+ className,
73
+ min = 0,
74
+ max = Infinity
59
75
  }: ArrayContainerProps<T>) {
60
76
 
61
77
  const hasValue = value && Array.isArray(value) && value.length > 0;
@@ -66,7 +82,14 @@ export function ArrayContainer<T>({
66
82
  const [internalIds, setInternalIds] = useState<number[]>(
67
83
  hasValue
68
84
  ? Object.values(internalIdsRef.current)
69
- : []);
85
+ : []
86
+ );
87
+
88
+ const itemCustomPropsRef = useRef<Record<number, object>>({});
89
+
90
+ const updateItemCustomProps = useCallback((internalId: number, customProps: object) => {
91
+ itemCustomPropsRef.current[internalId] = customProps;
92
+ }, []);
70
93
 
71
94
  useEffect(() => {
72
95
  if (hasValue && value && value.length !== internalIds.length) {
@@ -86,7 +109,7 @@ export function ArrayContainer<T>({
86
109
 
87
110
  const insertInEnd = (e: React.SyntheticEvent) => {
88
111
  e.preventDefault();
89
- if (disabled) return;
112
+ if (disabled || (value ?? []).length >= max) return;
90
113
  const id = getRandomId();
91
114
  const newIds: number[] = [...internalIds, id];
92
115
  if (onInternalIdAdded)
@@ -96,6 +119,7 @@ export function ArrayContainer<T>({
96
119
  };
97
120
 
98
121
  const remove = (index: number) => {
122
+ if ((value ?? []).length <= min) return;
99
123
  const newIds = [...internalIds];
100
124
  newIds.splice(index, 1);
101
125
  setInternalIds(newIds);
@@ -103,12 +127,14 @@ export function ArrayContainer<T>({
103
127
  };
104
128
 
105
129
  const copy = (index: number) => {
130
+ if ((value ?? []).length >= max) return;
106
131
  const id = getRandomId();
107
132
  const copyingItem = value[index];
108
133
  const newIds: number[] = [
109
- ...internalIds.splice(0, index + 1),
134
+ ...internalIds.slice(0, index + 1),
110
135
  id,
111
- ...internalIds.splice(index + 1, internalIds.length - index - 1)];
136
+ ...internalIds.slice(index + 1)
137
+ ];
112
138
  if (onInternalIdAdded)
113
139
  onInternalIdAdded(id);
114
140
  setInternalIds(newIds);
@@ -116,6 +142,20 @@ export function ArrayContainer<T>({
116
142
  onValueChange([...value.slice(0, index + 1), copyingItem, ...value.slice(index + 1)]);
117
143
  };
118
144
 
145
+ const addInIndex = (index: number) => {
146
+ if ((value ?? []).length >= max) return;
147
+ const id = getRandomId();
148
+ const newIds: number[] = [
149
+ ...internalIds.slice(0, index),
150
+ id,
151
+ ...internalIds.slice(index)
152
+ ];
153
+ if (onInternalIdAdded)
154
+ onInternalIdAdded(id);
155
+ setInternalIds(newIds);
156
+ onValueChange([...value.slice(0, index), newDefaultEntry, ...value.slice(index)]);
157
+ }
158
+
119
159
  const onDragEnd = (result: any) => {
120
160
  // dropped outside the list
121
161
  if (!result.destination) {
@@ -150,13 +190,17 @@ export function ArrayContainer<T>({
150
190
  remove={remove}
151
191
  copy={copy}
152
192
  isDragging={snapshot.isDragging}
193
+ storedProps={itemCustomPropsRef.current[internalId]}
194
+ updateItemCustomProps={updateItemCustomProps}
195
+ addInIndex={addInIndex}
196
+ includeAddButton={includeAddButton}
153
197
  />
154
198
  );
155
199
  }}
156
200
  >
157
201
  {(droppableProvided, droppableSnapshot) => (
158
202
  <div
159
- className={className}
203
+ className={cls("space-y-1", className)}
160
204
  {...droppableProvided.droppableProps}
161
205
  ref={droppableProvided.innerRef}>
162
206
  {hasValue && internalIds.map((internalId: number, index: number) => {
@@ -177,6 +221,10 @@ export function ArrayContainer<T>({
177
221
  remove={remove}
178
222
  copy={copy}
179
223
  isDragging={snapshot.isDragging}
224
+ storedProps={itemCustomPropsRef.current[internalId]}
225
+ updateItemCustomProps={updateItemCustomProps}
226
+ addInIndex={addInIndex}
227
+ includeAddButton={includeAddButton}
180
228
  />
181
229
  )}
182
230
  </Draggable>
@@ -185,17 +233,19 @@ export function ArrayContainer<T>({
185
233
 
186
234
  {droppableProvided.placeholder}
187
235
 
188
- {includeAddButton && <div className="py-4 justify-center text-left">
189
- <Button
190
- variant={"text"}
191
- size={size === "small" ? "small" : "medium"}
192
- color="primary"
193
- disabled={disabled}
194
- startIcon={<AddIcon/>}
195
- onClick={insertInEnd}>
196
- {addLabel ?? "Add"}
197
- </Button>
198
- </div>}
236
+ {includeAddButton && (
237
+ <div className="my-4 justify-center text-left">
238
+ <Button
239
+ variant={"text"}
240
+ size={size === "small" ? "small" : "medium"}
241
+ color="primary"
242
+ disabled={disabled || value?.length >= max}
243
+ startIcon={<AddIcon/>}
244
+ onClick={insertInEnd}>
245
+ {addLabel ?? "Add"}
246
+ </Button>
247
+ </div>
248
+ )}
199
249
  </div>
200
250
  )}
201
251
  </Droppable>
@@ -209,10 +259,14 @@ type ArrayContainerItemProps = {
209
259
  internalId: number,
210
260
  size?: "small" | "medium",
211
261
  disabled: boolean,
212
- buildEntry: (index: number, internalId: number) => React.ReactNode,
262
+ buildEntry: ArrayEntryBuilder,
213
263
  remove: (index: number) => void,
214
264
  copy: (index: number) => void,
265
+ addInIndex?: (index: number) => void,
266
+ includeAddButton?: boolean,
215
267
  isDragging: boolean,
268
+ storedProps?: object,
269
+ updateItemCustomProps: (internalId: number, props: object) => void
216
270
  };
217
271
 
218
272
  export function ArrayContainerItem({
@@ -223,36 +277,41 @@ export function ArrayContainerItem({
223
277
  disabled,
224
278
  buildEntry,
225
279
  remove,
280
+ addInIndex,
281
+ includeAddButton,
226
282
  copy,
227
- isDragging
283
+ isDragging,
284
+ storedProps,
285
+ updateItemCustomProps
228
286
  }: ArrayContainerItemProps) {
229
287
 
230
- const [onHover, setOnHover] = React.useState(false);
231
- const setOnHoverTrue = useCallback(() => setOnHover(true), []);
232
- const setOnHoverFalse = useCallback(() => setOnHover(false), []);
233
-
234
288
  return <div
235
- onMouseEnter={setOnHoverTrue}
236
- onMouseMove={setOnHoverTrue}
237
- onMouseLeave={setOnHoverFalse}
238
289
  ref={provided.innerRef}
239
290
  {...provided.draggableProps}
240
291
  style={provided.draggableProps.style}
241
- className={`${
242
- (isDragging || onHover) ? "hover:bg-slate-50 dark:hover:bg-gray-800 dark:hover:bg-opacity-20" : ""
243
- } mb-1 rounded-md opacity-100`}
292
+ className={`relative ${
293
+ !isDragging ? "hover:bg-surface-accent-50 dark:hover:bg-surface-800 dark:hover:bg-opacity-20" : ""
294
+ } rounded-md opacity-100`}
244
295
  >
245
296
  <div
246
297
  className="flex items-start">
247
298
  <div
248
299
  className="flex-grow w-[calc(100%-48px)] text-text-primary dark:text-text-primary-dark">
249
- {buildEntry(index, internalId)}
300
+ {buildEntry({
301
+ index,
302
+ internalId,
303
+ isDragging,
304
+ storedProps,
305
+ storeProps: (props: object) => updateItemCustomProps(internalId, props)
306
+ })}
250
307
  </div>
251
308
  <ArrayItemOptions direction={size === "small" ? "row" : "column"}
252
309
  disabled={disabled}
253
310
  remove={remove}
254
311
  index={index}
255
312
  provided={provided}
313
+ addInIndex={addInIndex}
314
+ includeAddButton={includeAddButton}
256
315
  copy={copy}/>
257
316
  </div>
258
317
  </div>;
@@ -265,13 +324,17 @@ export function ArrayItemOptions({
265
324
  index,
266
325
  provided,
267
326
  copy,
327
+ includeAddButton,
328
+ addInIndex
268
329
  }: {
269
330
  direction?: "row" | "column",
270
331
  disabled: boolean,
271
332
  remove: (index: number) => void,
272
333
  index: number,
273
334
  provided: any,
274
- copy: (index: number) => void
335
+ copy: (index: number) => void,
336
+ includeAddButton?: boolean,
337
+ addInIndex?: (index: number) => void
275
338
  }) {
276
339
 
277
340
  const [menuOpen, setMenuOpen] = useState(false);
@@ -321,6 +384,24 @@ export function ArrayItemOptions({
321
384
  Copy
322
385
  </MenuItem>
323
386
 
387
+ {includeAddButton && addInIndex && <MenuItem dense
388
+ onClick={() => {
389
+ setMenuOpen(false);
390
+ addInIndex(index);
391
+ }}>
392
+ <KeyboardArrowUpIcon size={"small"}/>
393
+ Add on top
394
+ </MenuItem>}
395
+
396
+ {includeAddButton && addInIndex && <MenuItem dense
397
+ onClick={() => {
398
+ setMenuOpen(false);
399
+ addInIndex(index + 1);
400
+ }}>
401
+ <KeyboardArrowDownIcon size={"small"}/>
402
+ Add below
403
+ </MenuItem>}
404
+
324
405
  </Menu>
325
406
  </Tooltip>
326
407
 
@@ -13,7 +13,7 @@ export function CircularProgressCenter({ text, ...props }: CircularProgressProps
13
13
  }) {
14
14
  return (
15
15
  <div
16
- className="flex w-full h-screen max-h-full max-w-full bg-gray-50 dark:bg-gray-900 gap-4">
16
+ className="flex w-full h-screen max-h-full max-w-full gap-4">
17
17
  <div className="m-auto flex flex-col gap-2 items-center">
18
18
  <CircularProgress {...props}/>
19
19
  {text && <Typography
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { Button, Dialog, DialogActions, DialogContent, LoadingButton, Typography } from "@firecms/ui";
3
+ import { Button, Dialog, DialogActions, DialogContent, DialogTitle, LoadingButton, Typography } from "@firecms/ui";
4
4
 
5
5
  export function ConfirmationDialog({
6
6
  open,
@@ -22,8 +22,8 @@ export function ConfirmationDialog({
22
22
  open={open}
23
23
  onOpenChange={(open) => !open ? onCancel() : undefined}
24
24
  >
25
+ <DialogTitle variant={"h6"} className={"mb-2"}>{title}</DialogTitle>
25
26
  <DialogContent>
26
- <Typography variant={"h6"} className={"mb-2"}>{title}</Typography>
27
27
  {body}
28
28
  </DialogContent>
29
29