@cerberus-design/react 0.6.1-next-1315bf2 → 0.6.1-next-8062b70

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 (66) hide show
  1. package/build/legacy/_tsup-dts-rollup.d.ts +78 -0
  2. package/build/legacy/{chunk-5RA3ZIXA.js → chunk-5GEC53G7.js} +5 -5
  3. package/build/legacy/{chunk-3TYUA4C7.js → chunk-6TXQZ3PB.js} +2 -2
  4. package/build/legacy/{chunk-SCAVVE6E.js → chunk-C45DY4VE.js} +2 -1
  5. package/build/legacy/chunk-C45DY4VE.js.map +1 -0
  6. package/build/legacy/{chunk-JJGZRBIR.js → chunk-CU7HXAKM.js} +4 -4
  7. package/build/legacy/chunk-G3JEWPLM.js +29 -0
  8. package/build/legacy/chunk-G3JEWPLM.js.map +1 -0
  9. package/build/legacy/{chunk-VLVKNEA5.js → chunk-TAZI77TP.js} +2 -2
  10. package/build/legacy/{chunk-YRUUO4AP.js → chunk-UZIN7UOS.js} +19 -38
  11. package/build/legacy/chunk-UZIN7UOS.js.map +1 -0
  12. package/build/legacy/chunk-WKSC2WCV.js +202 -0
  13. package/build/legacy/chunk-WKSC2WCV.js.map +1 -0
  14. package/build/legacy/components/Input.js +4 -4
  15. package/build/legacy/components/Label.js +2 -2
  16. package/build/legacy/components/ModalIcon.js +7 -0
  17. package/build/legacy/components/ModalIcon.js.map +1 -0
  18. package/build/legacy/components/Toggle.js +3 -3
  19. package/build/legacy/config/cerbIcons.js +1 -1
  20. package/build/legacy/config/defineIcons.js +2 -2
  21. package/build/legacy/context/confirm-modal.js +4 -3
  22. package/build/legacy/context/prompt-modal.js +20 -0
  23. package/build/legacy/context/prompt-modal.js.map +1 -0
  24. package/build/legacy/index.js +24 -14
  25. package/build/modern/_tsup-dts-rollup.d.ts +78 -0
  26. package/build/modern/{chunk-5RA3ZIXA.js → chunk-5GEC53G7.js} +5 -5
  27. package/build/modern/{chunk-3TYUA4C7.js → chunk-6TXQZ3PB.js} +2 -2
  28. package/build/modern/{chunk-SCAVVE6E.js → chunk-C45DY4VE.js} +2 -1
  29. package/build/modern/chunk-C45DY4VE.js.map +1 -0
  30. package/build/modern/{chunk-JJGZRBIR.js → chunk-CU7HXAKM.js} +4 -4
  31. package/build/modern/chunk-G3JEWPLM.js +29 -0
  32. package/build/modern/chunk-G3JEWPLM.js.map +1 -0
  33. package/build/modern/{chunk-VLVKNEA5.js → chunk-TAZI77TP.js} +2 -2
  34. package/build/modern/{chunk-BVK6GEDZ.js → chunk-X2GKC3IU.js} +19 -38
  35. package/build/modern/chunk-X2GKC3IU.js.map +1 -0
  36. package/build/modern/chunk-YHJTKBVE.js +200 -0
  37. package/build/modern/chunk-YHJTKBVE.js.map +1 -0
  38. package/build/modern/components/Input.js +4 -4
  39. package/build/modern/components/Label.js +2 -2
  40. package/build/modern/components/ModalIcon.js +7 -0
  41. package/build/modern/components/ModalIcon.js.map +1 -0
  42. package/build/modern/components/Toggle.js +3 -3
  43. package/build/modern/config/cerbIcons.js +1 -1
  44. package/build/modern/config/defineIcons.js +2 -2
  45. package/build/modern/context/confirm-modal.js +4 -3
  46. package/build/modern/context/prompt-modal.js +20 -0
  47. package/build/modern/context/prompt-modal.js.map +1 -0
  48. package/build/modern/index.js +24 -14
  49. package/package.json +2 -2
  50. package/src/components/ModalIcon.tsx +28 -0
  51. package/src/config/cerbIcons.ts +2 -0
  52. package/src/context/confirm-modal.tsx +20 -43
  53. package/src/context/prompt-modal.tsx +231 -0
  54. package/src/index.ts +2 -0
  55. package/build/legacy/chunk-SCAVVE6E.js.map +0 -1
  56. package/build/legacy/chunk-YRUUO4AP.js.map +0 -1
  57. package/build/modern/chunk-BVK6GEDZ.js.map +0 -1
  58. package/build/modern/chunk-SCAVVE6E.js.map +0 -1
  59. /package/build/legacy/{chunk-5RA3ZIXA.js.map → chunk-5GEC53G7.js.map} +0 -0
  60. /package/build/legacy/{chunk-3TYUA4C7.js.map → chunk-6TXQZ3PB.js.map} +0 -0
  61. /package/build/legacy/{chunk-JJGZRBIR.js.map → chunk-CU7HXAKM.js.map} +0 -0
  62. /package/build/legacy/{chunk-VLVKNEA5.js.map → chunk-TAZI77TP.js.map} +0 -0
  63. /package/build/modern/{chunk-5RA3ZIXA.js.map → chunk-5GEC53G7.js.map} +0 -0
  64. /package/build/modern/{chunk-3TYUA4C7.js.map → chunk-6TXQZ3PB.js.map} +0 -0
  65. /package/build/modern/{chunk-JJGZRBIR.js.map → chunk-CU7HXAKM.js.map} +0 -0
  66. /package/build/modern/{chunk-VLVKNEA5.js.map → chunk-TAZI77TP.js.map} +0 -0
