@firecms/core 3.0.0-canary.1 → 3.0.0-canary.100

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 (301) hide show
  1. package/README.md +2 -2
  2. package/dist/app/AppBar.d.ts +12 -0
  3. package/dist/app/Drawer.d.ts +17 -0
  4. package/dist/app/Scaffold.d.ts +30 -0
  5. package/dist/app/index.d.ts +4 -0
  6. package/dist/app/useApp.d.ts +16 -0
  7. package/dist/components/CircularProgressCenter.d.ts +1 -1
  8. package/dist/components/ClearFilterSortButton.d.ts +5 -0
  9. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +11 -12
  10. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  11. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +5 -3
  12. package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +3 -2
  13. package/dist/components/EntityCollectionTable/column_utils.d.ts +1 -2
  14. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +2 -0
  15. package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +1 -4
  16. package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +2 -2
  17. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
  18. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +13 -4
  19. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +11 -0
  20. package/dist/components/EntityCollectionView/useSelectionController.d.ts +2 -0
  21. package/dist/components/EntityPreview.d.ts +26 -7
  22. package/dist/components/EntityView.d.ts +11 -0
  23. package/dist/components/ErrorView.d.ts +1 -1
  24. package/dist/components/FieldCaption.d.ts +5 -0
  25. package/dist/components/HomePage/DefaultHomePage.d.ts +1 -1
  26. package/dist/components/HomePage/NavigationCard.d.ts +8 -0
  27. package/dist/components/HomePage/{NavigationCollectionCard.d.ts → NavigationCardBinding.d.ts} +3 -3
  28. package/dist/components/HomePage/SmallNavigationCard.d.ts +6 -0
  29. package/dist/components/HomePage/index.d.ts +3 -1
  30. package/dist/components/ReferenceWidget.d.ts +6 -4
  31. package/dist/components/SelectableTable/SelectableTable.d.ts +1 -1
  32. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +2 -1
  33. package/dist/components/VirtualTable/VirtualTableProps.d.ts +16 -13
  34. package/dist/components/VirtualTable/types.d.ts +3 -3
  35. package/dist/components/{EntityCollectionTable/internal → common}/default_entity_actions.d.ts +1 -1
  36. package/dist/components/common/index.d.ts +1 -0
  37. package/dist/components/common/table_height.d.ts +5 -0
  38. package/dist/components/common/types.d.ts +4 -6
  39. package/dist/components/common/useColumnsIds.d.ts +2 -1
  40. package/dist/components/common/useDataSourceEntityCollectionTableController.d.ts +3 -0
  41. package/dist/components/index.d.ts +6 -4
  42. package/dist/contexts/AuthControllerContext.d.ts +1 -1
  43. package/dist/{components/FireCMSAppBar.d.ts → core/DefaultAppBar.d.ts} +6 -9
  44. package/dist/core/DefaultDrawer.d.ts +19 -0
  45. package/dist/core/DrawerNavigationItem.d.ts +9 -0
  46. package/dist/core/EntityEditView.d.ts +36 -0
  47. package/dist/core/FireCMS.d.ts +1 -1
  48. package/dist/core/NavigationRoutes.d.ts +3 -3
  49. package/dist/core/index.d.ts +3 -6
  50. package/dist/form/PropertiesForm.d.ts +8 -0
  51. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  52. package/dist/form/components/ErrorFocus.d.ts +1 -1
  53. package/dist/form/components/FieldHelperText.d.ts +3 -3
  54. package/dist/form/components/StorageItemPreview.d.ts +4 -3
  55. package/dist/form/components/StorageUploadProgress.d.ts +1 -1
  56. package/dist/form/components/index.d.ts +1 -0
  57. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  58. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  59. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +3 -4
  60. package/dist/form/field_bindings/TextFieldBinding.d.ts +2 -2
  61. package/dist/form/index.d.ts +1 -2
  62. package/dist/form/validation.d.ts +1 -1
  63. package/dist/hooks/data/delete.d.ts +2 -2
  64. package/dist/hooks/data/save.d.ts +2 -3
  65. package/dist/hooks/data/useDataSource.d.ts +2 -2
  66. package/dist/hooks/data/useEntityFetch.d.ts +3 -3
  67. package/dist/hooks/index.d.ts +4 -1
  68. package/dist/{core → hooks}/useBuildModeController.d.ts +1 -1
  69. package/dist/hooks/useBuildNavigationController.d.ts +6 -4
  70. package/dist/hooks/useProjectLog.d.ts +6 -2
  71. package/dist/hooks/useStorageSource.d.ts +2 -2
  72. package/dist/hooks/useValidateAuthenticator.d.ts +21 -0
  73. package/dist/index.d.ts +1 -0
  74. package/dist/index.es.js +16400 -12423
  75. package/dist/index.es.js.map +1 -1
  76. package/dist/index.umd.js +19713 -7
  77. package/dist/index.umd.js.map +1 -1
  78. package/dist/internal/useBuildDataSource.d.ts +1 -12
  79. package/dist/preview/PropertyPreview.d.ts +1 -1
  80. package/dist/preview/PropertyPreviewProps.d.ts +6 -4
  81. package/dist/preview/components/BooleanPreview.d.ts +5 -1
  82. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  83. package/dist/preview/components/ReferencePreview.d.ts +3 -8
  84. package/dist/preview/components/StorageThumbnail.d.ts +2 -1
  85. package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
  86. package/dist/types/analytics.d.ts +1 -1
  87. package/dist/types/auth.d.ts +38 -2
  88. package/dist/types/collections.d.ts +45 -8
  89. package/dist/types/datasource.d.ts +34 -20
  90. package/dist/types/entities.d.ts +6 -1
  91. package/dist/types/entity_actions.d.ts +14 -0
  92. package/dist/types/entity_callbacks.d.ts +2 -2
  93. package/dist/types/entity_overrides.d.ts +6 -0
  94. package/dist/types/fields.d.ts +36 -30
  95. package/dist/types/index.d.ts +2 -1
  96. package/dist/types/navigation.d.ts +15 -14
  97. package/dist/types/permissions.d.ts +5 -1
  98. package/dist/types/plugins.d.ts +31 -23
  99. package/dist/types/properties.d.ts +34 -21
  100. package/dist/types/property_config.d.ts +2 -2
  101. package/dist/types/roles.d.ts +31 -0
  102. package/dist/types/storage.d.ts +11 -3
  103. package/dist/types/user.d.ts +5 -0
  104. package/dist/util/collections.d.ts +9 -1
  105. package/dist/util/entities.d.ts +1 -1
  106. package/dist/util/icon_list.d.ts +5 -1
  107. package/dist/util/icon_synonyms.d.ts +1 -97
  108. package/dist/util/icons.d.ts +9 -3
  109. package/dist/util/index.d.ts +1 -0
  110. package/dist/util/navigation_utils.d.ts +2 -2
  111. package/dist/util/objects.d.ts +1 -1
  112. package/dist/util/permissions.d.ts +4 -4
  113. package/dist/util/plurals.d.ts +0 -2
  114. package/dist/util/references.d.ts +4 -2
  115. package/dist/util/resolutions.d.ts +15 -14
  116. package/dist/util/storage.d.ts +23 -2
  117. package/dist/util/useStorageUploadController.d.ts +1 -1
  118. package/dist/util/useTraceUpdate.d.ts +1 -0
  119. package/package.json +128 -119
  120. package/src/app/AppBar.tsx +18 -0
  121. package/src/app/Drawer.tsx +25 -0
  122. package/src/app/Scaffold.tsx +251 -0
  123. package/src/app/index.ts +4 -0
  124. package/src/app/useApp.tsx +32 -0
  125. package/src/components/ArrayContainer.tsx +1 -1
  126. package/src/components/CircularProgressCenter.tsx +1 -1
  127. package/src/components/ClearFilterSortButton.tsx +41 -0
  128. package/src/components/DeleteEntityDialog.tsx +4 -4
  129. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +11 -21
  130. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +276 -279
  131. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +9 -5
  132. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +49 -45
  133. package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
  134. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +20 -18
  135. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +17 -9
  136. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +29 -34
  137. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +16 -12
  138. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +4 -5
  139. package/src/components/EntityCollectionView/EntityCollectionView.tsx +95 -92
  140. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +5 -6
  141. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +68 -0
  142. package/src/components/EntityCollectionView/useSelectionController.tsx +42 -0
  143. package/src/components/EntityPreview.tsx +210 -70
  144. package/src/components/EntityView.tsx +84 -0
  145. package/src/components/ErrorView.tsx +1 -1
  146. package/src/components/FieldCaption.tsx +14 -0
  147. package/src/components/HomePage/DefaultHomePage.tsx +37 -24
  148. package/src/components/HomePage/NavigationCard.tsx +69 -0
  149. package/src/components/HomePage/NavigationCardBinding.tsx +116 -0
  150. package/src/components/HomePage/SmallNavigationCard.tsx +45 -0
  151. package/src/components/HomePage/index.tsx +3 -1
  152. package/src/components/PropertyIdCopyTooltipContent.tsx +2 -3
  153. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +4 -4
  154. package/src/components/ReferenceWidget.tsx +26 -16
  155. package/src/components/SearchIconsView.tsx +9 -6
  156. package/src/components/SelectableTable/SelectableTable.tsx +7 -7
  157. package/src/components/SelectableTable/filters/BooleanFilterField.tsx +2 -3
  158. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +22 -7
  159. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +38 -24
  160. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +35 -15
  161. package/src/components/VirtualTable/VirtualTable.tsx +70 -37
  162. package/src/components/VirtualTable/VirtualTableCell.tsx +1 -1
  163. package/src/components/VirtualTable/VirtualTableHeader.tsx +4 -4
  164. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +2 -2
  165. package/src/components/VirtualTable/VirtualTableProps.tsx +19 -15
  166. package/src/components/VirtualTable/VirtualTableRow.tsx +4 -5
  167. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
  168. package/src/components/VirtualTable/types.tsx +2 -3
  169. package/src/components/{EntityCollectionTable/internal → common}/default_entity_actions.tsx +11 -7
  170. package/src/components/common/index.ts +1 -0
  171. package/src/components/{VirtualTable/common.tsx → common/table_height.tsx} +5 -2
  172. package/src/components/common/types.tsx +4 -6
  173. package/src/components/common/useColumnsIds.tsx +23 -2
  174. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +12 -1
  175. package/src/components/common/useTableSearchHelper.ts +52 -12
  176. package/src/components/index.tsx +6 -4
  177. package/src/contexts/AuthControllerContext.tsx +1 -1
  178. package/src/contexts/DialogsProvider.tsx +2 -2
  179. package/src/{components/FireCMSAppBar.tsx → core/DefaultAppBar.tsx} +60 -37
  180. package/src/core/DefaultDrawer.tsx +177 -0
  181. package/src/core/DrawerNavigationItem.tsx +62 -0
  182. package/src/core/EntityEditView.tsx +1130 -0
  183. package/src/core/EntitySidePanel.tsx +3 -4
  184. package/src/core/FireCMS.tsx +55 -44
  185. package/src/core/NavigationRoutes.tsx +15 -8
  186. package/src/core/SideDialogs.tsx +1 -0
  187. package/src/core/field_configs.tsx +2 -3
  188. package/src/core/index.tsx +3 -6
  189. package/src/form/PropertiesForm.tsx +81 -0
  190. package/src/form/PropertyFieldBinding.tsx +38 -9
  191. package/src/form/components/FieldHelperText.tsx +3 -3
  192. package/src/form/components/StorageItemPreview.tsx +21 -10
  193. package/src/form/components/StorageUploadProgress.tsx +9 -8
  194. package/src/form/components/index.tsx +1 -0
  195. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +10 -8
  196. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +18 -18
  197. package/src/form/field_bindings/BlockFieldBinding.tsx +4 -5
  198. package/src/form/field_bindings/DateTimeFieldBinding.tsx +3 -3
  199. package/src/form/field_bindings/KeyValueFieldBinding.tsx +62 -57
  200. package/src/form/field_bindings/MapFieldBinding.tsx +28 -20
  201. package/src/form/field_bindings/MarkdownFieldBinding.tsx +3 -4
  202. package/src/form/field_bindings/MultiSelectBinding.tsx +2 -3
  203. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +4 -11
  204. package/src/form/field_bindings/ReferenceFieldBinding.tsx +21 -17
  205. package/src/form/field_bindings/RepeatFieldBinding.tsx +14 -11
  206. package/src/form/field_bindings/SelectFieldBinding.tsx +5 -6
  207. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +28 -40
  208. package/src/form/field_bindings/SwitchFieldBinding.tsx +3 -4
  209. package/src/form/field_bindings/TextFieldBinding.tsx +10 -9
  210. package/src/form/index.tsx +5 -4
  211. package/src/form/validation.ts +4 -21
  212. package/src/hooks/data/delete.ts +3 -3
  213. package/src/hooks/data/save.ts +4 -2
  214. package/src/hooks/data/useCollectionFetch.tsx +1 -1
  215. package/src/hooks/data/useDataSource.tsx +7 -2
  216. package/src/hooks/data/useEntityFetch.tsx +4 -4
  217. package/src/hooks/index.tsx +6 -1
  218. package/src/{core → hooks}/useBuildLocalConfigurationPersistence.tsx +8 -10
  219. package/src/{core → hooks}/useBuildModeController.tsx +12 -6
  220. package/src/hooks/useBuildNavigationController.tsx +208 -92
  221. package/src/hooks/useProjectLog.tsx +30 -9
  222. package/src/hooks/useReferenceDialog.tsx +2 -2
  223. package/src/hooks/useResolvedNavigationFrom.tsx +1 -1
  224. package/src/hooks/useStorageSource.tsx +7 -2
  225. package/src/hooks/useValidateAuthenticator.tsx +115 -0
  226. package/src/index.ts +1 -0
  227. package/src/internal/useBuildDataSource.ts +56 -44
  228. package/src/internal/useBuildSideEntityController.tsx +88 -21
  229. package/src/preview/PropertyPreview.tsx +11 -18
  230. package/src/preview/PropertyPreviewProps.tsx +4 -8
  231. package/src/preview/components/BooleanPreview.tsx +19 -4
  232. package/src/preview/components/EnumValuesChip.tsx +2 -2
  233. package/src/preview/components/ImagePreview.tsx +21 -33
  234. package/src/preview/components/ReferencePreview.tsx +74 -166
  235. package/src/preview/components/StorageThumbnail.tsx +5 -1
  236. package/src/preview/components/UrlComponentPreview.tsx +44 -11
  237. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +0 -1
  238. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +2 -1
  239. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +0 -1
  240. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +0 -1
  241. package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -3
  242. package/src/preview/property_previews/ArrayPropertyPreview.tsx +2 -3
  243. package/src/preview/property_previews/MapPropertyPreview.tsx +5 -5
  244. package/src/preview/property_previews/StringPropertyPreview.tsx +8 -7
  245. package/src/types/analytics.ts +1 -0
  246. package/src/types/auth.tsx +51 -2
  247. package/src/types/collections.ts +52 -8
  248. package/src/types/customization_controller.tsx +0 -1
  249. package/src/types/datasource.ts +41 -24
  250. package/src/types/entities.ts +13 -1
  251. package/src/types/entity_actions.tsx +17 -0
  252. package/src/types/entity_callbacks.ts +2 -2
  253. package/src/types/entity_overrides.tsx +7 -0
  254. package/src/types/fields.tsx +39 -33
  255. package/src/types/firecms.tsx +0 -1
  256. package/src/types/index.ts +2 -1
  257. package/src/types/navigation.ts +17 -17
  258. package/src/types/permissions.ts +6 -1
  259. package/src/types/plugins.tsx +38 -31
  260. package/src/types/properties.ts +40 -22
  261. package/src/types/property_config.tsx +2 -2
  262. package/src/types/roles.ts +41 -0
  263. package/src/types/side_entity_controller.tsx +1 -0
  264. package/src/types/storage.ts +12 -3
  265. package/src/types/user.ts +7 -0
  266. package/src/util/collections.ts +22 -0
  267. package/src/util/entities.ts +5 -4
  268. package/src/util/enums.ts +1 -1
  269. package/src/util/icon_list.ts +15 -10
  270. package/src/util/icon_synonyms.ts +3 -99
  271. package/src/util/icons.tsx +11 -3
  272. package/src/util/index.ts +1 -0
  273. package/src/util/navigation_utils.ts +6 -6
  274. package/src/util/objects.ts +25 -28
  275. package/src/util/permissions.ts +12 -8
  276. package/src/util/plurals.ts +0 -2
  277. package/src/util/references.ts +36 -5
  278. package/src/util/resolutions.ts +44 -39
  279. package/src/util/storage.ts +75 -21
  280. package/src/util/strings.ts +2 -2
  281. package/src/util/useStorageUploadController.tsx +21 -3
  282. package/src/util/useTraceUpdate.tsx +2 -1
  283. package/dist/components/VirtualTable/common.d.ts +0 -2
  284. package/dist/core/Drawer.d.ts +0 -23
  285. package/dist/core/Scaffold.d.ts +0 -55
  286. package/dist/form/EntityForm.d.ts +0 -77
  287. package/dist/internal/EntityView.d.ts +0 -22
  288. package/dist/internal/useBuildCustomizationController.d.ts +0 -2
  289. package/dist/internal/useLocaleConfig.d.ts +0 -1
  290. package/dist/types/appcheck.d.ts +0 -26
  291. package/src/components/HomePage/NavigationCollectionCard.tsx +0 -146
  292. package/src/core/Drawer.tsx +0 -164
  293. package/src/core/Scaffold.tsx +0 -281
  294. package/src/form/EntityForm.tsx +0 -720
  295. package/src/internal/EntityView.tsx +0 -578
  296. package/src/internal/useBuildCustomizationController.tsx +0 -5
  297. package/src/internal/useLocaleConfig.tsx +0 -18
  298. package/src/types/appcheck.ts +0 -29
  299. /package/dist/{components → form/components}/LabelWithIcon.d.ts +0 -0
  300. /package/dist/{core → hooks}/useBuildLocalConfigurationPersistence.d.ts +0 -0
  301. /package/src/{components → form/components}/LabelWithIcon.tsx +0 -0
