@cerberus-design/react 0.6.1-next-1315bf2 → 0.6.1-next-2d28489

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 (49) hide show
  1. package/build/legacy/_tsup-dts-rollup.d.ts +74 -0
  2. package/build/legacy/{chunk-3TYUA4C7.js → chunk-6TXQZ3PB.js} +2 -2
  3. package/build/{modern/chunk-5RA3ZIXA.js → legacy/chunk-7ISHDUYN.js} +2 -2
  4. package/build/legacy/{chunk-YRUUO4AP.js → chunk-BLJ4SRAF.js} +5 -4
  5. package/build/{modern/chunk-BVK6GEDZ.js.map → legacy/chunk-BLJ4SRAF.js.map} +1 -1
  6. package/build/legacy/{chunk-SCAVVE6E.js → chunk-C45DY4VE.js} +2 -1
  7. package/build/legacy/chunk-C45DY4VE.js.map +1 -0
  8. package/build/legacy/chunk-SNSBODYR.js +224 -0
  9. package/build/legacy/chunk-SNSBODYR.js.map +1 -0
  10. package/build/legacy/{chunk-VLVKNEA5.js → chunk-TAZI77TP.js} +2 -2
  11. package/build/legacy/components/Input.js +3 -3
  12. package/build/legacy/components/Toggle.js +3 -3
  13. package/build/legacy/config/cerbIcons.js +1 -1
  14. package/build/legacy/config/defineIcons.js +2 -2
  15. package/build/legacy/context/confirm-modal.js +5 -3
  16. package/build/legacy/context/prompt-modal.js +22 -0
  17. package/build/legacy/context/prompt-modal.js.map +1 -0
  18. package/build/legacy/index.js +15 -5
  19. package/build/modern/_tsup-dts-rollup.d.ts +74 -0
  20. package/build/modern/{chunk-BVK6GEDZ.js → chunk-4GURONLE.js} +5 -4
  21. package/build/{legacy/chunk-YRUUO4AP.js.map → modern/chunk-4GURONLE.js.map} +1 -1
  22. package/build/modern/{chunk-3TYUA4C7.js → chunk-6TXQZ3PB.js} +2 -2
  23. package/build/{legacy/chunk-5RA3ZIXA.js → modern/chunk-7ISHDUYN.js} +2 -2
  24. package/build/modern/{chunk-SCAVVE6E.js → chunk-C45DY4VE.js} +2 -1
  25. package/build/modern/chunk-C45DY4VE.js.map +1 -0
  26. package/build/modern/chunk-FZ75OJLJ.js +222 -0
  27. package/build/modern/chunk-FZ75OJLJ.js.map +1 -0
  28. package/build/modern/{chunk-VLVKNEA5.js → chunk-TAZI77TP.js} +2 -2
  29. package/build/modern/components/Input.js +3 -3
  30. package/build/modern/components/Toggle.js +3 -3
  31. package/build/modern/config/cerbIcons.js +1 -1
  32. package/build/modern/config/defineIcons.js +2 -2
  33. package/build/modern/context/confirm-modal.js +5 -3
  34. package/build/modern/context/prompt-modal.js +22 -0
  35. package/build/modern/context/prompt-modal.js.map +1 -0
  36. package/build/modern/index.js +15 -5
  37. package/package.json +2 -2
  38. package/src/config/cerbIcons.ts +2 -0
  39. package/src/context/confirm-modal.tsx +3 -3
  40. package/src/context/prompt-modal.tsx +254 -0
  41. package/src/index.ts +1 -0
  42. package/build/legacy/chunk-SCAVVE6E.js.map +0 -1
  43. package/build/modern/chunk-SCAVVE6E.js.map +0 -1
  44. /package/build/legacy/{chunk-3TYUA4C7.js.map → chunk-6TXQZ3PB.js.map} +0 -0
  45. /package/build/legacy/{chunk-5RA3ZIXA.js.map → chunk-7ISHDUYN.js.map} +0 -0
  46. /package/build/legacy/{chunk-VLVKNEA5.js.map → chunk-TAZI77TP.js.map} +0 -0
  47. /package/build/modern/{chunk-3TYUA4C7.js.map → chunk-6TXQZ3PB.js.map} +0 -0
  48. /package/build/modern/{chunk-5RA3ZIXA.js.map → chunk-7ISHDUYN.js.map} +0 -0
  49. /package/build/modern/{chunk-VLVKNEA5.js.map → chunk-TAZI77TP.js.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cerberus-design/react",
3
- "version": "0.6.1-next-1315bf2",
3
+ "version": "0.6.1-next-2d28489",
4
4
  "description": "The Cerberus Design React component library.",
5
5
  "browserslist": "> 0.25%, not dead",
6
6
  "sideEffects": false,
@@ -23,7 +23,7 @@
23
23
  "react-dom": "^18",
24
24
  "tsup": "^8.1.0",
25
25
  "@cerberus-design/configs": "0.0.0",
26
- "@cerberus-design/styled-system": "0.6.1-next-1315bf2"
26
+ "@cerberus-design/styled-system": "0.6.1-next-2d28489"
27
27
  },
