@cerberus-design/react 0.11.1 → 0.12.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.
Files changed (162) hide show
  1. package/build/legacy/_tsup-dts-rollup.d.cts +244 -33
  2. package/build/legacy/components/Admonition.cjs +1 -1
  3. package/build/legacy/components/Admonition.cjs.map +1 -1
  4. package/build/legacy/components/Avatar.cjs +1 -1
  5. package/build/legacy/components/Avatar.cjs.map +1 -1
  6. package/build/legacy/components/Checkbox.cjs +1 -1
  7. package/build/legacy/components/Checkbox.cjs.map +1 -1
  8. package/build/legacy/components/FileStatus.cjs +1 -1
  9. package/build/legacy/components/FileStatus.cjs.map +1 -1
  10. package/build/legacy/components/FileUploader.cjs +1 -1
  11. package/build/legacy/components/FileUploader.cjs.map +1 -1
  12. package/build/legacy/components/Input.cjs +1 -1
  13. package/build/legacy/components/Input.cjs.map +1 -1
  14. package/build/legacy/components/Menu.cjs +82 -0
  15. package/build/legacy/components/Menu.cjs.map +1 -0
  16. package/build/legacy/components/ModalHeader.cjs +2 -1
  17. package/build/legacy/components/ModalHeader.cjs.map +1 -1
  18. package/build/legacy/components/NavMenuLink.cjs.map +1 -1
  19. package/build/legacy/components/NavMenuList.cjs.map +1 -1
  20. package/build/legacy/components/NavMenuTrigger.cjs.map +1 -1
  21. package/build/legacy/components/Notification.cjs +3 -3
  22. package/build/legacy/components/Notification.cjs.map +1 -1
  23. package/build/legacy/components/Select.cjs +1 -1
  24. package/build/legacy/components/Select.cjs.map +1 -1
  25. package/build/legacy/components/Tag.cjs +3 -3
  26. package/build/legacy/components/Tag.cjs.map +1 -1
  27. package/build/legacy/components/Tbody.cjs.map +1 -1
  28. package/build/legacy/components/Td.cjs.map +1 -1
  29. package/build/legacy/components/Th.cjs +1 -0
  30. package/build/legacy/components/Th.cjs.map +1 -1
  31. package/build/legacy/components/Thead.cjs.map +1 -1
  32. package/build/legacy/components/Toggle.cjs +1 -1
  33. package/build/legacy/components/Toggle.cjs.map +1 -1
  34. package/build/legacy/config/cerbIcons.cjs +1 -1
  35. package/build/legacy/config/cerbIcons.cjs.map +1 -1
  36. package/build/legacy/config/defineIcons.cjs +1 -1
  37. package/build/legacy/config/defineIcons.cjs.map +1 -1
  38. package/build/legacy/context/confirm-modal.cjs +3 -2
  39. package/build/legacy/context/confirm-modal.cjs.map +1 -1
  40. package/build/legacy/context/cta-modal.cjs +567 -0
  41. package/build/legacy/context/cta-modal.cjs.map +1 -0
  42. package/build/legacy/context/navMenu.cjs.map +1 -1
  43. package/build/legacy/context/notification-center.cjs +3 -3
  44. package/build/legacy/context/notification-center.cjs.map +1 -1
  45. package/build/legacy/context/prompt-modal.cjs +3 -2
  46. package/build/legacy/context/prompt-modal.cjs.map +1 -1
  47. package/build/legacy/index.cjs +501 -324
  48. package/build/legacy/index.cjs.map +1 -1
  49. package/build/legacy/utils/index.cjs +34 -0
  50. package/build/legacy/utils/index.cjs.map +1 -0
  51. package/build/modern/_tsup-dts-rollup.d.ts +244 -33
  52. package/build/modern/{chunk-HPM2XRWT.js → chunk-3R4TIF2X.js} +1 -1
  53. package/build/modern/{chunk-HPM2XRWT.js.map → chunk-3R4TIF2X.js.map} +1 -1
  54. package/build/modern/{chunk-RDQHHCFR.js → chunk-5OSUZUR4.js} +2 -2
  55. package/build/modern/{chunk-O75QAT4Z.js → chunk-6WS765J3.js} +1 -1
  56. package/build/modern/chunk-6WS765J3.js.map +1 -0
  57. package/build/modern/{chunk-KLUBAM4U.js → chunk-7SGPJM66.js} +4 -4
  58. package/build/modern/chunk-7SGPJM66.js.map +1 -0
  59. package/build/modern/{chunk-X4Y4WTRU.js → chunk-CSEHDNMJ.js} +7 -7
  60. package/build/modern/{chunk-TMR7JGMP.js → chunk-F27AAKQ3.js} +3 -3
  61. package/build/modern/chunk-F27AAKQ3.js.map +1 -0
  62. package/build/modern/{chunk-243VUIA6.js → chunk-F72ZABKX.js} +2 -2
  63. package/build/modern/chunk-F72ZABKX.js.map +1 -0
  64. package/build/modern/{chunk-KF6V5JLW.js → chunk-N4QTLDVM.js} +3 -3
  65. package/build/modern/{chunk-MDIUFBDX.js → chunk-NB6DV4VA.js} +2 -2
  66. package/build/modern/{chunk-UJKS4DDN.js → chunk-NKM6PISB.js} +2 -2
  67. package/build/modern/{chunk-YWCTMLLO.js → chunk-NMNONSHU.js} +2 -2
  68. package/build/modern/{chunk-OWKN5IV7.js → chunk-PM7CWT3N.js} +2 -2
  69. package/build/modern/chunk-PM7CWT3N.js.map +1 -0
  70. package/build/modern/chunk-RUR5MV54.js +52 -0
  71. package/build/modern/chunk-RUR5MV54.js.map +1 -0
  72. package/build/modern/{chunk-CO4BKT7K.js → chunk-SGKHA4EB.js} +1 -1
  73. package/build/modern/chunk-SGKHA4EB.js.map +1 -0
  74. package/build/modern/{chunk-ZX6DBC2Z.js → chunk-SPZYPRZ6.js} +2 -2
  75. package/build/modern/chunk-T6LS5P5W.js +155 -0
  76. package/build/modern/chunk-T6LS5P5W.js.map +1 -0
  77. package/build/modern/chunk-UTGEFJ3L.js +10 -0
  78. package/build/modern/chunk-UTGEFJ3L.js.map +1 -0
  79. package/build/modern/{chunk-5V5MBSM3.js → chunk-UZVQ4INR.js} +2 -2
  80. package/build/modern/chunk-UZVQ4INR.js.map +1 -0
  81. package/build/modern/{chunk-FT7DFRHQ.js → chunk-VERRHMW4.js} +2 -2
  82. package/build/modern/{chunk-3NE6C66J.js → chunk-VP5ERLAY.js} +8 -8
  83. package/build/modern/{chunk-HCB5NQ5J.js → chunk-W4DXACNV.js} +3 -3
  84. package/build/modern/{chunk-KBBASJIY.js → chunk-WPVDQRRF.js} +1 -1
  85. package/build/modern/chunk-WPVDQRRF.js.map +1 -0
  86. package/build/modern/{chunk-PA5EB7EO.js → chunk-XL4JREDT.js} +2 -2
  87. package/build/modern/{chunk-PKY46RRA.js → chunk-Y6QQCRQV.js} +1 -1
  88. package/build/modern/{chunk-PKY46RRA.js.map → chunk-Y6QQCRQV.js.map} +1 -1
  89. package/build/modern/{chunk-YMJMB6OP.js → chunk-ZBMA5G54.js} +6 -6
  90. package/build/modern/{chunk-ULYQLKWA.js → chunk-ZFAIE47A.js} +3 -2
  91. package/build/modern/{chunk-ULYQLKWA.js.map → chunk-ZFAIE47A.js.map} +1 -1
  92. package/build/modern/{chunk-PKQTTFWA.js → chunk-ZR37P4NZ.js} +1 -1
  93. package/build/modern/{chunk-PKQTTFWA.js.map → chunk-ZR37P4NZ.js.map} +1 -1
  94. package/build/modern/components/Admonition.js +4 -4
  95. package/build/modern/components/Avatar.js +3 -3
  96. package/build/modern/components/Checkbox.js +3 -3
  97. package/build/modern/components/FileStatus.js +5 -5
  98. package/build/modern/components/FileUploader.js +4 -4
  99. package/build/modern/components/Input.js +3 -3
  100. package/build/modern/components/Menu.js +19 -0
  101. package/build/modern/components/Menu.js.map +1 -0
  102. package/build/modern/components/ModalHeader.js +1 -1
  103. package/build/modern/components/NavMenuLink.js +1 -1
  104. package/build/modern/components/NavMenuList.js +2 -2
  105. package/build/modern/components/NavMenuTrigger.js +2 -2
  106. package/build/modern/components/Notification.js +3 -3
  107. package/build/modern/components/Select.js +3 -3
  108. package/build/modern/components/Tag.js +3 -3
  109. package/build/modern/components/Tbody.js +1 -1
  110. package/build/modern/components/Td.js +1 -1
  111. package/build/modern/components/Th.js +2 -1
  112. package/build/modern/components/Thead.js +1 -1
  113. package/build/modern/components/Toggle.js +3 -3
  114. package/build/modern/config/cerbIcons.js +1 -1
  115. package/build/modern/config/defineIcons.js +2 -2
  116. package/build/modern/context/confirm-modal.js +6 -6
  117. package/build/modern/context/cta-modal.js +25 -0
  118. package/build/modern/context/cta-modal.js.map +1 -0
  119. package/build/modern/context/navMenu.js +1 -1
  120. package/build/modern/context/notification-center.js +4 -4
  121. package/build/modern/context/prompt-modal.js +7 -7
  122. package/build/modern/index.js +72 -46
  123. package/build/modern/index.js.map +1 -1
  124. package/build/modern/utils/index.js +7 -0
  125. package/build/modern/utils/index.js.map +1 -0
  126. package/package.json +3 -2
  127. package/src/components/Menu.tsx +244 -0
  128. package/src/components/ModalHeader.tsx +1 -0
  129. package/src/components/NavMenuLink.tsx +1 -11
  130. package/src/components/NavMenuList.tsx +1 -3
  131. package/src/components/NavMenuTrigger.tsx +1 -10
  132. package/src/components/Notification.tsx +2 -2
  133. package/src/components/Tag.tsx +8 -4
  134. package/src/components/Tbody.tsx +1 -2
  135. package/src/components/Td.tsx +1 -2
  136. package/src/components/Th.tsx +4 -2
  137. package/src/components/Thead.tsx +1 -2
  138. package/src/config/cerbIcons.ts +2 -2
  139. package/src/context/cta-modal.tsx +210 -0
  140. package/src/context/navMenu.tsx +1 -2
  141. package/src/index.ts +3 -0
  142. package/src/utils/index.ts +19 -0
  143. package/build/modern/chunk-243VUIA6.js.map +0 -1
  144. package/build/modern/chunk-5V5MBSM3.js.map +0 -1
  145. package/build/modern/chunk-CO4BKT7K.js.map +0 -1
  146. package/build/modern/chunk-KBBASJIY.js.map +0 -1
  147. package/build/modern/chunk-KLUBAM4U.js.map +0 -1
  148. package/build/modern/chunk-O75QAT4Z.js.map +0 -1
  149. package/build/modern/chunk-OWKN5IV7.js.map +0 -1
  150. package/build/modern/chunk-TMR7JGMP.js.map +0 -1
  151. /package/build/modern/{chunk-RDQHHCFR.js.map → chunk-5OSUZUR4.js.map} +0 -0
  152. /package/build/modern/{chunk-X4Y4WTRU.js.map → chunk-CSEHDNMJ.js.map} +0 -0
  153. /package/build/modern/{chunk-KF6V5JLW.js.map → chunk-N4QTLDVM.js.map} +0 -0
  154. /package/build/modern/{chunk-MDIUFBDX.js.map → chunk-NB6DV4VA.js.map} +0 -0
  155. /package/build/modern/{chunk-UJKS4DDN.js.map → chunk-NKM6PISB.js.map} +0 -0
  156. /package/build/modern/{chunk-YWCTMLLO.js.map → chunk-NMNONSHU.js.map} +0 -0
  157. /package/build/modern/{chunk-ZX6DBC2Z.js.map → chunk-SPZYPRZ6.js.map} +0 -0
  158. /package/build/modern/{chunk-FT7DFRHQ.js.map → chunk-VERRHMW4.js.map} +0 -0
  159. /package/build/modern/{chunk-3NE6C66J.js.map → chunk-VP5ERLAY.js.map} +0 -0
  160. /package/build/modern/{chunk-HCB5NQ5J.js.map → chunk-W4DXACNV.js.map} +0 -0
  161. /package/build/modern/{chunk-PA5EB7EO.js.map → chunk-XL4JREDT.js.map} +0 -0
  162. /package/build/modern/{chunk-YMJMB6OP.js.map → chunk-ZBMA5G54.js.map} +0 -0
