@itwin/appui-react 4.2.0 → 4.3.0-dev.1

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 (104) hide show
  1. package/lib/cjs/appui-react/UiFramework.d.ts +0 -7
  2. package/lib/cjs/appui-react/UiFramework.d.ts.map +1 -1
  3. package/lib/cjs/appui-react/UiFramework.js +0 -21
  4. package/lib/cjs/appui-react/UiFramework.js.map +1 -1
  5. package/lib/cjs/appui-react/_variables.scss +3 -3
  6. package/lib/cjs/appui-react/accudraw/AccuDrawFieldContainer.scss +3 -3
  7. package/lib/cjs/appui-react/accudraw/AccuDrawInputField.scss +3 -3
  8. package/lib/cjs/appui-react/childwindow/InternalChildWindowManager.d.ts.map +1 -1
  9. package/lib/cjs/appui-react/childwindow/InternalChildWindowManager.js +1 -2
  10. package/lib/cjs/appui-react/childwindow/InternalChildWindowManager.js.map +1 -1
  11. package/lib/cjs/appui-react/childwindow/InternalChildWindowManager.scss +3 -3
  12. package/lib/cjs/appui-react/configurableui/configurableui.scss +3 -3
  13. package/lib/cjs/appui-react/content/DefaultViewOverlay.scss +3 -3
  14. package/lib/cjs/appui-react/feedback/ValidationTextbox.scss +3 -3
  15. package/lib/cjs/appui-react/frontstage/FrontstageDef.d.ts.map +1 -1
  16. package/lib/cjs/appui-react/frontstage/FrontstageDef.js +24 -5
  17. package/lib/cjs/appui-react/frontstage/FrontstageDef.js.map +1 -1
  18. package/lib/cjs/appui-react/navigationaids/SheetNavigationAid.scss +3 -3
  19. package/lib/cjs/appui-react/navigationaids/StandardRotationNavigationAid.scss +3 -3
  20. package/lib/cjs/appui-react/pickers/ViewSelector.d.ts.map +1 -1
  21. package/lib/cjs/appui-react/pickers/ViewSelector.js +3 -1
  22. package/lib/cjs/appui-react/pickers/ViewSelector.js.map +1 -1
  23. package/lib/cjs/appui-react/popup/CardPopup.scss +3 -3
  24. package/lib/cjs/appui-react/selection/HideIsolateEmphasizeManager.d.ts.map +1 -1
  25. package/lib/cjs/appui-react/selection/HideIsolateEmphasizeManager.js +0 -53
  26. package/lib/cjs/appui-react/selection/HideIsolateEmphasizeManager.js.map +1 -1
  27. package/lib/cjs/appui-react/settings/quantityformatting/QuantityFormat.scss +3 -3
  28. package/lib/cjs/appui-react/settings/ui/UiSettingsPage.scss +3 -3
  29. package/lib/cjs/appui-react/statusbar/Separator.scss +3 -3
  30. package/lib/cjs/appui-react/statusfields/SectionsField.scss +3 -3
  31. package/lib/cjs/appui-react/statusfields/SelectionCount.scss +3 -3
  32. package/lib/cjs/appui-react/statusfields/SelectionScope.scss +3 -3
  33. package/lib/cjs/appui-react/statusfields/ViewAttributes.scss +3 -3
  34. package/lib/cjs/appui-react/statusfields/tileloading/TileLoadingIndicator.scss +3 -3
  35. package/lib/cjs/appui-react/statusfields/toolassistance/ToolAssistanceField.scss +3 -3
  36. package/lib/cjs/appui-react/widget-panels/Frontstage.d.ts +3 -1
  37. package/lib/cjs/appui-react/widget-panels/Frontstage.d.ts.map +1 -1
  38. package/lib/cjs/appui-react/widget-panels/Frontstage.js +85 -70
  39. package/lib/cjs/appui-react/widget-panels/Frontstage.js.map +1 -1
  40. package/lib/cjs/appui-react/widget-panels/Frontstage.scss +3 -3
  41. package/lib/cjs/appui-react/widget-panels/Tab.scss +3 -3
  42. package/lib/cjs/appui-react/widget-panels/ToolSettings.d.ts +1 -1
  43. package/lib/cjs/appui-react/widget-panels/ToolSettings.d.ts.map +1 -1
  44. package/lib/cjs/appui-react/widget-panels/ToolSettings.js +22 -29
  45. package/lib/cjs/appui-react/widget-panels/ToolSettings.js.map +1 -1
  46. package/lib/cjs/appui-react/widget-panels/ToolSettings.scss +3 -3
  47. package/lib/cjs/appui-react/widget-panels/Toolbars.scss +3 -3
  48. package/lib/cjs/appui-react/widgets/WidgetDef.d.ts +1 -1
  49. package/lib/cjs/appui-react/widgets/WidgetDef.d.ts.map +1 -1
  50. package/lib/cjs/appui-react/widgets/WidgetDef.js +12 -11
  51. package/lib/cjs/appui-react/widgets/WidgetDef.js.map +1 -1
  52. package/lib/esm/appui-react/UiFramework.d.ts +0 -7
  53. package/lib/esm/appui-react/UiFramework.d.ts.map +1 -1
  54. package/lib/esm/appui-react/UiFramework.js +0 -21
  55. package/lib/esm/appui-react/UiFramework.js.map +1 -1
  56. package/lib/esm/appui-react/_variables.scss +3 -3
  57. package/lib/esm/appui-react/accudraw/AccuDrawFieldContainer.scss +3 -3
  58. package/lib/esm/appui-react/accudraw/AccuDrawInputField.scss +3 -3
  59. package/lib/esm/appui-react/childwindow/InternalChildWindowManager.d.ts.map +1 -1
  60. package/lib/esm/appui-react/childwindow/InternalChildWindowManager.js +1 -2
  61. package/lib/esm/appui-react/childwindow/InternalChildWindowManager.js.map +1 -1
  62. package/lib/esm/appui-react/childwindow/InternalChildWindowManager.scss +3 -3
  63. package/lib/esm/appui-react/configurableui/configurableui.scss +3 -3
  64. package/lib/esm/appui-react/content/DefaultViewOverlay.scss +3 -3
  65. package/lib/esm/appui-react/feedback/ValidationTextbox.scss +3 -3
  66. package/lib/esm/appui-react/frontstage/FrontstageDef.d.ts.map +1 -1
  67. package/lib/esm/appui-react/frontstage/FrontstageDef.js +24 -5
  68. package/lib/esm/appui-react/frontstage/FrontstageDef.js.map +1 -1
  69. package/lib/esm/appui-react/navigationaids/SheetNavigationAid.scss +3 -3
  70. package/lib/esm/appui-react/navigationaids/StandardRotationNavigationAid.scss +3 -3
  71. package/lib/esm/appui-react/pickers/ViewSelector.d.ts.map +1 -1
  72. package/lib/esm/appui-react/pickers/ViewSelector.js +3 -1
  73. package/lib/esm/appui-react/pickers/ViewSelector.js.map +1 -1
  74. package/lib/esm/appui-react/popup/CardPopup.scss +3 -3
  75. package/lib/esm/appui-react/selection/HideIsolateEmphasizeManager.d.ts.map +1 -1
  76. package/lib/esm/appui-react/selection/HideIsolateEmphasizeManager.js +0 -53
  77. package/lib/esm/appui-react/selection/HideIsolateEmphasizeManager.js.map +1 -1
  78. package/lib/esm/appui-react/settings/quantityformatting/QuantityFormat.scss +3 -3
  79. package/lib/esm/appui-react/settings/ui/UiSettingsPage.scss +3 -3
  80. package/lib/esm/appui-react/statusbar/Separator.scss +3 -3
  81. package/lib/esm/appui-react/statusfields/SectionsField.scss +3 -3
  82. package/lib/esm/appui-react/statusfields/SelectionCount.scss +3 -3
  83. package/lib/esm/appui-react/statusfields/SelectionScope.scss +3 -3
  84. package/lib/esm/appui-react/statusfields/ViewAttributes.scss +3 -3
  85. package/lib/esm/appui-react/statusfields/tileloading/TileLoadingIndicator.scss +3 -3
  86. package/lib/esm/appui-react/statusfields/toolassistance/ToolAssistanceField.scss +3 -3
  87. package/lib/esm/appui-react/widget-panels/Frontstage.d.ts +3 -1
  88. package/lib/esm/appui-react/widget-panels/Frontstage.d.ts.map +1 -1
  89. package/lib/esm/appui-react/widget-panels/Frontstage.js +82 -67
  90. package/lib/esm/appui-react/widget-panels/Frontstage.js.map +1 -1
  91. package/lib/esm/appui-react/widget-panels/Frontstage.scss +3 -3
  92. package/lib/esm/appui-react/widget-panels/Tab.scss +3 -3
  93. package/lib/esm/appui-react/widget-panels/ToolSettings.d.ts +1 -1
  94. package/lib/esm/appui-react/widget-panels/ToolSettings.d.ts.map +1 -1
  95. package/lib/esm/appui-react/widget-panels/ToolSettings.js +22 -29
  96. package/lib/esm/appui-react/widget-panels/ToolSettings.js.map +1 -1
  97. package/lib/esm/appui-react/widget-panels/ToolSettings.scss +3 -3
  98. package/lib/esm/appui-react/widget-panels/Toolbars.scss +3 -3
  99. package/lib/esm/appui-react/widgets/WidgetDef.d.ts +1 -1
  100. package/lib/esm/appui-react/widgets/WidgetDef.d.ts.map +1 -1
  101. package/lib/esm/appui-react/widgets/WidgetDef.js +12 -11
  102. package/lib/esm/appui-react/widgets/WidgetDef.js.map +1 -1
  103. package/lib/public/locales/en/UiFramework.json +3 -1
  104. package/package.json +12 -12
