@tamagui/alert-dialog 3.0.0-beta.922.1 → 3.0.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/dist/cjs/AlertDialog.cjs +34 -31
- package/dist/cjs/AlertDialog.native.cjs +33 -106
- package/dist/cjs/AlertDialog.native.js +33 -106
- package/dist/cjs/AlertDialog.native.js.map +1 -1
- package/dist/cjs/alertDialogPart.cjs +30 -0
- package/dist/cjs/alertDialogPart.native.cjs +32 -0
- package/dist/cjs/alertDialogPart.native.js +34 -0
- package/dist/cjs/alertDialogPart.native.js.map +1 -0
- package/dist/cjs/useNativeAlertDialog.cjs +24 -0
- package/dist/cjs/useNativeAlertDialog.native.cjs +139 -0
- package/dist/cjs/useNativeAlertDialog.native.js +141 -0
- package/dist/cjs/useNativeAlertDialog.native.js.map +1 -0
- package/dist/esm/AlertDialog.mjs +35 -19
- package/dist/esm/AlertDialog.mjs.map +1 -1
- package/dist/esm/AlertDialog.native.js +33 -104
- package/dist/esm/AlertDialog.native.js.map +1 -1
- package/dist/esm/alertDialogPart.mjs +7 -0
- package/dist/esm/alertDialogPart.mjs.map +1 -0
- package/dist/esm/alertDialogPart.native.js +7 -0
- package/dist/esm/alertDialogPart.native.js.map +1 -0
- package/dist/esm/useNativeAlertDialog.mjs +4 -0
- package/dist/esm/useNativeAlertDialog.mjs.map +1 -0
- package/dist/esm/useNativeAlertDialog.native.js +112 -0
- package/dist/esm/useNativeAlertDialog.native.js.map +1 -0
- package/dist/jsx/AlertDialog.mjs +35 -19
- package/dist/jsx/AlertDialog.mjs.map +1 -1
- package/dist/jsx/AlertDialog.native.cjs +33 -106
- package/dist/jsx/AlertDialog.native.js +33 -106
- package/dist/jsx/AlertDialog.native.js.map +1 -1
- package/dist/jsx/alertDialogPart.mjs +7 -0
- package/dist/jsx/alertDialogPart.mjs.map +1 -0
- package/dist/jsx/alertDialogPart.native.cjs +32 -0
- package/dist/jsx/alertDialogPart.native.js +34 -0
- package/dist/jsx/alertDialogPart.native.js.map +1 -0
- package/dist/jsx/useNativeAlertDialog.mjs +4 -0
- package/dist/jsx/useNativeAlertDialog.mjs.map +1 -0
- package/dist/jsx/useNativeAlertDialog.native.cjs +139 -0
- package/dist/jsx/useNativeAlertDialog.native.js +141 -0
- package/dist/jsx/useNativeAlertDialog.native.js.map +1 -0
- package/package.json +21 -19
- package/src/AlertDialog.tsx +19 -141
- package/src/alertDialogPart.ts +26 -0
- package/src/useNativeAlertDialog.native.tsx +129 -0
- package/src/useNativeAlertDialog.ts +11 -0
- package/types/AlertDialog.d.ts +41 -83
- package/types/AlertDialog.d.ts.map +1 -1
- package/types/alertDialogPart.d.ts +15 -0
- package/types/alertDialogPart.d.ts.map +1 -0
- package/types/useNativeAlertDialog.d.ts +11 -0
- package/types/useNativeAlertDialog.d.ts.map +1 -0
- package/types/useNativeAlertDialog.native.d.ts +11 -0
- package/types/useNativeAlertDialog.native.d.ts.map +1 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all) __defProp(target, name, {
|
|
11
|
+
get: all[name],
|
|
12
|
+
enumerable: true
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
var __copyProps = (to, from, except, desc) => {
|
|
16
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
18
|
+
get: () => from[key],
|
|
19
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return to;
|
|
23
|
+
};
|
|
24
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
25
|
+
value: mod,
|
|
26
|
+
enumerable: true
|
|
27
|
+
}) : target, mod));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var useNativeAlertDialog_native_exports = {};
|
|
30
|
+
__export(useNativeAlertDialog_native_exports, { useNativeAlertDialog: () => useNativeAlertDialog });
|
|
31
|
+
module.exports = __toCommonJS(useNativeAlertDialog_native_exports);
|
|
32
|
+
var import_constants = require("@tamagui/constants");
|
|
33
|
+
var import_core = require("@tamagui/core");
|
|
34
|
+
var import_use_controllable_state = require("@tamagui/use-controllable-state");
|
|
35
|
+
var React = __toESM(require("react"), 1);
|
|
36
|
+
var import_react_native = require("react-native");
|
|
37
|
+
var import_alertDialogPart = require("./alertDialogPart.native.js");
|
|
38
|
+
var useNativeAlertDialog = function(props) {
|
|
39
|
+
var { native } = props;
|
|
40
|
+
var [open, setOpen] = (0, import_use_controllable_state.useControllableState)({
|
|
41
|
+
prop: props.open,
|
|
42
|
+
defaultProp: props.defaultOpen || false,
|
|
43
|
+
onChange: props.onOpenChange,
|
|
44
|
+
transition: true
|
|
45
|
+
});
|
|
46
|
+
var triggerElement = null;
|
|
47
|
+
var title = "";
|
|
48
|
+
var description = "";
|
|
49
|
+
var buttons = [];
|
|
50
|
+
forEachChildDeep(React.Children.toArray(props.children), function(child) {
|
|
51
|
+
if (!/* @__PURE__ */ React.isValidElement(child)) return false;
|
|
52
|
+
var part = (0, import_core.isTamaguiElement)(child) ? child.type.staticConfig[import_alertDialogPart.ALERT_DIALOG_PART] : void 0;
|
|
53
|
+
switch (part) {
|
|
54
|
+
case "trigger": {
|
|
55
|
+
triggerElement = /* @__PURE__ */ React.cloneElement(child, { __native: true });
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
case "title": {
|
|
59
|
+
title = getStringChildren(child);
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
case "description": {
|
|
63
|
+
description = getStringChildren(child);
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
case "action":
|
|
67
|
+
case "destructive":
|
|
68
|
+
case "cancel": {
|
|
69
|
+
var style = part === "action" ? "default" : part === "destructive" ? "destructive" : "cancel";
|
|
70
|
+
var text = getStringChildren(child);
|
|
71
|
+
var onPress = function() {
|
|
72
|
+
var _childProps_onPress;
|
|
73
|
+
var childProps = child.props;
|
|
74
|
+
childProps === null || childProps === void 0 ? void 0 : (_childProps_onPress = childProps.onPress) === null || _childProps_onPress === void 0 ? void 0 : _childProps_onPress.call(childProps, { native: true });
|
|
75
|
+
setOpen(false);
|
|
76
|
+
};
|
|
77
|
+
buttons.push({
|
|
78
|
+
style,
|
|
79
|
+
text,
|
|
80
|
+
onPress
|
|
81
|
+
});
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
default: {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
(0, import_constants.useIsomorphicLayoutEffect)(function() {
|
|
90
|
+
if (!open || !native) return;
|
|
91
|
+
if (title || description) {
|
|
92
|
+
import_react_native.Alert.alert(title, description, buttons);
|
|
93
|
+
}
|
|
94
|
+
}, [native, open]);
|
|
95
|
+
if (native) {
|
|
96
|
+
return /* @__PURE__ */ React.cloneElement(triggerElement, { __onPress: function() {
|
|
97
|
+
setOpen(true);
|
|
98
|
+
} });
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
};
|
|
102
|
+
function forEachChildDeep(children, onChild) {
|
|
103
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
104
|
+
try {
|
|
105
|
+
for (var _iterator = children[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
106
|
+
var child = _step.value;
|
|
107
|
+
if (!/* @__PURE__ */ React.isValidElement(child)) continue;
|
|
108
|
+
if (!onChild(child)) continue;
|
|
109
|
+
var childProps = child.props;
|
|
110
|
+
if (childProps.children) {
|
|
111
|
+
forEachChildDeep(React.Children.toArray(childProps.children), onChild);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
} catch (err) {
|
|
115
|
+
_didIteratorError = true;
|
|
116
|
+
_iteratorError = err;
|
|
117
|
+
} finally {
|
|
118
|
+
try {
|
|
119
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
120
|
+
_iterator.return();
|
|
121
|
+
}
|
|
122
|
+
} finally {
|
|
123
|
+
if (_didIteratorError) {
|
|
124
|
+
throw _iteratorError;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function getStringChildren(child) {
|
|
130
|
+
var string = "";
|
|
131
|
+
forEachChildDeep(React.Children.toArray(child), function(child2) {
|
|
132
|
+
if (typeof child2.props.children === "string") {
|
|
133
|
+
string = child2.props.children;
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
return true;
|
|
137
|
+
});
|
|
138
|
+
return string;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
//# sourceMappingURL=useNativeAlertDialog.native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useNativeAlertDialog.native.js","names":[],"sources":["jsx/useNativeAlertDialog.native.js"],"sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. \"__esModule\" has not been set), then set\n // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\nvar useNativeAlertDialog_native_exports = {};\n__export(useNativeAlertDialog_native_exports, {\n useNativeAlertDialog: () => useNativeAlertDialog\n});\nmodule.exports = __toCommonJS(useNativeAlertDialog_native_exports);\nvar import_constants = require(\"@tamagui/constants\");\nvar import_core = require(\"@tamagui/core\");\nvar import_use_controllable_state = require(\"@tamagui/use-controllable-state\");\nvar React = __toESM(require(\"react\"), 1);\nvar import_react_native = require(\"react-native\");\nvar import_alertDialogPart = require(\"./alertDialogPart\");\nvar useNativeAlertDialog = function(props) {\n var { native } = props;\n var [open, setOpen] = (0, import_use_controllable_state.useControllableState)({\n prop: props.open,\n defaultProp: props.defaultOpen || false,\n onChange: props.onOpenChange,\n transition: true\n });\n var triggerElement = null;\n var title = \"\";\n var description = \"\";\n var buttons = [];\n forEachChildDeep(React.Children.toArray(props.children), function(child) {\n if (!/* @__PURE__ */ React.isValidElement(child)) return false;\n var part = (0, import_core.isTamaguiElement)(child) ? child.type.staticConfig[import_alertDialogPart.ALERT_DIALOG_PART] : void 0;\n switch (part) {\n case \"trigger\": {\n triggerElement = /* @__PURE__ */ React.cloneElement(child, {\n __native: true\n });\n return false;\n }\n case \"title\": {\n title = getStringChildren(child);\n return false;\n }\n case \"description\": {\n description = getStringChildren(child);\n return false;\n }\n case \"action\":\n case \"destructive\":\n case \"cancel\": {\n var style = part === \"action\" ? \"default\" : part === \"destructive\" ? \"destructive\" : \"cancel\";\n var text = getStringChildren(child);\n var onPress = function() {\n var _childProps_onPress;\n var childProps = child.props;\n childProps === null || childProps === void 0 ? void 0 : (_childProps_onPress = childProps.onPress) === null || _childProps_onPress === void 0 ? void 0 : _childProps_onPress.call(childProps, {\n native: true\n });\n setOpen(false);\n };\n buttons.push({\n style,\n text,\n // @ts-ignore\n onPress\n });\n return false;\n }\n default: {\n return true;\n }\n }\n });\n (0, import_constants.useIsomorphicLayoutEffect)(function() {\n if (!open || !native) return;\n if (title || description) {\n import_react_native.Alert.alert(title, description, buttons);\n }\n }, [\n native,\n open\n ]);\n if (native) {\n return /* @__PURE__ */ React.cloneElement(triggerElement, {\n __onPress: function() {\n setOpen(true);\n }\n });\n }\n return null;\n};\nfunction forEachChildDeep(children, onChild) {\n var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;\n try {\n for (var _iterator = children[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var child = _step.value;\n if (!/* @__PURE__ */ React.isValidElement(child)) continue;\n if (!onChild(child)) continue;\n var childProps = child.props;\n if (childProps.children) {\n forEachChildDeep(React.Children.toArray(childProps.children), onChild);\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n}\nfunction getStringChildren(child) {\n var string = \"\";\n forEachChildDeep(React.Children.toArray(child), function(child2) {\n if (typeof child2.props.children === \"string\") {\n string = child2.props.children;\n return false;\n }\n return true;\n });\n return string;\n}\n//# sourceMappingURL=useNativeAlertDialog.native.js.map\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/alert-dialog",
|
|
3
|
-
"version": "3.0.0
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"license": "MIT",
|
|
4
5
|
"source": "src/index.ts",
|
|
5
6
|
"files": [
|
|
6
7
|
"src",
|
|
@@ -34,26 +35,26 @@
|
|
|
34
35
|
"clean:build": "tamagui-build clean:build"
|
|
35
36
|
},
|
|
36
37
|
"dependencies": {
|
|
37
|
-
"@tamagui/animate-presence": "3.0.0
|
|
38
|
-
"@tamagui/compose-refs": "3.0.0
|
|
39
|
-
"@tamagui/constants": "3.0.0
|
|
40
|
-
"@tamagui/core": "3.0.0
|
|
41
|
-
"@tamagui/create-context": "3.0.0
|
|
42
|
-
"@tamagui/dialog": "3.0.0
|
|
43
|
-
"@tamagui/dismissable": "3.0.0
|
|
44
|
-
"@tamagui/focus-scope": "3.0.0
|
|
45
|
-
"@tamagui/helpers": "3.0.0
|
|
46
|
-
"@tamagui/polyfill-dev": "3.0.0
|
|
47
|
-
"@tamagui/portal": "3.0.0
|
|
48
|
-
"@tamagui/remove-scroll": "3.0.0
|
|
49
|
-
"@tamagui/stacks": "3.0.0
|
|
50
|
-
"@tamagui/text": "3.0.0
|
|
51
|
-
"@tamagui/use-controllable-state": "3.0.0
|
|
38
|
+
"@tamagui/animate-presence": "3.0.0",
|
|
39
|
+
"@tamagui/compose-refs": "3.0.0",
|
|
40
|
+
"@tamagui/constants": "3.0.0",
|
|
41
|
+
"@tamagui/core": "3.0.0",
|
|
42
|
+
"@tamagui/create-context": "3.0.0",
|
|
43
|
+
"@tamagui/dialog": "3.0.0",
|
|
44
|
+
"@tamagui/dismissable": "3.0.0",
|
|
45
|
+
"@tamagui/focus-scope": "3.0.0",
|
|
46
|
+
"@tamagui/helpers": "3.0.0",
|
|
47
|
+
"@tamagui/polyfill-dev": "3.0.0",
|
|
48
|
+
"@tamagui/portal": "3.0.0",
|
|
49
|
+
"@tamagui/remove-scroll": "3.0.0",
|
|
50
|
+
"@tamagui/stacks": "3.0.0",
|
|
51
|
+
"@tamagui/text": "3.0.0",
|
|
52
|
+
"@tamagui/use-controllable-state": "3.0.0"
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
54
|
-
"@tamagui/build": "3.0.0
|
|
55
|
+
"@tamagui/build": "3.0.0",
|
|
55
56
|
"react": "19.2.3",
|
|
56
|
-
"react-native": "0.
|
|
57
|
+
"react-native": "0.87.1"
|
|
57
58
|
},
|
|
58
59
|
"peerDependencies": {
|
|
59
60
|
"react": ">=19",
|
|
@@ -65,5 +66,6 @@
|
|
|
65
66
|
"type": "git",
|
|
66
67
|
"url": "git+https://github.com/tamagui/tamagui.git",
|
|
67
68
|
"directory": "code/ui/alert-dialog"
|
|
68
|
-
}
|
|
69
|
+
},
|
|
70
|
+
"releaseSourceCommit": "15fbca480b143f876f6975601e23a17d3f90d2ee"
|
|
69
71
|
}
|
package/src/AlertDialog.tsx
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
import { createStyledHOC
|
|
1
|
+
import { createStyledHOC } from '@tamagui/core'
|
|
2
2
|
// forked from radix-ui
|
|
3
3
|
// https://github.com/radix-ui/primitives/blob/main/packages/react/alert-dialog/src/AlertDialog.tsx
|
|
4
4
|
|
|
5
5
|
import { useComposedRefs } from '@tamagui/compose-refs'
|
|
6
6
|
import { isWeb, useIsomorphicLayoutEffect } from '@tamagui/constants'
|
|
7
7
|
import type { TamaguiElement } from '@tamagui/core'
|
|
8
|
-
import {
|
|
9
|
-
Slottable,
|
|
10
|
-
View,
|
|
11
|
-
createStyledContext,
|
|
12
|
-
isTamaguiElement,
|
|
13
|
-
styled,
|
|
14
|
-
} from '@tamagui/core'
|
|
8
|
+
import { Slottable, View, createStyledContext, styled } from '@tamagui/core'
|
|
15
9
|
import type {
|
|
16
10
|
DialogCloseProps,
|
|
17
11
|
DialogContentProps,
|
|
@@ -27,6 +21,7 @@ import {
|
|
|
27
21
|
Dialog,
|
|
28
22
|
DialogClose,
|
|
29
23
|
DialogContent,
|
|
24
|
+
DialogContentFrame,
|
|
30
25
|
DialogDescription,
|
|
31
26
|
DialogOverlay,
|
|
32
27
|
DialogOverlayFrame,
|
|
@@ -36,9 +31,10 @@ import {
|
|
|
36
31
|
DialogWarningProvider,
|
|
37
32
|
} from '@tamagui/dialog'
|
|
38
33
|
import { composeEventHandlers, withStaticProperties } from '@tamagui/helpers'
|
|
39
|
-
import { useControllableState } from '@tamagui/use-controllable-state'
|
|
40
34
|
import * as React from 'react'
|
|
41
|
-
|
|
35
|
+
|
|
36
|
+
import { markAlertDialogPart } from './alertDialogPart'
|
|
37
|
+
import { useNativeAlertDialog } from './useNativeAlertDialog'
|
|
42
38
|
|
|
43
39
|
const getAlertDialogScope = (scope?: string) => scope
|
|
44
40
|
|
|
@@ -47,27 +43,6 @@ const getAlertDialogScope = (scope?: string) => scope
|
|
|
47
43
|
* -----------------------------------------------------------------------------------------------*/
|
|
48
44
|
|
|
49
45
|
const ROOT_NAME = 'AlertDialog'
|
|
50
|
-
const ALERT_DIALOG_PART = Symbol('AlertDialogPart')
|
|
51
|
-
|
|
52
|
-
type AlertDialogPart =
|
|
53
|
-
| 'trigger'
|
|
54
|
-
| 'title'
|
|
55
|
-
| 'description'
|
|
56
|
-
| 'action'
|
|
57
|
-
| 'cancel'
|
|
58
|
-
| 'destructive'
|
|
59
|
-
|
|
60
|
-
type AlertDialogPartStaticConfig = {
|
|
61
|
-
[ALERT_DIALOG_PART]?: AlertDialogPart
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const markAlertDialogPart = (
|
|
65
|
-
component: { staticConfig: object },
|
|
66
|
-
part: AlertDialogPart
|
|
67
|
-
) => {
|
|
68
|
-
Object.assign(component.staticConfig, { [ALERT_DIALOG_PART]: part })
|
|
69
|
-
}
|
|
70
|
-
|
|
71
46
|
export type AlertDialogScopes = string
|
|
72
47
|
|
|
73
48
|
type ScopedProps<P> = Omit<P, 'scope'> & { scope?: AlertDialogScopes }
|
|
@@ -175,8 +150,17 @@ type AlertDialogContentProps = ScopedProps<
|
|
|
175
150
|
Omit<DialogContentProps, 'onPointerDownOutside' | 'onInteractOutside'>
|
|
176
151
|
>
|
|
177
152
|
|
|
178
|
-
|
|
179
|
-
|
|
153
|
+
// a styled HOC, not a plain component wrapping DialogContent: `styled()` on a
|
|
154
|
+
// plain component would land the animation props on this outer frame, which
|
|
155
|
+
// renders above the presence boundary DialogContent creates, and an exiting
|
|
156
|
+
// frame that never joins presence finishes its exit instantly
|
|
157
|
+
const AlertDialogContentFrame = styled(DialogContentFrame, {
|
|
158
|
+
displayName: CONTENT_NAME,
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
const AlertDialogContent = createStyledHOC(
|
|
162
|
+
AlertDialogContentFrame,
|
|
163
|
+
function AlertDialogContent(props: AlertDialogContentProps, forwardedRef) {
|
|
180
164
|
const { scope, children, ...contentProps } = props
|
|
181
165
|
const dialogScope = getAlertDialogScope(scope)
|
|
182
166
|
const contentRef = React.useRef<TamaguiElement>(null)
|
|
@@ -392,118 +376,12 @@ const AlertDialogInner: React.FC<AlertDialogProps> = (props) => {
|
|
|
392
376
|
const { scope, native, ...alertDialogProps } = props
|
|
393
377
|
const dialogScope = getAlertDialogScope(scope)
|
|
394
378
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
prop: props.open,
|
|
398
|
-
defaultProp: props.defaultOpen || false,
|
|
399
|
-
onChange: props.onOpenChange,
|
|
400
|
-
transition: true,
|
|
401
|
-
})
|
|
402
|
-
|
|
403
|
-
let triggerElement: any = null
|
|
404
|
-
let title = ''
|
|
405
|
-
let description = ''
|
|
406
|
-
const buttons: {
|
|
407
|
-
text: string
|
|
408
|
-
onPress: (value?: string | undefined) => void
|
|
409
|
-
style?: 'default' | 'cancel' | 'destructive'
|
|
410
|
-
}[] = []
|
|
411
|
-
|
|
412
|
-
forEachChildDeep(React.Children.toArray(props.children), (child) => {
|
|
413
|
-
if (!React.isValidElement(child)) return false
|
|
414
|
-
const part = isTamaguiElement(child)
|
|
415
|
-
? (child.type.staticConfig as AlertDialogPartStaticConfig)[ALERT_DIALOG_PART]
|
|
416
|
-
: undefined
|
|
417
|
-
switch (part) {
|
|
418
|
-
case 'trigger': {
|
|
419
|
-
triggerElement = React.cloneElement(child as any, {
|
|
420
|
-
__native: true,
|
|
421
|
-
})
|
|
422
|
-
return false
|
|
423
|
-
}
|
|
424
|
-
case 'title': {
|
|
425
|
-
title = getStringChildren(child)
|
|
426
|
-
return false
|
|
427
|
-
}
|
|
428
|
-
case 'description': {
|
|
429
|
-
description = getStringChildren(child)
|
|
430
|
-
return false
|
|
431
|
-
}
|
|
432
|
-
case 'action':
|
|
433
|
-
case 'destructive':
|
|
434
|
-
case 'cancel': {
|
|
435
|
-
const style =
|
|
436
|
-
part === 'action'
|
|
437
|
-
? 'default'
|
|
438
|
-
: part === 'destructive'
|
|
439
|
-
? 'destructive'
|
|
440
|
-
: 'cancel'
|
|
441
|
-
const text = getStringChildren(child)
|
|
442
|
-
const onPress = () => {
|
|
443
|
-
const childProps = child.props as any
|
|
444
|
-
childProps?.onPress?.({ native: true })
|
|
445
|
-
setOpen(false)
|
|
446
|
-
}
|
|
447
|
-
buttons.push({
|
|
448
|
-
style,
|
|
449
|
-
text,
|
|
450
|
-
// @ts-ignore
|
|
451
|
-
onPress,
|
|
452
|
-
})
|
|
453
|
-
return false
|
|
454
|
-
}
|
|
455
|
-
default: {
|
|
456
|
-
return true
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
})
|
|
460
|
-
|
|
461
|
-
useIsomorphicLayoutEffect(() => {
|
|
462
|
-
if (!open || !native) return
|
|
463
|
-
if (title || description) {
|
|
464
|
-
Alert.alert(title, description, buttons)
|
|
465
|
-
}
|
|
466
|
-
}, [native, open])
|
|
467
|
-
|
|
468
|
-
if (native) {
|
|
469
|
-
return React.cloneElement(triggerElement, {
|
|
470
|
-
__onPress: () => {
|
|
471
|
-
setOpen(true)
|
|
472
|
-
},
|
|
473
|
-
})
|
|
474
|
-
}
|
|
475
|
-
}
|
|
379
|
+
const nativeAlert = useNativeAlertDialog(props)
|
|
380
|
+
if (nativeAlert) return nativeAlert
|
|
476
381
|
|
|
477
382
|
return <Dialog scope={dialogScope} {...alertDialogProps} modal />
|
|
478
383
|
}
|
|
479
384
|
|
|
480
|
-
function forEachChildDeep(
|
|
481
|
-
children: React.ReactNode[],
|
|
482
|
-
onChild: (el: React.ReactElement) => boolean
|
|
483
|
-
) {
|
|
484
|
-
for (const child of children) {
|
|
485
|
-
if (!React.isValidElement(child)) continue
|
|
486
|
-
if (!onChild(child)) continue
|
|
487
|
-
// TODO react 19 doesn't like child.props
|
|
488
|
-
const childProps = child.props as unknown as any
|
|
489
|
-
if (childProps.children) {
|
|
490
|
-
forEachChildDeep(React.Children.toArray(childProps.children), onChild)
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
function getStringChildren(child: React.ReactElement) {
|
|
496
|
-
let string = ''
|
|
497
|
-
forEachChildDeep(React.Children.toArray(child), (child) => {
|
|
498
|
-
if (typeof (child.props as Record<string, any>).children === 'string') {
|
|
499
|
-
string = (child.props as Record<string, any>).children
|
|
500
|
-
return false
|
|
501
|
-
}
|
|
502
|
-
return true
|
|
503
|
-
})
|
|
504
|
-
return string
|
|
505
|
-
}
|
|
506
|
-
|
|
507
385
|
const AlertDialog = withStaticProperties(AlertDialogInner, {
|
|
508
386
|
Trigger: AlertDialogTrigger,
|
|
509
387
|
Portal: AlertDialogPortal,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which slot a child fills, stamped onto the styled component's staticConfig so
|
|
3
|
+
* the native path can find the title, description and buttons by walking the
|
|
4
|
+
* tree instead of rendering it. Lives here so the native-only walker can read
|
|
5
|
+
* it without importing back into `AlertDialog`.
|
|
6
|
+
*/
|
|
7
|
+
export const ALERT_DIALOG_PART = Symbol('AlertDialogPart')
|
|
8
|
+
|
|
9
|
+
export type AlertDialogPart =
|
|
10
|
+
| 'trigger'
|
|
11
|
+
| 'title'
|
|
12
|
+
| 'description'
|
|
13
|
+
| 'action'
|
|
14
|
+
| 'cancel'
|
|
15
|
+
| 'destructive'
|
|
16
|
+
|
|
17
|
+
export type AlertDialogPartStaticConfig = {
|
|
18
|
+
[ALERT_DIALOG_PART]?: AlertDialogPart
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const markAlertDialogPart = (
|
|
22
|
+
component: { staticConfig: object },
|
|
23
|
+
part: AlertDialogPart
|
|
24
|
+
) => {
|
|
25
|
+
Object.assign(component.staticConfig, { [ALERT_DIALOG_PART]: part })
|
|
26
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { useIsomorphicLayoutEffect } from '@tamagui/constants'
|
|
2
|
+
import { isTamaguiElement } from '@tamagui/core'
|
|
3
|
+
import type { DialogProps } from '@tamagui/dialog'
|
|
4
|
+
import { useControllableState } from '@tamagui/use-controllable-state'
|
|
5
|
+
import * as React from 'react'
|
|
6
|
+
import { Alert } from 'react-native'
|
|
7
|
+
|
|
8
|
+
import type { AlertDialogPartStaticConfig } from './alertDialogPart'
|
|
9
|
+
import { ALERT_DIALOG_PART } from './alertDialogPart'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* With `native`, the dialog is the platform's own alert: the children are never
|
|
13
|
+
* rendered, they are read for their title, description and buttons and handed
|
|
14
|
+
* to `Alert.alert`, and only the trigger stays in the tree.
|
|
15
|
+
*/
|
|
16
|
+
export const useNativeAlertDialog = (
|
|
17
|
+
props: DialogProps & { native?: boolean }
|
|
18
|
+
): React.ReactElement | null => {
|
|
19
|
+
const { native } = props
|
|
20
|
+
|
|
21
|
+
const [open, setOpen] = useControllableState({
|
|
22
|
+
prop: props.open,
|
|
23
|
+
defaultProp: props.defaultOpen || false,
|
|
24
|
+
onChange: props.onOpenChange,
|
|
25
|
+
transition: true,
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
let triggerElement: any = null
|
|
29
|
+
let title = ''
|
|
30
|
+
let description = ''
|
|
31
|
+
const buttons: {
|
|
32
|
+
text: string
|
|
33
|
+
onPress: (value?: string | undefined) => void
|
|
34
|
+
style?: 'default' | 'cancel' | 'destructive'
|
|
35
|
+
}[] = []
|
|
36
|
+
|
|
37
|
+
forEachChildDeep(React.Children.toArray(props.children), (child) => {
|
|
38
|
+
if (!React.isValidElement(child)) return false
|
|
39
|
+
const part = isTamaguiElement(child)
|
|
40
|
+
? (child.type.staticConfig as AlertDialogPartStaticConfig)[ALERT_DIALOG_PART]
|
|
41
|
+
: undefined
|
|
42
|
+
switch (part) {
|
|
43
|
+
case 'trigger': {
|
|
44
|
+
triggerElement = React.cloneElement(child as any, {
|
|
45
|
+
__native: true,
|
|
46
|
+
})
|
|
47
|
+
return false
|
|
48
|
+
}
|
|
49
|
+
case 'title': {
|
|
50
|
+
title = getStringChildren(child)
|
|
51
|
+
return false
|
|
52
|
+
}
|
|
53
|
+
case 'description': {
|
|
54
|
+
description = getStringChildren(child)
|
|
55
|
+
return false
|
|
56
|
+
}
|
|
57
|
+
case 'action':
|
|
58
|
+
case 'destructive':
|
|
59
|
+
case 'cancel': {
|
|
60
|
+
const style =
|
|
61
|
+
part === 'action'
|
|
62
|
+
? 'default'
|
|
63
|
+
: part === 'destructive'
|
|
64
|
+
? 'destructive'
|
|
65
|
+
: 'cancel'
|
|
66
|
+
const text = getStringChildren(child)
|
|
67
|
+
const onPress = () => {
|
|
68
|
+
const childProps = child.props as any
|
|
69
|
+
childProps?.onPress?.({ native: true })
|
|
70
|
+
setOpen(false)
|
|
71
|
+
}
|
|
72
|
+
buttons.push({
|
|
73
|
+
style,
|
|
74
|
+
text,
|
|
75
|
+
// @ts-ignore
|
|
76
|
+
onPress,
|
|
77
|
+
})
|
|
78
|
+
return false
|
|
79
|
+
}
|
|
80
|
+
default: {
|
|
81
|
+
return true
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
useIsomorphicLayoutEffect(() => {
|
|
87
|
+
if (!open || !native) return
|
|
88
|
+
if (title || description) {
|
|
89
|
+
Alert.alert(title, description, buttons)
|
|
90
|
+
}
|
|
91
|
+
}, [native, open])
|
|
92
|
+
|
|
93
|
+
if (native) {
|
|
94
|
+
return React.cloneElement(triggerElement, {
|
|
95
|
+
__onPress: () => {
|
|
96
|
+
setOpen(true)
|
|
97
|
+
},
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return null
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function forEachChildDeep(
|
|
105
|
+
children: React.ReactNode[],
|
|
106
|
+
onChild: (el: React.ReactElement) => boolean
|
|
107
|
+
) {
|
|
108
|
+
for (const child of children) {
|
|
109
|
+
if (!React.isValidElement(child)) continue
|
|
110
|
+
if (!onChild(child)) continue
|
|
111
|
+
// TODO react 19 doesn't like child.props
|
|
112
|
+
const childProps = child.props as unknown as any
|
|
113
|
+
if (childProps.children) {
|
|
114
|
+
forEachChildDeep(React.Children.toArray(childProps.children), onChild)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function getStringChildren(child: React.ReactElement) {
|
|
120
|
+
let string = ''
|
|
121
|
+
forEachChildDeep(React.Children.toArray(child), (child) => {
|
|
122
|
+
if (typeof (child.props as Record<string, any>).children === 'string') {
|
|
123
|
+
string = (child.props as Record<string, any>).children
|
|
124
|
+
return false
|
|
125
|
+
}
|
|
126
|
+
return true
|
|
127
|
+
})
|
|
128
|
+
return string
|
|
129
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DialogProps } from '@tamagui/dialog'
|
|
2
|
+
import type * as React from 'react'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* `native` asks for the platform's own alert, which the web does not have, so
|
|
6
|
+
* the web build always falls through to the real dialog. The native sibling is
|
|
7
|
+
* where the work happens.
|
|
8
|
+
*/
|
|
9
|
+
export const useNativeAlertDialog = (
|
|
10
|
+
_props: DialogProps & { native?: boolean }
|
|
11
|
+
): React.ReactElement | null => null
|