@hanzogui/alert-dialog 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA,cAAc","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export * from "./AlertDialog.mjs";
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA,cAAc","ignoreList":[]}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __copyProps = (to, from, except, desc) => {
8
+ if (from && typeof from == "object" || typeof from == "function") for (let key of __getOwnPropNames(from)) !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, {
9
+ get: () => from[key],
10
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
11
+ });
12
+ return to;
13
+ },
14
+ __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
15
+ var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
16
+ value: !0
17
+ }), mod);
18
+ var index_exports = {};
19
+ module.exports = __toCommonJS(index_exports);
20
+ __reExport(index_exports, require("./AlertDialog.native.js"), module.exports);
21
+ //# sourceMappingURL=index.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA","ignoreList":[]}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@hanzogui/alert-dialog",
3
+ "version": "2.0.0",
4
+ "source": "src/index.ts",
5
+ "files": [
6
+ "src",
7
+ "types",
8
+ "dist"
9
+ ],
10
+ "type": "module",
11
+ "sideEffects": [
12
+ "*.css"
13
+ ],
14
+ "main": "dist/cjs",
15
+ "module": "dist/esm",
16
+ "types": "./types/index.d.ts",
17
+ "exports": {
18
+ "./package.json": "./package.json",
19
+ ".": {
20
+ "types": "./types/index.d.ts",
21
+ "react-native": "./dist/esm/index.native.js",
22
+ "browser": "./dist/esm/index.mjs",
23
+ "module": "./dist/esm/index.mjs",
24
+ "import": "./dist/esm/index.mjs",
25
+ "require": "./dist/cjs/index.cjs",
26
+ "default": "./dist/esm/index.mjs"
27
+ }
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "scripts": {
33
+ "build": "hanzo-gui-build",
34
+ "watch": "hanzo-gui-build --watch",
35
+ "clean": "hanzo-gui-build clean",
36
+ "clean:build": "hanzo-gui-build clean:build"
37
+ },
38
+ "dependencies": {
39
+ "@hanzogui/animate-presence": "2.0.0",
40
+ "@hanzogui/compose-refs": "2.0.0-rc.29",
41
+ "@hanzogui/constants": "2.0.0-rc.29",
42
+ "@hanzogui/core": "2.0.0-rc.29",
43
+ "@hanzogui/create-context": "2.0.0-rc.29",
44
+ "@hanzogui/dialog": "2.0.0",
45
+ "@hanzogui/dismissable": "2.0.0",
46
+ "@hanzogui/focus-scope": "2.0.0",
47
+ "@hanzogui/helpers": "2.0.0-rc.29",
48
+ "@hanzogui/polyfill-dev": "2.0.0-rc.29",
49
+ "@hanzogui/portal": "2.0.0",
50
+ "@hanzogui/remove-scroll": "2.0.0",
51
+ "@hanzogui/stacks": "2.0.0",
52
+ "@hanzogui/text": "2.0.0",
53
+ "@hanzogui/use-controllable-state": "2.0.0-rc.29"
54
+ },
55
+ "devDependencies": {
56
+ "@hanzogui/build": "2.0.0-rc.29",
57
+ "react": ">=19",
58
+ "react-native": "0.83.2"
59
+ },
60
+ "peerDependencies": {
61
+ "react": ">=19",
62
+ "react-native": "*"
63
+ },
64
+ "module:jsx": "dist/jsx",
65
+ "removeSideEffects": true
66
+ }
@@ -0,0 +1,515 @@
1
+ // forked from radix-ui
2
+ // https://github.com/radix-ui/primitives/blob/main/packages/react/alert-dialog/src/AlertDialog.tsx
3
+
4
+ import { useComposedRefs } from '@hanzogui/compose-refs'
5
+ import { isWeb, useIsomorphicLayoutEffect } from '@hanzogui/constants'
6
+ import type { GuiElement } from '@hanzogui/core'
7
+ import {
8
+ Slottable,
9
+ View,
10
+ createStyledContext,
11
+ isGuiElement,
12
+ styled,
13
+ } from '@hanzogui/core'
14
+ import type {
15
+ DialogCloseProps,
16
+ DialogContentProps,
17
+ DialogDescriptionProps,
18
+ DialogOverlayExtraProps,
19
+ DialogOverlayProps,
20
+ DialogPortalProps,
21
+ DialogProps,
22
+ DialogTitleProps,
23
+ DialogTriggerProps,
24
+ } from '@hanzogui/dialog'
25
+ import {
26
+ Dialog,
27
+ DialogClose,
28
+ DialogContent,
29
+ DialogDescription,
30
+ DialogOverlay,
31
+ DialogOverlayFrame,
32
+ DialogPortal,
33
+ DialogTitle,
34
+ DialogTrigger,
35
+ DialogWarningProvider,
36
+ } from '@hanzogui/dialog'
37
+ import { composeEventHandlers, withStaticProperties } from '@hanzogui/helpers'
38
+ import { useControllableState } from '@hanzogui/use-controllable-state'
39
+ import * as React from 'react'
40
+ import { Alert } from 'react-native'
41
+
42
+ const getAlertDialogScope = (scope?: string) => scope
43
+
44
+ /* -------------------------------------------------------------------------------------------------
45
+ * AlertDialog
46
+ * -----------------------------------------------------------------------------------------------*/
47
+
48
+ const ROOT_NAME = 'AlertDialog'
49
+
50
+ export type AlertDialogScopes = string
51
+
52
+ type ScopedProps<P> = Omit<P, 'scope'> & { scope?: AlertDialogScopes }
53
+
54
+ type AlertDialogProps = ScopedProps<DialogProps> & {
55
+ native?: boolean
56
+ }
57
+
58
+ /* -------------------------------------------------------------------------------------------------
59
+ * AlertDialogTrigger
60
+ * -----------------------------------------------------------------------------------------------*/
61
+
62
+ const TRIGGER_NAME = 'AlertDialogTrigger'
63
+
64
+ type AlertDialogTriggerProps = ScopedProps<DialogTriggerProps>
65
+
66
+ const NativeAlertDialogTriggerFrame = styled(View, {
67
+ name: TRIGGER_NAME,
68
+ })
69
+
70
+ const AlertDialogTrigger =
71
+ NativeAlertDialogTriggerFrame.styleable<AlertDialogTriggerProps>(
72
+ function AlertDialogTrigger(props, forwardedRef) {
73
+ if (props['__native']) {
74
+ const { __native, onPress, __onPress, ...rest } = props as any
75
+ return (
76
+ <NativeAlertDialogTriggerFrame
77
+ {...rest}
78
+ onPress={composeEventHandlers(onPress, __onPress)}
79
+ />
80
+ )
81
+ }
82
+
83
+ const { scope, ...triggerProps } = props
84
+ return (
85
+ <DialogTrigger
86
+ scope={getAlertDialogScope(scope)}
87
+ {...triggerProps}
88
+ ref={forwardedRef}
89
+ />
90
+ )
91
+ }
92
+ )
93
+
94
+ /* -------------------------------------------------------------------------------------------------
95
+ * AlertDialogPortal
96
+ * -----------------------------------------------------------------------------------------------*/
97
+
98
+ const PORTAL_NAME = 'AlertDialogPortal'
99
+
100
+ type AlertDialogPortalProps = ScopedProps<DialogPortalProps>
101
+
102
+ const AlertDialogPortal: React.FC<AlertDialogPortalProps> = function AlertDialogPortal(
103
+ props: ScopedProps<AlertDialogPortalProps>
104
+ ) {
105
+ const { scope, ...portalProps } = props
106
+ return <DialogPortal scope={getAlertDialogScope(scope)} {...portalProps} />
107
+ }
108
+
109
+ /* -------------------------------------------------------------------------------------------------
110
+ * AlertDialogOverlay
111
+ * -----------------------------------------------------------------------------------------------*/
112
+
113
+ const OVERLAY_NAME = 'AlertDialogOverlay'
114
+
115
+ const AlertDialogOverlayFrame = styled(DialogOverlayFrame, {
116
+ name: OVERLAY_NAME,
117
+ })
118
+
119
+ type AlertDialogOverlayExtraProps = ScopedProps<{}> & DialogOverlayExtraProps
120
+ type AlertDialogOverlayProps = AlertDialogOverlayExtraProps & DialogOverlayProps
121
+
122
+ const AlertDialogOverlay = AlertDialogOverlayFrame.styleable<AlertDialogOverlayProps>(
123
+ function AlertDialogOverlay(props, forwardedRef) {
124
+ const { scope, ...overlayProps } = props
125
+ return (
126
+ <DialogOverlay
127
+ scope={getAlertDialogScope(scope)}
128
+ {...overlayProps}
129
+ ref={forwardedRef}
130
+ />
131
+ )
132
+ }
133
+ )
134
+
135
+ /* -------------------------------------------------------------------------------------------------
136
+ * AlertDialogContent
137
+ * -----------------------------------------------------------------------------------------------*/
138
+
139
+ const CONTENT_NAME = 'AlertDialogContent'
140
+
141
+ type AlertDialogContentContextValue = {
142
+ cancelRef?: React.RefObject<GuiElement | null>
143
+ destructiveRef?: React.RefObject<GuiElement | null>
144
+ }
145
+
146
+ const {
147
+ Provider: AlertDialogContextProvider,
148
+ useStyledContext: useAlertDialogContentContext,
149
+ } = createStyledContext<AlertDialogContentContextValue>({}, 'AlertDialogContext')
150
+
151
+ type AlertDialogContentProps = ScopedProps<
152
+ Omit<DialogContentProps, 'onPointerDownOutside' | 'onInteractOutside'>
153
+ >
154
+
155
+ const AlertDialogContent = React.forwardRef<GuiElement, AlertDialogContentProps>(
156
+ function AlertDialogContent(props, forwardedRef) {
157
+ const { scope, children, ...contentProps } = props
158
+ const dialogScope = getAlertDialogScope(scope)
159
+ const contentRef = React.useRef<GuiElement>(null)
160
+ const composedRefs = useComposedRefs(forwardedRef, contentRef)
161
+ const cancelRef = React.useRef<GuiElement | null>(null)
162
+ const destructiveRef = React.useRef<GuiElement | null>(null)
163
+
164
+ return (
165
+ <DialogWarningProvider
166
+ contentName={CONTENT_NAME}
167
+ titleName={TITLE_NAME}
168
+ docsSlug="alert-dialog"
169
+ >
170
+ <AlertDialogContextProvider
171
+ scope={scope}
172
+ cancelRef={cancelRef}
173
+ destructiveRef={destructiveRef}
174
+ >
175
+ <DialogContent
176
+ role="alertdialog"
177
+ aria-modal={true}
178
+ scope={dialogScope}
179
+ {...contentProps}
180
+ ref={composedRefs}
181
+ onOpenAutoFocus={composeEventHandlers(
182
+ contentProps.onOpenAutoFocus,
183
+ (event) => {
184
+ event.preventDefault()
185
+ if (isWeb) {
186
+ cancelRef.current?.focus({ preventScroll: true })
187
+ }
188
+ }
189
+ )}
190
+ onPointerDownOutside={(event) => event.preventDefault()}
191
+ onInteractOutside={(event) => event.preventDefault()}
192
+ >
193
+ {/**
194
+ * We have to use `Slottable` here as we cannot wrap the `AlertDialogContentProvider`
195
+ * around everything, otherwise the `DescriptionWarning` would be rendered straight away.
196
+ * This is because we want the accessibility checks to run only once the content is actually
197
+ * open and that behaviour is already encapsulated in `DialogContent`.
198
+ */}
199
+ <Slottable>{children}</Slottable>
200
+ {process.env.NODE_ENV === 'development' && (
201
+ <DescriptionWarning contentRef={contentRef} />
202
+ )}
203
+ </DialogContent>
204
+ </AlertDialogContextProvider>
205
+ </DialogWarningProvider>
206
+ )
207
+ }
208
+ )
209
+
210
+ /* -------------------------------------------------------------------------------------------------
211
+ * AlertDialogTitle
212
+ * -----------------------------------------------------------------------------------------------*/
213
+
214
+ const TITLE_NAME = 'AlertDialogTitle'
215
+
216
+ type AlertDialogTitleProps = ScopedProps<DialogTitleProps>
217
+
218
+ const AlertDialogTitleFrame = styled(View, {
219
+ name: TITLE_NAME,
220
+ })
221
+
222
+ const AlertDialogTitle = AlertDialogTitleFrame.styleable<AlertDialogTitleProps>(
223
+ function AlertDialogTitle(props, forwardedRef) {
224
+ const { scope, ...titleProps } = props
225
+ return (
226
+ <DialogTitle
227
+ scope={getAlertDialogScope(scope)}
228
+ {...titleProps}
229
+ ref={forwardedRef}
230
+ />
231
+ )
232
+ }
233
+ )
234
+
235
+ /* -------------------------------------------------------------------------------------------------
236
+ * AlertDialogDescription
237
+ * -----------------------------------------------------------------------------------------------*/
238
+
239
+ const DESCRIPTION_NAME = 'AlertDialogDescription'
240
+
241
+ type AlertDialogDescriptionProps = ScopedProps<DialogDescriptionProps>
242
+
243
+ const AlertDialogDescriptionFrame = styled(View, {
244
+ name: DESCRIPTION_NAME,
245
+ })
246
+
247
+ const AlertDialogDescription =
248
+ AlertDialogDescriptionFrame.styleable<AlertDialogDescriptionProps>(
249
+ function AlertDialogDescription(props, forwardedRef) {
250
+ const { scope, ...descriptionProps } = props
251
+ return (
252
+ <DialogDescription
253
+ scope={getAlertDialogScope(scope)}
254
+ {...descriptionProps}
255
+ ref={forwardedRef}
256
+ />
257
+ )
258
+ }
259
+ )
260
+
261
+ /* -------------------------------------------------------------------------------------------------
262
+ * AlertDialogAction
263
+ * -----------------------------------------------------------------------------------------------*/
264
+
265
+ const ACTION_NAME = 'AlertDialogAction'
266
+
267
+ type AlertDialogActionProps = ScopedProps<DialogCloseProps>
268
+
269
+ const AlertDialogActionFrame = styled(View, {
270
+ name: ACTION_NAME,
271
+ })
272
+
273
+ const AlertDialogAction = AlertDialogActionFrame.styleable<AlertDialogActionProps>(
274
+ function AlertDialogAction(props, forwardedRef) {
275
+ const { scope, ...actionProps } = props
276
+ return (
277
+ <DialogClose
278
+ scope={getAlertDialogScope(scope)}
279
+ {...actionProps}
280
+ ref={forwardedRef}
281
+ />
282
+ )
283
+ }
284
+ )
285
+
286
+ /* -------------------------------------------------------------------------------------------------
287
+ * AlertDialogCancel
288
+ * -----------------------------------------------------------------------------------------------*/
289
+
290
+ const CANCEL_NAME = 'AlertDialogCancel'
291
+
292
+ type AlertDialogCancelProps = ScopedProps<DialogCloseProps>
293
+
294
+ const AlertDialogCancelFrame = styled(View, {
295
+ name: CANCEL_NAME,
296
+ })
297
+
298
+ const AlertDialogCancel = AlertDialogCancelFrame.styleable<AlertDialogCancelProps>(
299
+ function AlertDialogCancel(props, forwardedRef) {
300
+ const { scope, ...cancelProps } = props
301
+ const { cancelRef } = useAlertDialogContentContext(scope)
302
+ const ref = useComposedRefs(forwardedRef, cancelRef)
303
+ return <DialogClose scope={getAlertDialogScope(scope)} {...cancelProps} ref={ref} />
304
+ }
305
+ )
306
+
307
+ /* -------------------------------------------------------------------------------------------------
308
+ * AlertDialogDestructive
309
+ * -----------------------------------------------------------------------------------------------*/
310
+
311
+ const DESTRUCTIVE_NAME = 'AlertDialogDestructive'
312
+
313
+ type AlertDialogDestructiveProps = ScopedProps<DialogCloseProps>
314
+
315
+ const AlertDialogDestructiveFrame = styled(View, {
316
+ name: DESTRUCTIVE_NAME,
317
+ })
318
+
319
+ const AlertDialogDestructive =
320
+ AlertDialogDestructiveFrame.styleable<AlertDialogDestructiveProps>(
321
+ function AlertDialogDestructive(props, forwardedRef) {
322
+ const { scope, ...destructiveProps } = props
323
+ const { destructiveRef } = useAlertDialogContentContext(scope)
324
+ const ref = useComposedRefs(forwardedRef, destructiveRef)
325
+ return (
326
+ <DialogClose scope={getAlertDialogScope(scope)} {...destructiveProps} ref={ref} />
327
+ )
328
+ }
329
+ )
330
+
331
+ /* ---------------------------------------------------------------------------------------------- */
332
+
333
+ type DescriptionWarningProps = {
334
+ contentRef: React.RefObject<GuiElement | null>
335
+ }
336
+
337
+ const DescriptionWarning: React.FC<DescriptionWarningProps> = ({ contentRef }) => {
338
+ if (process.env.NODE_ENV === 'development') {
339
+ React.useEffect(() => {
340
+ if (!isWeb) return
341
+ const hasDescription = document.getElementById(
342
+ // @ts-ignore
343
+ contentRef.current?.getAttribute('aria-describedby')
344
+ )
345
+ if (!hasDescription) {
346
+ console.warn(`\`${CONTENT_NAME}\` requires a description for the component to be accessible for screen reader users.
347
+
348
+ You 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.
349
+
350
+ Alternatively, 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.
351
+
352
+ For more information, see https://gui.dev/docs/components/alert-dialog`)
353
+ }
354
+ }, [contentRef])
355
+ }
356
+
357
+ return null
358
+ }
359
+
360
+ const AlertDialogInner: React.FC<AlertDialogProps> = (props) => {
361
+ const { scope, native, ...alertDialogProps } = props
362
+ const dialogScope = getAlertDialogScope(scope)
363
+
364
+ if (process.env.HANZO_GUI_TARGET === 'native') {
365
+ const [open, setOpen] = useControllableState({
366
+ prop: props.open,
367
+ defaultProp: props.defaultOpen || false,
368
+ onChange: props.onOpenChange,
369
+ transition: true,
370
+ })
371
+
372
+ let triggerElement: any = null
373
+ let title = ''
374
+ let description = ''
375
+ const buttons: {
376
+ text: string
377
+ onPress: (value?: string | undefined) => void
378
+ style?: 'default' | 'cancel' | 'destructive'
379
+ }[] = []
380
+
381
+ forEachChildDeep(React.Children.toArray(props.children), (child) => {
382
+ if (!React.isValidElement(child)) return false
383
+ const name = isGuiElement(child)
384
+ ? child.type.staticConfig.componentName
385
+ : (child.type['displayName'] as string | undefined)
386
+ switch (name) {
387
+ case TRIGGER_NAME: {
388
+ triggerElement = React.cloneElement(child as any, {
389
+ __native: true,
390
+ })
391
+ return false
392
+ }
393
+ case TITLE_NAME: {
394
+ title = getStringChildren(child)
395
+ return false
396
+ }
397
+ case DESCRIPTION_NAME: {
398
+ description = getStringChildren(child)
399
+ return false
400
+ }
401
+ case ACTION_NAME:
402
+ case DESTRUCTIVE_NAME:
403
+ case CANCEL_NAME: {
404
+ const style =
405
+ name === ACTION_NAME
406
+ ? 'default'
407
+ : name === DESTRUCTIVE_NAME
408
+ ? 'destructive'
409
+ : 'cancel'
410
+ const text = getStringChildren(child)
411
+ const onPress = () => {
412
+ const childProps = child.props as any
413
+ childProps?.onPress?.({ native: true })
414
+ setOpen(false)
415
+ }
416
+ buttons.push({
417
+ style,
418
+ text,
419
+ // @ts-ignore
420
+ onPress,
421
+ })
422
+ return false
423
+ }
424
+ default: {
425
+ return true
426
+ }
427
+ }
428
+ })
429
+
430
+ useIsomorphicLayoutEffect(() => {
431
+ if (!open || !native) return
432
+ if (title || description) {
433
+ Alert.alert(title, description, buttons)
434
+ }
435
+ }, [native, open])
436
+
437
+ if (native) {
438
+ return React.cloneElement(triggerElement, {
439
+ __onPress: () => {
440
+ setOpen(true)
441
+ },
442
+ })
443
+ }
444
+ }
445
+
446
+ return <Dialog scope={dialogScope} {...alertDialogProps} modal />
447
+ }
448
+
449
+ function forEachChildDeep(
450
+ children: React.ReactNode[],
451
+ onChild: (el: React.ReactElement) => boolean
452
+ ) {
453
+ for (const child of children) {
454
+ if (!React.isValidElement(child)) continue
455
+ if (!onChild(child)) continue
456
+ // TODO react 19 doesn't like child.props
457
+ const childProps = child.props as unknown as any
458
+ if (childProps.children) {
459
+ forEachChildDeep(React.Children.toArray(childProps.children), onChild)
460
+ }
461
+ }
462
+ }
463
+
464
+ function getStringChildren(child: React.ReactElement) {
465
+ let string = ''
466
+ forEachChildDeep(React.Children.toArray(child), (child) => {
467
+ if (typeof (child.props as Record<string, any>).children === 'string') {
468
+ string = (child.props as Record<string, any>).children
469
+ return false
470
+ }
471
+ return true
472
+ })
473
+ return string
474
+ }
475
+
476
+ const AlertDialog = withStaticProperties(AlertDialogInner, {
477
+ Trigger: AlertDialogTrigger,
478
+ Portal: AlertDialogPortal,
479
+ Overlay: AlertDialogOverlay,
480
+ Content: AlertDialogContent,
481
+ Action: AlertDialogAction,
482
+ Cancel: AlertDialogCancel,
483
+ Destructive: AlertDialogDestructive,
484
+ Title: AlertDialogTitle,
485
+ Description: AlertDialogDescription,
486
+ })
487
+
488
+ AlertDialog.displayName = ROOT_NAME
489
+
490
+ export {
491
+ //
492
+ AlertDialog,
493
+ AlertDialogAction,
494
+ AlertDialogCancel,
495
+ AlertDialogDestructive,
496
+ AlertDialogContent,
497
+ AlertDialogDescription,
498
+ AlertDialogOverlay,
499
+ AlertDialogPortal,
500
+ AlertDialogTitle,
501
+ AlertDialogTrigger,
502
+ }
503
+
504
+ export type {
505
+ AlertDialogActionProps,
506
+ AlertDialogCancelProps,
507
+ AlertDialogDestructiveProps,
508
+ AlertDialogContentProps,
509
+ AlertDialogDescriptionProps,
510
+ AlertDialogOverlayProps,
511
+ AlertDialogPortalProps,
512
+ AlertDialogProps,
513
+ AlertDialogTitleProps,
514
+ AlertDialogTriggerProps,
515
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './AlertDialog'