@@ -0,0 +1,231 @@
1
+ 'use client'
2
+
3
+ import {
4
+ createContext,
5
+ useCallback,
6
+ useContext,
7
+ useMemo,
8
+ useRef,
9
+ useState,
10
+ type ChangeEvent,
11
+ type MouseEvent,
12
+ type PropsWithChildren,
13
+ } from 'react'
14
+ import { Portal } from '../components/Portal'
15
+ import { Button } from '../components/Button'
16
+ import { css } from '@cerberus-design/styled-system/css'
17
+ import { hstack, vstack } from '@cerberus-design/styled-system/patterns'
18
+ import { modal } from '@cerberus-design/styled-system/recipes'
19
+ import { trapFocus } from '../aria-helpers/trap-focus.aria'
20
+ import { Input } from '../components/Input'
21
+ import { Field } from './field'
22
+ import { Label } from '../components/Label'
23
+ import { $cerberusIcons } from '../config/defineIcons'
24
+ import { ModalIcon } from '../components/ModalIcon'
25
+ import { Show } from '../components/Show'
26
+
27
+ /**
28
+ * This module provides a context and hook for the prompt modal.
29
+ * @module
30
+ */
31
+
32
+ export interface ShowPromptModalOptions {
33
+ kind?: 'destructive' | 'non-destructive'
34
+ heading: string
35
+ description?: string
36
+ key: string
37
+ actionText: string
38
+ cancelText: string
39
+ }
40
+ export type PromptShowResult =
41
+ | ((value: string | PromiseLike<string>) => void)
42
+ | null
43
+
44
+ export interface PromptModalValue {
45
+ show: (options: ShowPromptModalOptions) => Promise<string>
46
+ }
47
+
48
+ const PromptModalContext = createContext<PromptModalValue | null>(null)
49
+
50
+ export interface PromptModalProviderProps {}
51
+
52
+ /**
53
+ * Provides a prompt modal to the app.
54
+ * @example
55
+ * ```tsx
56
+ * // Wrap the Provider around the root of the feature.
57
+ * <PromptModal>
58
+ * <SomeFeatureSection />
59
+ * </PromptModal>
60
+ *
61
+ * // Use the hook to show the prompt modal.
62
+ * const prompt = usePromptModal()
63
+ *
64
+ * const handleClick = useCallback(async () => {
65
+ * const accepted = await prompt.show({
66
+ * kind: 'destructive',
67
+ * heading: 'Delete channel?',
68
+ * description:
69
+ * 'This will permanently delete a channel on your account. There is no going back.',
70
+ * key: CHANNEL_NAME,
71
+ * actionText: 'Yes, delete channel',
72
+ * cancelText: 'No, cancel',
73
+ * })
74
+ * // do something with accepted
75
+ * }, [prompt])
76
+ * ```
77
+ */
78
+ export function PromptModal(
79
+ props: PropsWithChildren<PromptModalProviderProps>,
80
+ ) {
81
+ const dialogRef = useRef<HTMLDialogElement>(null)
82
+ const resolveRef = useRef<PromptShowResult>(null)
83
+ const [content, setContent] = useState<ShowPromptModalOptions | null>(null)
84
+ const [inputValue, setInputValue] = useState<string>('')
85
+ const focusTrap = trapFocus(dialogRef)
86
+ const PromptIcon = $cerberusIcons.promptModal
87
+
88
+ const isValid = useMemo(
89
+ () => inputValue === content?.key,
90
+ [inputValue, content],
91
+ )
92
+
93
+ const palette = useMemo(
94
+ () => (content?.kind === 'destructive' ? 'danger' : 'action'),
95
+ [content],
96
+ )
97
+ const styles = modal()
98
+
99
+ const handleChange = useCallback(
100
+ (e: ChangeEvent<HTMLInputElement>) => {
101
+ setInputValue(e.currentTarget.value)
102
+ },
103
+ [content],
104
+ )
105
+
106
+ const handleChoice = useCallback(
107
+ (e: MouseEvent<HTMLButtonElement>) => {
108
+ const target = e.currentTarget as HTMLButtonElement
109
+ if (target.value === 'true') {
110
+ resolveRef.current?.(inputValue)
111
+ }
112
+ dialogRef?.current?.close()
113
+ },
114
+ [inputValue],
115
+ )
116
+
117
+ const handleShow = useCallback((options: ShowPromptModalOptions) => {
118
+ return new Promise<string>((resolve) => {
119
+ setContent({ ...options, kind: options.kind || 'non-destructive' })
120
+ dialogRef?.current?.showModal()
121
+ resolveRef.current = resolve
122
+ })
123
+ }, [])
124
+
125
+ const value = useMemo(
126
+ () => ({
127
+ show: handleShow,
128
+ }),
129
+ [handleShow],
130
+ )
131
+
132
+ return (
133
+ <PromptModalContext.Provider value={value}>
134
+ {props.children}
135
+
136
+ <Portal>
137
+ <dialog className={styles.dialog} onKeyDown={focusTrap} ref={dialogRef}>
138
+ <div
139
+ className={vstack({
140
+ alignItems: 'flex-start',
141
+ gap: '4',
142
+ })}
143
+ >
144
+ <Show
145
+ when={palette === 'danger'}
146
+ fallback={
147
+ <ModalIcon palette="action">
148
+ <PromptIcon size={24} />
149
+ </ModalIcon>
150
+ }
151
+ >
152
+ <ModalIcon palette="danger">
153
+ <PromptIcon size={24} />
154
+ </ModalIcon>
155
+ </Show>
156
+ <h2 className={styles.heading}>{content?.heading}</h2>
157
+ <p className={styles.description}>{content?.description}</p>
158
+ </div>
159
+
160
+ <div
161
+ className={vstack({
162
+ alignItems: 'flex-start',
163
+ mt: '4',
164
+ mb: '8',
165
+ })}
166
+ >
167
+ <Field invalid={!isValid}>
168
+ <Label htmlFor="confirm" size="md">
169
+ Type
170
+ <strong
171
+ className={css({
172
+ textTransform: 'uppercase',
173
+ })}
174
+ >
175
+ {content?.key}
176
+ </strong>
177
+ to confirm
178
+ </Label>
179
+ <Input
180
+ id="confirm"
181
+ name="confirm"
182
+ onChange={handleChange}
183
+ type="text"
184
+ />
185
+ </Field>
186
+ </div>
187
+
188
+ <div
189
+ className={hstack({
190
+ justifyContent: 'stretch',
191
+ gap: '4',
192
+ })}
193
+ >
194
+ <Button
195
+ autoFocus
196
+ className={css({
197
+ w: '1/2',
198
+ })}
199
+ disabled={!isValid}
200
+ name="confirm"
201
+ onClick={handleChoice}
202
+ palette={palette}
203
+ value="true"
204
+ >
205
+ {content?.actionText}
206
+ </Button>
207
+ <Button
208
+ className={css({
209
+ w: '1/2',
210
+ })}
211
+ name="cancel"
212
+ onClick={handleChoice}
213
+ usage="outlined"
214
+ value="false"
215
+ >
216
+ {content?.cancelText}
217
+ </Button>
218
+ </div>
219
+ </dialog>
220
+ </Portal>
221
+ </PromptModalContext.Provider>
222
+ )
223
+ }
224
+
225
+ export function usePromptModal(): PromptModalValue {
226
+ const context = useContext(PromptModalContext)
227
+ if (context === null) {
228
+ throw new Error('usePromptModal must be used within a PromptModal Provider')
229
+ }
230
+ return context
231
+ }
package/src/index.ts CHANGED
@@ -11,6 +11,7 @@ export * from './components/FeatureFlag'
11
11
  export * from './components/IconButton'
