@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.
Files changed (170) hide show
  1. package/dist/cjs/lib/api/role.d.ts.map +1 -1
  2. package/dist/cjs/lib/api/role.js +35 -14
  3. package/dist/cjs/lib/api/role.js.map +1 -1
  4. package/dist/cjs/lib/api/user.d.ts.map +1 -1
  5. package/dist/cjs/lib/api/user.js +105 -67
  6. package/dist/cjs/lib/api/user.js.map +1 -1
  7. package/dist/cjs/lib/constants.d.ts +2 -1
  8. package/dist/cjs/lib/constants.d.ts.map +1 -1
  9. package/dist/cjs/lib/constants.js +3 -2
  10. package/dist/cjs/lib/constants.js.map +1 -1
  11. package/dist/cjs/lib/delete-user-dialog.d.ts.map +1 -1
  12. package/dist/cjs/lib/delete-user-dialog.js +1 -1
  13. package/dist/cjs/lib/delete-user-dialog.js.map +1 -1
  14. package/dist/cjs/lib/edit-user-details-dialog.d.ts.map +1 -1
  15. package/dist/cjs/lib/edit-user-details-dialog.js +3 -5
  16. package/dist/cjs/lib/edit-user-details-dialog.js.map +1 -1
  17. package/dist/cjs/lib/elements.d.ts +21 -12
  18. package/dist/cjs/lib/elements.d.ts.map +1 -1
  19. package/dist/cjs/lib/elements.js +118 -30
  20. package/dist/cjs/lib/elements.js.map +1 -1
  21. package/dist/cjs/lib/error-boundary.d.ts +58 -0
  22. package/dist/cjs/lib/error-boundary.d.ts.map +1 -0
  23. package/dist/cjs/lib/error-boundary.js +113 -0
  24. package/dist/cjs/lib/error-boundary.js.map +1 -0
  25. package/dist/cjs/lib/errors.d.ts +34 -0
  26. package/dist/cjs/lib/errors.d.ts.map +1 -0
  27. package/dist/cjs/lib/errors.js +40 -0
  28. package/dist/cjs/lib/errors.js.map +1 -0
  29. package/dist/cjs/lib/invite-user-dialog.d.ts.map +1 -1
  30. package/dist/cjs/lib/invite-user-dialog.js +2 -2
  31. package/dist/cjs/lib/invite-user-dialog.js.map +1 -1
  32. package/dist/cjs/lib/resend-invite-dialog.d.ts.map +1 -1
  33. package/dist/cjs/lib/resend-invite-dialog.js +2 -2
  34. package/dist/cjs/lib/resend-invite-dialog.js.map +1 -1
  35. package/dist/cjs/lib/revoke-invite-dialog.d.ts.map +1 -1
  36. package/dist/cjs/lib/revoke-invite-dialog.js +1 -1
  37. package/dist/cjs/lib/revoke-invite-dialog.js.map +1 -1
  38. package/dist/cjs/lib/use-layout-effect.d.ts +4 -0
  39. package/dist/cjs/lib/use-layout-effect.d.ts.map +1 -0
  40. package/dist/cjs/lib/use-layout-effect.js +8 -0
  41. package/dist/cjs/lib/use-layout-effect.js.map +1 -0
  42. package/dist/cjs/lib/user-actions-dropdown.d.ts.map +1 -1
  43. package/dist/cjs/lib/user-actions-dropdown.js +2 -9
  44. package/dist/cjs/lib/user-actions-dropdown.js.map +1 -1
  45. package/dist/cjs/lib/users-filter.d.ts +1 -0
  46. package/dist/cjs/lib/users-filter.d.ts.map +1 -1
  47. package/dist/cjs/lib/users-filter.js +2 -9
  48. package/dist/cjs/lib/users-filter.js.map +1 -1
  49. package/dist/cjs/lib/users-management-context.d.ts +2 -2
  50. package/dist/cjs/lib/users-management-context.d.ts.map +1 -1
  51. package/dist/cjs/lib/users-management.d.ts +9 -6
  52. package/dist/cjs/lib/users-management.d.ts.map +1 -1
  53. package/dist/cjs/lib/users-management.js +77 -20
  54. package/dist/cjs/lib/users-management.js.map +1 -1
  55. package/dist/cjs/lib/users-search.d.ts.map +1 -1
  56. package/dist/cjs/lib/users-search.js +3 -9
  57. package/dist/cjs/lib/users-search.js.map +1 -1
  58. package/dist/cjs/lib/utils.d.ts +2 -0
  59. package/dist/cjs/lib/utils.d.ts.map +1 -1
  60. package/dist/cjs/lib/utils.js +18 -0
  61. package/dist/cjs/lib/utils.js.map +1 -1
  62. package/dist/cjs/users-management.client.d.ts +1 -1
  63. package/dist/cjs/users-management.client.d.ts.map +1 -1
  64. package/dist/cjs/users-management.client.js +15 -5
  65. package/dist/cjs/users-management.client.js.map +1 -1
  66. package/dist/cjs/workos-widgets.client.d.ts.map +1 -1
  67. package/dist/cjs/workos-widgets.client.js +2 -1
  68. package/dist/cjs/workos-widgets.client.js.map +1 -1
  69. package/dist/esm/lib/api/role.d.ts.map +1 -1
  70. package/dist/esm/lib/api/role.js +35 -14
  71. package/dist/esm/lib/api/role.js.map +1 -1
  72. package/dist/esm/lib/api/user.d.ts.map +1 -1
  73. package/dist/esm/lib/api/user.js +105 -67
  74. package/dist/esm/lib/api/user.js.map +1 -1
  75. package/dist/esm/lib/constants.d.ts +2 -1
  76. package/dist/esm/lib/constants.d.ts.map +1 -1
  77. package/dist/esm/lib/constants.js +2 -1
  78. package/dist/esm/lib/constants.js.map +1 -1
  79. package/dist/esm/lib/delete-user-dialog.d.ts.map +1 -1
  80. package/dist/esm/lib/delete-user-dialog.js +2 -2
  81. package/dist/esm/lib/delete-user-dialog.js.map +1 -1
  82. package/dist/esm/lib/edit-user-details-dialog.d.ts.map +1 -1
  83. package/dist/esm/lib/edit-user-details-dialog.js +4 -6
  84. package/dist/esm/lib/edit-user-details-dialog.js.map +1 -1
  85. package/dist/esm/lib/elements.d.ts +21 -12
  86. package/dist/esm/lib/elements.d.ts.map +1 -1
  87. package/dist/esm/lib/elements.js +95 -30
  88. package/dist/esm/lib/elements.js.map +1 -1
  89. package/dist/esm/lib/error-boundary.d.ts +58 -0
  90. package/dist/esm/lib/error-boundary.d.ts.map +1 -0
  91. package/dist/esm/lib/error-boundary.js +86 -0
  92. package/dist/esm/lib/error-boundary.js.map +1 -0
  93. package/dist/esm/lib/errors.d.ts +34 -0
  94. package/dist/esm/lib/errors.d.ts.map +1 -0
  95. package/dist/esm/lib/errors.js +34 -0
  96. package/dist/esm/lib/errors.js.map +1 -0
  97. package/dist/esm/lib/invite-user-dialog.d.ts.map +1 -1
  98. package/dist/esm/lib/invite-user-dialog.js +3 -3
  99. package/dist/esm/lib/invite-user-dialog.js.map +1 -1
  100. package/dist/esm/lib/resend-invite-dialog.d.ts.map +1 -1
  101. package/dist/esm/lib/resend-invite-dialog.js +3 -3
  102. package/dist/esm/lib/resend-invite-dialog.js.map +1 -1
  103. package/dist/esm/lib/revoke-invite-dialog.d.ts.map +1 -1
  104. package/dist/esm/lib/revoke-invite-dialog.js +2 -2
  105. package/dist/esm/lib/revoke-invite-dialog.js.map +1 -1
  106. package/dist/esm/lib/use-layout-effect.d.ts +4 -0
  107. package/dist/esm/lib/use-layout-effect.d.ts.map +1 -0
  108. package/dist/esm/lib/use-layout-effect.js +5 -0
  109. package/dist/esm/lib/use-layout-effect.js.map +1 -0
  110. package/dist/esm/lib/user-actions-dropdown.d.ts.map +1 -1
  111. package/dist/esm/lib/user-actions-dropdown.js +3 -10
  112. package/dist/esm/lib/user-actions-dropdown.js.map +1 -1
  113. package/dist/esm/lib/users-filter.d.ts +1 -0
  114. package/dist/esm/lib/users-filter.d.ts.map +1 -1
  115. package/dist/esm/lib/users-filter.js +4 -11
  116. package/dist/esm/lib/users-filter.js.map +1 -1
  117. package/dist/esm/lib/users-management-context.d.ts +2 -2
  118. package/dist/esm/lib/users-management-context.d.ts.map +1 -1
  119. package/dist/esm/lib/users-management.d.ts +9 -6
  120. package/dist/esm/lib/users-management.d.ts.map +1 -1
  121. package/dist/esm/lib/users-management.js +74 -22
  122. package/dist/esm/lib/users-management.js.map +1 -1
  123. package/dist/esm/lib/users-search.d.ts.map +1 -1
  124. package/dist/esm/lib/users-search.js +5 -11
  125. package/dist/esm/lib/users-search.js.map +1 -1
  126. package/dist/esm/lib/utils.d.ts +2 -0
  127. package/dist/esm/lib/utils.d.ts.map +1 -1
  128. package/dist/esm/lib/utils.js +13 -0
  129. package/dist/esm/lib/utils.js.map +1 -1
  130. package/dist/esm/users-management.client.d.ts +1 -1
  131. package/dist/esm/users-management.client.d.ts.map +1 -1
  132. package/dist/esm/users-management.client.js +16 -6
  133. package/dist/esm/users-management.client.js.map +1 -1
  134. package/dist/esm/workos-widgets.client.d.ts.map +1 -1
  135. package/dist/esm/workos-widgets.client.js +2 -1
  136. package/dist/esm/workos-widgets.client.js.map +1 -1
  137. package/dist/tsconfig.cjs.tsbuildinfo +1 -1
  138. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  139. package/package.json +8 -3
  140. package/src/base.css +111 -0
  141. package/src/lib/api/role.ts +39 -16
  142. package/src/lib/api/user.ts +119 -75
  143. package/src/lib/constants.ts +2 -1
  144. package/src/lib/delete-user-dialog.tsx +7 -3
  145. package/src/lib/edit-user-details-dialog.tsx +15 -10
  146. package/src/lib/elements.tsx +242 -61
  147. package/src/lib/error-boundary.tsx +166 -0
  148. package/src/lib/errors.ts +49 -0
  149. package/src/lib/invite-user-dialog.tsx +21 -12
  150. package/src/lib/resend-invite-dialog.tsx +11 -5
  151. package/src/lib/revoke-invite-dialog.tsx +7 -3
  152. package/src/lib/use-layout-effect.ts +6 -0
  153. package/src/lib/user-actions-dropdown.tsx +8 -16
  154. package/src/lib/users-filter.tsx +13 -73
  155. package/src/lib/users-management-context.tsx +1 -1
  156. package/src/lib/users-management.tsx +345 -184
  157. package/src/lib/users-search.tsx +5 -63
  158. package/src/lib/utils.ts +21 -0
  159. package/src/users-management.client.tsx +39 -16
  160. package/src/users-management.css +4 -0
  161. package/src/workos-widgets.client.tsx +2 -1
  162. package/dist/cjs/lib/pagination.d.ts +0 -8
  163. package/dist/cjs/lib/pagination.d.ts.map +0 -1
  164. package/dist/cjs/lib/pagination.js +0 -67
  165. package/dist/cjs/lib/pagination.js.map +0 -1
  166. package/dist/esm/lib/pagination.d.ts +0 -8
  167. package/dist/esm/lib/pagination.d.ts.map +0 -1
  168. package/dist/esm/lib/pagination.js +0 -40
  169. package/dist/esm/lib/pagination.js.map +0 -1
  170. package/src/lib/pagination.tsx +0 -69