@@ -0,0 +1,244 @@
1
+ import { Menu as ArkMenu } from '@ark-ui/react'
2
+ import { menu } from '@cerberus/styled-system/recipes'
3
+ import { cx } from '@cerberus/styled-system/css'
4
+
5
+ /**
6
+ * This module contains the Menu component family.
7
+ * @module Menu
8
+ */
9
+
10
+ const menuStyles = menu()
11
+
12
+ /**
13
+ * The root Menu component which controls the menu.
14
+ * @definition [Cerberus docs](https://cerberus.digitalu.design/react/menu)
15
+ * @example
16
+ * ```tsx
17
+ * <Menu>
18
+ * <MenuTrigger>Trigger</MenuTrigger>
19
+ * </Menu>
20
+ */
21
+ export const Menu = ArkMenu.Root
22
+
23
+ /**
24
+ * The MenuTrigger component opens/closes the Menu.
25
+ * @definition [Cerberus docs](https://cerberus.digitalu.design/react/menu)
26
+ * @example
27
+ * ```tsx
28
+ * <Menu>
29
+ * <MenuTrigger>
30
+ * <Button>Trigger</Button>
31
+ * </MenuTrigger>
32
+ * </Menu>
33
+ */
34
+ export function MenuTrigger(props: ArkMenu.TriggerProps) {
35
+ return <ArkMenu.Trigger {...props} asChild />
36
+ }
37
+
38
+ /**
39
+ * The MenuContent component is the container for the menu items.
40
+ * @definition [Cerberus docs](https://cerberus.digitalu.design/react/menu)
41
+ * @example
42
+ * ```tsx
43
+ * <Menu>
44
+ * <MenuTrigger>
45
+ * <Button>Trigger</Button>
46
+ * </MenuTrigger>
47
+ * <MenuContent>
48
+ * <MenuItem value="item_1">Item 1</MenuItem>
49
+ * <MenuItem value="item_2">Item 2</MenuItem>
50
+ * </MenuContent>
51
+ * </Menu>
52
+ */
53
+ export function MenuContent(props: ArkMenu.ContentProps) {
54
+ return (
55
+ <ArkMenu.Positioner>
56
+ <ArkMenu.Content
57
+ {...props}
58
+ className={cx(props.className, menuStyles.content)}
59
+ />
60
+ </ArkMenu.Positioner>
61
+ )
62
+ }
63
+
64
+ /**
65
+ * The MenuItem component is a single item in the menu.
66
+ * @definition [Cerberus docs](https://cerberus.digitalu.design/react/menu)
67
+ * @example
68
+ * ```tsx
69
+ * <Menu>
70
+ * <MenuTrigger>
71
+ * <Button>Trigger</Button>
72
+ * </MenuTrigger>
73
+ * <MenuContent>
74
+ * <MenuItem value="item_1">Item 1</MenuItem>
75
+ * <MenuItem value="item_2">Item 2</MenuItem>
76
+ * </MenuContent>
77
+ * </Menu>
78
+ */
79
+ export function MenuItem(props: ArkMenu.ItemProps) {
80
+ return (
81
+ <ArkMenu.Item {...props} className={cx(props.className, menuStyles.item)} />
82
+ )
83
+ }
84
+
85
+ /**
86
+ * The MenuItemGroup component is a group of menu items.
87
+ * @definition [Cerberus docs](https://cerberus.digitalu.design/react/menu)
88
+ * @example
89
+ * ```tsx
90
+ * <Menu>
91
+ * <MenuTrigger>
92
+ * <Button>Trigger</Button>
93
+ * </MenuTrigger>
94
+ * <MenuContent>
95
+ * <MenuItemGroup>
96
+ * <MenuItem value="item_1">Item 1</MenuItem>
97
+ * <MenuItem value="item_2">Item 2</MenuItem>
98
+ * </MenuItemGroup>
99
+ * </MenuContent>
100
+ * </Menu>
101
+ */
102
+ export const MenuItemGroup = ArkMenu.ItemGroup
103
+
104
+ /**
105
+ * The MenuItemGroupLabel component is the label for a group of menu items.
106
+ * @definition [Cerberus docs](https://cerberus.digitalu.design/react/menu)
107
+ * @example
108
+ * ```tsx
109
+ * <Menu>
110
+ * <MenuTrigger>
111
+ * <Button>Trigger</Button>
112
+ * </MenuTrigger>
113
+ * <MenuContent>
114
+ * <MenuItemGroup>
115
+ * <MenuItemGroupLabel>Group Label</MenuItemGroupLabel>
116
+ * <MenuItem value="item_1">Item 1</MenuItem>
117
+ * <MenuItem value="item_2">Item 2</MenuItem>
118
+ * </MenuItemGroup>
119
+ * </MenuContent>
120
+ * </Menu>
121
+ */
122
+ export function MenuGroupLabel(props: ArkMenu.ItemGroupLabelProps) {
123
+ return (
124
+ <ArkMenu.ItemGroupLabel
125
+ {...props}
126
+ className={cx(props.className, menuStyles.itemGroupLabel)}
127
+ />
128
+ )
129
+ }
130
+
131
+ /**
132
+ * The MenuSeparator component is a visual divider between menu items.
133
+ * @definition [Cerberus docs](https://cerberus.digitalu.design/react/menu)
134
+ * @example
135
+ * ```tsx
136
+ * <Menu>
137
+ * <MenuTrigger>
138
+ * <Button>Trigger</Button>
139
+ * </MenuTrigger>
140
+ * <MenuContent>
141
+ * <MenuItemGroup>
142
+ * <MenuGroupLabel>Group Label</MenuGroupLabel>
143
+ * <MenuSeparator />
144
+ * <MenuItem value="item_1">Item 1</MenuItem>
145
+ * <MenuItem value="item_2">Item 2</MenuItem>
146
+ * </MenuItemGroup>
147
+ * </MenuContent>
148
+ * </Menu>
149
+ */
150
+ export function MenuSeparator(props: ArkMenu.SeparatorProps) {
151
+ return (
152
+ <ArkMenu.Separator
153
+ {...props}
154
+ className={cx(props.className, menuStyles.separator)}
155
+ />
156
+ )
157
+ }
158
+
159
+ /**
160
+ * The MenuCheckboxItem component is a menu item with a checkbox.
161
+ * @definition [Cerberus docs](https://cerberus.digitalu.design/react/menu)
162
+ * @example
163
+ * ```tsx
164
+ * <Menu>
165
+ * <MenuTrigger>
166
+ * <Button>Trigger</Button>
167
+ * </MenuTrigger>
168
+ * <MenuContent>
169
+ * <MenuCheckboxItem
170
+ * checked={checked}
171
+ * onCheckedChange={setChecked}
172
+ * value="checked"
173
+ * >
174
+ * <MenuItemIndicator>✅</MenuItemIndicator>
175
+ * <MenuItemText>Check me</MenuItemText>
176
+ * </MenuCheckboxItem>
177
+ * </MenuContent>
178
+ */
179
+ // export function MenuCheckboxItem(props: ArkMenu.CheckboxItemProps) {
180
+ // return (
181
+ // <ArkMenu.CheckboxItem
182
+ // {...props}
183
+ // className={cx(props.className, menuStyles.item)}
184
+ // />
185
+ // )
186
+ // }
187
+
188
+ /**
189
+ * The MenuItemText component is the text for a grouped menu item.
190
+ * @definition [Cerberus docs](https://cerberus.digitalu.design/react/menu)
191
+ * @example
192
+ * ```tsx
193
+ * <Menu>
194
+ * <MenuTrigger>
195
+ * <Button>Trigger</Button>
196
+ * </MenuTrigger>
197
+ * <MenuContent>
198
+ * <MenuCheckboxItem
199
+ * checked={checked}
200
+ * onCheckedChange={setChecked}
201
+ * value="checked"
202
+ * >
203
+ * <MenuItemText>Item 1</MenuItemText>
204
+ * </MenuCheckboxItem>
205
+ * </MenuContent>
206
+ * </Menu>
207
+ */
208
+ // export function MenuItemText(props: ArkMenu.ItemTextProps) {
209
+ // return (
210
+ // <ArkMenu.ItemText
211
+ // {...props}
212
+ // className={cx(props.className, menuStyles.itemText)}
213
+ // />
214
+ // )
215
+ // }
216
+
217
+ /**
218
+ * The MenuItemIndicator component is the indicator for a grouped menu item.
219
+ * @definition [Cerberus docs](https://cerberus.digitalu.design/react/menu)
220
+ * @example
221
+ * ```tsx
222
+ * <Menu>
223
+ * <MenuTrigger>
224
+ * <Button>Trigger</Button>
225
+ * </MenuTrigger>
226
+ * <MenuContent>
227
+ * <MenuCheckboxItem
228
+ * checked={checked}
229
+ * onCheckedChange={setChecked}
230
+ * value="checked"
231
+ * >
232
+ * <MenuItemIndicator>✅</MenuItemIndicator>
233
+ * <MenuItemText>Check me</MenuItemText>
234
+ * </MenuCheckboxItem>
235
+ * </MenuContent>
236
+ */
237
+ // export function MenuItemIndicator(props: ArkMenu.ItemIndicatorProps) {
238
+ // return (
239
+ // <ArkMenu.ItemIndicator
240
+ // {...props}
241
+ // className={cx(props.className, menuStyles.itemIndicator)}
242
+ // />
243
+ // )
244
+ // }
@@ -31,6 +31,7 @@ export function ModalHeader(props: ModalHeaderProps) {
31
31
  alignItems: 'flex-start',
32
32
  gap: 'md',
33
33
  mb: 'md',
34
+ position: 'relative',
34
35
  }),
