@workos-inc/widgets 1.1.4 → 1.2.0
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/LICENSE +21 -0
- package/dist/cjs/lib/organization-switcher.d.ts +10 -1
- package/dist/cjs/lib/organization-switcher.d.ts.map +1 -1
- package/dist/cjs/lib/organization-switcher.js +31 -3
- package/dist/cjs/lib/organization-switcher.js.map +1 -1
- package/dist/cjs/workos-widgets.client.d.ts +6 -0
- package/dist/cjs/workos-widgets.client.d.ts.map +1 -1
- package/dist/cjs/workos-widgets.client.js +23 -3
- package/dist/cjs/workos-widgets.client.js.map +1 -1
- package/dist/esm/lib/organization-switcher.d.ts +10 -1
- package/dist/esm/lib/organization-switcher.d.ts.map +1 -1
- package/dist/esm/lib/organization-switcher.js +31 -3
- package/dist/esm/lib/organization-switcher.js.map +1 -1
- package/dist/esm/workos-widgets.client.d.ts +6 -0
- package/dist/esm/workos-widgets.client.d.ts.map +1 -1
- package/dist/esm/workos-widgets.client.js +25 -5
- package/dist/esm/workos-widgets.client.js.map +1 -1
- package/package.json +40 -47
- package/src/api/api-provider.tsx +0 -158
- package/src/api/constants.ts +0 -1
- package/src/api/endpoint.ts +0 -3097
- package/src/api/errors.ts +0 -48
- package/src/api/index.ts +0 -2
- package/src/api/utils.ts +0 -42
- package/src/api/widgets-api-client.ts +0 -87
- package/src/card-list.tsx +0 -26
- package/src/index.ts +0 -9
- package/src/lib/add-mfa-dialog.tsx +0 -379
- package/src/lib/api/config.ts +0 -9
- package/src/lib/api/user.ts +0 -98
- package/src/lib/change-password-dialog.tsx +0 -290
- package/src/lib/constants.ts +0 -3
- package/src/lib/copy-button.tsx +0 -53
- package/src/lib/delete-user-dialog.tsx +0 -110
- package/src/lib/edit-user-profile-dialog.tsx +0 -181
- package/src/lib/edit-user-role-dialog.tsx +0 -178
- package/src/lib/elements.tsx +0 -428
- package/src/lib/elevated-access.tsx +0 -261
- package/src/lib/error-boundary.tsx +0 -166
- package/src/lib/errors.ts +0 -49
- package/src/lib/generic-error.tsx +0 -70
- package/src/lib/icon-panel.tsx +0 -26
- package/src/lib/icons.tsx +0 -21
- package/src/lib/invite-user-dialog.tsx +0 -327
- package/src/lib/logout-all-sessions-dialog.tsx +0 -82
- package/src/lib/logout-dialog.tsx +0 -85
- package/src/lib/marker.tsx +0 -39
- package/src/lib/oauth-icons.tsx +0 -138
- package/src/lib/organization-switcher.tsx +0 -156
- package/src/lib/otp-input.tsx +0 -276
- package/src/lib/resend-invite-dialog.tsx +0 -145
- package/src/lib/reset-mfa-dialog.tsx +0 -104
- package/src/lib/revoke-invite-dialog.tsx +0 -111
- package/src/lib/save-button.tsx +0 -113
- package/src/lib/search-provider.tsx +0 -51
- package/src/lib/set-password-dialog.tsx +0 -204
- package/src/lib/use-dialog-close.tsx +0 -19
- package/src/lib/use-is-hydrated.ts +0 -13
- package/src/lib/use-layout-effect.ts +0 -6
- package/src/lib/use-security-settings.tsx +0 -49
- package/src/lib/user-actions-dropdown.tsx +0 -157
- package/src/lib/user-profile.tsx +0 -227
- package/src/lib/user-security.tsx +0 -187
- package/src/lib/user-sessions.tsx +0 -204
- package/src/lib/users-filter.tsx +0 -62
- package/src/lib/users-management-context.tsx +0 -74
- package/src/lib/users-management-state.ts +0 -165
- package/src/lib/users-management.tsx +0 -594
- package/src/lib/users-search.tsx +0 -73
- package/src/lib/utils.ts +0 -131
- package/src/lib/widgets-context.ts +0 -29
- package/src/organization-switcher.client.tsx +0 -81
- package/src/user-profile.client.tsx +0 -55
- package/src/user-security.client.tsx +0 -55
- package/src/user-sessions.client.tsx +0 -100
- package/src/users-management.client.tsx +0 -73
- package/src/workos-widgets.client.tsx +0 -75
- /package/{src → dist/css}/base.css +0 -0
- /package/{src → dist/css}/lib/card-list.css +0 -0
- /package/{src → dist/css}/lib/marker.css +0 -0
- /package/{src → dist/css}/lib/save-button.css +0 -0
- /package/{src → dist/css}/styles.css +0 -0
- /package/{src → dist/css}/users-management.css +0 -0
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import {
|
|
5
|
-
Callout,
|
|
6
|
-
Dialog,
|
|
7
|
-
Flex,
|
|
8
|
-
Select,
|
|
9
|
-
Text,
|
|
10
|
-
VisuallyHidden,
|
|
11
|
-
} from "@radix-ui/themes";
|
|
12
|
-
import { type ReactNode, useState } from "react";
|
|
13
|
-
import { useUpdateUserRole } from "./api/user";
|
|
14
|
-
import {
|
|
15
|
-
DialogContent,
|
|
16
|
-
PrimaryButton,
|
|
17
|
-
SecondaryButton,
|
|
18
|
-
SelectContent,
|
|
19
|
-
SelectItem,
|
|
20
|
-
SelectTrigger,
|
|
21
|
-
Skeleton,
|
|
22
|
-
} from "./elements";
|
|
23
|
-
import { getBestName } from "./utils";
|
|
24
|
-
import { Member, useRoles } from "../api";
|
|
25
|
-
|
|
26
|
-
interface EditUserRoleDialogProps extends Dialog.RootProps {
|
|
27
|
-
open: boolean;
|
|
28
|
-
onOpenChange: (open: boolean) => void;
|
|
29
|
-
user: Member;
|
|
30
|
-
children?: ReactNode;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function EditUserRoleDialog({
|
|
34
|
-
children,
|
|
35
|
-
user,
|
|
36
|
-
...props
|
|
37
|
-
}: EditUserRoleDialogProps) {
|
|
38
|
-
const displayName = getBestName(user) || user.email;
|
|
39
|
-
const rolesQuery = useRoles({
|
|
40
|
-
query: {
|
|
41
|
-
initialData: [],
|
|
42
|
-
},
|
|
43
|
-
});
|
|
44
|
-
const { data: roles } = rolesQuery;
|
|
45
|
-
const updateUser = useUpdateUserRole();
|
|
46
|
-
const [selectedRole, setSelectedRole] = useState(
|
|
47
|
-
user.roles?.at(0)?.slug || "Unknown",
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
const onSubmitForm = ({ id, roles }: { id: string; roles: string[] }) => {
|
|
51
|
-
updateUser.mutate(
|
|
52
|
-
{ userId: id, data: { roles } },
|
|
53
|
-
{
|
|
54
|
-
onSuccess: () => {
|
|
55
|
-
props.onOpenChange(false);
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const rootId = React.useId();
|
|
62
|
-
const formId = `edit-user-form-${rootId}`;
|
|
63
|
-
const selectId = `role-select-${rootId}`;
|
|
64
|
-
const selectLabelId = `${selectId}-label`;
|
|
65
|
-
const infoId = `${selectId}-info`;
|
|
66
|
-
const errorId = `${selectId}-error`;
|
|
67
|
-
const showErrorMessage = !!rolesQuery.error;
|
|
68
|
-
const showSingleRoleInfo = rolesQuery.isSuccess && roles.length === 1;
|
|
69
|
-
|
|
70
|
-
return (
|
|
71
|
-
<Dialog.Root {...props}>
|
|
72
|
-
{children && <Dialog.Trigger>{children}</Dialog.Trigger>}
|
|
73
|
-
<DialogContent maxWidth="480px">
|
|
74
|
-
<Dialog.Title>Edit role</Dialog.Title>
|
|
75
|
-
<Dialog.Description>
|
|
76
|
-
Select the role to assign to <Text weight="bold">{displayName}</Text>
|
|
77
|
-
</Dialog.Description>
|
|
78
|
-
<Flex mt="2" direction="column" gap="1" asChild>
|
|
79
|
-
<form
|
|
80
|
-
id={formId}
|
|
81
|
-
onSubmit={async (event) => {
|
|
82
|
-
event.preventDefault();
|
|
83
|
-
onSubmitForm({ id: user.id, roles: [selectedRole] });
|
|
84
|
-
}}
|
|
85
|
-
>
|
|
86
|
-
<Select.Root
|
|
87
|
-
name="roles"
|
|
88
|
-
value={selectedRole ?? "Unknown"}
|
|
89
|
-
onValueChange={setSelectedRole}
|
|
90
|
-
disabled={rolesQuery.isLoading || showSingleRoleInfo}
|
|
91
|
-
>
|
|
92
|
-
<Skeleton loading={rolesQuery.isLoading}>
|
|
93
|
-
<SelectTrigger
|
|
94
|
-
id={selectId}
|
|
95
|
-
placeholder="Assign a role"
|
|
96
|
-
aria-labelledby={selectLabelId}
|
|
97
|
-
aria-invalid={showErrorMessage || undefined}
|
|
98
|
-
aria-describedby={
|
|
99
|
-
[showErrorMessage && errorId, showSingleRoleInfo && infoId]
|
|
100
|
-
.filter(Boolean)
|
|
101
|
-
.join(" ") || undefined
|
|
102
|
-
}
|
|
103
|
-
/>
|
|
104
|
-
</Skeleton>
|
|
105
|
-
|
|
106
|
-
<SelectContent>
|
|
107
|
-
{roles.map((role) => (
|
|
108
|
-
<SelectItem key={role.slug} value={role.slug}>
|
|
109
|
-
{role.name}
|
|
110
|
-
</SelectItem>
|
|
111
|
-
))}
|
|
112
|
-
</SelectContent>
|
|
113
|
-
</Select.Root>
|
|
114
|
-
|
|
115
|
-
{showErrorMessage ? (
|
|
116
|
-
<Text color="red" size="2" id={errorId}>
|
|
117
|
-
{getRoleSelectErrorMessage(rolesQuery.error)}
|
|
118
|
-
</Text>
|
|
119
|
-
) : null}
|
|
120
|
-
|
|
121
|
-
{showSingleRoleInfo ? (
|
|
122
|
-
<Text color="gray" size="2" id={infoId} mt="1">
|
|
123
|
-
You cannot update the role for this user as there is only one
|
|
124
|
-
role available.
|
|
125
|
-
</Text>
|
|
126
|
-
) : null}
|
|
127
|
-
</form>
|
|
128
|
-
</Flex>
|
|
129
|
-
|
|
130
|
-
{updateUser.error ? (
|
|
131
|
-
<Callout.Root color="red" mt="4" mb="-2">
|
|
132
|
-
<Callout.Text>
|
|
133
|
-
{getMutationErrorMessage(updateUser.error)}
|
|
134
|
-
</Callout.Text>
|
|
135
|
-
</Callout.Root>
|
|
136
|
-
) : null}
|
|
137
|
-
|
|
138
|
-
<Flex mt="5" gap="3" justify="end">
|
|
139
|
-
<Dialog.Close>
|
|
140
|
-
<SecondaryButton disabled={updateUser.isPending}>
|
|
141
|
-
Cancel
|
|
142
|
-
</SecondaryButton>
|
|
143
|
-
</Dialog.Close>
|
|
144
|
-
|
|
145
|
-
<PrimaryButton
|
|
146
|
-
form={formId}
|
|
147
|
-
loading={updateUser.isPending}
|
|
148
|
-
disabled={rolesQuery.isLoading || showSingleRoleInfo || undefined}
|
|
149
|
-
>
|
|
150
|
-
Save
|
|
151
|
-
</PrimaryButton>
|
|
152
|
-
</Flex>
|
|
153
|
-
{/* mirror errors in a live region */}
|
|
154
|
-
<VisuallyHidden asChild>
|
|
155
|
-
<section aria-live="polite">
|
|
156
|
-
{getMutationErrorMessage(updateUser.error)}
|
|
157
|
-
</section>
|
|
158
|
-
</VisuallyHidden>
|
|
159
|
-
</DialogContent>
|
|
160
|
-
</Dialog.Root>
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function getRoleSelectErrorMessage(error: unknown) {
|
|
165
|
-
if (!error) {
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
|
-
// TODO Handle server errors
|
|
169
|
-
return "There was an error fetching roles. Please try again.";
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function getMutationErrorMessage(error: unknown) {
|
|
173
|
-
if (!error) {
|
|
174
|
-
return null;
|
|
175
|
-
}
|
|
176
|
-
// TODO Handle server errors
|
|
177
|
-
return "There was an error updating the user role. Please try again.";
|
|
178
|
-
}
|
package/src/lib/elements.tsx
DELETED
|
@@ -1,428 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import {
|
|
5
|
-
AlertDialog as RadixAlertDialog,
|
|
6
|
-
Avatar as RadixAvatar,
|
|
7
|
-
AvatarProps as RadixAvatarProps,
|
|
8
|
-
Badge as RadixBadge,
|
|
9
|
-
Button as RadixButton,
|
|
10
|
-
Dialog as RadixDialog,
|
|
11
|
-
DropdownMenu as RadixDropdownMenu,
|
|
12
|
-
IconButton as RadixIconButton,
|
|
13
|
-
Select as RadixSelect,
|
|
14
|
-
Skeleton as RadixSkeleton,
|
|
15
|
-
Text,
|
|
16
|
-
TextField as RadixTextField,
|
|
17
|
-
type BadgeProps,
|
|
18
|
-
type ButtonProps,
|
|
19
|
-
type IconButtonProps,
|
|
20
|
-
type SkeletonProps,
|
|
21
|
-
type TextProps,
|
|
22
|
-
} from "@radix-ui/themes";
|
|
23
|
-
import type {
|
|
24
|
-
GetPropDefTypes,
|
|
25
|
-
avatarPropDefs,
|
|
26
|
-
badgePropDefs,
|
|
27
|
-
buttonPropDefs,
|
|
28
|
-
dialogContentPropDefs,
|
|
29
|
-
dropdownMenuContentPropDefs,
|
|
30
|
-
dropdownMenuItemPropDefs,
|
|
31
|
-
iconButtonPropDefs,
|
|
32
|
-
textPropDefs,
|
|
33
|
-
textFieldRootPropDefs,
|
|
34
|
-
selectTriggerPropDefs,
|
|
35
|
-
skeletonPropDefs,
|
|
36
|
-
} from "@radix-ui/themes/props";
|
|
37
|
-
import { useComposedRefs } from "@radix-ui/react-compose-refs";
|
|
38
|
-
import cx from "clsx";
|
|
39
|
-
import { useElement } from "./widgets-context";
|
|
40
|
-
import { namespaceClassNames } from "./utils";
|
|
41
|
-
import { useLayoutEffect } from "./use-layout-effect";
|
|
42
|
-
import { EyeClosedIcon, EyeOpenIcon } from "@radix-ui/react-icons";
|
|
43
|
-
|
|
44
|
-
export const PrimaryButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
45
|
-
function PrimaryButton({ className, ...props }, ref) {
|
|
46
|
-
const element = useElement("primaryButton");
|
|
47
|
-
return (
|
|
48
|
-
<RadixButton
|
|
49
|
-
ref={ref}
|
|
50
|
-
className={cx(
|
|
51
|
-
namespaceClassNames("button", "button--primary"),
|
|
52
|
-
className,
|
|
53
|
-
)}
|
|
54
|
-
variant="solid"
|
|
55
|
-
{...props}
|
|
56
|
-
{...element}
|
|
57
|
-
/>
|
|
58
|
-
);
|
|
59
|
-
},
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
export const SecondaryButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
63
|
-
function SecondaryButton({ className, ...props }, ref) {
|
|
64
|
-
const element = useElement("secondaryButton");
|
|
65
|
-
return (
|
|
66
|
-
<RadixButton
|
|
67
|
-
ref={ref}
|
|
68
|
-
highContrast
|
|
69
|
-
className={cx(
|
|
70
|
-
namespaceClassNames("button", "button--secondary"),
|
|
71
|
-
className,
|
|
72
|
-
)}
|
|
73
|
-
variant="surface"
|
|
74
|
-
color="gray"
|
|
75
|
-
{...props}
|
|
76
|
-
{...element}
|
|
77
|
-
/>
|
|
78
|
-
);
|
|
79
|
-
},
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
export const DestructiveButton = React.forwardRef<
|
|
83
|
-
HTMLButtonElement,
|
|
84
|
-
ButtonProps
|
|
85
|
-
>(function DestructiveButton({ className, ...props }, ref) {
|
|
86
|
-
const element = useElement("destructiveButton");
|
|
87
|
-
return (
|
|
88
|
-
<RadixButton
|
|
89
|
-
ref={ref}
|
|
90
|
-
className={cx(
|
|
91
|
-
namespaceClassNames("button", "button--destructive"),
|
|
92
|
-
className,
|
|
93
|
-
)}
|
|
94
|
-
variant="solid"
|
|
95
|
-
color="red"
|
|
96
|
-
{...props}
|
|
97
|
-
{...element}
|
|
98
|
-
/>
|
|
99
|
-
);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
export const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(
|
|
103
|
-
function IconButton({ className, ...props }, ref) {
|
|
104
|
-
const element = useElement("iconButton");
|
|
105
|
-
return (
|
|
106
|
-
<RadixIconButton
|
|
107
|
-
ref={ref}
|
|
108
|
-
className={cx(namespaceClassNames("button", "icon-button"), className)}
|
|
109
|
-
variant="ghost"
|
|
110
|
-
color="gray"
|
|
111
|
-
{...props}
|
|
112
|
-
{...element}
|
|
113
|
-
/>
|
|
114
|
-
);
|
|
115
|
-
},
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
export const Skeleton = React.forwardRef<HTMLSpanElement, SkeletonProps>(
|
|
119
|
-
function Skeleton({ className, ...props }, ref) {
|
|
120
|
-
const element = useElement("skeleton");
|
|
121
|
-
return (
|
|
122
|
-
<RadixSkeleton
|
|
123
|
-
ref={ref}
|
|
124
|
-
className={cx(namespaceClassNames("skeleton"), className)}
|
|
125
|
-
{...props}
|
|
126
|
-
{...element}
|
|
127
|
-
/>
|
|
128
|
-
);
|
|
129
|
-
},
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
export const SelectTrigger = React.forwardRef<
|
|
133
|
-
HTMLButtonElement,
|
|
134
|
-
RadixSelect.TriggerProps
|
|
135
|
-
>(function SelectTrigger({ className, ...props }, ref) {
|
|
136
|
-
const element = useElement("select");
|
|
137
|
-
return (
|
|
138
|
-
<RadixSelect.Trigger
|
|
139
|
-
ref={ref}
|
|
140
|
-
className={cx(namespaceClassNames("select"), className)}
|
|
141
|
-
{...props}
|
|
142
|
-
{...element}
|
|
143
|
-
/>
|
|
144
|
-
);
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
export const SelectContent = React.forwardRef<
|
|
148
|
-
HTMLDivElement,
|
|
149
|
-
RadixSelect.ContentProps
|
|
150
|
-
>(function SelectContent({ className, ...props }, ref) {
|
|
151
|
-
const element = useElement("dropdown");
|
|
152
|
-
return (
|
|
153
|
-
<RadixSelect.Content
|
|
154
|
-
ref={ref}
|
|
155
|
-
className={cx(
|
|
156
|
-
namespaceClassNames("dropdown", "select-dropdown"),
|
|
157
|
-
className,
|
|
158
|
-
)}
|
|
159
|
-
{...props}
|
|
160
|
-
{...element}
|
|
161
|
-
/>
|
|
162
|
-
);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
export const SelectItem = React.forwardRef<
|
|
166
|
-
HTMLDivElement,
|
|
167
|
-
RadixSelect.ItemProps
|
|
168
|
-
>(function SelectItem({ className, ...props }, ref) {
|
|
169
|
-
const element = useElement("primaryMenuItem");
|
|
170
|
-
return (
|
|
171
|
-
<RadixSelect.Item
|
|
172
|
-
ref={ref}
|
|
173
|
-
className={cx(namespaceClassNames("menu-item", "select-item"), className)}
|
|
174
|
-
{...props}
|
|
175
|
-
{...element}
|
|
176
|
-
/>
|
|
177
|
-
);
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
export const Label = React.forwardRef<HTMLLabelElement, TextProps>(
|
|
181
|
-
function Label({ children, className, style = {}, ...props }, ref) {
|
|
182
|
-
const element = useElement("label");
|
|
183
|
-
return (
|
|
184
|
-
// @ts-expect-error: Text props are a complex union type depending on the
|
|
185
|
-
// `as` prop value, which breaks down when spreading in `element`
|
|
186
|
-
<Text
|
|
187
|
-
as="label"
|
|
188
|
-
ref={ref}
|
|
189
|
-
weight="bold"
|
|
190
|
-
size="2"
|
|
191
|
-
className={cx(namespaceClassNames("label"), className)}
|
|
192
|
-
style={{ width: "fit-content", ...style }}
|
|
193
|
-
{...props}
|
|
194
|
-
{...element}
|
|
195
|
-
>
|
|
196
|
-
{children}
|
|
197
|
-
</Text>
|
|
198
|
-
);
|
|
199
|
-
},
|
|
200
|
-
);
|
|
201
|
-
|
|
202
|
-
export const TextField = React.forwardRef<
|
|
203
|
-
HTMLInputElement,
|
|
204
|
-
RadixTextField.RootProps
|
|
205
|
-
>(function TextField({ className, ...props }, ref) {
|
|
206
|
-
const element = useElement("textfield");
|
|
207
|
-
return (
|
|
208
|
-
<RadixTextField.Root
|
|
209
|
-
ref={ref}
|
|
210
|
-
variant="surface"
|
|
211
|
-
className={cx(namespaceClassNames("text-field"), className)}
|
|
212
|
-
{...props}
|
|
213
|
-
{...element}
|
|
214
|
-
/>
|
|
215
|
-
);
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
export const TextFieldSlot = React.forwardRef<
|
|
219
|
-
HTMLDivElement,
|
|
220
|
-
RadixTextField.SlotProps
|
|
221
|
-
>(function TextFieldSlot({ className, ...props }, ref) {
|
|
222
|
-
return (
|
|
223
|
-
<RadixTextField.Slot
|
|
224
|
-
ref={ref}
|
|
225
|
-
className={cx(namespaceClassNames("text-field-slot"), className)}
|
|
226
|
-
{...props}
|
|
227
|
-
/>
|
|
228
|
-
);
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
export const PasswordField = React.forwardRef<
|
|
232
|
-
HTMLInputElement,
|
|
233
|
-
RadixTextField.RootProps
|
|
234
|
-
>(function TextField({ className, ...props }, ref) {
|
|
235
|
-
const element = useElement("textfield");
|
|
236
|
-
const [showPassword, setShowPassword] = React.useState(false);
|
|
237
|
-
return (
|
|
238
|
-
<RadixTextField.Root
|
|
239
|
-
ref={ref}
|
|
240
|
-
variant="surface"
|
|
241
|
-
className={cx(namespaceClassNames("text-field"), className)}
|
|
242
|
-
{...props}
|
|
243
|
-
{...element}
|
|
244
|
-
type={showPassword ? "text" : "password"}
|
|
245
|
-
>
|
|
246
|
-
<RadixTextField.Slot side="right">
|
|
247
|
-
<IconButton
|
|
248
|
-
type="button"
|
|
249
|
-
size="1"
|
|
250
|
-
variant="ghost"
|
|
251
|
-
color="gray"
|
|
252
|
-
onClick={() => setShowPassword(!showPassword)}
|
|
253
|
-
>
|
|
254
|
-
{showPassword ? <EyeOpenIcon /> : <EyeClosedIcon />}
|
|
255
|
-
</IconButton>
|
|
256
|
-
</RadixTextField.Slot>
|
|
257
|
-
</RadixTextField.Root>
|
|
258
|
-
);
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
export const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(
|
|
262
|
-
function Badge({ className, ...props }, ref) {
|
|
263
|
-
const element = useElement("badge");
|
|
264
|
-
return (
|
|
265
|
-
<RadixBadge
|
|
266
|
-
ref={ref}
|
|
267
|
-
className={cx(namespaceClassNames("badge"), className)}
|
|
268
|
-
{...element}
|
|
269
|
-
{...props}
|
|
270
|
-
/>
|
|
271
|
-
);
|
|
272
|
-
},
|
|
273
|
-
);
|
|
274
|
-
|
|
275
|
-
export const DropdownMenuContent = React.forwardRef<
|
|
276
|
-
HTMLDivElement,
|
|
277
|
-
RadixDropdownMenu.ContentProps
|
|
278
|
-
>(function DropdownMenuContent({ className, ...props }, ref) {
|
|
279
|
-
const element = useElement("dropdown");
|
|
280
|
-
return (
|
|
281
|
-
<RadixDropdownMenu.Content
|
|
282
|
-
ref={ref}
|
|
283
|
-
className={cx(namespaceClassNames("dropdown"), className)}
|
|
284
|
-
{...props}
|
|
285
|
-
{...element}
|
|
286
|
-
/>
|
|
287
|
-
);
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
export const PrimaryMenuItem = React.forwardRef<
|
|
291
|
-
HTMLDivElement,
|
|
292
|
-
RadixDropdownMenu.ItemProps
|
|
293
|
-
>(function PrimaryMenuItem({ className, ...props }, ref) {
|
|
294
|
-
const element = useElement("primaryMenuItem");
|
|
295
|
-
return (
|
|
296
|
-
<RadixDropdownMenu.Item
|
|
297
|
-
ref={ref}
|
|
298
|
-
className={cx(namespaceClassNames("menu-item"), className)}
|
|
299
|
-
{...props}
|
|
300
|
-
{...element}
|
|
301
|
-
/>
|
|
302
|
-
);
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
export const DestructiveMenuItem = React.forwardRef<
|
|
306
|
-
HTMLDivElement,
|
|
307
|
-
RadixDropdownMenu.ItemProps
|
|
308
|
-
>(function DestructiveMenuItem({ className, ...props }, ref) {
|
|
309
|
-
const element = useElement("destructiveMenuItem");
|
|
310
|
-
return (
|
|
311
|
-
<RadixDropdownMenu.Item
|
|
312
|
-
ref={ref}
|
|
313
|
-
className={cx(
|
|
314
|
-
namespaceClassNames("menu-item", "menu-item--destructive"),
|
|
315
|
-
className,
|
|
316
|
-
)}
|
|
317
|
-
color="red"
|
|
318
|
-
{...props}
|
|
319
|
-
{...element}
|
|
320
|
-
/>
|
|
321
|
-
);
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
interface AvatarProps extends RadixAvatarProps {
|
|
325
|
-
dim?: boolean;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
export const Avatar = React.forwardRef<HTMLImageElement, AvatarProps>(
|
|
329
|
-
function Avatar({ dim, className, ...props }, ref) {
|
|
330
|
-
const element = useElement("avatar");
|
|
331
|
-
return (
|
|
332
|
-
<RadixAvatar
|
|
333
|
-
ref={ref}
|
|
334
|
-
color="gray"
|
|
335
|
-
className={cx(namespaceClassNames("avatar"), className)}
|
|
336
|
-
{...props}
|
|
337
|
-
{...element}
|
|
338
|
-
// TODO: use CSS var instead of hard-coded value for opacity
|
|
339
|
-
style={dim ? { opacity: 0.6, ...props.style } : props.style}
|
|
340
|
-
/>
|
|
341
|
-
);
|
|
342
|
-
},
|
|
343
|
-
);
|
|
344
|
-
|
|
345
|
-
export const DialogContent = React.forwardRef<
|
|
346
|
-
HTMLDivElement,
|
|
347
|
-
RadixDialog.ContentProps
|
|
348
|
-
>(function DialogContent({ className, ...props }, forwardedRef) {
|
|
349
|
-
const element = useElement("dialog");
|
|
350
|
-
const [node, setNode] = React.useState<HTMLDivElement | null>(null);
|
|
351
|
-
const ref = useComposedRefs(forwardedRef, setNode as any);
|
|
352
|
-
useDialogOverlayHack(node, {
|
|
353
|
-
className: namespaceClassNames("dialog-overlay"),
|
|
354
|
-
selector: ".rt-DialogOverlay",
|
|
355
|
-
});
|
|
356
|
-
return (
|
|
357
|
-
<RadixDialog.Content
|
|
358
|
-
ref={ref}
|
|
359
|
-
className={cx(namespaceClassNames("dialog"), className)}
|
|
360
|
-
{...props}
|
|
361
|
-
{...element}
|
|
362
|
-
/>
|
|
363
|
-
);
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
export const AlertDialogContent = React.forwardRef<
|
|
367
|
-
HTMLDivElement,
|
|
368
|
-
RadixAlertDialog.ContentProps
|
|
369
|
-
>(function AlertDialogContent({ className, ...props }, forwardedRef) {
|
|
370
|
-
const element = useElement("dialog");
|
|
371
|
-
const [node, setNode] = React.useState<HTMLDivElement | null>(null);
|
|
372
|
-
const ref = useComposedRefs(forwardedRef, setNode as any);
|
|
373
|
-
useDialogOverlayHack(node, {
|
|
374
|
-
className: namespaceClassNames("dialog-overlay"),
|
|
375
|
-
selector: ".rt-AlertDialogOverlay",
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
return (
|
|
379
|
-
<RadixAlertDialog.Content
|
|
380
|
-
ref={ref}
|
|
381
|
-
className={cx(namespaceClassNames("dialog"), className)}
|
|
382
|
-
{...props}
|
|
383
|
-
{...element}
|
|
384
|
-
/>
|
|
385
|
-
);
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
/**
|
|
389
|
-
* HACK: Radix themes does not expose the dialog overlay, but we want consumer
|
|
390
|
-
* to be able to style it with a classname. This will add a classname to the
|
|
391
|
-
* overlay when the dialog content is mounted.
|
|
392
|
-
*/
|
|
393
|
-
function useDialogOverlayHack(
|
|
394
|
-
node: HTMLDivElement | null,
|
|
395
|
-
{ className, selector }: { className: string; selector: string },
|
|
396
|
-
) {
|
|
397
|
-
useLayoutEffect(() => {
|
|
398
|
-
if (!node) {
|
|
399
|
-
return;
|
|
400
|
-
}
|
|
401
|
-
const document = node.ownerDocument;
|
|
402
|
-
const overlay = document.querySelector<HTMLDivElement>(selector);
|
|
403
|
-
overlay?.classList.add(className);
|
|
404
|
-
}, [node, className, selector]);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
type OmitAsChild<T> = {
|
|
408
|
-
[K in keyof T]: T[K] extends undefined
|
|
409
|
-
? undefined
|
|
410
|
-
: Omit<NonNullable<T[K]>, "asChild">;
|
|
411
|
-
};
|
|
412
|
-
|
|
413
|
-
export type Elements = OmitAsChild<{
|
|
414
|
-
dialog?: GetPropDefTypes<typeof dialogContentPropDefs>;
|
|
415
|
-
primaryButton?: GetPropDefTypes<typeof buttonPropDefs>;
|
|
416
|
-
secondaryButton?: GetPropDefTypes<typeof buttonPropDefs>;
|
|
417
|
-
destructiveButton?: GetPropDefTypes<typeof buttonPropDefs>;
|
|
418
|
-
iconButton?: GetPropDefTypes<typeof iconButtonPropDefs>;
|
|
419
|
-
textfield?: GetPropDefTypes<typeof textFieldRootPropDefs>;
|
|
420
|
-
select?: GetPropDefTypes<typeof selectTriggerPropDefs>;
|
|
421
|
-
badge?: GetPropDefTypes<typeof badgePropDefs>;
|
|
422
|
-
dropdown?: GetPropDefTypes<typeof dropdownMenuContentPropDefs>;
|
|
423
|
-
primaryMenuItem?: GetPropDefTypes<typeof dropdownMenuItemPropDefs>;
|
|
424
|
-
destructiveMenuItem?: GetPropDefTypes<typeof dropdownMenuItemPropDefs>;
|
|
425
|
-
avatar?: Omit<GetPropDefTypes<typeof avatarPropDefs>, "fallback">;
|
|
426
|
-
label?: GetPropDefTypes<typeof textPropDefs>;
|
|
427
|
-
skeleton?: GetPropDefTypes<typeof skeletonPropDefs>;
|
|
428
|
-
}>;
|