@@ -13,7 +13,7 @@ import { unstable_batchedUpdates } from "react-dom";
13
13
  import { assert, Logger, ProcessDetector } from "@itwin/core-bentley";
14
14
  import { Rectangle, Size, UiStateStorageStatus } from "@itwin/core-react";
15
15
  import { ToolbarPopupAutoHideContext } from "@itwin/components-react";
16
- import { addFloatingWidget, addPanelWidget, addTab, addTabToWidget, convertAllPopupWidgetContainersToFloating, createLayoutStore, createNineZoneState, floatingWidgetBringToFront, FloatingWidgets, getTabLocation, getUniqueId, getWidgetPanelSectionId, insertPanelWidget, insertTabToWidget, isFloatingTabLocation, isHorizontalPanelSide, isPanelTabLocation, isPopoutTabLocation, NineZone, NineZoneStateReducer, panelSides, removeTab, removeTabFromWidget, toolSettingsTabId, WidgetPanels, } from "@itwin/appui-layout-react";
16
+ import { addDockedToolSettings, addFloatingWidget, addPanelWidget, addTab, addTabToWidget, addWidgetToolSettings, convertAllPopupWidgetContainersToFloating, createLayoutStore, createNineZoneState, floatingWidgetBringToFront, FloatingWidgets, getTabLocation, getUniqueId, getWidgetPanelSectionId, insertPanelWidget, insertTabToWidget, isFloatingTabLocation, isHorizontalPanelSide, isPanelTabLocation, isPopoutTabLocation, NineZone, NineZoneStateReducer, panelSides, removeTab, removeTabFromWidget, removeToolSettings, WidgetPanels, } from "@itwin/appui-layout-react";
17
17
  import { StagePanelState, toPanelSide } from "../stagepanels/StagePanelDef";
