@react-fabric/core 1.0.0-beta.61 → 1.0.0-beta.63

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 (317) hide show
  1. package/css/components/_animations.css +7 -11
  2. package/css/components/_avatar.css +5 -5
  3. package/css/components/_badge.css +2 -1
  4. package/css/components/_breadcrumbs.css +7 -5
  5. package/css/components/_button.css +49 -9
  6. package/css/components/_card.css +9 -17
  7. package/css/components/_chip.css +0 -4
  8. package/css/components/_dropdown.css +1 -0
  9. package/css/components/_flyout.css +1 -1
  10. package/css/components/_media.css +2 -14
  11. package/css/components/_menu.css +1 -1
  12. package/css/components/_modal.css +3 -3
  13. package/css/components/_progress.css +1 -1
  14. package/css/components/_stepper.css +2 -1
  15. package/css/components/_tabPanel.css +4 -4
  16. package/css/core/_aside.css +3 -3
  17. package/css/core/_errorboundary.css +2 -10
  18. package/css/core/_page.css +1 -1
  19. package/css/core/_responsive.css +8 -0
  20. package/css/core/_theme.css +1 -1
  21. package/css/core/_viewport.css +1 -5
  22. package/css/reset/_reset.css +42 -43
  23. package/css/reset/_theme.css +214 -201
  24. package/css/styles.css +5 -0
  25. package/css/theme/_colors.css +14 -0
  26. package/css/theme/_utilities.css +103 -225
  27. package/css/theme/index.css +4 -6
  28. package/dist/cjs/components/actionLabel/ActionLabel.js +1 -1
  29. package/dist/cjs/components/animations/Animations.js +7 -7
  30. package/dist/cjs/components/avatar/Avatar.js +1 -1
  31. package/dist/cjs/components/avatar/AvatarGroup.js +1 -1
  32. package/dist/cjs/components/badge/Badge.js +5 -27
  33. package/dist/cjs/components/breadcrumbs/Breadcrumbs.js +1 -1
  34. package/dist/cjs/components/button/Button.js +8 -6
  35. package/dist/cjs/components/button/ButtonGroup.js +1 -1
  36. package/dist/cjs/components/button/ConfirmButton.js +7 -6
  37. package/dist/cjs/components/button/ToggleButtonGroup.js +1 -1
  38. package/dist/cjs/components/callout/Callout.js +8 -7
  39. package/dist/cjs/components/card/Card.js +3 -3
  40. package/dist/cjs/components/card/CardCover.js +1 -1
  41. package/dist/cjs/components/card/FlipContent.js +2 -2
  42. package/dist/cjs/components/chip/Chip.js +8 -7
  43. package/dist/cjs/components/collapsable/Collapsable.js +4 -3
  44. package/dist/cjs/components/divider/Divider.js +2 -2
  45. package/dist/cjs/components/dropdown/Dropdown.js +28 -14
  46. package/dist/cjs/components/empty/EmptyContent.js +1 -1
  47. package/dist/cjs/components/icon/Icon.js +26 -40
  48. package/dist/cjs/components/media/Media.js +13 -13
  49. package/dist/cjs/components/menu/ContextMenu.js +23 -13
  50. package/dist/cjs/components/menu/Menu.js +19 -14
  51. package/dist/cjs/components/menu/MenuItem.js +5 -4
  52. package/dist/cjs/components/meter/Meter.js +1 -1
  53. package/dist/cjs/components/navigator/Navigator.js +6 -6
  54. package/dist/cjs/components/panel/Panel.js +6 -4
  55. package/dist/cjs/components/panel/PanelGroup.js +3 -3
  56. package/dist/cjs/components/panel/PanelStack.js +5 -5
  57. package/dist/cjs/components/progress/ProgressBar.js +2 -2
  58. package/dist/cjs/components/progress/ProgressCircle.js +2 -2
  59. package/dist/cjs/components/tabpanel/Tab.js +6 -4
  60. package/dist/cjs/components/tabpanel/TabPanel.js +7 -6
  61. package/dist/cjs/context/Global.js +2 -55
  62. package/dist/cjs/context/NotificationCenter.js +38 -39
  63. package/dist/cjs/context/context.js +59 -0
  64. package/dist/cjs/core/aside/Aside.js +9 -7
  65. package/dist/cjs/core/boundary/ErrorBoundary.js +2 -4
  66. package/dist/cjs/core/page/Page.js +4 -1
  67. package/dist/cjs/core/responsive/Responsive.js +3 -2
  68. package/dist/cjs/core/theme/ThemeProvider.js +5 -4
  69. package/dist/cjs/core/viewport/Viewport.js +1 -1
  70. package/dist/cjs/hooks/useContextMenu.js +103 -0
  71. package/dist/cjs/hooks/useIsDark.js +6 -4
  72. package/dist/cjs/hooks/useNavigator.js +11 -10
  73. package/dist/cjs/hooks/useOverlayService.js +27 -38
  74. package/dist/cjs/hooks/usePropToggle.js +2 -2
  75. package/dist/cjs/hooks/useResize.js +8 -6
  76. package/dist/cjs/hooks/useResizeObserver.js +5 -5
  77. package/dist/cjs/hooks/useStepper.js +2 -6
  78. package/dist/cjs/hotkeys/HotKey.js +2 -2
  79. package/dist/cjs/hotkeys/HotKeyWrapper.js +8 -13
  80. package/dist/cjs/hotkeys/commons.js +1 -1
  81. package/dist/cjs/hotkeys/context.js +36 -0
  82. package/dist/cjs/i18n/index.js +4 -4
  83. package/dist/cjs/index.js +10 -5
  84. package/dist/cjs/overlays/alert/Alert.js +6 -5
  85. package/dist/cjs/overlays/flyout/Flyout.js +8 -6
  86. package/dist/cjs/overlays/message/Message.js +5 -5
  87. package/dist/cjs/overlays/modal/Modal.js +5 -3
  88. package/dist/cjs/overlays/toast/Toast.js +4 -4
  89. package/dist/cjs/overlays/tooltip/Tooltip.js +2 -16
  90. package/dist/cjs/typography/Abbr.js +4 -5
  91. package/dist/cjs/typography/Anchor.js +2 -2
  92. package/dist/cjs/typography/Copy.js +2 -2
  93. package/dist/cjs/typography/Mark.js +2 -4
  94. package/dist/cjs/typography/Text.js +4 -4
  95. package/dist/cjs/typography/Title.js +2 -2
  96. package/dist/cjs/utils/cloneElement.js +4 -4
  97. package/dist/cjs/utils/getBadgeProps.js +51 -0
  98. package/dist/cjs/utils/getIconProps.js +42 -0
  99. package/dist/cjs/utils/getTooltipProps.js +45 -0
  100. package/dist/esm/components/actionLabel/ActionLabel.js +1 -1
  101. package/dist/esm/components/animations/Animations.js +7 -7
  102. package/dist/esm/components/avatar/Avatar.js +1 -1
  103. package/dist/esm/components/avatar/AvatarGroup.js +1 -1
  104. package/dist/esm/components/badge/Badge.js +7 -28
  105. package/dist/esm/components/breadcrumbs/Breadcrumbs.js +1 -1
  106. package/dist/esm/components/button/Button.js +9 -7
  107. package/dist/esm/components/button/ButtonGroup.js +3 -3
  108. package/dist/esm/components/button/ConfirmButton.js +8 -7
  109. package/dist/esm/components/button/ToggleButtonGroup.js +3 -3
  110. package/dist/esm/components/callout/Callout.js +8 -7
  111. package/dist/esm/components/card/Card.js +4 -4
  112. package/dist/esm/components/card/CardCover.js +1 -1
  113. package/dist/esm/components/card/FlipContent.js +2 -2
  114. package/dist/esm/components/chip/Chip.js +9 -8
  115. package/dist/esm/components/collapsable/Collapsable.js +4 -3
  116. package/dist/esm/components/divider/Divider.js +2 -2
  117. package/dist/esm/components/dropdown/Dropdown.js +30 -16
  118. package/dist/esm/components/empty/EmptyContent.js +1 -1
  119. package/dist/esm/components/icon/Icon.js +28 -41
  120. package/dist/esm/components/media/Media.js +13 -13
  121. package/dist/esm/components/menu/ContextMenu.js +24 -14
  122. package/dist/esm/components/menu/Menu.js +22 -17
  123. package/dist/esm/components/menu/MenuItem.js +6 -5
  124. package/dist/esm/components/meter/Meter.js +1 -1
  125. package/dist/esm/components/navigator/Navigator.js +7 -7
  126. package/dist/esm/components/panel/Panel.js +6 -4
  127. package/dist/esm/components/panel/PanelGroup.js +4 -4
  128. package/dist/esm/components/panel/PanelStack.js +6 -6
  129. package/dist/esm/components/progress/ProgressBar.js +2 -2
  130. package/dist/esm/components/progress/ProgressCircle.js +2 -2
  131. package/dist/esm/components/tabpanel/Tab.js +6 -4
  132. package/dist/esm/components/tabpanel/TabPanel.js +8 -7
  133. package/dist/esm/context/Global.js +3 -52
  134. package/dist/esm/context/NotificationCenter.js +38 -39
  135. package/dist/esm/context/context.js +56 -0
  136. package/dist/esm/core/aside/Aside.js +10 -8
  137. package/dist/esm/core/boundary/ErrorBoundary.js +1 -3
  138. package/dist/esm/core/page/Page.js +4 -1
  139. package/dist/esm/core/responsive/Responsive.js +3 -2
  140. package/dist/esm/core/theme/ThemeProvider.js +4 -3
  141. package/dist/esm/core/viewport/Viewport.js +1 -1
  142. package/dist/esm/hooks/useContextMenu.js +103 -0
  143. package/dist/esm/hooks/useIsDark.js +7 -5
  144. package/dist/esm/hooks/useNavigator.js +12 -11
  145. package/dist/esm/hooks/useOverlayService.js +28 -39
  146. package/dist/esm/hooks/usePropToggle.js +3 -3
  147. package/dist/esm/hooks/useResize.js +9 -7
  148. package/dist/esm/hooks/useResizeObserver.js +6 -6
  149. package/dist/esm/hooks/useStepper.js +2 -6
  150. package/dist/esm/hotkeys/HotKey.js +1 -1
  151. package/dist/esm/hotkeys/HotKeyWrapper.js +9 -12
  152. package/dist/esm/hotkeys/commons.js +1 -1
  153. package/dist/esm/hotkeys/context.js +35 -0
  154. package/dist/esm/i18n/index.js +2 -2
  155. package/dist/esm/index.js +8 -4
  156. package/dist/esm/overlays/alert/Alert.js +7 -6
  157. package/dist/esm/overlays/flyout/Flyout.js +9 -7
  158. package/dist/esm/overlays/message/Message.js +6 -6
  159. package/dist/esm/overlays/modal/Modal.js +6 -4
  160. package/dist/esm/overlays/toast/Toast.js +5 -5
  161. package/dist/esm/overlays/tooltip/Tooltip.js +4 -17
  162. package/dist/esm/typography/Abbr.js +4 -5
  163. package/dist/esm/typography/Anchor.js +2 -2
  164. package/dist/esm/typography/Copy.js +3 -3
  165. package/dist/esm/typography/Mark.js +2 -4
  166. package/dist/esm/typography/Text.js +5 -5
  167. package/dist/esm/typography/Title.js +2 -2
  168. package/dist/esm/utils/cloneElement.js +4 -4
  169. package/dist/esm/utils/getBadgeProps.js +51 -0
  170. package/dist/esm/utils/getIconProps.js +42 -0
  171. package/dist/esm/utils/getTooltipProps.js +45 -0
  172. package/dist/types/components/actionLabel/ActionLabel.d.ts +1 -1
  173. package/dist/types/components/animations/Animations.d.ts +6 -6
  174. package/dist/types/components/avatar/Avatar.d.ts +1 -1
  175. package/dist/types/components/avatar/AvatarGroup.d.ts +1 -1
  176. package/dist/types/components/badge/Badge.d.ts +2 -10
  177. package/dist/types/components/breadcrumbs/Breadcrumbs.d.ts +1 -1
  178. package/dist/types/components/button/Button.d.ts +1 -1
  179. package/dist/types/components/button/ButtonGroup.d.ts +1 -1
  180. package/dist/types/components/button/ConfirmButton.d.ts +1 -1
  181. package/dist/types/components/button/ToggleButtonGroup.d.ts +1 -1
  182. package/dist/types/components/callout/Callout.d.ts +7 -3
  183. package/dist/types/components/card/Card.d.ts +2 -2
  184. package/dist/types/components/card/CardCover.d.ts +1 -1
  185. package/dist/types/components/card/FlipContent.d.ts +1 -1
  186. package/dist/types/components/chip/Chip.d.ts +1 -1
  187. package/dist/types/components/collapsable/Collapsable.d.ts +1 -1
  188. package/dist/types/components/divider/Divider.d.ts +1 -1
  189. package/dist/types/components/dropdown/Dropdown.d.ts +7 -3
  190. package/dist/types/components/dropdown/DropdownTool.d.ts +1 -1
  191. package/dist/types/components/empty/EmptyContent.d.ts +3 -3
  192. package/dist/types/components/icon/Icon.d.ts +3 -4
  193. package/dist/types/components/index.d.ts +3 -3
  194. package/dist/types/components/media/Media.d.ts +2 -2
  195. package/dist/types/components/menu/ContextMenu.d.ts +1 -1
  196. package/dist/types/components/menu/Menu.d.ts +1 -1
  197. package/dist/types/components/menu/types.d.ts +6 -1
  198. package/dist/types/components/meter/Meter.d.ts +1 -1
  199. package/dist/types/components/navigator/Navigator.d.ts +7 -1
  200. package/dist/types/components/panel/Panel.d.ts +2 -2
  201. package/dist/types/components/panel/PanelGroup.d.ts +1 -1
  202. package/dist/types/components/panel/PanelStack.d.ts +1 -1
  203. package/dist/types/components/progress/ProgressBar.d.ts +1 -1
  204. package/dist/types/components/progress/ProgressCircle.d.ts +1 -1
  205. package/dist/types/components/tabpanel/Tab.d.ts +1 -1
  206. package/dist/types/components/tabpanel/TabPanel.d.ts +1 -1
  207. package/dist/types/context/Global.d.ts +0 -82
  208. package/dist/types/context/context.d.ts +85 -0
  209. package/dist/types/core/aside/Aside.d.ts +2 -2
  210. package/dist/types/core/responsive/Responsive.d.ts +5 -1
  211. package/dist/types/core/theme/ThemeProvider.d.ts +2 -2
  212. package/dist/types/hooks/useContextMenu.d.ts +10 -0
  213. package/dist/types/hooks/useOverlayService.d.ts +3 -5
  214. package/dist/types/hotkeys/HotKeyWrapper.d.ts +0 -9
  215. package/dist/types/hotkeys/context.d.ts +9 -0
  216. package/dist/types/index.d.ts +4 -2
  217. package/dist/types/overlays/alert/Alert.d.ts +2 -2
  218. package/dist/types/overlays/flyout/Flyout.d.ts +2 -2
  219. package/dist/types/overlays/message/Message.d.ts +2 -2
  220. package/dist/types/overlays/modal/Modal.d.ts +2 -2
  221. package/dist/types/overlays/toast/Toast.d.ts +2 -2
  222. package/dist/types/overlays/tooltip/Tooltip.d.ts +0 -3
  223. package/dist/types/types/index.d.ts +2 -2
  224. package/dist/types/typography/Abbr.d.ts +4 -8
  225. package/dist/types/typography/Anchor.d.ts +1 -1
  226. package/dist/types/typography/Copy.d.ts +1 -1
  227. package/dist/types/typography/Mark.d.ts +2 -2
  228. package/dist/types/typography/Text.d.ts +1 -1
  229. package/dist/types/typography/Title.d.ts +1 -1
  230. package/dist/types/utils/getBadgeProps.d.ts +9 -0
  231. package/dist/types/utils/getIconProps.d.ts +2 -0
  232. package/dist/types/utils/getTooltipProps.d.ts +4 -0
  233. package/dist/types/utils/index.d.ts +3 -0
  234. package/package.json +14 -15
  235. package/src/components/actionLabel/ActionLabel.tsx +1 -1
  236. package/src/components/animations/Animations.tsx +6 -6
  237. package/src/components/avatar/Avatar.tsx +1 -1
  238. package/src/components/avatar/AvatarGroup.tsx +1 -1
  239. package/src/components/badge/Badge.tsx +8 -46
  240. package/src/components/breadcrumbs/Breadcrumbs.tsx +1 -1
  241. package/src/components/button/Button.tsx +24 -52
  242. package/src/components/button/ButtonGroup.tsx +1 -1
  243. package/src/components/button/ConfirmButton.tsx +23 -20
  244. package/src/components/button/ToggleButtonGroup.tsx +1 -1
  245. package/src/components/callout/Callout.tsx +14 -19
  246. package/src/components/card/Card.tsx +9 -11
  247. package/src/components/card/CardCover.tsx +1 -1
  248. package/src/components/card/FlipContent.tsx +2 -2
  249. package/src/components/chip/Chip.tsx +16 -33
  250. package/src/components/collapsable/Collapsable.tsx +2 -2
  251. package/src/components/divider/Divider.tsx +1 -1
  252. package/src/components/dropdown/Dropdown.tsx +60 -73
  253. package/src/components/dropdown/DropdownTool.tsx +1 -1
  254. package/src/components/empty/EmptyContent.tsx +3 -3
  255. package/src/components/icon/Icon.tsx +27 -54
  256. package/src/components/index.ts +5 -4
  257. package/src/components/media/Media.tsx +3 -3
  258. package/src/components/menu/ContextMenu.tsx +30 -30
  259. package/src/components/menu/Menu.tsx +35 -63
  260. package/src/components/menu/MenuItem.tsx +9 -28
  261. package/src/components/menu/types.ts +6 -1
  262. package/src/components/meter/Meter.tsx +1 -1
  263. package/src/components/navigator/Navigator.tsx +13 -11
  264. package/src/components/panel/Panel.tsx +13 -54
  265. package/src/components/panel/PanelGroup.tsx +3 -4
  266. package/src/components/panel/PanelStack.tsx +20 -25
  267. package/src/components/progress/ProgressBar.tsx +2 -2
  268. package/src/components/progress/ProgressCircle.tsx +2 -2
  269. package/src/components/tabpanel/Tab.tsx +9 -28
  270. package/src/components/tabpanel/TabPanel.tsx +13 -15
  271. package/src/context/Global.tsx +18 -125
  272. package/src/context/NotificationCenter.tsx +0 -1
  273. package/src/context/context.ts +100 -0
  274. package/src/core/aside/Aside.tsx +18 -55
  275. package/src/core/boundary/ErrorBoundary.tsx +8 -37
  276. package/src/core/page/Page.tsx +3 -5
  277. package/src/core/responsive/Responsive.tsx +10 -34
  278. package/src/core/theme/ThemeProvider.tsx +5 -8
  279. package/src/core/viewport/Viewport.tsx +1 -1
  280. package/src/hooks/useContextMenu.tsx +131 -0
  281. package/src/hooks/useIsDark.ts +7 -5
  282. package/src/hooks/useNavigator.tsx +8 -12
  283. package/src/hooks/useOverlayService.tsx +22 -17
  284. package/src/hooks/usePropToggle.ts +3 -3
  285. package/src/hooks/useResize.ts +14 -17
  286. package/src/hooks/useResizeObserver.ts +21 -21
  287. package/src/hooks/useStepper.tsx +1 -1
  288. package/src/hotkeys/HotKey.tsx +1 -1
  289. package/src/hotkeys/HotKeyWrapper.tsx +81 -105
  290. package/src/hotkeys/commons.ts +2 -0
  291. package/src/hotkeys/context.ts +32 -0
  292. package/src/i18n/index.ts +2 -2
  293. package/src/index.ts +4 -7
  294. package/src/overlays/alert/Alert.tsx +12 -16
  295. package/src/overlays/flyout/Flyout.tsx +32 -69
  296. package/src/overlays/message/Message.tsx +11 -15
  297. package/src/overlays/modal/Modal.tsx +23 -57
  298. package/src/overlays/toast/Toast.tsx +16 -15
  299. package/src/overlays/tooltip/Tooltip.tsx +6 -29
  300. package/src/types/global.d.ts +12 -0
  301. package/src/types/index.ts +2 -2
  302. package/src/typography/Abbr.tsx +11 -39
  303. package/src/typography/Anchor.tsx +1 -1
  304. package/src/typography/Copy.tsx +4 -4
  305. package/src/typography/Mark.tsx +2 -3
  306. package/src/typography/Text.tsx +8 -6
  307. package/src/typography/Title.tsx +1 -1
  308. package/src/utils/getBadgeProps.ts +45 -0
  309. package/src/utils/getIconProps.ts +35 -0
  310. package/src/utils/getTooltipProps.ts +38 -0
  311. package/src/utils/index.ts +3 -0
  312. /package/dist/cjs/i18n/{ar.json.js → ar/core.json.js} +0 -0
  313. /package/dist/cjs/i18n/{en.json.js → en/core.json.js} +0 -0
  314. /package/dist/esm/i18n/{ar.json.js → ar/core.json.js} +0 -0
  315. /package/dist/esm/i18n/{en.json.js → en/core.json.js} +0 -0
  316. /package/src/i18n/{ar.json → ar/core.json} +0 -0
  317. /package/src/i18n/{en.json → en/core.json} +0 -0
