@tamagui/alert-dialog 1.0.1-beta.104
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/LICENSE +21 -0
- package/dist/cjs/AlertDialog.js +219 -0
- package/dist/cjs/AlertDialog.js.map +7 -0
- package/dist/cjs/Dialog.js +523 -0
- package/dist/cjs/Dialog.js.map +7 -0
- package/dist/cjs/index.js +18 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/esm/AlertDialog.js +202 -0
- package/dist/esm/AlertDialog.js.map +7 -0
- package/dist/esm/Dialog.js +498 -0
- package/dist/esm/Dialog.js.map +7 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +7 -0
- package/dist/jsx/AlertDialog.js +144 -0
- package/dist/jsx/AlertDialog.js.map +7 -0
- package/dist/jsx/Dialog.js +355 -0
- package/dist/jsx/Dialog.js.map +7 -0
- package/dist/jsx/index.js +2 -0
- package/dist/jsx/index.js.map +7 -0
- package/package.json +56 -0
- package/src/AlertDialog.tsx +313 -0
- package/src/index.ts +1 -0
- package/types/AlertDialog.d.ts +1378 -0
- package/types/AlertDialog.d.ts.map +1 -0
- package/types/index.d.ts +2 -0
- package/types/index.d.ts.map +1 -0
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tamagui/alert-dialog",
|
|
3
|
+
"version": "1.0.1-beta.104",
|
|
4
|
+
"source": "src/index.ts",
|
|
5
|
+
"types": "./types/index.d.ts",
|
|
6
|
+
"main": "dist/cjs",
|
|
7
|
+
"module": "dist/esm",
|
|
8
|
+
"module:jsx": "dist/jsx",
|
|
9
|
+
"sideEffects": [
|
|
10
|
+
"*.css"
|
|
11
|
+
],
|
|
12
|
+
"files": [
|
|
13
|
+
"src",
|
|
14
|
+
"types",
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tamagui-build",
|
|
19
|
+
"watch": "tamagui-build --watch",
|
|
20
|
+
"clean": "tamagui-build clean",
|
|
21
|
+
"clean:build": "tamagui-build clean:build"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@tamagui/animate-presence": "^1.0.1-beta.104",
|
|
25
|
+
"@tamagui/compose-refs": "^1.0.1-beta.104",
|
|
26
|
+
"@tamagui/core": "^1.0.1-beta.104",
|
|
27
|
+
"@tamagui/create-context": "^1.0.1-beta.104",
|
|
28
|
+
"@tamagui/dialog": "^1.0.1-beta.104",
|
|
29
|
+
"@tamagui/dismissable": "^1.0.1-beta.104",
|
|
30
|
+
"@tamagui/focus-scope": "^1.0.1-beta.104",
|
|
31
|
+
"@tamagui/polyfill-dev": "^1.0.1-beta.104",
|
|
32
|
+
"@tamagui/popper": "^1.0.1-beta.104",
|
|
33
|
+
"@tamagui/portal": "^1.0.1-beta.104",
|
|
34
|
+
"@tamagui/stacks": "^1.0.1-beta.104",
|
|
35
|
+
"@tamagui/text": "^1.0.1-beta.104",
|
|
36
|
+
"@tamagui/use-controllable-state": "^1.0.1-beta.104",
|
|
37
|
+
"aria-hidden": "^1.1.3",
|
|
38
|
+
"react-remove-scroll": "^2.5.5"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"react": "*",
|
|
42
|
+
"react-dom": "*",
|
|
43
|
+
"react-native": "*"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@tamagui/build": "^1.0.1-beta.104",
|
|
47
|
+
"@types/react-dom": "^18.0.3",
|
|
48
|
+
"@types/react-native": "^0.69.2",
|
|
49
|
+
"react": "*",
|
|
50
|
+
"react-dom": "*",
|
|
51
|
+
"react-native": "*"
|
|
52
|
+
},
|
|
53
|
+
"publishConfig": {
|
|
54
|
+
"access": "public"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,313 @@
|
|
|
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 '@tamagui/compose-refs'
|
|
5
|
+
import {
|
|
6
|
+
Slottable,
|
|
7
|
+
TamaguiElement,
|
|
8
|
+
composeEventHandlers,
|
|
9
|
+
isWeb,
|
|
10
|
+
withStaticProperties,
|
|
11
|
+
} from '@tamagui/core'
|
|
12
|
+
import { Scope, createContextScope } from '@tamagui/create-context'
|
|
13
|
+
import {
|
|
14
|
+
Dialog,
|
|
15
|
+
DialogClose,
|
|
16
|
+
DialogCloseProps,
|
|
17
|
+
DialogContent,
|
|
18
|
+
DialogContentProps,
|
|
19
|
+
DialogDescription,
|
|
20
|
+
DialogDescriptionProps,
|
|
21
|
+
DialogOverlay,
|
|
22
|
+
DialogOverlayProps,
|
|
23
|
+
DialogPortal,
|
|
24
|
+
DialogPortalProps,
|
|
25
|
+
DialogProps,
|
|
26
|
+
DialogTitle,
|
|
27
|
+
DialogTitleProps,
|
|
28
|
+
DialogTrigger,
|
|
29
|
+
DialogTriggerProps,
|
|
30
|
+
DialogWarningProvider,
|
|
31
|
+
createDialogScope,
|
|
32
|
+
} from '@tamagui/dialog'
|
|
33
|
+
import * as React from 'react'
|
|
34
|
+
|
|
35
|
+
const ROOT_NAME = 'AlertDialog'
|
|
36
|
+
|
|
37
|
+
type ScopedProps<P> = P & { __scopeAlertDialog?: Scope }
|
|
38
|
+
const [createAlertDialogContext, createAlertDialogScope] = createContextScope(ROOT_NAME, [
|
|
39
|
+
createDialogScope,
|
|
40
|
+
])
|
|
41
|
+
|
|
42
|
+
const useDialogScope = createDialogScope()
|
|
43
|
+
|
|
44
|
+
interface AlertDialogProps extends Omit<DialogProps, 'modal'> {}
|
|
45
|
+
|
|
46
|
+
/* -------------------------------------------------------------------------------------------------
|
|
47
|
+
* AlertDialogTrigger
|
|
48
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
49
|
+
const TRIGGER_NAME = 'AlertDialogTrigger'
|
|
50
|
+
|
|
51
|
+
interface AlertDialogTriggerProps extends DialogTriggerProps {}
|
|
52
|
+
|
|
53
|
+
const AlertDialogTrigger = React.forwardRef<TamaguiElement, AlertDialogTriggerProps>(
|
|
54
|
+
(props: ScopedProps<AlertDialogTriggerProps>, forwardedRef) => {
|
|
55
|
+
const { __scopeAlertDialog, ...triggerProps } = props
|
|
56
|
+
const dialogScope = useDialogScope(__scopeAlertDialog)
|
|
57
|
+
return <DialogTrigger {...dialogScope} {...triggerProps} ref={forwardedRef} />
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
AlertDialogTrigger.displayName = TRIGGER_NAME
|
|
62
|
+
|
|
63
|
+
/* -------------------------------------------------------------------------------------------------
|
|
64
|
+
* AlertDialogPortal
|
|
65
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
66
|
+
|
|
67
|
+
const PORTAL_NAME = 'AlertDialogPortal'
|
|
68
|
+
|
|
69
|
+
interface AlertDialogPortalProps extends DialogPortalProps {}
|
|
70
|
+
|
|
71
|
+
const AlertDialogPortal: React.FC<AlertDialogPortalProps> = (
|
|
72
|
+
props: ScopedProps<AlertDialogPortalProps>
|
|
73
|
+
) => {
|
|
74
|
+
const { __scopeAlertDialog, ...portalProps } = props
|
|
75
|
+
const dialogScope = useDialogScope(__scopeAlertDialog)
|
|
76
|
+
return <DialogPortal {...dialogScope} {...portalProps} />
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
AlertDialogPortal.displayName = PORTAL_NAME
|
|
80
|
+
|
|
81
|
+
/* -------------------------------------------------------------------------------------------------
|
|
82
|
+
* AlertDialogOverlay
|
|
83
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
84
|
+
|
|
85
|
+
const OVERLAY_NAME = 'AlertDialogOverlay'
|
|
86
|
+
|
|
87
|
+
interface AlertDialogOverlayProps extends DialogOverlayProps {}
|
|
88
|
+
|
|
89
|
+
const AlertDialogOverlay = React.forwardRef<TamaguiElement, AlertDialogOverlayProps>(
|
|
90
|
+
(props: ScopedProps<AlertDialogOverlayProps>, forwardedRef) => {
|
|
91
|
+
const { __scopeAlertDialog, ...overlayProps } = props
|
|
92
|
+
const dialogScope = useDialogScope(__scopeAlertDialog)
|
|
93
|
+
return <DialogOverlay {...dialogScope} {...overlayProps} ref={forwardedRef} />
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
AlertDialogOverlay.displayName = OVERLAY_NAME
|
|
98
|
+
|
|
99
|
+
/* -------------------------------------------------------------------------------------------------
|
|
100
|
+
* AlertDialogContent
|
|
101
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
102
|
+
|
|
103
|
+
const CONTENT_NAME = 'AlertDialogContent'
|
|
104
|
+
|
|
105
|
+
type AlertDialogContentContextValue = {
|
|
106
|
+
cancelRef: React.MutableRefObject<TamaguiElement | null>
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const [AlertDialogContentProvider, useAlertDialogContentContext] =
|
|
110
|
+
createAlertDialogContext<AlertDialogContentContextValue>(CONTENT_NAME)
|
|
111
|
+
|
|
112
|
+
interface AlertDialogContentProps
|
|
113
|
+
extends Omit<DialogContentProps, 'onPointerDownOutside' | 'onInteractOutside'> {}
|
|
114
|
+
|
|
115
|
+
const AlertDialogContent = React.forwardRef<TamaguiElement, AlertDialogContentProps>(
|
|
116
|
+
(props: ScopedProps<AlertDialogContentProps>, forwardedRef) => {
|
|
117
|
+
const { __scopeAlertDialog, children, ...contentProps } = props
|
|
118
|
+
const dialogScope = useDialogScope(__scopeAlertDialog)
|
|
119
|
+
const contentRef = React.useRef<TamaguiElement>(null)
|
|
120
|
+
const composedRefs = useComposedRefs(forwardedRef, contentRef)
|
|
121
|
+
const cancelRef = React.useRef<TamaguiElement | null>(null)
|
|
122
|
+
|
|
123
|
+
return (
|
|
124
|
+
<DialogWarningProvider
|
|
125
|
+
contentName={CONTENT_NAME}
|
|
126
|
+
titleName={TITLE_NAME}
|
|
127
|
+
docsSlug="alert-dialog"
|
|
128
|
+
>
|
|
129
|
+
<AlertDialogContentProvider scope={__scopeAlertDialog} cancelRef={cancelRef}>
|
|
130
|
+
<DialogContent
|
|
131
|
+
// @ts-ignore
|
|
132
|
+
role="alertdialog"
|
|
133
|
+
{...dialogScope}
|
|
134
|
+
{...contentProps}
|
|
135
|
+
ref={composedRefs}
|
|
136
|
+
onOpenAutoFocus={composeEventHandlers(contentProps.onOpenAutoFocus, (event) => {
|
|
137
|
+
event.preventDefault()
|
|
138
|
+
if (isWeb) {
|
|
139
|
+
// @ts-ignore
|
|
140
|
+
cancelRef.current?.focus({ preventScroll: true })
|
|
141
|
+
}
|
|
142
|
+
})}
|
|
143
|
+
onPointerDownOutside={(event) => event.preventDefault()}
|
|
144
|
+
onInteractOutside={(event) => event.preventDefault()}
|
|
145
|
+
>
|
|
146
|
+
{/**
|
|
147
|
+
* We have to use `Slottable` here as we cannot wrap the `AlertDialogContentProvider`
|
|
148
|
+
* around everything, otherwise the `DescriptionWarning` would be rendered straight away.
|
|
149
|
+
* This is because we want the accessibility checks to run only once the content is actually
|
|
150
|
+
* open and that behaviour is already encapsulated in `DialogContent`.
|
|
151
|
+
*/}
|
|
152
|
+
<Slottable>{children}</Slottable>
|
|
153
|
+
{process.env.NODE_ENV === 'development' && (
|
|
154
|
+
<DescriptionWarning contentRef={contentRef} />
|
|
155
|
+
)}
|
|
156
|
+
</DialogContent>
|
|
157
|
+
</AlertDialogContentProvider>
|
|
158
|
+
</DialogWarningProvider>
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
AlertDialogContent.displayName = CONTENT_NAME
|
|
164
|
+
|
|
165
|
+
/* -------------------------------------------------------------------------------------------------
|
|
166
|
+
* AlertDialogTitle
|
|
167
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
168
|
+
|
|
169
|
+
const TITLE_NAME = 'AlertDialogTitle'
|
|
170
|
+
|
|
171
|
+
type AlertDialogTitleProps = DialogTitleProps
|
|
172
|
+
|
|
173
|
+
const AlertDialogTitle = React.forwardRef<TamaguiElement, AlertDialogTitleProps>(
|
|
174
|
+
(props: ScopedProps<AlertDialogTitleProps>, forwardedRef) => {
|
|
175
|
+
const { __scopeAlertDialog, ...titleProps } = props
|
|
176
|
+
const dialogScope = useDialogScope(__scopeAlertDialog)
|
|
177
|
+
return <DialogTitle {...dialogScope} {...titleProps} ref={forwardedRef} />
|
|
178
|
+
}
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
AlertDialogTitle.displayName = TITLE_NAME
|
|
182
|
+
|
|
183
|
+
/* -------------------------------------------------------------------------------------------------
|
|
184
|
+
* AlertDialogDescription
|
|
185
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
186
|
+
|
|
187
|
+
const DESCRIPTION_NAME = 'AlertDialogDescription'
|
|
188
|
+
|
|
189
|
+
type AlertDialogDescriptionProps = DialogDescriptionProps
|
|
190
|
+
|
|
191
|
+
const AlertDialogDescription = React.forwardRef<TamaguiElement, AlertDialogDescriptionProps>(
|
|
192
|
+
(props: ScopedProps<AlertDialogDescriptionProps>, forwardedRef) => {
|
|
193
|
+
const { __scopeAlertDialog, ...descriptionProps } = props
|
|
194
|
+
const dialogScope = useDialogScope(__scopeAlertDialog)
|
|
195
|
+
return <DialogDescription {...dialogScope} {...descriptionProps} ref={forwardedRef} />
|
|
196
|
+
}
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
AlertDialogDescription.displayName = DESCRIPTION_NAME
|
|
200
|
+
|
|
201
|
+
/* -------------------------------------------------------------------------------------------------
|
|
202
|
+
* AlertDialogAction
|
|
203
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
204
|
+
|
|
205
|
+
const ACTION_NAME = 'AlertDialogAction'
|
|
206
|
+
|
|
207
|
+
type AlertDialogActionProps = DialogCloseProps
|
|
208
|
+
|
|
209
|
+
const AlertDialogAction = React.forwardRef<TamaguiElement, AlertDialogActionProps>(
|
|
210
|
+
(props: ScopedProps<AlertDialogActionProps>, forwardedRef) => {
|
|
211
|
+
const { __scopeAlertDialog, ...actionProps } = props
|
|
212
|
+
const dialogScope = useDialogScope(__scopeAlertDialog)
|
|
213
|
+
return <DialogClose {...dialogScope} {...actionProps} ref={forwardedRef} />
|
|
214
|
+
}
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
AlertDialogAction.displayName = ACTION_NAME
|
|
218
|
+
|
|
219
|
+
/* -------------------------------------------------------------------------------------------------
|
|
220
|
+
* AlertDialogCancel
|
|
221
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
222
|
+
|
|
223
|
+
const CANCEL_NAME = 'AlertDialogCancel'
|
|
224
|
+
|
|
225
|
+
interface AlertDialogCancelProps extends DialogCloseProps {}
|
|
226
|
+
|
|
227
|
+
const AlertDialogCancel = React.forwardRef<TamaguiElement, AlertDialogCancelProps>(
|
|
228
|
+
(props: ScopedProps<AlertDialogCancelProps>, forwardedRef) => {
|
|
229
|
+
const { __scopeAlertDialog, ...cancelProps } = props
|
|
230
|
+
const { cancelRef } = useAlertDialogContentContext(CANCEL_NAME, __scopeAlertDialog)
|
|
231
|
+
const dialogScope = useDialogScope(__scopeAlertDialog)
|
|
232
|
+
const ref = useComposedRefs(forwardedRef, cancelRef)
|
|
233
|
+
return <DialogClose {...dialogScope} {...cancelProps} ref={ref} />
|
|
234
|
+
}
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
AlertDialogCancel.displayName = CANCEL_NAME
|
|
238
|
+
|
|
239
|
+
/* ---------------------------------------------------------------------------------------------- */
|
|
240
|
+
|
|
241
|
+
type DescriptionWarningProps = {
|
|
242
|
+
contentRef: React.RefObject<TamaguiElement>
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const DescriptionWarning: React.FC<DescriptionWarningProps> = ({ contentRef }) => {
|
|
246
|
+
const MESSAGE = `\`${CONTENT_NAME}\` requires a description for the component to be accessible for screen reader users.
|
|
247
|
+
|
|
248
|
+
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.
|
|
249
|
+
|
|
250
|
+
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.
|
|
251
|
+
|
|
252
|
+
For more information, see https://tamagui.dev/docs/components/alert-dialog`
|
|
253
|
+
|
|
254
|
+
React.useEffect(() => {
|
|
255
|
+
if (!isWeb) return
|
|
256
|
+
const hasDescription = document.getElementById(
|
|
257
|
+
// @ts-ignore
|
|
258
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
|
|
259
|
+
contentRef.current?.getAttribute('aria-describedby')!
|
|
260
|
+
)
|
|
261
|
+
if (!hasDescription) console.warn(MESSAGE)
|
|
262
|
+
}, [MESSAGE, contentRef])
|
|
263
|
+
|
|
264
|
+
return null
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/* -------------------------------------------------------------------------------------------------
|
|
268
|
+
* AlertDialog
|
|
269
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
270
|
+
|
|
271
|
+
const AlertDialogInner: React.FC<AlertDialogProps> = (props: ScopedProps<AlertDialogProps>) => {
|
|
272
|
+
const { __scopeAlertDialog, ...alertDialogProps } = props
|
|
273
|
+
const dialogScope = useDialogScope(__scopeAlertDialog)
|
|
274
|
+
return <Dialog {...dialogScope} {...alertDialogProps} modal={true} />
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const AlertDialog = withStaticProperties(AlertDialogInner, {
|
|
278
|
+
Trigger: AlertDialogTrigger,
|
|
279
|
+
Portal: AlertDialogPortal,
|
|
280
|
+
Overlay: AlertDialogOverlay,
|
|
281
|
+
Content: AlertDialogContent,
|
|
282
|
+
Action: AlertDialogAction,
|
|
283
|
+
Cancel: AlertDialogCancel,
|
|
284
|
+
Title: AlertDialogTitle,
|
|
285
|
+
Description: AlertDialogDescription,
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
AlertDialog.displayName = ROOT_NAME
|
|
289
|
+
|
|
290
|
+
export {
|
|
291
|
+
createAlertDialogScope,
|
|
292
|
+
//
|
|
293
|
+
AlertDialog,
|
|
294
|
+
AlertDialogTrigger,
|
|
295
|
+
AlertDialogPortal,
|
|
296
|
+
AlertDialogOverlay,
|
|
297
|
+
AlertDialogContent,
|
|
298
|
+
AlertDialogAction,
|
|
299
|
+
AlertDialogCancel,
|
|
300
|
+
AlertDialogTitle,
|
|
301
|
+
AlertDialogDescription,
|
|
302
|
+
}
|
|
303
|
+
export type {
|
|
304
|
+
AlertDialogProps,
|
|
305
|
+
AlertDialogTriggerProps,
|
|
306
|
+
AlertDialogPortalProps,
|
|
307
|
+
AlertDialogOverlayProps,
|
|
308
|
+
AlertDialogContentProps,
|
|
309
|
+
AlertDialogActionProps,
|
|
310
|
+
AlertDialogCancelProps,
|
|
311
|
+
AlertDialogTitleProps,
|
|
312
|
+
AlertDialogDescriptionProps,
|
|
313
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './AlertDialog'
|