@workos-inc/widgets 0.0.0-pre.1 → 0.0.0-pre.3

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 (181) 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 +23 -12
  18. package/dist/cjs/lib/elements.d.ts.map +1 -1
  19. package/dist/cjs/lib/elements.js +104 -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 +4 -4
  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 +1 -1
  56. package/dist/cjs/lib/users-search.d.ts.map +1 -1
  57. package/dist/cjs/lib/users-search.js +3 -9
  58. package/dist/cjs/lib/users-search.js.map +1 -1
  59. package/dist/cjs/lib/utils.d.ts +2 -0
  60. package/dist/cjs/lib/utils.d.ts.map +1 -1
  61. package/dist/cjs/lib/utils.js +18 -0
  62. package/dist/cjs/lib/utils.js.map +1 -1
  63. package/dist/cjs/users-management.client.d.ts +1 -1
  64. package/dist/cjs/users-management.client.d.ts.map +1 -1
  65. package/dist/cjs/users-management.client.js +15 -5
  66. package/dist/cjs/users-management.client.js.map +1 -1
  67. package/dist/cjs/workos-widgets.client.d.ts.map +1 -1
  68. package/dist/cjs/workos-widgets.client.js +2 -1
  69. package/dist/cjs/workos-widgets.client.js.map +1 -1
  70. package/dist/esm/lib/api/role.d.ts.map +1 -1
  71. package/dist/esm/lib/api/role.js +35 -14
  72. package/dist/esm/lib/api/role.js.map +1 -1
  73. package/dist/esm/lib/api/user.d.ts.map +1 -1
  74. package/dist/esm/lib/api/user.js +105 -67
  75. package/dist/esm/lib/api/user.js.map +1 -1
  76. package/dist/esm/lib/constants.d.ts +2 -1
  77. package/dist/esm/lib/constants.d.ts.map +1 -1
  78. package/dist/esm/lib/constants.js +2 -1
  79. package/dist/esm/lib/constants.js.map +1 -1
  80. package/dist/esm/lib/delete-user-dialog.d.ts.map +1 -1
  81. package/dist/esm/lib/delete-user-dialog.js +2 -2
  82. package/dist/esm/lib/delete-user-dialog.js.map +1 -1
  83. package/dist/esm/lib/edit-user-details-dialog.d.ts.map +1 -1
  84. package/dist/esm/lib/edit-user-details-dialog.js +4 -6
  85. package/dist/esm/lib/edit-user-details-dialog.js.map +1 -1
  86. package/dist/esm/lib/elements.d.ts +23 -12
  87. package/dist/esm/lib/elements.d.ts.map +1 -1
  88. package/dist/esm/lib/elements.js +81 -30
  89. package/dist/esm/lib/elements.js.map +1 -1
  90. package/dist/esm/lib/error-boundary.d.ts +58 -0
  91. package/dist/esm/lib/error-boundary.d.ts.map +1 -0
  92. package/dist/esm/lib/error-boundary.js +86 -0
  93. package/dist/esm/lib/error-boundary.js.map +1 -0
  94. package/dist/esm/lib/errors.d.ts +34 -0
  95. package/dist/esm/lib/errors.d.ts.map +1 -0
  96. package/dist/esm/lib/errors.js +34 -0
  97. package/dist/esm/lib/errors.js.map +1 -0
  98. package/dist/esm/lib/invite-user-dialog.d.ts.map +1 -1
  99. package/dist/esm/lib/invite-user-dialog.js +4 -4
  100. package/dist/esm/lib/invite-user-dialog.js.map +1 -1
  101. package/dist/esm/lib/resend-invite-dialog.d.ts.map +1 -1
  102. package/dist/esm/lib/resend-invite-dialog.js +3 -3
  103. package/dist/esm/lib/resend-invite-dialog.js.map +1 -1
  104. package/dist/esm/lib/revoke-invite-dialog.d.ts.map +1 -1
  105. package/dist/esm/lib/revoke-invite-dialog.js +2 -2
  106. package/dist/esm/lib/revoke-invite-dialog.js.map +1 -1
  107. package/dist/esm/lib/use-layout-effect.d.ts +4 -0
  108. package/dist/esm/lib/use-layout-effect.d.ts.map +1 -0
  109. package/dist/esm/lib/use-layout-effect.js +5 -0
  110. package/dist/esm/lib/use-layout-effect.js.map +1 -0
  111. package/dist/esm/lib/user-actions-dropdown.d.ts.map +1 -1
  112. package/dist/esm/lib/user-actions-dropdown.js +3 -10
  113. package/dist/esm/lib/user-actions-dropdown.js.map +1 -1
  114. package/dist/esm/lib/users-filter.d.ts +1 -0
  115. package/dist/esm/lib/users-filter.d.ts.map +1 -1
  116. package/dist/esm/lib/users-filter.js +4 -11
  117. package/dist/esm/lib/users-filter.js.map +1 -1
  118. package/dist/esm/lib/users-management-context.d.ts +2 -2
  119. package/dist/esm/lib/users-management-context.d.ts.map +1 -1
  120. package/dist/esm/lib/users-management.d.ts +9 -6
  121. package/dist/esm/lib/users-management.d.ts.map +1 -1
  122. package/dist/esm/lib/users-management.js +74 -22
  123. package/dist/esm/lib/users-management.js.map +1 -1
  124. package/dist/esm/lib/users-search.d.ts +1 -1
  125. package/dist/esm/lib/users-search.d.ts.map +1 -1
  126. package/dist/esm/lib/users-search.js +5 -11
  127. package/dist/esm/lib/users-search.js.map +1 -1
  128. package/dist/esm/lib/utils.d.ts +2 -0
  129. package/dist/esm/lib/utils.d.ts.map +1 -1
  130. package/dist/esm/lib/utils.js +13 -0
  131. package/dist/esm/lib/utils.js.map +1 -1
  132. package/dist/esm/users-management.client.d.ts +1 -1
  133. package/dist/esm/users-management.client.d.ts.map +1 -1
  134. package/dist/esm/users-management.client.js +16 -6
  135. package/dist/esm/users-management.client.js.map +1 -1
  136. package/dist/esm/workos-widgets.client.d.ts.map +1 -1
  137. package/dist/esm/workos-widgets.client.js +2 -1
  138. package/dist/esm/workos-widgets.client.js.map +1 -1
  139. package/dist/tsconfig.cjs.tsbuildinfo +1 -1
  140. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  141. package/package.json +8 -3
  142. package/src/base.css +111 -0
  143. package/src/lib/api/role.ts +39 -16
  144. package/src/lib/api/user.ts +119 -75
  145. package/src/lib/constants.ts +2 -1
  146. package/src/lib/delete-user-dialog.tsx +7 -3
  147. package/src/lib/edit-user-details-dialog.tsx +15 -10
  148. package/src/lib/elements.tsx +254 -70
  149. package/src/lib/error-boundary.tsx +166 -0
  150. package/src/lib/errors.ts +49 -0
  151. package/src/lib/invite-user-dialog.tsx +22 -13
  152. package/src/lib/resend-invite-dialog.tsx +11 -5
  153. package/src/lib/revoke-invite-dialog.tsx +7 -3
  154. package/src/lib/use-layout-effect.ts +6 -0
  155. package/src/lib/user-actions-dropdown.tsx +8 -16
  156. package/src/lib/users-filter.tsx +13 -73
  157. package/src/lib/users-management-context.tsx +1 -1
  158. package/src/lib/users-management.tsx +339 -184
  159. package/src/lib/users-search.tsx +5 -63
  160. package/src/lib/utils.ts +21 -0
  161. package/src/users-management.client.tsx +37 -16
  162. package/src/users-management.css +4 -0
  163. package/src/workos-widgets.client.tsx +2 -1
  164. package/dist/cjs/lib/label.d.ts +0 -7
  165. package/dist/cjs/lib/label.d.ts.map +0 -1
  166. package/dist/cjs/lib/label.js +0 -9
  167. package/dist/cjs/lib/label.js.map +0 -1
  168. package/dist/cjs/lib/pagination.d.ts +0 -8
  169. package/dist/cjs/lib/pagination.d.ts.map +0 -1
  170. package/dist/cjs/lib/pagination.js +0 -67
  171. package/dist/cjs/lib/pagination.js.map +0 -1
  172. package/dist/esm/lib/label.d.ts +0 -7
  173. package/dist/esm/lib/label.d.ts.map +0 -1
  174. package/dist/esm/lib/label.js +0 -6
  175. package/dist/esm/lib/label.js.map +0 -1
  176. package/dist/esm/lib/pagination.d.ts +0 -8
  177. package/dist/esm/lib/pagination.d.ts.map +0 -1
  178. package/dist/esm/lib/pagination.js +0 -40
  179. package/dist/esm/lib/pagination.js.map +0 -1
  180. package/src/lib/label.tsx +0 -14
  181. package/src/lib/pagination.tsx +0 -69
