diff --git a/.changeset/actionbar-flicker-fix.md b/.changeset/actionbar-flicker-fix.md new file mode 100644 index 00000000000..4219365d26b --- /dev/null +++ b/.changeset/actionbar-flicker-fix.md @@ -0,0 +1,5 @@ +--- +'@primer/react': patch +--- + +ActionBar: Fixed flickering on initial render by applying visibility:hidden during initial width calculations. This prevents items from briefly appearing and then disappearing on slower devices. diff --git a/.vscode/settings.json b/.vscode/settings.json index c5f11daa02b..50b422ce52f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -43,4 +43,4 @@ "node_modules/@primer/primitives/dist/css/functional/themes/light-tritanopia.css" ], "cssvar.files": ["node_modules/@primer/primitives/dist/css/**/*.css"] -} +} \ No newline at end of file diff --git a/packages/react/src/ActionBar/ActionBar.tsx b/packages/react/src/ActionBar/ActionBar.tsx index 83712ce21fd..e37c826a58f 100644 --- a/packages/react/src/ActionBar/ActionBar.tsx +++ b/packages/react/src/ActionBar/ActionBar.tsx @@ -303,8 +303,10 @@ export const ActionBar: React.FC> = prop const [childRegistry, setChildRegistry] = ActionBarItemsRegistry.useRegistryState() const [menuItemIds, setMenuItemIds] = useState>(() => new Set()) + const [isInitialRender, setIsInitialRender] = useState(true) const navRef = useRef(null) + // measure gap after first render & whenever gap scale changes useIsomorphicLayoutEffect(() => { if (!listRef.current) return @@ -322,6 +324,7 @@ export const ActionBar: React.FC> = prop if (navWidth > 0) { const newMenuItemIds = getMenuItems(navWidth, moreMenuWidth, childRegistry, hasActiveMenu, computedGap) if (newMenuItemIds) setMenuItemIds(newMenuItemIds) + setIsInitialRender(false) } }, navRef as RefObject) @@ -361,6 +364,7 @@ export const ActionBar: React.FC> = prop aria-label={ariaLabel} aria-labelledby={ariaLabelledBy} data-gap={gap} + style={isInitialRender ? {visibility: 'hidden'} : undefined} > {children} {menuItemIds.size > 0 && (