@firecms/core 3.0.0-alpha.79 → 3.0.0-alpha.80

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
3
  "type": "module",
4
- "version": "3.0.0-alpha.79",
4
+ "version": "3.0.0-alpha.80",
5
5
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/firecmsco"
@@ -38,7 +38,7 @@
38
38
  "generateIcons": "ts-node --esm src/icons/generateIcons.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@firecms/ui": "^3.0.0-alpha.79",
41
+ "@firecms/ui": "^3.0.0-alpha.80",
42
42
  "@fontsource/ibm-plex-mono": "^5.0.8",
43
43
  "@fontsource/roboto": "^5.0.8",
44
44
  "@hello-pangea/dnd": "^16.5.0",
@@ -107,7 +107,7 @@
107
107
  "dist",
108
108
  "src"
109
109
  ],
110
- "gitHead": "f41d941643af2a0f25d15f5aa85d05b2ab65228c",
110
+ "gitHead": "60fbe594a5ad36fa5a47ba279ef3f55014fe823f",
111
111
  "publishConfig": {
112
112
  "access": "public"
113
113
  }
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useContext, useEffect, useMemo } from "react";
1
+ import React, { useCallback, useContext, useEffect, useMemo, useRef } from "react";
2
2
  import equal from "react-fast-compare";
3
3
  import {
4
4
  AdditionalFieldDelegate,
@@ -29,6 +29,7 @@ import { DateTimeFilterField } from "./filters/DateTimeFilterField";
29
29
  import { CustomFieldValidator } from "../../form/validation";
30
30
  import { renderSkeletonText } from "../../preview";
31
31
  import { propertiesToColumns } from "./column_utils";
32
+ import { useOutsideAlerter } from "@firecms/ui";
32
33
 
33
34
  const DEFAULT_STATE = {} as any;
34
35
 
@@ -114,6 +115,8 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
114
115
  textSearchLoading
115
116
  }: EntityCollectionTableProps<M>) {
116
117
 
118
+ const ref = useRef<HTMLDivElement>(null);
119
+
117
120
  const largeLayout = useLargeLayout();
118
121
  const disabledFilterChange = Boolean(forceFilter);
119
122
  const selectedEntities = selectionController?.selectedEntities?.length > 0 ? selectionController?.selectedEntities : highlightedEntities;
@@ -135,6 +138,14 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
135
138
  setItemCount?.(itemCount + pageSize);
136
139
  };
137
140
 
141
+ useOutsideAlerter(ref,
142
+ () => {
143
+ if (selectedCell) {
144
+ unselect();
145
+ }
146
+ },
147
+ Boolean(selectedCell));
148
+
138
149
  const resetPagination = useCallback(() => {
139
150
  setItemCount?.(pageSize);
140
151
  }, [pageSize]);
@@ -366,7 +377,8 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
366
377
  }}
367
378
  >
368
379
 
369
- <div className="h-full w-full flex flex-col bg-white dark:bg-gray-950">
380
+ <div ref={ref}
381
+ className="h-full w-full flex flex-col bg-white dark:bg-gray-950">
370
382
 
371
383
  <CollectionTableToolbar
372
384
  forceFilter={disabledFilterChange}
@@ -190,7 +190,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
190
190
  height,
191
191
  entity,
192
192
  cellRect,
193
- propertyKey: propertyKey as Extract<keyof M, string>,
193
+ propertyKey: propertyKey as Extract<keyof M, string>
194
194
  });
195
195
  }
196
196
  }, [entity, height, propertyKey, select, width]);
@@ -4,7 +4,7 @@ import useMeasure from "react-use-measure";
4
4
 
5
5
  import { VirtualTableSize } from "../../VirtualTable";
6
6
  import { getRowHeight } from "../../VirtualTable/common";