@@ -1,149 +1,270 @@
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,
15
+ Text,
16
+ type BadgeProps,
17
+ type ButtonProps,
18
+ type IconButtonProps,
19
+ type TextProps,
11
20
  } from "@radix-ui/themes";
12
21
  import type {
13
22
  GetPropDefTypes,
14
23
  avatarPropDefs,
15
24
  badgePropDefs,
16
25
  buttonPropDefs,
26
+ dialogContentPropDefs,
17
27
  dropdownMenuContentPropDefs,
18
28
  dropdownMenuItemPropDefs,
19
29
  iconButtonPropDefs,
30
+ textPropDefs,
20
31
  textFieldRootPropDefs,
32
+ selectTriggerPropDefs,
21
33
  } from "@radix-ui/themes/props";
22
- import { type ComponentPropsWithoutRef, forwardRef } from "react";
34
+ import { useComposedRefs } from "@radix-ui/react-compose-refs";
23
35
  import { useElement } from "./widgets-context";
36
+ import { cx, namespaceClassName } from "./utils";
37
+ import { useLayoutEffect } from "./use-layout-effect";
24
38
 
25
- export const PrimaryButton = forwardRef<
26
- HTMLButtonElement,
27
- ComponentPropsWithoutRef<typeof Button>
28
- >((props, ref) => {
29
- const element = useElement("primaryButton");
30
-
31
- return <Button ref={ref} variant="solid" {...props} {...element} />;
32
- });
39
+ export const PrimaryButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
40
+ function PrimaryButton({ className, ...props }, ref) {
41
+ const element = useElement("primaryButton");
42
+ return (
43
+ <RadixButton
44
+ ref={ref}
45
+ className={cx("button", "button--primary", className)}
46
+ variant="solid"
47
+ {...props}
48
+ {...element}
49
+ />
50
+ );
51
+ },
52
+ );
33
53
 
