@cdx-ui/primitives 0.0.1-beta.112 → 0.0.1-beta.114

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 (32) hide show
  1. package/lib/commonjs/dialog/DialogContent.js +79 -0
  2. package/lib/commonjs/dialog/DialogContent.js.map +1 -0
  3. package/lib/commonjs/dialog/DialogOverlay.js +54 -0
  4. package/lib/commonjs/dialog/DialogOverlay.js.map +1 -0
  5. package/lib/commonjs/dialog/DialogPortal.js +37 -0
  6. package/lib/commonjs/dialog/DialogPortal.js.map +1 -0
  7. package/lib/commonjs/dialog/index.js +21 -0
  8. package/lib/commonjs/dialog/index.js.map +1 -1
  9. package/lib/module/dialog/DialogContent.js +75 -0
  10. package/lib/module/dialog/DialogContent.js.map +1 -0
  11. package/lib/module/dialog/DialogOverlay.js +50 -0
  12. package/lib/module/dialog/DialogOverlay.js.map +1 -0
  13. package/lib/module/dialog/DialogPortal.js +33 -0
  14. package/lib/module/dialog/DialogPortal.js.map +1 -0
  15. package/lib/module/dialog/index.js +3 -0
  16. package/lib/module/dialog/index.js.map +1 -1
  17. package/lib/typescript/dialog/DialogContent.d.ts +16 -0
  18. package/lib/typescript/dialog/DialogContent.d.ts.map +1 -0
  19. package/lib/typescript/dialog/DialogOverlay.d.ts +11 -0
  20. package/lib/typescript/dialog/DialogOverlay.d.ts.map +1 -0
  21. package/lib/typescript/dialog/DialogPortal.d.ts +16 -0
  22. package/lib/typescript/dialog/DialogPortal.d.ts.map +1 -0
  23. package/lib/typescript/dialog/index.d.ts +4 -1
  24. package/lib/typescript/dialog/index.d.ts.map +1 -1
  25. package/lib/typescript/dialog/types.d.ts +24 -0
  26. package/lib/typescript/dialog/types.d.ts.map +1 -1
  27. package/package.json +2 -2
  28. package/src/dialog/DialogContent.tsx +77 -0
  29. package/src/dialog/DialogOverlay.tsx +51 -0
  30. package/src/dialog/DialogPortal.tsx +29 -0
  31. package/src/dialog/index.tsx +6 -0
  32. package/src/dialog/types.ts +27 -0
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.DialogContent = void 0;
7
+ var _react = require("react");
8
+ var _reactNative = require("react-native");
9
+ var _focus = require("@react-native-aria/focus");
10
+ var _slot = require("../slot");
11
+ var _overlay = require("../overlay");
12
+ var _dataAttributes = require("../utils/dataAttributes");
13
+ var _context = require("./context");
14
+ var _jsxRuntime = require("react/jsx-runtime");
15
+ /**
16
+ * Dialog content panel primitive. Provides:
17
+ * - ARIA role, aria-modal, aria-labelledby/describedby
18
+ * - FocusScope (focus trap + restore + auto-focus)
19
+ * - Escape key dismissal (web)
20
+ * - Android hardware back button dismissal (native)
21
+ * - data-state attribute for CSS transition targeting
22
+ *
23
+ * Unstyled — the styled layer applies centering, background, border-radius, etc.
24
+ */
25
+ const DialogContent = exports.DialogContent = /*#__PURE__*/(0, _react.forwardRef)(({
26
+ asChild = false,
27
+ forceMount = false,
28
+ children,
29
+ ...props
30
+ }, ref) => {
31
+ const {
32
+ open,
33
+ onOpenChange,
34
+ closeOnEscKey,
35
+ nativeID,
36
+ role
37
+ } = (0, _context.useDialog)();
38
+ const handleClose = (0, _react.useCallback)(() => {
39
+ onOpenChange(false);
40
+ }, [onOpenChange]);
41
+ (0, _overlay.useEscapeKey)(open && closeOnEscKey, handleClose);
42
+ (0, _react.useEffect)(() => {
43
+ if (!open) return;
44
+ const backHandler = _reactNative.BackHandler.addEventListener('hardwareBackPress', () => {
45
+ onOpenChange(false);
46
+ return true;
47
+ });
48
+ return () => {
49
+ backHandler.remove();
50
+ };
51
+ }, [open, onOpenChange]);
52
+ if (!forceMount && !open) {
53
+ return null;
54
+ }
55
+ const Comp = asChild ? _slot.Slot : _reactNative.View;
56
+ const ariaProps = {
57
+ role,
58
+ 'aria-modal': true,
59
+ 'aria-labelledby': `${nativeID}-title`,
60
+ 'aria-describedby': `${nativeID}-description`
61
+ };
62
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_focus.FocusScope, {
63
+ contain: open,
64
+ restoreFocus: true,
65
+ autoFocus: open,
66
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {
67
+ ref: ref,
68
+ nativeID: nativeID,
69
+ ...ariaProps,
70
+ ...props,
71
+ ...(0, _dataAttributes.mergeDataAttributes)(props, forceMount ? undefined : (0, _dataAttributes.dataAttributes)({
72
+ state: open ? 'open' : 'closed'
73
+ })),
74
+ children: children
75
+ })
76
+ });
77
+ });
78
+ DialogContent.displayName = 'DialogContent';
79
+ //# sourceMappingURL=DialogContent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","require","_reactNative","_focus","_slot","_overlay","_dataAttributes","_context","_jsxRuntime","DialogContent","exports","forwardRef","asChild","forceMount","children","props","ref","open","onOpenChange","closeOnEscKey","nativeID","role","useDialog","handleClose","useCallback","useEscapeKey","useEffect","backHandler","BackHandler","addEventListener","remove","Comp","Slot","View","ariaProps","jsx","FocusScope","contain","restoreFocus","autoFocus","mergeDataAttributes","undefined","dataAttributes","state","displayName"],"sourceRoot":"../../../src","sources":["dialog/DialogContent.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AACA,IAAAE,MAAA,GAAAF,OAAA;AACA,IAAAG,KAAA,GAAAH,OAAA;AACA,IAAAI,QAAA,GAAAJ,OAAA;AACA,IAAAK,eAAA,GAAAL,OAAA;AACA,IAAAM,QAAA,GAAAN,OAAA;AAAsC,IAAAO,WAAA,GAAAP,OAAA;AAKtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMQ,aAAa,GAAAC,OAAA,CAAAD,aAAA,gBAAG,IAAAE,iBAAU,EACrC,CAAC;EAAEC,OAAO,GAAG,KAAK;EAAEC,UAAU,GAAG,KAAK;EAAEC,QAAQ;EAAE,GAAGC;AAAM,CAAC,EAAEC,GAAG,KAAK;EACpE,MAAM;IAAEC,IAAI;IAAEC,YAAY;IAAEC,aAAa;IAAEC,QAAQ;IAAEC;EAAK,CAAC,GAAG,IAAAC,kBAAS,EAAC,CAAC;EAEzE,MAAMC,WAAW,GAAG,IAAAC,kBAAW,EAAC,MAAM;IACpCN,YAAY,CAAC,KAAK,CAAC;EACrB,CAAC,EAAE,CAACA,YAAY,CAAC,CAAC;EAElB,IAAAO,qBAAY,EAACR,IAAI,IAAIE,aAAa,EAAEI,WAAW,CAAC;EAEhD,IAAAG,gBAAS,EAAC,MAAM;IACd,IAAI,CAACT,IAAI,EAAE;IAEX,MAAMU,WAAW,GAAGC,wBAAW,CAACC,gBAAgB,CAAC,mBAAmB,EAAE,MAAM;MAC1EX,YAAY,CAAC,KAAK,CAAC;MACnB,OAAO,IAAI;IACb,CAAC,CAAC;IAEF,OAAO,MAAM;MACXS,WAAW,CAACG,MAAM,CAAC,CAAC;IACtB,CAAC;EACH,CAAC,EAAE,CAACb,IAAI,EAAEC,YAAY,CAAC,CAAC;EAExB,IAAI,CAACL,UAAU,IAAI,CAACI,IAAI,EAAE;IACxB,OAAO,IAAI;EACb;EAEA,MAAMc,IAAI,GAAGnB,OAAO,GAAGoB,UAAI,GAAGC,iBAAI;EAElC,MAAMC,SAAS,GAAG;IAChBb,IAAI;IACJ,YAAY,EAAE,IAAI;IAClB,iBAAiB,EAAE,GAAGD,QAAQ,QAAQ;IACtC,kBAAkB,EAAE,GAAGA,QAAQ;EACjC,CAAC;EAED,oBACE,IAAAZ,WAAA,CAAA2B,GAAA,EAAChC,MAAA,CAAAiC,UAAU;IAACC,OAAO,EAAEpB,IAAK;IAACqB,YAAY;IAACC,SAAS,EAAEtB,IAAK;IAAAH,QAAA,eACtD,IAAAN,WAAA,CAAA2B,GAAA,EAACJ,IAAI;MACHf,GAAG,EAAEA,GAAI;MACTI,QAAQ,EAAEA,QAAS;MAAA,GACfc,SAAS;MAAA,GACRnB,KAAK;MAAA,GACN,IAAAyB,mCAAmB,EACrBzB,KAAK,EACLF,UAAU,GAAG4B,SAAS,GAAG,IAAAC,8BAAc,EAAC;QAAEC,KAAK,EAAE1B,IAAI,GAAG,MAAM,GAAG;MAAS,CAAC,CAC7E,CAAC;MAAAH,QAAA,EAEAA;IAAQ,CACL;EAAC,CACG,CAAC;AAEjB,CACF,CAAC;AAEDL,aAAa,CAACmC,WAAW,GAAG,eAAe","ignoreList":[]}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.DialogOverlay = void 0;
7
+ var _react = require("react");
8
+ var _reactNative = require("react-native");
9
+ var _slot = require("../slot");
10
+ var _dataAttributes = require("../utils/dataAttributes");
11
+ var _context = require("./context");
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+ /**
14
+ * Backdrop overlay that dismisses the dialog on press (when closeOnBackdropPress
15
+ * is enabled). Supports `forceMount` for exit animation coordination.
16
+ *
17
+ * Unstyled — the styled layer applies opacity/color via className.
18
+ */
19
+ const DialogOverlay = exports.DialogOverlay = /*#__PURE__*/(0, _react.forwardRef)(({
20
+ asChild = false,
21
+ forceMount = false,
22
+ onPress,
23
+ ...props
24
+ }, ref) => {
25
+ const {
26
+ open,
27
+ onOpenChange,
28
+ closeOnBackdropPress
29
+ } = (0, _context.useDialog)();
30
+ const handlePress = (0, _react.useCallback)(e => {
31
+ if (closeOnBackdropPress) {
32
+ onOpenChange(false);
33
+ }
34
+ if (typeof onPress === 'function') {
35
+ onPress(e);
36
+ }
37
+ }, [closeOnBackdropPress, onOpenChange, onPress]);
38
+ if (!forceMount && !open) {
39
+ return null;
40
+ }
41
+ const Comp = asChild ? _slot.Slot : _reactNative.Pressable;
42
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {
43
+ ref: ref,
44
+ accessible: false,
45
+ importantForAccessibility: "no-hide-descendants",
46
+ onPress: handlePress,
47
+ ...props,
48
+ ...(0, _dataAttributes.mergeDataAttributes)(props, (0, _dataAttributes.dataAttributes)({
49
+ slot: 'dialog-overlay'
50
+ }))
51
+ });
52
+ });
53
+ DialogOverlay.displayName = 'DialogOverlay';
54
+ //# sourceMappingURL=DialogOverlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","require","_reactNative","_slot","_dataAttributes","_context","_jsxRuntime","DialogOverlay","exports","forwardRef","asChild","forceMount","onPress","props","ref","open","onOpenChange","closeOnBackdropPress","useDialog","handlePress","useCallback","e","Comp","Slot","Pressable","jsx","accessible","importantForAccessibility","mergeDataAttributes","dataAttributes","slot","displayName"],"sourceRoot":"../../../src","sources":["dialog/DialogOverlay.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AACA,IAAAE,KAAA,GAAAF,OAAA;AACA,IAAAG,eAAA,GAAAH,OAAA;AACA,IAAAI,QAAA,GAAAJ,OAAA;AAAsC,IAAAK,WAAA,GAAAL,OAAA;AAKtC;AACA;AACA;AACA;AACA;AACA;AACO,MAAMM,aAAa,GAAAC,OAAA,CAAAD,aAAA,gBAAG,IAAAE,iBAAU,EACrC,CAAC;EAAEC,OAAO,GAAG,KAAK;EAAEC,UAAU,GAAG,KAAK;EAAEC,OAAO;EAAE,GAAGC;AAAM,CAAC,EAAEC,GAAG,KAAK;EACnE,MAAM;IAAEC,IAAI;IAAEC,YAAY;IAAEC;EAAqB,CAAC,GAAG,IAAAC,kBAAS,EAAC,CAAC;EAEhE,MAAMC,WAAW,GAAG,IAAAC,kBAAW,EAC5BC,CAAM,IAAK;IACV,IAAIJ,oBAAoB,EAAE;MACxBD,YAAY,CAAC,KAAK,CAAC;IACrB;IACA,IAAI,OAAOJ,OAAO,KAAK,UAAU,EAAE;MACjCA,OAAO,CAACS,CAAC,CAAC;IACZ;EACF,CAAC,EACD,CAACJ,oBAAoB,EAAED,YAAY,EAAEJ,OAAO,CAC9C,CAAC;EAED,IAAI,CAACD,UAAU,IAAI,CAACI,IAAI,EAAE;IACxB,OAAO,IAAI;EACb;EAEA,MAAMO,IAAI,GAAGZ,OAAO,GAAGa,UAAI,GAAGC,sBAAS;EAEvC,oBACE,IAAAlB,WAAA,CAAAmB,GAAA,EAACH,IAAI;IACHR,GAAG,EAAEA,GAAI;IACTY,UAAU,EAAE,KAAM;IAClBC,yBAAyB,EAAC,qBAAqB;IAC/Cf,OAAO,EAAEO,WAAY;IAAA,GAChBN,KAAK;IAAA,GACN,IAAAe,mCAAmB,EAACf,KAAK,EAAE,IAAAgB,8BAAc,EAAC;MAAEC,IAAI,EAAE;IAAiB,CAAC,CAAC;EAAC,CAC3E,CAAC;AAEN,CACF,CAAC;AAEDvB,aAAa,CAACwB,WAAW,GAAG,eAAe","ignoreList":[]}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.DialogPortal = DialogPortal;
7
+ var _portal = require("../portal");
8
+ var _context = require("./context");
9
+ var _jsxRuntime = require("react/jsx-runtime");
10
+ /**
11
+ * Mounts dialog children into the shared PortalHost. Re-provides DialogContext
12
+ * inside the portal boundary (React context does not cross the portal store).
13
+ *
14
+ * When `forceMount` is false (default), the portal is unmounted when the
15
+ * dialog is closed. Set `forceMount={true}` to keep the portal mounted so
16
+ * exit animations can play before the styled layer removes it from the tree.
17
+ */
18
+ function DialogPortal({
19
+ forceMount = false,
20
+ hostName,
21
+ children
22
+ }) {
23
+ const ctx = (0, _context.useDialog)();
24
+ if (!forceMount && !ctx.open) {
25
+ return null;
26
+ }
27
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_portal.Portal, {
28
+ name: `${ctx.nativeID}-portal`,
29
+ hostName: hostName,
30
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_context.DialogProvider, {
31
+ value: ctx,
32
+ children: children
33
+ })
34
+ });
35
+ }
36
+ DialogPortal.displayName = 'DialogPortal';
37
+ //# sourceMappingURL=DialogPortal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_portal","require","_context","_jsxRuntime","DialogPortal","forceMount","hostName","children","ctx","useDialog","open","jsx","Portal","name","nativeID","DialogProvider","value","displayName"],"sourceRoot":"../../../src","sources":["dialog/DialogPortal.tsx"],"mappings":";;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,QAAA,GAAAD,OAAA;AAAsD,IAAAE,WAAA,GAAAF,OAAA;AAKtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASG,YAAYA,CAAC;EAAEC,UAAU,GAAG,KAAK;EAAEC,QAAQ;EAAEC;AAA4B,CAAC,EAAE;EAC1F,MAAMC,GAAG,GAAG,IAAAC,kBAAS,EAAC,CAAC;EAEvB,IAAI,CAACJ,UAAU,IAAI,CAACG,GAAG,CAACE,IAAI,EAAE;IAC5B,OAAO,IAAI;EACb;EAEA,oBACE,IAAAP,WAAA,CAAAQ,GAAA,EAACX,OAAA,CAAAY,MAAM;IAACC,IAAI,EAAE,GAAGL,GAAG,CAACM,QAAQ,SAAU;IAACR,QAAQ,EAAEA,QAAS;IAAAC,QAAA,eACzD,IAAAJ,WAAA,CAAAQ,GAAA,EAACT,QAAA,CAAAa,cAAc;MAACC,KAAK,EAAER,GAAI;MAAAD,QAAA,EAAEA;IAAQ,CAAiB;EAAC,CACjD,CAAC;AAEb;AAEAH,YAAY,CAACa,WAAW,GAAG,cAAc","ignoreList":[]}
@@ -9,12 +9,30 @@ Object.defineProperty(exports, "DialogClose", {
9
9
  return _DialogClose.DialogClose;
10
10
  }
11
11
  });
