+ AlertDialogHeader
+
+
+ Contains the header content of the dialog, including the title and description.
+
+
+ Same props as a {""} element.
+
+
+
+
+ AlertDialogFooter
+
+
+ Contains the footer content of the dialog, including the action and cancel buttons.
+
+
+ Same props as a {""} element.
+
+
+
+
+ AlertDialogTitle
+
+ An accessible name to be announced when the dialog is opened.
+
+ Alternatively, you can provide aria-label or{" "}
+ aria-labelledby to AlertDialogContent and exclude this
+ component.
+
+
+ Radix{" "}
+
+ AlertDialog.Title
+ {" "}
+ props.
+
+
+
+
+ AlertDialogDescription
+
+ An accessible description to be announced when the dialog is opened.
+
+ Alternatively, you can provide aria-describedby to{" "}
+ AlertDialogContent and exclude this component.
+
+
+ Radix{" "}
+
+ AlertDialog.Description
+ {" "}
+ props.
+
+
+
+
+ AlertDialogAction
+
+
+ A button that closes the alert dialog and confirms the action. Will default to{" "}
+ appearance="filled" , as well as the priority color from the{" "}
+ AlertDialog
+
+
+ These buttons should be distinguished visually from the AlertDialogCancel button.
+
+
+ Composes around the mantle Button component.
+
+
+ Same props as the Button component.
+
+
+
+
+ AlertDialogCancel
+
+
+ A button that closes the dialog and cancels the action. Will default to{" "}
+ appearance="outlined" and priority="neutral" .
+
+
+ This button should be distinguished visually from AlertDialogAction buttons.
+
+
+ Composes around the mantle Button component.
+
+
+ Same props as the Button component.
+
+
+
+
+ );
+}
diff --git a/apps/www/app/types/routes.ts b/apps/www/app/types/routes.ts
index 260ff55c..6ec9d87f 100644
--- a/apps/www/app/types/routes.ts
+++ b/apps/www/app/types/routes.ts
@@ -22,6 +22,7 @@ export const routePatterns = [
"/components/label",
"/components/media-object",
"/components/password-input",
+ "/components/preview/alert-dialog",
"/components/preview/calendar",
"/components/preview/pagination",
"/components/preview/popover",
@@ -69,6 +70,7 @@ export const routes = [
"/components/label",
"/components/media-object",
"/components/password-input",
+ "/components/preview/alert-dialog",
"/components/preview/calendar",
"/components/preview/pagination",
"/components/preview/popover",
diff --git a/packages/mantle/package.json b/packages/mantle/package.json
index 250399d2..6c49844d 100644
--- a/packages/mantle/package.json
+++ b/packages/mantle/package.json
@@ -3,7 +3,7 @@
"description": "mantle is ngrok's UI library and design system.",
"author": "ngrok",
"license": "MIT",
- "version": "0.12.1",
+ "version": "0.13.0",
"homepage": "https://mantle.ngrok.com",
"repository": {
"type": "git",
@@ -37,6 +37,7 @@
},
"dependencies": {
"@headlessui/react": "2.2.0",
+ "@radix-ui/react-alert-dialog": "1.1.2",
"@radix-ui/react-dialog": "1.1.2",
"@radix-ui/react-dropdown-menu": "2.1.2",
"@radix-ui/react-popover": "1.1.2",
@@ -96,183 +97,187 @@
"./mantle.css": "./assets/mantle.css",
"./package.json": "./package.json",
"./tailwind-preset": {
- "@ngrok/mantle/source": "./src/tailwind-preset/index.ts",
+ "@ngrok/mantle/source": "./src/tailwind-preset/index.ts",
"types": "./dist/tailwind-preset.d.ts",
"import": "./dist/tailwind-preset.js",
"require": "./dist/tailwind-preset.cjs"
},
"./alert": {
- "@ngrok/mantle/source": "./src/components/alert/index.ts",
+ "@ngrok/mantle/source": "./src/components/alert/index.ts",
"import": "./dist/alert.js",
"types": "./dist/alert.d.ts"
},
+ "./alert-dialog": {
+ "@ngrok/mantle/source": "./src/components/alert-dialog/index.ts",
+ "import": "./dist/alert-dialog.js",
+ "types": "./dist/alert-dialog.d.ts"
+ },
"./anchor": {
- "@ngrok/mantle/source": "./src/components/anchor/index.ts",
+ "@ngrok/mantle/source": "./src/components/anchor/index.ts",
"import": "./dist/anchor.js",
"types": "./dist/anchor.d.ts"
},
"./badge": {
- "@ngrok/mantle/source": "./src/components/badge/index.ts",
+ "@ngrok/mantle/source": "./src/components/badge/index.ts",
"import": "./dist/badge.js",
"types": "./dist/badge.d.ts"
},
"./button": {
- "@ngrok/mantle/source": "./src/components/button/index.ts",
+ "@ngrok/mantle/source": "./src/components/button/index.ts",
"import": "./dist/button.js",
"types": "./dist/button.d.ts"
},
"./calendar": {
- "@ngrok/mantle/source": "./src/components/calendar/index.ts",
+ "@ngrok/mantle/source": "./src/components/calendar/index.ts",
"import": "./dist/calendar.js",
"types": "./dist/calendar.d.ts"
},
"./card": {
- "@ngrok/mantle/source": "./src/components/card/index.ts",
+ "@ngrok/mantle/source": "./src/components/card/index.ts",
"import": "./dist/card.js",
"types": "./dist/card.d.ts"
},
"./checkbox": {
- "@ngrok/mantle/source": "./src/components/checkbox/index.ts",
+ "@ngrok/mantle/source": "./src/components/checkbox/index.ts",
"import": "./dist/checkbox.js",
"types": "./dist/checkbox.d.ts"
},
"./code-block": {
- "@ngrok/mantle/source": "./src/components/code-block/index.ts",
+ "@ngrok/mantle/source": "./src/components/code-block/index.ts",
"import": "./dist/code-block.js",
"types": "./dist/code-block.d.ts"
},
"./color": {
- "@ngrok/mantle/source": "./src/utils/color/index.ts",
+ "@ngrok/mantle/source": "./src/utils/color/index.ts",
"import": "./dist/color.js",
"types": "./dist/color.d.ts"
},
"./compose-refs": {
- "@ngrok/mantle/source": "./src/utils/compose-refs/index.ts",
+ "@ngrok/mantle/source": "./src/utils/compose-refs/index.ts",
"import": "./dist/compose-refs.js",
"types": "./dist/compose-refs.d.ts"
},
"./cx": {
- "@ngrok/mantle/source": "./src/utils/cx/index.ts",
+ "@ngrok/mantle/source": "./src/utils/cx/index.ts",
"import": "./dist/cx.js",
"types": "./dist/cx.d.ts"
},
- "./data-table": {
- "@ngrok/mantle/source": "./src/components/data-table/index.ts"
- },
- "./date-picker": {
- },
+ "./data-table": {
+ "@ngrok/mantle/source": "./src/components/data-table/index.ts"
+ },
+ "./date-picker": {},
"./dialog": {
- "@ngrok/mantle/source": "./src/components/dialog/index.ts",
+ "@ngrok/mantle/source": "./src/components/dialog/index.ts",
"import": "./dist/dialog.js",
"types": "./dist/dialog.d.ts"
},
"./dropdown-menu": {
- "@ngrok/mantle/source": "./src/components/dropdown-menu/index.ts",
+ "@ngrok/mantle/source": "./src/components/dropdown-menu/index.ts",
"import": "./dist/dropdown-menu.js",
"types": "./dist/dropdown-menu.d.ts"
},
"./hooks": {
- "@ngrok/mantle/source": "./src/hooks/index.ts",
+ "@ngrok/mantle/source": "./src/hooks/index.ts",
"import": "./dist/hooks.js",
"types": "./dist/hooks.d.ts"
},
"./icon": {
- "@ngrok/mantle/source": "./src/components/icon/index.ts",
+ "@ngrok/mantle/source": "./src/components/icon/index.ts",
"import": "./dist/icon.js",
"types": "./dist/icon.d.ts"
},
"./inline-code": {
- "@ngrok/mantle/source": "./src/components/inline-code/index.ts",
+ "@ngrok/mantle/source": "./src/components/inline-code/index.ts",
"import": "./dist/inline-code.js",
"types": "./dist/inline-code.d.ts"
},
"./input": {
- "@ngrok/mantle/source": "./src/components/input/index.ts",
+ "@ngrok/mantle/source": "./src/components/input/index.ts",
"import": "./dist/input.js",
"types": "./dist/input.d.ts"
},
"./label": {
- "@ngrok/mantle/source": "./src/components/label/index.ts",
+ "@ngrok/mantle/source": "./src/components/label/index.ts",
"import": "./dist/label.js",
"types": "./dist/label.d.ts"
},
"./media-object": {
- "@ngrok/mantle/source": "./src/components/media-object/index.ts",
+ "@ngrok/mantle/source": "./src/components/media-object/index.ts",
"import": "./dist/media-object.js",
"types": "./dist/media-object.d.ts"
},
"./pagination": {
- "@ngrok/mantle/source": "./src/components/pagination/index.ts",
+ "@ngrok/mantle/source": "./src/components/pagination/index.ts",
"import": "./dist/pagination.js",
"types": "./dist/pagination.d.ts"
},
"./popover": {
- "@ngrok/mantle/source": "./src/components/popover/index.ts",
+ "@ngrok/mantle/source": "./src/components/popover/index.ts",
"import": "./dist/popover.js",
"types": "./dist/popover.d.ts"
},
"./progress": {
- "@ngrok/mantle/source": "./src/components/progress/index.ts",
+ "@ngrok/mantle/source": "./src/components/progress/index.ts",
"import": "./dist/progress.js",
"types": "./dist/progress.d.ts"
},
"./radio-group": {
- "@ngrok/mantle/source": "./src/components/radio-group/index.ts",
+ "@ngrok/mantle/source": "./src/components/radio-group/index.ts",
"import": "./dist/radio-group.js",
"types": "./dist/radio-group.d.ts"
},
"./select": {
- "@ngrok/mantle/source": "./src/components/select/index.ts",
+ "@ngrok/mantle/source": "./src/components/select/index.ts",
"import": "./dist/select.js",
"types": "./dist/select.d.ts"
},
"./separator": {
- "@ngrok/mantle/source": "./src/components/separator/index.ts",
+ "@ngrok/mantle/source": "./src/components/separator/index.ts",
"import": "./dist/separator.js",
"types": "./dist/separator.d.ts"
},
"./sheet": {
- "@ngrok/mantle/source": "./src/components/sheet/index.ts",
+ "@ngrok/mantle/source": "./src/components/sheet/index.ts",
"import": "./dist/sheet.js",
"types": "./dist/sheet.d.ts"
},
"./skeleton": {
- "@ngrok/mantle/source": "./src/components/skeleton/index.ts",
+ "@ngrok/mantle/source": "./src/components/skeleton/index.ts",
"import": "./dist/skeleton.js",
"types": "./dist/skeleton.d.ts"
},
"./switch": {
- "@ngrok/mantle/source": "./src/components/switch/index.ts",
+ "@ngrok/mantle/source": "./src/components/switch/index.ts",
"import": "./dist/switch.js",
"types": "./dist/switch.d.ts"
},
"./table": {
- "@ngrok/mantle/source": "./src/components/table/index.ts",
+ "@ngrok/mantle/source": "./src/components/table/index.ts",
"import": "./dist/table.js",
"types": "./dist/table.d.ts"
},
"./tabs": {
- "@ngrok/mantle/source": "./src/components/tabs/index.ts",
+ "@ngrok/mantle/source": "./src/components/tabs/index.ts",
"import": "./dist/tabs.js",
"types": "./dist/tabs.d.ts"
},
"./text-area": {
- "@ngrok/mantle/source": "./src/components/text-area/index.ts",
+ "@ngrok/mantle/source": "./src/components/text-area/index.ts",
"import": "./dist/text-area.js",
"types": "./dist/text-area.d.ts"
},
"./theme-provider": {
- "@ngrok/mantle/source": "./src/components/theme-provider/index.ts",
+ "@ngrok/mantle/source": "./src/components/theme-provider/index.ts",
"import": "./dist/theme-provider.js",
"types": "./dist/theme-provider.d.ts"
},
"./tooltip": {
- "@ngrok/mantle/source": "./src/components/tooltip/index.ts",
+ "@ngrok/mantle/source": "./src/components/tooltip/index.ts",
"import": "./dist/tooltip.js",
"types": "./dist/tooltip.d.ts"
},
"./types": {
- "@ngrok/mantle/source": "./src/types/index.ts",
+ "@ngrok/mantle/source": "./src/types/index.ts",
"types": "./dist/types.d.ts"
}
}
diff --git a/packages/mantle/src/components/alert-dialog/alert-dialog.tsx b/packages/mantle/src/components/alert-dialog/alert-dialog.tsx
new file mode 100644
index 00000000..818b757f
--- /dev/null
+++ b/packages/mantle/src/components/alert-dialog/alert-dialog.tsx
@@ -0,0 +1,279 @@
+"use client";
+
+import { Info } from "@phosphor-icons/react/Info";
+import { Warning } from "@phosphor-icons/react/Warning";
+import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
+import {
+ createContext,
+ forwardRef,
+ useContext,
+ type ComponentProps,
+ type ComponentPropsWithoutRef,
+ type ElementRef,
+ type ReactNode,
+} from "react";
+import invariant from "tiny-invariant";
+import { cx } from "../../utils/cx/cx.js";
+import { Button, type ButtonPriority, type ButtonProps } from "../button/button.js";
+import { IconBase } from "../icon/_icon-base.js";
+import type { SvgAttributes } from "../icon/types.js";
+
+const priorities = ["info", "danger"] as const;
+type Priority = (typeof priorities)[number];
+
+type AlertDialogContextValue = {
+ priority: Priority;
+};
+
+const AlertDialogContext = createContext(null);
+
+function useAlertDialogContext() {
+ const context = useContext(AlertDialogContext);
+ invariant(context, "AlertDialog child component used outside of AlertDialog parent!");
+ return context;
+}
+
+type AlertDialogProps = ComponentProps & {
+ /**
+ * Indicates the importance or impact level of the AlertDialog, affecting its
+ * color and styling to communicate its purpose to the user.
+ */
+ priority: Priority;
+};
+
+/**
+ * The root component for the Alert Dialog
+ */
+function AlertDialog({ priority, ...props }: AlertDialogProps) {
+ return (
+
+
+
+ );
+}
+
+/**
+ * A button that opens the Alert Dialog.
+ */
+const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
+
+const AlertDialogPortal = AlertDialogPrimitive.Portal;
+
+/**
+ * A layer that covers the inert portion of the view when the dialog is open.
+ */
+const AlertDialogOverlay = forwardRef<
+ ElementRef,
+ ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
+
+/**
+ * The popover alert dialog container.
+ *
+ * Renders on top of the overlay and is centered in the viewport.
+ */
+const AlertDialogContent = forwardRef<
+ ElementRef,
+ ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+
+));
+AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
+
+/**
+ * Contains the main content of the dialog.
+ */
+const AlertDialogBody = ({ className, ...props }: ComponentProps<"div">) => (
+
+);
+
+/**
+ * Contains the header content of the dialog, including the title and description.
+ */
+const AlertDialogHeader = ({ className, ...props }: ComponentProps<"div">) => (
+
+);
+AlertDialogHeader.displayName = "AlertDialogHeader";
+
+/**
+ * Contains the footer content of the dialog, including the action and cancel buttons.
+ */
+const AlertDialogFooter = ({ className, ...props }: ComponentProps<"div">) => (
+
+);
+AlertDialogFooter.displayName = "AlertDialogFooter";
+
+/**
+ * An accessible name to be announced when the dialog is opened.
+ *
+ * Alternatively, you can provide `aria-label` or `aria-labelledby` to
+ * `AlertDialogContent` and exclude this component.
+ */
+const AlertDialogTitle = forwardRef<
+ ElementRef,
+ ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
+
+/**
+ * An accessible description to be announced when the dialog is opened.
+ *
+ * Alternatively, you can provide `aria-describedby` to `AlertDialogContent` and
+ * exclude this component.
+ */
+const AlertDialogDescription = forwardRef<
+ ElementRef,
+ ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
+
+/**
+ * A button that closes the dialog and confirms the action.
+ * Will default to appearance="filled", as well as the priority color from the `AlertDialog`.
+ *
+ * These buttons should be distinguished visually from the AlertDialogCancel button.
+ *
+ * Composes around the mantle Button component.
+ */
+const AlertDialogAction = forwardRef, ButtonProps>(
+ (
+ {
+ //,
+ appearance = "filled",
+ ...props
+ },
+ ref,
+ ) => {
+ const ctx = useAlertDialogContext();
+ let buttonPriority: NonNullable = "default";
+ if (ctx.priority === "danger") {
+ buttonPriority = "danger";
+ }
+
+ return (
+
+
+
+ );
+ },
+);
+AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
+
+/**
+ * A button that closes the dialog and cancels the action.
+ * Will default to appearance="outlined" and priority="neutral".
+ *
+ * This button should be distinguished visually from AlertDialogAction buttons.
+ *
+ * Composes around the mantle Button component.
+ */
+const AlertDialogCancel = forwardRef, ButtonProps>(
+ (
+ {
+ //,
+ appearance = "outlined",
+ className,
+ priority = "neutral",
+ ...props
+ },
+ ref,
+ ) => (
+
+
+
+ ),
+);
+AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
+
+type AlertDialogIconProps = Omit & {
+ svg?: ReactNode;
+};
+
+/**
+ * An icon that visually represents the priority of the AlertDialog.
+ *
+ * Defaults to a warning icon for danger priority and an info icon for info
+ * priority with the appropriate color.
+ *
+ * Can be overridden with a custom icon using the `svg` prop.
+ */
+const AlertDialogIcon = forwardRef, AlertDialogIconProps>(({ className, svg, ...props }, ref) => {
+ const ctx = useAlertDialogContext();
+ const defaultColor = ctx.priority === "danger" ? "text-danger-600" : "text-accent-600";
+ const defaultIcon = ctx.priority === "danger" ? : ;
+
+ return (
+
+ );
+});
+AlertDialogIcon.displayName = "AlertDialogIcon";
+
+export {
+ //,
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogBody,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogIcon,
+ AlertDialogTitle,
+ AlertDialogTrigger,
+};
diff --git a/packages/mantle/src/components/alert-dialog/index.ts b/packages/mantle/src/components/alert-dialog/index.ts
new file mode 100644
index 00000000..afc3c7e4
--- /dev/null
+++ b/packages/mantle/src/components/alert-dialog/index.ts
@@ -0,0 +1,14 @@
+export {
+ //,
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogBody,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogIcon,
+ AlertDialogTitle,
+ AlertDialogTrigger,
+} from "./alert-dialog.js";
diff --git a/packages/mantle/src/components/button/button.tsx b/packages/mantle/src/components/button/button.tsx
index 19cfcb72..65bc5256 100644
--- a/packages/mantle/src/components/button/button.tsx
+++ b/packages/mantle/src/components/button/button.tsx
@@ -3,7 +3,7 @@ import { Slot } from "@radix-ui/react-slot";
import { cva } from "class-variance-authority";
import clsx from "clsx";
import { Children, cloneElement, forwardRef, isValidElement } from "react";
-import type { ButtonHTMLAttributes, PropsWithChildren, ReactNode } from "react";
+import type { ButtonHTMLAttributes, ComponentProps, PropsWithChildren, ReactNode } from "react";
import invariant from "tiny-invariant";
import { parseBooleanish } from "../../types/index.js";
import type { VariantProps } from "../../types/variant-props.js";
@@ -103,10 +103,13 @@ const buttonVariants = cva(
type ButtonVariants = VariantProps;
+type ButtonAppearance = Pick["appearance"];
+type ButtonPriority = Pick["priority"];
+
/**
* The props for the `Button` component.
*/
-type ButtonProps = ButtonHTMLAttributes &
+type ButtonProps = ComponentProps<"button"> &
ButtonVariants & {
/**
* An icon to render inside the button. If the `state` is `"pending"`, then
@@ -250,8 +253,18 @@ const Button = forwardRef(
);
Button.displayName = "Button";
-export { Button, buttonVariants };
-export type { ButtonProps };
+export {
+ //,
+ Button,
+ buttonVariants,
+};
+
+export type {
+ //,
+ ButtonProps,
+ ButtonAppearance,
+ ButtonPriority,
+};
type InnerContentProps = PropsWithChildren & Pick;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8c1cf374..85f77d66 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -159,6 +159,9 @@ importers:
'@headlessui/react':
specifier: 2.2.0
version: 2.2.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-alert-dialog':
+ specifier: 1.1.2
+ version: 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-dialog':
specifier: 1.1.2
version: 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -1187,6 +1190,19 @@ packages:
'@radix-ui/primitive@1.1.0':
resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==}
+ '@radix-ui/react-alert-dialog@1.1.2':
+ resolution: {integrity: sha512-eGSlLzPhKO+TErxkiGcCZGuvbVMnLA1MTnyBksGOeGRGkxHiiJUujsjmNTdWTm4iHVSRaUao9/4Ur671auMghQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-arrow@1.1.0':
resolution: {integrity: sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==}
peerDependencies:
@@ -5802,6 +5818,20 @@ snapshots:
'@radix-ui/primitive@1.1.0': {}
+ '@radix-ui/react-alert-dialog@1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.0
+ '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1)
+ '@radix-ui/react-context': 1.1.1(@types/react@18.3.12)(react@18.3.1)
+ '@radix-ui/react-dialog': 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-slot': 1.1.0(@types/react@18.3.12)(react@18.3.1)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.12
+ '@types/react-dom': 18.3.1
+
'@radix-ui/react-arrow@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)