) {
draft.dynamic[args.placement].active = undefined;
return;
}
- draft.dynamic.left.active = undefined;
+
+ const placements = ["left", "right"] as const;
+ for (const placement of placements) {
+ const slice = draft.dynamic[placement];
+ const panel = slice.active;
+ if (!panel) continue;
+ if (panel.id !== args.id) continue;
+
+ slice.active = undefined;
+ }
})
);
},
@@ -140,19 +162,22 @@ export function PanelsProvider(props: React.PropsWithChildren) {
React.useEffect(() => {
if (!frontstageDef) return;
return store.subscribe((state, prevState) => {
- const prevOpen = prevState.dynamic.left.active?.id;
- const currOpen = state.dynamic.left.active?.id;
- if (prevOpen === currOpen) return;
- prevOpen &&
- frontstageDef.panels.onPanelOpenChanged.raiseEvent({
- id: prevOpen,
- open: false,
- });
- currOpen &&
- frontstageDef.panels.onPanelOpenChanged.raiseEvent({
- id: currOpen,
- open: true,
- });
+ const placements = ["left", "right"] as const;
+ for (const placement of placements) {
+ const prevOpen = prevState.dynamic[placement].active?.id;
+ const currOpen = state.dynamic[placement].active?.id;
+ if (prevOpen === currOpen) continue;
+ prevOpen &&
+ frontstageDef.panels.onPanelOpenChanged.raiseEvent({
+ id: prevOpen,
+ open: false,
+ });
+ currOpen &&
+ frontstageDef.panels.onPanelOpenChanged.raiseEvent({
+ id: currOpen,
+ open: true,
+ });
+ }
});
}, [frontstageDef, store]);
return (
From 69667e9a06f6255ebbae40a961d6d26a13366cde Mon Sep 17 00:00:00 2001
From: GerardasB <10091419+GerardasB@users.noreply.github.com>
Date: Fri, 19 Dec 2025 15:28:58 +0200
Subject: [PATCH 05/12] fix sb
---
docs/storybook/src/frontstage/Panels.stories.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/storybook/src/frontstage/Panels.stories.tsx b/docs/storybook/src/frontstage/Panels.stories.tsx
index 9131158584b..0d551e930e8 100644
--- a/docs/storybook/src/frontstage/Panels.stories.tsx
+++ b/docs/storybook/src/frontstage/Panels.stories.tsx
@@ -9,7 +9,7 @@ import { createWidget, removeProperty } from "../Utils";
import { Button } from "@itwin/itwinui-react";
import { useActiveFrontstageDef } from "@itwin/appui-react";
import React from "react";
-import { action } from "storybook/internal/actions";
+import { action } from "storybook/actions";
const meta = {
title: "Frontstage/Panels",
From 4fb744cd24c39abb6d47ee9d214e0c55dd265067 Mon Sep 17 00:00:00 2001
From: GerardasB <10091419+GerardasB@users.noreply.github.com>
Date: Mon, 22 Dec 2025 14:43:07 +0200
Subject: [PATCH 06/12] useSyncExternalStore
---
.../src/frontstage/Panels.stories.tsx | 42 +++++++++++--------
.../appui-react/frontstage/FrontstageDef.tsx | 24 +++++++----
2 files changed, 41 insertions(+), 25 deletions(-)
diff --git a/docs/storybook/src/frontstage/Panels.stories.tsx b/docs/storybook/src/frontstage/Panels.stories.tsx
index 0d551e930e8..a7df6310299 100644
--- a/docs/storybook/src/frontstage/Panels.stories.tsx
+++ b/docs/storybook/src/frontstage/Panels.stories.tsx
@@ -2,14 +2,14 @@
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
+import * as React from "react";
+import { useActiveFrontstageDef } from "@itwin/appui-react";
+import { Button } from "@itwin/itwinui-react";
import type { Meta, StoryObj } from "@storybook/react-vite";
+import { action } from "storybook/actions";
import { Page } from "../AppUiStory";
import { PanelsStory } from "./Panels";
import { createWidget, removeProperty } from "../Utils";
-import { Button } from "@itwin/itwinui-react";
-import { useActiveFrontstageDef } from "@itwin/appui-react";
-import React from "react";
-import { action } from "storybook/actions";
const meta = {
title: "Frontstage/Panels",
@@ -68,19 +68,27 @@ export const DynamicPanel: Story = {
},
};
-function Widget() {
+function useOpenPanels() {
const frontstageDef = useActiveFrontstageDef();
- const [openPanels, setOpenPanels] = React.useState(() => {
- if (!frontstageDef) return [];
- return frontstageDef.panels.getOpenPanels();
- });
- React.useEffect(() => {
- if (!frontstageDef) return;
- return frontstageDef.panels.onPanelOpenChanged.addListener((args) => {
- action("onPanelOpenChanged")(args);
- setOpenPanels(frontstageDef.panels.getOpenPanels());
- });
+ const subscribe = React.useCallback(
+ (onStoreChange: () => void) => {
+ if (!frontstageDef) return () => {};
+ return frontstageDef.panels.onPanelOpenChanged.addListener((args) => {
+ action("onPanelOpenChanged")(args);
+ onStoreChange();
+ });
+ },
+ [frontstageDef]
+ );
+ const getSnapshot = React.useCallback(() => {
+ return frontstageDef?.panels.getOpenPanels();
}, [frontstageDef]);
+ return React.useSyncExternalStore(subscribe, getSnapshot);
+}
+
+function Widget() {
+ const frontstageDef = useActiveFrontstageDef();
+ const openPanels = useOpenPanels();
return (
{
const id = "panel1";
- const isActive = openPanels.some((p) => p === id);
+ const isActive = openPanels?.some((p) => p === id);
if (isActive) {
frontstageDef?.panels.close({
id,
@@ -108,7 +116,7 @@ function Widget() {
+
);
}
From db84b7c2645393ae15044df1608398e79e77c176 Mon Sep 17 00:00:00 2001
From: GerardasB <10091419+GerardasB@users.noreply.github.com>
Date: Tue, 23 Dec 2025 16:19:02 +0200
Subject: [PATCH 09/12] Refactor
---
.../appui-react/frontstage/FrontstageDef.tsx | 16 +++--
.../layout/widget-panels/Panel.tsx | 22 +------
.../src/appui-react/panel/DynamicPanel.scss | 4 +-
.../src/appui-react/panel/DynamicPanel.tsx | 62 +++++++++++++++----
.../src/appui-react/panel/PanelsState.tsx | 13 ++--
5 files changed, 74 insertions(+), 43 deletions(-)
diff --git a/ui/appui-react/src/appui-react/frontstage/FrontstageDef.tsx b/ui/appui-react/src/appui-react/frontstage/FrontstageDef.tsx
index b0147f69750..d69cbf6f099 100644
--- a/ui/appui-react/src/appui-react/frontstage/FrontstageDef.tsx
+++ b/ui/appui-react/src/appui-react/frontstage/FrontstageDef.tsx
@@ -64,7 +64,11 @@ import {
FRONTSTAGE_SETTINGS_NAMESPACE,
getFrontstageStateSettingName,
} from "../widget-panels/Frontstage.js";
-import type { createPanelsStore, PanelsState } from "../panel/PanelsState.js";
+import {
+ type createPanelsStore,
+ dynamicPanelPlacements,
+ type PanelsState,
+} from "../panel/PanelsState.js";
import type { Panel } from "../panel/Panel.js";
import { shallow } from "zustand/shallow";
@@ -1195,10 +1199,12 @@ function createFrontstagePanels(
if (!panelsStore) return [];
const state = panelsStore.getState();
const panels: Panel["id"][] = [];
- if (state.dynamic.left.active)
- panels.push(state.dynamic.left.active.id);
- if (state.dynamic.right.active)
- panels.push(state.dynamic.right.active.id);
+ for (const placement of dynamicPanelPlacements) {
+ const slice = state.dynamic[placement];
+ const panel = slice.active;
+ if (!panel) continue;
+ panels.push(panel.id);
+ }
return panels;
})();
if (shallow(openPanels, prevOpenPanels)) return prevOpenPanels;
diff --git a/ui/appui-react/src/appui-react/layout/widget-panels/Panel.tsx b/ui/appui-react/src/appui-react/layout/widget-panels/Panel.tsx
index 20564a4f9c1..32885f53368 100644
--- a/ui/appui-react/src/appui-react/layout/widget-panels/Panel.tsx
+++ b/ui/appui-react/src/appui-react/layout/widget-panels/Panel.tsx
@@ -31,11 +31,7 @@ import type {
import { useAnimatePanel } from "./useAnimatePanel.js";
import { useMaximizedPanel } from "../../preview/enable-maximized-widget/useMaximizedWidget.js";
import type { RectangleProps } from "../../utils/RectangleProps.js";
-import { DynamicPanel } from "../../panel/DynamicPanel.js";
-import {
- type DynamicPanelPlacement,
- usePanelsStore,
-} from "../../panel/PanelsState.js";
+import { DynamicPanelRenderer } from "../../panel/DynamicPanel.js";
/** Properties of [[WidgetPanelProvider]] component.
* @internal
@@ -51,11 +47,6 @@ export function WidgetPanelProvider({ side }: WidgetPanelProviderProps) {
const hasWidgets = useLayout(
(state) => state.panels[side].widgets.length > 0
);
- const slice = usePanelsStore((state) => {
- const placement = toDynamicPanelPlacement(side);
- if (!placement) return undefined;
- return state.dynamic[placement];
- });
return (
@@ -63,19 +54,10 @@ export function WidgetPanelProvider({ side }: WidgetPanelProviderProps) {
- {slice?.active && }
+
);
}
-
-function toDynamicPanelPlacement(
- side: PanelSide
-): DynamicPanelPlacement | undefined {
- if (side === "left") return "left";
- if (side === "right") return "right";
- return undefined;
-}
-
/** @internal */
export function WidgetPanel() {
const side = React.useContext(PanelSideContext);
diff --git a/ui/appui-react/src/appui-react/panel/DynamicPanel.scss b/ui/appui-react/src/appui-react/panel/DynamicPanel.scss
index d3c0726cb3c..9e5e43981ea 100644
--- a/ui/appui-react/src/appui-react/panel/DynamicPanel.scss
+++ b/ui/appui-react/src/appui-react/panel/DynamicPanel.scss
@@ -19,11 +19,11 @@
flex-direction: column;
gap: $padding;
- &:where([data-_appui-panel-side="left"]) {
+ &:where([data-_appui-placement="left"]) {
border-right-width: 1px;
}
- &:where([data-_appui-panel-side="right"]) {
+ &:where([data-_appui-placement="right"]) {
border-left-width: 1px;
}
}
diff --git a/ui/appui-react/src/appui-react/panel/DynamicPanel.tsx b/ui/appui-react/src/appui-react/panel/DynamicPanel.tsx
index d00af3fa9c8..8c52049a794 100644
--- a/ui/appui-react/src/appui-react/panel/DynamicPanel.tsx
+++ b/ui/appui-react/src/appui-react/panel/DynamicPanel.tsx
@@ -10,37 +10,75 @@ import "./DynamicPanel.scss";
import * as React from "react";
import { Divider, IconButton } from "@itwin/itwinui-react";
import { SvgCloseSmall } from "@itwin/itwinui-icons-react";
-import type { DynamicPanel, DynamicPanelSlice } from "./PanelsState.js";
-import { PanelSideContext } from "../layout/widget-panels/Panel.js";
+import { type DynamicPanelPlacement, usePanelsStore } from "./PanelsState.js";
import { useConditionalValueProp } from "../shared/ConditionalValue.js";
+import { PanelSideContext } from "../layout/widget-panels/Panel.js";
+import type { PanelSide } from "../layout/widget-panels/PanelTypes.js";
+import { useSafeContext } from "../hooks/useSafeContext.js";
interface DynamicPanelProps {
- panel: DynamicPanel;
- slice: DynamicPanelSlice;
+ placement: DynamicPanelPlacement;
+ label: string | undefined;
+ onClose?: () => void;
+ content: React.ReactNode;
}
-/** @internal */
function DynamicPanelComponent(props: DynamicPanelProps) {
- const side = React.useContext(PanelSideContext);
- const { panel, slice } = props;
- const label = useConditionalValueProp(panel.label);
+ const { placement, label, onClose, content } = props;
return (
-
+
{label}
-
{panel.content}
+
{content}
);
}
-export { DynamicPanelComponent as DynamicPanel };
+interface FrameworkDynamicPanelProps {
+ placement: DynamicPanelPlacement;
+}
+
+function FrameworkDynamicPanel(props: FrameworkDynamicPanelProps) {
+ const { placement } = props;
+ const slice = usePanelsStore((state) => {
+ if (!placement) return undefined;
+ return state.dynamic[placement];
+ });
+ const panel = slice?.active;
+ const label = useConditionalValueProp(panel?.label);
+ if (!panel) return null;
+ return (
+
+ );
+}
+
+/** @internal */
+export function DynamicPanelRenderer() {
+ const side = useSafeContext(PanelSideContext);
+ const placement = toDynamicPanelPlacement(side);
+ if (!placement) return;
+ return
;
+}
+
+function toDynamicPanelPlacement(
+ side: PanelSide
+): DynamicPanelPlacement | undefined {
+ if (side === "left") return "left";
+ if (side === "right") return "right";
+ return undefined;
+}
diff --git a/ui/appui-react/src/appui-react/panel/PanelsState.tsx b/ui/appui-react/src/appui-react/panel/PanelsState.tsx
index 9fe45b7f775..9bf5b516c0f 100644
--- a/ui/appui-react/src/appui-react/panel/PanelsState.tsx
+++ b/ui/appui-react/src/appui-react/panel/PanelsState.tsx
@@ -20,17 +20,23 @@ export type DynamicPanelPlacement = Extract<
"left" | "right"
>;
+/** @internal */
+export const dynamicPanelPlacements = [
+ "left",
+ "right",
+] as const satisfies readonly DynamicPanelPlacement[];
+
interface OpenPanelArgs {
id: string;
}
type ClosePanelArgs =
| {
- id: string;
+ id: Panel["id"];
}
| {
type: "dynamic";
- placement: "left" | "right";
+ placement: DynamicPanelPlacement;
};
/** @internal */
@@ -112,8 +118,7 @@ export function createPanelsStore(stateOverrides?: Partial
) {
return;
}
- const placements = ["left", "right"] as const;
- for (const placement of placements) {
+ for (const placement of dynamicPanelPlacements) {
const slice = draft.dynamic[placement];
const panel = slice.active;
if (!panel) continue;
From d60170f7ad01e8a72153b31fdfcba404c78e7bbc Mon Sep 17 00:00:00 2001
From: GerardasB <10091419+GerardasB@users.noreply.github.com>
Date: Tue, 23 Dec 2025 17:42:34 +0200
Subject: [PATCH 10/12] Extract API
---
common/api/appui-react.api.md | 13 +++++++++++++
common/api/summary/appui-react.exports.csv | 1 +
2 files changed, 14 insertions(+)
diff --git a/common/api/appui-react.api.md b/common/api/appui-react.api.md
index 185387d8aab..28855c4f77d 100644
--- a/common/api/appui-react.api.md
+++ b/common/api/appui-react.api.md
@@ -94,6 +94,7 @@ import { SnapMode } from '@itwin/core-frontend';
import type { SolarDataProvider } from '@itwin/imodel-components-react';
import { StandardViewId } from '@itwin/core-frontend';
import type { Store } from 'redux';
+import { StoreApi } from 'zustand';
import type { StringGetter } from '@itwin/appui-abstract';
import type { ToggleSwitch } from '@itwin/itwinui-react';
import { Tool } from '@itwin/core-frontend';
@@ -2352,6 +2353,8 @@ export class FrontstageDef {
getFloatingWidgetContainerIdByWidgetId(widgetId: string): string | undefined;
// (undocumented)
getFloatingWidgetContainerIds(): string[];
+ // @internal (undocumented)
+ getPanelsStore(): ReturnType | undefined;
// @beta
getStagePanelDef(location: StagePanelLocation): StagePanelDef | undefined;
// (undocumented)
@@ -2386,6 +2389,8 @@ export class FrontstageDef {
openPopoutWidgetContainer(widgetContainerId: string, oldState: NineZoneState | undefined): boolean;
// @beta
get panelDefs(): StagePanelDef[];
+ // (undocumented)
+ get panels(): FrontstagePanels;
// @beta
popoutWidget(widgetId: string, position?: XAndY, size?: SizeProps): void;
// @beta
@@ -2404,6 +2409,8 @@ export class FrontstageDef {
setFloatingWidgetContainerBounds(floatingWidgetId: string, bounds: RectangleProps): boolean;
// @internal (undocumented)
setIsApplicationClosing(value: boolean): void;
+ // @internal (undocumented)
+ setPanelsStore(panelsStore: ReturnType): void;
// (undocumented)
get statusBar(): WidgetDef | undefined;
// @internal (undocumented)
@@ -3450,6 +3457,9 @@ export interface OverflowToolbarOptions {
overflowExpandsTo?: Direction;
}
+// @public
+export type Panel = CommonPanel | InformationPanel | DynamicPanel;
+
// @public @deprecated
export interface PanelPinnedChangedEventArgs {
// (undocumented)
@@ -5246,6 +5256,8 @@ export class UiItemsManager {
// @internal
static clearAllProviders(): void;
static getBackstageItems(): ReadonlyArray>;
+ // (undocumented)
+ static getPanels(stageId: string, stageUsage: string): ReadonlyArray>;
static getStatusBarItems(stageId: string, stageUsage: string): ReadonlyArray>;
static getToolbarButtonItems(stageId: string, stageUsage: string, usage: ToolbarUsage, orientation: ToolbarOrientation): ReadonlyArray>;
static getToolbarItems(stageId: string, stageUsage: string): ReadonlyArray>;
@@ -5264,6 +5276,7 @@ export class UiItemsManager {
// @public
export interface UiItemsProvider {
readonly getBackstageItems?: () => ReadonlyArray;
+ readonly getPanels?: () => ReadonlyArray;
readonly getStatusBarItems?: () => ReadonlyArray;
readonly getToolbarItems?: () => ReadonlyArray;
readonly getWidgets?: () => ReadonlyArray;
diff --git a/common/api/summary/appui-react.exports.csv b/common/api/summary/appui-react.exports.csv
index d9847a78ec8..9fbb6934b65 100644
--- a/common/api/summary/appui-react.exports.csv
+++ b/common/api/summary/appui-react.exports.csv
@@ -478,6 +478,7 @@ public;interface;OpenChildWindowInfo
public;class;OpenMessageCenterEvent
deprecated;class;OpenMessageCenterEvent
public;interface;OverflowToolbarOptions
+public;type;Panel
public;interface;PanelPinnedChangedEventArgs
deprecated;interface;PanelPinnedChangedEventArgs
beta;class;PanelStateChangedEvent
From 47cff125dbd04aaab1ded98a646fa242e7d28623 Mon Sep 17 00:00:00 2001
From: GerardasB <10091419+GerardasB@users.noreply.github.com>
Date: Tue, 23 Dec 2025 17:42:43 +0200
Subject: [PATCH 11/12] pnpm changeset
---
.changeset/free-shoes-chew.md | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 .changeset/free-shoes-chew.md
diff --git a/.changeset/free-shoes-chew.md b/.changeset/free-shoes-chew.md
new file mode 100644
index 00000000000..b0c5feed478
--- /dev/null
+++ b/.changeset/free-shoes-chew.md
@@ -0,0 +1,23 @@
+---
+"@itwin/appui-react": minor
+---
+
+Added `getPanels` property to `UiItemsProvider` interface which allows panel items to be defined. Once defined the `panels` getter of `FrontstageDef` class can be used to control the visibility and behavior of provided panels.
+
+```tsx
+UiItemsManager.register({
+ id: "my-provider",
+ getPanels: () => [
+ {
+ id: "panel1",
+ type: "dynamic",
+ placement: "left",
+ label: "Panel 1",
+ content: <>Panel 1 content>,
+ },
+ ],
+});
+
+const frontstageDef = UiFramework.frontstages.activeFrontstageDef;
+frontstageDef?.panels.open({ id: "panel1" });
+```
From c1ace7bb65db97142b09915eebbfd96e6f28fafc Mon Sep 17 00:00:00 2001
From: GerardasB <10091419+GerardasB@users.noreply.github.com>
Date: Mon, 29 Dec 2025 14:22:54 +0200
Subject: [PATCH 12/12] Fix tests
---
.../src/appui-react/panel/DynamicPanel.tsx | 20 +++++++++++--------
.../src/appui-react/panel/PanelsState.tsx | 12 ++---------
.../test/hooks/useConditionalValue.test.tsx | 4 +++-
3 files changed, 17 insertions(+), 19 deletions(-)
diff --git a/ui/appui-react/src/appui-react/panel/DynamicPanel.tsx b/ui/appui-react/src/appui-react/panel/DynamicPanel.tsx
index 8c52049a794..cdf2f5a8a0f 100644
--- a/ui/appui-react/src/appui-react/panel/DynamicPanel.tsx
+++ b/ui/appui-react/src/appui-react/panel/DynamicPanel.tsx
@@ -8,13 +8,15 @@
import "./DynamicPanel.scss";
import * as React from "react";
+import { useStore } from "zustand";
import { Divider, IconButton } from "@itwin/itwinui-react";
import { SvgCloseSmall } from "@itwin/itwinui-icons-react";
-import { type DynamicPanelPlacement, usePanelsStore } from "./PanelsState.js";
+import { PanelsStoreContext } from "./PanelsState.js";
import { useConditionalValueProp } from "../shared/ConditionalValue.js";
import { PanelSideContext } from "../layout/widget-panels/Panel.js";
+import type { createPanelsStore } from "./PanelsState.js";
+import type { DynamicPanelPlacement } from "./PanelsState.js";
import type { PanelSide } from "../layout/widget-panels/PanelTypes.js";
-import { useSafeContext } from "../hooks/useSafeContext.js";
interface DynamicPanelProps {
placement: DynamicPanelPlacement;
@@ -46,11 +48,12 @@ function DynamicPanelComponent(props: DynamicPanelProps) {
interface FrameworkDynamicPanelProps {
placement: DynamicPanelPlacement;
+ store: ReturnType;
}
function FrameworkDynamicPanel(props: FrameworkDynamicPanelProps) {
- const { placement } = props;
- const slice = usePanelsStore((state) => {
+ const { placement, store } = props;
+ const slice = useStore(store, (state) => {
if (!placement) return undefined;
return state.dynamic[placement];
});
@@ -69,14 +72,15 @@ function FrameworkDynamicPanel(props: FrameworkDynamicPanelProps) {
/** @internal */
export function DynamicPanelRenderer() {
- const side = useSafeContext(PanelSideContext);
+ const side = React.useContext(PanelSideContext);
+ const store = React.useContext(PanelsStoreContext);
const placement = toDynamicPanelPlacement(side);
- if (!placement) return;
- return ;
+ if (!placement || !store) return;
+ return ;
}
function toDynamicPanelPlacement(
- side: PanelSide
+ side: PanelSide | undefined
): DynamicPanelPlacement | undefined {
if (side === "left") return "left";
if (side === "right") return "right";
diff --git a/ui/appui-react/src/appui-react/panel/PanelsState.tsx b/ui/appui-react/src/appui-react/panel/PanelsState.tsx
index 9bf5b516c0f..054ff5d3772 100644
--- a/ui/appui-react/src/appui-react/panel/PanelsState.tsx
+++ b/ui/appui-react/src/appui-react/panel/PanelsState.tsx
@@ -5,7 +5,6 @@
import * as React from "react";
import type { StateCreator } from "zustand";
import { createStore, useStore } from "zustand";
-import { useSafeContext } from "../hooks/useSafeContext.js";
import { isDynamicPanel, type Panel } from "./Panel.js";
import { UiItemsManager } from "../ui-items-provider/UiItemsManager.js";
import { useActiveFrontstageDef } from "../frontstage/FrontstageDef.js";
@@ -134,7 +133,8 @@ export function createPanelsStore(stateOverrides?: Partial) {
});
}
-const PanelsStoreContext = React.createContext<
+/** @internal */
+export const PanelsStoreContext = React.createContext<
ReturnType | undefined
>(undefined);
@@ -191,11 +191,3 @@ export function PanelsProvider(props: React.PropsWithChildren) {
);
}
-
-/** @internal */
-export function usePanelsStore(
- selector: (state: PanelsState) => SelectorOutput
-) {
- const store = useSafeContext(PanelsStoreContext);
- return useStore(store, selector);
-}
diff --git a/ui/appui-react/src/test/hooks/useConditionalValue.test.tsx b/ui/appui-react/src/test/hooks/useConditionalValue.test.tsx
index 5ce42e83f46..683e649b9d3 100644
--- a/ui/appui-react/src/test/hooks/useConditionalValue.test.tsx
+++ b/ui/appui-react/src/test/hooks/useConditionalValue.test.tsx
@@ -21,18 +21,20 @@ describe("useConditionalValue", () => {
let counter = 0;
const { result } = renderHook(() =>
useConditionalValue(() => {
- return counter++;
+ return counter;
}, ["myEvent1"])
);
expect(result.current).toEqual(0);
act(() => {
+ counter++;
SyncUiEventDispatcher.dispatchSyncUiEvent("myEvent1");
vi.advanceTimersByTime(timeToWaitForUiSyncCallback);
});
expect(result.current).toEqual(1);
act(() => {
+ counter++;
SyncUiEventDispatcher.dispatchSyncUiEvent("myevent1");
vi.advanceTimersByTime(timeToWaitForUiSyncCallback);
});