7
- import { useOutsideAlerter, cn, RemoveCircleIcon, Tooltip } from "@firecms/ui";
7
+ import { cn, RemoveCircleIcon, Tooltip } from "@firecms/ui";
8
8
  import { ErrorBoundary } from "../../../components";
9
9
 
10
10
  interface EntityTableCellProps {
@@ -90,13 +90,7 @@ export const EntityTableCell = React.memo<EntityTableCellProps>(
90
90
 
91
91
  const [measureRef, bounds] = useMeasure();
92
92
  const ref = useRef<HTMLDivElement>(null);
93
- useOutsideAlerter(ref, () => {
94
- if (selected && onSelect) {
95
- onSelect(undefined);
96
- }
97
- }, Boolean(selected && onSelect));
98
93
 
99
- const [isOverflowing, setIsOverflowing] = useState<boolean>(false);
100
94
  const maxHeight = useMemo(() => getRowHeight(size), [size]);
101
95
 
102
96
  const [onHover, setOnHover] = useState(false);
@@ -167,13 +161,12 @@ export const EntityTableCell = React.memo<EntityTableCellProps>(
167
161
  event.stopPropagation();
168
162
  }, [onSelectCallback]);
169
163
 
170
- useEffect(() => {
164
+ const isOverflowing = useMemo(() => {
171
165
  if (bounds) {
172
- const newOverflowingValue = bounds.height > maxHeight;
173
- if (isOverflowing !== newOverflowingValue)
174
- setIsOverflowing(newOverflowingValue);
166
+ return bounds.height > maxHeight;
175
167
  }
176
- }, [bounds, isOverflowing, maxHeight]);
168
+ return false;
169
+ }, [bounds, maxHeight]);
177
170
 
178
171
  const isSelected = !showError && selected;
179
172
 
@@ -247,17 +240,18 @@ export const EntityTableCell = React.memo<EntityTableCellProps>(
247
240
 
248
241
  </div>
249
242
  );
250
- }, (a, b) =>
251
- a.error === b.error &&
252
- a.value === b.value &&
253
- a.disabled === b.disabled &&
254
- a.saved === b.saved &&
255
- a.allowScroll === b.allowScroll &&
256
- a.align === b.align &&
257
- a.size === b.size &&
258
- a.disabledTooltip === b.disabledTooltip &&
259
- a.width === b.width &&
260
- a.showExpandIcon === b.showExpandIcon &&
261
- a.removePadding === b.removePadding &&
262
- a.fullHeight === b.fullHeight &&
263
- a.selected === b.selected) as React.FunctionComponent<EntityTableCellProps>;
243
+ }, (a, b) => {
244
+ return a.error === b.error &&
245
+ a.value === b.value &&
246
+ a.disabled === b.disabled &&
247
+ a.saved === b.saved &&
248
+ a.allowScroll === b.allowScroll &&
249
+ a.align === b.align &&
250
+ a.size === b.size &&
251
+ a.disabledTooltip === b.disabledTooltip &&
252
+ a.width === b.width &&
253
+ a.showExpandIcon === b.showExpandIcon &&
254
+ a.removePadding === b.removePadding &&
255
+ a.fullHeight === b.fullHeight &&
256
+ a.selected === b.selected;
257
+ }) as React.FunctionComponent<EntityTableCellProps>;
@@ -1,5 +1,7 @@
1
1
  import { useEffect, useState } from "react";
2
2
 