28
28
  "publishConfig": {
29
29
  "access": "public"
@@ -8,12 +8,14 @@ import type { ElementType } from 'react'
8
8
 
9
9
  export interface DefinedIcons {
10
10
  confirmModal?: CarbonIconType | ElementType
11
+ promptModal?: CarbonIconType | ElementType
11
12
  invalid: CarbonIconType | ElementType
12
13
  toggleChecked?: CarbonIconType | ElementType
13
14
  }
14
15
 
15
16
  export const defaultIcons: DefinedIcons = {
16
17
  confirmModal: Information,
18
+ promptModal: Information,
17
19
  invalid: WarningFilled,
18
20
  toggleChecked: Checkmark,
19
21
  }
@@ -164,14 +164,14 @@ export function ConfirmModal(
164
164
 
165
165
  // This is to help show the variant styles for the icon since Panda is
166
166
  // not syncing correctly for the danger variant.
167
- function ConfirmModalIcon(props: ConfirmModalVariantProps) {
167
+ export function ConfirmModalIcon(props: ConfirmModalVariantProps) {
168
168
  const InfoIcon = $cerberusIcons.confirmModal
169
169
  return (
170
170
  <Show
171
171
  when={props.palette === 'danger'}
172
172
  fallback={
173
173
  <div className={cx(confirmModal().icon, circle())}>
174
- <InfoIcon />
174
+ <InfoIcon size={24} />
175
175
  </div>
176
176
  }
177
177
  >
@@ -188,7 +188,7 @@ function ConfirmModalIcon(props: ConfirmModalVariantProps) {
188
188
  color: 'var(--cerberus-colors-danger-text-100)',
189
189
  }}
190
190
  >
191
- <InfoIcon />
191
+ <InfoIcon size={24} />
192
192
  </div>
193
193
  </Show>
194
194
  )
@@ -0,0 +1,254 @@
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, cx } from '@cerberus-design/styled-system/css'
17
+ import { circle, hstack, vstack } from '@cerberus-design/styled-system/patterns'
18
+ import {
19
+ confirmModal,
20
+ type ConfirmModalVariantProps,
21
+ } from '@cerberus-design/styled-system/recipes'
22
+ import { trapFocus } from '../aria-helpers/trap-focus.aria'
23
+ import { Input } from '../components/Input'
24
+ import { Field } from './field'
25
+ import { Label } from '../components/Label'
26
+ import { ConfirmModalIcon } from './confirm-modal'
27
+ import { $cerberusIcons } from '../config/defineIcons'
28
+ import { Show } from '../components/Show'
29
+
30
+ /**
31
+ * This module provides a context and hook for the prompt modal.
32
+ * @module
33
+ */
34
+
35
+ export interface ShowPromptModalOptions {
36
+ kind?: 'destructive' | 'non-destructive'
37
+ heading: string
38
+ description?: string
39
+ key: string
40
+ actionText: string
41
+ cancelText: string
42
+ }
43
+ export type PromptShowResult =
44
+ | ((value: string | PromiseLike<string>) => void)
45
+ | null
46
+
47
+ export interface PromptModalValue {
48
+ show: (options: ShowPromptModalOptions) => Promise<string>
49
+ }
50
+
51
+ const PromptModalContext = createContext<PromptModalValue | null>(null)
52
+
53
+ export interface PromptModalProviderProps {}
54
+
55
+ /**
56
+ * Provides a prompt modal to the app.
57
+ * @example
58
+ * ```tsx
59
+ * // Wrap the Provider around the root of the feature.
60
+ * <PromptModal>
61
+ * <SomeFeatureSection />
62
+ * </PromptModal>
63
+ *
64
+ * // Use the hook to show the prompt modal.
65
+ * const prompt = usePromptModal()
66
+ *
67
+ * const handleClick = useCallback(async () => {
68
+ * const accepted = await prompt.show({
69
+ * kind: 'destructive',
70
+ * heading: 'Delete channel?',
71
+ * description:
72
+ * 'This will permanently delete a channel on your account. There is no going back.',
73
+ * key: CHANNEL_NAME,
74
+ * actionText: 'Yes, delete channel',
75
+ * cancelText: 'No, cancel',
76
+ * })
77
+ * // do something with accepted
78
+ * }, [prompt])
79
+ * ```
80
+ */
81
+ export function PromptModal(
82
+ props: PropsWithChildren<PromptModalProviderProps>,
83
+ ) {
84
+ const dialogRef = useRef<HTMLDialogElement>(null)
85
+ const resolveRef = useRef<PromptShowResult>(null)
86
+ const [content, setContent] = useState<ShowPromptModalOptions | null>(null)
87
+ const [inputValue, setInputValue] = useState<string>('')
88
+ const focusTrap = trapFocus(dialogRef)
89
+
90
+ const isValid = useMemo(
91
+ () => inputValue === content?.key,
92
+ [inputValue, content],
93
+ )
94
+
95
+ const palette = useMemo(
96
+ () => (content?.kind === 'destructive' ? 'danger' : 'action'),
97
+ [content],
98
+ )
99
+ const styles = confirmModal({ palette })
100
+
101
+ const handleChange = useCallback(
102
+ (e: ChangeEvent<HTMLInputElement>) => {
103
+ setInputValue(e.currentTarget.value)
104
+ },
105
+ [content],
106
+ )
107
+
108
+ const handleChoice = useCallback(
109
+ (e: MouseEvent<HTMLButtonElement>) => {
110
+ const target = e.currentTarget as HTMLButtonElement
111
+ if (target.value === 'true') {
112
+ resolveRef.current?.(inputValue)
113
+ }
114
+ dialogRef?.current?.close()
115
+ },
116
+ [inputValue],
117
+ )
118
+
119
+ const handleShow = useCallback((options: ShowPromptModalOptions) => {
120
+ return new Promise<string>((resolve) => {
121
+ setContent({ ...options, kind: options.kind || 'non-destructive' })
122
+ dialogRef?.current?.showModal()
123
+ resolveRef.current = resolve
124
+ })
125
+ }, [])
126
+
127
+ const value = useMemo(
128
+ () => ({
129
+ show: handleShow,
130
+ }),
131
+ [handleShow],
132
+ )
133
+
134
+ return (
135
+ <PromptModalContext.Provider value={value}>
136
+ {props.children}
137
+
138
+ <Portal>
139
+ <dialog className={styles.dialog} onKeyDown={focusTrap} ref={dialogRef}>
140
+ <div
141
+ className={vstack({
142
+ alignItems: 'flex-start',
143
+ gap: '4',
144
+ })}
145
+ >
146
+ <ConfirmModalIcon palette={palette} />
147
+ <h2 className={styles.heading}>{content?.heading}</h2>
148
+ <p className={styles.description}>{content?.description}</p>
149
+ </div>
150
+
151
+ <div
152
+ className={vstack({
153
+ alignItems: 'flex-start',
154
+ mt: '4',
155
+ mb: '8',
156
+ })}
157
+ >
158
+ <Field invalid={!isValid}>
159
+ <Label htmlFor="confirm" size="md">
160
+ Type
161
+ <strong
162
+ className={css({
163
+ textTransform: 'uppercase',
164
+ })}
165
+ >
166
+ {content?.key}
167
+ </strong>
168
+ to confirm
169
+ </Label>
170
+ <Input
171
+ id="confirm"
172
+ name="confirm"
173
+ onChange={handleChange}
174
+ type="text"
175
+ />
176
+ </Field>
177
+ </div>
178
+
179
+ <div
180
+ className={hstack({
181
+ justifyContent: 'stretch',
182
+ gap: '4',
183
+ })}
184
+ >
185
+ <Button
186
+ autoFocus
187
+ className={css({
188
+ w: '1/2',
189
+ })}
190
+ disabled={!isValid}
191
+ name="confirm"
192
+ onClick={handleChoice}
193
+ palette={palette}
194
+ value="true"
195
+ >
196
+ {content?.actionText}
197
+ </Button>
198
+ <Button
199
+ className={css({
200
+ w: '1/2',
201
+ })}
202
+ name="cancel"
203
+ onClick={handleChoice}
204
+ usage="outlined"
205
+ value="false"
206
+ >
207
+ {content?.cancelText}
208
+ </Button>
209
+ </div>
210
+ </dialog>
211
+ </Portal>
212
+ </PromptModalContext.Provider>
213
+ )
214
+ }
215
+
216
+ // This is to help show the variant styles for the icon since Panda is
217
+ // not syncing correctly for the danger variant.
218
+ export function PromptModalIcon(props: ConfirmModalVariantProps) {
219
+ const PromptIcon = $cerberusIcons.promptModal
220
+ return (
221
+ <Show
222
+ when={props.palette === 'danger'}
223
+ fallback={
224
+ <div className={cx(confirmModal().icon, circle())}>
225
+ <PromptIcon size={24} />
226
+ </div>
227
+ }
228
+ >
229
+ <div
230
+ className={cx(
231
+ confirmModal({
232
+ palette: 'danger',
233
+ }).icon,
234
+ circle({
235
+ bgColor: 'danger.surface.initial',
236
+ }),
237
+ )}
238
+ style={{
239
+ color: 'var(--cerberus-colors-danger-text-100)',
240
+ }}
241
+ >
242
+ <PromptIcon size={24} />
243
+ </div>
244
+ </Show>
245
+ )
246
+ }
247
+
248
+ export function usePromptModal(): PromptModalValue {
249
+ const context = useContext(PromptModalContext)
250
+ if (context === null) {
251
+ throw new Error('usePromptModal must be used within a PromptModal Provider')
252
+ }
253
+ return context
254
+ }
package/src/index.ts CHANGED
@@ -30,6 +30,7 @@ export * from './context/confirm-modal'
30
30
  export * from './context/feature-flags'
31
31
  export * from './context/field'
32
32
  export * from './context/navMenu'
33
+ export * from './context/prompt-modal'
33
34
  export * from './context/tabs'
34
35
  export * from './context/theme'
35
36
 
@@ -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/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":[]}