@workos-inc/widgets 0.0.0-pre.1 → 0.0.0-pre.2
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/cjs/lib/api/role.d.ts.map +1 -1
- package/dist/cjs/lib/api/role.js +35 -14
- package/dist/cjs/lib/api/role.js.map +1 -1
- package/dist/cjs/lib/api/user.d.ts.map +1 -1
- package/dist/cjs/lib/api/user.js +105 -67
- package/dist/cjs/lib/api/user.js.map +1 -1
- package/dist/cjs/lib/constants.d.ts +2 -1
- package/dist/cjs/lib/constants.d.ts.map +1 -1
- package/dist/cjs/lib/constants.js +3 -2
- package/dist/cjs/lib/constants.js.map +1 -1
- package/dist/cjs/lib/delete-user-dialog.d.ts.map +1 -1
- package/dist/cjs/lib/delete-user-dialog.js +1 -1
- package/dist/cjs/lib/delete-user-dialog.js.map +1 -1
- package/dist/cjs/lib/edit-user-details-dialog.d.ts.map +1 -1
- package/dist/cjs/lib/edit-user-details-dialog.js +3 -5
- package/dist/cjs/lib/edit-user-details-dialog.js.map +1 -1
- package/dist/cjs/lib/elements.d.ts +21 -12
- package/dist/cjs/lib/elements.d.ts.map +1 -1
- package/dist/cjs/lib/elements.js +118 -30
- package/dist/cjs/lib/elements.js.map +1 -1
- package/dist/cjs/lib/error-boundary.d.ts +58 -0
- package/dist/cjs/lib/error-boundary.d.ts.map +1 -0
- package/dist/cjs/lib/error-boundary.js +113 -0
- package/dist/cjs/lib/error-boundary.js.map +1 -0
- package/dist/cjs/lib/errors.d.ts +34 -0
- package/dist/cjs/lib/errors.d.ts.map +1 -0
- package/dist/cjs/lib/errors.js +40 -0
- package/dist/cjs/lib/errors.js.map +1 -0
- package/dist/cjs/lib/invite-user-dialog.d.ts.map +1 -1
- package/dist/cjs/lib/invite-user-dialog.js +2 -2
- package/dist/cjs/lib/invite-user-dialog.js.map +1 -1
- package/dist/cjs/lib/resend-invite-dialog.d.ts.map +1 -1
- package/dist/cjs/lib/resend-invite-dialog.js +2 -2
- package/dist/cjs/lib/resend-invite-dialog.js.map +1 -1
- package/dist/cjs/lib/revoke-invite-dialog.d.ts.map +1 -1
- package/dist/cjs/lib/revoke-invite-dialog.js +1 -1
- package/dist/cjs/lib/revoke-invite-dialog.js.map +1 -1
- package/dist/cjs/lib/use-layout-effect.d.ts +4 -0
- package/dist/cjs/lib/use-layout-effect.d.ts.map +1 -0
- package/dist/cjs/lib/use-layout-effect.js +8 -0
- package/dist/cjs/lib/use-layout-effect.js.map +1 -0
- package/dist/cjs/lib/user-actions-dropdown.d.ts.map +1 -1
- package/dist/cjs/lib/user-actions-dropdown.js +2 -9
- package/dist/cjs/lib/user-actions-dropdown.js.map +1 -1
- package/dist/cjs/lib/users-filter.d.ts +1 -0
- package/dist/cjs/lib/users-filter.d.ts.map +1 -1
- package/dist/cjs/lib/users-filter.js +2 -9
- package/dist/cjs/lib/users-filter.js.map +1 -1
- package/dist/cjs/lib/users-management-context.d.ts +2 -2
- package/dist/cjs/lib/users-management-context.d.ts.map +1 -1
- package/dist/cjs/lib/users-management.d.ts +9 -6
- package/dist/cjs/lib/users-management.d.ts.map +1 -1
- package/dist/cjs/lib/users-management.js +77 -20
- package/dist/cjs/lib/users-management.js.map +1 -1
- package/dist/cjs/lib/users-search.d.ts.map +1 -1
- package/dist/cjs/lib/users-search.js +3 -9
- package/dist/cjs/lib/users-search.js.map +1 -1
- package/dist/cjs/lib/utils.d.ts +2 -0
- package/dist/cjs/lib/utils.d.ts.map +1 -1
- package/dist/cjs/lib/utils.js +18 -0
- package/dist/cjs/lib/utils.js.map +1 -1
- package/dist/cjs/users-management.client.d.ts +1 -1
- package/dist/cjs/users-management.client.d.ts.map +1 -1
- package/dist/cjs/users-management.client.js +15 -5
- package/dist/cjs/users-management.client.js.map +1 -1
- package/dist/cjs/workos-widgets.client.d.ts.map +1 -1
- package/dist/cjs/workos-widgets.client.js +2 -1
- package/dist/cjs/workos-widgets.client.js.map +1 -1
- package/dist/esm/lib/api/role.d.ts.map +1 -1
- package/dist/esm/lib/api/role.js +35 -14
- package/dist/esm/lib/api/role.js.map +1 -1
- package/dist/esm/lib/api/user.d.ts.map +1 -1
- package/dist/esm/lib/api/user.js +105 -67
- package/dist/esm/lib/api/user.js.map +1 -1
- package/dist/esm/lib/constants.d.ts +2 -1
- package/dist/esm/lib/constants.d.ts.map +1 -1
- package/dist/esm/lib/constants.js +2 -1
- package/dist/esm/lib/constants.js.map +1 -1
- package/dist/esm/lib/delete-user-dialog.d.ts.map +1 -1
- package/dist/esm/lib/delete-user-dialog.js +2 -2
- package/dist/esm/lib/delete-user-dialog.js.map +1 -1
- package/dist/esm/lib/edit-user-details-dialog.d.ts.map +1 -1
- package/dist/esm/lib/edit-user-details-dialog.js +4 -6
- package/dist/esm/lib/edit-user-details-dialog.js.map +1 -1
- package/dist/esm/lib/elements.d.ts +21 -12
- package/dist/esm/lib/elements.d.ts.map +1 -1
- package/dist/esm/lib/elements.js +95 -30
- package/dist/esm/lib/elements.js.map +1 -1
- package/dist/esm/lib/error-boundary.d.ts +58 -0
- package/dist/esm/lib/error-boundary.d.ts.map +1 -0
- package/dist/esm/lib/error-boundary.js +86 -0
- package/dist/esm/lib/error-boundary.js.map +1 -0
- package/dist/esm/lib/errors.d.ts +34 -0
- package/dist/esm/lib/errors.d.ts.map +1 -0
- package/dist/esm/lib/errors.js +34 -0
- package/dist/esm/lib/errors.js.map +1 -0
- package/dist/esm/lib/invite-user-dialog.d.ts.map +1 -1
- package/dist/esm/lib/invite-user-dialog.js +3 -3
- package/dist/esm/lib/invite-user-dialog.js.map +1 -1
- package/dist/esm/lib/resend-invite-dialog.d.ts.map +1 -1
- package/dist/esm/lib/resend-invite-dialog.js +3 -3
- package/dist/esm/lib/resend-invite-dialog.js.map +1 -1
- package/dist/esm/lib/revoke-invite-dialog.d.ts.map +1 -1
- package/dist/esm/lib/revoke-invite-dialog.js +2 -2
- package/dist/esm/lib/revoke-invite-dialog.js.map +1 -1
- package/dist/esm/lib/use-layout-effect.d.ts +4 -0
- package/dist/esm/lib/use-layout-effect.d.ts.map +1 -0
- package/dist/esm/lib/use-layout-effect.js +5 -0
- package/dist/esm/lib/use-layout-effect.js.map +1 -0
- package/dist/esm/lib/user-actions-dropdown.d.ts.map +1 -1
- package/dist/esm/lib/user-actions-dropdown.js +3 -10
- package/dist/esm/lib/user-actions-dropdown.js.map +1 -1
- package/dist/esm/lib/users-filter.d.ts +1 -0
- package/dist/esm/lib/users-filter.d.ts.map +1 -1
- package/dist/esm/lib/users-filter.js +4 -11
- package/dist/esm/lib/users-filter.js.map +1 -1
- package/dist/esm/lib/users-management-context.d.ts +2 -2
- package/dist/esm/lib/users-management-context.d.ts.map +1 -1
- package/dist/esm/lib/users-management.d.ts +9 -6
- package/dist/esm/lib/users-management.d.ts.map +1 -1
- package/dist/esm/lib/users-management.js +74 -22
- package/dist/esm/lib/users-management.js.map +1 -1
- package/dist/esm/lib/users-search.d.ts.map +1 -1
- package/dist/esm/lib/users-search.js +5 -11
- package/dist/esm/lib/users-search.js.map +1 -1
- package/dist/esm/lib/utils.d.ts +2 -0
- package/dist/esm/lib/utils.d.ts.map +1 -1
- package/dist/esm/lib/utils.js +13 -0
- package/dist/esm/lib/utils.js.map +1 -1
- package/dist/esm/users-management.client.d.ts +1 -1
- package/dist/esm/users-management.client.d.ts.map +1 -1
- package/dist/esm/users-management.client.js +16 -6
- package/dist/esm/users-management.client.js.map +1 -1
- package/dist/esm/workos-widgets.client.d.ts.map +1 -1
- package/dist/esm/workos-widgets.client.js +2 -1
- package/dist/esm/workos-widgets.client.js.map +1 -1
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +8 -3
- package/src/base.css +111 -0
- package/src/lib/api/role.ts +39 -16
- package/src/lib/api/user.ts +119 -75
- package/src/lib/constants.ts +2 -1
- package/src/lib/delete-user-dialog.tsx +7 -3
- package/src/lib/edit-user-details-dialog.tsx +15 -10
- package/src/lib/elements.tsx +242 -61
- package/src/lib/error-boundary.tsx +166 -0
- package/src/lib/errors.ts +49 -0
- package/src/lib/invite-user-dialog.tsx +21 -12
- package/src/lib/resend-invite-dialog.tsx +11 -5
- package/src/lib/revoke-invite-dialog.tsx +7 -3
- package/src/lib/use-layout-effect.ts +6 -0
- package/src/lib/user-actions-dropdown.tsx +8 -16
- package/src/lib/users-filter.tsx +13 -73
- package/src/lib/users-management-context.tsx +1 -1
- package/src/lib/users-management.tsx +345 -184
- package/src/lib/users-search.tsx +5 -63
- package/src/lib/utils.ts +21 -0
- package/src/users-management.client.tsx +39 -16
- package/src/users-management.css +4 -0
- package/src/workos-widgets.client.tsx +2 -1
- package/dist/cjs/lib/pagination.d.ts +0 -8
- package/dist/cjs/lib/pagination.d.ts.map +0 -1
- package/dist/cjs/lib/pagination.js +0 -67
- package/dist/cjs/lib/pagination.js.map +0 -1
- package/dist/esm/lib/pagination.d.ts +0 -8
- package/dist/esm/lib/pagination.d.ts.map +0 -1
- package/dist/esm/lib/pagination.js +0 -40
- package/dist/esm/lib/pagination.js.map +0 -1
- package/src/lib/pagination.tsx +0 -69
package/src/lib/elements.tsx
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
+
import * as React from "react";
|
|
3
4
|
import {
|
|
4
|
-
Button,
|
|
5
|
-
DropdownMenu,
|
|
5
|
+
Button as RadixButton,
|
|
6
|
+
DropdownMenu as RadixDropdownMenu,
|
|
6
7
|
Avatar as RadixAvatar,
|
|
7
8
|
AvatarProps as RadixAvatarProps,
|
|
9
|
+
AlertDialog as RadixAlertDialog,
|
|
10
|
+
Dialog as RadixDialog,
|
|
8
11
|
Badge as RadixBadge,
|
|
9
12
|
IconButton as RadixIconButton,
|
|
13
|
+
Select as RadixSelect,
|
|
10
14
|
TextField as RadixTextField,
|
|
11
15
|
} from "@radix-ui/themes";
|
|
12
16
|
import type {
|
|
@@ -14,60 +18,76 @@ import type {
|
|
|
14
18
|
avatarPropDefs,
|
|
15
19
|
badgePropDefs,
|
|
16
20
|
buttonPropDefs,
|
|
21
|
+
dialogContentPropDefs,
|
|
17
22
|
dropdownMenuContentPropDefs,
|
|
18
23
|
dropdownMenuItemPropDefs,
|
|
19
24
|
iconButtonPropDefs,
|
|
20
25
|
textFieldRootPropDefs,
|
|
26
|
+
selectTriggerPropDefs,
|
|
21
27
|
} from "@radix-ui/themes/props";
|
|
22
|
-
import { type ComponentPropsWithoutRef, forwardRef } from "react";
|
|
23
28
|
import { useElement } from "./widgets-context";
|
|
29
|
+
import { cx, namespaceClassName } from "./utils";
|
|
30
|
+
import { useLayoutEffect } from "./use-layout-effect";
|
|
24
31
|
|
|
25
|
-
export const PrimaryButton = forwardRef<
|
|
32
|
+
export const PrimaryButton = React.forwardRef<
|
|
26
33
|
HTMLButtonElement,
|
|
27
|
-
ComponentPropsWithoutRef<typeof
|
|
28
|
-
>((props, ref)
|
|
34
|
+
React.ComponentPropsWithoutRef<typeof RadixButton>
|
|
35
|
+
>(function PrimaryButton({ className, ...props }, ref) {
|
|
29
36
|
const element = useElement("primaryButton");
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
return (
|
|
38
|
+
<RadixButton
|
|
39
|
+
ref={ref}
|
|
40
|
+
className={cx("button", className)}
|
|
41
|
+
variant="solid"
|
|
42
|
+
{...props}
|
|
43
|
+
{...element}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
32
46
|
});
|
|
33
47
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
export const SecondaryButton = forwardRef<
|
|
48
|
+
export const SecondaryButton = React.forwardRef<
|
|
37
49
|
HTMLButtonElement,
|
|
38
|
-
ComponentPropsWithoutRef<typeof
|
|
39
|
-
>((props, ref)
|
|
50
|
+
React.ComponentPropsWithoutRef<typeof RadixButton>
|
|
51
|
+
>(function SecondaryButton({ className, ...props }, ref) {
|
|
40
52
|
const element = useElement("secondaryButton");
|
|
41
|
-
|
|
42
53
|
return (
|
|
43
|
-
<
|
|
54
|
+
<RadixButton
|
|
55
|
+
ref={ref}
|
|
56
|
+
className={cx(["button", "button--secondary"], className)}
|
|
57
|
+
variant="surface"
|
|
58
|
+
color="gray"
|
|
59
|
+
{...props}
|
|
60
|
+
{...element}
|
|
61
|
+
/>
|
|
44
62
|
);
|
|
45
63
|
});
|
|
46
64
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
export const DestructiveButton = forwardRef<
|
|
65
|
+
export const DestructiveButton = React.forwardRef<
|
|
50
66
|
HTMLButtonElement,
|
|
51
|
-
ComponentPropsWithoutRef<typeof
|
|
52
|
-
>((props, ref)
|
|
67
|
+
React.ComponentPropsWithoutRef<typeof RadixButton>
|
|
68
|
+
>(function DestructiveButton({ className, ...props }, ref) {
|
|
53
69
|
const element = useElement("destructiveButton");
|
|
54
|
-
|
|
55
70
|
return (
|
|
56
|
-
<
|
|
71
|
+
<RadixButton
|
|
72
|
+
ref={ref}
|
|
73
|
+
className={cx(["button", "button--destructive"], className)}
|
|
74
|
+
variant="solid"
|
|
75
|
+
color="red"
|
|
76
|
+
{...props}
|
|
77
|
+
{...element}
|
|
78
|
+
/>
|
|
57
79
|
);
|
|
58
80
|
});
|
|
59
81
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
export const IconButton = forwardRef<
|
|
82
|
+
export const IconButton = React.forwardRef<
|
|
63
83
|
HTMLButtonElement,
|
|
64
|
-
ComponentPropsWithoutRef<typeof RadixIconButton>
|
|
65
|
-
>((props, ref)
|
|
84
|
+
React.ComponentPropsWithoutRef<typeof RadixIconButton>
|
|
85
|
+
>(function IconButton({ className, ...props }, ref) {
|
|
66
86
|
const element = useElement("iconButton");
|
|
67
|
-
|
|
68
87
|
return (
|
|
69
88
|
<RadixIconButton
|
|
70
89
|
ref={ref}
|
|
90
|
+
className={cx(["button", "icon-button"], className)}
|
|
71
91
|
variant="ghost"
|
|
72
92
|
color="gray"
|
|
73
93
|
{...props}
|
|
@@ -76,74 +96,153 @@ export const IconButton = forwardRef<
|
|
|
76
96
|
);
|
|
77
97
|
});
|
|
78
98
|
|
|
79
|
-
|
|
99
|
+
export const SelectTrigger = React.forwardRef<
|
|
100
|
+
HTMLButtonElement,
|
|
101
|
+
React.ComponentPropsWithoutRef<typeof RadixSelect.Trigger>
|
|
102
|
+
>(function SelectTrigger({ className, ...props }, ref) {
|
|
103
|
+
const element = useElement("select");
|
|
104
|
+
return (
|
|
105
|
+
<RadixSelect.Trigger
|
|
106
|
+
ref={ref}
|
|
107
|
+
className={cx("select", className)}
|
|
108
|
+
{...props}
|
|
109
|
+
{...element}
|
|
110
|
+
/>
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
export const SelectContent = React.forwardRef<
|
|
115
|
+
HTMLDivElement,
|
|
116
|
+
React.ComponentPropsWithoutRef<typeof RadixSelect.Content>
|
|
117
|
+
>(function SelectContent({ className, ...props }, ref) {
|
|
118
|
+
const element = useElement("dropdown");
|
|
119
|
+
return (
|
|
120
|
+
<RadixSelect.Content
|
|
121
|
+
ref={ref}
|
|
122
|
+
className={cx(["dropdown", "select-dropdown"], className)}
|
|
123
|
+
{...props}
|
|
124
|
+
{...element}
|
|
125
|
+
/>
|
|
126
|
+
);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
export const SelectItem = React.forwardRef<
|
|
130
|
+
HTMLDivElement,
|
|
131
|
+
React.ComponentPropsWithoutRef<typeof RadixSelect.Item>
|
|
132
|
+
>(function SelectItem({ className, ...props }, ref) {
|
|
133
|
+
const element = useElement("primaryMenuItem");
|
|
134
|
+
return (
|
|
135
|
+
<RadixSelect.Item
|
|
136
|
+
ref={ref}
|
|
137
|
+
className={cx(["menu-item", "select-item"], className)}
|
|
138
|
+
{...props}
|
|
139
|
+
{...element}
|
|
140
|
+
/>
|
|
141
|
+
);
|
|
142
|
+
});
|
|
80
143
|
|
|
81
|
-
export const TextField = forwardRef<
|
|
144
|
+
export const TextField = React.forwardRef<
|
|
82
145
|
HTMLInputElement,
|
|
83
|
-
ComponentPropsWithoutRef<typeof RadixTextField.Root>
|
|
84
|
-
>((props, ref)
|
|
146
|
+
React.ComponentPropsWithoutRef<typeof RadixTextField.Root>
|
|
147
|
+
>(function TextField({ className, ...props }, ref) {
|
|
85
148
|
const element = useElement("textfield");
|
|
86
|
-
|
|
87
149
|
return (
|
|
88
150
|
<RadixTextField.Root
|
|
89
|
-
data-1p-ignore
|
|
90
151
|
ref={ref}
|
|
91
152
|
variant="surface"
|
|
153
|
+
className={cx("text-field", className)}
|
|
92
154
|
{...props}
|
|
93
155
|
{...element}
|
|
94
156
|
/>
|
|
95
157
|
);
|
|
96
158
|
});
|
|
97
159
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
160
|
+
export const TextFieldSlot = React.forwardRef<
|
|
161
|
+
HTMLDivElement,
|
|
162
|
+
React.ComponentPropsWithoutRef<typeof RadixTextField.Slot>
|
|
163
|
+
>(function TextFieldSlot({ className, ...props }, ref) {
|
|
164
|
+
return (
|
|
165
|
+
<RadixTextField.Slot
|
|
166
|
+
ref={ref}
|
|
167
|
+
className={cx("text-field-slot", className)}
|
|
168
|
+
{...props}
|
|
169
|
+
/>
|
|
170
|
+
);
|
|
171
|
+
});
|
|
101
172
|
|
|
102
|
-
export const Badge = forwardRef<
|
|
173
|
+
export const Badge = React.forwardRef<
|
|
103
174
|
HTMLSpanElement,
|
|
104
|
-
ComponentPropsWithoutRef<typeof RadixBadge>
|
|
105
|
-
>((props, ref)
|
|
175
|
+
React.ComponentPropsWithoutRef<typeof RadixBadge>
|
|
176
|
+
>(function Badge({ className, ...props }, ref) {
|
|
106
177
|
const element = useElement("badge");
|
|
107
|
-
|
|
108
|
-
|
|
178
|
+
return (
|
|
179
|
+
<RadixBadge
|
|
180
|
+
ref={ref}
|
|
181
|
+
className={cx("badge", className)}
|
|
182
|
+
{...element}
|
|
183
|
+
{...props}
|
|
184
|
+
/>
|
|
185
|
+
);
|
|
109
186
|
});
|
|
110
187
|
|
|
111
|
-
|
|
188
|
+
export const DropdownMenuContent = React.forwardRef<
|
|
189
|
+
HTMLDivElement,
|
|
190
|
+
React.ComponentPropsWithoutRef<typeof RadixDropdownMenu.Content>
|
|
191
|
+
>(function DropdownMenuContent({ className, ...props }, ref) {
|
|
192
|
+
const element = useElement("dropdown");
|
|
193
|
+
return (
|
|
194
|
+
<RadixDropdownMenu.Content
|
|
195
|
+
ref={ref}
|
|
196
|
+
className={cx("dropdown", className)}
|
|
197
|
+
{...props}
|
|
198
|
+
{...element}
|
|
199
|
+
/>
|
|
200
|
+
);
|
|
201
|
+
});
|
|
112
202
|
|
|
113
|
-
export const PrimaryMenuItem = forwardRef<
|
|
203
|
+
export const PrimaryMenuItem = React.forwardRef<
|
|
114
204
|
HTMLDivElement,
|
|
115
|
-
ComponentPropsWithoutRef<typeof
|
|
116
|
-
>((props, ref)
|
|
205
|
+
React.ComponentPropsWithoutRef<typeof RadixDropdownMenu.Item>
|
|
206
|
+
>(function PrimaryMenuItem({ className, ...props }, ref) {
|
|
117
207
|
const element = useElement("primaryMenuItem");
|
|
118
|
-
|
|
119
|
-
|
|
208
|
+
return (
|
|
209
|
+
<RadixDropdownMenu.Item
|
|
210
|
+
ref={ref}
|
|
211
|
+
className={cx("menu-item", className)}
|
|
212
|
+
{...props}
|
|
213
|
+
{...element}
|
|
214
|
+
/>
|
|
215
|
+
);
|
|
120
216
|
});
|
|
121
217
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
export const DestructiveMenuItem = forwardRef<
|
|
218
|
+
export const DestructiveMenuItem = React.forwardRef<
|
|
125
219
|
HTMLDivElement,
|
|
126
|
-
ComponentPropsWithoutRef<typeof
|
|
127
|
-
>((props, ref)
|
|
220
|
+
React.ComponentPropsWithoutRef<typeof RadixDropdownMenu.Item>
|
|
221
|
+
>(function DestructiveMenuItem({ className, ...props }, ref) {
|
|
128
222
|
const element = useElement("destructiveMenuItem");
|
|
129
|
-
|
|
130
|
-
|
|
223
|
+
return (
|
|
224
|
+
<RadixDropdownMenu.Item
|
|
225
|
+
ref={ref}
|
|
226
|
+
className={cx(["menu-item", "menu-item--destructive"], className)}
|
|
227
|
+
color="red"
|
|
228
|
+
{...props}
|
|
229
|
+
{...element}
|
|
230
|
+
/>
|
|
231
|
+
);
|
|
131
232
|
});
|
|
132
233
|
|
|
133
|
-
DestructiveMenuItem.displayName = "DestructiveMenuItem";
|
|
134
|
-
|
|
135
234
|
interface AvatarProps extends RadixAvatarProps {
|
|
136
235
|
dim?: boolean;
|
|
137
236
|
}
|
|
138
237
|
|
|
139
|
-
export const Avatar = forwardRef<HTMLImageElement, AvatarProps>(
|
|
140
|
-
({ dim, ...props }, ref)
|
|
238
|
+
export const Avatar = React.forwardRef<HTMLImageElement, AvatarProps>(
|
|
239
|
+
function Avatar({ dim, className, ...props }, ref) {
|
|
141
240
|
const element = useElement("avatar");
|
|
142
|
-
|
|
143
241
|
return (
|
|
144
242
|
<RadixAvatar
|
|
145
243
|
ref={ref}
|
|
146
244
|
color="gray"
|
|
245
|
+
className={cx("avatar", className)}
|
|
147
246
|
{...props}
|
|
148
247
|
{...element}
|
|
149
248
|
// TODO: use CSS var instead of hard-coded value for opacity
|
|
@@ -153,7 +252,87 @@ export const Avatar = forwardRef<HTMLImageElement, AvatarProps>(
|
|
|
153
252
|
},
|
|
154
253
|
);
|
|
155
254
|
|
|
156
|
-
|
|
255
|
+
export const DialogContent = React.forwardRef<
|
|
256
|
+
HTMLDivElement,
|
|
257
|
+
React.ComponentPropsWithoutRef<typeof RadixDialog.Content>
|
|
258
|
+
>(function DialogContent({ className, ...props }, forwardedRef) {
|
|
259
|
+
const element = useElement("dialog");
|
|
260
|
+
const [node, setNode] = React.useState<HTMLDivElement | null>(null);
|
|
261
|
+
const ref = useComposedRefs(forwardedRef, setNode as any);
|
|
262
|
+
useDialogOverlayHack(node, {
|
|
263
|
+
className: namespaceClassName("dialog-overlay"),
|
|
264
|
+
selector: ".rt-DialogOverlay",
|
|
265
|
+
});
|
|
266
|
+
return (
|
|
267
|
+
<RadixDialog.Content
|
|
268
|
+
ref={ref}
|
|
269
|
+
className={cx("dialog", className)}
|
|
270
|
+
{...props}
|
|
271
|
+
{...element}
|
|
272
|
+
/>
|
|
273
|
+
);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
export const AlertDialogContent = React.forwardRef<
|
|
277
|
+
HTMLDivElement,
|
|
278
|
+
React.ComponentPropsWithoutRef<typeof RadixAlertDialog.Content>
|
|
279
|
+
>(function AlertDialogContent({ className, ...props }, forwardedRef) {
|
|
280
|
+
const element = useElement("dialog");
|
|
281
|
+
const [node, setNode] = React.useState<HTMLDivElement | null>(null);
|
|
282
|
+
const ref = useComposedRefs(forwardedRef, setNode as any);
|
|
283
|
+
useDialogOverlayHack(node, {
|
|
284
|
+
className: namespaceClassName("dialog-overlay"),
|
|
285
|
+
selector: ".rt-AlertDialogOverlay",
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
return (
|
|
289
|
+
<RadixAlertDialog.Content
|
|
290
|
+
ref={ref}
|
|
291
|
+
className={cx("dialog", className)}
|
|
292
|
+
{...props}
|
|
293
|
+
{...element}
|
|
294
|
+
/>
|
|
295
|
+
);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* HACK: Radix themes does not expose the dialog overlay, but we want consumer
|
|
300
|
+
* to be able to style it with a classname. This will add a classname to the
|
|
301
|
+
* overlay when the dialog content is mounted.
|
|
302
|
+
*/
|
|
303
|
+
function useDialogOverlayHack(
|
|
304
|
+
node: HTMLDivElement | null,
|
|
305
|
+
{ className, selector }: { className: string; selector: string },
|
|
306
|
+
) {
|
|
307
|
+
useLayoutEffect(() => {
|
|
308
|
+
if (!node) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
const document = node.ownerDocument;
|
|
312
|
+
const overlay = document.querySelector<HTMLDivElement>(selector);
|
|
313
|
+
overlay?.classList.add(className);
|
|
314
|
+
}, [node, className, selector]);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function useComposedRefs<T>(...refs: Array<React.Ref<T>>) {
|
|
318
|
+
return React.useCallback(
|
|
319
|
+
(value: T) => {
|
|
320
|
+
for (const ref of refs) {
|
|
321
|
+
if (typeof ref === "function") {
|
|
322
|
+
ref(value);
|
|
323
|
+
} else if (ref != null) {
|
|
324
|
+
try {
|
|
325
|
+
(ref as React.MutableRefObject<T | null>).current = value;
|
|
326
|
+
} catch {
|
|
327
|
+
//
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
333
|
+
refs,
|
|
334
|
+
);
|
|
335
|
+
}
|
|
157
336
|
|
|
158
337
|
type OmitAsChild<T> = {
|
|
159
338
|
[K in keyof T]: T[K] extends undefined
|
|
@@ -162,11 +341,13 @@ type OmitAsChild<T> = {
|
|
|
162
341
|
};
|
|
163
342
|
|
|
164
343
|
export type Elements = OmitAsChild<{
|
|
344
|
+
dialog?: GetPropDefTypes<typeof dialogContentPropDefs>;
|
|
165
345
|
primaryButton?: GetPropDefTypes<typeof buttonPropDefs>;
|
|
166
346
|
secondaryButton?: GetPropDefTypes<typeof buttonPropDefs>;
|
|
167
347
|
destructiveButton?: GetPropDefTypes<typeof buttonPropDefs>;
|
|
168
348
|
iconButton?: GetPropDefTypes<typeof iconButtonPropDefs>;
|
|
169
349
|
textfield?: GetPropDefTypes<typeof textFieldRootPropDefs>;
|
|
350
|
+
select?: GetPropDefTypes<typeof selectTriggerPropDefs>;
|
|
170
351
|
badge?: GetPropDefTypes<typeof badgePropDefs>;
|
|
171
352
|
dropdown?: GetPropDefTypes<typeof dropdownMenuContentPropDefs>;
|
|
172
353
|
primaryMenuItem?: GetPropDefTypes<typeof dropdownMenuItemPropDefs>;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// Modified from https://github.com/bvaughn/react-error-boundary
|
|
2
|
+
// Copyright (c) 2020 Brian Vaughn, MIT License
|
|
3
|
+
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
|
|
6
|
+
type ErrorBoundaryState =
|
|
7
|
+
| { didCatch: true; error: any }
|
|
8
|
+
| { didCatch: false; error: null };
|
|
9
|
+
|
|
10
|
+
export interface ErrorBoundaryContextValue {
|
|
11
|
+
didCatch: boolean;
|
|
12
|
+
error: any;
|
|
13
|
+
resetErrorBoundary: (...args: any[]) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const ErrorBoundaryContext =
|
|
17
|
+
React.createContext<ErrorBoundaryContextValue | null>(null);
|
|
18
|
+
ErrorBoundaryContext.displayName = "ErrorBoundaryContext";
|
|
19
|
+
|
|
20
|
+
const initialState: ErrorBoundaryState = {
|
|
21
|
+
didCatch: false,
|
|
22
|
+
error: null,
|
|
23
|
+
} satisfies ErrorBoundaryState;
|
|
24
|
+
|
|
25
|
+
export class ErrorBoundary extends React.Component<
|
|
26
|
+
ErrorBoundaryProps,
|
|
27
|
+
ErrorBoundaryState
|
|
28
|
+
> {
|
|
29
|
+
constructor(props: ErrorBoundaryProps) {
|
|
30
|
+
super(props);
|
|
31
|
+
|
|
32
|
+
this.resetErrorBoundary = this.resetErrorBoundary.bind(this);
|
|
33
|
+
this.state = initialState;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static getDerivedStateFromError(error: Error) {
|
|
37
|
+
return { didCatch: true, error };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
resetErrorBoundary(...args: any[]) {
|
|
41
|
+
const { error } = this.state;
|
|
42
|
+
|
|
43
|
+
if (error !== null) {
|
|
44
|
+
this.props.onReset?.({
|
|
45
|
+
args,
|
|
46
|
+
reason: "imperative-api",
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
this.setState(initialState);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
componentDidCatch(error: Error, info: React.ErrorInfo) {
|
|
54
|
+
this.props.onError?.(error, info);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
componentDidUpdate(
|
|
58
|
+
prevProps: ErrorBoundaryProps,
|
|
59
|
+
prevState: ErrorBoundaryState,
|
|
60
|
+
) {
|
|
61
|
+
const { didCatch } = this.state;
|
|
62
|
+
const { resetKeys } = this.props;
|
|
63
|
+
|
|
64
|
+
// There's an edge case where if the thing that triggered the error happens
|
|
65
|
+
// to *also* be in the resetKeys array, we'd end up resetting the error
|
|
66
|
+
// boundary immediately.
|
|
67
|
+
//
|
|
68
|
+
// This would likely trigger a second error to be thrown. So we make sure
|
|
69
|
+
// that we don't check the resetKeys on the first call of cDU after the
|
|
70
|
+
// error is set.
|
|
71
|
+
if (
|
|
72
|
+
didCatch &&
|
|
73
|
+
prevState.error !== null &&
|
|
74
|
+
hasArrayChanged(prevProps.resetKeys, resetKeys)
|
|
75
|
+
) {
|
|
76
|
+
this.props.onReset?.({
|
|
77
|
+
next: resetKeys,
|
|
78
|
+
prev: prevProps.resetKeys,
|
|
79
|
+
reason: "keys",
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
this.setState(initialState);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
render() {
|
|
87
|
+
const { children, fallbackRender, FallbackComponent, fallback } =
|
|
88
|
+
this.props;
|
|
89
|
+
const { didCatch, error } = this.state;
|
|
90
|
+
|
|
91
|
+
let childToRender = children;
|
|
92
|
+
|
|
93
|
+
if (didCatch) {
|
|
94
|
+
const props: FallbackProps = {
|
|
95
|
+
error,
|
|
96
|
+
resetErrorBoundary: this.resetErrorBoundary,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
if (typeof fallbackRender === "function") {
|
|
100
|
+
childToRender = fallbackRender(props);
|
|
101
|
+
} else if (FallbackComponent) {
|
|
102
|
+
childToRender = React.createElement(FallbackComponent, props);
|
|
103
|
+
} else if (fallback !== undefined) {
|
|
104
|
+
childToRender = fallback;
|
|
105
|
+
} else {
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<ErrorBoundaryContext.Provider
|
|
112
|
+
value={{
|
|
113
|
+
didCatch,
|
|
114
|
+
error,
|
|
115
|
+
resetErrorBoundary: this.resetErrorBoundary,
|
|
116
|
+
}}
|
|
117
|
+
>
|
|
118
|
+
{childToRender}
|
|
119
|
+
</ErrorBoundaryContext.Provider>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function hasArrayChanged(a: any[] = [], b: any[] = []) {
|
|
125
|
+
return (
|
|
126
|
+
a.length !== b.length || a.some((item, index) => !Object.is(item, b[index]))
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export type FallbackProps = {
|
|
131
|
+
error: any;
|
|
132
|
+
resetErrorBoundary: (...args: any[]) => void;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
type ErrorBoundarySharedProps = React.PropsWithChildren<{
|
|
136
|
+
onError?: (error: Error, info: React.ErrorInfo) => void;
|
|
137
|
+
onReset?: (
|
|
138
|
+
details:
|
|
139
|
+
| { reason: "imperative-api"; args: any[] }
|
|
140
|
+
| { reason: "keys"; prev: any[] | undefined; next: any[] | undefined },
|
|
141
|
+
) => void;
|
|
142
|
+
resetKeys?: any[];
|
|
143
|
+
}>;
|
|
144
|
+
|
|
145
|
+
export type ErrorBoundaryPropsWithComponent = ErrorBoundarySharedProps & {
|
|
146
|
+
fallback?: never;
|
|
147
|
+
FallbackComponent: React.ComponentType<FallbackProps>;
|
|
148
|
+
fallbackRender?: never;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export type ErrorBoundaryPropsWithRender = ErrorBoundarySharedProps & {
|
|
152
|
+
fallback?: never;
|
|
153
|
+
FallbackComponent?: never;
|
|
154
|
+
fallbackRender: (props: FallbackProps) => React.ReactNode;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export type ErrorBoundaryPropsWithFallback = ErrorBoundarySharedProps & {
|
|
158
|
+
fallback: React.ReactNode;
|
|
159
|
+
FallbackComponent?: never;
|
|
160
|
+
fallbackRender?: never;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export type ErrorBoundaryProps =
|
|
164
|
+
| ErrorBoundaryPropsWithFallback
|
|
165
|
+
| ErrorBoundaryPropsWithComponent
|
|
166
|
+
| ErrorBoundaryPropsWithRender;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
type QueryType = "query" | "mutation";
|
|
2
|
+
type RecordType = "users" | "roles";
|
|
3
|
+
|
|
4
|
+
export class FetchError extends Error {
|
|
5
|
+
queryType: QueryType;
|
|
6
|
+
recordType: RecordType;
|
|
7
|
+
context: unknown;
|
|
8
|
+
constructor(args: {
|
|
9
|
+
message: string;
|
|
10
|
+
queryType: QueryType;
|
|
11
|
+
recordType: RecordType;
|
|
12
|
+
context?: unknown;
|
|
13
|
+
}) {
|
|
14
|
+
super(args.message);
|
|
15
|
+
this.name = "FetchError";
|
|
16
|
+
this.queryType = args.queryType;
|
|
17
|
+
this.recordType = args.recordType;
|
|
18
|
+
this.context = args.context;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class ApiError extends Error {
|
|
23
|
+
status: number;
|
|
24
|
+
queryType: QueryType;
|
|
25
|
+
recordType: RecordType;
|
|
26
|
+
context: unknown;
|
|
27
|
+
constructor(args: {
|
|
28
|
+
message: string;
|
|
29
|
+
queryType: QueryType;
|
|
30
|
+
recordType: RecordType;
|
|
31
|
+
status: number;
|
|
32
|
+
context?: unknown;
|
|
33
|
+
}) {
|
|
34
|
+
super(args.message);
|
|
35
|
+
this.name = "ApiError";
|
|
36
|
+
this.status = args.status;
|
|
37
|
+
this.queryType = args.queryType;
|
|
38
|
+
this.recordType = args.recordType;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class NoAuthTokenError extends Error {
|
|
43
|
+
context: unknown;
|
|
44
|
+
constructor(args?: { context?: unknown }) {
|
|
45
|
+
super("No auth token provided");
|
|
46
|
+
this.name = "NoAuthTokenError";
|
|
47
|
+
this.context = args?.context;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -11,7 +11,15 @@ import {
|
|
|
11
11
|
import * as React from "react";
|
|
12
12
|
import { type Role, useRoles } from "./api/role";
|
|
13
13
|
import { type InviteUserPayload, useInviteUser } from "./api/user";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
DialogContent,
|
|
16
|
+
PrimaryButton,
|
|
17
|
+
SecondaryButton,
|
|
18
|
+
SelectContent,
|
|
19
|
+
SelectItem,
|
|
20
|
+
SelectTrigger,
|
|
21
|
+
TextField,
|
|
22
|
+
} from "./elements";
|
|
15
23
|
import { Label } from "./label";
|
|
16
24
|
import { isErrorLike } from "./utils";
|
|
17
25
|
|
|
@@ -74,7 +82,7 @@ export const InviteUserDialog = ({ children }: InviteUserDialogProps) => {
|
|
|
74
82
|
return (
|
|
75
83
|
<Dialog.Root open={open} onOpenChange={setOpen}>
|
|
76
84
|
{children && <Dialog.Trigger>{children}</Dialog.Trigger>}
|
|
77
|
-
<
|
|
85
|
+
<DialogContent maxWidth="480px" key={String(open)}>
|
|
78
86
|
<Dialog.Title>Invite user</Dialog.Title>
|
|
79
87
|
<Dialog.Description>
|
|
80
88
|
An invitation will be sent to this email address with a link to
|
|
@@ -100,9 +108,10 @@ export const InviteUserDialog = ({ children }: InviteUserDialogProps) => {
|
|
|
100
108
|
control={(props) => (
|
|
101
109
|
<TextField
|
|
102
110
|
{...props}
|
|
103
|
-
data-1p-ignore
|
|
111
|
+
data-1p-ignore="true"
|
|
112
|
+
data-lpignore="true"
|
|
104
113
|
type="email"
|
|
105
|
-
autoComplete="
|
|
114
|
+
autoComplete="off"
|
|
106
115
|
placeholder="Enter an email address"
|
|
107
116
|
/>
|
|
108
117
|
)}
|
|
@@ -133,21 +142,21 @@ export const InviteUserDialog = ({ children }: InviteUserDialogProps) => {
|
|
|
133
142
|
value={selectedRole}
|
|
134
143
|
onValueChange={setSelectedRole}
|
|
135
144
|
>
|
|
136
|
-
<
|
|
145
|
+
<SelectTrigger
|
|
137
146
|
id={id}
|
|
138
147
|
aria-invalid={ariaInvalid}
|
|
139
148
|
aria-describedby={ariaDescribedBy}
|
|
140
149
|
/>
|
|
141
|
-
<
|
|
142
|
-
<
|
|
150
|
+
<SelectContent>
|
|
151
|
+
<SelectItem value={PLACEHOLDER_ROLE} disabled>
|
|
143
152
|
Select a role
|
|
144
|
-
</
|
|
153
|
+
</SelectItem>
|
|
145
154
|
{roles.map((role) => (
|
|
146
|
-
<
|
|
155
|
+
<SelectItem key={role.slug} value={role.slug}>
|
|
147
156
|
{role.name}
|
|
148
|
-
</
|
|
157
|
+
</SelectItem>
|
|
149
158
|
))}
|
|
150
|
-
</
|
|
159
|
+
</SelectContent>
|
|
151
160
|
</Select.Root>
|
|
152
161
|
)}
|
|
153
162
|
/>
|
|
@@ -179,7 +188,7 @@ export const InviteUserDialog = ({ children }: InviteUserDialogProps) => {
|
|
|
179
188
|
<VisuallyHidden asChild>
|
|
180
189
|
<section aria-live="polite">{formErrors.form}</section>
|
|
181
190
|
</VisuallyHidden>
|
|
182
|
-
</
|
|
191
|
+
</DialogContent>
|
|
183
192
|
</Dialog.Root>
|
|
184
193
|
);
|
|
185
194
|
};
|