34
- PrimaryButton.displayName = "PrimaryButton";
54
+ export const SecondaryButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
55
+ function SecondaryButton({ className, ...props }, ref) {
56
+ const element = useElement("secondaryButton");
57
+ return (
58
+ <RadixButton
59
+ ref={ref}
60
+ className={cx(["button", "button--secondary"], className)}
61
+ variant="surface"
62
+ color="gray"
63
+ {...props}
64
+ {...element}
65
+ />
66
+ );
67
+ },
68
+ );
35
69
 
36
- export const SecondaryButton = forwardRef<
70
+ export const DestructiveButton = React.forwardRef<
37
71
  HTMLButtonElement,
38
- ComponentPropsWithoutRef<typeof Button>
39
- >((props, ref) => {
40
- const element = useElement("secondaryButton");
41
-
72
+ ButtonProps
73
+ >(function DestructiveButton({ className, ...props }, ref) {
74
+ const element = useElement("destructiveButton");
42
75
  return (
43
- <Button ref={ref} variant="surface" color="gray" {...props} {...element} />
76
+ <RadixButton
77
+ ref={ref}
78
+ className={cx(["button", "button--destructive"], className)}
79
+ variant="solid"
80
+ color="red"
81
+ {...props}
82
+ {...element}
83
+ />
44
84
  );
45
85
  });
46
86
 
47
- SecondaryButton.displayName = "SecondaryButton";
87
+ export const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(
88
+ function IconButton({ className, ...props }, ref) {
89
+ const element = useElement("iconButton");
90
+ return (
91
+ <RadixIconButton
92
+ ref={ref}
93
+ className={cx(["button", "icon-button"], className)}
94
+ variant="ghost"
95
+ color="gray"
96
+ {...props}
97
+ {...element}
98
+ />
99
+ );
100
+ },
101
+ );
48
102
 
49
- export const DestructiveButton = forwardRef<
103
+ export const SelectTrigger = React.forwardRef<
50
104
  HTMLButtonElement,
51
- ComponentPropsWithoutRef<typeof Button>
52
- >((props, ref) => {
53
- const element = useElement("destructiveButton");
54
-
105
+ RadixSelect.TriggerProps
106
+ >(function SelectTrigger({ className, ...props }, ref) {
107
+ const element = useElement("select");
55
108
  return (
56
- <Button ref={ref} variant="solid" color="red" {...props} {...element} />
109
+ <RadixSelect.Trigger
110
+ ref={ref}
111
+ className={cx("select", className)}
112
+ {...props}
113
+ {...element}
114
+ />
57
115
  );
58
116
  });
59
117
 
60
- DestructiveButton.displayName = "DestructiveButton";
61
-
62
- export const IconButton = forwardRef<
63
- HTMLButtonElement,
64
- ComponentPropsWithoutRef<typeof RadixIconButton>
65
- >((props, ref) => {
66
- const element = useElement("iconButton");
118
+ export const SelectContent = React.forwardRef<
119
+ HTMLDivElement,
120
+ RadixSelect.ContentProps
121
+ >(function SelectContent({ className, ...props }, ref) {
122
+ const element = useElement("dropdown");
123
+ return (
124
+ <RadixSelect.Content
125
+ ref={ref}
126
+ className={cx(["dropdown", "select-dropdown"], className)}
127
+ {...props}
128
+ {...element}
129
+ />
130
+ );
131
+ });
67
132
 
133
+ export const SelectItem = React.forwardRef<
134
+ HTMLDivElement,
135
+ RadixSelect.ItemProps
136
+ >(function SelectItem({ className, ...props }, ref) {
137
+ const element = useElement("primaryMenuItem");
68
138
  return (
69
- <RadixIconButton
139
+ <RadixSelect.Item
70
140
  ref={ref}
71
- variant="ghost"
72
- color="gray"
141
+ className={cx(["menu-item", "select-item"], className)}
73
142
  {...props}
74
143
  {...element}
75
144
  />
76
145
  );
77
146
  });
78
147
 
79
- IconButton.displayName = "IconButton";
148
+ export const Label = React.forwardRef<HTMLLabelElement, TextProps>(
149
+ function Label({ children, className, ...props }, ref) {
150
+ const element = useElement("label");
151
+ return (
152
+ <Text
153
+ as="label"
154
+ ref={ref}
155
+ weight="bold"
156
+ size="2"
157
+ className={cx("label", className)}
158
+ {...props}
159
+ {...element}
160
+ >
161
+ {children}
162
+ </Text>
163
+ );
164
+ },
165
+ );
80
166
 
81
- export const TextField = forwardRef<
167
+ export const TextField = React.forwardRef<
82
168
  HTMLInputElement,
83
- ComponentPropsWithoutRef<typeof RadixTextField.Root>
84
- >((props, ref) => {
169
+ RadixTextField.RootProps
170
+ >(function TextField({ className, ...props }, ref) {
85
171
  const element = useElement("textfield");
86
-
87
172
  return (
88
173
  <RadixTextField.Root
89
- data-1p-ignore
90
174
  ref={ref}
91
175
  variant="surface"
176
+ className={cx("text-field", className)}
92
177
  {...props}
93
178
  {...element}
94
179
  />
95
180
  );
96
181
  });
97
182
 
98
- TextField.displayName = "TextField";
99
-
100
- export const TextFieldSlot = RadixTextField.Slot;
183
+ export const TextFieldSlot = React.forwardRef<
184
+ HTMLDivElement,
185
+ RadixTextField.SlotProps
186
+ >(function TextFieldSlot({ className, ...props }, ref) {
187
+ return (
188
+ <RadixTextField.Slot
189
+ ref={ref}
190
+ className={cx("text-field-slot", className)}
191
+ {...props}
192
+ />
193
+ );
194
+ });
101
195
 
102
- export const Badge = forwardRef<
103
- HTMLSpanElement,
104
- ComponentPropsWithoutRef<typeof RadixBadge>
105
- >((props, ref) => {
106
- const element = useElement("badge");
196
+ export const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(
197
+ function Badge({ className, ...props }, ref) {
198
+ const element = useElement("badge");
199
+ return (
200
+ <RadixBadge
201
+ ref={ref}
202
+ className={cx("badge", className)}
203
+ {...element}
204
+ {...props}
205
+ />
206
+ );
207
+ },
208
+ );
107
209
 
108
- return <RadixBadge ref={ref} {...element} {...props} />;
210
+ export const DropdownMenuContent = React.forwardRef<
211
+ HTMLDivElement,
212
+ RadixDropdownMenu.ContentProps
213
+ >(function DropdownMenuContent({ className, ...props }, ref) {
214
+ const element = useElement("dropdown");
215
+ return (
216
+ <RadixDropdownMenu.Content
217
+ ref={ref}
218
+ className={cx("dropdown", className)}
219
+ {...props}
220
+ {...element}
221
+ />
222
+ );
109
223
  });
110
224
 
111
- Badge.displayName = "Badge";
112
-
113
- export const PrimaryMenuItem = forwardRef<
225
+ export const PrimaryMenuItem = React.forwardRef<
114
226
  HTMLDivElement,
115
- ComponentPropsWithoutRef<typeof DropdownMenu.Item>
116
- >((props, ref) => {
227
+ RadixDropdownMenu.ItemProps
228
+ >(function PrimaryMenuItem({ className, ...props }, ref) {
117
229
  const element = useElement("primaryMenuItem");
118
-
119
- return <DropdownMenu.Item ref={ref} {...props} {...element} />;
230
+ return (
231
+ <RadixDropdownMenu.Item
232
+ ref={ref}
233
+ className={cx("menu-item", className)}
234
+ {...props}
235
+ {...element}
236
+ />
237
+ );
120
238
  });
121
239
 
122
- PrimaryMenuItem.displayName = "PrimaryMenuItem";
123
-
124
- export const DestructiveMenuItem = forwardRef<
240
+ export const DestructiveMenuItem = React.forwardRef<
125
241
  HTMLDivElement,
126
- ComponentPropsWithoutRef<typeof DropdownMenu.Item>
127
- >((props, ref) => {
242
+ RadixDropdownMenu.ItemProps
243
+ >(function DestructiveMenuItem({ className, ...props }, ref) {
128
244
  const element = useElement("destructiveMenuItem");
129
-
130
- return <DropdownMenu.Item ref={ref} color="red" {...props} {...element} />;
245
+ return (
246
+ <RadixDropdownMenu.Item
247
+ ref={ref}
248
+ className={cx(["menu-item", "menu-item--destructive"], className)}
249
+ color="red"
250
+ {...props}
251
+ {...element}
252
+ />
253
+ );
131
254
  });
132
255
 
133
- DestructiveMenuItem.displayName = "DestructiveMenuItem";
134
-
135
256
  interface AvatarProps extends RadixAvatarProps {
136
257
  dim?: boolean;
137
258
  }
138
259
 
139
- export const Avatar = forwardRef<HTMLImageElement, AvatarProps>(
140
- ({ dim, ...props }, ref) => {
260
+ export const Avatar = React.forwardRef<HTMLImageElement, AvatarProps>(
261
+ function Avatar({ dim, className, ...props }, ref) {
141
262
  const element = useElement("avatar");
142
-
143
263
  return (
144
264
  <RadixAvatar
145
265
  ref={ref}
146
266
  color="gray"
267
+ className={cx("avatar", className)}
147
268
  {...props}
148
269
  {...element}
149
270
  // TODO: use CSS var instead of hard-coded value for opacity
@@ -153,7 +274,67 @@ export const Avatar = forwardRef<HTMLImageElement, AvatarProps>(
153
274
  },
154
275
  );
155
276
 
156
- Avatar.displayName = "Avatar";
277
+ export const DialogContent = React.forwardRef<
278
+ HTMLDivElement,
279
+ RadixDialog.ContentProps
280
+ >(function DialogContent({ className, ...props }, forwardedRef) {
281
+ const element = useElement("dialog");
282
+ const [node, setNode] = React.useState<HTMLDivElement | null>(null);
283
+ const ref = useComposedRefs(forwardedRef, setNode as any);
284
+ useDialogOverlayHack(node, {
285
+ className: namespaceClassName("dialog-overlay"),
286
+ selector: ".rt-DialogOverlay",
287
+ });
288
+ return (
289
+ <RadixDialog.Content
290
+ ref={ref}
291
+ className={cx("dialog", className)}
292
+ {...props}
293
+ {...element}
294
+ />
295
+ );
296
+ });
297
+
298
+ export const AlertDialogContent = React.forwardRef<
299
+ HTMLDivElement,
300
+ RadixAlertDialog.ContentProps
301
+ >(function AlertDialogContent({ className, ...props }, forwardedRef) {
302
+ const element = useElement("dialog");
303
+ const [node, setNode] = React.useState<HTMLDivElement | null>(null);
304
+ const ref = useComposedRefs(forwardedRef, setNode as any);
305
+ useDialogOverlayHack(node, {
306
+ className: namespaceClassName("dialog-overlay"),
307
+ selector: ".rt-AlertDialogOverlay",
308
+ });
309
+
310
+ return (
311
+ <RadixAlertDialog.Content
312
+ ref={ref}
313
+ className={cx("dialog", className)}
314
+ {...props}
315
+ {...element}
316
+ />
317
+ );
318
+ });
319
+
320
+ /**
321
+ * HACK: Radix themes does not expose the dialog overlay, but we want consumer
322
+ * to be able to style it with a classname. This will add a classname to the
323
+ * overlay when the dialog content is mounted.
324
+ */
325
+ function useDialogOverlayHack(
326
+ node: HTMLDivElement | null,
327
+ { className, selector }: { className: string; selector: string },
328
+ ) {
329
+ useLayoutEffect(() => {
330
+ if (!node) {
331
+ return;
332
+ }
333
+ const document = node.ownerDocument;
334
+ const overlay = document.querySelector<HTMLDivElement>(selector);
335
+ overlay?.classList.add(className);
336
+ }, [node, className, selector]);
337
+ }
157
338
 
158
339
  type OmitAsChild<T> = {
159
340
  [K in keyof T]: T[K] extends undefined
@@ -162,14 +343,17 @@ type OmitAsChild<T> = {
162
343
  };
163
344
 
164
345
  export type Elements = OmitAsChild<{
346
+ dialog?: GetPropDefTypes<typeof dialogContentPropDefs>;
165
347
  primaryButton?: GetPropDefTypes<typeof buttonPropDefs>;
166
348
  secondaryButton?: GetPropDefTypes<typeof buttonPropDefs>;
167
349
  destructiveButton?: GetPropDefTypes<typeof buttonPropDefs>;
168
350
  iconButton?: GetPropDefTypes<typeof iconButtonPropDefs>;
169
351
  textfield?: GetPropDefTypes<typeof textFieldRootPropDefs>;
352
+ select?: GetPropDefTypes<typeof selectTriggerPropDefs>;
170
353
  badge?: GetPropDefTypes<typeof badgePropDefs>;
171
354
  dropdown?: GetPropDefTypes<typeof dropdownMenuContentPropDefs>;
172
355
  primaryMenuItem?: GetPropDefTypes<typeof dropdownMenuItemPropDefs>;
173
356
  destructiveMenuItem?: GetPropDefTypes<typeof dropdownMenuItemPropDefs>;
174
357
  avatar?: Omit<GetPropDefTypes<typeof avatarPropDefs>, "fallback">;
358
+ label?: Omit<GetPropDefTypes<typeof textPropDefs>, "as">;
175
359
  }>;
@@ -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
+ }