12
12
  export * from './components/Input'
13
13
  export * from './components/Label'
14
+ export * from './components/ModalIcon'
14
15
  export * from './components/NavMenuTrigger'
15
16
  export * from './components/NavMenuList'
16
17
  export * from './components/NavMenuLink'
@@ -30,6 +31,7 @@ export * from './context/confirm-modal'
30
31
  export * from './context/feature-flags'
31
32
  export * from './context/field'
32
33
  export * from './context/navMenu'
34
+ export * from './context/prompt-modal'
33
35
  export * from './context/tabs'
34
36
  export * from './context/theme'
35
37
 
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/config/cerbIcons.ts"],"sourcesContent":["import {\n Checkmark,\n Information,\n WarningFilled,\n type CarbonIconType,\n} from '@cerberus/icons'\nimport type { ElementType } from 'react'\n\nexport interface DefinedIcons {\n confirmModal?: CarbonIconType | ElementType\n invalid: CarbonIconType | ElementType\n toggleChecked?: CarbonIconType | ElementType\n}\n\nexport const defaultIcons: DefinedIcons = {\n confirmModal: Information,\n invalid: WarningFilled,\n toggleChecked: Checkmark,\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AASA,IAAM,eAA6B;AAAA,EACxC,cAAc;AAAA,EACd,SAAS;AAAA,EACT,eAAe;AACjB;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/context/confirm-modal.tsx"],"sourcesContent":["'use client'\n\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n type MouseEvent,\n type PropsWithChildren,\n} from 'react'\nimport { Portal } from '../components/Portal'\nimport { Button } from '../components/Button'\nimport { css, cx } from '@cerberus-design/styled-system/css'\nimport { circle, hstack, vstack } from '@cerberus-design/styled-system/patterns'\nimport { $cerberusIcons } from '../config/defineIcons'\nimport {\n confirmModal,\n type ConfirmModalVariantProps,\n} from '@cerberus-design/styled-system/recipes'\nimport { trapFocus } from '../aria-helpers/trap-focus.aria'\nimport { Show } from '../components/Show'\n\n/**\n * This module provides a context and hook for the confirm modal.\n * @module\n */\n\nexport interface ShowConfirmModalOptions {\n kind?: 'destructive' | 'non-destructive'\n heading: string\n description?: string\n actionText: string\n cancelText: string\n}\nexport type ShowResult =\n | ((value: boolean | PromiseLike<boolean>) => void)\n | null\n\nexport interface ConfirmModalValue {\n show: (options: ShowConfirmModalOptions) => Promise<boolean>\n}\n\nconst ConfirmModalContext = createContext<ConfirmModalValue | null>(null)\n\nexport interface ConfirmModalProviderProps {}\n\n/**\n * Provides a confirm modal to the app.\n * @example\n * ```tsx\n * // Wrap the Provider around the root of the feature.\n * <ConfirmModal>\n * <SomeFeatureSection />\n * </ConfirmModal>\n *\n * // Use the hook to show the confirm modal.\n * const confirm = useConfirmModal()\n *\n * const handleClick = useCallback(async () => {\n * const userConsent = await confirm.show({\n * heading: 'Add new payment method?',\n * description:\n * 'This will add a new payment method to your account to be billed for future purchases.',\n * actionText: 'Yes, add payment method',\n * cancelText: 'No, cancel',\n * })\n * setConsent(userConsent)\n * }, [confirm])\n * ```\n */\nexport function ConfirmModal(\n props: PropsWithChildren<ConfirmModalProviderProps>,\n) {\n const dialogRef = useRef<HTMLDialogElement>(null)\n const resolveRef = useRef<ShowResult>(null)\n const [content, setContent] = useState<ShowConfirmModalOptions | null>(null)\n const focusTrap = trapFocus(dialogRef)\n\n const palette = useMemo(\n () => (content?.kind === 'destructive' ? 'danger' : 'action'),\n [content],\n )\n const styles = confirmModal({ palette })\n\n const handleChoice = useCallback((e: MouseEvent<HTMLButtonElement>) => {\n const target = e.currentTarget as HTMLButtonElement\n if (target.value === 'true') {\n resolveRef.current?.(true)\n }\n resolveRef.current?.(false)\n dialogRef?.current?.close()\n }, [])\n\n const handleShow = useCallback((options: ShowConfirmModalOptions) => {\n return new Promise<boolean>((resolve) => {\n setContent({ ...options, kind: options.kind || 'non-destructive' })\n dialogRef?.current?.showModal()\n resolveRef.current = resolve\n })\n }, [])\n\n const value = useMemo(\n () => ({\n show: handleShow,\n }),\n [handleShow],\n )\n\n return (\n <ConfirmModalContext.Provider value={value}>\n {props.children}\n\n <Portal>\n <dialog className={styles.dialog} onKeyDown={focusTrap} ref={dialogRef}>\n <div\n className={vstack({\n alignItems: 'flex-start',\n gap: '4',\n mb: '8',\n })}\n >\n <ConfirmModalIcon palette={palette} />\n <h2 className={styles.heading}>{content?.heading}</h2>\n <p className={styles.description}>{content?.description}</p>\n </div>\n\n <div\n className={hstack({\n justifyContent: 'stretch',\n gap: '4',\n })}\n >\n <Button\n autoFocus\n className={css({\n w: '1/2',\n })}\n name=\"confirm\"\n onClick={handleChoice}\n palette={palette}\n value=\"true\"\n >\n {content?.actionText}\n </Button>\n <Button\n className={css({\n w: '1/2',\n })}\n name=\"cancel\"\n onClick={handleChoice}\n usage=\"outlined\"\n value=\"false\"\n >\n {content?.cancelText}\n </Button>\n </div>\n </dialog>\n </Portal>\n </ConfirmModalContext.Provider>\n )\n}\n\n// This is to help show the variant styles for the icon since Panda is\n// not syncing correctly for the danger variant.\nfunction ConfirmModalIcon(props: ConfirmModalVariantProps) {\n const InfoIcon = $cerberusIcons.confirmModal\n return (\n <Show\n when={props.palette === 'danger'}\n fallback={\n <div className={cx(confirmModal().icon, circle())}>\n <InfoIcon />\n </div>\n }\n >\n <div\n className={cx(\n confirmModal({\n palette: 'danger',\n }).icon,\n circle({\n bgColor: 'danger.surface.initial',\n }),\n )}\n style={{\n color: 'var(--cerberus-colors-danger-text-100)',\n }}\n >\n <InfoIcon />\n </div>\n </Show>\n )\n}\n\nexport function useConfirmModal(): ConfirmModalValue {\n const context = useContext(ConfirmModalContext)\n if (context === null) {\n throw new Error(\n 'useConfirmModal must be used within a ConfirmModal Provider',\n )\n }\n return context\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/context/confirm-modal.tsx"],"sourcesContent":["'use client'\n\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n type MouseEvent,\n type PropsWithChildren,\n} from 'react'\nimport { Portal } from '../components/Portal'\nimport { Button } from '../components/Button'\nimport { css, cx } from '@cerberus-design/styled-system/css'\nimport { circle, hstack, vstack } from '@cerberus-design/styled-system/patterns'\nimport { $cerberusIcons } from '../config/defineIcons'\nimport {\n confirmModal,\n type ConfirmModalVariantProps,\n} from '@cerberus-design/styled-system/recipes'\nimport { trapFocus } from '../aria-helpers/trap-focus.aria'\nimport { Show } from '../components/Show'\n\n/**\n * This module provides a context and hook for the confirm modal.\n * @module\n */\n\nexport interface ShowConfirmModalOptions {\n kind?: 'destructive' | 'non-destructive'\n heading: string\n description?: string\n actionText: string\n cancelText: string\n}\nexport type ShowResult =\n | ((value: boolean | PromiseLike<boolean>) => void)\n | null\n\nexport interface ConfirmModalValue {\n show: (options: ShowConfirmModalOptions) => Promise<boolean>\n}\n\nconst ConfirmModalContext = createContext<ConfirmModalValue | null>(null)\n\nexport interface ConfirmModalProviderProps {}\n\n/**\n * Provides a confirm modal to the app.\n * @example\n * ```tsx\n * // Wrap the Provider around the root of the feature.\n * <ConfirmModal>\n * <SomeFeatureSection />\n * </ConfirmModal>\n *\n * // Use the hook to show the confirm modal.\n * const confirm = useConfirmModal()\n *\n * const handleClick = useCallback(async () => {\n * const userConsent = await confirm.show({\n * heading: 'Add new payment method?',\n * description:\n * 'This will add a new payment method to your account to be billed for future purchases.',\n * actionText: 'Yes, add payment method',\n * cancelText: 'No, cancel',\n * })\n * setConsent(userConsent)\n * }, [confirm])\n * ```\n */\nexport function ConfirmModal(\n props: PropsWithChildren<ConfirmModalProviderProps>,\n) {\n const dialogRef = useRef<HTMLDialogElement>(null)\n const resolveRef = useRef<ShowResult>(null)\n const [content, setContent] = useState<ShowConfirmModalOptions | null>(null)\n const focusTrap = trapFocus(dialogRef)\n\n const palette = useMemo(\n () => (content?.kind === 'destructive' ? 'danger' : 'action'),\n [content],\n )\n const styles = confirmModal({ palette })\n\n const handleChoice = useCallback((e: MouseEvent<HTMLButtonElement>) => {\n const target = e.currentTarget as HTMLButtonElement\n if (target.value === 'true') {\n resolveRef.current?.(true)\n }\n resolveRef.current?.(false)\n dialogRef?.current?.close()\n }, [])\n\n const handleShow = useCallback((options: ShowConfirmModalOptions) => {\n return new Promise<boolean>((resolve) => {\n setContent({ ...options, kind: options.kind || 'non-destructive' })\n dialogRef?.current?.showModal()\n resolveRef.current = resolve\n })\n }, [])\n\n const value = useMemo(\n () => ({\n show: handleShow,\n }),\n [handleShow],\n )\n\n return (\n <ConfirmModalContext.Provider value={value}>\n {props.children}\n\n <Portal>\n <dialog className={styles.dialog} onKeyDown={focusTrap} ref={dialogRef}>\n <div\n className={vstack({\n alignItems: 'flex-start',\n gap: '4',\n mb: '8',\n })}\n >\n <ConfirmModalIcon palette={palette} />\n <h2 className={styles.heading}>{content?.heading}</h2>\n <p className={styles.description}>{content?.description}</p>\n </div>\n\n <div\n className={hstack({\n justifyContent: 'stretch',\n gap: '4',\n })}\n >\n <Button\n autoFocus\n className={css({\n w: '1/2',\n })}\n name=\"confirm\"\n onClick={handleChoice}\n palette={palette}\n value=\"true\"\n >\n {content?.actionText}\n </Button>\n <Button\n className={css({\n w: '1/2',\n })}\n name=\"cancel\"\n onClick={handleChoice}\n usage=\"outlined\"\n value=\"false\"\n >\n {content?.cancelText}\n </Button>\n </div>\n </dialog>\n </Portal>\n </ConfirmModalContext.Provider>\n )\n}\n\n// This is to help show the variant styles for the icon since Panda is\n// not syncing correctly for the danger variant.\nfunction ConfirmModalIcon(props: ConfirmModalVariantProps) {\n const InfoIcon = $cerberusIcons.confirmModal\n return (\n <Show\n when={props.palette === 'danger'}\n fallback={\n <div className={cx(confirmModal().icon, circle())}>\n <InfoIcon />\n </div>\n }\n >\n <div\n className={cx(\n confirmModal({\n palette: 'danger',\n }).icon,\n circle({\n bgColor: 'danger.surface.initial',\n }),\n )}\n style={{\n color: 'var(--cerberus-colors-danger-text-100)',\n }}\n >\n <InfoIcon />\n </div>\n </Show>\n )\n}\n\nexport function useConfirmModal(): ConfirmModalValue {\n const context = useContext(ConfirmModalContext)\n if (context === null) {\n throw new Error(\n 'useConfirmModal must be used within a ConfirmModal Provider',\n )\n }\n return context\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAGP,SAAS,KAAK,UAAU;AACxB,SAAS,QAAQ,QAAQ,cAAc;AAEvC;AAAA,EACE;AAAA,OAEK;AAgGG,SAOE,KAPF;AAxEV,IAAM,sBAAsB,cAAwC,IAAI;AA4BjE,SAAS,aACd,OACA;AACA,QAAM,YAAY,OAA0B,IAAI;AAChD,QAAM,aAAa,OAAmB,IAAI;AAC1C,QAAM,CAAC,SAAS,UAAU,IAAI,SAAyC,IAAI;AAC3E,QAAM,YAAY,UAAU,SAAS;AAErC,QAAM,UAAU;AAAA,IACd,MAAO,SAAS,SAAS,gBAAgB,WAAW;AAAA,IACpD,CAAC,OAAO;AAAA,EACV;AACA,QAAM,SAAS,aAAa,EAAE,QAAQ,CAAC;AAEvC,QAAM,eAAe,YAAY,CAAC,MAAqC;AACrE,UAAM,SAAS,EAAE;AACjB,QAAI,OAAO,UAAU,QAAQ;AAC3B,iBAAW,UAAU,IAAI;AAAA,IAC3B;AACA,eAAW,UAAU,KAAK;AAC1B,eAAW,SAAS,MAAM;AAAA,EAC5B,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,YAAY,CAAC,YAAqC;AACnE,WAAO,IAAI,QAAiB,CAAC,YAAY;AACvC,iBAAW,EAAE,GAAG,SAAS,MAAM,QAAQ,QAAQ,kBAAkB,CAAC;AAClE,iBAAW,SAAS,UAAU;AAC9B,iBAAW,UAAU;AAAA,IACvB,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL,MAAM;AAAA,IACR;AAAA,IACA,CAAC,UAAU;AAAA,EACb;AAEA,SACE,qBAAC,oBAAoB,UAApB,EAA6B,OAC3B;AAAA,UAAM;AAAA,IAEP,oBAAC,UACC,+BAAC,YAAO,WAAW,OAAO,QAAQ,WAAW,WAAW,KAAK,WAC3D;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,OAAO;AAAA,YAChB,YAAY;AAAA,YACZ,KAAK;AAAA,YACL,IAAI;AAAA,UACN,CAAC;AAAA,UAED;AAAA,gCAAC,oBAAiB,SAAkB;AAAA,YACpC,oBAAC,QAAG,WAAW,OAAO,SAAU,mBAAS,SAAQ;AAAA,YACjD,oBAAC,OAAE,WAAW,OAAO,aAAc,mBAAS,aAAY;AAAA;AAAA;AAAA,MAC1D;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,OAAO;AAAA,YAChB,gBAAgB;AAAA,YAChB,KAAK;AAAA,UACP,CAAC;AAAA,UAED;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAS;AAAA,gBACT,WAAW,IAAI;AAAA,kBACb,GAAG;AAAA,gBACL,CAAC;AAAA,gBACD,MAAK;AAAA,gBACL,SAAS;AAAA,gBACT;AAAA,gBACA,OAAM;AAAA,gBAEL,mBAAS;AAAA;AAAA,YACZ;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW,IAAI;AAAA,kBACb,GAAG;AAAA,gBACL,CAAC;AAAA,gBACD,MAAK;AAAA,gBACL,SAAS;AAAA,gBACT,OAAM;AAAA,gBACN,OAAM;AAAA,gBAEL,mBAAS;AAAA;AAAA,YACZ;AAAA;AAAA;AAAA,MACF;AAAA,OACF,GACF;AAAA,KACF;AAEJ;AAIA,SAAS,iBAAiB,OAAiC;AACzD,QAAM,WAAW,eAAe;AAChC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM,MAAM,YAAY;AAAA,MACxB,UACE,oBAAC,SAAI,WAAW,GAAG,aAAa,EAAE,MAAM,OAAO,CAAC,GAC9C,8BAAC,YAAS,GACZ;AAAA,MAGF;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT,aAAa;AAAA,cACX,SAAS;AAAA,YACX,CAAC,EAAE;AAAA,YACH,OAAO;AAAA,cACL,SAAS;AAAA,YACX,CAAC;AAAA,UACH;AAAA,UACA,OAAO;AAAA,YACL,OAAO;AAAA,UACT;AAAA,UAEA,8BAAC,YAAS;AAAA;AAAA,MACZ;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,kBAAqC;AACnD,QAAM,UAAU,WAAW,mBAAmB;AAC9C,MAAI,YAAY,MAAM;AACpB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/config/cerbIcons.ts"],"sourcesContent":["import {\n Checkmark,\n Information,\n WarningFilled,\n type CarbonIconType,\n} from '@cerberus/icons'\nimport type { ElementType } from 'react'\n\nexport interface DefinedIcons {\n confirmModal?: CarbonIconType | ElementType\n invalid: CarbonIconType | ElementType\n toggleChecked?: CarbonIconType | ElementType\n}\n\nexport const defaultIcons: DefinedIcons = {\n confirmModal: Information,\n invalid: WarningFilled,\n toggleChecked: Checkmark,\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AASA,IAAM,eAA6B;AAAA,EACxC,cAAc;AAAA,EACd,SAAS;AAAA,EACT,eAAe;AACjB;","names":[]}