@korsolutions/ui 0.0.37 → 0.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/module/components/alert-dialog/alert-dialog.js +41 -0
  2. package/dist/module/components/alert-dialog/alert-dialog.js.map +1 -0
  3. package/dist/module/components/alert-dialog/async-alert-dialog.js +117 -0
  4. package/dist/module/components/alert-dialog/async-alert-dialog.js.map +1 -0
  5. package/dist/module/components/alert-dialog/index.js +6 -0
  6. package/dist/module/components/alert-dialog/index.js.map +1 -0
  7. package/dist/module/components/alert-dialog/variants/default.js +93 -0
  8. package/dist/module/components/alert-dialog/variants/default.js.map +1 -0
  9. package/dist/module/components/alert-dialog/variants/index.js +7 -0
  10. package/dist/module/components/alert-dialog/variants/index.js.map +1 -0
  11. package/dist/module/components/index.js +1 -0
  12. package/dist/module/components/index.js.map +1 -1
  13. package/dist/module/index.js +2 -1
  14. package/dist/module/index.js.map +1 -1
  15. package/dist/module/primitives/alert-dialog/alert-dialog-action.js +34 -0
  16. package/dist/module/primitives/alert-dialog/alert-dialog-action.js.map +1 -0
  17. package/dist/module/primitives/alert-dialog/alert-dialog-cancel.js +34 -0
  18. package/dist/module/primitives/alert-dialog/alert-dialog-cancel.js.map +1 -0
  19. package/dist/module/primitives/alert-dialog/alert-dialog-content.js +23 -0
  20. package/dist/module/primitives/alert-dialog/alert-dialog-content.js.map +1 -0
  21. package/dist/module/primitives/alert-dialog/alert-dialog-description.js +23 -0
  22. package/dist/module/primitives/alert-dialog/alert-dialog-description.js.map +1 -0
  23. package/dist/module/primitives/alert-dialog/alert-dialog-footer.js +23 -0
  24. package/dist/module/primitives/alert-dialog/alert-dialog-footer.js.map +1 -0
  25. package/dist/module/primitives/alert-dialog/alert-dialog-overlay.js +26 -0
  26. package/dist/module/primitives/alert-dialog/alert-dialog-overlay.js.map +1 -0
  27. package/dist/module/primitives/alert-dialog/alert-dialog-portal.js +20 -0
  28. package/dist/module/primitives/alert-dialog/alert-dialog-portal.js.map +1 -0
  29. package/dist/module/primitives/alert-dialog/alert-dialog-root.js +22 -0
  30. package/dist/module/primitives/alert-dialog/alert-dialog-root.js.map +1 -0
  31. package/dist/module/primitives/alert-dialog/alert-dialog-title.js +23 -0
  32. package/dist/module/primitives/alert-dialog/alert-dialog-title.js.map +1 -0
  33. package/dist/module/primitives/alert-dialog/alert-dialog-trigger.js +28 -0
  34. package/dist/module/primitives/alert-dialog/alert-dialog-trigger.js.map +1 -0
  35. package/dist/module/primitives/alert-dialog/context.js +12 -0
  36. package/dist/module/primitives/alert-dialog/context.js.map +1 -0
  37. package/dist/module/primitives/alert-dialog/index.js +26 -0
  38. package/dist/module/primitives/alert-dialog/index.js.map +1 -0
  39. package/dist/module/primitives/alert-dialog/types.js +4 -0
  40. package/dist/module/primitives/alert-dialog/types.js.map +1 -0
  41. package/dist/module/primitives/index.js +1 -0
  42. package/dist/module/primitives/index.js.map +1 -1
  43. package/dist/module/primitives/popover/popover-portal.js +1 -1
  44. package/dist/module/primitives/popover/popover-portal.js.map +1 -1
  45. package/dist/typescript/src/components/alert-dialog/alert-dialog.d.ts +15 -0
  46. package/dist/typescript/src/components/alert-dialog/alert-dialog.d.ts.map +1 -0
  47. package/dist/typescript/src/components/alert-dialog/async-alert-dialog.d.ts +19 -0
  48. package/dist/typescript/src/components/alert-dialog/async-alert-dialog.d.ts.map +1 -0
  49. package/dist/typescript/src/components/alert-dialog/index.d.ts +4 -0
  50. package/dist/typescript/src/components/alert-dialog/index.d.ts.map +1 -0
  51. package/dist/typescript/src/components/alert-dialog/variants/default.d.ts +3 -0
  52. package/dist/typescript/src/components/alert-dialog/variants/default.d.ts.map +1 -0
  53. package/dist/typescript/src/components/alert-dialog/variants/index.d.ts +4 -0
  54. package/dist/typescript/src/components/alert-dialog/variants/index.d.ts.map +1 -0
  55. package/dist/typescript/src/components/index.d.ts +1 -0
  56. package/dist/typescript/src/components/index.d.ts.map +1 -1
  57. package/dist/typescript/src/index.d.ts.map +1 -1
  58. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-action.d.ts +8 -0
  59. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-action.d.ts.map +1 -0
  60. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-cancel.d.ts +8 -0
  61. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-cancel.d.ts.map +1 -0
  62. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-content.d.ts +8 -0
  63. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-content.d.ts.map +1 -0
  64. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-description.d.ts +8 -0
  65. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-description.d.ts.map +1 -0
  66. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-footer.d.ts +8 -0
  67. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-footer.d.ts.map +1 -0
  68. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-overlay.d.ts +7 -0
  69. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-overlay.d.ts.map +1 -0
  70. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-portal.d.ts +7 -0
  71. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-portal.d.ts.map +1 -0
  72. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-root.d.ts +8 -0
  73. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-root.d.ts.map +1 -0
  74. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-title.d.ts +8 -0
  75. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-title.d.ts.map +1 -0
  76. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-trigger.d.ts +154 -0
  77. package/dist/typescript/src/primitives/alert-dialog/alert-dialog-trigger.d.ts.map +1 -0
  78. package/dist/typescript/src/primitives/alert-dialog/context.d.ts +10 -0
  79. package/dist/typescript/src/primitives/alert-dialog/context.d.ts.map +1 -0
  80. package/dist/typescript/src/primitives/alert-dialog/index.d.ts +33 -0
  81. package/dist/typescript/src/primitives/alert-dialog/index.d.ts.map +1 -0
  82. package/dist/typescript/src/primitives/alert-dialog/types.d.ts +13 -0
  83. package/dist/typescript/src/primitives/alert-dialog/types.d.ts.map +1 -0
  84. package/dist/typescript/src/primitives/index.d.ts +1 -0
  85. package/dist/typescript/src/primitives/index.d.ts.map +1 -1
  86. package/package.json +1 -1
  87. package/src/components/alert-dialog/alert-dialog.tsx +38 -0
  88. package/src/components/alert-dialog/async-alert-dialog.tsx +121 -0
  89. package/src/components/alert-dialog/index.ts +3 -0
  90. package/src/components/alert-dialog/variants/default.tsx +82 -0
  91. package/src/components/alert-dialog/variants/index.ts +5 -0
  92. package/src/components/index.ts +1 -0
  93. package/src/index.tsx +2 -0
  94. package/src/primitives/alert-dialog/alert-dialog-action.tsx +27 -0
  95. package/src/primitives/alert-dialog/alert-dialog-cancel.tsx +27 -0
  96. package/src/primitives/alert-dialog/alert-dialog-content.tsx +21 -0
  97. package/src/primitives/alert-dialog/alert-dialog-description.tsx +21 -0
  98. package/src/primitives/alert-dialog/alert-dialog-footer.tsx +21 -0
  99. package/src/primitives/alert-dialog/alert-dialog-overlay.tsx +25 -0
  100. package/src/primitives/alert-dialog/alert-dialog-portal.tsx +20 -0
  101. package/src/primitives/alert-dialog/alert-dialog-root.tsx +25 -0
  102. package/src/primitives/alert-dialog/alert-dialog-title.tsx +21 -0
  103. package/src/primitives/alert-dialog/alert-dialog-trigger.tsx +27 -0
  104. package/src/primitives/alert-dialog/context.ts +18 -0
  105. package/src/primitives/alert-dialog/index.ts +34 -0
  106. package/src/primitives/alert-dialog/types.ts +13 -0
  107. package/src/primitives/index.ts +1 -0
  108. package/src/primitives/popover/popover-portal.tsx +1 -1
