-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathconfirm-context.tsx
91 lines (80 loc) · 2.34 KB
/
confirm-context.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
'use client'
import {
Button,
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogModal,
DialogModalOverlay,
DialogTitle,
} from '@stacklok/ui-kit'
import type { ReactNode } from 'react'
import { createContext, useState } from 'react'
type Buttons = {
yes: ReactNode
no: ReactNode
}
type Config = {
buttons: Buttons
title?: ReactNode
isDestructive?: boolean
}
type Question = {
message: ReactNode
config: Config
resolve: (value: boolean) => void
}
type ConfirmContextType = {
confirm: (message: ReactNode, config: Config) => Promise<boolean>
}
export const ConfirmContext = createContext<ConfirmContextType | null>(null)
export function ConfirmProvider({ children }: { children: ReactNode }) {
const [activeQuestion, setActiveQuestion] = useState<Question | null>(null)
const [isOpen, setIsOpen] = useState<boolean>(false)
const handleAnswer = (answer: boolean) => {
if (activeQuestion === null) return
activeQuestion.resolve(answer)
setIsOpen(false)
}
const confirm = (message: ReactNode, config: Config) => {
return new Promise<boolean>((resolve) => {
setActiveQuestion({ message, config, resolve })
setIsOpen(true)
})
}
return (
<ConfirmContext.Provider value={{ confirm }}>
{children}
<DialogModalOverlay
isDismissable
isOpen={isOpen}
onOpenChange={setIsOpen}
>
<DialogModal isDismissable>
<Dialog>
<DialogHeader>
<DialogTitle>{activeQuestion?.config.title}</DialogTitle>
</DialogHeader>
<DialogContent>{activeQuestion?.message}</DialogContent>
<DialogFooter>
<div className="flex grow justify-end gap-2">
<Button variant="secondary" onPress={() => handleAnswer(false)}>
{activeQuestion?.config.buttons.no ?? ' '}
</Button>
<Button
autoFocus
isDestructive={activeQuestion?.config.isDestructive}
variant="primary"
onPress={() => handleAnswer(true)}
>
{activeQuestion?.config.buttons.yes ?? ' '}
</Button>
</div>
</DialogFooter>
</Dialog>
</DialogModal>
</DialogModalOverlay>
</ConfirmContext.Provider>
)
}