35
36
  )}
36
37
  />
@@ -17,17 +17,7 @@ export interface NavMenuLinkProps
17
17
  }
18
18
 
19
19
  /**
20
- * The NavMenuLink component is a link element that is used within the NavMenu.
21
- * @see https://cerberus.digitalu.design/react/nav-menu
22
- * @example
23
- * ```tsx
24
- * <NavMenu>
25
- * <NavMenuList id="nav-menu-list" position="bottom">
26
- * <NavMenuLink href="/home">Home</NavMenuLink>
27
- * <NavMenuLink href="/about">About</NavMenuLink>
28
- * </NavMenuList>
29
- * </NavMenu>
30
- * ```
20
+ * @deprecated use the {@link Menu} family instead
31
21
  */
32
22
  export function NavMenuLink(props: NavMenuLinkProps): JSX.Element {
33
23
  const { as, ...nativeProps } = props
@@ -32,9 +32,7 @@ interface GetPositionResult {
32
32
  }
33
33
 
34
34
  /**
35
- * Returns the position of the NavMenuList based on the position prop.
36
- * @param position - The position of the NavMenuList.
37
- * @returns The position of the NavMenuList.
35
+ * @deprecated use the {@link Menu} family instead
38
36
  */
39
37
  export function getPosition(position: Positions): GetPositionResult {
40
38
  const defaultPositions = {
@@ -37,16 +37,7 @@ export interface NavMenuTriggerProps
37
37
  }
38
38
 
39
39
  /**
40
- * A component that allows the user to trigger a navigation menu.
41
- * @definition [NavMenu Docs](https://cerberus.digitalu.design/react/nav-menu)
42
- * @example
43
- * ```tsx
44
- * <NavMenu>
45
- * <NavMenuTrigger controls="nav-menu-list">
46
- * Menu
47
- * </NavMenuTrigger>
48
- * </NavMenu>
49
- * ```
40
+ * @deprecated use the {@link Menu} family instead
50
41
  */
51
42
  export function NavMenuTrigger(props: NavMenuTriggerProps): JSX.Element {
52
43
  const {
@@ -12,7 +12,6 @@ import {
12
12
  type PropsWithChildren,
13
13
  type MouseEvent,
14
14
  } from 'react'
15
- import { Close } from '@cerberus/icons'
16
15
  import { $cerberusIcons } from '../config/defineIcons'
17
16
  import type { IconType } from '../config/cerbIcons'
18
17
  import { trapFocus } from '../aria-helpers/trap-focus.aria'
@@ -62,6 +61,7 @@ export function Notification(props: PropsWithChildren<NotificationProps>) {
62
61
  const ref = useRef<HTMLDialogElement>(null)
63
62
  const onKeyDown = trapFocus(ref)
64
63
  const styles = notification({ palette })
64
+ const { close: CloseIcon } = $cerberusIcons
65
65
 
66
66
  return (
67
67
  <dialog
@@ -97,7 +97,7 @@ export function Notification(props: PropsWithChildren<NotificationProps>) {
97
97
  onClick={onClose}
98
98
  value={props.id}
99
99
  >
100
- <Close />
100
+ <CloseIcon />
101
101
  </button>
102
102
  </dialog>
103
103
  )
@@ -1,4 +1,8 @@
1
- import type { HTMLAttributes, PropsWithChildren } from 'react'
1
+ import type {
2
+ HTMLAttributes,
3
+ MouseEventHandler,
4
+ PropsWithChildren,
5
+ } from 'react'
2
6
  import { Show } from './Show'
3
7
  import { css, cx } from '@cerberus/styled-system/css'
4
8
  import {
@@ -36,19 +40,19 @@ export type ClickableTagProps = HTMLAttributes<HTMLSpanElement> & {
36
40
  /**
37
41
  * The action to be performed when the tag is clicked.
38
42
  */
39
- onClick: () => void
43
+ onClick: MouseEventHandler<HTMLSpanElement>
40
44
  /**
41
45
  * The shape of the tag. Not available when the onClick prop is provided.
42
46
  * @type 'pill' | 'rounded'
43
47
  * @default 'pill'
44
48
  */
45
- shape: 'pill'
49
+ shape?: never
46
50
  /**
47
51
  * The usage of the tag. Not available when the onClick prop is provided.
48
52
  * @type 'filled' | 'outlined'
49
53
  * @default 'filled'
50
54
  */
51
- usage: 'filled'
55
+ usage?: never
52
56
  }
53
57
 
54
58
  export type TagProps = StaticTagProps | ClickableTagProps
@@ -1,13 +1,12 @@
1
1
  import { tbody, type TbodyVariantProps } from '@cerberus/styled-system/recipes'
2
2
  import { cx } from '@cerberus/styled-system/css'
3
- import type { TableHTMLAttributes } from 'react'
4
3
 
5
4
  /**
6
5
  * This module provides a TBody component.
7
6
  * @module
8
7
  */
9
8
 
10
- export type TbodyBaseProps = TableHTMLAttributes<HTMLTableSectionElement>
9
+ export type TbodyBaseProps = JSX.IntrinsicElements['tbody']
11
10
  export type TbodyProps = TbodyBaseProps & TbodyVariantProps
12
11
 
13
12
  /**
@@ -1,13 +1,12 @@
1
1
  import { cx } from '@cerberus/styled-system/css'
2
2
  import { td, type TdVariantProps } from '@cerberus/styled-system/recipes'
3
- import type { TableHTMLAttributes } from 'react'
4
3
 
5
4
  /**
6
5
  * Th component for the Td component
7
6
  * @module
8
7
  */
9
8
 
10
- export type TdBaseProps = TableHTMLAttributes<HTMLTableCellElement>
9
+ export type TdBaseProps = JSX.IntrinsicElements['td']
11
10
  export type TdProps = TdBaseProps & TdVariantProps
12
11
 
13
12
  /**
@@ -1,6 +1,8 @@
1
+ 'use client'
2
+
1
3
  import { css, cx } from '@cerberus/styled-system/css'
2
4
  import { th, type ThVariantProps } from '@cerberus/styled-system/recipes'
3
- import type { MouseEvent, TableHTMLAttributes } from 'react'
5
+ import type { MouseEvent } from 'react'
4
6
  import { Show } from './Show'
5
7
 
6
8
  /**
@@ -8,7 +10,7 @@ import { Show } from './Show'
8
10
  * @module
9
11
  */
10
12
 
11
- export type ThBaseProps = TableHTMLAttributes<HTMLTableCellElement> & {
13
+ export type ThBaseProps = JSX.IntrinsicElements['th'] & {
12
14
  /**
13
15
  * Converts the Th into a actionable button. Called when the user clicks on
14
16
  * the Th.
@@ -1,13 +1,12 @@
1
1
  import { cx } from '@cerberus/styled-system/css'
2
2
  import { thead } from '@cerberus/styled-system/recipes'
3
- import type { TableHTMLAttributes } from 'react'
4
3
 
5
4
  /**
6
5
  * This module contains the Thead component.
7
6
  * @module
8
7
  */
9
8
 
10
- export type TheadProps = TableHTMLAttributes<HTMLTableSectionElement>
9
+ export type TheadProps = JSX.IntrinsicElements['thead']
11
10
 
12
11
  /**
13
12
  * The Thead component is used to render a table header.
@@ -2,7 +2,7 @@ import {
2
2
  Checkmark,
3
3
  CheckmarkOutline,
4
4
  ChevronDown,
5
- CloseFilled,
5
+ Close,
6
6
  CloudUpload,
7
7
  Information,
8
8
  Restart,
@@ -43,7 +43,7 @@ export interface DefinedIcons {
43
43
  export const defaultIcons: DefinedIcons = {
44
44
  avatar: UserFilled,
45
45
  checkbox: CheckmarkIcon,
46
- close: CloseFilled,
46
+ close: Close,
47
47
  confirmModal: Information,
48
48
  delete: TrashCan,
49
49
  promptModal: Information,
@@ -0,0 +1,210 @@
1
+ 'use client'
2
+
3
+ import {
4
+ createContext,
5
+ useCallback,
6
+ useContext,
7
+ useMemo,
8
+ useState,
9
+ type ButtonHTMLAttributes,
10
+ type MouseEvent,
11
+ type PropsWithChildren,
12
+ type ReactNode,
13
+ } from 'react'
14
+ import { Portal } from '../components/Portal'
15
+ import { Button } from '../components/Button'
16
+ import { $cerberusIcons } from '../config/defineIcons'
17
+ import { trapFocus } from '../aria-helpers/trap-focus.aria'
18
+ 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
+ import { Avatar } from '../components/Avatar'
25
+ import { HStack } from '@cerberus/styled-system/jsx'
26
+ import { IconButton } from '../components/IconButton'
27
+ import { css } from '@cerberus/styled-system/css'
28
+ import { VStack } from '@cerberus/styled-system/jsx'
29
+
30
+ /**
31
+ * This module provides a context and hook for the cta modal.
32
+ * @module
33
+ */
34
+
35
+ export interface ShowCTAModalOptions {
36
+ /**
37
+ * The heading of the cta modal.
38
+ */
39
+ heading: string
40
+ /**
41
+ * The description of the cta modal.
42
+ */
43
+ description?: string
44
+ /**
45
+ * The icon used for the modal Avatar.
46
+ */
47
+ icon?: ReactNode
48
+ /**
49
+ * The actions for the cta modal. Max of 2 actions.
50
+ */
51
+ actions: {
52
+ text: string
53
+ onClick: Required<ButtonHTMLAttributes<HTMLButtonElement>['onClick']>
54
+ }[]
55
+ }
56
+
57
+ export interface CTAModalValue {
58
+ show: (options: ShowCTAModalOptions) => void
59
+ }
60
+
61
+ const CTAModalContext = createContext<CTAModalValue | null>(null)
62
+
63
+ export interface CTAModalProviderProps {}
64
+
65
+ /**
66
+ * Provides a CTA modal to the app.
67
+ * @see https://cerberus.digitalu.design/react/cta-modal
68
+ * @example
69
+ * ```tsx
70
+ * // Wrap the Provider around the root of the feature.
71
+ * <CTAModal>
72
+ * <SomeFeatureSection />
73
+ * </CTAModal>
74
+ *
75
+ * // Use the hook to show the cta modal.
76
+ * const cta = useCTAModal()
77
+ *
78
+ * const handleClick = useCallback(async () => {
79
+ * const userConsent = await cta.show({
80
+ * heading: 'Create or copy a Cohort',
81
+ * description:
82
+ * 'Create a new cohort or copy and existing one.',
83
+ * icon: <Copy size={24} />,
84
+ * actions: [
85
+ * {
86
+ * text: 'Create Cohort',
87
+ * onClick: () => {},
88
+ * {
89
+ * text: 'Copy Cohort',
90
+ * onClick: () => {}
91
+ * }
92
+ * })
93
+ * setConsent(userConsent)
94
+ * }, [cta])
95
+ * ```
96
+ */
97
+ export function CTAModal(props: PropsWithChildren<CTAModalProviderProps>) {
98
+ const { modalRef, show, close } = useModal()
99
+ const [content, setContent] = useState<ShowCTAModalOptions | null>(null)
100
+ const focusTrap = trapFocus(modalRef)
101
+ const FallbackIcon = $cerberusIcons.confirmModal
102
+ const confirmIcon = content?.icon as ReactNode
103
+ const { close: CloseIcon } = $cerberusIcons
104
+
105
+ const handleShow = useCallback(
106
+ (options: ShowCTAModalOptions) => {
107
+ const maxActions = 2
108
+ if (options.actions.length > maxActions) {
109
+ throw new Error(
110
+ `CTA Modal only supports a maximum of ${maxActions} actions.`,
111
+ )
112
+ }
113
+ setContent({ ...options })
114
+ show()
115
+ },
116
+ [show],
117
+ )
118
+
119
+ const handleActionClick = useCallback(
120
+ (event: MouseEvent<HTMLButtonElement>) => {
121
+ const index = event.currentTarget.getAttribute('data-index')
122
+ const action = content?.actions[Number(index)]
123
+ if (typeof action?.onClick === 'function') {
124
+ action.onClick(event)
125
+ }
126
+ close()
127
+ },
128
+ [content, close],
129
+ )
130
+
131
+ const value = useMemo(
132
+ () => ({
133
+ show: handleShow,
134
+ }),
135
+ [handleShow],
136
+ )
137
+
138
+ return (
139
+ <CTAModalContext.Provider value={value}>
140
+ {props.children}
141
+
142
+ <Portal>
143
+ <Modal onKeyDown={focusTrap} ref={modalRef}>
144
+ <span
145
+ className={css({
146
+ padding: 'md',
147
+ position: 'absolute',
148
+ right: 0,
149
+ top: 0,
150
+ zIndex: 'decorator',
151
+ })}
152
+ >
153
+ <IconButton ariaLabel="Close modal" onClick={close}>
154
+ <CloseIcon />
155
+ </IconButton>
156
+ </span>
157
+
158
+ <ModalHeader>
159
+ <HStack justify="center" w="full">
160
+ <Avatar
161
+ ariaLabel=""
162
+ gradient="charon-light"
163
+ icon={
164
+ <Show
165
+ when={Boolean(confirmIcon)}
166
+ fallback={<FallbackIcon size={24} />}
167
+ >
168
+ {confirmIcon}
169
+ </Show>
170
+ }
171
+ src=""
172
+ />
173
+ </HStack>
174
+ <VStack gap="lg" w="full">
175
+ <ModalHeading>{content?.heading}</ModalHeading>
176
+ <ModalDescription>{content?.description}</ModalDescription>
177
+ </VStack>
178
+ </ModalHeader>
179
+
180
+ <HStack gap="md" pt="sm" w="full">
181
+ <Show when={Boolean(content?.actions?.length)}>
182
+ {content?.actions?.map((action, index) => (
183
+ <Button
184
+ data-index={index}
185
+ className={css({
186
+ w: '1/2',
187
+ })}
188
+ key={index}
189
+ onClick={handleActionClick}
190
+ shape="rounded"
191
+ usage="outlined"
192
+ >
193
+ {action.text}
194
+ </Button>
195
+ ))}
196
+ </Show>
197
+ </HStack>
198
+ </Modal>
199
+ </Portal>
200
+ </CTAModalContext.Provider>
201
+ )
202
+ }
203
+
204
+ export function useCTAModal(): CTAModalValue {
205
+ const context = useContext(CTAModalContext)
206
+ if (context === null) {
207
+ throw new Error('useCTAModal must be used within a CTAModal Provider')
208
+ }
209
+ return context
210
+ }
@@ -42,8 +42,7 @@ export interface NavMenuContextValue {
42
42
  const NavMenuContext = createContext<NavMenuContextValue | null>(null)
43
43
 
44
44
  /**
45
- * Provides the nav menu state for all the NavMenu family components.
46
- * @see https://cerberus.digitalu.design/react/nav-menu
45
+ * @deprecated use the {@link Menu} family instead
47
46
  */
48
47
  export function NavMenu(props: PropsWithChildren): JSX.Element {
49
48
  const triggerRef = useRef<HTMLButtonElement>(null)
package/src/index.ts CHANGED
@@ -21,6 +21,7 @@ export * from './components/IconButton'
21
21
  export * from './components/Input'
22
22
  export * from './components/Label'
23
23
  export * from './components/Legend'
24
+ export * from './components/Menu'
24
25
  export * from './components/Modal'
25
26
  export * from './components/ModalHeader'
26
27
  export * from './components/ModalHeading'
@@ -52,6 +53,7 @@ export * from './components/Show'
52
53
  // context
53
54
 
54
55
  export * from './context/confirm-modal'
56
+ export * from './context/cta-modal'
55
57
  export * from './context/feature-flags'
56
58
  export * from './context/field'
57
59
  export * from './context/navMenu'
@@ -75,6 +77,7 @@ export * from './aria-helpers/trap-focus.aria'
75
77
  // utils
76
78
 
77
79
  export * from './config/defineIcons'
80
+ export * from './utils/index'
78
81
 
79
82
  // shared types
80
83