@@ -14,4 +14,5 @@ export * from "./portal";
14
14
  export * from "./calendar";
15
15
  export * from "./tabs";
16
16
  export * from "./checkbox";
17
+ export * from "./alert-dialog";
17
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/primitives/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/primitives/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@korsolutions/ui",
3
- "version": "0.0.37",
3
+ "version": "0.0.38",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,38 @@
1
+ import { AlertDialogPrimitive } from "@/primitives";
2
+ import type { PressableProps } from "react-native";
3
+ import { AlertDialogVariants } from "./variants";
4
+
5
+ interface AlertDialogProps {
6
+ trigger: React.ReactElement<PressableProps>;
7
+ title: string;
8
+ description: string;
9
+ actionLabel?: string;
10
+ cancelLabel?: string;
11
+ onAction?: () => void;
12
+ onCancel?: () => void;
13
+ variant?: keyof typeof AlertDialogVariants;
14
+ }
15
+
16
+ export function AlertDialog(props: AlertDialogProps) {
17
+ const { title, description, actionLabel = "Continue", cancelLabel = "Cancel", onAction, onCancel, variant = "default" } = props;
18
+
19
+ const useVariantStyles = AlertDialogVariants[variant];
20
+ const variantStyles = useVariantStyles();
21
+
22
+ return (
23
+ <AlertDialogPrimitive.Root styles={variantStyles}>
24
+ <AlertDialogPrimitive.Trigger>{props.trigger}</AlertDialogPrimitive.Trigger>
25
+ <AlertDialogPrimitive.Portal>
26
+ <AlertDialogPrimitive.Overlay />
27
+ <AlertDialogPrimitive.Content>
28
+ <AlertDialogPrimitive.Title>{title}</AlertDialogPrimitive.Title>
29
+ <AlertDialogPrimitive.Description>{description}</AlertDialogPrimitive.Description>
30
+ <AlertDialogPrimitive.Footer>
31
+ <AlertDialogPrimitive.Cancel onPress={onCancel}>{cancelLabel}</AlertDialogPrimitive.Cancel>
32
+ <AlertDialogPrimitive.Action onPress={onAction}>{actionLabel}</AlertDialogPrimitive.Action>
33
+ </AlertDialogPrimitive.Footer>
34
+ </AlertDialogPrimitive.Content>
35
+ </AlertDialogPrimitive.Portal>
36
+ </AlertDialogPrimitive.Root>
37
+ );
38
+ }
@@ -0,0 +1,121 @@
1
+ import { AlertDialogPrimitive } from "@/primitives";
2
+ import React, { useEffect, useState } from "react";
3
+ import { useAlertDialog } from "@/primitives/alert-dialog/context";
4
+ import { AlertDialogVariants } from "./variants";
5
+
6
+ interface AsyncAlertDialogProps {
7
+ title: string;
8
+ description: string;
9
+ actionLabel?: string;
10
+ cancelLabel?: string;
11
+ variant?: keyof typeof AlertDialogVariants;
12
+ }
13
+
14
+ interface AsyncAlertDialogResult {
15
+ confirmed: boolean;
16
+ }
17
+
18
+ interface AsyncAlertDialogInstance {
19
+ id: string;
20
+ resolve: (result: AsyncAlertDialogResult) => void;
21
+ props: AsyncAlertDialogProps;
22
+ }
23
+
24
+ // Global state
25
+ const dialogQueue: AsyncAlertDialogInstance[] = [];
26
+ let currentDialog: AsyncAlertDialogInstance | null = null;
27
+ let setCurrentDialogFn: ((dialog: AsyncAlertDialogInstance | null) => void) | null = null;
28
+
29
+ // Process next dialog in queue
30
+ function processQueue() {
31
+ if (currentDialog || dialogQueue.length === 0) return;
32
+
33
+ currentDialog = dialogQueue.shift()!;
34
+ setCurrentDialogFn?.(currentDialog);
35
+ }
36
+
37
+ // Close current dialog
38
+ function closeDialog(confirmed: boolean) {
39
+ if (!currentDialog) return;
40
+
41
+ currentDialog.resolve({ confirmed });
42
+ currentDialog = null;
43
+ setCurrentDialogFn?.(null);
44
+
45
+ // Process next in queue after a small delay
46
+ setTimeout(processQueue, 100);
47
+ }
48
+
49
+ // Inner component that has access to the dialog context
50
+ function AsyncAlertDialogContent({ instance }: { instance: AsyncAlertDialogInstance }) {
51
+ const { title, description, actionLabel = "Continue", cancelLabel = "Cancel" } = instance.props;
52
+ const { setIsOpen } = useAlertDialog();
53
+
54
+ const handleAction = () => closeDialog(true);
55
+ const handleCancel = () => closeDialog(false);
56
+
57
+ // Automatically open the dialog when mounted
58
+ useEffect(() => {
59
+ setIsOpen(true);
60
+ }, [setIsOpen]);
61
+
62
+ return (
63
+ <AlertDialogPrimitive.Portal>
64
+ <AlertDialogPrimitive.Overlay onPress={handleCancel} />
65
+ <AlertDialogPrimitive.Content>
66
+ <AlertDialogPrimitive.Title>{title}</AlertDialogPrimitive.Title>
67
+ <AlertDialogPrimitive.Description>{description}</AlertDialogPrimitive.Description>
68
+ <AlertDialogPrimitive.Footer>
69
+ <AlertDialogPrimitive.Cancel onPress={handleCancel}>{cancelLabel}</AlertDialogPrimitive.Cancel>
70
+ <AlertDialogPrimitive.Action onPress={handleAction}>{actionLabel}</AlertDialogPrimitive.Action>
71
+ </AlertDialogPrimitive.Footer>
72
+ </AlertDialogPrimitive.Content>
73
+ </AlertDialogPrimitive.Portal>
74
+ );
75
+ }
76
+
77
+ // Component that renders a single dialog instance
78
+ function AsyncAlertDialogInstance({ instance }: { instance: AsyncAlertDialogInstance }) {
79
+ const { variant = "default" } = instance.props;
80
+
81
+ const useVariantStyles = AlertDialogVariants[variant];
82
+ const variantStyles = useVariantStyles();
83
+
84
+ return (
85
+ <AlertDialogPrimitive.Root styles={variantStyles}>
86
+ <AsyncAlertDialogContent instance={instance} />
87
+ </AlertDialogPrimitive.Root>
88
+ );
89
+ }
90
+
91
+ export function AsyncAlertDialogManager() {
92
+ const [dialog, setDialog] = useState<AsyncAlertDialogInstance | null>(null);
93
+
94
+ useEffect(() => {
95
+ setCurrentDialogFn = setDialog;
96
+ return () => {
97
+ setCurrentDialogFn = null;
98
+ };
99
+ }, []);
100
+
101
+ if (!dialog) return null;
102
+
103
+ return <AsyncAlertDialogInstance instance={dialog} />;
104
+ }
105
+
106
+ function show(props: AsyncAlertDialogProps): Promise<AsyncAlertDialogResult> {
107
+ return new Promise((resolve) => {
108
+ const instance: AsyncAlertDialogInstance = {
109
+ id: Date.now().toString(),
110
+ props,
111
+ resolve,
112
+ };
113
+
114
+ dialogQueue.push(instance);
115
+ processQueue();
116
+ });
117
+ }
118
+
119
+ export const AsyncAlertDialog = {
120
+ show,
121
+ };
@@ -0,0 +1,3 @@
1
+ export { AlertDialog } from "./alert-dialog";
2
+ export { AlertDialogVariants } from "./variants";
3
+ export { AsyncAlertDialog, AsyncAlertDialogManager } from "./async-alert-dialog";
@@ -0,0 +1,82 @@
1
+ import { type AlertDialogStyles } from "@/primitives";
2
+ import { useThemedStyles } from "@/utils/use-themed-styles";
3
+
4
+ export const useAlertDialogVariantDefault = (): AlertDialogStyles => {
5
+ return useThemedStyles(
6
+ ({ colors, radius, fontFamily, fontSize }): AlertDialogStyles => ({
7
+ overlay: {
8
+ position: "absolute",
9
+ top: 0,
10
+ left: 0,
11
+ right: 0,
12
+ bottom: 0,
13
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
14
+ justifyContent: "center",
15
+ alignItems: "center",
16
+ },
17
+ content: {
18
+ backgroundColor: colors.background,
19
+ borderRadius: radius,
20
+ padding: 24,
21
+ maxWidth: 400,
22
+ width: "90%",
23
+ shadowColor: "#000",
24
+ shadowOffset: { width: 0, height: 2 },
25
+ shadowOpacity: 0.25,
26
+ shadowRadius: 8,
27
+ elevation: 5,
28
+ position: "absolute",
29
+ top: "50%",
30
+ left: "50%",
31
+ transform: [{ translateX: "-50%" }, { translateY: "-50%" }],
32
+ borderWidth: 1,
33
+ borderColor: colors.border,
34
+ },
35
+ title: {
36
+ fontSize: fontSize * 1.25,
37
+ fontWeight: "600",
38
+ color: colors.foreground,
39
+ fontFamily,
40
+ marginBottom: 8,
41
+ },
42
+ description: {
43
+ fontSize,
44
+ color: colors.mutedForeground,
45
+ fontFamily,
46
+ lineHeight: fontSize * 1.5,
47
+ },
48
+ footer: {
49
+ flexDirection: "row",
50
+ justifyContent: "flex-end",
51
+ gap: 12,
52
+ marginTop: 24,
53
+ },
54
+ cancel: {
55
+ paddingVertical: 10,
56
+ paddingHorizontal: 16,
57
+ borderRadius: radius,
58
+ borderWidth: 1,
59
+ borderColor: colors.border,
60
+ backgroundColor: colors.background,
61
+ },
62
+ cancelText: {
63
+ color: colors.foreground,
64
+ fontSize,
65
+ fontWeight: "500",
66
+ fontFamily,
67
+ },
68
+ action: {
69
+ paddingVertical: 10,
70
+ paddingHorizontal: 16,
71
+ borderRadius: radius,
72
+ backgroundColor: colors.primary,
73
+ },
74
+ actionText: {
75
+ color: colors.primaryForeground,
76
+ fontSize,
77
+ fontWeight: "500",
78
+ fontFamily,
79
+ },
80
+ })
81
+ );
82
+ };
@@ -0,0 +1,5 @@
1
+ import { useAlertDialogVariantDefault } from "./default";
2
+
3
+ export const AlertDialogVariants = {
4
+ default: useAlertDialogVariantDefault,
5
+ };
@@ -15,3 +15,4 @@ export * from "./popover/popover";
15
15
  export * from "./calendar/calendar";