@@ -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 Button>
28
- >((props, ref) => {
34
+ React.ComponentPropsWithoutRef<typeof RadixButton>
35
+ >(function PrimaryButton({ className, ...props }, ref) {
29
36
  const element = useElement("primaryButton");
30
-
31
- return <Button ref={ref} variant="solid" {...props} {...element} />;
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
- PrimaryButton.displayName = "PrimaryButton";
35
-
36
- export const SecondaryButton = forwardRef<
48
+ export const SecondaryButton = React.forwardRef<
37
49
  HTMLButtonElement,
38
- ComponentPropsWithoutRef<typeof Button>
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
- <Button ref={ref} variant="surface" color="gray" {...props} {...element} />
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
- SecondaryButton.displayName = "SecondaryButton";
48
-
49
- export const DestructiveButton = forwardRef<
65
+ export const DestructiveButton = React.forwardRef<
50
66
  HTMLButtonElement,
51
- ComponentPropsWithoutRef<typeof Button>
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
- <Button ref={ref} variant="solid" color="red" {...props} {...element} />
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
- DestructiveButton.displayName = "DestructiveButton";
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
- IconButton.displayName = "IconButton";
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
- TextField.displayName = "TextField";
99
-
100
- export const TextFieldSlot = RadixTextField.Slot;
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
- return <RadixBadge ref={ref} {...element} {...props} />;
178
+ return (
179
+ <RadixBadge
180
+ ref={ref}
181
+ className={cx("badge", className)}
182
+ {...element}
183
+ {...props}
184
+ />
185
+ );
109
186
  });
110
187
 
111
- Badge.displayName = "Badge";
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 DropdownMenu.Item>
116
- >((props, ref) => {
205
+ React.ComponentPropsWithoutRef<typeof RadixDropdownMenu.Item>
206
+ >(function PrimaryMenuItem({ className, ...props }, ref) {
117
207
  const element = useElement("primaryMenuItem");
118
-
119
- return <DropdownMenu.Item ref={ref} {...props} {...element} />;
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
- PrimaryMenuItem.displayName = "PrimaryMenuItem";
123
-
124
- export const DestructiveMenuItem = forwardRef<
218
+ export const DestructiveMenuItem = React.forwardRef<
125
219
  HTMLDivElement,
126
- ComponentPropsWithoutRef<typeof DropdownMenu.Item>
127
- >((props, ref) => {
220
+ React.ComponentPropsWithoutRef<typeof RadixDropdownMenu.Item>
221
+ >(function DestructiveMenuItem({ className, ...props }, ref) {
128
222
  const element = useElement("destructiveMenuItem");
129
-
130
- return <DropdownMenu.Item ref={ref} color="red" {...props} {...element} />;
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
- Avatar.displayName = "Avatar";
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 { PrimaryButton, SecondaryButton, TextField } from "./elements";
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
- <Dialog.Content maxWidth="480px" key={String(open)}>
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="email"
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
- <Select.Trigger
145
+ <SelectTrigger
137
146
  id={id}
138
147
  aria-invalid={ariaInvalid}
139
148
  aria-describedby={ariaDescribedBy}
140
149
  />
141
- <Select.Content>
142
- <Select.Item value={PLACEHOLDER_ROLE} disabled>
150
+ <SelectContent>
151
+ <SelectItem value={PLACEHOLDER_ROLE} disabled>
143
152
  Select a role
144
- </Select.Item>
153
+ </SelectItem>
145
154
  {roles.map((role) => (
146
- <Select.Item key={role.slug} value={role.slug}>
155
+ <SelectItem key={role.slug} value={role.slug}>
147
156
  {role.name}
148
- </Select.Item>
157
+ </SelectItem>
149
158
  ))}
150
- </Select.Content>
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
- </Dialog.Content>
191
+ </DialogContent>
183
192
  </Dialog.Root>
184
193
  );
185
194
  };