@@ -1,11 +1,11 @@
1
1
  import React, { useState } from "react";
2
2
  import { CMSType, FieldProps, ResolvedProperty } from "../../types";
3
- import { FieldHelperText, FormikArrayContainer } from "../components";
4
- import { ErrorBoundary, LabelWithIcon } from "../../components";
5
- import { useClearRestoreValue } from "../../hooks";
6
- import { getIconForProperty } from "../../util";
3
+ import { FieldHelperText, FormikArrayContainer, LabelWithIcon } from "../components";
4
+ import { ErrorBoundary } from "../../components";
5
+ import { getDefaultValueFor, getIconForProperty } from "../../util";
7
6
  import { PropertyFieldBinding } from "../PropertyFieldBinding";
8
- import { ExpandablePanel } from "@firecms/ui";
7
+ import { ExpandablePanel, Typography } from "@firecms/ui";
8
+ import { useClearRestoreValue } from "../useClearRestoreValue";
9
9
 
10
10
  /**
11
11
  * Generic array field that allows reordering and renders the child property
@@ -63,7 +63,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
63
63
  autoFocus: internalId === lastAddedId
64
64
  };
65
65
  return <ErrorBoundary>
66
- <PropertyFieldBinding {...fieldProps}/>
66
+ <PropertyFieldBinding {...fieldProps} index={index}/>
67
67
  </ErrorBoundary>;
68
68
  };
69
69
 
@@ -75,12 +75,15 @@ export function RepeatFieldBinding<T extends Array<any>>({
75
75
  onInternalIdAdded={setLastAddedId}
76
76
  disabled={isSubmitting || Boolean(property.disabled)}
77
77
  includeAddButton={!property.disabled}
78
- newDefaultEntry={property.of.defaultValue}/>;
78
+ newDefaultEntry={getDefaultValueFor(property.of)}/>;
79
79
 
80
- const title = (<LabelWithIcon icon={getIconForProperty(property, "small")}
81
- required={property.validation?.required}
82
- title={property.name}
83
- className={"text-text-secondary dark:text-text-secondary-dark"}/>);
80
+ const title = (<>
81
+ <LabelWithIcon icon={getIconForProperty(property, "small")}
82
+ required={property.validation?.required}
83
+ title={property.name}
84
+ className={"flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
85
+ {Array.isArray(value) && <Typography variant={"caption"} className={"px-4"}>({value.length})</Typography>}
86
+ </>);
84
87
 
85
88
  return (
86
89
 
@@ -1,12 +1,11 @@
1
1
  import React, { useCallback } from "react";
2
2
 
3
3
  import { EnumType, FieldProps } from "../../types";
4
- import { FieldHelperText } from "../components";
5
- import { LabelWithIcon } from "../../components";
6
- import { useClearRestoreValue } from "../../hooks";
4
+ import { FieldHelperText, LabelWithIcon } from "../components";
7
5
  import { EnumValuesChip } from "../../preview";
8
6
  import { getIconForProperty } from "../../util";
9
- import { ClearIcon, cn, IconButton, Select, SelectItem } from "@firecms/ui";
7
+ import { ClearIcon, cls, IconButton, Select, SelectItem } from "@firecms/ui";
8
+ import { useClearRestoreValue } from "../useClearRestoreValue";
10
9
 
11
10
  type SelectProps<T extends EnumType> = FieldProps<T>;
12
11
 
@@ -49,10 +48,10 @@ export function SelectFieldBinding<T extends EnumType>({
49
48
  <>
50
49
 
51
50
  <Select
52
- value={value ? value.toString() : ""}
51
+ value={value !== undefined && value != null ? value.toString() : ""}
53
52
  disabled={disabled}
54
53
  position="item-aligned"
55
- inputClassName={cn("w-full")}
54
+ inputClassName={cls("w-full")}
56
55
  label={<LabelWithIcon icon={getIconForProperty(property, "small")}
57
56
  required={property.validation?.required}
58
57
  title={property.name}
@@ -1,36 +1,29 @@
1
1
  import React, { useCallback } from "react";
2
2
 
3
- import {
4
- ArrayProperty,
5
- Entity,
6
- FieldProps,
7
- ResolvedArrayProperty,
8
- ResolvedStringProperty,
9
- StorageConfig
10
- } from "../../types";
3
+ import { ArrayProperty, FieldProps, ResolvedArrayProperty, ResolvedStringProperty, StorageConfig } from "../../types";
11
4
  import { useDropzone } from "react-dropzone";
12
5
  import { PreviewSize } from "../../preview";
13
- import { FieldHelperText } from "../components";
14
- import { LabelWithIcon } from "../../components";
6
+ import { FieldHelperText, LabelWithIcon } from "../components";
15
7
 
16
8
  import { getIconForProperty, isReadOnly } from "../../util";
17
- import { useClearRestoreValue, useSnackbarController, useStorageSource } from "../../hooks";
9
+ import { useSnackbarController, useStorageSource } from "../../hooks";
18
10
  import { DragDropContext, Draggable, Droppable } from "@hello-pangea/dnd";
19
11
  import { StorageFieldItem, useStorageUploadController } from "../../util/useStorageUploadController";
20
12
  import { StorageUploadProgress } from "../components/StorageUploadProgress";
21
13
  import { StorageItemPreview } from "../components/StorageItemPreview";
22
14
  import {
23
- cn,
15
+ cls,
24
16
  fieldBackgroundDisabledMixin,
25
17
  fieldBackgroundHoverMixin,
26
18
  fieldBackgroundMixin,
27
19
  focusedMixin,
28
20
  Typography
29
21
  } from "@firecms/ui";
22
+ import { useClearRestoreValue } from "../useClearRestoreValue";
30
23
 
31
24
  const dropZoneClasses = "box-border relative pt-[2px] items-center border border-transparent min-h-[254px] outline-none rounded-md duration-200 ease-[cubic-bezier(0.4,0,0.2,1)] focus:border-primary-solid";
32
25
  const disabledClasses = "border-dotted-gray"
33
- const nonActiveDropClasses = "hover:bg-field-hover dark:hover:bg-field-hover-dark"
26
+ const nonActiveDropClasses = fieldBackgroundHoverMixin
34
27
  const activeDropClasses = "pt-0 border-2 border-solid"
35
28
  const acceptDropClasses = "transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-2 border-solid border-green-500"
36
29
  const rejectDropClasses = "transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-2 border-solid border-red-500"
@@ -55,13 +48,13 @@ export function StorageUploadFieldBinding({
55
48
  property,
56
49
  includeDescription,
57
50
  context,
58
- isSubmitting
51
+ isSubmitting,
59
52
  }: StorageUploadFieldProps) {
60
53
 
61
54
  if (!context.entityId)
62
55
  throw new Error("StorageUploadFieldBinding: Entity id is null");
63
56
 
64
- const storageSource = useStorageSource();
57
+ const storageSource = useStorageSource(context.collection);
65
58
  const disabled = isReadOnly(property) || !!property.disabled || isSubmitting;
66
59
 
67
60
  const {
@@ -80,7 +73,7 @@ export function StorageUploadFieldBinding({
80
73
  propertyKey,
81
74
  value,
82
75
  storageSource,
83
- disabled,
76
+ disabled: disabled ?? false,
84
77
  onChange: setValue
85
78
  });
86
79
 
@@ -90,12 +83,6 @@ export function StorageUploadFieldBinding({
90
83
  setValue
91
84
  });
92
85
 
93
- const entity: Entity<any> = {
94
- id: context.entityId,
95
- values: context.values,
96
- path: context.path
97
- };
98
-
99
86
  return (
100
87
 
101
88
  <>
@@ -109,13 +96,12 @@ export function StorageUploadFieldBinding({
109
96
  <StorageUpload
110
97
  value={internalValue}
111
98
  name={propertyKey}
112
- disabled={disabled}
113
- autoFocus={autoFocus}
99
+ disabled={disabled ?? false}
100
+ autoFocus={autoFocus ?? false}
114
101
  property={property}
115
102
  onChange={setValue}
116
103
  setInternalValue={setInternalValue}
117
104
  onFilesAdded={onFilesAdded}
118
- entity={entity}
119
105
  onFileUploadComplete={onFileUploadComplete}
120
106
  storagePathBuilder={storagePathBuilder}
121
107
  storage={storage}
@@ -141,7 +127,6 @@ function FileDropComponent({
141
127
  autoFocus,
142
128
  internalValue,
143
129
  property,
144
- entity,
145
130
  onClear,
146
131
  metadata,
147
132
  storagePathBuilder,
@@ -161,7 +146,6 @@ function FileDropComponent({
161
146
  property: ResolvedStringProperty,
162
147
  onClear: (clearedStoragePathOrDownloadUrl: string) => void,
163
148
  metadata: any,
164
- entity: Entity<any>;
165
149
  storagePathBuilder: (file: File) => string,
166
150
  onFileUploadComplete: (uploadedPath: string, entry: StorageFieldItem, fileMetadata?: any) => Promise<void>,
167
151
  size: PreviewSize,
@@ -186,10 +170,18 @@ function FileDropComponent({
186
170
  onDropRejected: (fileRejections, event) => {
187
171
  for (const fileRejection of fileRejections) {
188
172
  for (const error of fileRejection.errors) {
189
- snackbarContext.open({
190
- type: "error",
191
- message: `Error uploading file: File is larger than ${storage.maxSize} bytes`
192
- });
173
+ console.log("Error uploading file: ", error);
174
+ if (error.code === "file-too-large") {
175
+ snackbarContext.open({
176
+ type: "error",
177
+ message: `Error uploading file: File is larger than ${storage.maxSize} bytes`
178
+ });
179
+ } else if (error.code === "file-invalid-type") {
180
+ snackbarContext.open({
181
+ type: "error",
182
+ message: "Error uploading file: File type is not supported"
183
+ });
184
+ }
193
185
  }
194
186
  }
195
187
  }
@@ -199,7 +191,7 @@ function FileDropComponent({
199
191
  return (
200
192
  <div
201
193
  {...getRootProps()}
202
- className={cn(
194
+ className={cls(
203
195
  fieldBackgroundMixin,
204
196
  disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,
205
197
  dropZoneClasses,
@@ -216,7 +208,7 @@ function FileDropComponent({
216
208
  <div
217
209
  {...droppableProvided.droppableProps}
218
210
  ref={droppableProvided.innerRef}
219
- className={cn("flex items-center p-1 no-scrollbar",
211
+ className={cls("flex items-center p-1 no-scrollbar",
220
212
  multipleFilesSupported && internalValue.length ? "overflow-auto" : "",
221
213
  multipleFilesSupported && internalValue.length ? "min-h-[180px]" : "min-h-[250px]"
222
214
  )}
@@ -234,7 +226,6 @@ function FileDropComponent({
234
226
  name={`storage_preview_${entry.storagePathOrDownloadUrl}`}
235
227
  property={property}
236
228
  disabled={disabled}
237
- entity={entity}
238
229
  value={entry.storagePathOrDownloadUrl}
239
230
  onRemove={onClear}
240
231
  size={entry.size}/>
@@ -263,7 +254,7 @@ function FileDropComponent({
263
254
  ref={provided.innerRef}
264
255
  {...provided.draggableProps}
265
256
  {...provided.dragHandleProps}
266
- className={cn(focusedMixin, "rounded-md")}
257
+ className={cls(focusedMixin, "rounded-md")}
267
258
  style={{
268
259
  ...provided.draggableProps.style
269
260
  }}
@@ -301,7 +292,6 @@ export interface StorageUploadProps {
301
292
  multipleFilesSupported: boolean;
302
293
  autoFocus: boolean;
303
294
  disabled: boolean;
304
- entity: Entity<any>;
305
295
  storage: StorageConfig;
306
296
  onFilesAdded: (acceptedFiles: File[]) => void;
307
297
  storagePathBuilder: (file: File) => string;
@@ -320,8 +310,7 @@ export function StorageUpload({
320
310
  onFilesAdded,
321
311
  autoFocus,
322
312
  storage,
323
- entity,
324
- storagePathBuilder
313
+ storagePathBuilder,
325
314
  }: StorageUploadProps) {
326
315
 
327
316
  if (multipleFilesSupported) {
@@ -402,9 +391,9 @@ export function StorageUpload({
402
391
  >
403
392
  <StorageItemPreview
404
393
  name={`storage_preview_${entry.storagePathOrDownloadUrl}`}
394
+ placeholder={true}
405
395
  property={renderProperty}
406
396
  disabled={true}
407
- entity={entity}
408
397
  value={entry.storagePathOrDownloadUrl as string}
409
398
  onRemove={onClear}
410
399
  size={entry.size}/>
@@ -422,7 +411,6 @@ export function StorageUpload({
422
411
  autoFocus={autoFocus}
423
412
  internalValue={value}
424
413
  property={renderProperty}
425
- entity={entity}
426
414
  onClear={onClear}
427
415
  metadata={metadata}
428
416
  storagePathBuilder={storagePathBuilder}
@@ -1,11 +1,10 @@
1
1
  import React from "react";
2
2
 
3
3
  import { FieldProps } from "../../types";
4
- import { useClearRestoreValue } from "../../hooks";
5
4
  import { getIconForProperty } from "../../util";
6
- import { FieldHelperText } from "../components/FieldHelperText";
5
+ import { FieldHelperText, LabelWithIcon } from "../components";
7
6
  import { BooleanSwitchWithLabel } from "@firecms/ui";
8
- import { LabelWithIcon } from "../../components";
7
+ import { useClearRestoreValue } from "../useClearRestoreValue";
9
8
 
10
9
  type SwitchFieldProps = FieldProps<boolean>;
11
10
 
@@ -47,7 +46,7 @@ export const SwitchFieldBinding = React.forwardRef(function SwitchFieldBinding({
47
46
  title={property.name}/>}
48
47
  disabled={disabled}
49
48
  autoFocus={autoFocus}
50
- size={"medium"}
49
+ size={"large"}
51
50
  />
52
51
 
53
52
  <FieldHelperText includeDescription={includeDescription}
@@ -1,14 +1,13 @@
1
1
  import React, { useCallback } from "react";
2
2
 
3
+ import { ClearIcon, Collapse, IconButton, TextField } from "@firecms/ui";
3
4
  import { FieldProps, PreviewType } from "../../types";
4
- import { FieldHelperText } from "../components";
5
- import { useClearRestoreValue } from "../../hooks";
5
+ import { FieldHelperText, LabelWithIcon } from "../components";
6
6
  import { getIconForProperty } from "../../util";
7
- import { ClearIcon, Collapse, IconButton, TextField } from "@firecms/ui";
8
7
  import { PropertyPreview } from "../../preview";
9
- import { LabelWithIcon } from "../../components";
8
+ import { useClearRestoreValue } from "../useClearRestoreValue";
10
9
 
11
- interface TextFieldProps<T extends string | number> extends FieldProps<T> {
10
+ interface TextFieldBindingProps<T extends string | number> extends FieldProps<T> {
12
11
  allowInfinity?: boolean
13
12
  }
14
13
 
@@ -19,6 +18,7 @@ interface TextFieldProps<T extends string | number> extends FieldProps<T> {
19
18
  * @group Form fields
20
19
  */
