@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/dist/hooks/useLargeLayout.d.ts +1 -1
- package/dist/index.es.js +2570 -2553
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +5 -5
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +14 -2
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +20 -26
- package/src/hooks/useLargeLayout.tsx +74 -11
- package/src/internal/useBuildSideDialogsController.tsx +1 -0
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.
|
|
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.
|
|
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": "
|
|
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
|
|
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 {
|
|
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
|
-
|
|
164
|
+
const isOverflowing = useMemo(() => {
|
|
171
165
|
if (bounds) {
|
|
172
|
-
|
|
173
|
-
if (isOverflowing !== newOverflowingValue)
|
|
174
|
-
setIsOverflowing(newOverflowingValue);
|
|
166
|
+
return bounds.height > maxHeight;
|
|
175
167
|
}
|
|
176
|
-
|
|
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
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
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
|
-
|
|
13
|
-
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
setIsLargeLayout(
|
|
37
|
+
// Listener function to update component state
|
|
38
|
+
const listener: LayoutListener = (newIsLargeLayout) => {
|
|
39
|
+
setIsLargeLayout(newIsLargeLayout);
|
|
19
40
|
};
|
|
20
41
|
|
|
21
|
-
//
|
|
22
|
-
|
|
42
|
+
// Register listener
|
|
43
|
+
listeners.push(listener);
|
|
23
44
|
|
|
24
|
-
//
|
|
25
|
-
|
|
45
|
+
// Initial state
|
|
46
|
+
setIsLargeLayout(isLargeLayoutGlobal);
|
|
26
47
|
|
|
27
|
-
// Clean up
|
|
48
|
+
// Clean up by removing the listener
|
|
28
49
|
return () => {
|
|
29
|
-
|
|
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();
|