-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.tsx
More file actions
74 lines (67 loc) · 1.57 KB
/
index.tsx
File metadata and controls
74 lines (67 loc) · 1.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import { ReactNode, useMemo } from "react";
import { useSlashID } from "../../hooks/use-slash-id";
type Props = {
belongsTo: string | ((groups: string[]) => boolean);
children: ReactNode;
};
/**
* Conditional rendering helper.
*
* Use this component where some content should be shown only to users belonging to one or more specific groups.
*
* @param belongsTo group name or predicate function - the predicate function is called with a list of group names that the user belongs to.
*
* @example
* User belongs to group "admin"
* ```tsx
* <Groups
* belongsTo="admin"
* >
* ...
* </Groups>
* ```
*
* @example
* User belongs to either "admin" or "user"
* ```tsx
* <Groups
* belongsTo={Groups.some("admin", "user")}
* >
* ...
* </Groups>
* ```
*
* @example
* User belongs to both "admin" and "user"
* ```tsx
* <Groups
* belongsTo={Groups.all("admin", "user")}
* >
* ...
* </Groups>
* ```
*/
export const Groups = ({ belongsTo, children }: Props) => {
const { user } = useSlashID();
const shouldRender = useMemo(() => {
if (!user) {
return false;
}
const groups = user.getGroups();
return typeof belongsTo === "string"
? groups.includes(belongsTo)
: belongsTo(groups);
}, [user, belongsTo]);
if (!shouldRender) {
return null;
}
return <>{children}</>;
};
Groups.some =
(...groups: string[]) =>
(userGroups: string[]) =>
groups.some((group) => userGroups.includes(group));
Groups.all =
(...groups: string[]) =>
(userGroups: string[]) =>
groups.every((group) => userGroups.includes(group));