18
18
  import { UiFramework } from "../UiFramework";
19
19
  import { useUiStateStorageHandler } from "../uistate/useUiStateStorage";
@@ -120,14 +120,6 @@ export function useNineZoneDispatch(frontstageDef) {
120
120
  if (action.type === "RESIZE") {
121
121
  InternalFrontstageManager.nineZoneSize = Size.create(action.size);
122
122
  }
123
- // istanbul ignore if
124
- if (action.type === "TOOL_SETTINGS_DRAG_START") {
125
- void UiFramework.postTelemetry("Tool Settings Undocking", "28B04E07-AE73-4533-A0BA-8E2A8DC99ADF");
126
- }
127
- // istanbul ignore if
128
- if (action.type === "TOOL_SETTINGS_DOCK") {
129
- void UiFramework.postTelemetry("Tool Settings Docking to Settings Bar", "BEDE684B-B3DB-4637-B3AF-DC3CBA223F94");
130
- }
131
123
  if (action.type === "WIDGET_TAB_POPOUT") {
132
124
  const tabId = action.id;
133
125
  frontstageDef.popoutWidget(tabId);
@@ -204,6 +196,19 @@ export function useLabels() {
204
196
  popoutActiveTab: UiFramework.translate("widget.tooltips.popoutActiveTab"),
205
197
  }), []);