12
+ Object.defineProperty(exports, "DialogContent", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _DialogContent.DialogContent;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "DialogOverlay", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _DialogOverlay.DialogOverlay;
22
+ }
23
+ });
12
24
  Object.defineProperty(exports, "DialogPopup", {
13
25
  enumerable: true,
14
26
  get: function () {
15
27
  return _DialogPopup.DialogPopup;
16
28
  }
17
29
  });
30
+ Object.defineProperty(exports, "DialogPortal", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _DialogPortal.DialogPortal;
34
+ }
35
+ });
18
36
  Object.defineProperty(exports, "DialogProvider", {
19
37
  enumerable: true,
20
38
  get: function () {
@@ -42,6 +60,9 @@ Object.defineProperty(exports, "useDialog", {
42
60
  var _context = require("./context");
43
61
  var _DialogRoot = require("./DialogRoot");
44
62
  var _DialogTrigger = require("./DialogTrigger");
63
+ var _DialogPortal = require("./DialogPortal");
64
+ var _DialogOverlay = require("./DialogOverlay");
65
+ var _DialogContent = require("./DialogContent");
45
66
  var _DialogPopup = require("./DialogPopup");
46
67
  var _DialogClose = require("./DialogClose");
47
68
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_context","require","_DialogRoot","_DialogTrigger","_DialogPopup","_DialogClose"],"sourceRoot":"../../../src","sources":["dialog/index.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,QAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AACA,IAAAE,cAAA,GAAAF,OAAA;AACA,IAAAG,YAAA,GAAAH,OAAA;AACA,IAAAI,YAAA,GAAAJ,OAAA","ignoreList":[]}
1
+ {"version":3,"names":["_context","require","_DialogRoot","_DialogTrigger","_DialogPortal","_DialogOverlay","_DialogContent","_DialogPopup","_DialogClose"],"sourceRoot":"../../../src","sources":["dialog/index.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,QAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AACA,IAAAE,cAAA,GAAAF,OAAA;AACA,IAAAG,aAAA,GAAAH,OAAA;AACA,IAAAI,cAAA,GAAAJ,OAAA;AACA,IAAAK,cAAA,GAAAL,OAAA;AACA,IAAAM,YAAA,GAAAN,OAAA;AACA,IAAAO,YAAA,GAAAP,OAAA","ignoreList":[]}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+
3
+ import { forwardRef, useCallback, useEffect } from 'react';
4
+ import { BackHandler, View } from 'react-native';
5
+ import { FocusScope } from '@react-native-aria/focus';
6
+ import { Slot } from '../slot';
7
+ import { useEscapeKey } from '../overlay';
8
+ import { dataAttributes, mergeDataAttributes } from '../utils/dataAttributes';
9
+ import { useDialog } from './context';
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ /**
12
+ * Dialog content panel primitive. Provides:
13
+ * - ARIA role, aria-modal, aria-labelledby/describedby
14
+ * - FocusScope (focus trap + restore + auto-focus)
15
+ * - Escape key dismissal (web)
16
+ * - Android hardware back button dismissal (native)
17
+ * - data-state attribute for CSS transition targeting
18
+ *
19
+ * Unstyled — the styled layer applies centering, background, border-radius, etc.
20
+ */
21
+ export const DialogContent = /*#__PURE__*/forwardRef(({
22
+ asChild = false,
23
+ forceMount = false,
24
+ children,
25
+ ...props
26
+ }, ref) => {
27
+ const {
28
+ open,
29
+ onOpenChange,
30
+ closeOnEscKey,
31
+ nativeID,
32
+ role
33
+ } = useDialog();
34
+ const handleClose = useCallback(() => {
35
+ onOpenChange(false);
36
+ }, [onOpenChange]);
37
+ useEscapeKey(open && closeOnEscKey, handleClose);
38
+ useEffect(() => {
39
+ if (!open) return;
40
+ const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
41
+ onOpenChange(false);
42
+ return true;
43
+ });
44
+ return () => {
45
+ backHandler.remove();
46
+ };
47
+ }, [open, onOpenChange]);
48
+ if (!forceMount && !open) {
49
+ return null;
50
+ }
51
+ const Comp = asChild ? Slot : View;
52
+ const ariaProps = {
53
+ role,
54
+ 'aria-modal': true,
55
+ 'aria-labelledby': `${nativeID}-title`,
56
+ 'aria-describedby': `${nativeID}-description`
57
+ };
58
+ return /*#__PURE__*/_jsx(FocusScope, {
59
+ contain: open,
60
+ restoreFocus: true,
61
+ autoFocus: open,
62
+ children: /*#__PURE__*/_jsx(Comp, {
63
+ ref: ref,
64
+ nativeID: nativeID,
65
+ ...ariaProps,
66
+ ...props,
67
+ ...mergeDataAttributes(props, forceMount ? undefined : dataAttributes({
68
+ state: open ? 'open' : 'closed'
69
+ })),
70
+ children: children
71
+ })
72
+ });
73
+ });
74
+ DialogContent.displayName = 'DialogContent';
75
+ //# sourceMappingURL=DialogContent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["forwardRef","useCallback","useEffect","BackHandler","View","FocusScope","Slot","useEscapeKey","dataAttributes","mergeDataAttributes","useDialog","jsx","_jsx","DialogContent","asChild","forceMount","children","props","ref","open","onOpenChange","closeOnEscKey","nativeID","role","handleClose","backHandler","addEventListener","remove","Comp","ariaProps","contain","restoreFocus","autoFocus","undefined","state","displayName"],"sourceRoot":"../../../src","sources":["dialog/DialogContent.tsx"],"mappings":";;AAAA,SAASA,UAAU,EAAEC,WAAW,EAAEC,SAAS,QAA2B,OAAO;AAC7E,SAASC,WAAW,EAAEC,IAAI,QAAwB,cAAc;AAChE,SAASC,UAAU,QAAQ,0BAA0B;AACrD,SAASC,IAAI,QAAQ,SAAS;AAC9B,SAASC,YAAY,QAAQ,YAAY;AACzC,SAASC,cAAc,EAAEC,mBAAmB,QAAQ,yBAAyB;AAC7E,SAASC,SAAS,QAAQ,WAAW;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAKtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,aAAa,gBAAGb,UAAU,CACrC,CAAC;EAAEc,OAAO,GAAG,KAAK;EAAEC,UAAU,GAAG,KAAK;EAAEC,QAAQ;EAAE,GAAGC;AAAM,CAAC,EAAEC,GAAG,KAAK;EACpE,MAAM;IAAEC,IAAI;IAAEC,YAAY;IAAEC,aAAa;IAAEC,QAAQ;IAAEC;EAAK,CAAC,GAAGb,SAAS,CAAC,CAAC;EAEzE,MAAMc,WAAW,GAAGvB,WAAW,CAAC,MAAM;IACpCmB,YAAY,CAAC,KAAK,CAAC;EACrB,CAAC,EAAE,CAACA,YAAY,CAAC,CAAC;EAElBb,YAAY,CAACY,IAAI,IAAIE,aAAa,EAAEG,WAAW,CAAC;EAEhDtB,SAAS,CAAC,MAAM;IACd,IAAI,CAACiB,IAAI,EAAE;IAEX,MAAMM,WAAW,GAAGtB,WAAW,CAACuB,gBAAgB,CAAC,mBAAmB,EAAE,MAAM;MAC1EN,YAAY,CAAC,KAAK,CAAC;MACnB,OAAO,IAAI;IACb,CAAC,CAAC;IAEF,OAAO,MAAM;MACXK,WAAW,CAACE,MAAM,CAAC,CAAC;IACtB,CAAC;EACH,CAAC,EAAE,CAACR,IAAI,EAAEC,YAAY,CAAC,CAAC;EAExB,IAAI,CAACL,UAAU,IAAI,CAACI,IAAI,EAAE;IACxB,OAAO,IAAI;EACb;EAEA,MAAMS,IAAI,GAAGd,OAAO,GAAGR,IAAI,GAAGF,IAAI;EAElC,MAAMyB,SAAS,GAAG;IAChBN,IAAI;IACJ,YAAY,EAAE,IAAI;IAClB,iBAAiB,EAAE,GAAGD,QAAQ,QAAQ;IACtC,kBAAkB,EAAE,GAAGA,QAAQ;EACjC,CAAC;EAED,oBACEV,IAAA,CAACP,UAAU;IAACyB,OAAO,EAAEX,IAAK;IAACY,YAAY;IAACC,SAAS,EAAEb,IAAK;IAAAH,QAAA,eACtDJ,IAAA,CAACgB,IAAI;MACHV,GAAG,EAAEA,GAAI;MACTI,QAAQ,EAAEA,QAAS;MAAA,GACfO,SAAS;MAAA,GACRZ,KAAK;MAAA,GACNR,mBAAmB,CACrBQ,KAAK,EACLF,UAAU,GAAGkB,SAAS,GAAGzB,cAAc,CAAC;QAAE0B,KAAK,EAAEf,IAAI,GAAG,MAAM,GAAG;MAAS,CAAC,CAC7E,CAAC;MAAAH,QAAA,EAEAA;IAAQ,CACL;EAAC,CACG,CAAC;AAEjB,CACF,CAAC;AAEDH,aAAa,CAACsB,WAAW,GAAG,eAAe","ignoreList":[]}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ import { forwardRef, useCallback } from 'react';
4
+ import { Pressable } from 'react-native';
5
+ import { Slot } from '../slot';
6
+ import { dataAttributes, mergeDataAttributes } from '../utils/dataAttributes';
7
+ import { useDialog } from './context';
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ /**
10
+ * Backdrop overlay that dismisses the dialog on press (when closeOnBackdropPress
11
+ * is enabled). Supports `forceMount` for exit animation coordination.
12
+ *
13
+ * Unstyled — the styled layer applies opacity/color via className.
14
+ */
15
+ export const DialogOverlay = /*#__PURE__*/forwardRef(({
16
+ asChild = false,
17
+ forceMount = false,
18
+ onPress,
19
+ ...props
20
+ }, ref) => {
21
+ const {
22
+ open,
23
+ onOpenChange,
24
+ closeOnBackdropPress
25
+ } = useDialog();
26
+ const handlePress = useCallback(e => {
27
+ if (closeOnBackdropPress) {
28
+ onOpenChange(false);
29
+ }
30
+ if (typeof onPress === 'function') {
31
+ onPress(e);
32
+ }
33
+ }, [closeOnBackdropPress, onOpenChange, onPress]);
34
+ if (!forceMount && !open) {
35
+ return null;
36
+ }
37
+ const Comp = asChild ? Slot : Pressable;
38
+ return /*#__PURE__*/_jsx(Comp, {
39
+ ref: ref,
40
+ accessible: false,
41
+ importantForAccessibility: "no-hide-descendants",
42
+ onPress: handlePress,
43
+ ...props,
44
+ ...mergeDataAttributes(props, dataAttributes({
45
+ slot: 'dialog-overlay'
46
+ }))
47
+ });
48
+ });
49
+ DialogOverlay.displayName = 'DialogOverlay';
50
+ //# sourceMappingURL=DialogOverlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["forwardRef","useCallback","Pressable","Slot","dataAttributes","mergeDataAttributes","useDialog","jsx","_jsx","DialogOverlay","asChild","forceMount","onPress","props","ref","open","onOpenChange","closeOnBackdropPress","handlePress","e","Comp","accessible","importantForAccessibility","slot","displayName"],"sourceRoot":"../../../src","sources":["dialog/DialogOverlay.tsx"],"mappings":";;AAAA,SAASA,UAAU,EAAEC,WAAW,QAA2B,OAAO;AAClE,SAASC,SAAS,QAA6B,cAAc;AAC7D,SAASC,IAAI,QAAQ,SAAS;AAC9B,SAASC,cAAc,EAAEC,mBAAmB,QAAQ,yBAAyB;AAC7E,SAASC,SAAS,QAAQ,WAAW;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAKtC;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,aAAa,gBAAGT,UAAU,CACrC,CAAC;EAAEU,OAAO,GAAG,KAAK;EAAEC,UAAU,GAAG,KAAK;EAAEC,OAAO;EAAE,GAAGC;AAAM,CAAC,EAAEC,GAAG,KAAK;EACnE,MAAM;IAAEC,IAAI;IAAEC,YAAY;IAAEC;EAAqB,CAAC,GAAGX,SAAS,CAAC,CAAC;EAEhE,MAAMY,WAAW,GAAGjB,WAAW,CAC5BkB,CAAM,IAAK;IACV,IAAIF,oBAAoB,EAAE;MACxBD,YAAY,CAAC,KAAK,CAAC;IACrB;IACA,IAAI,OAAOJ,OAAO,KAAK,UAAU,EAAE;MACjCA,OAAO,CAACO,CAAC,CAAC;IACZ;EACF,CAAC,EACD,CAACF,oBAAoB,EAAED,YAAY,EAAEJ,OAAO,CAC9C,CAAC;EAED,IAAI,CAACD,UAAU,IAAI,CAACI,IAAI,EAAE;IACxB,OAAO,IAAI;EACb;EAEA,MAAMK,IAAI,GAAGV,OAAO,GAAGP,IAAI,GAAGD,SAAS;EAEvC,oBACEM,IAAA,CAACY,IAAI;IACHN,GAAG,EAAEA,GAAI;IACTO,UAAU,EAAE,KAAM;IAClBC,yBAAyB,EAAC,qBAAqB;IAC/CV,OAAO,EAAEM,WAAY;IAAA,GAChBL,KAAK;IAAA,GACNR,mBAAmB,CAACQ,KAAK,EAAET,cAAc,CAAC;MAAEmB,IAAI,EAAE;IAAiB,CAAC,CAAC;EAAC,CAC3E,CAAC;AAEN,CACF,CAAC;AAEDd,aAAa,CAACe,WAAW,GAAG,eAAe","ignoreList":[]}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ import { Portal } from '../portal';
4
+ import { DialogProvider, useDialog } from './context';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ /**
7
+ * Mounts dialog children into the shared PortalHost. Re-provides DialogContext
8
+ * inside the portal boundary (React context does not cross the portal store).
9
+ *
10
+ * When `forceMount` is false (default), the portal is unmounted when the
11
+ * dialog is closed. Set `forceMount={true}` to keep the portal mounted so
12
+ * exit animations can play before the styled layer removes it from the tree.
13
+ */
14
+ export function DialogPortal({
15
+ forceMount = false,
16
+ hostName,
17
+ children
18
+ }) {
19
+ const ctx = useDialog();
20
+ if (!forceMount && !ctx.open) {
21
+ return null;
22
+ }
23
+ return /*#__PURE__*/_jsx(Portal, {
24
+ name: `${ctx.nativeID}-portal`,
25
+ hostName: hostName,
26
+ children: /*#__PURE__*/_jsx(DialogProvider, {
27
+ value: ctx,
28
+ children: children
29
+ })
30
+ });
31
+ }
32
+ DialogPortal.displayName = 'DialogPortal';
33
+ //# sourceMappingURL=DialogPortal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Portal","DialogProvider","useDialog","jsx","_jsx","DialogPortal","forceMount","hostName","children","ctx","open","name","nativeID","value","displayName"],"sourceRoot":"../../../src","sources":["dialog/DialogPortal.tsx"],"mappings":";;AAAA,SAASA,MAAM,QAAQ,WAAW;AAClC,SAASC,cAAc,EAAEC,SAAS,QAAQ,WAAW;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAKtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,YAAYA,CAAC;EAAEC,UAAU,GAAG,KAAK;EAAEC,QAAQ;EAAEC;AAA4B,CAAC,EAAE;EAC1F,MAAMC,GAAG,GAAGP,SAAS,CAAC,CAAC;EAEvB,IAAI,CAACI,UAAU,IAAI,CAACG,GAAG,CAACC,IAAI,EAAE;IAC5B,OAAO,IAAI;EACb;EAEA,oBACEN,IAAA,CAACJ,MAAM;IAACW,IAAI,EAAE,GAAGF,GAAG,CAACG,QAAQ,SAAU;IAACL,QAAQ,EAAEA,QAAS;IAAAC,QAAA,eACzDJ,IAAA,CAACH,cAAc;MAACY,KAAK,EAAEJ,GAAI;MAAAD,QAAA,EAAEA;IAAQ,CAAiB;EAAC,CACjD,CAAC;AAEb;AAEAH,YAAY,CAACS,WAAW,GAAG,cAAc","ignoreList":[]}
@@ -3,6 +3,9 @@
3
3
  export { DialogProvider, useDialog } from './context';
4
4
  export { DialogRoot } from './DialogRoot';
5
5
  export { DialogTrigger } from './DialogTrigger';
6
+ export { DialogPortal } from './DialogPortal';
7
+ export { DialogOverlay } from './DialogOverlay';
8
+ export { DialogContent } from './DialogContent';
6
9
  export { DialogPopup } from './DialogPopup';
7
10
  export { DialogClose } from './DialogClose';
8
11
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["DialogProvider","useDialog","DialogRoot","DialogTrigger","DialogPopup","DialogClose"],"sourceRoot":"../../../src","sources":["dialog/index.tsx"],"mappings":";;AAAA,SAASA,cAAc,EAAEC,SAAS,QAAQ,WAAW;AACrD,SAASC,UAAU,QAA8B,cAAc;AAC/D,SAASC,aAAa,QAAiC,iBAAiB;AACxE,SAASC,WAAW,QAA+B,eAAe;AAClE,SAASC,WAAW,QAA+B,eAAe","ignoreList":[]}
1
+ {"version":3,"names":["DialogProvider","useDialog","DialogRoot","DialogTrigger","DialogPortal","DialogOverlay","DialogContent","DialogPopup","DialogClose"],"sourceRoot":"../../../src","sources":["dialog/index.tsx"],"mappings":";;AAAA,SAASA,cAAc,EAAEC,SAAS,QAAQ,WAAW;AACrD,SAASC,UAAU,QAA8B,cAAc;AAC/D,SAASC,aAAa,QAAiC,iBAAiB;AACxE,SAASC,YAAY,QAAgC,gBAAgB;AACrE,SAASC,aAAa,QAAiC,iBAAiB;AACxE,SAASC,aAAa,QAAiC,iBAAiB;AACxE,SAASC,WAAW,QAA+B,eAAe;AAClE,SAASC,WAAW,QAA+B,eAAe","ignoreList":[]}
@@ -0,0 +1,16 @@
1
+ import { View } from 'react-native';
2
+ import type { IDialogContentProps } from './types';
3
+ export interface DialogContentProps extends IDialogContentProps {
4
+ }
5
+ /**
6
+ * Dialog content panel primitive. Provides:
7
+ * - ARIA role, aria-modal, aria-labelledby/describedby
8
+ * - FocusScope (focus trap + restore + auto-focus)
9
+ * - Escape key dismissal (web)
10
+ * - Android hardware back button dismissal (native)
11
+ * - data-state attribute for CSS transition targeting
12
+ *
13
+ * Unstyled — the styled layer applies centering, background, border-radius, etc.
14
+ */
15
+ export declare const DialogContent: import("react").ForwardRefExoticComponent<DialogContentProps & import("react").RefAttributes<View>>;
16
+ //# sourceMappingURL=DialogContent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DialogContent.d.ts","sourceRoot":"","sources":["../../../src/dialog/DialogContent.tsx"],"names":[],"mappings":"AACA,OAAO,EAAe,IAAI,EAAkB,MAAM,cAAc,CAAC;AAMjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;CAAG;AAElE;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,qGAqDzB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { IDialogOverlayProps } from './types';
2
+ export interface DialogOverlayProps extends IDialogOverlayProps {
3
+ }
4
+ /**
5
+ * Backdrop overlay that dismisses the dialog on press (when closeOnBackdropPress
6
+ * is enabled). Supports `forceMount` for exit animation coordination.
7
+ *
8
+ * Unstyled — the styled layer applies opacity/color via className.
9
+ */
10
+ export declare const DialogOverlay: import("react").ForwardRefExoticComponent<DialogOverlayProps & import("react").RefAttributes<import("react-native").View>>;
11
+ //# sourceMappingURL=DialogOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DialogOverlay.d.ts","sourceRoot":"","sources":["../../../src/dialog/DialogOverlay.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;CAAG;AAElE;;;;;GAKG;AACH,eAAO,MAAM,aAAa,4HAiCzB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { IDialogPortalProps } from './types';
2
+ export interface DialogPortalProps extends IDialogPortalProps {
3
+ }
4
+ /**
5
+ * Mounts dialog children into the shared PortalHost. Re-provides DialogContext
6
+ * inside the portal boundary (React context does not cross the portal store).
7
+ *
8
+ * When `forceMount` is false (default), the portal is unmounted when the
9
+ * dialog is closed. Set `forceMount={true}` to keep the portal mounted so
10
+ * exit animations can play before the styled layer removes it from the tree.
11
+ */
12
+ export declare function DialogPortal({ forceMount, hostName, children }: DialogPortalProps): import("react/jsx-runtime").JSX.Element | null;
13
+ export declare namespace DialogPortal {
14
+ var displayName: string;
15
+ }
16
+ //# sourceMappingURL=DialogPortal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DialogPortal.d.ts","sourceRoot":"","sources":["../../../src/dialog/DialogPortal.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;CAAG;AAEhE;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,EAAE,UAAkB,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,iBAAiB,kDAYzF;yBAZe,YAAY"}
@@ -1,7 +1,10 @@
1
1
  export { DialogProvider, useDialog } from './context';
2
2
  export { DialogRoot, type DialogRootProps } from './DialogRoot';
3
3
  export { DialogTrigger, type DialogTriggerProps } from './DialogTrigger';
4
+ export { DialogPortal, type DialogPortalProps } from './DialogPortal';
5
+ export { DialogOverlay, type DialogOverlayProps } from './DialogOverlay';
6
+ export { DialogContent, type DialogContentProps } from './DialogContent';
4
7
  export { DialogPopup, type DialogPopupProps } from './DialogPopup';
5
8
  export { DialogClose, type DialogCloseProps } from './DialogClose';
6
- export type { IDialogContextType, IDialogRootProps, IDialogTriggerProps, IDialogPopupProps, IDialogCloseProps, } from './types';
9
+ export type { IDialogContextType, IDialogRootProps, IDialogTriggerProps, IDialogPortalProps, IDialogOverlayProps, IDialogContentProps, IDialogPopupProps, IDialogCloseProps, } from './types';
7
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dialog/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dialog/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
@@ -20,6 +20,30 @@ export interface IDialogRootProps {
20
20
  export interface IDialogTriggerProps extends PressableProps {
21
21
  readonly asChild?: boolean;
22
22
  }
23
+ export interface IDialogPortalProps {
24
+ readonly forceMount?: boolean;
25
+ readonly hostName?: string;
26
+ readonly children: React.ReactNode;
27
+ }
28
+ export interface IDialogOverlayProps extends PressableProps {
29
+ readonly asChild?: boolean;
30
+ readonly forceMount?: boolean;
31
+ }
32
+ export interface IDialogContentProps extends ViewProps {
33
+ readonly asChild?: boolean;
34
+ readonly forceMount?: boolean;
35
+ /**
36
+ * Whether the content shifts up to clear the on-screen keyboard (native only).
37
+ * No-op on web. Defaults to `true`.
38
+ */
39
+ readonly avoidKeyboard?: boolean;
40
+ /**
41
+ * Distance (in px) between the keyboard and the content when keyboard avoidance
42
+ * is active. Forwarded to the underlying keyboard-avoiding layer on native.
43
+ * Defaults to `0`.
44
+ */
45
+ readonly keyboardVerticalOffset?: number;
46
+ }
23
47
  export interface IDialogPopupProps extends ViewProps {
24
48
  readonly forceMount?: boolean;
25
49
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/dialog/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,aAAa,CAAC;CACzC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CACpC;AAED,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAClD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CAC1C;AAED,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/dialog/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,aAAa,CAAC;CACzC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CACpC;AAED,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CACpC;AAED,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,mBAAoB,SAAQ,SAAS;IACpD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CAC1C;AAED,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAClD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CAC1C;AAED,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdx-ui/primitives",
3
- "version": "0.0.1-beta.112",
3
+ "version": "0.0.1-beta.114",
4
4
  "main": "lib/commonjs/index.js",
5
5
  "module": "lib/module/index.js",
6
6
  "react-native": "src/index.ts",
@@ -60,7 +60,7 @@
60
60
  "@react-stately/checkbox": "3.7.4",
61
61
  "@react-stately/radio": "3.12.0",
62
62
  "@react-stately/toggle": "3.9.4",
63
- "@cdx-ui/utils": "0.0.1-beta.112"
63
+ "@cdx-ui/utils": "0.0.1-beta.114"
64
64
  },
65
65
  "devDependencies": {
66
66
  "@types/react": "19.1.17",
@@ -0,0 +1,77 @@
1
+ import { forwardRef, useCallback, useEffect, type ComponentRef } from 'react';
2
+ import { BackHandler, View, type ViewProps } from 'react-native';
3
+ import { FocusScope } from '@react-native-aria/focus';
4
+ import { Slot } from '../slot';
5
+ import { useEscapeKey } from '../overlay';
6
+ import { dataAttributes, mergeDataAttributes } from '../utils/dataAttributes';
7
+ import { useDialog } from './context';
8
+ import type { IDialogContentProps } from './types';
9
+
10
+ export interface DialogContentProps extends IDialogContentProps {}
11
+
12
+ /**
13
+ * Dialog content panel primitive. Provides:
14
+ * - ARIA role, aria-modal, aria-labelledby/describedby
15
+ * - FocusScope (focus trap + restore + auto-focus)
16
+ * - Escape key dismissal (web)
17
+ * - Android hardware back button dismissal (native)
18
+ * - data-state attribute for CSS transition targeting
19
+ *
20
+ * Unstyled — the styled layer applies centering, background, border-radius, etc.
21
+ */
22
+ export const DialogContent = forwardRef<ComponentRef<typeof View>, DialogContentProps>(
23
+ ({ asChild = false, forceMount = false, children, ...props }, ref) => {
24
+ const { open, onOpenChange, closeOnEscKey, nativeID, role } = useDialog();
25
+
26
+ const handleClose = useCallback(() => {
27
+ onOpenChange(false);
28
+ }, [onOpenChange]);
29
+
30
+ useEscapeKey(open && closeOnEscKey, handleClose);
31
+
32
+ useEffect(() => {
33
+ if (!open) return;
34
+
35
+ const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
36
+ onOpenChange(false);
37
+ return true;
38
+ });
39
+
40
+ return () => {
41
+ backHandler.remove();
42
+ };
43
+ }, [open, onOpenChange]);
44
+
45
+ if (!forceMount && !open) {
46
+ return null;
47
+ }
48
+
49
+ const Comp = asChild ? Slot : View;
50
+
51
+ const ariaProps = {
52
+ role,
53
+ 'aria-modal': true,
54
+ 'aria-labelledby': `${nativeID}-title`,
55
+ 'aria-describedby': `${nativeID}-description`,
56
+ };
57
+
58
+ return (
59
+ <FocusScope contain={open} restoreFocus autoFocus={open}>
60
+ <Comp
61
+ ref={ref}
62
+ nativeID={nativeID}
63
+ {...ariaProps}
64
+ {...(props as ViewProps)}
65
+ {...mergeDataAttributes(
66
+ props,
67
+ forceMount ? undefined : dataAttributes({ state: open ? 'open' : 'closed' }),
68
+ )}
69
+ >
70
+ {children}
71
+ </Comp>
72
+ </FocusScope>
73
+ );
74
+ },
75
+ );
76
+
77
+ DialogContent.displayName = 'DialogContent';
@@ -0,0 +1,51 @@
1
+ import { forwardRef, useCallback, type ComponentRef } from 'react';
2
+ import { Pressable, type PressableProps } from 'react-native';
3
+ import { Slot } from '../slot';
4
+ import { dataAttributes, mergeDataAttributes } from '../utils/dataAttributes';
5
+ import { useDialog } from './context';
6
+ import type { IDialogOverlayProps } from './types';
7
+
8
+ export interface DialogOverlayProps extends IDialogOverlayProps {}
9
+
10
+ /**
11
+ * Backdrop overlay that dismisses the dialog on press (when closeOnBackdropPress
12
+ * is enabled). Supports `forceMount` for exit animation coordination.
13
+ *
14
+ * Unstyled — the styled layer applies opacity/color via className.
15
+ */
16
+ export const DialogOverlay = forwardRef<ComponentRef<typeof Pressable>, DialogOverlayProps>(
17
+ ({ asChild = false, forceMount = false, onPress, ...props }, ref) => {
18
+ const { open, onOpenChange, closeOnBackdropPress } = useDialog();
19
+
20
+ const handlePress = useCallback(
21
+ (e: any) => {
22
+ if (closeOnBackdropPress) {
23
+ onOpenChange(false);
24
+ }
25
+ if (typeof onPress === 'function') {
26
+ onPress(e);
27
+ }
28
+ },
29
+ [closeOnBackdropPress, onOpenChange, onPress],
30
+ );
31
+
32
+ if (!forceMount && !open) {
33
+ return null;
34
+ }
35
+
36
+ const Comp = asChild ? Slot : Pressable;
37
+
38
+ return (
39
+ <Comp
40
+ ref={ref}
41
+ accessible={false}
42
+ importantForAccessibility="no-hide-descendants"
43
+ onPress={handlePress}
44
+ {...(props as PressableProps)}
45
+ {...mergeDataAttributes(props, dataAttributes({ slot: 'dialog-overlay' }))}
46
+ />
47
+ );
48
+ },
49
+ );
50
+
51
+ DialogOverlay.displayName = 'DialogOverlay';
@@ -0,0 +1,29 @@
1
+ import { Portal } from '../portal';
2
+ import { DialogProvider, useDialog } from './context';
3
+ import type { IDialogPortalProps } from './types';
4
+
5
+ export interface DialogPortalProps extends IDialogPortalProps {}
6
+
7
+ /**
8
+ * Mounts dialog children into the shared PortalHost. Re-provides DialogContext
9
+ * inside the portal boundary (React context does not cross the portal store).
10
+ *
11
+ * When `forceMount` is false (default), the portal is unmounted when the
12
+ * dialog is closed. Set `forceMount={true}` to keep the portal mounted so
13
+ * exit animations can play before the styled layer removes it from the tree.
14
+ */
15
+ export function DialogPortal({ forceMount = false, hostName, children }: DialogPortalProps) {
16
+ const ctx = useDialog();
17
+
18
+ if (!forceMount && !ctx.open) {
19
+ return null;
20
+ }
21
+
22
+ return (
23
+ <Portal name={`${ctx.nativeID}-portal`} hostName={hostName}>
24
+ <DialogProvider value={ctx}>{children}</DialogProvider>
25
+ </Portal>
26
+ );
27
+ }
28
+
29
+ DialogPortal.displayName = 'DialogPortal';
@@ -1,12 +1,18 @@
1
1
  export { DialogProvider, useDialog } from './context';
2
2
  export { DialogRoot, type DialogRootProps } from './DialogRoot';
3
3
  export { DialogTrigger, type DialogTriggerProps } from './DialogTrigger';
4
+ export { DialogPortal, type DialogPortalProps } from './DialogPortal';
5
+ export { DialogOverlay, type DialogOverlayProps } from './DialogOverlay';
6
+ export { DialogContent, type DialogContentProps } from './DialogContent';
4
7
  export { DialogPopup, type DialogPopupProps } from './DialogPopup';
5
8
  export { DialogClose, type DialogCloseProps } from './DialogClose';
6
9
  export type {
7
10
  IDialogContextType,
8
11
  IDialogRootProps,
9
12
  IDialogTriggerProps,
13
+ IDialogPortalProps,
14
+ IDialogOverlayProps,
15
+ IDialogContentProps,
10
16
  IDialogPopupProps,
11
17
  IDialogCloseProps,
12
18
  } from './types';
@@ -24,6 +24,33 @@ export interface IDialogTriggerProps extends PressableProps {
24
24
  readonly asChild?: boolean;
25
25
  }
26
26
 
27
+ export interface IDialogPortalProps {
28
+ readonly forceMount?: boolean;
29
+ readonly hostName?: string;
30
+ readonly children: React.ReactNode;
31
+ }
32
+
33
+ export interface IDialogOverlayProps extends PressableProps {
34
+ readonly asChild?: boolean;
35
+ readonly forceMount?: boolean;
36
+ }
37
+
38
+ export interface IDialogContentProps extends ViewProps {
39
+ readonly asChild?: boolean;
40
+ readonly forceMount?: boolean;
41
+ /**
42
+ * Whether the content shifts up to clear the on-screen keyboard (native only).
43
+ * No-op on web. Defaults to `true`.
44
+ */
45
+ readonly avoidKeyboard?: boolean;
46
+ /**
47
+ * Distance (in px) between the keyboard and the content when keyboard avoidance
48
+ * is active. Forwarded to the underlying keyboard-avoiding layer on native.
49
+ * Defaults to `0`.
50
+ */
51
+ readonly keyboardVerticalOffset?: number;
52
+ }
53
+
27
54
  export interface IDialogPopupProps extends ViewProps {
28
55
  readonly forceMount?: boolean;
29
56
  /**