From 53268fa77233b25a9c30198f4c229ca66430a64b Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Wed, 25 Feb 2026 16:55:08 +0000 Subject: [PATCH] Add BgReset Signed-off-by: Charles de Dreuille --- .storybook/preview.tsx | 2 +- packages/ui/report.api.md | 4 +- packages/ui/src/components/Dialog/Dialog.tsx | 15 +- packages/ui/src/components/Menu/Menu.tsx | 241 +++++++++--------- .../components/Popover/Popover.stories.tsx | 2 +- .../ui/src/components/Popover/Popover.tsx | 15 +- .../ui/src/components/Tooltip/Tooltip.tsx | 15 +- packages/ui/src/hooks/useBg.tsx | 18 ++ packages/ui/src/types.ts | 5 +- 9 files changed, 177 insertions(+), 140 deletions(-) diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index c5074f7749..9734cee295 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -176,7 +176,7 @@ export default definePreview({ : parseInt(selectedBackground.split('-')[1], 10), }).reduce( children => ( - + {children} ), diff --git a/packages/ui/report.api.md b/packages/ui/report.api.md index 25522f1825..3ca30cd73c 100644 --- a/packages/ui/report.api.md +++ b/packages/ui/report.api.md @@ -76,7 +76,7 @@ export const AccordionDefinition: { readonly propDefs: { readonly bg: { readonly dataAttribute: true; - readonly default: 'neutral-auto'; + readonly default: 'neutral'; }; readonly children: {}; readonly className: {}; @@ -1604,7 +1604,7 @@ export interface PopoverProps extends Omit { } // @public -export type ProviderBg = ContainerBg | 'neutral-auto'; +export type ProviderBg = 'neutral' | 'danger' | 'warning' | 'success'; // @public (undocumented) export interface QueryOptions { diff --git a/packages/ui/src/components/Dialog/Dialog.tsx b/packages/ui/src/components/Dialog/Dialog.tsx index efdc6c4567..0c0f4bf53f 100644 --- a/packages/ui/src/components/Dialog/Dialog.tsx +++ b/packages/ui/src/components/Dialog/Dialog.tsx @@ -34,6 +34,7 @@ import { useStyles } from '../../hooks/useStyles'; import { DialogDefinition } from './definition'; import { Flex } from '../Flex'; import { Box } from '../Box'; +import { BgReset } from '../../hooks/useBg'; import styles from './Dialog.module.css'; /** @public */ @@ -72,12 +73,14 @@ export const Dialog = forwardRef, DialogProps>( ...style, }} > - - {children} - + + + {children} + + ); diff --git a/packages/ui/src/components/Menu/Menu.tsx b/packages/ui/src/components/Menu/Menu.tsx index da4243f643..a9835b2f68 100644 --- a/packages/ui/src/components/Menu/Menu.tsx +++ b/packages/ui/src/components/Menu/Menu.tsx @@ -59,6 +59,7 @@ import { import styles from './Menu.module.css'; import clsx from 'clsx'; import { Box } from '../Box'; +import { BgReset } from '../../hooks/useBg'; const { RoutingProvider, useRoutingRegistrationEffect } = createRoutingRegistration(); @@ -120,23 +121,25 @@ export const Menu = (props: MenuProps) => { )} placement={placement} > - - {virtualized ? ( - - {menuContent} - - ) : ( - menuContent - )} - + + + {virtualized ? ( + + {menuContent} + + ) : ( + menuContent + )} + + ); @@ -175,23 +178,25 @@ export const MenuListBox = (props: MenuListBoxProps) => { )} placement={placement} > - - {virtualized ? ( - - {listBoxContent} - - ) : ( - listBoxContent - )} - + + + {virtualized ? ( + + {listBoxContent} + + ) : ( + listBoxContent + )} + + ); }; @@ -230,48 +235,50 @@ export const MenuAutocomplete = (props: MenuAutocompleteProps) => { )} placement={placement} > - - - + + + + + + + + + {virtualized ? ( + + {menuContent} + + ) : ( + menuContent )} - aria-label={props.placeholder || 'Search'} - > - - - - - - {virtualized ? ( - - {menuContent} - - ) : ( - menuContent - )} - - + + + ); @@ -314,48 +321,50 @@ export const MenuAutocompleteListbox = ( )} placement={placement} > - - - + + + + + + + + + {virtualized ? ( + + {listBoxContent} + + ) : ( + listBoxContent )} - aria-label={props.placeholder || 'Search'} - > - - - - - - {virtualized ? ( - - {listBoxContent} - - ) : ( - listBoxContent - )} - - + + + ); }; diff --git a/packages/ui/src/components/Popover/Popover.stories.tsx b/packages/ui/src/components/Popover/Popover.stories.tsx index e05b352fc9..0a0e68b572 100644 --- a/packages/ui/src/components/Popover/Popover.stories.tsx +++ b/packages/ui/src/components/Popover/Popover.stories.tsx @@ -208,7 +208,7 @@ export const WithRichContent = Default.extend({ This is a popover with rich content. It can contain multiple elements and formatted text. - + You can also use the automatic bg system inside it. diff --git a/packages/ui/src/components/Popover/Popover.tsx b/packages/ui/src/components/Popover/Popover.tsx index ad8a203558..ed13328a94 100644 --- a/packages/ui/src/components/Popover/Popover.tsx +++ b/packages/ui/src/components/Popover/Popover.tsx @@ -23,6 +23,7 @@ import { useStyles } from '../../hooks/useStyles'; import { PopoverDefinition } from './definition'; import styles from './Popover.module.css'; import { Box } from '../Box'; +import { BgReset } from '../../hooks/useBg'; /** * A popover component built on React Aria Components that displays floating @@ -95,12 +96,14 @@ export const Popover = forwardRef( )} - - {children} - + + + {children} + + )} diff --git a/packages/ui/src/components/Tooltip/Tooltip.tsx b/packages/ui/src/components/Tooltip/Tooltip.tsx index a64c8c072d..d7fb97005b 100644 --- a/packages/ui/src/components/Tooltip/Tooltip.tsx +++ b/packages/ui/src/components/Tooltip/Tooltip.tsx @@ -28,6 +28,7 @@ import { useStyles } from '../../hooks/useStyles'; import { TooltipDefinition } from './definition'; import styles from './Tooltip.module.css'; import { Box } from '../Box'; +import { BgReset } from '../../hooks/useBg'; /** @public */ export const TooltipTrigger = (props: TooltipTriggerComponentProps) => { @@ -71,12 +72,14 @@ export const Tooltip = forwardRef( - - {children} - + + + {children} + + ); }, diff --git a/packages/ui/src/hooks/useBg.tsx b/packages/ui/src/hooks/useBg.tsx index ea9376b039..e67c47da49 100644 --- a/packages/ui/src/hooks/useBg.tsx +++ b/packages/ui/src/hooks/useBg.tsx @@ -69,6 +69,24 @@ export const BgProvider = ({ bg, children }: BgProviderProps) => { ); }; +/** + * Resets the bg context to undefined, cutting any inherited neutral chain. + * Use this inside overlay components (Popover, Tooltip, Dialog, Menu) so + * their content always starts from neutral-1 regardless of where the trigger + * is placed in the tree. + * + * @internal + */ +export const BgReset = ({ children }: { children: ReactNode }) => { + return ( + + {children} + + ); +}; + /** * Hook for consumer components (e.g. Button) to read the parent bg context. * diff --git a/packages/ui/src/types.ts b/packages/ui/src/types.ts index 05ef25d5dc..af87bfb20b 100644 --- a/packages/ui/src/types.ts +++ b/packages/ui/src/types.ts @@ -190,9 +190,10 @@ export interface ComponentDefinition { * The 'neutral-4' level is not exposed as a prop value -- it is reserved * for leaf component CSS (e.g. Button on a 'neutral-3' surface). * - * This type is internal. Use `ProviderBg` for component prop types. + * This is the resolved/internal representation used by the bg context system. + * For the prop type accepted by container components, use `ProviderBg` instead. * - * @internal + * @public */ export type ContainerBg = | 'neutral-1'