206
198
  }
199
+ function toTabArgs(widget) {
200
+ const label = getWidgetLabel(widget.label);
201
+ return {
202
+ allowedPanelTargets: widget.allowedPanelTargets?.map((location) => toPanelSide(location)),
203
+ hideWithUiWhenFloating: !!widget.hideWithUiWhenFloating,
204
+ canPopout: widget.canPopout,
205
+ iconSpec: widget.iconSpec,
206
+ isFloatingStateWindowResizable: widget.isFloatingStateWindowResizable,
207
+ label,
208
+ preferredFloatingWidgetSize: widget.defaultFloatingSize,
209
+ preferredPanelWidgetSize: widget.preferredPanelSize,
210
+ };
211
+ }
207
212
  /** @internal */
208
213
  export function addWidgets(state, widgets, side, widgetId) {
209
214
  const visibleWidgets = widgets.filter((w) => w.isVisible && w.defaultState !== WidgetState.Floating);
@@ -211,17 +216,7 @@ export function addWidgets(state, widgets, side, widgetId) {
211
216
  return state;
212
217
  const tabs = new Array();
213
218
  for (const widget of visibleWidgets) {
214
- const label = getWidgetLabel(widget.label);
215
- state = addTab(state, widget.id, {
216
- label,
217
- iconSpec: widget.iconSpec,
218
- preferredPanelWidgetSize: widget.preferredPanelSize,
219
- preferredFloatingWidgetSize: widget.defaultFloatingSize,
220
- canPopout: widget.canPopout,
221
- isFloatingStateWindowResizable: widget.isFloatingStateWindowResizable,
222
- hideWithUiWhenFloating: !!widget.hideWithUiWhenFloating,
223
- allowedPanelTargets: widget.allowedPanelTargets?.map((location) => toPanelSide(location)),
224
- });
219
+ state = addTab(state, widget.id, toTabArgs(widget));
225
220
  tabs.push(widget.id);
226
221
  }
227
222
  const activeWidget = visibleWidgets.find((widget) => widget.isActive);
@@ -238,12 +233,9 @@ export function addWidgets(state, widgets, side, widgetId) {
238
233
  /** @internal */
239
234
  // istanbul ignore next
240
235
  export function appendWidgets(state, widgetDefs, location, section) {
241
- if (widgetDefs.length === 0)
242
- return state;
243
236
  const side = toPanelSide(location);
244
237
  // Add missing widget tabs.
245
238
  for (const widgetDef of widgetDefs) {
246
- const label = getWidgetLabel(widgetDef.label);
247
239
  const saveTab = state.tabs[widgetDef.id];
248
240
  const preferredPanelWidgetSize = saveTab
249
241
  ? saveTab.preferredPanelWidgetSize
@@ -258,15 +250,10 @@ export function appendWidgets(state, widgetDefs, location, section) {
258
250
  !!saveTab.preferredFloatingWidgetSize)
259
251
  : !!widgetDef.defaultFloatingSize;
260
252
  state = addTab(state, widgetDef.id, {
261
- label,
262
- iconSpec: widgetDef.iconSpec,
263
- canPopout: widgetDef.canPopout,
264
- preferredPanelWidgetSize,
253
+ ...toTabArgs(widgetDef),
265
254
  preferredFloatingWidgetSize,
255
+ preferredPanelWidgetSize,
266
256
  userSized,
267
- isFloatingStateWindowResizable: widgetDef.isFloatingStateWindowResizable,
268
- hideWithUiWhenFloating: !!widgetDef.hideWithUiWhenFloating,
269
- allowedPanelTargets: widgetDef.allowedPanelTargets?.map((l) => toPanelSide(l)),
270
257
  });
271
258
  if (widgetDef.isFloatingStateSupported &&
272
259
  widgetDef.defaultState === WidgetState.Floating) {
@@ -364,6 +351,12 @@ export function addMissingWidgets(frontstageDef, initialState) {
364
351
  .widgetDefs, state), StagePanelLocation.Bottom, StagePanelSection.Start);
365
352
  state = appendWidgets(state, determineNewWidgets(frontstageDef.bottomPanel?.getPanelSectionDef(StagePanelSection.End)
366
353
  .widgetDefs, state), StagePanelLocation.Bottom, StagePanelSection.End);
354
+ if (frontstageDef.toolSettings) {
355
+ const newToolSettingsWidgets = determineNewWidgets([frontstageDef.toolSettings], state);
356
+ for (const newToolSettingsWidget of newToolSettingsWidgets) {
357
+ state = addTab(state, newToolSettingsWidget.id, toTabArgs(newToolSettingsWidget));
358
+ }
359
+ }
367
360
  return state;
368
361
  }
369
362
  /** Hide widgets with Hidden defaultState. */
@@ -382,8 +375,8 @@ function hideWidgets(state, frontstageDef) {
382
375
  /** Removes NineZoneState widgets that are missing in frontstageDef.
383
376
  * @internal
384
377
  */
385
- export function removeMissingWidgets(frontstageDef, initialState) {
386
- let state = initialState;
378
+ export function removeMissingWidgets(frontstageDef, state) {
379
+ const toolSettingsTabId = state.toolSettings?.tabId;
387
380
  for (const [, tab] of Object.entries(state.tabs)) {
388
381
  if (tab.id === toolSettingsTabId)
389
382
  continue;
@@ -487,7 +480,8 @@ function getPanelMaxSize(maxSizeSpec, panel, nineZoneSize) {
487
480
  : nineZoneSize.width;
488
481
  return (maxSizeSpec.percentage / 100) * size;
489
482
  }
490
- const stateVersion = 13; // this needs to be bumped when NineZoneState is changed (to recreate the layout).
483
+ /** @internal */
484
+ export const stateVersion = 14; // this needs to be bumped when NineZoneState is changed (to recreate the layout).
491
485
  /** @internal */
492
486
  export function initializeNineZoneState(frontstageDef) {
493
487
  let nineZone = defaultNineZone;
@@ -504,29 +498,26 @@ export function initializeNineZoneState(frontstageDef) {
504
498
  nineZone = initializePanel(nineZone, frontstageDef, StagePanelLocation.Right);
505
499
  nineZone = initializePanel(nineZone, frontstageDef, StagePanelLocation.Top);
506
500
  nineZone = initializePanel(nineZone, frontstageDef, StagePanelLocation.Bottom);
507
- nineZone = produce(nineZone, (stateDraft) => {
508
- for (const [, panel] of Object.entries(stateDraft.panels)) {
509
- const expanded = panel.widgets.find((widgetId) => stateDraft.widgets[widgetId].minimized === false);
510
- const firstWidget = panel.widgets.length > 0
511
- ? stateDraft.widgets[panel.widgets[0]]
512
- : undefined;
501
+ nineZone = produce(nineZone, (draft) => {
502
+ for (const [, panel] of Object.entries(draft.panels)) {
503
+ const expanded = panel.widgets.find((widgetId) => draft.widgets[widgetId].minimized === false);
504
+ const firstWidget = panel.widgets.length > 0 ? draft.widgets[panel.widgets[0]] : undefined;
513
505
  // istanbul ignore next
514
506
  if (!expanded && firstWidget) {
515
507
  firstWidget.minimized = false;
516
508
  }
517
509
  }
518
- stateDraft.panels.left.collapsed = isPanelCollapsed(frontstageDef.leftPanel?.panelState);
519
- stateDraft.panels.right.collapsed = isPanelCollapsed(frontstageDef.rightPanel?.panelState);
520
- stateDraft.panels.top.collapsed = isPanelCollapsed(frontstageDef.topPanel?.panelState);
521
- stateDraft.panels.bottom.collapsed = isPanelCollapsed(frontstageDef.bottomPanel?.panelState);
522
- const toolSettingsWidgetDef = frontstageDef.toolSettings;
523
- if (toolSettingsWidgetDef) {
524
- const toolSettingsTab = stateDraft.tabs[toolSettingsTabId];
525
- toolSettingsTab.preferredPanelWidgetSize =
526
- toolSettingsWidgetDef.preferredPanelSize;
527
- }
510
+ draft.panels.left.collapsed = isPanelCollapsed(frontstageDef.leftPanel?.panelState);
511
+ draft.panels.right.collapsed = isPanelCollapsed(frontstageDef.rightPanel?.panelState);
512
+ draft.panels.top.collapsed = isPanelCollapsed(frontstageDef.topPanel?.panelState);
513
+ draft.panels.bottom.collapsed = isPanelCollapsed(frontstageDef.bottomPanel?.panelState);
528
514
  });
529
515
  nineZone = addMissingWidgets(frontstageDef, nineZone);
516
+ const toolSettingsWidgetDef = frontstageDef.toolSettings;
517
+ if (toolSettingsWidgetDef) {
518
+ const toolSettingsTabId = toolSettingsWidgetDef.id;
519
+ nineZone = addDockedToolSettings(nineZone, toolSettingsTabId);
520
+ }
530
521
  nineZone = hideWidgets(nineZone, frontstageDef);
531
522
  nineZone = processPopoutWidgets(nineZone, frontstageDef);
532
523
  return nineZone;
@@ -539,7 +530,7 @@ export function initializeNineZoneState(frontstageDef) {
539
530
  export function restoreNineZoneState(frontstageDef, saved) {
540
531
  let restored = {
541
532
  ...saved,
542
- tabs: defaultNineZone.tabs,
533
+ tabs: {},
543
534
  };
544
535
  for (const [, tab] of Object.entries(saved.tabs)) {
545
536
  // Re-add the placeholder tab in order to correctly remove it from the state if WidgetDef is not found.
@@ -556,12 +547,9 @@ export function restoreNineZoneState(frontstageDef, saved) {
556
547
  restored = produce(restored, (draft) => {
557
548
  draft.tabs[tab.id] = {
558
549
  ...tab,
559
- label: getWidgetLabel(widgetDef.label),
560
- hideWithUiWhenFloating: widgetDef.hideWithUiWhenFloating,
561
- iconSpec: widgetDef.iconSpec,
562
- canPopout: widgetDef.canPopout,
563
- isFloatingStateWindowResizable: widgetDef.isFloatingStateWindowResizable,
564
- allowedPanelTargets: widgetDef.allowedPanelTargets?.map((location) => toPanelSide(location)),
550
+ ...toTabArgs(widgetDef),
551
+ preferredFloatingWidgetSize: tab.preferredFloatingWidgetSize,
552
+ preferredPanelWidgetSize: tab.preferredPanelWidgetSize,
565
553
  };
566
554
  });
567
555
  }
@@ -618,12 +606,9 @@ export function packNineZoneState(state) {
618
606
  };
619
607
  packed = produce(packed, (draft) => {
620
608
  for (const [, tab] of Object.entries(state.tabs)) {
621
- if (tab.id === toolSettingsTabId)
622
- continue;
623
609
  draft.tabs[tab.id] = {
624
610
  id: tab.id,
625
611
  preferredFloatingWidgetSize: tab.preferredFloatingWidgetSize,
626
- allowedPanelTargets: tab.allowedPanelTargets,
627
612
  userSized: tab.userSized,
628
613
  };
629
614
  }
@@ -721,10 +706,20 @@ export function setWidgetState(state, widgetDef, widgetState) {
721
706
  }
722
707
  else if (widgetState === WidgetState.Open) {
723
708
  const id = widgetDef.id;
709
+ if (widgetDef.isToolSettings) {
710
+ if (!state.toolSettings && !widgetDef.tabLocation) {
711
+ state = addDockedToolSettings(state, id);
712
+ }
713
+ if (state.toolSettings?.type === "docked")
714
+ return state;
715
+ }
724
716
  let location = getTabLocation(state, id);
725
717
  if (!location) {
726
718
  state = addHiddenWidget(state, widgetDef);
727
719
  location = getTabLocation(state, id);
720
+ if (widgetDef.isToolSettings) {
721
+ state = addWidgetToolSettings(state, id);
722
+ }
728
723
  }
729
724
  return produce(state, (draft) => {
730
725
  assert(!!location);
@@ -748,6 +743,9 @@ export function setWidgetState(state, widgetDef, widgetState) {
748
743
  }
749
744
  else if (widgetState === WidgetState.Closed) {
750
745
  const id = widgetDef.id;
746
+ if (widgetDef.isToolSettings && state.toolSettings?.type !== "widget") {
747
+ return state;
748
+ }
751
749
  let location = getTabLocation(state, id);
752
750
  if (!location) {
753
751
  state = addHiddenWidget(state, widgetDef);
@@ -778,11 +776,28 @@ export function setWidgetState(state, widgetDef, widgetState) {
778
776
  state = removeTabFromWidget(state, id);
779
777
  const bounds = widgetDef.tabLocation?.floatingWidget?.bounds;
780
778
  state = addFloatingWidget(state, getUniqueId(), [id], { bounds });
779
+ if (widgetDef.isToolSettings) {
780
+ if (state.toolSettings?.type === "docked") {
781
+ state = removeToolSettings(state);
782
+ }
783
+ if (!state.toolSettings) {
784
+ state = addWidgetToolSettings(state, id);
785
+ }
786
+ }
781
787
  }
782
788
  return state;
783
789
  }
784
790
  /** Stores widget location and hides it in the UI. */
785
791
  function hideWidget(state, widgetDef) {
792
+ const toolSettingsTabId = state.toolSettings?.tabId;
793
+ if (widgetDef.id === toolSettingsTabId) {
794
+ widgetDef.tabLocation = undefined;
795
+ state = produce(state, (draft) => {
796
+ draft.toolSettings = undefined;
797
+ });
798
+ if (state.toolSettings?.type === "docked")
799
+ return state;
800
+ }
786
801
  const location = getTabLocation(state, widgetDef.id);
787
802
  if (!location)
788
803
  return state;
@@ -886,8 +901,8 @@ export function useSavedFrontstageState(frontstageDef) {
886
901
  return;
887
902
  if (isFrontstageStateSettingResult(settingResult)) {
888
903
  const setting = settingResult.setting;
889
- if (setting.version >= version &&
890
- setting.stateVersion >= stateVersion) {
904
+ if (setting.version === version &&
905
+ setting.stateVersion === stateVersion) {
891
906
  const restored = restoreNineZoneState(frontstageDef, setting.nineZone);
892
907
  frontstageDef.savedWidgetDefs = setting.widgets;
893
908
  restoreSavedWidgets(frontstageDef);
@@ -974,14 +989,11 @@ const createListener = (frontstageDef, listener) => {
974
989
  /** @internal */
975
990
  export function useFrontstageManager(frontstageDef, useToolAsToolSettingsLabel) {
976
991
  React.useEffect(() => {
977
- const listener = createListener(frontstageDef, ({ widgetDef, widgetState }) => {
978
- assert(!!frontstageDef.nineZoneState);
992
+ return UiFramework.frontstages.onWidgetStateChangedEvent.addListener(({ widgetDef, widgetState }) => {
993
+ if (!frontstageDef.nineZoneState)
994
+ return;
979
995
  frontstageDef.nineZoneState = setWidgetState(frontstageDef.nineZoneState, widgetDef, widgetState);
980
996
  });
981
- UiFramework.frontstages.onWidgetStateChangedEvent.addListener(listener);
982
- return () => {
983
- UiFramework.frontstages.onWidgetStateChangedEvent.removeListener(listener);
984
- };
985
997
  }, [frontstageDef]);
986
998
  React.useEffect(() => {
987
999
  const listener = createListener(frontstageDef, ({ widgetDef }) => {
@@ -1044,6 +1056,9 @@ export function useFrontstageManager(frontstageDef, useToolAsToolSettingsLabel)
1044
1056
  const label = useToolAsToolSettingsLabel
1045
1057
  ? IModelApp.tools.find(toolId)?.flyover || defaultLabel
1046
1058
  : defaultLabel;
1059
+ const toolSettingsTabId = frontstageDef.nineZoneState.toolSettings?.tabId;
1060
+ if (!toolSettingsTabId)
1061
+ return;
1047
1062
  frontstageDef.nineZoneState = setWidgetLabel(frontstageDef.nineZoneState, toolSettingsTabId, label);
1048
1063
  });
1049
1064
  // Whenever the frontstageDef or the useTool... changes, keep the label up to date.