@edux-design/popovers 1.0.6 → 1.1.1
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/CHANGELOG.md +17 -0
- package/README.md +14 -0
- package/dist/index.d.mts +129 -1
- package/dist/index.d.ts +129 -1
- package/dist/index.js +166 -20
- package/dist/index.mjs +165 -20
- package/docs/confirmation.md +118 -0
- package/package.json +10 -16
- package/src/demos/Popover.stories.jsx +0 -248
- package/src/elements/Popover.jsx +0 -156
- package/src/elements/Popover.test.jsx +0 -63
- package/src/index.js +0 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @edux-design/popovers
|
|
2
2
|
|
|
3
|
+
## 1.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Align the exact Radix Popover peer to 1.1.19 so popovers, menus, dialogs and tooltips share dismissal-layer ownership in the reviewed host graph. Preserve the existing Popover JavaScript runtime and public composition.
|
|
8
|
+
|
|
9
|
+
## 1.1.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- Add controlled confirmation dialog and anchored popover compositions with pending dismissal policy, error/retry content and safe focus handling. Generate declared public types for both packages.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @edux-design/buttons@0.3.0
|
|
19
|
+
|
|
3
20
|
## 1.0.6
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Thin, design-token-aware wrappers around Radix UI’s popover primitives. Use them directly or via higher-level components (menus, tooltips, etc.).
|
|
4
4
|
|
|
5
|
+
This release requires `@radix-ui/react-popover@1.1.19`. Together with Dialog
|
|
6
|
+
`1.1.19` and Tooltip `1.2.12`, it shares one dismissal-layer context. Align direct
|
|
7
|
+
Radix dependencies with this pair so Escape dismisses a nested popup before its
|
|
8
|
+
parent modal. This compatibility patch changes package metadata, not Edux's
|
|
9
|
+
JavaScript implementation.
|
|
10
|
+
|
|
5
11
|
Exports: `Popover`, `PopoverTrigger`, `PopoverAnchor`, `PopoverPortal`, `PopoverContent`, `PopoverClose`.
|
|
6
12
|
|
|
7
13
|
---
|
|
@@ -56,6 +62,10 @@ export function HelpPopover() {
|
|
|
56
62
|
|
|
57
63
|
Everything is wrapped in `PopoverPortal` so content escapes stacking context issues by default.
|
|
58
64
|
|
|
65
|
+
The default four-pixel placement nudge uses the shared `--motion-distance-xs`
|
|
66
|
+
token for each side. It is a motion/positioning contract rather than a new
|
|
67
|
+
spacing token, so custom content can override it through `className` or `style`.
|
|
68
|
+
|
|
59
69
|
---
|
|
60
70
|
|
|
61
71
|
## Development
|
|
@@ -75,3 +85,7 @@ Stories: `src/demos/Popover.stories.jsx`.
|
|
|
75
85
|
- Since these components forward all props to Radix, refer to the Radix documentation for advanced features (modals, anchors, collision handling).
|
|
76
86
|
- The default surface uses the `bg-fg-base` / `text-fg-invert` combo; override via Tailwind classes when you need alternate skins.
|
|
77
87
|
- Popovers are used directly via `Popover`, `PopoverTrigger`, and `PopoverContent`; no package-level provider is required.
|
|
88
|
+
|
|
89
|
+
## Additional components
|
|
90
|
+
|
|
91
|
+
[Confirmation popovers](./docs/confirmation.md).
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,130 @@
|
|
|
1
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
2
|
+
import React from 'react';
|
|
1
3
|
|
|
2
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Root Popover component.
|
|
6
|
+
*
|
|
7
|
+
* Wraps a `PopoverTrigger` (or `Popover.Anchor + Trigger`) and a `PopoverContent`.
|
|
8
|
+
* Supports both controlled and uncontrolled modes.
|
|
9
|
+
*
|
|
10
|
+
* @component
|
|
11
|
+
* @param {Object} props
|
|
12
|
+
* @param {boolean} [props.defaultOpen] – whether popover is open by default (uncontrolled mode)
|
|
13
|
+
* @param {boolean} [props.open] – controlled open state
|
|
14
|
+
* @param {(open: boolean) => void} [props.onOpenChange] – change handler for controlled mode
|
|
15
|
+
* @param {boolean} [props.modal=false] – whether to render modal behavior (blocking outside interactions) :contentReference[oaicite:1]{index=1}
|
|
16
|
+
* @param {React.ReactNode} props.children
|
|
17
|
+
* @returns JSX.Element
|
|
18
|
+
*/
|
|
19
|
+
declare const Popover: React.FC<PopoverPrimitive.PopoverProps>;
|
|
20
|
+
/**
|
|
21
|
+
* PopoverTrigger
|
|
22
|
+
*
|
|
23
|
+
* The interactive element that toggles opening/closing the popover.
|
|
24
|
+
*
|
|
25
|
+
* @component
|
|
26
|
+
* @param {React.ComponentProps<typeof PopoverPrimitive.Trigger>} props
|
|
27
|
+
* @example
|
|
28
|
+
* ```jsx
|
|
29
|
+
* <PopoverTrigger asChild>
|
|
30
|
+
* <button>Open Popover</button>
|
|
31
|
+
* </PopoverTrigger>
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
declare const PopoverTrigger: React.ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
35
|
+
/**
|
|
36
|
+
* PopoverAnchor
|
|
37
|
+
*
|
|
38
|
+
* Optional anchor component: if you want the PopoverContent positioned against an element
|
|
39
|
+
* other than the trigger. (Matches Radix’s `Popover.Anchor`) :contentReference[oaicite:2]{index=2}
|
|
40
|
+
*
|
|
41
|
+
* @component
|
|
42
|
+
* @param {React.ComponentProps<typeof PopoverPrimitive.Anchor>} props
|
|
43
|
+
*/
|
|
44
|
+
declare const PopoverAnchor: React.ForwardRefExoticComponent<PopoverPrimitive.PopoverAnchorProps & React.RefAttributes<HTMLDivElement>>;
|
|
45
|
+
/**
|
|
46
|
+
* PopoverPortal
|
|
47
|
+
*
|
|
48
|
+
* Portal wrapper. You can use this if you need to override portal container or force mount.
|
|
49
|
+
*
|
|
50
|
+
* @component
|
|
51
|
+
* @param {React.ComponentProps<typeof PopoverPrimitive.Portal>} props
|
|
52
|
+
*/
|
|
53
|
+
declare const PopoverPortal: React.FC<PopoverPrimitive.PopoverPortalProps>;
|
|
54
|
+
/**
|
|
55
|
+
* @typedef {import("@radix-ui/react-popover").PopoverProps} PopoverProps
|
|
56
|
+
* @typedef {Omit<import("@radix-ui/react-popover").PopoverContentProps, "forceMount"> & {
|
|
57
|
+
* container?: import("@radix-ui/react-popover").PopoverPortalProps["container"],
|
|
58
|
+
* portalProps?: import("@radix-ui/react-popover").PopoverPortalProps,
|
|
59
|
+
* showArrow?: boolean,
|
|
60
|
+
* forceMount?: boolean,
|
|
61
|
+
* contentProps?: import("@radix-ui/react-popover").PopoverContentProps
|
|
62
|
+
* }} PopoverContentProps
|
|
63
|
+
*/
|
|
64
|
+
/**
|
|
65
|
+
* PopoverContent
|
|
66
|
+
*
|
|
67
|
+
* The popover surface that appears. Renders in a Portal by default.
|
|
68
|
+
* You can override animation, styling, arrow, etc.
|
|
69
|
+
*
|
|
70
|
+
* @component
|
|
71
|
+
* @param {PopoverContentProps & React.RefAttributes<HTMLDivElement>} props
|
|
72
|
+
*/
|
|
73
|
+
/** @type {React.ForwardRefExoticComponent<PopoverContentProps & React.RefAttributes<HTMLDivElement>>} */
|
|
74
|
+
declare const PopoverContent: React.ForwardRefExoticComponent<PopoverContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
75
|
+
/**
|
|
76
|
+
* PopoverClose
|
|
77
|
+
*
|
|
78
|
+
* A button or element inside the PopoverContent that triggers closing action.
|
|
79
|
+
*
|
|
80
|
+
* @component
|
|
81
|
+
* @param {React.ComponentProps<typeof PopoverPrimitive.Close>} props
|
|
82
|
+
*/
|
|
83
|
+
declare const PopoverClose: React.ForwardRefExoticComponent<PopoverPrimitive.PopoverCloseProps & React.RefAttributes<HTMLButtonElement>>;
|
|
84
|
+
type PopoverProps = PopoverPrimitive.PopoverProps;
|
|
85
|
+
type PopoverContentProps = Omit<PopoverPrimitive.PopoverContentProps, "forceMount"> & {
|
|
86
|
+
container?: PopoverPrimitive.PopoverPortalProps["container"];
|
|
87
|
+
portalProps?: PopoverPrimitive.PopoverPortalProps;
|
|
88
|
+
showArrow?: boolean;
|
|
89
|
+
forceMount?: boolean;
|
|
90
|
+
contentProps?: PopoverPrimitive.PopoverContentProps;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
type ConfirmationPopoverActionProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children" | "disabled"> & React.RefAttributes<HTMLButtonElement>;
|
|
94
|
+
interface ConfirmationPopoverProps {
|
|
95
|
+
open?: boolean;
|
|
96
|
+
defaultOpen?: boolean;
|
|
97
|
+
onOpenChange?: (open: boolean) => void;
|
|
98
|
+
title: React.ReactNode;
|
|
99
|
+
description?: React.ReactNode;
|
|
100
|
+
children?: React.ReactNode;
|
|
101
|
+
/** A single ref-forwarding button that anchors the confirmation. */
|
|
102
|
+
trigger: React.ReactElement;
|
|
103
|
+
/** Optional separate ref-forwarding anchor; trigger semantics remain unchanged. */
|
|
104
|
+
anchor?: React.ReactElement;
|
|
105
|
+
onConfirm: React.MouseEventHandler<HTMLButtonElement>;
|
|
106
|
+
onCancel?: React.MouseEventHandler<HTMLButtonElement>;
|
|
107
|
+
confirmLabel?: React.ReactNode;
|
|
108
|
+
cancelLabel?: React.ReactNode;
|
|
109
|
+
pendingLabel?: React.ReactNode;
|
|
110
|
+
pending?: boolean;
|
|
111
|
+
error?: React.ReactNode;
|
|
112
|
+
confirmDisabled?: boolean;
|
|
113
|
+
cancelDisabled?: boolean;
|
|
114
|
+
/** Locks user dismissal. The controlled host may still close explicitly. */
|
|
115
|
+
dismissible?: boolean;
|
|
116
|
+
/** Explicit return target, useful when confirmation removes its own trigger. */
|
|
117
|
+
returnFocusRef?: React.RefObject<HTMLElement | null>;
|
|
118
|
+
isDanger?: boolean;
|
|
119
|
+
allowDismissWhilePending?: boolean;
|
|
120
|
+
/** Modal by default: focus is contained and outside pointer interaction blocked. */
|
|
121
|
+
modal?: boolean;
|
|
122
|
+
contentProps?: Omit<PopoverPrimitive.PopoverContentProps, "children" | "asChild">;
|
|
123
|
+
portalProps?: PopoverPrimitive.PopoverPortalProps;
|
|
124
|
+
confirmButtonProps?: ConfirmationPopoverActionProps;
|
|
125
|
+
cancelButtonProps?: ConfirmationPopoverActionProps;
|
|
126
|
+
}
|
|
127
|
+
/** Anchored controlled confirmation; domain checks and asynchronous work stay in the host. */
|
|
128
|
+
declare const ConfirmationPopover: React.ForwardRefExoticComponent<ConfirmationPopoverProps & React.RefAttributes<HTMLDivElement>>;
|
|
129
|
+
|
|
130
|
+
export { ConfirmationPopover, type ConfirmationPopoverActionProps, type ConfirmationPopoverProps, Popover, PopoverAnchor, PopoverClose, PopoverContent, type PopoverContentProps, PopoverPortal, type PopoverProps, PopoverTrigger };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,130 @@
|
|
|
1
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
2
|
+
import React from 'react';
|
|
1
3
|
|
|
2
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Root Popover component.
|
|
6
|
+
*
|
|
7
|
+
* Wraps a `PopoverTrigger` (or `Popover.Anchor + Trigger`) and a `PopoverContent`.
|
|
8
|
+
* Supports both controlled and uncontrolled modes.
|
|
9
|
+
*
|
|
10
|
+
* @component
|
|
11
|
+
* @param {Object} props
|
|
12
|
+
* @param {boolean} [props.defaultOpen] – whether popover is open by default (uncontrolled mode)
|
|
13
|
+
* @param {boolean} [props.open] – controlled open state
|
|
14
|
+
* @param {(open: boolean) => void} [props.onOpenChange] – change handler for controlled mode
|
|
15
|
+
* @param {boolean} [props.modal=false] – whether to render modal behavior (blocking outside interactions) :contentReference[oaicite:1]{index=1}
|
|
16
|
+
* @param {React.ReactNode} props.children
|
|
17
|
+
* @returns JSX.Element
|
|
18
|
+
*/
|
|
19
|
+
declare const Popover: React.FC<PopoverPrimitive.PopoverProps>;
|
|
20
|
+
/**
|
|
21
|
+
* PopoverTrigger
|
|
22
|
+
*
|
|
23
|
+
* The interactive element that toggles opening/closing the popover.
|
|
24
|
+
*
|
|
25
|
+
* @component
|
|
26
|
+
* @param {React.ComponentProps<typeof PopoverPrimitive.Trigger>} props
|
|
27
|
+
* @example
|
|
28
|
+
* ```jsx
|
|
29
|
+
* <PopoverTrigger asChild>
|
|
30
|
+
* <button>Open Popover</button>
|
|
31
|
+
* </PopoverTrigger>
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
declare const PopoverTrigger: React.ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
35
|
+
/**
|
|
36
|
+
* PopoverAnchor
|
|
37
|
+
*
|
|
38
|
+
* Optional anchor component: if you want the PopoverContent positioned against an element
|
|
39
|
+
* other than the trigger. (Matches Radix’s `Popover.Anchor`) :contentReference[oaicite:2]{index=2}
|
|
40
|
+
*
|
|
41
|
+
* @component
|
|
42
|
+
* @param {React.ComponentProps<typeof PopoverPrimitive.Anchor>} props
|
|
43
|
+
*/
|
|
44
|
+
declare const PopoverAnchor: React.ForwardRefExoticComponent<PopoverPrimitive.PopoverAnchorProps & React.RefAttributes<HTMLDivElement>>;
|
|
45
|
+
/**
|
|
46
|
+
* PopoverPortal
|
|
47
|
+
*
|
|
48
|
+
* Portal wrapper. You can use this if you need to override portal container or force mount.
|
|
49
|
+
*
|
|
50
|
+
* @component
|
|
51
|
+
* @param {React.ComponentProps<typeof PopoverPrimitive.Portal>} props
|
|
52
|
+
*/
|
|
53
|
+
declare const PopoverPortal: React.FC<PopoverPrimitive.PopoverPortalProps>;
|
|
54
|
+
/**
|
|
55
|
+
* @typedef {import("@radix-ui/react-popover").PopoverProps} PopoverProps
|
|
56
|
+
* @typedef {Omit<import("@radix-ui/react-popover").PopoverContentProps, "forceMount"> & {
|
|
57
|
+
* container?: import("@radix-ui/react-popover").PopoverPortalProps["container"],
|
|
58
|
+
* portalProps?: import("@radix-ui/react-popover").PopoverPortalProps,
|
|
59
|
+
* showArrow?: boolean,
|
|
60
|
+
* forceMount?: boolean,
|
|
61
|
+
* contentProps?: import("@radix-ui/react-popover").PopoverContentProps
|
|
62
|
+
* }} PopoverContentProps
|
|
63
|
+
*/
|
|
64
|
+
/**
|
|
65
|
+
* PopoverContent
|
|
66
|
+
*
|
|
67
|
+
* The popover surface that appears. Renders in a Portal by default.
|
|
68
|
+
* You can override animation, styling, arrow, etc.
|
|
69
|
+
*
|
|
70
|
+
* @component
|
|
71
|
+
* @param {PopoverContentProps & React.RefAttributes<HTMLDivElement>} props
|
|
72
|
+
*/
|
|
73
|
+
/** @type {React.ForwardRefExoticComponent<PopoverContentProps & React.RefAttributes<HTMLDivElement>>} */
|
|
74
|
+
declare const PopoverContent: React.ForwardRefExoticComponent<PopoverContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
75
|
+
/**
|
|
76
|
+
* PopoverClose
|
|
77
|
+
*
|
|
78
|
+
* A button or element inside the PopoverContent that triggers closing action.
|
|
79
|
+
*
|
|
80
|
+
* @component
|
|
81
|
+
* @param {React.ComponentProps<typeof PopoverPrimitive.Close>} props
|
|
82
|
+
*/
|
|
83
|
+
declare const PopoverClose: React.ForwardRefExoticComponent<PopoverPrimitive.PopoverCloseProps & React.RefAttributes<HTMLButtonElement>>;
|
|
84
|
+
type PopoverProps = PopoverPrimitive.PopoverProps;
|
|
85
|
+
type PopoverContentProps = Omit<PopoverPrimitive.PopoverContentProps, "forceMount"> & {
|
|
86
|
+
container?: PopoverPrimitive.PopoverPortalProps["container"];
|
|
87
|
+
portalProps?: PopoverPrimitive.PopoverPortalProps;
|
|
88
|
+
showArrow?: boolean;
|
|
89
|
+
forceMount?: boolean;
|
|
90
|
+
contentProps?: PopoverPrimitive.PopoverContentProps;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
type ConfirmationPopoverActionProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children" | "disabled"> & React.RefAttributes<HTMLButtonElement>;
|
|
94
|
+
interface ConfirmationPopoverProps {
|
|
95
|
+
open?: boolean;
|
|
96
|
+
defaultOpen?: boolean;
|
|
97
|
+
onOpenChange?: (open: boolean) => void;
|
|
98
|
+
title: React.ReactNode;
|
|
99
|
+
description?: React.ReactNode;
|
|
100
|
+
children?: React.ReactNode;
|
|
101
|
+
/** A single ref-forwarding button that anchors the confirmation. */
|
|
102
|
+
trigger: React.ReactElement;
|
|
103
|
+
/** Optional separate ref-forwarding anchor; trigger semantics remain unchanged. */
|
|
104
|
+
anchor?: React.ReactElement;
|
|
105
|
+
onConfirm: React.MouseEventHandler<HTMLButtonElement>;
|
|
106
|
+
onCancel?: React.MouseEventHandler<HTMLButtonElement>;
|
|
107
|
+
confirmLabel?: React.ReactNode;
|
|
108
|
+
cancelLabel?: React.ReactNode;
|
|
109
|
+
pendingLabel?: React.ReactNode;
|
|
110
|
+
pending?: boolean;
|
|
111
|
+
error?: React.ReactNode;
|
|
112
|
+
confirmDisabled?: boolean;
|
|
113
|
+
cancelDisabled?: boolean;
|
|
114
|
+
/** Locks user dismissal. The controlled host may still close explicitly. */
|
|
115
|
+
dismissible?: boolean;
|
|
116
|
+
/** Explicit return target, useful when confirmation removes its own trigger. */
|
|
117
|
+
returnFocusRef?: React.RefObject<HTMLElement | null>;
|
|
118
|
+
isDanger?: boolean;
|
|
119
|
+
allowDismissWhilePending?: boolean;
|
|
120
|
+
/** Modal by default: focus is contained and outside pointer interaction blocked. */
|
|
121
|
+
modal?: boolean;
|
|
122
|
+
contentProps?: Omit<PopoverPrimitive.PopoverContentProps, "children" | "asChild">;
|
|
123
|
+
portalProps?: PopoverPrimitive.PopoverPortalProps;
|
|
124
|
+
confirmButtonProps?: ConfirmationPopoverActionProps;
|
|
125
|
+
cancelButtonProps?: ConfirmationPopoverActionProps;
|
|
126
|
+
}
|
|
127
|
+
/** Anchored controlled confirmation; domain checks and asynchronous work stay in the host. */
|
|
128
|
+
declare const ConfirmationPopover: React.ForwardRefExoticComponent<ConfirmationPopoverProps & React.RefAttributes<HTMLDivElement>>;
|
|
129
|
+
|
|
130
|
+
export { ConfirmationPopover, type ConfirmationPopoverActionProps, type ConfirmationPopoverProps, Popover, PopoverAnchor, PopoverClose, PopoverContent, type PopoverContentProps, PopoverPortal, type PopoverProps, PopoverTrigger };
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
// src/index.js
|
|
30
30
|
var index_exports = {};
|
|
31
31
|
__export(index_exports, {
|
|
32
|
+
ConfirmationPopover: () => ConfirmationPopover,
|
|
32
33
|
Popover: () => Popover,
|
|
33
34
|
PopoverAnchor: () => PopoverAnchor,
|
|
34
35
|
PopoverClose: () => PopoverClose,
|
|
@@ -42,7 +43,14 @@ module.exports = __toCommonJS(index_exports);
|
|
|
42
43
|
var import_react = __toESM(require("react"));
|
|
43
44
|
var PopoverPrimitive = __toESM(require("@radix-ui/react-popover"));
|
|
44
45
|
var import_utils = require("@edux-design/utils");
|
|
46
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
45
47
|
var POPOVER_Z_INDEX = 2147483646;
|
|
48
|
+
var POPOVER_POSITIONING_CLASSES = {
|
|
49
|
+
top: "-translate-y-(--motion-distance-xs)",
|
|
50
|
+
right: "translate-x-(--motion-distance-xs)",
|
|
51
|
+
bottom: "translate-y-(--motion-distance-xs)",
|
|
52
|
+
left: "-translate-x-(--motion-distance-xs)"
|
|
53
|
+
};
|
|
46
54
|
var Popover = PopoverPrimitive.Root;
|
|
47
55
|
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
48
56
|
var PopoverAnchor = PopoverPrimitive.Anchor;
|
|
@@ -64,14 +72,8 @@ var PopoverContent = (0, import_react.forwardRef)(
|
|
|
64
72
|
contentProps = {},
|
|
65
73
|
...restProps
|
|
66
74
|
}, ref) => {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
top: "translate-y-[-4px]",
|
|
70
|
-
right: "translate-x-[4px]",
|
|
71
|
-
bottom: "translate-y-[4px]",
|
|
72
|
-
left: "translate-x-[-4px]"
|
|
73
|
-
}[side];
|
|
74
|
-
return /* @__PURE__ */ import_react.default.createElement(PopoverPortal, { container, ...portalProps }, /* @__PURE__ */ import_react.default.createElement(
|
|
75
|
+
const positioning = POPOVER_POSITIONING_CLASSES[side];
|
|
76
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PopoverPortal, { container, ...portalProps, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
75
77
|
PopoverPrimitive.Content,
|
|
76
78
|
{
|
|
77
79
|
ref,
|
|
@@ -84,24 +86,168 @@ var PopoverContent = (0, import_react.forwardRef)(
|
|
|
84
86
|
className: (0, import_utils.cx)(positioning, className, "relative"),
|
|
85
87
|
style: { zIndex: POPOVER_Z_INDEX, ...style },
|
|
86
88
|
...contentProps,
|
|
87
|
-
...restProps
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
89
|
+
...restProps,
|
|
90
|
+
children: [
|
|
91
|
+
children,
|
|
92
|
+
showArrow && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
93
|
+
PopoverPrimitive.Arrow,
|
|
94
|
+
{
|
|
95
|
+
className: "fill-fg-base",
|
|
96
|
+
width: 12,
|
|
97
|
+
height: 8
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
) });
|
|
99
103
|
}
|
|
100
104
|
);
|
|
101
105
|
PopoverContent.displayName = "PopoverContent";
|
|
102
106
|
var PopoverClose = PopoverPrimitive.Close;
|
|
107
|
+
|
|
108
|
+
// src/elements/ConfirmationPopover.tsx
|
|
109
|
+
var import_react2 = require("react");
|
|
110
|
+
var import_buttons = require("@edux-design/buttons");
|
|
111
|
+
var import_utils2 = require("@edux-design/utils");
|
|
112
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
113
|
+
var ConfirmationPopover = (0, import_react2.forwardRef)(function ConfirmationPopover2({
|
|
114
|
+
open,
|
|
115
|
+
defaultOpen = false,
|
|
116
|
+
onOpenChange,
|
|
117
|
+
title,
|
|
118
|
+
description,
|
|
119
|
+
children,
|
|
120
|
+
trigger,
|
|
121
|
+
onConfirm,
|
|
122
|
+
onCancel,
|
|
123
|
+
confirmLabel = "Confirm",
|
|
124
|
+
cancelLabel = "Cancel",
|
|
125
|
+
pendingLabel = "Working\u2026",
|
|
126
|
+
pending = false,
|
|
127
|
+
error,
|
|
128
|
+
confirmDisabled = false,
|
|
129
|
+
cancelDisabled = false,
|
|
130
|
+
dismissible = true,
|
|
131
|
+
returnFocusRef,
|
|
132
|
+
isDanger = false,
|
|
133
|
+
allowDismissWhilePending = false,
|
|
134
|
+
modal = true,
|
|
135
|
+
anchor,
|
|
136
|
+
contentProps = {},
|
|
137
|
+
portalProps,
|
|
138
|
+
confirmButtonProps = {},
|
|
139
|
+
cancelButtonProps = {}
|
|
140
|
+
}, ref) {
|
|
141
|
+
const [uncontrolledOpen, setUncontrolledOpen] = (0, import_react2.useState)(defaultOpen);
|
|
142
|
+
const resolvedOpen = open ?? uncontrolledOpen;
|
|
143
|
+
const cancelRef = (0, import_react2.useRef)(null);
|
|
144
|
+
const titleId = (0, import_react2.useId)();
|
|
145
|
+
const descriptionId = (0, import_react2.useId)();
|
|
146
|
+
const locked = !dismissible || pending && !allowDismissWhilePending;
|
|
147
|
+
const {
|
|
148
|
+
onClick: onCancelClick,
|
|
149
|
+
ref: actionRef,
|
|
150
|
+
...cancelProps
|
|
151
|
+
} = cancelButtonProps;
|
|
152
|
+
const { onClick: onConfirmClick, ...confirmProps } = confirmButtonProps;
|
|
153
|
+
const requestOpen = (next) => {
|
|
154
|
+
if (!next && locked) return;
|
|
155
|
+
if (open === void 0) setUncontrolledOpen(next);
|
|
156
|
+
onOpenChange?.(next);
|
|
157
|
+
};
|
|
158
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Popover, { open: resolvedOpen, onOpenChange: requestOpen, modal, children: [
|
|
159
|
+
anchor && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PopoverAnchor, { asChild: true, children: anchor }),
|
|
160
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PopoverTrigger, { asChild: true, children: trigger }),
|
|
161
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
162
|
+
PopoverContent,
|
|
163
|
+
{
|
|
164
|
+
side: "bottom",
|
|
165
|
+
align: "end",
|
|
166
|
+
...contentProps,
|
|
167
|
+
ref,
|
|
168
|
+
portalProps,
|
|
169
|
+
"aria-labelledby": contentProps["aria-labelledby"] ?? titleId,
|
|
170
|
+
"aria-describedby": contentProps["aria-describedby"] ?? (description ? descriptionId : void 0),
|
|
171
|
+
"aria-busy": pending || void 0,
|
|
172
|
+
className: (0, import_utils2.cx)(
|
|
173
|
+
"w-[min(320px,calc(100vw-32px))] max-h-[var(--radix-popover-content-available-height)] overflow-auto rounded-md border-2 border-border-subtle bg-bg-base p-16 text-sm text-fg-base shadow-lg motion-reduce:animate-none",
|
|
174
|
+
contentProps.className
|
|
175
|
+
),
|
|
176
|
+
onOpenAutoFocus: (event) => {
|
|
177
|
+
contentProps.onOpenAutoFocus?.(event);
|
|
178
|
+
if (!event.defaultPrevented) {
|
|
179
|
+
event.preventDefault();
|
|
180
|
+
if (!locked && !cancelDisabled) cancelRef.current?.focus();
|
|
181
|
+
else if (event.target instanceof HTMLElement) event.target.focus();
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
onCloseAutoFocus: (event) => {
|
|
185
|
+
contentProps.onCloseAutoFocus?.(event);
|
|
186
|
+
if (!event.defaultPrevented && returnFocusRef?.current?.isConnected) {
|
|
187
|
+
event.preventDefault();
|
|
188
|
+
returnFocusRef.current.focus();
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
onEscapeKeyDown: (event) => {
|
|
192
|
+
contentProps.onEscapeKeyDown?.(event);
|
|
193
|
+
if (locked) event.preventDefault();
|
|
194
|
+
},
|
|
195
|
+
onInteractOutside: (event) => {
|
|
196
|
+
contentProps.onInteractOutside?.(event);
|
|
197
|
+
if (locked) event.preventDefault();
|
|
198
|
+
},
|
|
199
|
+
children: [
|
|
200
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { id: titleId, className: "text-base font-semibold text-fg-base", children: title }),
|
|
201
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { id: descriptionId, className: "mt-8 text-sm text-fg-subtle", children: description }),
|
|
202
|
+
children && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "mt-12", children }),
|
|
203
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { role: "alert", className: "mt-8 text-fg-danger-emphasis", children: error }),
|
|
204
|
+
pending && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { role: "status", className: "sr-only", children: pendingLabel }),
|
|
205
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mt-16 flex flex-wrap justify-end gap-8", children: [
|
|
206
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
207
|
+
import_buttons.Button,
|
|
208
|
+
{
|
|
209
|
+
...cancelProps,
|
|
210
|
+
ref: (node) => {
|
|
211
|
+
cancelRef.current = node;
|
|
212
|
+
if (typeof actionRef === "function") actionRef(node);
|
|
213
|
+
else if (actionRef) actionRef.current = node;
|
|
214
|
+
},
|
|
215
|
+
type: "button",
|
|
216
|
+
size: "small",
|
|
217
|
+
isSecondary: true,
|
|
218
|
+
disabled: locked || cancelDisabled,
|
|
219
|
+
onClick: (event) => {
|
|
220
|
+
onCancelClick?.(event);
|
|
221
|
+
if (!event.defaultPrevented) onCancel?.(event);
|
|
222
|
+
if (!event.defaultPrevented) requestOpen(false);
|
|
223
|
+
},
|
|
224
|
+
children: cancelLabel
|
|
225
|
+
}
|
|
226
|
+
),
|
|
227
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
228
|
+
import_buttons.Button,
|
|
229
|
+
{
|
|
230
|
+
...confirmProps,
|
|
231
|
+
type: "button",
|
|
232
|
+
size: "small",
|
|
233
|
+
isDanger,
|
|
234
|
+
disabled: pending || confirmDisabled,
|
|
235
|
+
onClick: (event) => {
|
|
236
|
+
onConfirmClick?.(event);
|
|
237
|
+
if (!event.defaultPrevented) onConfirm(event);
|
|
238
|
+
},
|
|
239
|
+
children: pending ? pendingLabel : confirmLabel
|
|
240
|
+
}
|
|
241
|
+
)
|
|
242
|
+
] })
|
|
243
|
+
]
|
|
244
|
+
}
|
|
245
|
+
)
|
|
246
|
+
] });
|
|
247
|
+
});
|
|
103
248
|
// Annotate the CommonJS export names for ESM import in node:
|
|
104
249
|
0 && (module.exports = {
|
|
250
|
+
ConfirmationPopover,
|
|
105
251
|
Popover,
|
|
106
252
|
PopoverAnchor,
|
|
107
253
|
PopoverClose,
|