@tamagui/alert-dialog 1.0.1-beta.113 → 1.0.1-beta.116
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.js +102 -1
- package/dist/cjs/AlertDialog.js.map +2 -2
- package/dist/esm/AlertDialog.js +104 -1
- package/dist/esm/AlertDialog.js.map +2 -2
- package/dist/jsx/AlertDialog.js +101 -1
- package/dist/jsx/AlertDialog.js.map +2 -2
- package/package.json +17 -17
- package/src/AlertDialog.tsx +127 -6
- package/types/AlertDialog.d.ts +9 -8
- package/types/AlertDialog.d.ts.map +1 -1
package/dist/cjs/AlertDialog.js
CHANGED
|
@@ -37,14 +37,27 @@ var import_compose_refs = require("@tamagui/compose-refs");
|
|
|
37
37
|
var import_core = require("@tamagui/core");
|
|
38
38
|
var import_create_context = require("@tamagui/create-context");
|
|
39
39
|
var import_dialog = require("@tamagui/dialog");
|
|
40
|
+
var import_stacks = require("@tamagui/stacks");
|
|
41
|
+
var import_use_controllable_state = require("@tamagui/use-controllable-state");
|
|
40
42
|
var React = __toESM(require("react"));
|
|
43
|
+
var import_react_native = require("react-native");
|
|
41
44
|
const ROOT_NAME = "AlertDialog";
|
|
42
45
|
const [createAlertDialogContext, createAlertDialogScope] = (0, import_create_context.createContextScope)(ROOT_NAME, [
|
|
43
46
|
import_dialog.createDialogScope
|
|
44
47
|
]);
|
|
45
48
|
const useDialogScope = (0, import_dialog.createDialogScope)();
|
|
46
49
|
const TRIGGER_NAME = "AlertDialogTrigger";
|
|
50
|
+
const NativeAlertDialogTriggerFrame = (0, import_core.styled)(import_stacks.YStack, {
|
|
51
|
+
name: "DialogTrigger"
|
|
52
|
+
});
|
|
47
53
|
const AlertDialogTrigger = React.forwardRef((props, forwardedRef) => {
|
|
54
|
+
if (props["__native"]) {
|
|
55
|
+
const { __native, onPress, __onPress, ...rest } = props;
|
|
56
|
+
return /* @__PURE__ */ React.createElement(NativeAlertDialogTriggerFrame, {
|
|
57
|
+
...rest,
|
|
58
|
+
onPress: (0, import_core.composeEventHandlers)(onPress, __onPress)
|
|
59
|
+
});
|
|
60
|
+
}
|
|
48
61
|
const { __scopeAlertDialog, ...triggerProps } = props;
|
|
49
62
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
50
63
|
return /* @__PURE__ */ React.createElement(import_dialog.DialogTrigger, {
|
|
@@ -174,14 +187,102 @@ For more information, see https://tamagui.dev/docs/components/alert-dialog`;
|
|
|
174
187
|
return null;
|
|
175
188
|
};
|
|
176
189
|
const AlertDialogInner = (props) => {
|
|
177
|
-
const { __scopeAlertDialog, ...alertDialogProps } = props;
|
|
190
|
+
const { __scopeAlertDialog, native, ...alertDialogProps } = props;
|
|
178
191
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
192
|
+
if (process.env.TAMAGUI_TARGET === "native") {
|
|
193
|
+
const [open, setOpen] = (0, import_use_controllable_state.useControllableState)({
|
|
194
|
+
prop: props.open,
|
|
195
|
+
defaultProp: props.defaultOpen || false,
|
|
196
|
+
onChange: props.onOpenChange
|
|
197
|
+
});
|
|
198
|
+
let triggerElement = null;
|
|
199
|
+
let title = "";
|
|
200
|
+
let description = "";
|
|
201
|
+
const buttons = [];
|
|
202
|
+
forEachChildDeep(React.Children.toArray(props.children), (child) => {
|
|
203
|
+
if (!React.isValidElement(child))
|
|
204
|
+
return false;
|
|
205
|
+
const name = (0, import_core.isTamaguiElement)(child) ? child.type.staticConfig.componentName : child.type["displayName"];
|
|
206
|
+
switch (name) {
|
|
207
|
+
case TRIGGER_NAME: {
|
|
208
|
+
triggerElement = React.cloneElement(child, {
|
|
209
|
+
__native: true
|
|
210
|
+
});
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
case TITLE_NAME: {
|
|
214
|
+
title = getStringChildren(child);
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
case DESCRIPTION_NAME: {
|
|
218
|
+
description = getStringChildren(child);
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
case ACTION_NAME:
|
|
222
|
+
case CANCEL_NAME: {
|
|
223
|
+
const style = name === ACTION_NAME ? "default" : "cancel";
|
|
224
|
+
const text = getStringChildren(child);
|
|
225
|
+
const onPress = () => {
|
|
226
|
+
var _a, _b;
|
|
227
|
+
;
|
|
228
|
+
(_b = (_a = child.props) == null ? void 0 : _a.onPress) == null ? void 0 : _b.call(_a, { native: true });
|
|
229
|
+
setOpen(false);
|
|
230
|
+
};
|
|
231
|
+
buttons.push({
|
|
232
|
+
style,
|
|
233
|
+
text,
|
|
234
|
+
onPress
|
|
235
|
+
});
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
default: {
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
React.useLayoutEffect(() => {
|
|
244
|
+
if (!open || !native)
|
|
245
|
+
return;
|
|
246
|
+
if (title || description) {
|
|
247
|
+
import_react_native.Alert.alert(title, description, buttons);
|
|
248
|
+
}
|
|
249
|
+
}, [native, open]);
|
|
250
|
+
if (native) {
|
|
251
|
+
return React.cloneElement(triggerElement, {
|
|
252
|
+
__onPress: () => {
|
|
253
|
+
setOpen(true);
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
}
|
|
179
258
|
return /* @__PURE__ */ React.createElement(import_dialog.Dialog, {
|
|
180
259
|
...dialogScope,
|
|
181
260
|
...alertDialogProps,
|
|
182
261
|
modal: true
|
|
183
262
|
});
|
|
184
263
|
};
|
|
264
|
+
function forEachChildDeep(children, onChild) {
|
|
265
|
+
for (const child of children) {
|
|
266
|
+
if (!React.isValidElement(child))
|
|
267
|
+
continue;
|
|
268
|
+
if (!onChild(child))
|
|
269
|
+
continue;
|
|
270
|
+
if (child.props.children) {
|
|
271
|
+
forEachChildDeep(React.Children.toArray(child.props.children), onChild);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function getStringChildren(child) {
|
|
276
|
+
let string = "";
|
|
277
|
+
forEachChildDeep(React.Children.toArray(child), (child2) => {
|
|
278
|
+
if (typeof child2.props.children === "string") {
|
|
279
|
+
string = child2.props.children;
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
return true;
|
|
283
|
+
});
|
|
284
|
+
return string;
|
|
285
|
+
}
|
|
185
286
|
const AlertDialog = (0, import_core.withStaticProperties)(AlertDialogInner, {
|
|
186
287
|
Trigger: AlertDialogTrigger,
|
|
187
288
|
Portal: AlertDialogPortal,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/AlertDialog.tsx"],
|
|
4
|
-
"sourcesContent": ["// forked from radix-ui\n// https://github.com/radix-ui/primitives/blob/main/packages/react/alert-dialog/src/AlertDialog.tsx\n\nimport { useComposedRefs } from '@tamagui/compose-refs'\nimport {\n Slottable,\n TamaguiElement,\n composeEventHandlers,\n isWeb,\n withStaticProperties,\n} from '@tamagui/core'\nimport { Scope, createContextScope } from '@tamagui/create-context'\nimport {\n Dialog,\n DialogClose,\n DialogCloseProps,\n DialogContent,\n DialogContentProps,\n DialogDescription,\n DialogDescriptionProps,\n DialogOverlay,\n DialogOverlayProps,\n DialogPortal,\n DialogPortalProps,\n DialogProps,\n DialogTitle,\n DialogTitleProps,\n DialogTrigger,\n DialogTriggerProps,\n DialogWarningProvider,\n createDialogScope,\n} from '@tamagui/dialog'\nimport * as React from 'react'\n\nconst ROOT_NAME = 'AlertDialog'\n\ntype ScopedProps<P> = P & { __scopeAlertDialog?: Scope }\nconst [createAlertDialogContext, createAlertDialogScope] = createContextScope(ROOT_NAME, [\n createDialogScope,\n])\n\nconst useDialogScope = createDialogScope()\n\ninterface AlertDialogProps extends Omit<DialogProps, 'modal'> {}\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogTrigger\n * -----------------------------------------------------------------------------------------------*/\nconst TRIGGER_NAME = 'AlertDialogTrigger'\n\ninterface AlertDialogTriggerProps extends DialogTriggerProps {}\n\nconst AlertDialogTrigger = React.forwardRef<TamaguiElement, AlertDialogTriggerProps>(\n (props: ScopedProps<AlertDialogTriggerProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...triggerProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogTrigger {...dialogScope} {...triggerProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogTrigger.displayName = TRIGGER_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogPortal\n * -----------------------------------------------------------------------------------------------*/\n\nconst PORTAL_NAME = 'AlertDialogPortal'\n\ninterface AlertDialogPortalProps extends DialogPortalProps {}\n\nconst AlertDialogPortal: React.FC<AlertDialogPortalProps> = (\n props: ScopedProps<AlertDialogPortalProps>\n) => {\n const { __scopeAlertDialog, ...portalProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogPortal {...dialogScope} {...portalProps} />\n}\n\nAlertDialogPortal.displayName = PORTAL_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogOverlay\n * -----------------------------------------------------------------------------------------------*/\n\nconst OVERLAY_NAME = 'AlertDialogOverlay'\n\ninterface AlertDialogOverlayProps extends DialogOverlayProps {}\n\nconst AlertDialogOverlay = React.forwardRef<TamaguiElement, AlertDialogOverlayProps>(\n (props: ScopedProps<AlertDialogOverlayProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...overlayProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogOverlay {...dialogScope} {...overlayProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogOverlay.displayName = OVERLAY_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogContent\n * -----------------------------------------------------------------------------------------------*/\n\nconst CONTENT_NAME = 'AlertDialogContent'\n\ntype AlertDialogContentContextValue = {\n cancelRef: React.MutableRefObject<TamaguiElement | null>\n}\n\nconst [AlertDialogContentProvider, useAlertDialogContentContext] =\n createAlertDialogContext<AlertDialogContentContextValue>(CONTENT_NAME)\n\ninterface AlertDialogContentProps\n extends Omit<DialogContentProps, 'onPointerDownOutside' | 'onInteractOutside'> {}\n\nconst AlertDialogContent = React.forwardRef<TamaguiElement, AlertDialogContentProps>(\n (props: ScopedProps<AlertDialogContentProps>, forwardedRef) => {\n const { __scopeAlertDialog, children, ...contentProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n const contentRef = React.useRef<TamaguiElement>(null)\n const composedRefs = useComposedRefs(forwardedRef, contentRef)\n const cancelRef = React.useRef<TamaguiElement | null>(null)\n\n return (\n <DialogWarningProvider\n contentName={CONTENT_NAME}\n titleName={TITLE_NAME}\n docsSlug=\"alert-dialog\"\n >\n <AlertDialogContentProvider scope={__scopeAlertDialog} cancelRef={cancelRef}>\n <DialogContent\n // @ts-ignore\n role=\"alertdialog\"\n {...dialogScope}\n {...contentProps}\n ref={composedRefs}\n onOpenAutoFocus={composeEventHandlers(contentProps.onOpenAutoFocus, (event) => {\n event.preventDefault()\n if (isWeb) {\n // @ts-ignore\n cancelRef.current?.focus({ preventScroll: true })\n }\n })}\n onPointerDownOutside={(event) => event.preventDefault()}\n onInteractOutside={(event) => event.preventDefault()}\n >\n {/**\n * We have to use `Slottable` here as we cannot wrap the `AlertDialogContentProvider`\n * around everything, otherwise the `DescriptionWarning` would be rendered straight away.\n * This is because we want the accessibility checks to run only once the content is actually\n * open and that behaviour is already encapsulated in `DialogContent`.\n */}\n <Slottable>{children}</Slottable>\n {process.env.NODE_ENV === 'development' && (\n <DescriptionWarning contentRef={contentRef} />\n )}\n </DialogContent>\n </AlertDialogContentProvider>\n </DialogWarningProvider>\n )\n }\n)\n\nAlertDialogContent.displayName = CONTENT_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogTitle\n * -----------------------------------------------------------------------------------------------*/\n\nconst TITLE_NAME = 'AlertDialogTitle'\n\ntype AlertDialogTitleProps = DialogTitleProps\n\nconst AlertDialogTitle = React.forwardRef<TamaguiElement, AlertDialogTitleProps>(\n (props: ScopedProps<AlertDialogTitleProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...titleProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogTitle {...dialogScope} {...titleProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogTitle.displayName = TITLE_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogDescription\n * -----------------------------------------------------------------------------------------------*/\n\nconst DESCRIPTION_NAME = 'AlertDialogDescription'\n\ntype AlertDialogDescriptionProps = DialogDescriptionProps\n\nconst AlertDialogDescription = React.forwardRef<TamaguiElement, AlertDialogDescriptionProps>(\n (props: ScopedProps<AlertDialogDescriptionProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...descriptionProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogDescription {...dialogScope} {...descriptionProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogDescription.displayName = DESCRIPTION_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogAction\n * -----------------------------------------------------------------------------------------------*/\n\nconst ACTION_NAME = 'AlertDialogAction'\n\ntype AlertDialogActionProps = DialogCloseProps\n\nconst AlertDialogAction = React.forwardRef<TamaguiElement, AlertDialogActionProps>(\n (props: ScopedProps<AlertDialogActionProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...actionProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogClose {...dialogScope} {...actionProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogAction.displayName = ACTION_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogCancel\n * -----------------------------------------------------------------------------------------------*/\n\nconst CANCEL_NAME = 'AlertDialogCancel'\n\ninterface AlertDialogCancelProps extends DialogCloseProps {}\n\nconst AlertDialogCancel = React.forwardRef<TamaguiElement, AlertDialogCancelProps>(\n (props: ScopedProps<AlertDialogCancelProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...cancelProps } = props\n const { cancelRef } = useAlertDialogContentContext(CANCEL_NAME, __scopeAlertDialog)\n const dialogScope = useDialogScope(__scopeAlertDialog)\n const ref = useComposedRefs(forwardedRef, cancelRef)\n return <DialogClose {...dialogScope} {...cancelProps} ref={ref} />\n }\n)\n\nAlertDialogCancel.displayName = CANCEL_NAME\n\n/* ---------------------------------------------------------------------------------------------- */\n\ntype DescriptionWarningProps = {\n contentRef: React.RefObject<TamaguiElement>\n}\n\nconst DescriptionWarning: React.FC<DescriptionWarningProps> = ({ contentRef }) => {\n const MESSAGE = `\\`${CONTENT_NAME}\\` requires a description for the component to be accessible for screen reader users.\n\nYou can add a description to the \\`${CONTENT_NAME}\\` by passing a \\`${DESCRIPTION_NAME}\\` component as a child, which also benefits sighted users by adding visible context to the dialog.\n\nAlternatively, you can use your own component as a description by assigning it an \\`id\\` and passing the same value to the \\`aria-describedby\\` prop in \\`${CONTENT_NAME}\\`. If the description is confusing or duplicative for sighted users, you can use the \\`@radix-ui/react-visually-hidden\\` primitive as a wrapper around your description component.\n\nFor more information, see https://tamagui.dev/docs/components/alert-dialog`\n\n React.useEffect(() => {\n if (!isWeb) return\n const hasDescription = document.getElementById(\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain\n contentRef.current?.getAttribute('aria-describedby')!\n )\n if (!hasDescription) console.warn(MESSAGE)\n }, [MESSAGE, contentRef])\n\n return null\n}\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialog\n * -----------------------------------------------------------------------------------------------*/\n\nconst AlertDialogInner: React.FC<AlertDialogProps> = (props: ScopedProps<AlertDialogProps>) => {\n const { __scopeAlertDialog, ...alertDialogProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <Dialog {...dialogScope} {...alertDialogProps} modal={true} />\n}\n\nconst AlertDialog = withStaticProperties(AlertDialogInner, {\n Trigger: AlertDialogTrigger,\n Portal: AlertDialogPortal,\n Overlay: AlertDialogOverlay,\n Content: AlertDialogContent,\n Action: AlertDialogAction,\n Cancel: AlertDialogCancel,\n Title: AlertDialogTitle,\n Description: AlertDialogDescription,\n})\n\nAlertDialog.displayName = ROOT_NAME\n\nexport {\n createAlertDialogScope,\n //\n AlertDialog,\n AlertDialogTrigger,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogContent,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogTitle,\n AlertDialogDescription,\n}\nexport type {\n AlertDialogProps,\n AlertDialogTriggerProps,\n AlertDialogPortalProps,\n AlertDialogOverlayProps,\n AlertDialogContentProps,\n AlertDialogActionProps,\n AlertDialogCancelProps,\n AlertDialogTitleProps,\n AlertDialogDescriptionProps,\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,0BAAgC;AAChC,
|
|
4
|
+
"sourcesContent": ["// forked from radix-ui\n// https://github.com/radix-ui/primitives/blob/main/packages/react/alert-dialog/src/AlertDialog.tsx\n\nimport { useComposedRefs } from '@tamagui/compose-refs'\nimport {\n Slottable,\n TamaguiElement,\n composeEventHandlers,\n isTamaguiElement,\n isWeb,\n styled,\n withStaticProperties,\n} from '@tamagui/core'\nimport { Scope, createContextScope } from '@tamagui/create-context'\nimport {\n Dialog,\n DialogClose,\n DialogCloseProps,\n DialogContent,\n DialogContentProps,\n DialogDescription,\n DialogDescriptionProps,\n DialogOverlay,\n DialogOverlayProps,\n DialogPortal,\n DialogPortalProps,\n DialogProps,\n DialogTitle,\n DialogTitleProps,\n DialogTrigger,\n DialogTriggerProps,\n DialogWarningProvider,\n createDialogScope,\n} from '@tamagui/dialog'\nimport { YStack } from '@tamagui/stacks'\n/* -------------------------------------------------------------------------------------------------\n * AlertDialog\n * -----------------------------------------------------------------------------------------------*/\nimport { useControllableState } from '@tamagui/use-controllable-state'\nimport * as React from 'react'\nimport { Alert } from 'react-native'\n\nconst ROOT_NAME = 'AlertDialog'\n\ntype ScopedProps<P> = P & { __scopeAlertDialog?: Scope }\nconst [createAlertDialogContext, createAlertDialogScope] = createContextScope(ROOT_NAME, [\n createDialogScope,\n])\n\nconst useDialogScope = createDialogScope()\n\ntype AlertDialogProps = DialogProps & {\n native?: boolean\n}\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogTrigger\n * -----------------------------------------------------------------------------------------------*/\nconst TRIGGER_NAME = 'AlertDialogTrigger'\n\ninterface AlertDialogTriggerProps extends DialogTriggerProps {}\n\nconst NativeAlertDialogTriggerFrame = styled(YStack, {\n name: 'DialogTrigger',\n})\n\nconst AlertDialogTrigger = React.forwardRef<TamaguiElement, AlertDialogTriggerProps>(\n (props: ScopedProps<AlertDialogTriggerProps>, forwardedRef) => {\n if (props['__native']) {\n const { __native, onPress, __onPress, ...rest } = props as any\n return (\n <NativeAlertDialogTriggerFrame\n {...rest}\n onPress={composeEventHandlers(onPress, __onPress)}\n />\n )\n }\n\n const { __scopeAlertDialog, ...triggerProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogTrigger {...dialogScope} {...triggerProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogTrigger.displayName = TRIGGER_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogPortal\n * -----------------------------------------------------------------------------------------------*/\n\nconst PORTAL_NAME = 'AlertDialogPortal'\n\ninterface AlertDialogPortalProps extends DialogPortalProps {}\n\nconst AlertDialogPortal: React.FC<AlertDialogPortalProps> = (\n props: ScopedProps<AlertDialogPortalProps>\n) => {\n const { __scopeAlertDialog, ...portalProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogPortal {...dialogScope} {...portalProps} />\n}\n\nAlertDialogPortal.displayName = PORTAL_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogOverlay\n * -----------------------------------------------------------------------------------------------*/\n\nconst OVERLAY_NAME = 'AlertDialogOverlay'\n\ninterface AlertDialogOverlayProps extends DialogOverlayProps {}\n\nconst AlertDialogOverlay = React.forwardRef<TamaguiElement, AlertDialogOverlayProps>(\n (props: ScopedProps<AlertDialogOverlayProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...overlayProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogOverlay {...dialogScope} {...overlayProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogOverlay.displayName = OVERLAY_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogContent\n * -----------------------------------------------------------------------------------------------*/\n\nconst CONTENT_NAME = 'AlertDialogContent'\n\ntype AlertDialogContentContextValue = {\n cancelRef: React.MutableRefObject<TamaguiElement | null>\n}\n\nconst [AlertDialogContentProvider, useAlertDialogContentContext] =\n createAlertDialogContext<AlertDialogContentContextValue>(CONTENT_NAME)\n\ninterface AlertDialogContentProps\n extends Omit<DialogContentProps, 'onPointerDownOutside' | 'onInteractOutside'> {}\n\nconst AlertDialogContent = React.forwardRef<TamaguiElement, AlertDialogContentProps>(\n (props: ScopedProps<AlertDialogContentProps>, forwardedRef) => {\n const { __scopeAlertDialog, children, ...contentProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n const contentRef = React.useRef<TamaguiElement>(null)\n const composedRefs = useComposedRefs(forwardedRef, contentRef)\n const cancelRef = React.useRef<TamaguiElement | null>(null)\n\n return (\n <DialogWarningProvider\n contentName={CONTENT_NAME}\n titleName={TITLE_NAME}\n docsSlug=\"alert-dialog\"\n >\n <AlertDialogContentProvider scope={__scopeAlertDialog} cancelRef={cancelRef}>\n <DialogContent\n // @ts-ignore\n role=\"alertdialog\"\n {...dialogScope}\n {...contentProps}\n ref={composedRefs}\n onOpenAutoFocus={composeEventHandlers(contentProps.onOpenAutoFocus, (event) => {\n event.preventDefault()\n if (isWeb) {\n // @ts-ignore\n cancelRef.current?.focus({ preventScroll: true })\n }\n })}\n onPointerDownOutside={(event) => event.preventDefault()}\n onInteractOutside={(event) => event.preventDefault()}\n >\n {/**\n * We have to use `Slottable` here as we cannot wrap the `AlertDialogContentProvider`\n * around everything, otherwise the `DescriptionWarning` would be rendered straight away.\n * This is because we want the accessibility checks to run only once the content is actually\n * open and that behaviour is already encapsulated in `DialogContent`.\n */}\n <Slottable>{children}</Slottable>\n {process.env.NODE_ENV === 'development' && (\n <DescriptionWarning contentRef={contentRef} />\n )}\n </DialogContent>\n </AlertDialogContentProvider>\n </DialogWarningProvider>\n )\n }\n)\n\nAlertDialogContent.displayName = CONTENT_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogTitle\n * -----------------------------------------------------------------------------------------------*/\n\nconst TITLE_NAME = 'AlertDialogTitle'\n\ntype AlertDialogTitleProps = DialogTitleProps\n\nconst AlertDialogTitle = React.forwardRef<TamaguiElement, AlertDialogTitleProps>(\n (props: ScopedProps<AlertDialogTitleProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...titleProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogTitle {...dialogScope} {...titleProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogTitle.displayName = TITLE_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogDescription\n * -----------------------------------------------------------------------------------------------*/\n\nconst DESCRIPTION_NAME = 'AlertDialogDescription'\n\ntype AlertDialogDescriptionProps = DialogDescriptionProps\n\nconst AlertDialogDescription = React.forwardRef<TamaguiElement, AlertDialogDescriptionProps>(\n (props: ScopedProps<AlertDialogDescriptionProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...descriptionProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogDescription {...dialogScope} {...descriptionProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogDescription.displayName = DESCRIPTION_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogAction\n * -----------------------------------------------------------------------------------------------*/\n\nconst ACTION_NAME = 'AlertDialogAction'\n\ntype AlertDialogActionProps = DialogCloseProps\n\nconst AlertDialogAction = React.forwardRef<TamaguiElement, AlertDialogActionProps>(\n (props: ScopedProps<AlertDialogActionProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...actionProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogClose {...dialogScope} {...actionProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogAction.displayName = ACTION_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogCancel\n * -----------------------------------------------------------------------------------------------*/\n\nconst CANCEL_NAME = 'AlertDialogCancel'\n\ninterface AlertDialogCancelProps extends DialogCloseProps {}\n\nconst AlertDialogCancel = React.forwardRef<TamaguiElement, AlertDialogCancelProps>(\n (props: ScopedProps<AlertDialogCancelProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...cancelProps } = props\n const { cancelRef } = useAlertDialogContentContext(CANCEL_NAME, __scopeAlertDialog)\n const dialogScope = useDialogScope(__scopeAlertDialog)\n const ref = useComposedRefs(forwardedRef, cancelRef)\n return <DialogClose {...dialogScope} {...cancelProps} ref={ref} />\n }\n)\n\nAlertDialogCancel.displayName = CANCEL_NAME\n\n/* ---------------------------------------------------------------------------------------------- */\n\ntype DescriptionWarningProps = {\n contentRef: React.RefObject<TamaguiElement>\n}\n\nconst DescriptionWarning: React.FC<DescriptionWarningProps> = ({ contentRef }) => {\n const MESSAGE = `\\`${CONTENT_NAME}\\` requires a description for the component to be accessible for screen reader users.\n\nYou can add a description to the \\`${CONTENT_NAME}\\` by passing a \\`${DESCRIPTION_NAME}\\` component as a child, which also benefits sighted users by adding visible context to the dialog.\n\nAlternatively, you can use your own component as a description by assigning it an \\`id\\` and passing the same value to the \\`aria-describedby\\` prop in \\`${CONTENT_NAME}\\`. If the description is confusing or duplicative for sighted users, you can use the \\`@radix-ui/react-visually-hidden\\` primitive as a wrapper around your description component.\n\nFor more information, see https://tamagui.dev/docs/components/alert-dialog`\n\n React.useEffect(() => {\n if (!isWeb) return\n const hasDescription = document.getElementById(\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain\n contentRef.current?.getAttribute('aria-describedby')!\n )\n if (!hasDescription) console.warn(MESSAGE)\n }, [MESSAGE, contentRef])\n\n return null\n}\n\nconst AlertDialogInner: React.FC<AlertDialogProps> = (props: ScopedProps<AlertDialogProps>) => {\n const { __scopeAlertDialog, native, ...alertDialogProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n\n if (process.env.TAMAGUI_TARGET === 'native') {\n const [open, setOpen] = useControllableState({\n prop: props.open,\n defaultProp: props.defaultOpen || false,\n onChange: props.onOpenChange,\n })\n\n let triggerElement: any = null\n let title = ''\n let description = ''\n const buttons: {\n text: string\n onPress: (value?: string | undefined) => void\n style?: 'default' | 'cancel' | 'destructive'\n }[] = []\n\n forEachChildDeep(React.Children.toArray(props.children), (child) => {\n if (!React.isValidElement(child)) return false\n const name = isTamaguiElement(child)\n ? child.type.staticConfig.componentName\n : (child.type['displayName'] as string | undefined)\n switch (name) {\n case TRIGGER_NAME: {\n triggerElement = React.cloneElement(child as any, {\n __native: true,\n })\n return false\n }\n case TITLE_NAME: {\n title = getStringChildren(child)\n return false\n }\n case DESCRIPTION_NAME: {\n description = getStringChildren(child)\n return false\n }\n case ACTION_NAME:\n case CANCEL_NAME: {\n const style = name === ACTION_NAME ? 'default' : 'cancel'\n const text = getStringChildren(child)\n const onPress = () => {\n ;(child.props as any)?.onPress?.({ native: true })\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\n React.useLayoutEffect(() => {\n if (!open || !native) return\n if (title || description) {\n Alert.alert(title, description, buttons)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [native, open])\n\n if (native) {\n return React.cloneElement(triggerElement, {\n __onPress: () => {\n setOpen(true)\n },\n })\n }\n }\n\n return <Dialog {...dialogScope} {...alertDialogProps} modal={true} />\n}\n\nfunction forEachChildDeep(\n children: React.ReactNode[],\n onChild: (el: React.ReactElement) => boolean\n) {\n for (const child of children) {\n if (!React.isValidElement(child)) continue\n if (!onChild(child)) continue\n if (child.props.children) {\n forEachChildDeep(React.Children.toArray(child.props.children), onChild)\n }\n }\n}\n\nfunction getStringChildren(child: React.ReactElement) {\n let string = ''\n forEachChildDeep(React.Children.toArray(child), (child) => {\n if (typeof child.props.children === 'string') {\n string = child.props.children\n return false\n }\n return true\n })\n return string\n}\n\nconst AlertDialog = withStaticProperties(AlertDialogInner, {\n Trigger: AlertDialogTrigger,\n Portal: AlertDialogPortal,\n Overlay: AlertDialogOverlay,\n Content: AlertDialogContent,\n Action: AlertDialogAction,\n Cancel: AlertDialogCancel,\n Title: AlertDialogTitle,\n Description: AlertDialogDescription,\n})\n\nAlertDialog.displayName = ROOT_NAME\n\nexport {\n createAlertDialogScope,\n //\n AlertDialog,\n AlertDialogTrigger,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogContent,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogTitle,\n AlertDialogDescription,\n}\nexport type {\n AlertDialogProps,\n AlertDialogTriggerProps,\n AlertDialogPortalProps,\n AlertDialogOverlayProps,\n AlertDialogContentProps,\n AlertDialogActionProps,\n AlertDialogCancelProps,\n AlertDialogTitleProps,\n AlertDialogDescriptionProps,\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,0BAAgC;AAChC,kBAQO;AACP,4BAA0C;AAC1C,oBAmBO;AACP,oBAAuB;AAIvB,oCAAqC;AACrC,YAAuB;AACvB,0BAAsB;AAEtB,MAAM,YAAY;AAGlB,MAAM,CAAC,0BAA0B,0BAA0B,8CAAmB,WAAW;AAAA,EACvF;AACF,CAAC;AAED,MAAM,iBAAiB,qCAAkB;AASzC,MAAM,eAAe;AAIrB,MAAM,gCAAgC,wBAAO,sBAAQ;AAAA,EACnD,MAAM;AACR,CAAC;AAED,MAAM,qBAAqB,MAAM,WAC/B,CAAC,OAA6C,iBAAiB;AAC7D,MAAI,MAAM,aAAa;AACrB,UAAM,EAAE,UAAU,SAAS,cAAc,SAAS;AAClD,WACE,oCAAC;AAAA,MACE,GAAG;AAAA,MACJ,SAAS,sCAAqB,SAAS,SAAS;AAAA,KAClD;AAAA,EAEJ;AAEA,QAAM,EAAE,uBAAuB,iBAAiB;AAChD,QAAM,cAAc,eAAe,kBAAkB;AACrD,SAAO,oCAAC;AAAA,IAAe,GAAG;AAAA,IAAc,GAAG;AAAA,IAAc,KAAK;AAAA,GAAc;AAC9E,CACF;AAEA,mBAAmB,cAAc;AAMjC,MAAM,cAAc;AAIpB,MAAM,oBAAsD,CAC1D,UACG;AACH,QAAM,EAAE,uBAAuB,gBAAgB;AAC/C,QAAM,cAAc,eAAe,kBAAkB;AACrD,SAAO,oCAAC;AAAA,IAAc,GAAG;AAAA,IAAc,GAAG;AAAA,GAAa;AACzD;AAEA,kBAAkB,cAAc;AAMhC,MAAM,eAAe;AAIrB,MAAM,qBAAqB,MAAM,WAC/B,CAAC,OAA6C,iBAAiB;AAC7D,QAAM,EAAE,uBAAuB,iBAAiB;AAChD,QAAM,cAAc,eAAe,kBAAkB;AACrD,SAAO,oCAAC;AAAA,IAAe,GAAG;AAAA,IAAc,GAAG;AAAA,IAAc,KAAK;AAAA,GAAc;AAC9E,CACF;AAEA,mBAAmB,cAAc;AAMjC,MAAM,eAAe;AAMrB,MAAM,CAAC,4BAA4B,gCACjC,yBAAyD,YAAY;AAKvE,MAAM,qBAAqB,MAAM,WAC/B,CAAC,OAA6C,iBAAiB;AAC7D,QAAM,EAAE,oBAAoB,aAAa,iBAAiB;AAC1D,QAAM,cAAc,eAAe,kBAAkB;AACrD,QAAM,aAAa,MAAM,OAAuB,IAAI;AACpD,QAAM,eAAe,yCAAgB,cAAc,UAAU;AAC7D,QAAM,YAAY,MAAM,OAA8B,IAAI;AAE1D,SACE,oCAAC;AAAA,IACC,aAAa;AAAA,IACb,WAAW;AAAA,IACX,UAAS;AAAA,KAET,oCAAC;AAAA,IAA2B,OAAO;AAAA,IAAoB;AAAA,KACrD,oCAAC;AAAA,IAEC,MAAK;AAAA,IACJ,GAAG;AAAA,IACH,GAAG;AAAA,IACJ,KAAK;AAAA,IACL,iBAAiB,sCAAqB,aAAa,iBAAiB,CAAC,UAAU;AA/J3F;AAgKc,YAAM,eAAe;AACrB,UAAI,mBAAO;AAET,wBAAU,YAAV,mBAAmB,MAAM,EAAE,eAAe,KAAK;AAAA,MACjD;AAAA,IACF,CAAC;AAAA,IACD,sBAAsB,CAAC,UAAU,MAAM,eAAe;AAAA,IACtD,mBAAmB,CAAC,UAAU,MAAM,eAAe;AAAA,KAQnD,oCAAC,6BAAW,QAAS,GACpB,QAAQ,IAAI,aAAa,iBACxB,oCAAC;AAAA,IAAmB;AAAA,GAAwB,CAEhD,CACF,CACF;AAEJ,CACF;AAEA,mBAAmB,cAAc;AAMjC,MAAM,aAAa;AAInB,MAAM,mBAAmB,MAAM,WAC7B,CAAC,OAA2C,iBAAiB;AAC3D,QAAM,EAAE,uBAAuB,eAAe;AAC9C,QAAM,cAAc,eAAe,kBAAkB;AACrD,SAAO,oCAAC;AAAA,IAAa,GAAG;AAAA,IAAc,GAAG;AAAA,IAAY,KAAK;AAAA,GAAc;AAC1E,CACF;AAEA,iBAAiB,cAAc;AAM/B,MAAM,mBAAmB;AAIzB,MAAM,yBAAyB,MAAM,WACnC,CAAC,OAAiD,iBAAiB;AACjE,QAAM,EAAE,uBAAuB,qBAAqB;AACpD,QAAM,cAAc,eAAe,kBAAkB;AACrD,SAAO,oCAAC;AAAA,IAAmB,GAAG;AAAA,IAAc,GAAG;AAAA,IAAkB,KAAK;AAAA,GAAc;AACtF,CACF;AAEA,uBAAuB,cAAc;AAMrC,MAAM,cAAc;AAIpB,MAAM,oBAAoB,MAAM,WAC9B,CAAC,OAA4C,iBAAiB;AAC5D,QAAM,EAAE,uBAAuB,gBAAgB;AAC/C,QAAM,cAAc,eAAe,kBAAkB;AACrD,SAAO,oCAAC;AAAA,IAAa,GAAG;AAAA,IAAc,GAAG;AAAA,IAAa,KAAK;AAAA,GAAc;AAC3E,CACF;AAEA,kBAAkB,cAAc;AAMhC,MAAM,cAAc;AAIpB,MAAM,oBAAoB,MAAM,WAC9B,CAAC,OAA4C,iBAAiB;AAC5D,QAAM,EAAE,uBAAuB,gBAAgB;AAC/C,QAAM,EAAE,cAAc,6BAA6B,aAAa,kBAAkB;AAClF,QAAM,cAAc,eAAe,kBAAkB;AACrD,QAAM,MAAM,yCAAgB,cAAc,SAAS;AACnD,SAAO,oCAAC;AAAA,IAAa,GAAG;AAAA,IAAc,GAAG;AAAA,IAAa;AAAA,GAAU;AAClE,CACF;AAEA,kBAAkB,cAAc;AAQhC,MAAM,qBAAwD,CAAC,EAAE,iBAAiB;AAChF,QAAM,UAAU,KAAK;AAAA;AAAA,qCAEc,iCAAiC;AAAA;AAAA,4JAEsF;AAAA;AAAA;AAI1J,QAAM,UAAU,MAAM;AArRxB;AAsRI,QAAI,CAAC;AAAO;AACZ,UAAM,iBAAiB,SAAS,eAG9B,iBAAW,YAAX,mBAAoB,aAAa,mBACnC;AACA,QAAI,CAAC;AAAgB,cAAQ,KAAK,OAAO;AAAA,EAC3C,GAAG,CAAC,SAAS,UAAU,CAAC;AAExB,SAAO;AACT;AAEA,MAAM,mBAA+C,CAAC,UAAyC;AAC7F,QAAM,EAAE,oBAAoB,WAAW,qBAAqB;AAC5D,QAAM,cAAc,eAAe,kBAAkB;AAErD,MAAI,QAAQ,IAAI,mBAAmB,UAAU;AAC3C,UAAM,CAAC,MAAM,WAAW,wDAAqB;AAAA,MAC3C,MAAM,MAAM;AAAA,MACZ,aAAa,MAAM,eAAe;AAAA,MAClC,UAAU,MAAM;AAAA,IAClB,CAAC;AAED,QAAI,iBAAsB;AAC1B,QAAI,QAAQ;AACZ,QAAI,cAAc;AAClB,UAAM,UAIA,CAAC;AAEP,qBAAiB,MAAM,SAAS,QAAQ,MAAM,QAAQ,GAAG,CAAC,UAAU;AAClE,UAAI,CAAC,MAAM,eAAe,KAAK;AAAG,eAAO;AACzC,YAAM,OAAO,kCAAiB,KAAK,IAC/B,MAAM,KAAK,aAAa,gBACvB,MAAM,KAAK;AAChB,cAAQ;AAAA,aACD,cAAc;AACjB,2BAAiB,MAAM,aAAa,OAAc;AAAA,YAChD,UAAU;AAAA,UACZ,CAAC;AACD,iBAAO;AAAA,QACT;AAAA,aACK,YAAY;AACf,kBAAQ,kBAAkB,KAAK;AAC/B,iBAAO;AAAA,QACT;AAAA,aACK,kBAAkB;AACrB,wBAAc,kBAAkB,KAAK;AACrC,iBAAO;AAAA,QACT;AAAA,aACK;AAAA,aACA,aAAa;AAChB,gBAAM,QAAQ,SAAS,cAAc,YAAY;AACjD,gBAAM,OAAO,kBAAkB,KAAK;AACpC,gBAAM,UAAU,MAAM;AA9UhC;AA+UY;AAAC,YAAC,kBAAM,UAAN,mBAAqB,YAArB,4BAA+B,EAAE,QAAQ,KAAK;AAChD,oBAAQ,KAAK;AAAA,UACf;AACA,kBAAQ,KAAK;AAAA,YACX;AAAA,YACA;AAAA,YAEA;AAAA,UACF,CAAC;AACD,iBAAO;AAAA,QACT;AAAA,iBACS;AACP,iBAAO;AAAA,QACT;AAAA;AAAA,IAEJ,CAAC;AAED,UAAM,gBAAgB,MAAM;AAC1B,UAAI,CAAC,QAAQ,CAAC;AAAQ;AACtB,UAAI,SAAS,aAAa;AACxB,kCAAM,MAAM,OAAO,aAAa,OAAO;AAAA,MACzC;AAAA,IAEF,GAAG,CAAC,QAAQ,IAAI,CAAC;AAEjB,QAAI,QAAQ;AACV,aAAO,MAAM,aAAa,gBAAgB;AAAA,QACxC,WAAW,MAAM;AACf,kBAAQ,IAAI;AAAA,QACd;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO,oCAAC;AAAA,IAAQ,GAAG;AAAA,IAAc,GAAG;AAAA,IAAkB,OAAO;AAAA,GAAM;AACrE;AAEA,0BACE,UACA,SACA;AACA,aAAW,SAAS,UAAU;AAC5B,QAAI,CAAC,MAAM,eAAe,KAAK;AAAG;AAClC,QAAI,CAAC,QAAQ,KAAK;AAAG;AACrB,QAAI,MAAM,MAAM,UAAU;AACxB,uBAAiB,MAAM,SAAS,QAAQ,MAAM,MAAM,QAAQ,GAAG,OAAO;AAAA,IACxE;AAAA,EACF;AACF;AAEA,2BAA2B,OAA2B;AACpD,MAAI,SAAS;AACb,mBAAiB,MAAM,SAAS,QAAQ,KAAK,GAAG,CAAC,WAAU;AACzD,QAAI,OAAO,OAAM,MAAM,aAAa,UAAU;AAC5C,eAAS,OAAM,MAAM;AACrB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,CAAC;AACD,SAAO;AACT;AAEA,MAAM,cAAc,sCAAqB,kBAAkB;AAAA,EACzD,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,aAAa;AACf,CAAC;AAED,YAAY,cAAc;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/esm/AlertDialog.js
CHANGED
|
@@ -2,7 +2,9 @@ import { useComposedRefs } from "@tamagui/compose-refs";
|
|
|
2
2
|
import {
|
|
3
3
|
Slottable,
|
|
4
4
|
composeEventHandlers,
|
|
5
|
+
isTamaguiElement,
|
|
5
6
|
isWeb,
|
|
7
|
+
styled,
|
|
6
8
|
withStaticProperties
|
|
7
9
|
} from "@tamagui/core";
|
|
8
10
|
import { createContextScope } from "@tamagui/create-context";
|
|
@@ -18,14 +20,27 @@ import {
|
|
|
18
20
|
DialogWarningProvider,
|
|
19
21
|
createDialogScope
|
|
20
22
|
} from "@tamagui/dialog";
|
|
23
|
+
import { YStack } from "@tamagui/stacks";
|
|
24
|
+
import { useControllableState } from "@tamagui/use-controllable-state";
|
|
21
25
|
import * as React from "react";
|
|
26
|
+
import { Alert } from "react-native";
|
|
22
27
|
const ROOT_NAME = "AlertDialog";
|
|
23
28
|
const [createAlertDialogContext, createAlertDialogScope] = createContextScope(ROOT_NAME, [
|
|
24
29
|
createDialogScope
|
|
25
30
|
]);
|
|
26
31
|
const useDialogScope = createDialogScope();
|
|
27
32
|
const TRIGGER_NAME = "AlertDialogTrigger";
|
|
33
|
+
const NativeAlertDialogTriggerFrame = styled(YStack, {
|
|
34
|
+
name: "DialogTrigger"
|
|
35
|
+
});
|
|
28
36
|
const AlertDialogTrigger = React.forwardRef((props, forwardedRef) => {
|
|
37
|
+
if (props["__native"]) {
|
|
38
|
+
const { __native, onPress, __onPress, ...rest } = props;
|
|
39
|
+
return /* @__PURE__ */ React.createElement(NativeAlertDialogTriggerFrame, {
|
|
40
|
+
...rest,
|
|
41
|
+
onPress: composeEventHandlers(onPress, __onPress)
|
|
42
|
+
});
|
|
43
|
+
}
|
|
29
44
|
const { __scopeAlertDialog, ...triggerProps } = props;
|
|
30
45
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
31
46
|
return /* @__PURE__ */ React.createElement(DialogTrigger, {
|
|
@@ -155,14 +170,102 @@ For more information, see https://tamagui.dev/docs/components/alert-dialog`;
|
|
|
155
170
|
return null;
|
|
156
171
|
};
|
|
157
172
|
const AlertDialogInner = (props) => {
|
|
158
|
-
const { __scopeAlertDialog, ...alertDialogProps } = props;
|
|
173
|
+
const { __scopeAlertDialog, native, ...alertDialogProps } = props;
|
|
159
174
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
175
|
+
if (process.env.TAMAGUI_TARGET === "native") {
|
|
176
|
+
const [open, setOpen] = useControllableState({
|
|
177
|
+
prop: props.open,
|
|
178
|
+
defaultProp: props.defaultOpen || false,
|
|
179
|
+
onChange: props.onOpenChange
|
|
180
|
+
});
|
|
181
|
+
let triggerElement = null;
|
|
182
|
+
let title = "";
|
|
183
|
+
let description = "";
|
|
184
|
+
const buttons = [];
|
|
185
|
+
forEachChildDeep(React.Children.toArray(props.children), (child) => {
|
|
186
|
+
if (!React.isValidElement(child))
|
|
187
|
+
return false;
|
|
188
|
+
const name = isTamaguiElement(child) ? child.type.staticConfig.componentName : child.type["displayName"];
|
|
189
|
+
switch (name) {
|
|
190
|
+
case TRIGGER_NAME: {
|
|
191
|
+
triggerElement = React.cloneElement(child, {
|
|
192
|
+
__native: true
|
|
193
|
+
});
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
case TITLE_NAME: {
|
|
197
|
+
title = getStringChildren(child);
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
case DESCRIPTION_NAME: {
|
|
201
|
+
description = getStringChildren(child);
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
case ACTION_NAME:
|
|
205
|
+
case CANCEL_NAME: {
|
|
206
|
+
const style = name === ACTION_NAME ? "default" : "cancel";
|
|
207
|
+
const text = getStringChildren(child);
|
|
208
|
+
const onPress = () => {
|
|
209
|
+
var _a, _b;
|
|
210
|
+
;
|
|
211
|
+
(_b = (_a = child.props) == null ? void 0 : _a.onPress) == null ? void 0 : _b.call(_a, { native: true });
|
|
212
|
+
setOpen(false);
|
|
213
|
+
};
|
|
214
|
+
buttons.push({
|
|
215
|
+
style,
|
|
216
|
+
text,
|
|
217
|
+
onPress
|
|
218
|
+
});
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
default: {
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
React.useLayoutEffect(() => {
|
|
227
|
+
if (!open || !native)
|
|
228
|
+
return;
|
|
229
|
+
if (title || description) {
|
|
230
|
+
Alert.alert(title, description, buttons);
|
|
231
|
+
}
|
|
232
|
+
}, [native, open]);
|
|
233
|
+
if (native) {
|
|
234
|
+
return React.cloneElement(triggerElement, {
|
|
235
|
+
__onPress: () => {
|
|
236
|
+
setOpen(true);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
160
241
|
return /* @__PURE__ */ React.createElement(Dialog, {
|
|
161
242
|
...dialogScope,
|
|
162
243
|
...alertDialogProps,
|
|
163
244
|
modal: true
|
|
164
245
|
});
|
|
165
246
|
};
|
|
247
|
+
function forEachChildDeep(children, onChild) {
|
|
248
|
+
for (const child of children) {
|
|
249
|
+
if (!React.isValidElement(child))
|
|
250
|
+
continue;
|
|
251
|
+
if (!onChild(child))
|
|
252
|
+
continue;
|
|
253
|
+
if (child.props.children) {
|
|
254
|
+
forEachChildDeep(React.Children.toArray(child.props.children), onChild);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function getStringChildren(child) {
|
|
259
|
+
let string = "";
|
|
260
|
+
forEachChildDeep(React.Children.toArray(child), (child2) => {
|
|
261
|
+
if (typeof child2.props.children === "string") {
|
|
262
|
+
string = child2.props.children;
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
return true;
|
|
266
|
+
});
|
|
267
|
+
return string;
|
|
268
|
+
}
|
|
166
269
|
const AlertDialog = withStaticProperties(AlertDialogInner, {
|
|
167
270
|
Trigger: AlertDialogTrigger,
|
|
168
271
|
Portal: AlertDialogPortal,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/AlertDialog.tsx"],
|
|
4
|
-
"sourcesContent": ["// forked from radix-ui\n// https://github.com/radix-ui/primitives/blob/main/packages/react/alert-dialog/src/AlertDialog.tsx\n\nimport { useComposedRefs } from '@tamagui/compose-refs'\nimport {\n Slottable,\n TamaguiElement,\n composeEventHandlers,\n isWeb,\n withStaticProperties,\n} from '@tamagui/core'\nimport { Scope, createContextScope } from '@tamagui/create-context'\nimport {\n Dialog,\n DialogClose,\n DialogCloseProps,\n DialogContent,\n DialogContentProps,\n DialogDescription,\n DialogDescriptionProps,\n DialogOverlay,\n DialogOverlayProps,\n DialogPortal,\n DialogPortalProps,\n DialogProps,\n DialogTitle,\n DialogTitleProps,\n DialogTrigger,\n DialogTriggerProps,\n DialogWarningProvider,\n createDialogScope,\n} from '@tamagui/dialog'\nimport * as React from 'react'\n\nconst ROOT_NAME = 'AlertDialog'\n\ntype ScopedProps<P> = P & { __scopeAlertDialog?: Scope }\nconst [createAlertDialogContext, createAlertDialogScope] = createContextScope(ROOT_NAME, [\n createDialogScope,\n])\n\nconst useDialogScope = createDialogScope()\n\ninterface AlertDialogProps extends Omit<DialogProps, 'modal'> {}\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogTrigger\n * -----------------------------------------------------------------------------------------------*/\nconst TRIGGER_NAME = 'AlertDialogTrigger'\n\ninterface AlertDialogTriggerProps extends DialogTriggerProps {}\n\nconst AlertDialogTrigger = React.forwardRef<TamaguiElement, AlertDialogTriggerProps>(\n (props: ScopedProps<AlertDialogTriggerProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...triggerProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogTrigger {...dialogScope} {...triggerProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogTrigger.displayName = TRIGGER_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogPortal\n * -----------------------------------------------------------------------------------------------*/\n\nconst PORTAL_NAME = 'AlertDialogPortal'\n\ninterface AlertDialogPortalProps extends DialogPortalProps {}\n\nconst AlertDialogPortal: React.FC<AlertDialogPortalProps> = (\n props: ScopedProps<AlertDialogPortalProps>\n) => {\n const { __scopeAlertDialog, ...portalProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogPortal {...dialogScope} {...portalProps} />\n}\n\nAlertDialogPortal.displayName = PORTAL_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogOverlay\n * -----------------------------------------------------------------------------------------------*/\n\nconst OVERLAY_NAME = 'AlertDialogOverlay'\n\ninterface AlertDialogOverlayProps extends DialogOverlayProps {}\n\nconst AlertDialogOverlay = React.forwardRef<TamaguiElement, AlertDialogOverlayProps>(\n (props: ScopedProps<AlertDialogOverlayProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...overlayProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogOverlay {...dialogScope} {...overlayProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogOverlay.displayName = OVERLAY_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogContent\n * -----------------------------------------------------------------------------------------------*/\n\nconst CONTENT_NAME = 'AlertDialogContent'\n\ntype AlertDialogContentContextValue = {\n cancelRef: React.MutableRefObject<TamaguiElement | null>\n}\n\nconst [AlertDialogContentProvider, useAlertDialogContentContext] =\n createAlertDialogContext<AlertDialogContentContextValue>(CONTENT_NAME)\n\ninterface AlertDialogContentProps\n extends Omit<DialogContentProps, 'onPointerDownOutside' | 'onInteractOutside'> {}\n\nconst AlertDialogContent = React.forwardRef<TamaguiElement, AlertDialogContentProps>(\n (props: ScopedProps<AlertDialogContentProps>, forwardedRef) => {\n const { __scopeAlertDialog, children, ...contentProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n const contentRef = React.useRef<TamaguiElement>(null)\n const composedRefs = useComposedRefs(forwardedRef, contentRef)\n const cancelRef = React.useRef<TamaguiElement | null>(null)\n\n return (\n <DialogWarningProvider\n contentName={CONTENT_NAME}\n titleName={TITLE_NAME}\n docsSlug=\"alert-dialog\"\n >\n <AlertDialogContentProvider scope={__scopeAlertDialog} cancelRef={cancelRef}>\n <DialogContent\n // @ts-ignore\n role=\"alertdialog\"\n {...dialogScope}\n {...contentProps}\n ref={composedRefs}\n onOpenAutoFocus={composeEventHandlers(contentProps.onOpenAutoFocus, (event) => {\n event.preventDefault()\n if (isWeb) {\n // @ts-ignore\n cancelRef.current?.focus({ preventScroll: true })\n }\n })}\n onPointerDownOutside={(event) => event.preventDefault()}\n onInteractOutside={(event) => event.preventDefault()}\n >\n {/**\n * We have to use `Slottable` here as we cannot wrap the `AlertDialogContentProvider`\n * around everything, otherwise the `DescriptionWarning` would be rendered straight away.\n * This is because we want the accessibility checks to run only once the content is actually\n * open and that behaviour is already encapsulated in `DialogContent`.\n */}\n <Slottable>{children}</Slottable>\n {process.env.NODE_ENV === 'development' && (\n <DescriptionWarning contentRef={contentRef} />\n )}\n </DialogContent>\n </AlertDialogContentProvider>\n </DialogWarningProvider>\n )\n }\n)\n\nAlertDialogContent.displayName = CONTENT_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogTitle\n * -----------------------------------------------------------------------------------------------*/\n\nconst TITLE_NAME = 'AlertDialogTitle'\n\ntype AlertDialogTitleProps = DialogTitleProps\n\nconst AlertDialogTitle = React.forwardRef<TamaguiElement, AlertDialogTitleProps>(\n (props: ScopedProps<AlertDialogTitleProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...titleProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogTitle {...dialogScope} {...titleProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogTitle.displayName = TITLE_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogDescription\n * -----------------------------------------------------------------------------------------------*/\n\nconst DESCRIPTION_NAME = 'AlertDialogDescription'\n\ntype AlertDialogDescriptionProps = DialogDescriptionProps\n\nconst AlertDialogDescription = React.forwardRef<TamaguiElement, AlertDialogDescriptionProps>(\n (props: ScopedProps<AlertDialogDescriptionProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...descriptionProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogDescription {...dialogScope} {...descriptionProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogDescription.displayName = DESCRIPTION_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogAction\n * -----------------------------------------------------------------------------------------------*/\n\nconst ACTION_NAME = 'AlertDialogAction'\n\ntype AlertDialogActionProps = DialogCloseProps\n\nconst AlertDialogAction = React.forwardRef<TamaguiElement, AlertDialogActionProps>(\n (props: ScopedProps<AlertDialogActionProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...actionProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogClose {...dialogScope} {...actionProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogAction.displayName = ACTION_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogCancel\n * -----------------------------------------------------------------------------------------------*/\n\nconst CANCEL_NAME = 'AlertDialogCancel'\n\ninterface AlertDialogCancelProps extends DialogCloseProps {}\n\nconst AlertDialogCancel = React.forwardRef<TamaguiElement, AlertDialogCancelProps>(\n (props: ScopedProps<AlertDialogCancelProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...cancelProps } = props\n const { cancelRef } = useAlertDialogContentContext(CANCEL_NAME, __scopeAlertDialog)\n const dialogScope = useDialogScope(__scopeAlertDialog)\n const ref = useComposedRefs(forwardedRef, cancelRef)\n return <DialogClose {...dialogScope} {...cancelProps} ref={ref} />\n }\n)\n\nAlertDialogCancel.displayName = CANCEL_NAME\n\n/* ---------------------------------------------------------------------------------------------- */\n\ntype DescriptionWarningProps = {\n contentRef: React.RefObject<TamaguiElement>\n}\n\nconst DescriptionWarning: React.FC<DescriptionWarningProps> = ({ contentRef }) => {\n const MESSAGE = `\\`${CONTENT_NAME}\\` requires a description for the component to be accessible for screen reader users.\n\nYou can add a description to the \\`${CONTENT_NAME}\\` by passing a \\`${DESCRIPTION_NAME}\\` component as a child, which also benefits sighted users by adding visible context to the dialog.\n\nAlternatively, you can use your own component as a description by assigning it an \\`id\\` and passing the same value to the \\`aria-describedby\\` prop in \\`${CONTENT_NAME}\\`. If the description is confusing or duplicative for sighted users, you can use the \\`@radix-ui/react-visually-hidden\\` primitive as a wrapper around your description component.\n\nFor more information, see https://tamagui.dev/docs/components/alert-dialog`\n\n React.useEffect(() => {\n if (!isWeb) return\n const hasDescription = document.getElementById(\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain\n contentRef.current?.getAttribute('aria-describedby')!\n )\n if (!hasDescription) console.warn(MESSAGE)\n }, [MESSAGE, contentRef])\n\n return null\n}\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialog\n * -----------------------------------------------------------------------------------------------*/\n\nconst AlertDialogInner: React.FC<AlertDialogProps> = (props: ScopedProps<AlertDialogProps>) => {\n const { __scopeAlertDialog, ...alertDialogProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <Dialog {...dialogScope} {...alertDialogProps} modal={true} />\n}\n\nconst AlertDialog = withStaticProperties(AlertDialogInner, {\n Trigger: AlertDialogTrigger,\n Portal: AlertDialogPortal,\n Overlay: AlertDialogOverlay,\n Content: AlertDialogContent,\n Action: AlertDialogAction,\n Cancel: AlertDialogCancel,\n Title: AlertDialogTitle,\n Description: AlertDialogDescription,\n})\n\nAlertDialog.displayName = ROOT_NAME\n\nexport {\n createAlertDialogScope,\n //\n AlertDialog,\n AlertDialogTrigger,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogContent,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogTitle,\n AlertDialogDescription,\n}\nexport type {\n AlertDialogProps,\n AlertDialogTriggerProps,\n AlertDialogPortalProps,\n AlertDialogOverlayProps,\n AlertDialogContentProps,\n AlertDialogActionProps,\n AlertDialogCancelProps,\n AlertDialogTitleProps,\n AlertDialogDescriptionProps,\n}\n"],
|
|
5
|
-
"mappings": "AAGA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["// forked from radix-ui\n// https://github.com/radix-ui/primitives/blob/main/packages/react/alert-dialog/src/AlertDialog.tsx\n\nimport { useComposedRefs } from '@tamagui/compose-refs'\nimport {\n Slottable,\n TamaguiElement,\n composeEventHandlers,\n isTamaguiElement,\n isWeb,\n styled,\n withStaticProperties,\n} from '@tamagui/core'\nimport { Scope, createContextScope } from '@tamagui/create-context'\nimport {\n Dialog,\n DialogClose,\n DialogCloseProps,\n DialogContent,\n DialogContentProps,\n DialogDescription,\n DialogDescriptionProps,\n DialogOverlay,\n DialogOverlayProps,\n DialogPortal,\n DialogPortalProps,\n DialogProps,\n DialogTitle,\n DialogTitleProps,\n DialogTrigger,\n DialogTriggerProps,\n DialogWarningProvider,\n createDialogScope,\n} from '@tamagui/dialog'\nimport { YStack } from '@tamagui/stacks'\n/* -------------------------------------------------------------------------------------------------\n * AlertDialog\n * -----------------------------------------------------------------------------------------------*/\nimport { useControllableState } from '@tamagui/use-controllable-state'\nimport * as React from 'react'\nimport { Alert } from 'react-native'\n\nconst ROOT_NAME = 'AlertDialog'\n\ntype ScopedProps<P> = P & { __scopeAlertDialog?: Scope }\nconst [createAlertDialogContext, createAlertDialogScope] = createContextScope(ROOT_NAME, [\n createDialogScope,\n])\n\nconst useDialogScope = createDialogScope()\n\ntype AlertDialogProps = DialogProps & {\n native?: boolean\n}\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogTrigger\n * -----------------------------------------------------------------------------------------------*/\nconst TRIGGER_NAME = 'AlertDialogTrigger'\n\ninterface AlertDialogTriggerProps extends DialogTriggerProps {}\n\nconst NativeAlertDialogTriggerFrame = styled(YStack, {\n name: 'DialogTrigger',\n})\n\nconst AlertDialogTrigger = React.forwardRef<TamaguiElement, AlertDialogTriggerProps>(\n (props: ScopedProps<AlertDialogTriggerProps>, forwardedRef) => {\n if (props['__native']) {\n const { __native, onPress, __onPress, ...rest } = props as any\n return (\n <NativeAlertDialogTriggerFrame\n {...rest}\n onPress={composeEventHandlers(onPress, __onPress)}\n />\n )\n }\n\n const { __scopeAlertDialog, ...triggerProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogTrigger {...dialogScope} {...triggerProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogTrigger.displayName = TRIGGER_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogPortal\n * -----------------------------------------------------------------------------------------------*/\n\nconst PORTAL_NAME = 'AlertDialogPortal'\n\ninterface AlertDialogPortalProps extends DialogPortalProps {}\n\nconst AlertDialogPortal: React.FC<AlertDialogPortalProps> = (\n props: ScopedProps<AlertDialogPortalProps>\n) => {\n const { __scopeAlertDialog, ...portalProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogPortal {...dialogScope} {...portalProps} />\n}\n\nAlertDialogPortal.displayName = PORTAL_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogOverlay\n * -----------------------------------------------------------------------------------------------*/\n\nconst OVERLAY_NAME = 'AlertDialogOverlay'\n\ninterface AlertDialogOverlayProps extends DialogOverlayProps {}\n\nconst AlertDialogOverlay = React.forwardRef<TamaguiElement, AlertDialogOverlayProps>(\n (props: ScopedProps<AlertDialogOverlayProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...overlayProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogOverlay {...dialogScope} {...overlayProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogOverlay.displayName = OVERLAY_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogContent\n * -----------------------------------------------------------------------------------------------*/\n\nconst CONTENT_NAME = 'AlertDialogContent'\n\ntype AlertDialogContentContextValue = {\n cancelRef: React.MutableRefObject<TamaguiElement | null>\n}\n\nconst [AlertDialogContentProvider, useAlertDialogContentContext] =\n createAlertDialogContext<AlertDialogContentContextValue>(CONTENT_NAME)\n\ninterface AlertDialogContentProps\n extends Omit<DialogContentProps, 'onPointerDownOutside' | 'onInteractOutside'> {}\n\nconst AlertDialogContent = React.forwardRef<TamaguiElement, AlertDialogContentProps>(\n (props: ScopedProps<AlertDialogContentProps>, forwardedRef) => {\n const { __scopeAlertDialog, children, ...contentProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n const contentRef = React.useRef<TamaguiElement>(null)\n const composedRefs = useComposedRefs(forwardedRef, contentRef)\n const cancelRef = React.useRef<TamaguiElement | null>(null)\n\n return (\n <DialogWarningProvider\n contentName={CONTENT_NAME}\n titleName={TITLE_NAME}\n docsSlug=\"alert-dialog\"\n >\n <AlertDialogContentProvider scope={__scopeAlertDialog} cancelRef={cancelRef}>\n <DialogContent\n // @ts-ignore\n role=\"alertdialog\"\n {...dialogScope}\n {...contentProps}\n ref={composedRefs}\n onOpenAutoFocus={composeEventHandlers(contentProps.onOpenAutoFocus, (event) => {\n event.preventDefault()\n if (isWeb) {\n // @ts-ignore\n cancelRef.current?.focus({ preventScroll: true })\n }\n })}\n onPointerDownOutside={(event) => event.preventDefault()}\n onInteractOutside={(event) => event.preventDefault()}\n >\n {/**\n * We have to use `Slottable` here as we cannot wrap the `AlertDialogContentProvider`\n * around everything, otherwise the `DescriptionWarning` would be rendered straight away.\n * This is because we want the accessibility checks to run only once the content is actually\n * open and that behaviour is already encapsulated in `DialogContent`.\n */}\n <Slottable>{children}</Slottable>\n {process.env.NODE_ENV === 'development' && (\n <DescriptionWarning contentRef={contentRef} />\n )}\n </DialogContent>\n </AlertDialogContentProvider>\n </DialogWarningProvider>\n )\n }\n)\n\nAlertDialogContent.displayName = CONTENT_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogTitle\n * -----------------------------------------------------------------------------------------------*/\n\nconst TITLE_NAME = 'AlertDialogTitle'\n\ntype AlertDialogTitleProps = DialogTitleProps\n\nconst AlertDialogTitle = React.forwardRef<TamaguiElement, AlertDialogTitleProps>(\n (props: ScopedProps<AlertDialogTitleProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...titleProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogTitle {...dialogScope} {...titleProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogTitle.displayName = TITLE_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogDescription\n * -----------------------------------------------------------------------------------------------*/\n\nconst DESCRIPTION_NAME = 'AlertDialogDescription'\n\ntype AlertDialogDescriptionProps = DialogDescriptionProps\n\nconst AlertDialogDescription = React.forwardRef<TamaguiElement, AlertDialogDescriptionProps>(\n (props: ScopedProps<AlertDialogDescriptionProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...descriptionProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogDescription {...dialogScope} {...descriptionProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogDescription.displayName = DESCRIPTION_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogAction\n * -----------------------------------------------------------------------------------------------*/\n\nconst ACTION_NAME = 'AlertDialogAction'\n\ntype AlertDialogActionProps = DialogCloseProps\n\nconst AlertDialogAction = React.forwardRef<TamaguiElement, AlertDialogActionProps>(\n (props: ScopedProps<AlertDialogActionProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...actionProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogClose {...dialogScope} {...actionProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogAction.displayName = ACTION_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogCancel\n * -----------------------------------------------------------------------------------------------*/\n\nconst CANCEL_NAME = 'AlertDialogCancel'\n\ninterface AlertDialogCancelProps extends DialogCloseProps {}\n\nconst AlertDialogCancel = React.forwardRef<TamaguiElement, AlertDialogCancelProps>(\n (props: ScopedProps<AlertDialogCancelProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...cancelProps } = props\n const { cancelRef } = useAlertDialogContentContext(CANCEL_NAME, __scopeAlertDialog)\n const dialogScope = useDialogScope(__scopeAlertDialog)\n const ref = useComposedRefs(forwardedRef, cancelRef)\n return <DialogClose {...dialogScope} {...cancelProps} ref={ref} />\n }\n)\n\nAlertDialogCancel.displayName = CANCEL_NAME\n\n/* ---------------------------------------------------------------------------------------------- */\n\ntype DescriptionWarningProps = {\n contentRef: React.RefObject<TamaguiElement>\n}\n\nconst DescriptionWarning: React.FC<DescriptionWarningProps> = ({ contentRef }) => {\n const MESSAGE = `\\`${CONTENT_NAME}\\` requires a description for the component to be accessible for screen reader users.\n\nYou can add a description to the \\`${CONTENT_NAME}\\` by passing a \\`${DESCRIPTION_NAME}\\` component as a child, which also benefits sighted users by adding visible context to the dialog.\n\nAlternatively, you can use your own component as a description by assigning it an \\`id\\` and passing the same value to the \\`aria-describedby\\` prop in \\`${CONTENT_NAME}\\`. If the description is confusing or duplicative for sighted users, you can use the \\`@radix-ui/react-visually-hidden\\` primitive as a wrapper around your description component.\n\nFor more information, see https://tamagui.dev/docs/components/alert-dialog`\n\n React.useEffect(() => {\n if (!isWeb) return\n const hasDescription = document.getElementById(\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain\n contentRef.current?.getAttribute('aria-describedby')!\n )\n if (!hasDescription) console.warn(MESSAGE)\n }, [MESSAGE, contentRef])\n\n return null\n}\n\nconst AlertDialogInner: React.FC<AlertDialogProps> = (props: ScopedProps<AlertDialogProps>) => {\n const { __scopeAlertDialog, native, ...alertDialogProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n\n if (process.env.TAMAGUI_TARGET === 'native') {\n const [open, setOpen] = useControllableState({\n prop: props.open,\n defaultProp: props.defaultOpen || false,\n onChange: props.onOpenChange,\n })\n\n let triggerElement: any = null\n let title = ''\n let description = ''\n const buttons: {\n text: string\n onPress: (value?: string | undefined) => void\n style?: 'default' | 'cancel' | 'destructive'\n }[] = []\n\n forEachChildDeep(React.Children.toArray(props.children), (child) => {\n if (!React.isValidElement(child)) return false\n const name = isTamaguiElement(child)\n ? child.type.staticConfig.componentName\n : (child.type['displayName'] as string | undefined)\n switch (name) {\n case TRIGGER_NAME: {\n triggerElement = React.cloneElement(child as any, {\n __native: true,\n })\n return false\n }\n case TITLE_NAME: {\n title = getStringChildren(child)\n return false\n }\n case DESCRIPTION_NAME: {\n description = getStringChildren(child)\n return false\n }\n case ACTION_NAME:\n case CANCEL_NAME: {\n const style = name === ACTION_NAME ? 'default' : 'cancel'\n const text = getStringChildren(child)\n const onPress = () => {\n ;(child.props as any)?.onPress?.({ native: true })\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\n React.useLayoutEffect(() => {\n if (!open || !native) return\n if (title || description) {\n Alert.alert(title, description, buttons)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [native, open])\n\n if (native) {\n return React.cloneElement(triggerElement, {\n __onPress: () => {\n setOpen(true)\n },\n })\n }\n }\n\n return <Dialog {...dialogScope} {...alertDialogProps} modal={true} />\n}\n\nfunction forEachChildDeep(\n children: React.ReactNode[],\n onChild: (el: React.ReactElement) => boolean\n) {\n for (const child of children) {\n if (!React.isValidElement(child)) continue\n if (!onChild(child)) continue\n if (child.props.children) {\n forEachChildDeep(React.Children.toArray(child.props.children), onChild)\n }\n }\n}\n\nfunction getStringChildren(child: React.ReactElement) {\n let string = ''\n forEachChildDeep(React.Children.toArray(child), (child) => {\n if (typeof child.props.children === 'string') {\n string = child.props.children\n return false\n }\n return true\n })\n return string\n}\n\nconst AlertDialog = withStaticProperties(AlertDialogInner, {\n Trigger: AlertDialogTrigger,\n Portal: AlertDialogPortal,\n Overlay: AlertDialogOverlay,\n Content: AlertDialogContent,\n Action: AlertDialogAction,\n Cancel: AlertDialogCancel,\n Title: AlertDialogTitle,\n Description: AlertDialogDescription,\n})\n\nAlertDialog.displayName = ROOT_NAME\n\nexport {\n createAlertDialogScope,\n //\n AlertDialog,\n AlertDialogTrigger,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogContent,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogTitle,\n AlertDialogDescription,\n}\nexport type {\n AlertDialogProps,\n AlertDialogTriggerProps,\n AlertDialogPortalProps,\n AlertDialogOverlayProps,\n AlertDialogContentProps,\n AlertDialogActionProps,\n AlertDialogCancelProps,\n AlertDialogTitleProps,\n AlertDialogDescriptionProps,\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/jsx/AlertDialog.js
CHANGED
|
@@ -2,7 +2,9 @@ import { useComposedRefs } from "@tamagui/compose-refs";
|
|
|
2
2
|
import {
|
|
3
3
|
Slottable,
|
|
4
4
|
composeEventHandlers,
|
|
5
|
+
isTamaguiElement,
|
|
5
6
|
isWeb,
|
|
7
|
+
styled,
|
|
6
8
|
withStaticProperties
|
|
7
9
|
} from "@tamagui/core";
|
|
8
10
|
import { createContextScope } from "@tamagui/create-context";
|
|
@@ -18,14 +20,24 @@ import {
|
|
|
18
20
|
DialogWarningProvider,
|
|
19
21
|
createDialogScope
|
|
20
22
|
} from "@tamagui/dialog";
|
|
23
|
+
import { YStack } from "@tamagui/stacks";
|
|
24
|
+
import { useControllableState } from "@tamagui/use-controllable-state";
|
|
21
25
|
import * as React from "react";
|
|
26
|
+
import { Alert } from "react-native";
|
|
22
27
|
const ROOT_NAME = "AlertDialog";
|
|
23
28
|
const [createAlertDialogContext, createAlertDialogScope] = createContextScope(ROOT_NAME, [
|
|
24
29
|
createDialogScope
|
|
25
30
|
]);
|
|
26
31
|
const useDialogScope = createDialogScope();
|
|
27
32
|
const TRIGGER_NAME = "AlertDialogTrigger";
|
|
33
|
+
const NativeAlertDialogTriggerFrame = styled(YStack, {
|
|
34
|
+
name: "DialogTrigger"
|
|
35
|
+
});
|
|
28
36
|
const AlertDialogTrigger = React.forwardRef((props, forwardedRef) => {
|
|
37
|
+
if (props["__native"]) {
|
|
38
|
+
const { __native, onPress, __onPress, ...rest } = props;
|
|
39
|
+
return <NativeAlertDialogTriggerFrame {...rest} onPress={composeEventHandlers(onPress, __onPress)} />;
|
|
40
|
+
}
|
|
29
41
|
const { __scopeAlertDialog, ...triggerProps } = props;
|
|
30
42
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
31
43
|
return <DialogTrigger {...dialogScope} {...triggerProps} ref={forwardedRef} />;
|
|
@@ -114,10 +126,98 @@ For more information, see https://tamagui.dev/docs/components/alert-dialog`;
|
|
|
114
126
|
return null;
|
|
115
127
|
};
|
|
116
128
|
const AlertDialogInner = (props) => {
|
|
117
|
-
const { __scopeAlertDialog, ...alertDialogProps } = props;
|
|
129
|
+
const { __scopeAlertDialog, native, ...alertDialogProps } = props;
|
|
118
130
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
131
|
+
if (process.env.TAMAGUI_TARGET === "native") {
|
|
132
|
+
const [open, setOpen] = useControllableState({
|
|
133
|
+
prop: props.open,
|
|
134
|
+
defaultProp: props.defaultOpen || false,
|
|
135
|
+
onChange: props.onOpenChange
|
|
136
|
+
});
|
|
137
|
+
let triggerElement = null;
|
|
138
|
+
let title = "";
|
|
139
|
+
let description = "";
|
|
140
|
+
const buttons = [];
|
|
141
|
+
forEachChildDeep(React.Children.toArray(props.children), (child) => {
|
|
142
|
+
if (!React.isValidElement(child))
|
|
143
|
+
return false;
|
|
144
|
+
const name = isTamaguiElement(child) ? child.type.staticConfig.componentName : child.type["displayName"];
|
|
145
|
+
switch (name) {
|
|
146
|
+
case TRIGGER_NAME: {
|
|
147
|
+
triggerElement = React.cloneElement(child, {
|
|
148
|
+
__native: true
|
|
149
|
+
});
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
case TITLE_NAME: {
|
|
153
|
+
title = getStringChildren(child);
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
case DESCRIPTION_NAME: {
|
|
157
|
+
description = getStringChildren(child);
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
case ACTION_NAME:
|
|
161
|
+
case CANCEL_NAME: {
|
|
162
|
+
const style = name === ACTION_NAME ? "default" : "cancel";
|
|
163
|
+
const text = getStringChildren(child);
|
|
164
|
+
const onPress = () => {
|
|
165
|
+
var _a, _b;
|
|
166
|
+
;
|
|
167
|
+
(_b = (_a = child.props) == null ? void 0 : _a.onPress) == null ? void 0 : _b.call(_a, { native: true });
|
|
168
|
+
setOpen(false);
|
|
169
|
+
};
|
|
170
|
+
buttons.push({
|
|
171
|
+
style,
|
|
172
|
+
text,
|
|
173
|
+
onPress
|
|
174
|
+
});
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
default: {
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
React.useLayoutEffect(() => {
|
|
183
|
+
if (!open || !native)
|
|
184
|
+
return;
|
|
185
|
+
if (title || description) {
|
|
186
|
+
Alert.alert(title, description, buttons);
|
|
187
|
+
}
|
|
188
|
+
}, [native, open]);
|
|
189
|
+
if (native) {
|
|
190
|
+
return React.cloneElement(triggerElement, {
|
|
191
|
+
__onPress: () => {
|
|
192
|
+
setOpen(true);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
119
197
|
return <Dialog {...dialogScope} {...alertDialogProps} modal={true} />;
|
|
120
198
|
};
|
|
199
|
+
function forEachChildDeep(children, onChild) {
|
|
200
|
+
for (const child of children) {
|
|
201
|
+
if (!React.isValidElement(child))
|
|
202
|
+
continue;
|
|
203
|
+
if (!onChild(child))
|
|
204
|
+
continue;
|
|
205
|
+
if (child.props.children) {
|
|
206
|
+
forEachChildDeep(React.Children.toArray(child.props.children), onChild);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function getStringChildren(child) {
|
|
211
|
+
let string = "";
|
|
212
|
+
forEachChildDeep(React.Children.toArray(child), (child2) => {
|
|
213
|
+
if (typeof child2.props.children === "string") {
|
|
214
|
+
string = child2.props.children;
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
return true;
|
|
218
|
+
});
|
|
219
|
+
return string;
|
|
220
|
+
}
|
|
121
221
|
const AlertDialog = withStaticProperties(AlertDialogInner, {
|
|
122
222
|
Trigger: AlertDialogTrigger,
|
|
123
223
|
Portal: AlertDialogPortal,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/AlertDialog.tsx"],
|
|
4
|
-
"sourcesContent": ["// forked from radix-ui\n// https://github.com/radix-ui/primitives/blob/main/packages/react/alert-dialog/src/AlertDialog.tsx\n\nimport { useComposedRefs } from '@tamagui/compose-refs'\nimport {\n Slottable,\n TamaguiElement,\n composeEventHandlers,\n isWeb,\n withStaticProperties,\n} from '@tamagui/core'\nimport { Scope, createContextScope } from '@tamagui/create-context'\nimport {\n Dialog,\n DialogClose,\n DialogCloseProps,\n DialogContent,\n DialogContentProps,\n DialogDescription,\n DialogDescriptionProps,\n DialogOverlay,\n DialogOverlayProps,\n DialogPortal,\n DialogPortalProps,\n DialogProps,\n DialogTitle,\n DialogTitleProps,\n DialogTrigger,\n DialogTriggerProps,\n DialogWarningProvider,\n createDialogScope,\n} from '@tamagui/dialog'\nimport * as React from 'react'\n\nconst ROOT_NAME = 'AlertDialog'\n\ntype ScopedProps<P> = P & { __scopeAlertDialog?: Scope }\nconst [createAlertDialogContext, createAlertDialogScope] = createContextScope(ROOT_NAME, [\n createDialogScope,\n])\n\nconst useDialogScope = createDialogScope()\n\ninterface AlertDialogProps extends Omit<DialogProps, 'modal'> {}\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogTrigger\n * -----------------------------------------------------------------------------------------------*/\nconst TRIGGER_NAME = 'AlertDialogTrigger'\n\ninterface AlertDialogTriggerProps extends DialogTriggerProps {}\n\nconst AlertDialogTrigger = React.forwardRef<TamaguiElement, AlertDialogTriggerProps>(\n (props: ScopedProps<AlertDialogTriggerProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...triggerProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogTrigger {...dialogScope} {...triggerProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogTrigger.displayName = TRIGGER_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogPortal\n * -----------------------------------------------------------------------------------------------*/\n\nconst PORTAL_NAME = 'AlertDialogPortal'\n\ninterface AlertDialogPortalProps extends DialogPortalProps {}\n\nconst AlertDialogPortal: React.FC<AlertDialogPortalProps> = (\n props: ScopedProps<AlertDialogPortalProps>\n) => {\n const { __scopeAlertDialog, ...portalProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogPortal {...dialogScope} {...portalProps} />\n}\n\nAlertDialogPortal.displayName = PORTAL_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogOverlay\n * -----------------------------------------------------------------------------------------------*/\n\nconst OVERLAY_NAME = 'AlertDialogOverlay'\n\ninterface AlertDialogOverlayProps extends DialogOverlayProps {}\n\nconst AlertDialogOverlay = React.forwardRef<TamaguiElement, AlertDialogOverlayProps>(\n (props: ScopedProps<AlertDialogOverlayProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...overlayProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogOverlay {...dialogScope} {...overlayProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogOverlay.displayName = OVERLAY_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogContent\n * -----------------------------------------------------------------------------------------------*/\n\nconst CONTENT_NAME = 'AlertDialogContent'\n\ntype AlertDialogContentContextValue = {\n cancelRef: React.MutableRefObject<TamaguiElement | null>\n}\n\nconst [AlertDialogContentProvider, useAlertDialogContentContext] =\n createAlertDialogContext<AlertDialogContentContextValue>(CONTENT_NAME)\n\ninterface AlertDialogContentProps\n extends Omit<DialogContentProps, 'onPointerDownOutside' | 'onInteractOutside'> {}\n\nconst AlertDialogContent = React.forwardRef<TamaguiElement, AlertDialogContentProps>(\n (props: ScopedProps<AlertDialogContentProps>, forwardedRef) => {\n const { __scopeAlertDialog, children, ...contentProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n const contentRef = React.useRef<TamaguiElement>(null)\n const composedRefs = useComposedRefs(forwardedRef, contentRef)\n const cancelRef = React.useRef<TamaguiElement | null>(null)\n\n return (\n <DialogWarningProvider\n contentName={CONTENT_NAME}\n titleName={TITLE_NAME}\n docsSlug=\"alert-dialog\"\n >\n <AlertDialogContentProvider scope={__scopeAlertDialog} cancelRef={cancelRef}>\n <DialogContent\n // @ts-ignore\n role=\"alertdialog\"\n {...dialogScope}\n {...contentProps}\n ref={composedRefs}\n onOpenAutoFocus={composeEventHandlers(contentProps.onOpenAutoFocus, (event) => {\n event.preventDefault()\n if (isWeb) {\n // @ts-ignore\n cancelRef.current?.focus({ preventScroll: true })\n }\n })}\n onPointerDownOutside={(event) => event.preventDefault()}\n onInteractOutside={(event) => event.preventDefault()}\n >\n {/**\n * We have to use `Slottable` here as we cannot wrap the `AlertDialogContentProvider`\n * around everything, otherwise the `DescriptionWarning` would be rendered straight away.\n * This is because we want the accessibility checks to run only once the content is actually\n * open and that behaviour is already encapsulated in `DialogContent`.\n */}\n <Slottable>{children}</Slottable>\n {process.env.NODE_ENV === 'development' && (\n <DescriptionWarning contentRef={contentRef} />\n )}\n </DialogContent>\n </AlertDialogContentProvider>\n </DialogWarningProvider>\n )\n }\n)\n\nAlertDialogContent.displayName = CONTENT_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogTitle\n * -----------------------------------------------------------------------------------------------*/\n\nconst TITLE_NAME = 'AlertDialogTitle'\n\ntype AlertDialogTitleProps = DialogTitleProps\n\nconst AlertDialogTitle = React.forwardRef<TamaguiElement, AlertDialogTitleProps>(\n (props: ScopedProps<AlertDialogTitleProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...titleProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogTitle {...dialogScope} {...titleProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogTitle.displayName = TITLE_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogDescription\n * -----------------------------------------------------------------------------------------------*/\n\nconst DESCRIPTION_NAME = 'AlertDialogDescription'\n\ntype AlertDialogDescriptionProps = DialogDescriptionProps\n\nconst AlertDialogDescription = React.forwardRef<TamaguiElement, AlertDialogDescriptionProps>(\n (props: ScopedProps<AlertDialogDescriptionProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...descriptionProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogDescription {...dialogScope} {...descriptionProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogDescription.displayName = DESCRIPTION_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogAction\n * -----------------------------------------------------------------------------------------------*/\n\nconst ACTION_NAME = 'AlertDialogAction'\n\ntype AlertDialogActionProps = DialogCloseProps\n\nconst AlertDialogAction = React.forwardRef<TamaguiElement, AlertDialogActionProps>(\n (props: ScopedProps<AlertDialogActionProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...actionProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogClose {...dialogScope} {...actionProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogAction.displayName = ACTION_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogCancel\n * -----------------------------------------------------------------------------------------------*/\n\nconst CANCEL_NAME = 'AlertDialogCancel'\n\ninterface AlertDialogCancelProps extends DialogCloseProps {}\n\nconst AlertDialogCancel = React.forwardRef<TamaguiElement, AlertDialogCancelProps>(\n (props: ScopedProps<AlertDialogCancelProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...cancelProps } = props\n const { cancelRef } = useAlertDialogContentContext(CANCEL_NAME, __scopeAlertDialog)\n const dialogScope = useDialogScope(__scopeAlertDialog)\n const ref = useComposedRefs(forwardedRef, cancelRef)\n return <DialogClose {...dialogScope} {...cancelProps} ref={ref} />\n }\n)\n\nAlertDialogCancel.displayName = CANCEL_NAME\n\n/* ---------------------------------------------------------------------------------------------- */\n\ntype DescriptionWarningProps = {\n contentRef: React.RefObject<TamaguiElement>\n}\n\nconst DescriptionWarning: React.FC<DescriptionWarningProps> = ({ contentRef }) => {\n const MESSAGE = `\\`${CONTENT_NAME}\\` requires a description for the component to be accessible for screen reader users.\n\nYou can add a description to the \\`${CONTENT_NAME}\\` by passing a \\`${DESCRIPTION_NAME}\\` component as a child, which also benefits sighted users by adding visible context to the dialog.\n\nAlternatively, you can use your own component as a description by assigning it an \\`id\\` and passing the same value to the \\`aria-describedby\\` prop in \\`${CONTENT_NAME}\\`. If the description is confusing or duplicative for sighted users, you can use the \\`@radix-ui/react-visually-hidden\\` primitive as a wrapper around your description component.\n\nFor more information, see https://tamagui.dev/docs/components/alert-dialog`\n\n React.useEffect(() => {\n if (!isWeb) return\n const hasDescription = document.getElementById(\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain\n contentRef.current?.getAttribute('aria-describedby')!\n )\n if (!hasDescription) console.warn(MESSAGE)\n }, [MESSAGE, contentRef])\n\n return null\n}\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialog\n * -----------------------------------------------------------------------------------------------*/\n\nconst AlertDialogInner: React.FC<AlertDialogProps> = (props: ScopedProps<AlertDialogProps>) => {\n const { __scopeAlertDialog, ...alertDialogProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <Dialog {...dialogScope} {...alertDialogProps} modal={true} />\n}\n\nconst AlertDialog = withStaticProperties(AlertDialogInner, {\n Trigger: AlertDialogTrigger,\n Portal: AlertDialogPortal,\n Overlay: AlertDialogOverlay,\n Content: AlertDialogContent,\n Action: AlertDialogAction,\n Cancel: AlertDialogCancel,\n Title: AlertDialogTitle,\n Description: AlertDialogDescription,\n})\n\nAlertDialog.displayName = ROOT_NAME\n\nexport {\n createAlertDialogScope,\n //\n AlertDialog,\n AlertDialogTrigger,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogContent,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogTitle,\n AlertDialogDescription,\n}\nexport type {\n AlertDialogProps,\n AlertDialogTriggerProps,\n AlertDialogPortalProps,\n AlertDialogOverlayProps,\n AlertDialogContentProps,\n AlertDialogActionProps,\n AlertDialogCancelProps,\n AlertDialogTitleProps,\n AlertDialogDescriptionProps,\n}\n"],
|
|
5
|
-
"mappings": "AAGA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["// forked from radix-ui\n// https://github.com/radix-ui/primitives/blob/main/packages/react/alert-dialog/src/AlertDialog.tsx\n\nimport { useComposedRefs } from '@tamagui/compose-refs'\nimport {\n Slottable,\n TamaguiElement,\n composeEventHandlers,\n isTamaguiElement,\n isWeb,\n styled,\n withStaticProperties,\n} from '@tamagui/core'\nimport { Scope, createContextScope } from '@tamagui/create-context'\nimport {\n Dialog,\n DialogClose,\n DialogCloseProps,\n DialogContent,\n DialogContentProps,\n DialogDescription,\n DialogDescriptionProps,\n DialogOverlay,\n DialogOverlayProps,\n DialogPortal,\n DialogPortalProps,\n DialogProps,\n DialogTitle,\n DialogTitleProps,\n DialogTrigger,\n DialogTriggerProps,\n DialogWarningProvider,\n createDialogScope,\n} from '@tamagui/dialog'\nimport { YStack } from '@tamagui/stacks'\n/* -------------------------------------------------------------------------------------------------\n * AlertDialog\n * -----------------------------------------------------------------------------------------------*/\nimport { useControllableState } from '@tamagui/use-controllable-state'\nimport * as React from 'react'\nimport { Alert } from 'react-native'\n\nconst ROOT_NAME = 'AlertDialog'\n\ntype ScopedProps<P> = P & { __scopeAlertDialog?: Scope }\nconst [createAlertDialogContext, createAlertDialogScope] = createContextScope(ROOT_NAME, [\n createDialogScope,\n])\n\nconst useDialogScope = createDialogScope()\n\ntype AlertDialogProps = DialogProps & {\n native?: boolean\n}\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogTrigger\n * -----------------------------------------------------------------------------------------------*/\nconst TRIGGER_NAME = 'AlertDialogTrigger'\n\ninterface AlertDialogTriggerProps extends DialogTriggerProps {}\n\nconst NativeAlertDialogTriggerFrame = styled(YStack, {\n name: 'DialogTrigger',\n})\n\nconst AlertDialogTrigger = React.forwardRef<TamaguiElement, AlertDialogTriggerProps>(\n (props: ScopedProps<AlertDialogTriggerProps>, forwardedRef) => {\n if (props['__native']) {\n const { __native, onPress, __onPress, ...rest } = props as any\n return (\n <NativeAlertDialogTriggerFrame\n {...rest}\n onPress={composeEventHandlers(onPress, __onPress)}\n />\n )\n }\n\n const { __scopeAlertDialog, ...triggerProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogTrigger {...dialogScope} {...triggerProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogTrigger.displayName = TRIGGER_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogPortal\n * -----------------------------------------------------------------------------------------------*/\n\nconst PORTAL_NAME = 'AlertDialogPortal'\n\ninterface AlertDialogPortalProps extends DialogPortalProps {}\n\nconst AlertDialogPortal: React.FC<AlertDialogPortalProps> = (\n props: ScopedProps<AlertDialogPortalProps>\n) => {\n const { __scopeAlertDialog, ...portalProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogPortal {...dialogScope} {...portalProps} />\n}\n\nAlertDialogPortal.displayName = PORTAL_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogOverlay\n * -----------------------------------------------------------------------------------------------*/\n\nconst OVERLAY_NAME = 'AlertDialogOverlay'\n\ninterface AlertDialogOverlayProps extends DialogOverlayProps {}\n\nconst AlertDialogOverlay = React.forwardRef<TamaguiElement, AlertDialogOverlayProps>(\n (props: ScopedProps<AlertDialogOverlayProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...overlayProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogOverlay {...dialogScope} {...overlayProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogOverlay.displayName = OVERLAY_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogContent\n * -----------------------------------------------------------------------------------------------*/\n\nconst CONTENT_NAME = 'AlertDialogContent'\n\ntype AlertDialogContentContextValue = {\n cancelRef: React.MutableRefObject<TamaguiElement | null>\n}\n\nconst [AlertDialogContentProvider, useAlertDialogContentContext] =\n createAlertDialogContext<AlertDialogContentContextValue>(CONTENT_NAME)\n\ninterface AlertDialogContentProps\n extends Omit<DialogContentProps, 'onPointerDownOutside' | 'onInteractOutside'> {}\n\nconst AlertDialogContent = React.forwardRef<TamaguiElement, AlertDialogContentProps>(\n (props: ScopedProps<AlertDialogContentProps>, forwardedRef) => {\n const { __scopeAlertDialog, children, ...contentProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n const contentRef = React.useRef<TamaguiElement>(null)\n const composedRefs = useComposedRefs(forwardedRef, contentRef)\n const cancelRef = React.useRef<TamaguiElement | null>(null)\n\n return (\n <DialogWarningProvider\n contentName={CONTENT_NAME}\n titleName={TITLE_NAME}\n docsSlug=\"alert-dialog\"\n >\n <AlertDialogContentProvider scope={__scopeAlertDialog} cancelRef={cancelRef}>\n <DialogContent\n // @ts-ignore\n role=\"alertdialog\"\n {...dialogScope}\n {...contentProps}\n ref={composedRefs}\n onOpenAutoFocus={composeEventHandlers(contentProps.onOpenAutoFocus, (event) => {\n event.preventDefault()\n if (isWeb) {\n // @ts-ignore\n cancelRef.current?.focus({ preventScroll: true })\n }\n })}\n onPointerDownOutside={(event) => event.preventDefault()}\n onInteractOutside={(event) => event.preventDefault()}\n >\n {/**\n * We have to use `Slottable` here as we cannot wrap the `AlertDialogContentProvider`\n * around everything, otherwise the `DescriptionWarning` would be rendered straight away.\n * This is because we want the accessibility checks to run only once the content is actually\n * open and that behaviour is already encapsulated in `DialogContent`.\n */}\n <Slottable>{children}</Slottable>\n {process.env.NODE_ENV === 'development' && (\n <DescriptionWarning contentRef={contentRef} />\n )}\n </DialogContent>\n </AlertDialogContentProvider>\n </DialogWarningProvider>\n )\n }\n)\n\nAlertDialogContent.displayName = CONTENT_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogTitle\n * -----------------------------------------------------------------------------------------------*/\n\nconst TITLE_NAME = 'AlertDialogTitle'\n\ntype AlertDialogTitleProps = DialogTitleProps\n\nconst AlertDialogTitle = React.forwardRef<TamaguiElement, AlertDialogTitleProps>(\n (props: ScopedProps<AlertDialogTitleProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...titleProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogTitle {...dialogScope} {...titleProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogTitle.displayName = TITLE_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogDescription\n * -----------------------------------------------------------------------------------------------*/\n\nconst DESCRIPTION_NAME = 'AlertDialogDescription'\n\ntype AlertDialogDescriptionProps = DialogDescriptionProps\n\nconst AlertDialogDescription = React.forwardRef<TamaguiElement, AlertDialogDescriptionProps>(\n (props: ScopedProps<AlertDialogDescriptionProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...descriptionProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogDescription {...dialogScope} {...descriptionProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogDescription.displayName = DESCRIPTION_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogAction\n * -----------------------------------------------------------------------------------------------*/\n\nconst ACTION_NAME = 'AlertDialogAction'\n\ntype AlertDialogActionProps = DialogCloseProps\n\nconst AlertDialogAction = React.forwardRef<TamaguiElement, AlertDialogActionProps>(\n (props: ScopedProps<AlertDialogActionProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...actionProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n return <DialogClose {...dialogScope} {...actionProps} ref={forwardedRef} />\n }\n)\n\nAlertDialogAction.displayName = ACTION_NAME\n\n/* -------------------------------------------------------------------------------------------------\n * AlertDialogCancel\n * -----------------------------------------------------------------------------------------------*/\n\nconst CANCEL_NAME = 'AlertDialogCancel'\n\ninterface AlertDialogCancelProps extends DialogCloseProps {}\n\nconst AlertDialogCancel = React.forwardRef<TamaguiElement, AlertDialogCancelProps>(\n (props: ScopedProps<AlertDialogCancelProps>, forwardedRef) => {\n const { __scopeAlertDialog, ...cancelProps } = props\n const { cancelRef } = useAlertDialogContentContext(CANCEL_NAME, __scopeAlertDialog)\n const dialogScope = useDialogScope(__scopeAlertDialog)\n const ref = useComposedRefs(forwardedRef, cancelRef)\n return <DialogClose {...dialogScope} {...cancelProps} ref={ref} />\n }\n)\n\nAlertDialogCancel.displayName = CANCEL_NAME\n\n/* ---------------------------------------------------------------------------------------------- */\n\ntype DescriptionWarningProps = {\n contentRef: React.RefObject<TamaguiElement>\n}\n\nconst DescriptionWarning: React.FC<DescriptionWarningProps> = ({ contentRef }) => {\n const MESSAGE = `\\`${CONTENT_NAME}\\` requires a description for the component to be accessible for screen reader users.\n\nYou can add a description to the \\`${CONTENT_NAME}\\` by passing a \\`${DESCRIPTION_NAME}\\` component as a child, which also benefits sighted users by adding visible context to the dialog.\n\nAlternatively, you can use your own component as a description by assigning it an \\`id\\` and passing the same value to the \\`aria-describedby\\` prop in \\`${CONTENT_NAME}\\`. If the description is confusing or duplicative for sighted users, you can use the \\`@radix-ui/react-visually-hidden\\` primitive as a wrapper around your description component.\n\nFor more information, see https://tamagui.dev/docs/components/alert-dialog`\n\n React.useEffect(() => {\n if (!isWeb) return\n const hasDescription = document.getElementById(\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain\n contentRef.current?.getAttribute('aria-describedby')!\n )\n if (!hasDescription) console.warn(MESSAGE)\n }, [MESSAGE, contentRef])\n\n return null\n}\n\nconst AlertDialogInner: React.FC<AlertDialogProps> = (props: ScopedProps<AlertDialogProps>) => {\n const { __scopeAlertDialog, native, ...alertDialogProps } = props\n const dialogScope = useDialogScope(__scopeAlertDialog)\n\n if (process.env.TAMAGUI_TARGET === 'native') {\n const [open, setOpen] = useControllableState({\n prop: props.open,\n defaultProp: props.defaultOpen || false,\n onChange: props.onOpenChange,\n })\n\n let triggerElement: any = null\n let title = ''\n let description = ''\n const buttons: {\n text: string\n onPress: (value?: string | undefined) => void\n style?: 'default' | 'cancel' | 'destructive'\n }[] = []\n\n forEachChildDeep(React.Children.toArray(props.children), (child) => {\n if (!React.isValidElement(child)) return false\n const name = isTamaguiElement(child)\n ? child.type.staticConfig.componentName\n : (child.type['displayName'] as string | undefined)\n switch (name) {\n case TRIGGER_NAME: {\n triggerElement = React.cloneElement(child as any, {\n __native: true,\n })\n return false\n }\n case TITLE_NAME: {\n title = getStringChildren(child)\n return false\n }\n case DESCRIPTION_NAME: {\n description = getStringChildren(child)\n return false\n }\n case ACTION_NAME:\n case CANCEL_NAME: {\n const style = name === ACTION_NAME ? 'default' : 'cancel'\n const text = getStringChildren(child)\n const onPress = () => {\n ;(child.props as any)?.onPress?.({ native: true })\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\n React.useLayoutEffect(() => {\n if (!open || !native) return\n if (title || description) {\n Alert.alert(title, description, buttons)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [native, open])\n\n if (native) {\n return React.cloneElement(triggerElement, {\n __onPress: () => {\n setOpen(true)\n },\n })\n }\n }\n\n return <Dialog {...dialogScope} {...alertDialogProps} modal={true} />\n}\n\nfunction forEachChildDeep(\n children: React.ReactNode[],\n onChild: (el: React.ReactElement) => boolean\n) {\n for (const child of children) {\n if (!React.isValidElement(child)) continue\n if (!onChild(child)) continue\n if (child.props.children) {\n forEachChildDeep(React.Children.toArray(child.props.children), onChild)\n }\n }\n}\n\nfunction getStringChildren(child: React.ReactElement) {\n let string = ''\n forEachChildDeep(React.Children.toArray(child), (child) => {\n if (typeof child.props.children === 'string') {\n string = child.props.children\n return false\n }\n return true\n })\n return string\n}\n\nconst AlertDialog = withStaticProperties(AlertDialogInner, {\n Trigger: AlertDialogTrigger,\n Portal: AlertDialogPortal,\n Overlay: AlertDialogOverlay,\n Content: AlertDialogContent,\n Action: AlertDialogAction,\n Cancel: AlertDialogCancel,\n Title: AlertDialogTitle,\n Description: AlertDialogDescription,\n})\n\nAlertDialog.displayName = ROOT_NAME\n\nexport {\n createAlertDialogScope,\n //\n AlertDialog,\n AlertDialogTrigger,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogContent,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogTitle,\n AlertDialogDescription,\n}\nexport type {\n AlertDialogProps,\n AlertDialogTriggerProps,\n AlertDialogPortalProps,\n AlertDialogOverlayProps,\n AlertDialogContentProps,\n AlertDialogActionProps,\n AlertDialogCancelProps,\n AlertDialogTitleProps,\n AlertDialogDescriptionProps,\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/alert-dialog",
|
|
3
|
-
"version": "1.0.1-beta.
|
|
3
|
+
"version": "1.0.1-beta.116",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"types": "./types/index.d.ts",
|
|
6
6
|
"main": "dist/cjs",
|
|
@@ -21,21 +21,21 @@
|
|
|
21
21
|
"clean:build": "tamagui-build clean:build"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@tamagui/animate-presence": "^1.0.1-beta.
|
|
25
|
-
"@tamagui/aria-hidden": "^1.0.1-beta.
|
|
26
|
-
"@tamagui/compose-refs": "^1.0.1-beta.
|
|
27
|
-
"@tamagui/core": "^1.0.1-beta.
|
|
28
|
-
"@tamagui/create-context": "^1.0.1-beta.
|
|
29
|
-
"@tamagui/dialog": "^1.0.1-beta.
|
|
30
|
-
"@tamagui/dismissable": "^1.0.1-beta.
|
|
31
|
-
"@tamagui/focus-scope": "^1.0.1-beta.
|
|
32
|
-
"@tamagui/polyfill-dev": "^1.0.1-beta.
|
|
33
|
-
"@tamagui/popper": "^1.0.1-beta.
|
|
34
|
-
"@tamagui/portal": "^1.0.1-beta.
|
|
35
|
-
"@tamagui/remove-scroll": "^1.0.1-beta.
|
|
36
|
-
"@tamagui/stacks": "^1.0.1-beta.
|
|
37
|
-
"@tamagui/text": "^1.0.1-beta.
|
|
38
|
-
"@tamagui/use-controllable-state": "^1.0.1-beta.
|
|
24
|
+
"@tamagui/animate-presence": "^1.0.1-beta.116",
|
|
25
|
+
"@tamagui/aria-hidden": "^1.0.1-beta.116",
|
|
26
|
+
"@tamagui/compose-refs": "^1.0.1-beta.116",
|
|
27
|
+
"@tamagui/core": "^1.0.1-beta.116",
|
|
28
|
+
"@tamagui/create-context": "^1.0.1-beta.116",
|
|
29
|
+
"@tamagui/dialog": "^1.0.1-beta.116",
|
|
30
|
+
"@tamagui/dismissable": "^1.0.1-beta.116",
|
|
31
|
+
"@tamagui/focus-scope": "^1.0.1-beta.116",
|
|
32
|
+
"@tamagui/polyfill-dev": "^1.0.1-beta.116",
|
|
33
|
+
"@tamagui/popper": "^1.0.1-beta.116",
|
|
34
|
+
"@tamagui/portal": "^1.0.1-beta.116",
|
|
35
|
+
"@tamagui/remove-scroll": "^1.0.1-beta.116",
|
|
36
|
+
"@tamagui/stacks": "^1.0.1-beta.116",
|
|
37
|
+
"@tamagui/text": "^1.0.1-beta.116",
|
|
38
|
+
"@tamagui/use-controllable-state": "^1.0.1-beta.116"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"react": "*",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"react-native": "*"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@tamagui/build": "^1.0.1-beta.
|
|
46
|
+
"@tamagui/build": "^1.0.1-beta.116",
|
|
47
47
|
"@types/react-dom": "^18.0.3",
|
|
48
48
|
"@types/react-native": "^0.69.2",
|
|
49
49
|
"react": "*",
|
package/src/AlertDialog.tsx
CHANGED
|
@@ -6,7 +6,9 @@ import {
|
|
|
6
6
|
Slottable,
|
|
7
7
|
TamaguiElement,
|
|
8
8
|
composeEventHandlers,
|
|
9
|
+
isTamaguiElement,
|
|
9
10
|
isWeb,
|
|
11
|
+
styled,
|
|
10
12
|
withStaticProperties,
|
|
11
13
|
} from '@tamagui/core'
|
|
12
14
|
import { Scope, createContextScope } from '@tamagui/create-context'
|
|
@@ -30,7 +32,13 @@ import {
|
|
|
30
32
|
DialogWarningProvider,
|
|
31
33
|
createDialogScope,
|
|
32
34
|
} from '@tamagui/dialog'
|
|
35
|
+
import { YStack } from '@tamagui/stacks'
|
|
36
|
+
/* -------------------------------------------------------------------------------------------------
|
|
37
|
+
* AlertDialog
|
|
38
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
39
|
+
import { useControllableState } from '@tamagui/use-controllable-state'
|
|
33
40
|
import * as React from 'react'
|
|
41
|
+
import { Alert } from 'react-native'
|
|
34
42
|
|
|
35
43
|
const ROOT_NAME = 'AlertDialog'
|
|
36
44
|
|
|
@@ -41,7 +49,9 @@ const [createAlertDialogContext, createAlertDialogScope] = createContextScope(RO
|
|
|
41
49
|
|
|
42
50
|
const useDialogScope = createDialogScope()
|
|
43
51
|
|
|
44
|
-
|
|
52
|
+
type AlertDialogProps = DialogProps & {
|
|
53
|
+
native?: boolean
|
|
54
|
+
}
|
|
45
55
|
|
|
46
56
|
/* -------------------------------------------------------------------------------------------------
|
|
47
57
|
* AlertDialogTrigger
|
|
@@ -50,8 +60,22 @@ const TRIGGER_NAME = 'AlertDialogTrigger'
|
|
|
50
60
|
|
|
51
61
|
interface AlertDialogTriggerProps extends DialogTriggerProps {}
|
|
52
62
|
|
|
63
|
+
const NativeAlertDialogTriggerFrame = styled(YStack, {
|
|
64
|
+
name: 'DialogTrigger',
|
|
65
|
+
})
|
|
66
|
+
|
|
53
67
|
const AlertDialogTrigger = React.forwardRef<TamaguiElement, AlertDialogTriggerProps>(
|
|
54
68
|
(props: ScopedProps<AlertDialogTriggerProps>, forwardedRef) => {
|
|
69
|
+
if (props['__native']) {
|
|
70
|
+
const { __native, onPress, __onPress, ...rest } = props as any
|
|
71
|
+
return (
|
|
72
|
+
<NativeAlertDialogTriggerFrame
|
|
73
|
+
{...rest}
|
|
74
|
+
onPress={composeEventHandlers(onPress, __onPress)}
|
|
75
|
+
/>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
55
79
|
const { __scopeAlertDialog, ...triggerProps } = props
|
|
56
80
|
const dialogScope = useDialogScope(__scopeAlertDialog)
|
|
57
81
|
return <DialogTrigger {...dialogScope} {...triggerProps} ref={forwardedRef} />
|
|
@@ -264,16 +288,113 @@ For more information, see https://tamagui.dev/docs/components/alert-dialog`
|
|
|
264
288
|
return null
|
|
265
289
|
}
|
|
266
290
|
|
|
267
|
-
/* -------------------------------------------------------------------------------------------------
|
|
268
|
-
* AlertDialog
|
|
269
|
-
* -----------------------------------------------------------------------------------------------*/
|
|
270
|
-
|
|
271
291
|
const AlertDialogInner: React.FC<AlertDialogProps> = (props: ScopedProps<AlertDialogProps>) => {
|
|
272
|
-
const { __scopeAlertDialog, ...alertDialogProps } = props
|
|
292
|
+
const { __scopeAlertDialog, native, ...alertDialogProps } = props
|
|
273
293
|
const dialogScope = useDialogScope(__scopeAlertDialog)
|
|
294
|
+
|
|
295
|
+
if (process.env.TAMAGUI_TARGET === 'native') {
|
|
296
|
+
const [open, setOpen] = useControllableState({
|
|
297
|
+
prop: props.open,
|
|
298
|
+
defaultProp: props.defaultOpen || false,
|
|
299
|
+
onChange: props.onOpenChange,
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
let triggerElement: any = null
|
|
303
|
+
let title = ''
|
|
304
|
+
let description = ''
|
|
305
|
+
const buttons: {
|
|
306
|
+
text: string
|
|
307
|
+
onPress: (value?: string | undefined) => void
|
|
308
|
+
style?: 'default' | 'cancel' | 'destructive'
|
|
309
|
+
}[] = []
|
|
310
|
+
|
|
311
|
+
forEachChildDeep(React.Children.toArray(props.children), (child) => {
|
|
312
|
+
if (!React.isValidElement(child)) return false
|
|
313
|
+
const name = isTamaguiElement(child)
|
|
314
|
+
? child.type.staticConfig.componentName
|
|
315
|
+
: (child.type['displayName'] as string | undefined)
|
|
316
|
+
switch (name) {
|
|
317
|
+
case TRIGGER_NAME: {
|
|
318
|
+
triggerElement = React.cloneElement(child as any, {
|
|
319
|
+
__native: true,
|
|
320
|
+
})
|
|
321
|
+
return false
|
|
322
|
+
}
|
|
323
|
+
case TITLE_NAME: {
|
|
324
|
+
title = getStringChildren(child)
|
|
325
|
+
return false
|
|
326
|
+
}
|
|
327
|
+
case DESCRIPTION_NAME: {
|
|
328
|
+
description = getStringChildren(child)
|
|
329
|
+
return false
|
|
330
|
+
}
|
|
331
|
+
case ACTION_NAME:
|
|
332
|
+
case CANCEL_NAME: {
|
|
333
|
+
const style = name === ACTION_NAME ? 'default' : 'cancel'
|
|
334
|
+
const text = getStringChildren(child)
|
|
335
|
+
const onPress = () => {
|
|
336
|
+
;(child.props as any)?.onPress?.({ native: true })
|
|
337
|
+
setOpen(false)
|
|
338
|
+
}
|
|
339
|
+
buttons.push({
|
|
340
|
+
style,
|
|
341
|
+
text,
|
|
342
|
+
// @ts-ignore
|
|
343
|
+
onPress,
|
|
344
|
+
})
|
|
345
|
+
return false
|
|
346
|
+
}
|
|
347
|
+
default: {
|
|
348
|
+
return true
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
})
|
|
352
|
+
|
|
353
|
+
React.useLayoutEffect(() => {
|
|
354
|
+
if (!open || !native) return
|
|
355
|
+
if (title || description) {
|
|
356
|
+
Alert.alert(title, description, buttons)
|
|
357
|
+
}
|
|
358
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
359
|
+
}, [native, open])
|
|
360
|
+
|
|
361
|
+
if (native) {
|
|
362
|
+
return React.cloneElement(triggerElement, {
|
|
363
|
+
__onPress: () => {
|
|
364
|
+
setOpen(true)
|
|
365
|
+
},
|
|
366
|
+
})
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
274
370
|
return <Dialog {...dialogScope} {...alertDialogProps} modal={true} />
|
|
275
371
|
}
|
|
276
372
|
|
|
373
|
+
function forEachChildDeep(
|
|
374
|
+
children: React.ReactNode[],
|
|
375
|
+
onChild: (el: React.ReactElement) => boolean
|
|
376
|
+
) {
|
|
377
|
+
for (const child of children) {
|
|
378
|
+
if (!React.isValidElement(child)) continue
|
|
379
|
+
if (!onChild(child)) continue
|
|
380
|
+
if (child.props.children) {
|
|
381
|
+
forEachChildDeep(React.Children.toArray(child.props.children), onChild)
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function getStringChildren(child: React.ReactElement) {
|
|
387
|
+
let string = ''
|
|
388
|
+
forEachChildDeep(React.Children.toArray(child), (child) => {
|
|
389
|
+
if (typeof child.props.children === 'string') {
|
|
390
|
+
string = child.props.children
|
|
391
|
+
return false
|
|
392
|
+
}
|
|
393
|
+
return true
|
|
394
|
+
})
|
|
395
|
+
return string
|
|
396
|
+
}
|
|
397
|
+
|
|
277
398
|
const AlertDialog = withStaticProperties(AlertDialogInner, {
|
|
278
399
|
Trigger: AlertDialogTrigger,
|
|
279
400
|
Portal: AlertDialogPortal,
|
package/types/AlertDialog.d.ts
CHANGED
|
@@ -2,8 +2,9 @@ import { TamaguiElement } from '@tamagui/core';
|
|
|
2
2
|
import { DialogCloseProps, DialogContentProps, DialogDescriptionProps, DialogOverlayProps, DialogPortalProps, DialogProps, DialogTitleProps, DialogTriggerProps } from '@tamagui/dialog';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
declare const createAlertDialogScope: import("@tamagui/create-context").CreateScope;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
declare type AlertDialogProps = DialogProps & {
|
|
6
|
+
native?: boolean;
|
|
7
|
+
};
|
|
7
8
|
interface AlertDialogTriggerProps extends DialogTriggerProps {
|
|
8
9
|
}
|
|
9
10
|
declare const AlertDialogTrigger: React.ForwardRefExoticComponent<AlertDialogTriggerProps & React.RefAttributes<TamaguiElement>>;
|
|
@@ -681,13 +682,13 @@ declare const AlertDialogDescription: React.ForwardRefExoticComponent<((Omit<imp
|
|
|
681
682
|
[x: string]: undefined;
|
|
682
683
|
}>>, string | number>) & React.RefAttributes<TamaguiElement>>;
|
|
683
684
|
declare type AlertDialogActionProps = DialogCloseProps;
|
|
684
|
-
declare const AlertDialogAction: React.ForwardRefExoticComponent<Omit<import("react-native").ViewProps, "
|
|
685
|
+
declare const AlertDialogAction: React.ForwardRefExoticComponent<Omit<import("react-native").ViewProps, "display" | "children"> & import("@tamagui/core").RNWViewProps & import("@tamagui/core").TamaguiComponentPropsBase & import("@tamagui/core").WithThemeValues<import("@tamagui/core").StackStylePropsBase> & import("@tamagui/core").WithShorthands<import("@tamagui/core").WithThemeValues<import("@tamagui/core").StackStylePropsBase>> & Omit<{}, "elevation" | "fullscreen"> & {
|
|
685
686
|
readonly fullscreen?: boolean | undefined;
|
|
686
687
|
readonly elevation?: import("@tamagui/core").SizeTokens | undefined;
|
|
687
|
-
} & import("@tamagui/core").MediaProps<Partial<Omit<import("react-native").ViewProps, "
|
|
688
|
+
} & import("@tamagui/core").MediaProps<Partial<Omit<import("react-native").ViewProps, "display" | "children"> & import("@tamagui/core").RNWViewProps & import("@tamagui/core").TamaguiComponentPropsBase & import("@tamagui/core").WithThemeValues<import("@tamagui/core").StackStylePropsBase> & import("@tamagui/core").WithShorthands<import("@tamagui/core").WithThemeValues<import("@tamagui/core").StackStylePropsBase>> & Omit<{}, "elevation" | "fullscreen"> & {
|
|
688
689
|
readonly fullscreen?: boolean | undefined;
|
|
689
690
|
readonly elevation?: import("@tamagui/core").SizeTokens | undefined;
|
|
690
|
-
}>> & import("@tamagui/core").PseudoProps<Partial<Omit<import("react-native").ViewProps, "
|
|
691
|
+
}>> & import("@tamagui/core").PseudoProps<Partial<Omit<import("react-native").ViewProps, "display" | "children"> & import("@tamagui/core").RNWViewProps & import("@tamagui/core").TamaguiComponentPropsBase & import("@tamagui/core").WithThemeValues<import("@tamagui/core").StackStylePropsBase> & import("@tamagui/core").WithShorthands<import("@tamagui/core").WithThemeValues<import("@tamagui/core").StackStylePropsBase>> & Omit<{}, "elevation" | "fullscreen"> & {
|
|
691
692
|
readonly fullscreen?: boolean | undefined;
|
|
692
693
|
readonly elevation?: import("@tamagui/core").SizeTokens | undefined;
|
|
693
694
|
}>> & React.RefAttributes<TamaguiElement>>;
|
|
@@ -699,13 +700,13 @@ declare const AlertDialog: React.FC<AlertDialogProps> & {
|
|
|
699
700
|
Portal: React.FC<AlertDialogPortalProps>;
|
|
700
701
|
Overlay: React.ForwardRefExoticComponent<AlertDialogOverlayProps & React.RefAttributes<TamaguiElement>>;
|
|
701
702
|
Content: React.ForwardRefExoticComponent<AlertDialogContentProps & React.RefAttributes<TamaguiElement>>;
|
|
702
|
-
Action: React.ForwardRefExoticComponent<Omit<import("react-native").ViewProps, "
|
|
703
|
+
Action: React.ForwardRefExoticComponent<Omit<import("react-native").ViewProps, "display" | "children"> & import("@tamagui/core").RNWViewProps & import("@tamagui/core").TamaguiComponentPropsBase & import("@tamagui/core").WithThemeValues<import("@tamagui/core").StackStylePropsBase> & import("@tamagui/core").WithShorthands<import("@tamagui/core").WithThemeValues<import("@tamagui/core").StackStylePropsBase>> & Omit<{}, "elevation" | "fullscreen"> & {
|
|
703
704
|
readonly fullscreen?: boolean | undefined;
|
|
704
705
|
readonly elevation?: import("@tamagui/core").SizeTokens | undefined;
|
|
705
|
-
} & import("@tamagui/core").MediaProps<Partial<Omit<import("react-native").ViewProps, "
|
|
706
|
+
} & import("@tamagui/core").MediaProps<Partial<Omit<import("react-native").ViewProps, "display" | "children"> & import("@tamagui/core").RNWViewProps & import("@tamagui/core").TamaguiComponentPropsBase & import("@tamagui/core").WithThemeValues<import("@tamagui/core").StackStylePropsBase> & import("@tamagui/core").WithShorthands<import("@tamagui/core").WithThemeValues<import("@tamagui/core").StackStylePropsBase>> & Omit<{}, "elevation" | "fullscreen"> & {
|
|
706
707
|
readonly fullscreen?: boolean | undefined;
|
|
707
708
|
readonly elevation?: import("@tamagui/core").SizeTokens | undefined;
|
|
708
|
-
}>> & import("@tamagui/core").PseudoProps<Partial<Omit<import("react-native").ViewProps, "
|
|
709
|
+
}>> & import("@tamagui/core").PseudoProps<Partial<Omit<import("react-native").ViewProps, "display" | "children"> & import("@tamagui/core").RNWViewProps & import("@tamagui/core").TamaguiComponentPropsBase & import("@tamagui/core").WithThemeValues<import("@tamagui/core").StackStylePropsBase> & import("@tamagui/core").WithShorthands<import("@tamagui/core").WithThemeValues<import("@tamagui/core").StackStylePropsBase>> & Omit<{}, "elevation" | "fullscreen"> & {
|
|
709
710
|
readonly fullscreen?: boolean | undefined;
|
|
710
711
|
readonly elevation?: import("@tamagui/core").SizeTokens | undefined;
|
|
711
712
|
}>> & React.RefAttributes<TamaguiElement>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AlertDialog.d.ts","sourceRoot":"","sources":["../src/AlertDialog.tsx"],"names":[],"mappings":"AAIA,OAAO,EAEL,cAAc,
|
|
1
|
+
{"version":3,"file":"AlertDialog.d.ts","sourceRoot":"","sources":["../src/AlertDialog.tsx"],"names":[],"mappings":"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"}
|