3
+ type LayoutListener = (isLargeLayout: boolean) => void;
4
+
3
5
  const breakpoints = {
4
6
  xs: 0,
5
7
  sm: 640,
@@ -9,26 +11,87 @@ const breakpoints = {
9
11
  "2xl": 1536,
10
12
  "3xl": 1920
11
13
  }
12
- export const useLargeLayout = (breakpoint: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" = "lg"): boolean => {
13
- const [isLargeLayout, setIsLargeLayout] = useState<boolean>(false);
14
+
15
+ // Global state and listeners array
16
+ let isLargeLayoutGlobal = checkLargeLayout("lg"); // Default value
17
+ const listeners: LayoutListener[] = [];
18
+
19
+ // Utility to notify all listeners
20
+ const notifyListeners = () => {
21
+ listeners.forEach(listener => listener(isLargeLayoutGlobal));
22
+ };
23
+
24
+ // Listen to resize events once, at a global level
25
+ window.addEventListener("resize", () => {
26
+ const newIsLargeLayout = checkLargeLayout("lg");
27
+ if (newIsLargeLayout !== isLargeLayoutGlobal) {
28
+ isLargeLayoutGlobal = newIsLargeLayout;
29
+ notifyListeners();
30
+ }
31
+ });
32
+
33
+ export const useLargeLayout = () => {
34
+ const [isLargeLayout, setIsLargeLayout] = useState(isLargeLayoutGlobal);
14
35
 
15
36
  useEffect(() => {
16
- const handleResize = () => {
17
- const matched = window.matchMedia(`(min-width: ${breakpoints[breakpoint] + 1}px)`).matches;
18
- setIsLargeLayout(matched);
37
+ // Listener function to update component state
38
+ const listener: LayoutListener = (newIsLargeLayout) => {
39
+ setIsLargeLayout(newIsLargeLayout);
19
40
  };
20
41
 
21
- // Set initial state
22
- handleResize();
42
+ // Register listener
43
+ listeners.push(listener);
23
44
 
24
- // Set up event listener for resize events
25
- window.addEventListener("resize", handleResize);
45
+ // Initial state
46
+ setIsLargeLayout(isLargeLayoutGlobal);
26
47
 
27
- // Clean up event listener when component unmounts
48
+ // Clean up by removing the listener
28
49
  return () => {
29
- window.removeEventListener("resize", handleResize);
50
+ const index = listeners.indexOf(listener);
51
+ if (index > -1) {
52
+ listeners.splice(index, 1);
53
+ }
30
54
  };
31
55
  }, []);
32
56
 
33
57
  return isLargeLayout;
34
58
  };
59
+
60
+ function checkLargeLayout(breakpoint: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" = "lg"): boolean {
61
+ return window.matchMedia(`(min-width: ${breakpoints[breakpoint] + 1}px)`).matches;
62
+ }
63
+
64
+ // import { useEffect, useState } from "react";
65
+ //
66
+ // const breakpoints = {
67
+ // xs: 0,
68
+ // sm: 640,
69
+ // md: 768,
70
+ // lg: 1024,
71
+ // xl: 1280,
72
+ // "2xl": 1536,
73
+ // "3xl": 1920
74
+ // }
75
+ // export const useLargeLayout = (breakpoint: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" = "lg"): boolean => {
76
+ // const [isLargeLayout, setIsLargeLayout] = useState<boolean>(false);
77
+ //
78
+ // useEffect(() => {
79
+ // const handleResize = () => {
80
+ // const matched = window.matchMedia(`(min-width: ${breakpoints[breakpoint] + 1}px)`).matches;
81
+ // setIsLargeLayout(matched);
82
+ // };
83
+ //
84
+ // // Set initial state
85
+ // handleResize();
86
+ //
87
+ // // Set up event listener for resize events
88
+ // window.addEventListener("resize", handleResize);
89
+ //
90
+ // // Clean up event listener when component unmounts
91
+ // return () => {
92
+ // window.removeEventListener("resize", handleResize);
93
+ // };
94
+ // }, []);
95
+ //
96
+ // return isLargeLayout;
97
+ // };
@@ -4,6 +4,7 @@ import { SideDialogPanelProps, SideDialogsController } from "../types";
4
4
  import equal from "react-fast-compare"
5
5
 
6
6
  export function useBuildSideDialogsController(): SideDialogsController {
7
+ console.log("useBuildSideDialogsController");
7
8
 
8
9
  const location = useLocation();
9
10
  const navigate = useNavigate();