@@ -42,6 +42,7 @@ import {
42
42
  Fragment,
43
43
  useCallback,
44
44
  useEffect,
45
+ useEffectEvent,
45
46
  useMemo,
46
47
  useRef,
47
48
  useState,
@@ -87,7 +88,7 @@ export type ConfirmButtonProps = ExtendedProps & ButtonProps;
87
88
  * It also supports custom placement of the dialog, and can display an action message when the action is completed.
88
89
  *
89
90
  * @param {ConfirmButtonProps} props - The properties for the ConfirmButton component.
90
- * @returns {JSX.Element} The rendered ConfirmButton component.
91
+ * @returns {React.ReactElement} The rendered ConfirmButton component.
91
92
  *
92
93
  * @example
93
94
  * ```jsx
@@ -123,21 +124,18 @@ export const ConfirmButton = <Tag extends React.ElementType = "button">({
123
124
  const [busy, setBusy] = useState(false);
124
125
  const [actionDone, setActionDone] = useState(false);
125
126
 
126
- const clickHandler = useCallback(
127
- (e: boolean) => {
128
- setBusy(e);
129
- const ret = onClick?.(e);
130
- if (e) {
131
- void Promise.resolve(ret).then((b) => {
132
- setBusy(false);
133
- if (b !== false && actionMessage && showActionDoneEvent === "click") {
134
- setActionDone(true);
135
- }
136
- });
137
- }
138
- },
139
- [onClick, actionMessage, showActionDoneEvent],
140
- );
127
+ const clickHandler = useEffectEvent((e: boolean) => {
128
+ setBusy(e);
129
+ const ret = onClick?.(e);
130
+ if (e) {
131
+ void Promise.resolve(ret).then((b) => {
132
+ setBusy(false);
133
+ if (b !== false && actionMessage && showActionDoneEvent === "click") {
134
+ setActionDone(true);
135
+ }
136
+ });
137
+ }
138
+ });
141
139
  useEffect(() => {
142
140
  if (actionDone) {
143
141
  const timer = setTimeout(() => setActionDone(false), 2000);
@@ -200,12 +198,17 @@ export const ConfirmButton = <Tag extends React.ElementType = "button">({
200
198
  data-dropdown-open={isOpen}
201
199
  />
202
200
  {isOpen && (
203
- <FloatingPortal>
204
- <FloatingFocusManager modal context={context}>
201
+ <FloatingPortal
202
+ root={
203
+ refs.domReference.current?.closest<HTMLElement>(".theme-base") ??
204
+ undefined
205
+ }
206
+ >
207
+ <FloatingFocusManager context={context}>
205
208
  <div
206
209
  data-color={color}
207
210
  className={classNames(
208
- "select-none not-italic rounded-capped shadow-lg outline outline-muted bg-base",
211
+ "select-none not-italic rounded-capped shadow-lg outline outline-muted bg-default",
209
212
  )}
210
213
  ref={refs.setFloating}
211
214
  style={{
@@ -244,7 +247,7 @@ export const ConfirmButton = <Tag extends React.ElementType = "button">({
244
247
  ref={arrowRef}
245
248
  context={context}
246
249
  strokeWidth={0.5}
247
- className="fill-base stroke-muted"
250
+ className="fill-default stroke-muted"
248
251
  />
249
252
  </div>
250
253
  </FloatingFocusManager>
@@ -99,7 +99,7 @@ export type ToggleButtonGroupProps<T> = BaseProps &
99
99
  * such as toggle switches, selection groups, or multi-select options.
100
100
  *
101
101
  * @param {ToggleButtonGroupProps} props - The properties for the ToggleButtonGroup component.
102
- * @returns {JSX.Element} The rendered ToggleButtonGroup component.
102
+ * @returns {React.ReactElement} The rendered ToggleButtonGroup component.
103
103
  *
104
104
  * @example
105
105
  * ```jsx
@@ -22,28 +22,22 @@
22
22
  */
23
23
 
24
24
  import classNames from "classnames";
25
- import {
26
- type AriaProps,
27
- type ChildrenProp,
28
- type ColorState,
29
- type CssProp,
30
- type TestProps,
31
- } from "../../types";
25
+ import { type AriaProps, type ChildrenProp, type ColorState, type CssProp, type TestProps } from "../../types";
32
26
  import { Icon } from "../icon/Icon";
33
27
 
34
- export interface CalloutProps
35
- extends AriaProps,
36
- ChildrenProp,
37
- CssProp,
38
- TestProps {
28
+ export interface CalloutProps extends AriaProps, ChildrenProp, CssProp, TestProps {
39
29
  /**
40
30
  * callout color
41
31
  */
42
- color?: ColorState | "none";
32
+ color?: ColorState | "dimmed";
43
33
  /**
44
34
  * legend title
45
35
  */
46
36
  legend?: string | React.ReactElement;
37
+ /**
38
+ * legend class name
39
+ */
40
+ legendClassName?: string;
47
41
  /**
48
42
  * callout icon
49
43
  */
@@ -64,9 +58,9 @@ export interface CalloutProps
64
58
 
65
59
  // colors for different callout types
66
60
  const colors = {
67
- none: "bg-base text-tint-900 border-tint-100",
68
- default: "bg-tint-50/50 text-tint-800 border-tint-300",
69
- muted: "bg-tint-50/50 text-muted border-muted",
61
+ default: "bg-default text-tint-900 border-tint-100",
62
+ dimmed: "bg-dimmed text-dimmed border-tint-200",
63
+ muted: "bg-muted text-muted border-tint-200",
70
64
  primary: "bg-primary-50/50 text-primary-800 border-primary-300",
71
65
  accent: "bg-accent-50/50 text-accent-800 border-accent-300",
72
66
  info: "bg-info-50/50 text-info-800 border-info-300",
@@ -83,7 +77,7 @@ const colors = {
83
77
  * such as alerts, notifications, or important messages.
84
78
  *
85
79
  * @param {CalloutProps} props - The properties for the Callout component.
86
- * @returns {JSX.Element} The rendered Callout component.
80
+ * @returns {React.ReactElement} The rendered Callout component.
87
81
  *
88
82
  * @example
89
83
  * ```jsx
@@ -105,6 +99,7 @@ export const Callout = ({
105
99
  children,
106
100
  color = "default",
107
101
  legend,
102
+ legendClassName,
108
103
  title,
109
104
  icon,
110
105
  border,
@@ -115,7 +110,7 @@ export const Callout = ({
115
110
  return (
116
111
  <fieldset
117
112
  className={classNames(
118
- "block rounded-capped border max-w-full relative overflow-hidden mb-4",
113
+ "block rounded-capped border max-w-full relative overflow-hidden",
119
114
  colors[color],
120
115
  className,
121
116
  border === "dashed" && "border-dashed",
@@ -124,7 +119,7 @@ export const Callout = ({
124
119
  {...aria}
125
120
  >
126
121
  {legend && (
127
- <legend className="px-2 mx-4 font-medium" data-ref="calloutLegend">
122
+ <legend className={classNames("px-2 mx-4 font-medium", legendClassName)} data-ref="calloutLegend">
128
123
  {legend}
129
124
  </legend>
130
125
  )}
@@ -24,7 +24,7 @@
24
24
  import classNames from "classnames";
25
25
  import {
26
26
  Children,
27
- useCallback,
27
+ useEffectEvent,
28
28
  useMemo,
29
29
  type DragEvent,
30
30
  type MouseEventHandler,
@@ -37,17 +37,18 @@ import {
37
37
  type HeadFootProps,
38
38
  } from "../../core/headfoot/HeadFoot";
39
39
  import {
40
- type PolymorphicProps,
41
40
  type AriaProps,
42
41
  type ChildrenProp,
43
42
  type CssProp,
43
+ type PolymorphicProps,
44
44
  type RefProp,
45
45
  type TestProps,
46
46
  } from "../../types";
47
47
  import { nodeCheck } from "../../utils";
48
48
 
49
49
  interface BaseProps
50
- extends CssProp,
50
+ extends
51
+ CssProp,
51
52
  AriaProps,
52
53
  TestProps,
53
54
  RefProp<HTMLDivElement>,
@@ -106,7 +107,7 @@ export type CardProps<Tag extends React.ElementType = "div"> = BaseProps &
106
107
  * It can be styled with custom CSS classes and supports features like selection indication and drag-and-drop functionality.
107
108
  *
108
109
  * @param {CardProps} props - The properties for the Card component.
109
- * @returns {JSX.Element} The rendered Card component.
110
+ * @returns {React.ReactElement} The rendered Card component.
110
111
  *
111
112
  * @example
112
113
  * ```jsx
@@ -161,13 +162,10 @@ export const Card = <Tag extends React.ElementType = "div">({
161
162
  );
162
163
  }, [children]);
163
164
 
164
- const handleDragStart = useCallback(
165
- (event: DragEvent) => {
166
- dragKey && event.dataTransfer?.setData(dragKey, JSON.stringify(dragData));
167
- dragKey && onDragStart?.(event, dragKey, dragData);
168
- },
169
- [onDragStart, dragKey, dragData],
170
- );
165
+ const handleDragStart = useEffectEvent((event: DragEvent) => {
166
+ dragKey && event.dataTransfer?.setData(dragKey, JSON.stringify(dragData));
167
+ dragKey && onDragStart?.(event, dragKey, dragData);
168
+ });
171
169
 
172
170
  const E = as ?? "div";
173
171
  return (
@@ -54,7 +54,7 @@ const scheme = {
54
54
  * It can be used to create visually appealing card layouts with media content.
55
55
  *
56
56
  * @param {CardCoverProps} props - The properties for the CardCover component.
57
- * @returns {JSX.Element} The rendered CardCover component.
57
+ * @returns {React.ReactElement} The rendered CardCover component.
58
58
  *
59
59
  * @example
60
60
  * ```jsx
@@ -48,7 +48,7 @@ export interface Props extends ChildrenProp, RefProp<FlipContentRef> {
48
48
  * The `flipCard` method can be called to toggle the visibility of the back content.
49
49
  *
50
50
  * @param {Props} props - The properties for the FlipContent component.
51
- * @returns {JSX.Element} The rendered FlipContent component.
51
+ * @returns {React.ReactElement} The rendered FlipContent component.
52
52
  *
53
53
  * @example
54
54
  * ```jsx
@@ -80,7 +80,7 @@ export const FlipContent = ({ ref, children }: Props) => {
80
80
  cloneElement(child, {
81
81
  className: classNames(
82
82
  child.props?.className ?? "",
83
- idx === 0 ? "bg-base relative" : "bg-base absolute inset-0",
83
+ idx === 0 ? "bg-content relative" : "bg-content absolute inset-0",
84
84
  ),
85
85
  "data-card-flip-face": idx === 0 ? "front" : "back",
86
86
  } as AnyObject),
@@ -22,7 +22,7 @@
22
22
  */
23
23
 
24
24
  import classNames from "classnames";
25
- import { useCallback, type ReactElement } from "react";
25
+ import { useEffectEvent, type ReactElement } from "react";
26
26
  import { useMemoDebugger } from "../../hooks/useEffectDebugger";
27
27
  import {
28
28
  type AriaProps,
@@ -35,15 +35,10 @@ import {
35
35
  type SizeType,
36
36
  type TestProps,
37
37
  } from "../../types";
38
- import { getColor } from "../../utils";
39
- import { getIconProps, Icon, type IconProps } from "../icon/Icon";
38
+ import { getColor, getIconProps } from "../../utils";
39
+ import { Icon, type IconProps } from "../icon/Icon";
40
40
 
41
- export interface ChipProps
42
- extends CssProp,
43
- AriaProps,
44
- TestProps,
45
- ChildProp<string | ReactElement>,
46
- RefProp<HTMLDivElement> {
41
+ export interface ChipProps extends CssProp, AriaProps, TestProps, ChildProp<string | ReactElement>, RefProp<HTMLDivElement> {
47
42
  /**
48
43
  * chip size
49
44
  */
@@ -107,7 +102,7 @@ const SizeMap: KeyValue<string> = {
107
102
  * It can also include an icon and a remove button, making it versatile for different use cases.
108
103
  *
109
104
  * @param {ChipProps} props - The properties for the Chip component.
110
- * @returns {JSX.Element} The rendered Chip component.
105
+ * @returns {React.ReactElement} The rendered Chip component.
111
106
  *
112
107
  * @example
113
108
  * ```jsx
@@ -155,22 +150,16 @@ export const Chip = <Tag extends React.ElementType = "div">({
155
150
  "Chip styles",
156
151
  );
157
152
 
158
- const clickHandler = useCallback(
159
- (e: React.MouseEvent) => {
160
- preventDefault && e.preventDefault();
161
- stopPropagation && e.stopPropagation();
162
- onClick?.(e);
163
- },
164
- [onClick, preventDefault, stopPropagation],
165
- );
153
+ const clickHandler = useEffectEvent((e: React.MouseEvent) => {
154
+ preventDefault && e.preventDefault();
155
+ stopPropagation && e.stopPropagation();
156
+ onClick?.(e);
157
+ });
166
158
 
167
- const removeHandler = useCallback(
168
- (e: React.MouseEvent) => {
169
- if (stopPropagation) e.stopPropagation();
170
- onRemove?.(e);
171
- },
172
- [onRemove, stopPropagation],
173
- );
159
+ const removeHandler = useEffectEvent((e: React.MouseEvent) => {
160
+ if (stopPropagation) e.stopPropagation();
161
+ onRemove?.(e);
162
+ });
174
163
 
175
164
  const E = as ?? "div";
176
165
  return (
@@ -201,10 +190,7 @@ export const Chip = <Tag extends React.ElementType = "div">({
201
190
  />
202
191
  )}
203
192
  {children && (
204
- <label
205
- data-ref="chipLabel"
206
- className={classNames("fabric-chipLabel", "truncate flex-1")}
207
- >
193
+ <label data-ref="chipLabel" className={classNames("fabric-chipLabel", "truncate flex-1")}>
208
194
  {children}
209
195
  </label>
210
196
  )}
@@ -213,10 +199,7 @@ export const Chip = <Tag extends React.ElementType = "div">({
213
199
  role="none"
214
200
  data-ref="chipRemove"
215
201
  data-inner-cliackable
216
- className={classNames(
217
- "fabric-chipRemove",
218
- "cursor-pointer pe-1 opacity-65 hover:opacity-90",
219
- )}
202
+ className={classNames("fabric-chipRemove", "cursor-pointer pe-1 opacity-65 hover:opacity-90")}
220
203
  onClick={removeHandler}
221
204
  >
222
205
  &times;
@@ -101,7 +101,7 @@ export interface CollapsableProps
101
101
  * This component is ideal for creating accordions, expandable panels, or sections that can be toggled by the user.
102
102
  *
103
103
  * @param {CollapsableProps} props - The properties for the Collapsable component.
104
- * @returns {JSX.Element} The rendered Collapsable component.
104
+ * @returns {React.ReactElement} The rendered Collapsable component.
105
105
  *
106
106
  * @example
107
107
  * ```jsx
@@ -167,7 +167,7 @@ export const Collapsable = ({
167
167
  "fabric-collapsableHead",
168
168
  "flex gap-1 flex-nowrap py-2 font-medium cursor-pointer items-center select-none hover:opacity-70",
169
169
  headerClassName,
170
- stickyHeader && "bg-base sticky top-0 py-1 z-10",
170
+ stickyHeader && "bg-default sticky top-0 py-1 z-10",
171
171
  iconAlign === "end" ? "flex-row-reverse" : "flex-row",
172
172
  )}
173
173
  onClick={() => !disabled && setOpenState(!openState)}
@@ -61,7 +61,7 @@ export interface DividerProps extends CssProp, Partial<ChildProp> {
61
61
  * styles, and alignment options.
62
62
  *
63
63
  * @param {DividerProps} props - The properties for the Divider component.
64
- * @returns {JSX.Element} The rendered Divider component.
64
+ * @returns {React.ReactElement} The rendered Divider component.
65
65
  *
66
66
  * @example
67
67
  * ```jsx
@@ -36,6 +36,7 @@ import {
36
36
  useClick,
37
37
  useDismiss,
38
38
  useFloating,
39
+ useFloatingNodeId,
39
40
  useFloatingTree,
40
41
  useHover,
41
42
  useInteractions,
@@ -43,16 +44,7 @@ import {
43
44
  } from "@floating-ui/react";
44
45
  import { mergeRefs } from "@react-fabric/utilities";
45
46
  import classNames from "classnames";
46
- import {
47
- Children,
48
- Fragment,
49
- cloneElement,
50
- useCallback,
51
- useEffect,
52
- useMemo,
53
- useRef,
54
- useState,
55
- } from "react";
47
+ import { Children, Fragment, cloneElement, useEffect, useEffectEvent, useMemo, useRef, useState } from "react";
56
48
  import { type ChildProp, type RefProp } from "../../types";
57
49
 
58
50
  export interface DropdownProps extends RefProp {
@@ -86,9 +78,13 @@ export interface DropdownProps extends RefProp {
86
78
  */
87
79
  dropdownClassName?: string;
88
80
  /**
89
- * dropdown event
81
+ * dropdown trigger event, default is click
82
+ */
83
+ trigger?: "click" | "hover";
84
+ /**
85
+ * portal root element
90
86
  */
91
- dropdownEvent?: "click" | "hover";
87
+ root?: HTMLElement;
92
88
  /**
93
89
  * open handler
94
90
  */
@@ -108,21 +104,21 @@ const DropdownElement = ({
108
104
  placement = "bottom",
109
105
  onClose,
110
106
  onOpen,
107
+ root,
111
108
  disabled,
112
109
  plainDropdown,
113
- dropdownEvent,
110
+ trigger = "click",
114
111
  dropdownClassName,
115
112
  }: DropdownProps) => {
116
113
  const arrowRef = useRef(null);
117
114
  const [isOpen, setIsOpen] = useState(false);
118
115
  const tree = useFloatingTree();
116
+ const nodeId = useFloatingNodeId();
119
117
 
120
- const [anchor, panel] = useMemo<AnyObject[]>(
121
- () => Children.toArray(children as AnyObject),
122
- [children],
123
- );
118
+ const [anchor, panel] = useMemo<AnyObject[]>(() => Children.toArray(children as AnyObject), [children]);
124
119
 
125
120
  const { refs, floatingStyles, context } = useFloating({
121
+ nodeId: `dropdown-${nodeId}`,
126
122
  open: isOpen,
127
123
  onOpenChange: (open, _, reason) => {
128
124
  if (reason === "reference-press") return;
@@ -143,50 +139,44 @@ const DropdownElement = ({
143
139
  ],
144
140
  });
145
141
 
146
- const handler = dropdownEvent === "hover" ? useHover : useClick;
142
+ const handler = trigger === "hover" ? useHover : useClick;
147
143
  const click = handler(context, {
148
144
  enabled: !disabled,
149
145
  handleClose: safePolygon({ blockPointerEvents: true }),
150
146
  });
147
+
151
148
  const dismiss = useDismiss(context, {
152
149
  referencePress: true,
153
150
  });
154
151
 
155
- const { getReferenceProps, getFloatingProps } = useInteractions([
156
- dismiss,
157
- click,
158
- ]);
152
+ const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, click]);
159
153
 
160
154
  const minWidth = useMemo(() => {
161
155
  if (fitToParent) {
162
156
  const el: HTMLElement =
163
157
  // @ts-expect-error ignore
164
- refs.reference.current?.closest('[data-ref="buttonGroup"]') ??
165
- refs.reference.current;
158
+ refs.reference.current?.closest('[data-ref="buttonGroup"]') ?? refs.reference.current;
166
159
  return el?.offsetWidth;
167
160
  }
168
161
  return undefined;
169
162
  }, [refs, isOpen, fitToParent]);
170
163
 
171
- const tryClosing = useCallback(
172
- (e: React.MouseEvent) => {
173
- if (
174
- !refs.floating.current?.contains(
175
- (e.target as HTMLElement).closest("[data-dropdown-dismiss='false']"),
176
- ) &&
177
- (!!closeOnClick ||
178
- refs.floating.current?.contains(
179
- (e.target as HTMLElement).closest("[data-dropdown-dismiss='true']"),
180
- ))
181
- ) {
182
- setTimeout(() => {
183
- setIsOpen(false);
184
- onClose?.();
185
- }, 100);
186
- }
187
- },
188
- [closeOnClick, onClose],
189
- );
164
+ const dismissDropdown = useEffectEvent(() => {
165
+ setIsOpen(false);
166
+ onClose?.();
167
+ });
168
+
169
+ const tryClosing = useEffectEvent((e: React.MouseEvent) => {
170
+ if (
171
+ !refs.floating.current?.contains((e.target as HTMLElement).closest("[data-dropdown-dismiss='false']")) &&
172
+ (!!closeOnClick || refs.floating.current?.contains((e.target as HTMLElement).closest("[data-dropdown-dismiss='true']")))
173
+ ) {
174
+ setTimeout(() => {
175
+ setIsOpen(false);
176
+ onClose?.();
177
+ }, 100);
178
+ }
179
+ });
190
180
 
191
181
  const innerRef = useMemo(
192
182
  () => mergeRefs(ref, anchor.props.ref, refs.setReference),
@@ -211,8 +201,7 @@ const DropdownElement = ({
211
201
  };
212
202
  }, [tree]);
213
203
 
214
- if (!anchor || !panel)
215
- throw Error("Dropdown requires two elements [Anchor, Panel]");
204
+ if (!anchor || !panel) throw Error("Dropdown requires two elements [Anchor, Panel]");
216
205
 
217
206
  return (
218
207
  <Fragment>
@@ -229,14 +218,9 @@ const DropdownElement = ({
229
218
  ref: innerRef,
230
219
  })}
231
220
  {isOpen && (
232
- <FloatingPortal
233
- root={
234
- refs.domReference.current?.closest<HTMLElement>(".theme-base") ??
235
- undefined
236
- }
237
- >
221
+ <FloatingPortal root={root ?? refs.domReference.current?.closest<HTMLElement>(".theme-base") ?? undefined}>
238
222
  <FloatingOverlay />
239
- <FloatingFocusManager context={context} modal>
223
+ <FloatingFocusManager context={context} closeOnFocusOut>
240
224
  <div
241
225
  ref={refs.setFloating}
242
226
  style={{
@@ -254,20 +238,22 @@ const DropdownElement = ({
254
238
  className={classNames(
255
239
  "fabric-dropdownBody",
256
240
  dropdownClassName,
257
- !plainDropdown && "shadow-lg bg-base ring-1 ring-tint-100",
258
- "rounded-capped overflow-auto scroll-thin grid max-h-[70vh]",
241
+ !plainDropdown && "shadow-lg bg-default ring-1 ring-tint-100",
242
+ "rounded-capped grid max-h-[70vh]",
259
243
  )}
260
244
  onMouseUpCapture={tryClosing}
261
245
  >
262
- {panel}
246
+ {cloneElement(
247
+ panel,
248
+ typeof panel.type === "string"
249
+ ? {}
250
+ : {
251
+ dismiss: dismissDropdown,
252
+ },
253
+ )}
263
254
  </div>
264
255
  {showArrow && (
265
- <FloatingArrow
266
- ref={arrowRef}
267
- context={context}
268
- strokeWidth={0.5}
269
- className="fill-base stroke-dimmed"
270
- />
256
+ <FloatingArrow ref={arrowRef} context={context} strokeWidth={0.5} className="fill-default stroke-dimmed" />
271
257
  )}
272
258
  </div>
273
259
  </FloatingFocusManager>
@@ -308,11 +294,17 @@ const DropdownElement = ({
308
294
  * @see {@link https://adarshpastakia.github.io/react-fabric/?path=/docs/core-components-dropdown--docs} for more details.
309
295
  * @see {@link https://floating-ui.com/docs/react} for more details on Floating UI.
310
296
  */
311
- export const Dropdown = (props: DropdownProps) => (
312
- <FloatingTree>
313
- <DropdownElement {...props} />
314
- </FloatingTree>
315
- );
297
+ export const Dropdown = (props: DropdownProps) => {
298
+ const tree = useFloatingTree();
299
+ if (tree) {
300
+ return <DropdownElement {...props} />;
301
+ }
302
+ return (
303
+ <FloatingTree>
304
+ <DropdownElement {...props} />
305
+ </FloatingTree>
306
+ );
307
+ };
316
308
 
317
309
  /**
318
310
  * A component that allows dismissing the dropdown when clicked.
@@ -323,10 +315,7 @@ export const Dropdown = (props: DropdownProps) => (
323
315
  * @param dismiss - Whether to dismiss the dropdown on click (default: true).
324
316
  * @returns JSX Element
325
317
  */
326
- export const DropdownDismiss = ({
327
- children,
328
- dismiss = true,
329
- }: ChildProp & { dismiss?: boolean }) => {
318
+ export const DropdownDismiss = ({ children, dismiss = true }: ChildProp & { dismiss?: boolean }) => {
330
319
  const tree = useFloatingTree();
331
320
 
332
321
  return (
@@ -334,9 +323,7 @@ export const DropdownDismiss = ({
334
323
  role="none"
335
324
  className="contents"
336
325
  data-dropdown-dismiss={dismiss}
337
- onMouseUp={() =>
338
- dismiss && setTimeout(() => tree?.events.emit("close"), 50)
339
- }
326
+ onMouseUp={() => dismiss && setTimeout(() => tree?.events.emit("close"), 50)}
340
327
  >
341
328
  {children}
342
329
  </div>
@@ -37,7 +37,7 @@ import { Dropdown, type DropdownProps } from "./Dropdown";
37
37
  * @param {string} icon - The icon to be displayed in the dropdown.
38
38
  * @param {boolean} groupHover - If true, the dropdown will only be visible when the parent group is hovered.
39
39
  * @param {DropdownProps} props - Additional properties for the dropdown.
40
- * @returns {JSX.Element} The rendered DropdownTool component.
40
+ * @returns {React.ReactElement} The rendered DropdownTool component.
41
41
  *
42
42
  * @example
43
43
  * ```jsx
@@ -41,11 +41,11 @@ export interface EmptyContentProps
41
41
  /**
42
42
  * empty title
43
43
  */
44
- title?: string | JSX.Element;
44
+ title?: string | React.ReactElement;
45
45
  /**
46
46
  * empty message
47
47
  */
48
- message: string | JSX.Element;
48
+ message: string | React.ReactElement;
49
49
  /**
50
50
  * content size
51
51
  */
@@ -113,7 +113,7 @@ const DefaultIcon = () => (
113
113
  * such as in empty states of lists, tables, or other content areas.
114
114
  *
115
115
  * @param {EmptyContentProps} props - The properties for the EmptyContent component.
116
- * @returns {JSX.Element} The rendered EmptyContent component.
116
+ * @returns {React.ReactElement} The rendered EmptyContent component.
117
117
  *
118
118
  * @example
119
119
  * ```jsx