21
20
  export function TextFieldBinding<T extends string | number>({
21
+ context,
22
22
  propertyKey,
23
23
  value,
24
24
  setValue,
@@ -28,7 +28,7 @@ export function TextFieldBinding<T extends string | number>({
28
28
  autoFocus,
29
29
  property,
30
30
  includeDescription,
31
- }: TextFieldProps<T>) {
31
+ }: TextFieldBindingProps<T>) {
32
32
 
33
33
  let multiline: boolean | undefined;
34
34
  let url: boolean | PreviewType | undefined;
@@ -97,9 +97,10 @@ export function TextFieldBinding<T extends string | number>({
97
97
  {url && <Collapse
98
98
  className="mt-1 ml-1"
99
99
  in={Boolean(value)}>
100
- <PropertyPreview value={value}
101
- property={property}
102
- size={"medium"}/>
100
+ <PropertyPreview
101
+ value={value}
102
+ property={property}
103
+ size={"medium"}/>
103
104
  </Collapse>}
104
105
 
105
106
  </>
@@ -34,9 +34,10 @@ export {
34
34
 
35
35
  export * from "./components";
36
36
 
37
- export type { EntityFormProps } from "./EntityForm";
38
- export {
39
- EntityForm
40
- } from "./EntityForm";
37
+ // export type { EntityFormProps } from "./EntityForm";
38
+ // export {
39
+ // EntityForm
40
+ // } from "./EntityForm";
41
41
 
42
42
  export { PropertyFieldBinding } from "./PropertyFieldBinding";
43
+ export * from "./useClearRestoreValue";
@@ -9,8 +9,7 @@ import {
9
9
  } from "../types";
10
10
  import * as yup from "yup";
11
11
  import { AnySchema, ArraySchema, BooleanSchema, DateSchema, NumberSchema, ObjectSchema, StringSchema } from "yup";
12
- import { enumToObjectEntries } from "../util/enums";
13
- import { getValueInPath, hydrateRegExp, isPropertyBuilder } from "../util";
12
+ import { enumToObjectEntries, getValueInPath, hydrateRegExp, isPropertyBuilder } from "../util";
14
13
 
15
14
  // Add custom unique function for array values
16
15
  declare module "yup" {
@@ -90,12 +89,12 @@ export function mapPropertyToYup<T extends CMSType>(propertyContext: PropertyCon
90
89
  throw Error("Unsupported data type in yup mapping");
91
90
  }
92
91
 
93
- export function getYupMapObjectSchema<M extends Record<string, any>>({
92
+ export function getYupMapObjectSchema({
94
93
  property,
95
94
  entityId,
96
95
  customFieldValidator,
97
96
  name
98
- }: PropertyContext<M>): ObjectSchema<any> {
97
+ }: PropertyContext<Record<string, any>>): ObjectSchema<any> {
99
98
  const objectSchema: any = {};
100
99
  const validation = property.validation;
101
100
  if (property.properties)
@@ -113,23 +112,7 @@ export function getYupMapObjectSchema<M extends Record<string, any>>({
113
112
  if (validation?.required) {
114
113
  return shape.required(validation?.requiredMessage ? validation.requiredMessage : "Required").nullable(true);
115
114
  }
116
- return shape.nullable(true);
117
- // const object: ObjectSchema<any> = yup.object().shape(objectSchema);
118
- // return validation?.required
119
- // ? object.required(validation?.requiredMessage ? validation.requiredMessage : "Required").nullable(true)
120
- // : yup.object().optional().default(undefined).notRequired().nullable(true).test(
121
- // "empty-check",
122
- // "Optional map can be empty",
123
- // (o: any, testContext: any) => {
124
- // try {
125
- // if (!o || Object.keys(o).length === 0) return true;
126
- // return object.validateSync(o);
127
- // } catch (e) {
128
- // testContext.createError(e);
129
- // console.error(e);
130
- // return false;
131
- // }
132
- // });
115
+ return yup.object().shape(shape.fields).default(undefined).notRequired().nullable(true);
133
116
  }
134
117
 
135
118
  function getYupStringSchema({
@@ -12,10 +12,10 @@ import {
12
12
  /**
13
13
  * @group Hooks and utilities
14
14
  */
15
- export type DeleteEntityWithCallbacksProps<M extends Record<string, any>> =
15
+ export type DeleteEntityWithCallbacksProps<M extends Record<string, any>, UserType extends User = User> =
16
16
  DeleteEntityProps<M>
17
17
  & {
18
- callbacks?: EntityCallbacks<M>;
18
+ callbacks?: EntityCallbacks<M, UserType>;
19
19
  onDeleteSuccess?: (entity: Entity<M>) => void;
20
20
  onDeleteFailure?: (entity: Entity<M>, e: Error) => void;
21
21
  onPreDeleteHookError?: (entity: Entity<M>, e: Error) => void;
@@ -62,7 +62,7 @@ export async function deleteEntityWithCallbacks<M extends Record<string, any>, U
62
62
 
63
63
  console.debug("Deleting entity", entity.path, entity.id);
64
64
 
65
- const entityDeleteProps: EntityOnDeleteProps<M, UserType> = {
65
+ const entityDeleteProps: EntityOnDeleteProps<M, any> = {
66
66
  entity,
67
67
  collection,
68
68
  entityId: entity.id,
@@ -17,7 +17,6 @@ import { resolveCollection } from "../../util";
17
17
  export type SaveEntityWithCallbacksProps<M extends Record<string, any>> =
18
18
  SaveEntityProps<M> &
19
19
  {
20
- callbacks?: EntityCallbacks<M>;
21
20
  onSaveSuccess?: (updatedEntity: Entity<M>) => void,
22
21
  onSaveFailure?: (e: Error) => void,
23
22
  onPreSaveHookError?: (e: Error) => void,
@@ -64,7 +63,7 @@ export async function saveEntityWithCallbacks<M extends Record<string, any>, Use
64
63
  onPreSaveHookError,
65
64
  onSaveSuccessHookError
66
65
  }: SaveEntityWithCallbacksProps<M> & {
67
- collection: EntityCollection<M>,
66
+ collection: EntityCollection<M, UserType>,
68
67
  dataSource: DataSource,
69
68
  context: FireCMSContext<UserType>,
70
69
  }
@@ -109,6 +108,7 @@ export async function saveEntityWithCallbacks<M extends Record<string, any>, Use
109
108
  updatedValues = values;
110
109
  }
111
110
 
111
+ console.log("Saving entity", entityId, updatedValues);
112
112
  return dataSource.saveEntity({
113
113
  collection,
114
114
  path: resolvedPath,
@@ -117,6 +117,7 @@ export async function saveEntityWithCallbacks<M extends Record<string, any>, Use
117
117
  previousValues,
118
118
  status
119
119
  }).then((entity) => {
120
+ console.log("Entity saved");
120
121
  try {
121
122
  if (callbacks?.onSaveSuccess) {
122
123
  const resolvedCollection = resolveCollection<M>({
@@ -145,6 +146,7 @@ export async function saveEntityWithCallbacks<M extends Record<string, any>, Use
145
146
  onSaveSuccess(entity);
146
147
  })
147
148
  .catch((e) => {
149
+ console.error("!!!", e);
148
150
  if (callbacks?.onSaveFailure) {
149
151
 
150
152
  const resolvedCollection = resolveCollection<M>({
@@ -70,7 +70,7 @@ export function useCollectionFetch<M extends Record<string, any>, UserType exten
70
70
  searchString
71
71
  }: CollectionFetchProps<M>): CollectionFetchResult<M> {
72
72
 
73
- const dataSource = useDataSource();
73
+ const dataSource = useDataSource(collection);
74
74
  const navigationController = useNavigationController();
75
75
 
76
76
  const path = navigationController.resolveAliasesFrom(inputPath);
@@ -1,9 +1,14 @@
1
1
  import { useContext } from "react";
2
- import { DataSource } from "../../types";
2
+ import { DataSource, EntityCollection } from "../../types";
3
3
  import { DataSourceContext } from "../../contexts/DataSourceContext";
4
4
 
5
5
  /**
6
6
  * Use this hook to get the datasource being used
7
7
  * @group Hooks and utilities
8
8
  */
9
- export const useDataSource = (): DataSource => useContext(DataSourceContext);
9
+ export const useDataSource = (collection?: EntityCollection<any, any>): DataSource => {
10
+ const defaultDataSource = useContext(DataSourceContext);
11
+ if (collection?.overrides?.dataSource)
12
+ return collection?.overrides.dataSource;
13
+ return defaultDataSource;
14
+ };
@@ -7,10 +7,10 @@ import { useFireCMSContext } from "../useFireCMSContext";
7
7
  /**
8
8
  * @group Hooks and utilities
9
9
  */
10
- export interface EntityFetchProps<M extends Record<string, any>> {
10
+ export interface EntityFetchProps<M extends Record<string, any>, UserType extends User = User> {
11
11
  path: string;
12
12
  entityId?: string;
13
- collection: EntityCollection<M>;
13
+ collection: EntityCollection<M, UserType>;
14
14
  useCache?: boolean;
15
15
  }
16
16
 
@@ -41,9 +41,9 @@ export function useEntityFetch<M extends Record<string, any>, UserType extends U
41
41
  entityId,
42
42
  collection,
43
43
  useCache = false
44
- }: EntityFetchProps<M>): EntityFetchResult<M> {
44
+ }: EntityFetchProps<M, UserType>): EntityFetchResult<M> {
45
45
 
46
- const dataSource = useDataSource();
46
+ const dataSource = useDataSource(collection);
47
47
  const navigationController = useNavigationController();
48
48
 
49
49
  const path = navigationController.resolveAliasesFrom(inputPath);
@@ -4,13 +4,13 @@ export * from "./data/useEntityFetch";
4
4
  export * from "./data/save";
5
5
  export * from "./data/delete";
6
6
 
7
- export * from "../form/useClearRestoreValue";
8
7
  export * from "./useNavigationController";
9
8
 
10
9
  export * from "./useResolvedNavigationFrom";
11
10
 
12
11
  export * from "./useStorageSource";
13
12
  export * from "./useAuthController";
13
+ export * from "./useDialogsController";
14
14
  export * from "./useSideDialogsController";
15
15
  export * from "./useSideEntityController";
16
16
  export * from "./useFireCMSContext";
@@ -23,3 +23,8 @@ export * from "./useReferenceDialog";
23
23
  export * from "./useBrowserTitleAndIcon";
24
24
  export * from "./useCustomizationController";
25
25
  export * from "./useBuildNavigationController";
26
+
27
+ export * from "./useBuildLocalConfigurationPersistence";
28
+ export * from "./useBuildModeController";
29
+
30
+ export * from "./useValidateAuthenticator";
@@ -1,10 +1,10 @@
1
- import { useCallback, useEffect, useState } from "react";
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
2
  import { PartialEntityCollection, UserConfigurationPersistence } from "../types";
3
3
  import { mergeDeep, stripCollectionPath } from "../util";
4
4
 
5
5
  export function useBuildLocalConfigurationPersistence(): UserConfigurationPersistence {
6
6
 
7
- const [configCache, setConfigCache] = useState<Record<string, PartialEntityCollection>>({});
7
+ const configCache = useRef<Record<string, PartialEntityCollection>>({});
8
8
 
9
9
  const getCollectionFromStorage = useCallback((storageKey: string) => {
10
10
  const item = localStorage.getItem(storageKey);
@@ -13,20 +13,18 @@ export function useBuildLocalConfigurationPersistence(): UserConfigurationPersis
13
13
 
14
14
  const getCollectionConfig = useCallback(<M extends Record<string, any>>(path: string): PartialEntityCollection<M> => {
15
15
  const storageKey = `collection_config::${stripCollectionPath(path)}`;
16
- if (configCache[storageKey]) {
17
- return configCache[storageKey] as PartialEntityCollection<M>;
16
+ if (configCache.current[storageKey]) {
17
+ return configCache.current[storageKey] as PartialEntityCollection<M>;
18
18
  }
19
19
  return getCollectionFromStorage(storageKey);
20
- }, [configCache, getCollectionFromStorage]);
20
+ }, [getCollectionFromStorage]);
21
21
 
22
22
  const onCollectionModified = useCallback(<M extends Record<string, any>>(path: string, data: PartialEntityCollection<M>) => {
23
23
  const storageKey = `collection_config::${stripCollectionPath(path)}`;
24
24
  localStorage.setItem(storageKey, JSON.stringify(data));
25
- setConfigCache((currentCache) => {
26
- const cachedConfig = currentCache[storageKey];
27
- const newConfig = mergeDeep(cachedConfig ?? getCollectionFromStorage(path), data);
28
- return (mergeDeep(currentCache, newConfig));
29
- });
25
+ const cachedConfig = configCache.current[storageKey];
26
+ const newConfig = mergeDeep(cachedConfig ?? getCollectionFromStorage(path), data);
27
+ configCache.current[storageKey] = mergeDeep(configCache.current[storageKey], newConfig);
30
28
  }, [getCollectionFromStorage]);
31
29
 
32
30
  const [recentlyVisitedPaths, _setRecentlyVisitedPaths] = useState<string[]>([]);
@@ -1,6 +1,6 @@
1
1
  import { useCallback, useEffect, useState } from "react";
2
2
 
3
- import { ModeController } from "../hooks";
3
+ import { ModeController } from "./index";
4
4
 
5
5
  /**
6
6
  * Use this hook to build a color mode controller that determines
@@ -8,8 +8,13 @@ import { ModeController } from "../hooks";
8
8
  */
9
9
  export function useBuildModeController(): ModeController {
10
10
 
11
- const prefersDarkModeQuery = typeof window !== "undefined" &&
12
- window.matchMedia("(prefers-color-scheme: dark)");
11
+ const prefersDarkModeQuery = useCallback((): boolean => {
12
+ if (typeof window === "undefined")
13
+ return false;
14
+ const mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)");
15
+ return mediaQueryList.matches;
16
+ }, []);
17
+
13
18
  const prefersDarkModeStorage: boolean | null = localStorage.getItem("prefers-dark-mode") != null ? localStorage.getItem("prefers-dark-mode") === "true" : null;
14
19
  const prefersDarkMode = prefersDarkModeStorage ?? prefersDarkModeQuery;
15
20
  const [mode, setMode] = useState<"light" | "dark">(prefersDarkMode ? "dark" : "light");
@@ -23,7 +28,7 @@ export function useBuildModeController(): ModeController {
23
28
  const setDarkMode = useCallback(() => {
24
29
  setMode("dark");
25
30
  setDocumentMode("dark");
26
- }, [prefersDarkModeQuery]);
31
+ }, []);
27
32
 
28
33
  const setLightMode = useCallback(() => {
29
34
  setMode("light");
@@ -37,14 +42,15 @@ export function useBuildModeController(): ModeController {
37
42
 
38
43
  const toggleMode = useCallback(() => {
39
44
 
45
+ const prefersDarkModeQueryResult = prefersDarkModeQuery();
40
46
  if (mode === "light") {
41
- if (!prefersDarkModeQuery)
47
+ if (!prefersDarkModeQueryResult)
42
48
  localStorage.setItem("prefers-dark-mode", "true");
43
49
  else
44
50
  localStorage.removeItem("prefers-dark-mode");
45
51
  setDarkMode();
46
52
  } else {
47
- if (prefersDarkModeQuery)
53
+ if (prefersDarkModeQueryResult)
48
54
  localStorage.setItem("prefers-dark-mode", "false");
49
55
  else
50
56
  localStorage.removeItem("prefers-dark-mode");