16
16
  export * from "./tabs";
17
17
  export * from "./checkbox";
18
+ export * from "./alert-dialog";
package/src/index.tsx CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ThemeProvider } from "@/themes";
2
+ import { AsyncAlertDialogManager } from "./components/alert-dialog/async-alert-dialog";
2
3
  import { ToastContainer } from "./components/toast/toast-manager";
3
4
  import { PortalHost } from "./primitives/portal";
4
5
  import { type PortalHostProps } from "./primitives/portal/portal.constants";
@@ -15,6 +16,7 @@ export const UniversalUIProvider = ({ children, portalContainer }: ProviderProps
15
16
  <ToastContainer />
16
17
  {children}
17
18
  <PortalHost container={portalContainer} />
19
+ <AsyncAlertDialogManager />
18
20
  </ThemeProvider>
19
21
  );
20
22
  };
@@ -0,0 +1,27 @@
1
+ import React from "react";
2
+ import { Pressable, Text, type PressableProps, type StyleProp, type ViewStyle } from "react-native";
3
+ import { useAlertDialog } from "./context";
4
+
5
+ export interface AlertDialogPrimitiveActionProps extends PressableProps {
6
+ children: React.ReactNode;
7
+ style?: StyleProp<ViewStyle>;
8
+ }
9
+
10
+ export function AlertDialogAction(props: AlertDialogPrimitiveActionProps) {
11
+ const { children, style, onPress, ...pressableProps } = props;
12
+ const { styles, setIsOpen } = useAlertDialog();
13
+
14
+ const handlePress: PressableProps["onPress"] = (event) => {
15
+ onPress?.(event);
16
+ setIsOpen(false);
17
+ };
18
+
19
+ const calculatedStyle = [styles?.action, style];
20
+ const textStyle = styles?.actionText;
21
+
22
+ return (
23
+ <Pressable {...pressableProps} style={calculatedStyle} onPress={handlePress}>
24
+ <Text style={textStyle}>{children}</Text>
25
+ </Pressable>
26
+ );
27
+ }
@@ -0,0 +1,27 @@
1
+ import React from "react";
2
+ import { Pressable, Text, type PressableProps, type StyleProp, type ViewStyle } from "react-native";
3
+ import { useAlertDialog } from "./context";
4
+
5
+ export interface AlertDialogPrimitiveCancelProps extends PressableProps {
6
+ children: React.ReactNode;
7
+ style?: StyleProp<ViewStyle>;
8
+ }
9
+
10
+ export function AlertDialogCancel(props: AlertDialogPrimitiveCancelProps) {
11
+ const { children, style, onPress, ...pressableProps } = props;
12
+ const { styles, setIsOpen } = useAlertDialog();
13
+
14
+ const handlePress: PressableProps["onPress"] = (event) => {
15
+ onPress?.(event);
16
+ setIsOpen(false);
17
+ };
18
+
19
+ const calculatedStyle = [styles?.cancel, style];
20
+ const textStyle = styles?.cancelText;
21
+
22
+ return (
23
+ <Pressable {...pressableProps} style={calculatedStyle} onPress={handlePress}>
24
+ <Text style={textStyle}>{children}</Text>
25
+ </Pressable>
26
+ );
27
+ }
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ import { View, type StyleProp, type ViewProps, type ViewStyle } from "react-native";
3
+ import { useAlertDialog } from "./context";
4
+
5
+ export interface AlertDialogPrimitiveContentProps extends ViewProps {
6
+ children: React.ReactNode;
7
+ style?: StyleProp<ViewStyle>;
8
+ }
9
+
10
+ export function AlertDialogContent(props: AlertDialogPrimitiveContentProps) {
11
+ const { children, style, ...viewProps } = props;
12
+ const { styles } = useAlertDialog();
13
+
14
+ const calculatedStyle = [styles?.content, style];
15
+
16
+ return (
17
+ <View {...viewProps} style={calculatedStyle}>
18
+ {children}
19
+ </View>
20
+ );
21
+ }
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ import { Text, type StyleProp, type TextProps, type TextStyle } from "react-native";
3
+ import { useAlertDialog } from "./context";
4
+
5
+ export interface AlertDialogPrimitiveDescriptionProps extends TextProps {
6
+ children: React.ReactNode;
7
+ style?: StyleProp<TextStyle>;
8
+ }
9
+
10
+ export function AlertDialogDescription(props: AlertDialogPrimitiveDescriptionProps) {
11
+ const { children, style, ...textProps } = props;
12
+ const { styles } = useAlertDialog();
13
+
14
+ const calculatedStyle = [styles?.description, style];
15
+
16
+ return (
17
+ <Text {...textProps} style={calculatedStyle}>
18
+ {children}
19
+ </Text>
20
+ );
21
+ }
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ import { View, type StyleProp, type ViewProps, type ViewStyle } from "react-native";
3
+ import { useAlertDialog } from "./context";
4
+
5
+ export interface AlertDialogPrimitiveFooterProps extends ViewProps {
6
+ children: React.ReactNode;
7
+ style?: StyleProp<ViewStyle>;
8
+ }
9
+
10
+ export function AlertDialogFooter(props: AlertDialogPrimitiveFooterProps) {
11
+ const { children, style, ...viewProps } = props;
12
+ const { styles } = useAlertDialog();
13
+
14
+ const calculatedStyle = [styles?.footer, style];
15
+
16
+ return (
17
+ <View {...viewProps} style={calculatedStyle}>
18
+ {children}
19
+ </View>
20
+ );
21
+ }
@@ -0,0 +1,25 @@
1
+ import React from "react";
2
+ import { Pressable, type PressableProps, type StyleProp, type ViewStyle } from "react-native";
3
+ import { useAlertDialog } from "./context";
4
+
5
+ export interface AlertDialogPrimitiveOverlayProps extends PressableProps {
6
+ style?: StyleProp<ViewStyle>;
7
+ }
8
+
9
+ export function AlertDialogOverlay(props: AlertDialogPrimitiveOverlayProps) {
10
+ const { style, ...pressableProps } = props;
11
+ const { styles, setIsOpen } = useAlertDialog();
12
+
13
+ const calculatedStyle = [styles?.overlay, style];
14
+
15
+ return (
16
+ <Pressable
17
+ {...pressableProps}
18
+ style={calculatedStyle}
19
+ onPress={() => setIsOpen(false)}
20
+ accessible={true}
21
+ accessibilityRole="button"
22
+ accessibilityLabel="Close alert dialog"
23
+ />
24
+ );
25
+ }
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import { Portal } from "../portal";
3
+ import { AlertDialogPrimitiveContext, useAlertDialog } from "./context";
4
+
5
+ interface AlertDialogPortalProps {
6
+ children: React.ReactNode;
7
+ }
8
+
9
+ export function AlertDialogPortal(props: AlertDialogPortalProps) {
10
+ const alertDialog = useAlertDialog();
11
+
12
+ if (!alertDialog.isOpen) {
13
+ return null;
14
+ }
15
+ return (
16
+ <Portal name="alert-dialog-content">
17
+ <AlertDialogPrimitiveContext.Provider value={alertDialog}>{props.children}</AlertDialogPrimitiveContext.Provider>
18
+ </Portal>
19
+ );
20
+ }
@@ -0,0 +1,25 @@
1
+ import React, { useMemo, useState } from "react";
2
+ import { AlertDialogPrimitiveContext } from "./context";
3
+ import type { AlertDialogStyles } from "./types";
4
+
5
+ export interface AlertDialogPrimitiveRootProps {
6
+ children: React.ReactNode;
7
+
8
+ styles?: AlertDialogStyles;
9
+ }
10
+
11
+ export function AlertDialogRoot(props: AlertDialogPrimitiveRootProps) {
12
+ const { children, styles } = props;
13
+ const [isOpen, setIsOpen] = useState(false);
14
+
15
+ const contextValue = useMemo(
16
+ () => ({
17
+ isOpen,
18
+ setIsOpen,
19
+ styles,
20
+ }),
21
+ [isOpen, styles]
22
+ );
23
+
24
+ return <AlertDialogPrimitiveContext.Provider value={contextValue}>{children}</AlertDialogPrimitiveContext.Provider>;
25
+ }
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ import { Text, type StyleProp, type TextProps, type TextStyle } from "react-native";
3
+ import { useAlertDialog } from "./context";
4
+
5
+ export interface AlertDialogPrimitiveTitleProps extends TextProps {
6
+ children: React.ReactNode;
7
+ style?: StyleProp<TextStyle>;
8
+ }
9
+
10
+ export function AlertDialogTitle(props: AlertDialogPrimitiveTitleProps) {
11
+ const { children, style, ...textProps } = props;
12
+ const { styles } = useAlertDialog();
13
+
14
+ const calculatedStyle = [styles?.title, style];
15
+
16
+ return (
17
+ <Text {...textProps} style={calculatedStyle}>
18
+ {children}
19
+ </Text>
20
+ );
21
+ }
@@ -0,0 +1,27 @@
1
+ import type { ViewRef } from "@/types/element.types";
2
+ import React from "react";
3
+ import { type PressableProps } from "react-native";
4
+ import { useAlertDialog } from "./context";
5
+
6
+ export interface AlertDialogPrimitiveTriggerProps extends PressableProps {
7
+ children: React.ReactElement<React.RefAttributes<ViewRef> & PressableProps>;
8
+ }
9
+
10
+ export function AlertDialogTrigger(props: AlertDialogPrimitiveTriggerProps) {
11
+ const { onPress } = props;
12
+ const { isOpen, setIsOpen } = useAlertDialog();
13
+
14
+ const handlePress: PressableProps["onPress"] = (event) => {
15
+ onPress?.(event);
16
+ setIsOpen(true);
17
+ };
18
+
19
+ return React.cloneElement(props.children, {
20
+ onPress: handlePress,
21
+ role: "button",
22
+ accessible: true,
23
+ accessibilityRole: "button",
24
+ accessibilityState: { expanded: isOpen },
25
+ ...props.children.props,
26
+ });
27
+ }
@@ -0,0 +1,18 @@
1
+ import React, { createContext, useContext, type Dispatch } from "react";
2
+ import type { AlertDialogStyles } from "./types";
3
+
4
+ export interface AlertDialogPrimitiveContextValue {
5
+ isOpen: boolean;
6
+ setIsOpen: Dispatch<React.SetStateAction<boolean>>;
7
+ styles?: AlertDialogStyles;
8
+ }
9
+
10
+ export const AlertDialogPrimitiveContext = createContext<AlertDialogPrimitiveContextValue | null>(null);
11
+
12
+ export const useAlertDialog = () => {
13
+ const context = useContext(AlertDialogPrimitiveContext);
14
+ if (!context) {
15
+ throw new Error("AlertDialog compound components must be used within AlertDialogPrimitive.Root");
16
+ }
17
+ return context;
18
+ };
@@ -0,0 +1,34 @@
1
+ import { AlertDialogAction } from "./alert-dialog-action";
2
+ import { AlertDialogCancel } from "./alert-dialog-cancel";
3
+ import { AlertDialogContent } from "./alert-dialog-content";
4
+ import { AlertDialogDescription } from "./alert-dialog-description";
5
+ import { AlertDialogFooter } from "./alert-dialog-footer";
6
+ import { AlertDialogOverlay } from "./alert-dialog-overlay";
7
+ import { AlertDialogPortal } from "./alert-dialog-portal";
8
+ import { AlertDialogRoot } from "./alert-dialog-root";
9
+ import { AlertDialogTitle } from "./alert-dialog-title";
10
+ import { AlertDialogTrigger } from "./alert-dialog-trigger";
11
+
12
+ export const AlertDialogPrimitive = {
13
+ Root: AlertDialogRoot,
14
+ Trigger: AlertDialogTrigger,
15
+ Portal: AlertDialogPortal,
16
+ Overlay: AlertDialogOverlay,
17
+ Content: AlertDialogContent,
18
+ Title: AlertDialogTitle,
19
+ Description: AlertDialogDescription,
20
+ Footer: AlertDialogFooter,
21
+ Action: AlertDialogAction,
22
+ Cancel: AlertDialogCancel,
23
+ };
24
+
25
+ export type { AlertDialogPrimitiveActionProps } from "./alert-dialog-action";
26
+ export type { AlertDialogPrimitiveCancelProps } from "./alert-dialog-cancel";
27
+ export type { AlertDialogPrimitiveContentProps } from "./alert-dialog-content";
28
+ export type { AlertDialogPrimitiveDescriptionProps } from "./alert-dialog-description";
29
+ export type { AlertDialogPrimitiveFooterProps } from "./alert-dialog-footer";
30
+ export type { AlertDialogPrimitiveOverlayProps } from "./alert-dialog-overlay";
31
+ export type { AlertDialogPrimitiveRootProps } from "./alert-dialog-root";
32
+ export type { AlertDialogPrimitiveTitleProps } from "./alert-dialog-title";
33
+ export type { AlertDialogPrimitiveTriggerProps } from "./alert-dialog-trigger";
34
+ export * from "./types";
@@ -0,0 +1,13 @@
1
+ import type { StyleProp, TextStyle, ViewStyle } from "react-native";
2
+
3
+ export interface AlertDialogStyles {
4
+ overlay?: StyleProp<ViewStyle>;
5
+ content?: StyleProp<ViewStyle>;
6
+ title?: StyleProp<TextStyle>;
7
+ description?: StyleProp<TextStyle>;
8
+ footer?: StyleProp<ViewStyle>;
9
+ action?: StyleProp<ViewStyle>;
10
+ actionText?: StyleProp<TextStyle>;
11
+ cancel?: StyleProp<ViewStyle>;
12
+ cancelText?: StyleProp<TextStyle>;
13
+ }
@@ -14,3 +14,4 @@ export * from "./portal";
14
14
  export * from "./calendar";
15
15
  export * from "./tabs";
16
16
  export * from "./checkbox";
17
+ export * from "./alert-dialog";
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { Portal } from "../portal";
3
- import { usePopover, PopoverContext } from "./context";
3
+ import { PopoverContext, usePopover } from "./context";
4
4
 
5
5
  export interface PopoverPortalProps {
6
6
  children?: React.ReactNode;