@cerberus-design/react 0.14.2 → 0.15.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.
- package/build/legacy/_tsup-dts-rollup.d.cts +374 -80
- package/build/legacy/components/Accordion.cjs +4 -187
- package/build/legacy/components/Accordion.cjs.map +1 -1
- package/build/legacy/components/Accordion.client.cjs +64 -0
- package/build/legacy/components/Accordion.client.cjs.map +1 -0
- package/build/legacy/components/AccordionItemGroup.cjs +41 -185
- package/build/legacy/components/AccordionItemGroup.cjs.map +1 -1
- package/build/legacy/components/Admonition.cjs +89 -239
- package/build/legacy/components/Admonition.cjs.map +1 -1
- package/build/legacy/components/Admonition.client.cjs +219 -0
- package/build/legacy/components/Admonition.client.cjs.map +1 -0
- package/build/legacy/components/AnimatingUploadIcon.cjs.map +1 -1
- package/build/legacy/components/Avatar.cjs +23 -174
- package/build/legacy/components/Avatar.cjs.map +1 -1
- package/build/legacy/components/Checkbox.cjs +22 -168
- package/build/legacy/components/Checkbox.cjs.map +1 -1
- package/build/legacy/components/DatePicker.client.cjs +129 -272
- package/build/legacy/components/DatePicker.client.cjs.map +1 -1
- package/build/legacy/components/DatePicker.server.cjs +17 -271
- package/build/legacy/components/DatePicker.server.cjs.map +1 -1
- package/build/legacy/components/Dialog.cjs +86 -0
- package/build/legacy/components/Dialog.cjs.map +1 -0
- package/build/legacy/components/Dialog.client.cjs +95 -0
- package/build/legacy/components/Dialog.client.cjs.map +1 -0
- package/build/legacy/components/FileStatus.cjs +62 -212
- package/build/legacy/components/FileStatus.cjs.map +1 -1
- package/build/legacy/components/FileUploader.cjs +29 -180
- package/build/legacy/components/FileUploader.cjs.map +1 -1
- package/build/legacy/components/Input.cjs +20 -172
- package/build/legacy/components/Input.cjs.map +1 -1
- package/build/legacy/components/Modal.cjs.map +1 -1
- package/build/legacy/components/ModalDescription.cjs.map +1 -1
- package/build/legacy/components/ModalHeader.cjs.map +1 -1
- package/build/legacy/components/ModalHeading.cjs.map +1 -1
- package/build/legacy/components/Notification.cjs +26 -176
- package/build/legacy/components/Notification.cjs.map +1 -1
- package/build/legacy/components/Select.cjs +26 -178
- package/build/legacy/components/Select.cjs.map +1 -1
- package/build/legacy/components/Tag.cjs +16 -167
- package/build/legacy/components/Tag.cjs.map +1 -1
- package/build/legacy/components/Toggle.cjs +20 -172
- package/build/legacy/components/Toggle.cjs.map +1 -1
- package/build/legacy/config/defineIcons.cjs +3 -39
- package/build/legacy/config/defineIcons.cjs.map +1 -1
- package/build/legacy/config/{cerbIcons.cjs → index.cjs} +22 -29
- package/build/legacy/config/index.cjs.map +1 -0
- package/build/legacy/config/types.cjs +19 -0
- package/build/legacy/config/types.cjs.map +1 -0
- package/build/legacy/context/cerberus.cjs +46 -0
- package/build/legacy/context/cerberus.cjs.map +1 -0
- package/build/legacy/context/confirm-modal.cjs +105 -321
- package/build/legacy/context/confirm-modal.cjs.map +1 -1
- package/build/legacy/context/cta-modal.cjs +137 -336
- package/build/legacy/context/cta-modal.cjs.map +1 -1
- package/build/legacy/context/notification-center/store.cjs +66 -0
- package/build/legacy/context/notification-center/store.cjs.map +1 -0
- package/build/legacy/context/notification-center/types.cjs +19 -0
- package/build/legacy/context/notification-center/types.cjs.map +1 -0
- package/build/legacy/context/notification-center.cjs +142 -249
- package/build/legacy/context/notification-center.cjs.map +1 -1
- package/build/legacy/context/prompt-modal.cjs +185 -388
- package/build/legacy/context/prompt-modal.cjs.map +1 -1
- package/build/legacy/index.cjs +1577 -1456
- package/build/legacy/index.cjs.map +1 -1
- package/build/modern/_tsup-dts-rollup.d.ts +374 -80
- package/build/modern/{chunk-BVCXVZAF.js → chunk-25HMVHLT.js} +6 -5
- package/build/modern/chunk-25HMVHLT.js.map +1 -0
- package/build/modern/chunk-36N4527B.js +1 -0
- package/build/modern/chunk-5EWCH7AI.js +82 -0
- package/build/modern/chunk-5EWCH7AI.js.map +1 -0
- package/build/modern/chunk-5SNLQZYP.js +25 -0
- package/build/modern/chunk-5SNLQZYP.js.map +1 -0
- package/build/modern/chunk-6BN3XKQF.js +42 -0
- package/build/modern/chunk-6BN3XKQF.js.map +1 -0
- package/build/modern/{chunk-2UXE5PDG.js → chunk-7NN3SJ7W.js} +1 -1
- package/build/modern/chunk-7NN3SJ7W.js.map +1 -0
- package/build/modern/{chunk-KWJ5FKX7.js → chunk-BAWZBF5Q.js} +5 -3
- package/build/modern/chunk-BAWZBF5Q.js.map +1 -0
- package/build/modern/{chunk-6BH5J5GF.js → chunk-BHB56M7S.js} +31 -46
- package/build/modern/chunk-BHB56M7S.js.map +1 -0
- package/build/modern/{chunk-HKJMLWVP.js → chunk-EDARV2EI.js} +5 -4
- package/build/modern/chunk-EDARV2EI.js.map +1 -0
- package/build/modern/{chunk-5OVH3INN.js → chunk-FGCO27TC.js} +25 -53
- package/build/modern/chunk-FGCO27TC.js.map +1 -0
- package/build/modern/{chunk-PVIMOXSO.js → chunk-GCQMH4QA.js} +5 -4
- package/build/modern/chunk-GCQMH4QA.js.map +1 -0
- package/build/modern/chunk-GITT5645.js +20 -0
- package/build/modern/chunk-GITT5645.js.map +1 -0
- package/build/modern/{chunk-TJCFYL5W.js → chunk-IGHMP4WA.js} +1 -20
- package/build/modern/chunk-IGHMP4WA.js.map +1 -0
- package/build/modern/chunk-ISCJ542I.js +82 -0
- package/build/modern/chunk-ISCJ542I.js.map +1 -0
- package/build/modern/{chunk-HVKM54BA.js → chunk-IW3LIRDG.js} +1 -1
- package/build/modern/chunk-IW3LIRDG.js.map +1 -0
- package/build/modern/chunk-JAROS4Q3.js +180 -0
- package/build/modern/chunk-JAROS4Q3.js.map +1 -0
- package/build/modern/{chunk-BE4EOU2P.js → chunk-JIRW4XOJ.js} +1 -1
- package/build/modern/chunk-JIRW4XOJ.js.map +1 -0
- package/build/modern/chunk-KDDPAJMR.js +9 -0
- package/build/modern/chunk-KDDPAJMR.js.map +1 -0
- package/build/modern/{chunk-XOROL3JY.js → chunk-KKHL3ZO4.js} +5 -4
- package/build/modern/chunk-KKHL3ZO4.js.map +1 -0
- package/build/modern/{chunk-U36UZJGZ.js → chunk-MZ3UCDUL.js} +5 -4
- package/build/modern/chunk-MZ3UCDUL.js.map +1 -0
- package/build/modern/{chunk-T2JOPPGL.js → chunk-N24COMHJ.js} +11 -4
- package/build/modern/chunk-N24COMHJ.js.map +1 -0
- package/build/modern/chunk-NJSETNRL.js +68 -0
- package/build/modern/chunk-NJSETNRL.js.map +1 -0
- package/build/modern/{chunk-XY6WL55R.js → chunk-NUMM4TNC.js} +1 -1
- package/build/modern/chunk-NUMM4TNC.js.map +1 -0
- package/build/modern/{chunk-FXLLRVAM.js → chunk-O6LFWUHI.js} +8 -6
- package/build/modern/chunk-O6LFWUHI.js.map +1 -0
- package/build/modern/{chunk-JJZQGR7A.js → chunk-RDRD6ACD.js} +9 -6
- package/build/modern/chunk-RDRD6ACD.js.map +1 -0
- package/build/modern/{chunk-XXWR7UGH.js → chunk-SD3OVTHT.js} +75 -103
- package/build/modern/chunk-SD3OVTHT.js.map +1 -0
- package/build/modern/chunk-TFL56AYR.js +56 -0
- package/build/modern/chunk-TFL56AYR.js.map +1 -0
- package/build/modern/chunk-V3M3ZOQI.js +38 -0
- package/build/modern/chunk-V3M3ZOQI.js.map +1 -0
- package/build/modern/{chunk-QK7R2XJM.js → chunk-XQICKZH4.js} +6 -5
- package/build/modern/chunk-XQICKZH4.js.map +1 -0
- package/build/modern/chunk-XZGXRRSQ.js +31 -0
- package/build/modern/chunk-XZGXRRSQ.js.map +1 -0
- package/build/modern/{chunk-KPUYKHLW.js → chunk-YKKNWILF.js} +71 -15
- package/build/modern/chunk-YKKNWILF.js.map +1 -0
- package/build/modern/{chunk-Q7BRMIBR.js → chunk-ZL6ZITLA.js} +1 -1
- package/build/modern/chunk-ZL6ZITLA.js.map +1 -0
- package/build/modern/components/Accordion.client.js +9 -0
- package/build/modern/components/Accordion.client.js.map +1 -0
- package/build/modern/components/Accordion.js +1 -7
- package/build/modern/components/AccordionItemGroup.js +4 -6
- package/build/modern/components/Admonition.client.js +11 -0
- package/build/modern/components/Admonition.client.js.map +1 -0
- package/build/modern/components/Admonition.js +4 -6
- package/build/modern/components/AnimatingUploadIcon.js +1 -1
- package/build/modern/components/Avatar.js +3 -5
- package/build/modern/components/Checkbox.js +2 -5
- package/build/modern/components/DatePicker.client.js +8 -7
- package/build/modern/components/DatePicker.server.js +3 -13
- package/build/modern/components/Dialog.client.js +10 -0
- package/build/modern/components/Dialog.client.js.map +1 -0
- package/build/modern/components/Dialog.js +24 -0
- package/build/modern/components/Dialog.js.map +1 -0
- package/build/modern/components/FileStatus.js +3 -6
- package/build/modern/components/FileUploader.js +3 -6
- package/build/modern/components/Input.js +2 -5
- package/build/modern/components/Modal.js +1 -1
- package/build/modern/components/ModalDescription.js +1 -1
- package/build/modern/components/ModalHeader.js +1 -1
- package/build/modern/components/ModalHeading.js +1 -1
- package/build/modern/components/Notification.js +2 -5
- package/build/modern/components/Select.js +2 -5
- package/build/modern/components/Tag.js +3 -5
- package/build/modern/components/Toggle.js +2 -5
- package/build/modern/config/defineIcons.js +2 -5
- package/build/modern/config/index.js +14 -0
- package/build/modern/config/index.js.map +1 -0
- package/build/modern/config/types.js +2 -0
- package/build/modern/config/types.js.map +1 -0
- package/build/modern/context/cerberus.js +10 -0
- package/build/modern/context/cerberus.js.map +1 -0
- package/build/modern/context/confirm-modal.js +5 -13
- package/build/modern/context/cta-modal.js +7 -14
- package/build/modern/context/notification-center/store.js +15 -0
- package/build/modern/context/notification-center/store.js.map +1 -0
- package/build/modern/context/notification-center/types.js +1 -0
- package/build/modern/context/notification-center/types.js.map +1 -0
- package/build/modern/context/notification-center.js +5 -7
- package/build/modern/context/prompt-modal.js +8 -15
- package/build/modern/index.js +111 -75
- package/build/modern/index.js.map +1 -1
- package/package.json +4 -8
- package/src/components/Accordion.client.tsx +46 -0
- package/src/components/Accordion.tsx +0 -37
- package/src/components/AccordionItemGroup.tsx +1 -1
- package/src/components/Admonition.client.tsx +73 -0
- package/src/components/Admonition.tsx +1 -70
- package/src/components/AnimatingUploadIcon.tsx +3 -3
- package/src/components/Avatar.tsx +5 -2
- package/src/components/Checkbox.tsx +10 -3
- package/src/components/DatePicker.client.tsx +111 -15
- package/src/components/DatePicker.server.tsx +2 -75
- package/src/components/Dialog.client.tsx +39 -0
- package/src/components/Dialog.tsx +165 -0
- package/src/components/FileStatus.tsx +5 -3
- package/src/components/FileUploader.tsx +3 -2
- package/src/components/Input.tsx +4 -2
- package/src/components/Modal.tsx +1 -16
- package/src/components/ModalDescription.tsx +1 -8
- package/src/components/ModalHeader.tsx +1 -10
- package/src/components/ModalHeading.tsx +1 -8
- package/src/components/Notification.tsx +9 -4
- package/src/components/Select.tsx +5 -2
- package/src/components/Tag.tsx +5 -2
- package/src/components/Toggle.tsx +4 -3
- package/src/config/defineIcons.ts +28 -16
- package/src/config/index.ts +28 -0
- package/src/config/types.ts +42 -0
- package/src/context/cerberus.tsx +44 -0
- package/src/context/confirm-modal.tsx +44 -42
- package/src/context/cta-modal.tsx +25 -38
- package/src/context/notification-center/store.ts +88 -0
- package/src/context/notification-center/types.ts +28 -0
- package/src/context/notification-center.tsx +81 -46
- package/src/context/prompt-modal.tsx +101 -103
- package/src/index.ts +15 -8
- package/build/legacy/config/cerbIcons.cjs.map +0 -1
- package/build/modern/chunk-2UXE5PDG.js.map +0 -1
- package/build/modern/chunk-5OVH3INN.js.map +0 -1
- package/build/modern/chunk-6BH5J5GF.js.map +0 -1
- package/build/modern/chunk-BC5SZDYY.js +0 -132
- package/build/modern/chunk-BC5SZDYY.js.map +0 -1
- package/build/modern/chunk-BE4EOU2P.js.map +0 -1
- package/build/modern/chunk-BVCXVZAF.js.map +0 -1
- package/build/modern/chunk-CRII2HNX.js +0 -55
- package/build/modern/chunk-CRII2HNX.js.map +0 -1
- package/build/modern/chunk-CVTON5DQ.js +0 -162
- package/build/modern/chunk-CVTON5DQ.js.map +0 -1
- package/build/modern/chunk-FXLLRVAM.js.map +0 -1
- package/build/modern/chunk-HKJMLWVP.js.map +0 -1
- package/build/modern/chunk-HVKM54BA.js.map +0 -1
- package/build/modern/chunk-JJZQGR7A.js.map +0 -1
- package/build/modern/chunk-KPUYKHLW.js.map +0 -1
- package/build/modern/chunk-KWJ5FKX7.js.map +0 -1
- package/build/modern/chunk-PVIMOXSO.js.map +0 -1
- package/build/modern/chunk-Q7BRMIBR.js.map +0 -1
- package/build/modern/chunk-QK7R2XJM.js.map +0 -1
- package/build/modern/chunk-QMF5ZNDG.js +0 -27
- package/build/modern/chunk-QMF5ZNDG.js.map +0 -1
- package/build/modern/chunk-QQOWWMZ3.js +0 -138
- package/build/modern/chunk-QQOWWMZ3.js.map +0 -1
- package/build/modern/chunk-T2JOPPGL.js.map +0 -1
- package/build/modern/chunk-TJCFYL5W.js.map +0 -1
- package/build/modern/chunk-U36UZJGZ.js.map +0 -1
- package/build/modern/chunk-XOROL3JY.js.map +0 -1
- package/build/modern/chunk-XXWR7UGH.js.map +0 -1
- package/build/modern/chunk-XY6WL55R.js.map +0 -1
- package/build/modern/config/cerbIcons.js +0 -9
- package/src/config/cerbIcons.ts +0 -73
- /package/build/modern/{config/cerbIcons.js.map → chunk-36N4527B.js.map} +0 -0
|
@@ -11,20 +11,19 @@ import {
|
|
|
11
11
|
type PropsWithChildren,
|
|
12
12
|
type ReactNode,
|
|
13
13
|
} from 'react'
|
|
14
|
-
import { Portal } from '../components/Portal'
|
|
15
14
|
import { Button } from '../components/Button'
|
|
16
15
|
import { css } from '@cerberus/styled-system/css'
|
|
17
|
-
import { hstack } from '@cerberus/styled-system/patterns'
|
|
18
|
-
import { $cerberusIcons } from '../config/defineIcons'
|
|
19
|
-
import { trapFocus } from '../aria-helpers/trap-focus.aria'
|
|
20
16
|
import { Show } from '../components/Show'
|
|
21
|
-
import { Modal } from '../components/Modal'
|
|
22
|
-
import { useModal } from '../hooks/useModal'
|
|
23
|
-
import { ModalHeader } from '../components/ModalHeader'
|
|
24
|
-
import { ModalHeading } from '../components/ModalHeading'
|
|
25
|
-
import { ModalDescription } from '../components/ModalDescription'
|
|
26
17
|
import { Avatar } from '../components/Avatar'
|
|
27
18
|
import { HStack, VStack } from '@cerberus/styled-system/jsx'
|
|
19
|
+
import { useCerberusContext } from './cerberus'
|
|
20
|
+
import {
|
|
21
|
+
Dialog,
|
|
22
|
+
DialogCloseTrigger,
|
|
23
|
+
DialogDescription,
|
|
24
|
+
DialogHeading,
|
|
25
|
+
DialogProvider,
|
|
26
|
+
} from '../components/Dialog'
|
|
28
27
|
|
|
29
28
|
/**
|
|
30
29
|
* This module provides a context and hook for the confirm modal.
|
|
@@ -116,13 +115,14 @@ export type ConfirmModalProviderProps = PropsWithChildren<unknown>
|
|
|
116
115
|
export function ConfirmModal(
|
|
117
116
|
props: PropsWithChildren<ConfirmModalProviderProps>,
|
|
118
117
|
) {
|
|
119
|
-
const
|
|
120
|
-
const resolveRef = useRef<ShowResult>(null)
|
|
118
|
+
const [open, setOpen] = useState<boolean>(false)
|
|
121
119
|
const [content, setContent] = useState<ShowConfirmModalOptions | null>(null)
|
|
122
|
-
const
|
|
123
|
-
const ConfirmIcon = $cerberusIcons.confirmModal
|
|
120
|
+
const resolveRef = useRef<ShowResult>(null)
|
|
124
121
|
const kind = content?.kind ?? 'non-destructive'
|
|
125
122
|
|
|
123
|
+
const { icons } = useCerberusContext()
|
|
124
|
+
const { confirmModal: ConfirmIcon } = icons
|
|
125
|
+
|
|
126
126
|
const palette = useMemo(
|
|
127
127
|
() => (kind === 'destructive' ? 'danger' : 'action'),
|
|
128
128
|
[kind],
|
|
@@ -135,20 +135,20 @@ export function ConfirmModal(
|
|
|
135
135
|
resolveRef.current?.(true)
|
|
136
136
|
}
|
|
137
137
|
resolveRef.current?.(false)
|
|
138
|
-
|
|
138
|
+
setOpen(false)
|
|
139
139
|
},
|
|
140
|
-
[
|
|
140
|
+
[setOpen],
|
|
141
141
|
)
|
|
142
142
|
|
|
143
143
|
const handleShow = useCallback(
|
|
144
144
|
(options: ShowConfirmModalOptions) => {
|
|
145
145
|
return new Promise<boolean>((resolve) => {
|
|
146
146
|
setContent({ ...options })
|
|
147
|
-
|
|
147
|
+
setOpen(true)
|
|
148
148
|
resolveRef.current = resolve
|
|
149
149
|
})
|
|
150
150
|
},
|
|
151
|
-
[
|
|
151
|
+
[setOpen, setContent],
|
|
152
152
|
)
|
|
153
153
|
|
|
154
154
|
const value = useMemo(
|
|
@@ -162,15 +162,15 @@ export function ConfirmModal(
|
|
|
162
162
|
<ConfirmModalContext.Provider value={value}>
|
|
163
163
|
{props.children}
|
|
164
164
|
|
|
165
|
-
<
|
|
166
|
-
<
|
|
165
|
+
<DialogProvider open={open} onOpenChange={(e) => setOpen(e.open)}>
|
|
166
|
+
<Dialog size="sm">
|
|
167
167
|
<VStack gap="xl" w="full">
|
|
168
|
-
<
|
|
169
|
-
<
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
168
|
+
<VStack alignItems="flex-start" gap="md" w="full">
|
|
169
|
+
<HStack
|
|
170
|
+
alignSelf="center"
|
|
171
|
+
justify="center"
|
|
172
|
+
paddingBlockEnd="md"
|
|
173
|
+
w="full"
|
|
174
174
|
>
|
|
175
175
|
<Show
|
|
176
176
|
when={palette === 'danger'}
|
|
@@ -190,10 +190,10 @@ export function ConfirmModal(
|
|
|
190
190
|
src=""
|
|
191
191
|
/>
|
|
192
192
|
</Show>
|
|
193
|
-
</
|
|
194
|
-
<
|
|
195
|
-
<
|
|
196
|
-
</
|
|
193
|
+
</HStack>
|
|
194
|
+
<DialogHeading>{content?.heading}</DialogHeading>
|
|
195
|
+
<DialogDescription>{content?.description}</DialogDescription>
|
|
196
|
+
</VStack>
|
|
197
197
|
|
|
198
198
|
<HStack gap="4" w="full">
|
|
199
199
|
<Button
|
|
@@ -208,21 +208,23 @@ export function ConfirmModal(
|
|
|
208
208
|
>
|
|
209
209
|
{content?.actionText}
|
|
210
210
|
</Button>
|
|
211
|
-
<
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
211
|
+
<DialogCloseTrigger asChild>
|
|
212
|
+
<Button
|
|
213
|
+
className={css({
|
|
214
|
+
w: '1/2',
|
|
215
|
+
})}
|
|
216
|
+
name="cancel"
|
|
217
|
+
onClick={handleChoice}
|
|
218
|
+
usage="outlined"
|
|
219
|
+
value="false"
|
|
220
|
+
>
|
|
221
|
+
{content?.cancelText}
|
|
222
|
+
</Button>
|
|
223
|
+
</DialogCloseTrigger>
|
|
222
224
|
</HStack>
|
|
223
225
|
</VStack>
|
|
224
|
-
</
|
|
225
|
-
</
|
|
226
|
+
</Dialog>
|
|
227
|
+
</DialogProvider>
|
|
226
228
|
</ConfirmModalContext.Provider>
|
|
227
229
|
)
|
|
228
230
|
}
|
|
@@ -11,21 +11,20 @@ import {
|
|
|
11
11
|
type PropsWithChildren,
|
|
12
12
|
type ReactNode,
|
|
13
13
|
} from 'react'
|
|
14
|
-
import { Portal } from '../components/Portal'
|
|
15
14
|
import { Button } from '../components/Button'
|
|
16
|
-
import { $cerberusIcons } from '../config/defineIcons'
|
|
17
|
-
import { trapFocus } from '../aria-helpers/trap-focus.aria'
|
|
18
15
|
import { Show } from '../components/Show'
|
|
19
|
-
import { Modal } from '../components/Modal'
|
|
20
|
-
import { useModal } from '../hooks/useModal'
|
|
21
|
-
import { ModalHeader } from '../components/ModalHeader'
|
|
22
|
-
import { ModalHeading } from '../components/ModalHeading'
|
|
23
|
-
import { ModalDescription } from '../components/ModalDescription'
|
|
24
16
|
import { Avatar } from '../components/Avatar'
|
|
17
|
+
import { useCerberusContext } from './cerberus'
|
|
25
18
|
import { HStack } from '@cerberus/styled-system/jsx'
|
|
26
|
-
import { IconButton } from '../components/IconButton'
|
|
27
19
|
import { css } from '@cerberus/styled-system/css'
|
|
28
20
|
import { VStack } from '@cerberus/styled-system/jsx'
|
|
21
|
+
import {
|
|
22
|
+
Dialog,
|
|
23
|
+
DialogDescription,
|
|
24
|
+
DialogHeading,
|
|
25
|
+
DialogProvider,
|
|
26
|
+
} from '../components/Dialog'
|
|
27
|
+
import { DialogCloseIconTrigger } from '../components/Dialog.client'
|
|
29
28
|
|
|
30
29
|
/**
|
|
31
30
|
* This module provides a context and hook for the cta modal.
|
|
@@ -95,12 +94,12 @@ export type CTAModalProviderProps = PropsWithChildren<unknown>
|
|
|
95
94
|
* ```
|
|
96
95
|
*/
|
|
97
96
|
export function CTAModal(props: PropsWithChildren<CTAModalProviderProps>) {
|
|
98
|
-
const
|
|
97
|
+
const [open, setOpen] = useState<boolean>(false)
|
|
99
98
|
const [content, setContent] = useState<ShowCTAModalOptions | null>(null)
|
|
100
|
-
const focusTrap = trapFocus(modalRef)
|
|
101
|
-
const FallbackIcon = $cerberusIcons.confirmModal
|
|
102
99
|
const confirmIcon = content?.icon
|
|
103
|
-
|
|
100
|
+
|
|
101
|
+
const { icons } = useCerberusContext()
|
|
102
|
+
const { confirmModal: FallbackIcon } = icons
|
|
104
103
|
|
|
105
104
|
const handleShow = useCallback(
|
|
106
105
|
(options: ShowCTAModalOptions) => {
|
|
@@ -111,9 +110,9 @@ export function CTAModal(props: PropsWithChildren<CTAModalProviderProps>) {
|
|
|
111
110
|
)
|
|
112
111
|
}
|
|
113
112
|
setContent({ ...options })
|
|
114
|
-
|
|
113
|
+
setOpen(true)
|
|
115
114
|
},
|
|
116
|
-
[
|
|
115
|
+
[setOpen],
|
|
117
116
|
)
|
|
118
117
|
|
|
119
118
|
const handleActionClick = useCallback(
|
|
@@ -122,9 +121,9 @@ export function CTAModal(props: PropsWithChildren<CTAModalProviderProps>) {
|
|
|
122
121
|
const action = content?.actions[Number(index)]
|
|
123
122
|
const { onClick } = action || {}
|
|
124
123
|
onClick?.(event)
|
|
125
|
-
|
|
124
|
+
setOpen(false)
|
|
126
125
|
},
|
|
127
|
-
[content,
|
|
126
|
+
[content, setOpen],
|
|
128
127
|
)
|
|
129
128
|
|
|
130
129
|
const value = useMemo(
|
|
@@ -138,24 +137,12 @@ export function CTAModal(props: PropsWithChildren<CTAModalProviderProps>) {
|
|
|
138
137
|
<CTAModalContext.Provider value={value}>
|
|
139
138
|
{props.children}
|
|
140
139
|
|
|
141
|
-
<
|
|
142
|
-
<
|
|
143
|
-
<
|
|
144
|
-
className={css({
|
|
145
|
-
padding: 'md',
|
|
146
|
-
position: 'absolute',
|
|
147
|
-
right: 0,
|
|
148
|
-
top: 0,
|
|
149
|
-
zIndex: 'decorator',
|
|
150
|
-
})}
|
|
151
|
-
>
|
|
152
|
-
<IconButton ariaLabel="Close modal" onClick={close}>
|
|
153
|
-
<CloseIcon />
|
|
154
|
-
</IconButton>
|
|
155
|
-
</span>
|
|
140
|
+
<DialogProvider open={open} onOpenChange={(e) => setOpen(e.open)}>
|
|
141
|
+
<Dialog size="sm">
|
|
142
|
+
<DialogCloseIconTrigger />
|
|
156
143
|
|
|
157
144
|
<VStack gap="xl" w="full">
|
|
158
|
-
<
|
|
145
|
+
<VStack alignItems="flex-start" gap="md" w="full">
|
|
159
146
|
<VStack gap="lg" w="full">
|
|
160
147
|
<Avatar
|
|
161
148
|
ariaLabel=""
|
|
@@ -170,10 +157,10 @@ export function CTAModal(props: PropsWithChildren<CTAModalProviderProps>) {
|
|
|
170
157
|
}
|
|
171
158
|
src=""
|
|
172
159
|
/>
|
|
173
|
-
<
|
|
174
|
-
<
|
|
160
|
+
<DialogHeading>{content?.heading}</DialogHeading>
|
|
161
|
+
<DialogDescription>{content?.description}</DialogDescription>
|
|
175
162
|
</VStack>
|
|
176
|
-
</
|
|
163
|
+
</VStack>
|
|
177
164
|
|
|
178
165
|
<HStack gap="md" w="full">
|
|
179
166
|
<Show when={Boolean(content?.actions?.length)}>
|
|
@@ -194,8 +181,8 @@ export function CTAModal(props: PropsWithChildren<CTAModalProviderProps>) {
|
|
|
194
181
|
</Show>
|
|
195
182
|
</HStack>
|
|
196
183
|
</VStack>
|
|
197
|
-
</
|
|
198
|
-
</
|
|
184
|
+
</Dialog>
|
|
185
|
+
</DialogProvider>
|
|
199
186
|
</CTAModalContext.Provider>
|
|
200
187
|
)
|
|
201
188
|
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { Dispatch } from 'react'
|
|
2
|
+
import type {
|
|
3
|
+
AddNotifyAction,
|
|
4
|
+
ClearNotifyAction,
|
|
5
|
+
NotificationsStore,
|
|
6
|
+
RemoveNotifyAction,
|
|
7
|
+
UpdateNotifyAction,
|
|
8
|
+
} from './types'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* This module contains the reducer store and actions for the notification
|
|
12
|
+
* center.
|
|
13
|
+
* @module notification-center/store
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The reducer for the notification center.
|
|
18
|
+
* @param state An array of notifications.
|
|
19
|
+
* @param action An action to take on the notifications.
|
|
20
|
+
* @returns The new state of the notifications.
|
|
21
|
+
*/
|
|
22
|
+
export function notificationCenterReducer(
|
|
23
|
+
state: NotificationsStore,
|
|
24
|
+
action:
|
|
25
|
+
| AddNotifyAction
|
|
26
|
+
| RemoveNotifyAction
|
|
27
|
+
| UpdateNotifyAction
|
|
28
|
+
| ClearNotifyAction,
|
|
29
|
+
): NotificationsStore {
|
|
30
|
+
switch (action.type) {
|
|
31
|
+
case 'ADD_NOTIFICATION':
|
|
32
|
+
return [...state, action.payload]
|
|
33
|
+
case 'REMOVE_NOTIFICATION':
|
|
34
|
+
return state.filter((n) => n.id !== action.payload.id)
|
|
35
|
+
case 'UPDATE_NOTIFICATION':
|
|
36
|
+
return state.map((n) =>
|
|
37
|
+
n.id === action.payload.id ? { ...n, ...action.payload } : n,
|
|
38
|
+
)
|
|
39
|
+
case 'CLEAR_NOTIFICATIONS':
|
|
40
|
+
return []
|
|
41
|
+
default:
|
|
42
|
+
return state
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Adds a notification to the notification center.
|
|
48
|
+
* @param dispatch The dispatch function.
|
|
49
|
+
* @param options The notification options.
|
|
50
|
+
*/
|
|
51
|
+
export function addNotification(
|
|
52
|
+
dispatch: Dispatch<AddNotifyAction>,
|
|
53
|
+
options: AddNotifyAction['payload'],
|
|
54
|
+
) {
|
|
55
|
+
dispatch({ type: 'ADD_NOTIFICATION', payload: { ...options } })
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Removes a notification from the notification center.
|
|
60
|
+
* @param dispatch The dispatch function.
|
|
61
|
+
* @param id The id of the notification to remove.
|
|
62
|
+
*/
|
|
63
|
+
export function removeNotification(
|
|
64
|
+
dispatch: Dispatch<RemoveNotifyAction>,
|
|
65
|
+
id: RemoveNotifyAction['payload']['id'],
|
|
66
|
+
) {
|
|
67
|
+
dispatch({ type: 'REMOVE_NOTIFICATION', payload: { id } })
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Updates a notification in the notification center.
|
|
72
|
+
* @param dispatch The dispatch function.
|
|
73
|
+
* @param options The notification options.
|
|
74
|
+
*/
|
|
75
|
+
export function updateNotificationState(
|
|
76
|
+
dispatch: Dispatch<UpdateNotifyAction>,
|
|
77
|
+
options: UpdateNotifyAction['payload'],
|
|
78
|
+
) {
|
|
79
|
+
dispatch({ type: 'UPDATE_NOTIFICATION', payload: { ...options } })
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Clears the notification state.
|
|
84
|
+
* @param dispatch The dispatch function.
|
|
85
|
+
*/
|
|
86
|
+
export function clearNotificationState(dispatch: Dispatch<ClearNotifyAction>) {
|
|
87
|
+
dispatch({ type: 'CLEAR_NOTIFICATIONS' })
|
|
88
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { NotifyOptions } from '../notification-center'
|
|
2
|
+
|
|
3
|
+
export type NotificationsStore = NotificationOption[]
|
|
4
|
+
|
|
5
|
+
export type NotificationOption = NotifyOptions & {
|
|
6
|
+
state: 'open' | 'closed'
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Actions
|
|
10
|
+
|
|
11
|
+
export type AddNotifyAction = {
|
|
12
|
+
type: 'ADD_NOTIFICATION'
|
|
13
|
+
payload: NotificationOption
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type RemoveNotifyAction = {
|
|
17
|
+
type: 'REMOVE_NOTIFICATION'
|
|
18
|
+
payload: { id: Required<NotificationOption['id']> }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type UpdateNotifyAction = {
|
|
22
|
+
type: 'UPDATE_NOTIFICATION'
|
|
23
|
+
payload: {
|
|
24
|
+
id: Required<NotificationOption['id']>
|
|
25
|
+
} & Partial<NotificationOption>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type ClearNotifyAction = { type: 'CLEAR_NOTIFICATIONS' }
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
useCallback,
|
|
6
6
|
useContext,
|
|
7
7
|
useMemo,
|
|
8
|
-
|
|
8
|
+
useReducer,
|
|
9
9
|
type MouseEvent,
|
|
10
10
|
type PropsWithChildren,
|
|
11
11
|
type ReactNode,
|
|
@@ -19,6 +19,13 @@ import { Portal, type PortalProps } from '../components/Portal'
|
|
|
19
19
|
import { notification } from '@cerberus/styled-system/recipes'
|
|
20
20
|
import { Button } from '../components/Button'
|
|
21
21
|
import { cx } from '@cerberus/styled-system/css'
|
|
22
|
+
import {
|
|
23
|
+
addNotification,
|
|
24
|
+
clearNotificationState,
|
|
25
|
+
notificationCenterReducer,
|
|
26
|
+
removeNotification,
|
|
27
|
+
updateNotificationState,
|
|
28
|
+
} from './notification-center/store'
|
|
22
29
|
|
|
23
30
|
/**
|
|
24
31
|
* This module provides a context and hook for notifications.
|
|
@@ -55,7 +62,13 @@ export interface NotificationsValue {
|
|
|
55
62
|
|
|
56
63
|
const NotificationsContext = createContext<NotificationsValue | null>(null)
|
|
57
64
|
|
|
58
|
-
export type NotificationsProviderProps = PortalProps
|
|
65
|
+
export type NotificationsProviderProps = PortalProps & {
|
|
66
|
+
/**
|
|
67
|
+
* The duration in milliseconds to show the notification.
|
|
68
|
+
* @default 6000
|
|
69
|
+
*/
|
|
70
|
+
duration?: number
|
|
71
|
+
}
|
|
59
72
|
|
|
60
73
|
/**
|
|
61
74
|
* Provides a notification center to the app.
|
|
@@ -82,35 +95,58 @@ export type NotificationsProviderProps = PortalProps
|
|
|
82
95
|
export function NotificationCenter(
|
|
83
96
|
props: PropsWithChildren<NotificationsProviderProps>,
|
|
84
97
|
) {
|
|
85
|
-
const [
|
|
86
|
-
NotifyOptions[]
|
|
87
|
-
>([])
|
|
98
|
+
const [state, dispatch] = useReducer(notificationCenterReducer, [])
|
|
88
99
|
const styles = notification()
|
|
89
100
|
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
})
|
|
95
|
-
}, [])
|
|
96
|
-
|
|
97
|
-
const handleClose = useCallback((e: MouseEvent<HTMLButtonElement>) => {
|
|
98
|
-
const target = e.currentTarget as HTMLButtonElement
|
|
99
|
-
setActiveNotifications((prev) => {
|
|
100
|
-
const item = prev.find((option) => option.id === target.value)
|
|
101
|
-
if (item?.onClose) item.onClose()
|
|
102
|
-
return prev.filter((option) => option.id !== target.value)
|
|
103
|
-
})
|
|
104
|
-
}, [])
|
|
101
|
+
const timeout = useMemo<number>(
|
|
102
|
+
() => props.duration || 6000,
|
|
103
|
+
[props.duration],
|
|
104
|
+
)
|
|
105
105
|
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
const closeNotification = useCallback(
|
|
107
|
+
(id: string) => {
|
|
108
|
+
updateNotificationState(dispatch, {
|
|
109
|
+
id,
|
|
110
|
+
state: 'closed',
|
|
111
|
+
})
|
|
112
|
+
window.setTimeout(() => {
|
|
113
|
+
removeNotification(dispatch, id)
|
|
114
|
+
}, 150)
|
|
115
|
+
},
|
|
116
|
+
[dispatch],
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
const handleNotify = useCallback(
|
|
120
|
+
(options: NotifyOptions) => {
|
|
121
|
+
const id = `${options.palette}:${state.length + 1}`
|
|
122
|
+
addNotification(dispatch, {
|
|
123
|
+
...options,
|
|
124
|
+
id,
|
|
125
|
+
state: 'open',
|
|
110
126
|
})
|
|
111
|
-
|
|
127
|
+
|
|
128
|
+
window.setTimeout(() => {
|
|
129
|
+
closeNotification(id)
|
|
130
|
+
}, timeout)
|
|
131
|
+
},
|
|
132
|
+
[dispatch, state, timeout, closeNotification],
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
const handleClose = useCallback(
|
|
136
|
+
(e: MouseEvent<HTMLButtonElement>) => {
|
|
137
|
+
const target = e.currentTarget as HTMLButtonElement
|
|
138
|
+
closeNotification(target.value)
|
|
139
|
+
},
|
|
140
|
+
[closeNotification],
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
const handleCloseAll = useCallback(() => {
|
|
144
|
+
state.forEach((item) => {
|
|
145
|
+
if (item.onClose) item.onClose()
|
|
112
146
|
})
|
|
113
|
-
|
|
147
|
+
// we don't want to animate out for this one
|
|
148
|
+
clearNotificationState(dispatch)
|
|
149
|
+
}, [state, dispatch])
|
|
114
150
|
|
|
115
151
|
const value = useMemo(
|
|
116
152
|
() => ({
|
|
@@ -126,10 +162,10 @@ export function NotificationCenter(
|
|
|
126
162
|
<NotificationsContext.Provider value={value}>
|
|
127
163
|
{props.children}
|
|
128
164
|
|
|
129
|
-
<Show when={
|
|
165
|
+
<Show when={state.length > 0}>
|
|
130
166
|
<Portal container={props.container}>
|
|
131
167
|
<div className={styles.center}>
|
|
132
|
-
<Show when={
|
|
168
|
+
<Show when={state.length >= 4}>
|
|
133
169
|
<Button
|
|
134
170
|
className={cx(styles.closeAll, animateIn())}
|
|
135
171
|
onClick={handleCloseAll}
|
|
@@ -151,11 +187,12 @@ export function NotificationCenter(
|
|
|
151
187
|
alignItems: 'flex-end',
|
|
152
188
|
}}
|
|
153
189
|
>
|
|
154
|
-
{
|
|
190
|
+
{state.map((option) => (
|
|
155
191
|
<MatchNotification
|
|
156
192
|
key={option.id}
|
|
157
193
|
{...option}
|
|
158
194
|
onClose={handleClose}
|
|
195
|
+
open={option.state}
|
|
159
196
|
/>
|
|
160
197
|
))}
|
|
161
198
|
</div>
|
|
@@ -167,23 +204,27 @@ export function NotificationCenter(
|
|
|
167
204
|
}
|
|
168
205
|
|
|
169
206
|
interface MatchNotificationProps extends Omit<NotifyOptions, 'onClose'> {
|
|
207
|
+
open: 'open' | 'closed'
|
|
170
208
|
onClose: (e: MouseEvent<HTMLButtonElement>) => void
|
|
171
209
|
key: string | undefined
|
|
172
210
|
}
|
|
173
211
|
|
|
174
212
|
function MatchNotification(props: MatchNotificationProps) {
|
|
175
|
-
const { palette, id, onClose, heading, description } = props
|
|
213
|
+
const { palette, id, onClose, heading, description, open } = props
|
|
214
|
+
const sharedProps = useMemo(
|
|
215
|
+
() => ({
|
|
216
|
+
id: id!,
|
|
217
|
+
open: true,
|
|
218
|
+
onClose,
|
|
219
|
+
'data-state': open,
|
|
220
|
+
}),
|
|
221
|
+
[id, open, onClose],
|
|
222
|
+
)
|
|
176
223
|
|
|
177
224
|
switch (palette) {
|
|
178
225
|
case 'success':
|
|
179
226
|
return (
|
|
180
|
-
<Notification
|
|
181
|
-
id={id!}
|
|
182
|
-
key={id}
|
|
183
|
-
onClose={onClose}
|
|
184
|
-
open
|
|
185
|
-
palette="success"
|
|
186
|
-
>
|
|
227
|
+
<Notification {...sharedProps} palette="success">
|
|
187
228
|
<NotificationHeading palette="success">{heading}</NotificationHeading>
|
|
188
229
|
<NotificationDescription palette="success">
|
|
189
230
|
{description}
|
|
@@ -193,13 +234,7 @@ function MatchNotification(props: MatchNotificationProps) {
|
|
|
193
234
|
|
|
194
235
|
case 'warning':
|
|
195
236
|
return (
|
|
196
|
-
<Notification
|
|
197
|
-
id={id!}
|
|
198
|
-
key={id}
|
|
199
|
-
onClose={onClose}
|
|
200
|
-
open
|
|
201
|
-
palette="warning"
|
|
202
|
-
>
|
|
237
|
+
<Notification {...sharedProps} palette="warning">
|
|
203
238
|
<NotificationHeading palette="warning">{heading}</NotificationHeading>
|
|
204
239
|
<NotificationDescription palette="warning">
|
|
205
240
|
{description}
|
|
@@ -209,7 +244,7 @@ function MatchNotification(props: MatchNotificationProps) {
|
|
|
209
244
|
|
|
210
245
|
case 'danger':
|
|
211
246
|
return (
|
|
212
|
-
<Notification
|
|
247
|
+
<Notification {...sharedProps} palette="danger">
|
|
213
248
|
<NotificationHeading palette="danger">{heading}</NotificationHeading>
|
|
214
249
|
<NotificationDescription palette="danger">
|
|
215
250
|
{description}
|
|
@@ -220,7 +255,7 @@ function MatchNotification(props: MatchNotificationProps) {
|
|
|
220
255
|
case 'info':
|
|
221
256
|
default:
|
|
222
257
|
return (
|
|
223
|
-
<Notification
|
|
258
|
+
<Notification {...sharedProps} palette="info">
|
|
224
259
|
<NotificationHeading palette="info">{heading}</NotificationHeading>
|
|
225
260
|
<NotificationDescription palette="info">
|
|
226
261
|
{description}
|