Skip to content

Commit

Permalink
Resize Popout to fit content on popout (#557)
Browse files Browse the repository at this point in the history
* Resize popout widgets to fit content

* Changelogs

* Move size calculation to internal method

* Update ui/appui-react/src/appui-react/childwindow/InternalChildWindowManager.tsx

Co-authored-by: Raphaël LEMIEUX <[email protected]>

* Resize only takes effect on intial popout

* extract-api

* Rush audit fixes

* Extract Api

* Revert "Rush audit fixes"

This reverts commit 8719f3e.

* Move size calculation further into nine zone state

* Update FrontstageDef.tsx

* Add test coverage

* extract-api

* Rush change

* Delete common/changes/@itwin/appui-layout-react/joeh-resizePopout_2023-10-24-19-16.json

* Delete common/changes/@itwin/appui-react/joeh-resizePopout_2023-10-24-19-16.json

* Update NextVersion.md

* Change playwright test

* Uneeded test changes

* Set min width for error boundary so that it appears in content renderer

* Check size of popout when fitting to container in test

* Delete common/changes/@itwin/appui-layout-react/joeh-resizePopout_2023-10-30-15-36.json

* Delete common/changes/@itwin/appui-react/joeh-resizePopout_2023-10-30-15-36.json

* Remove popout container and popout to floating widget bounds

* Refactor changelogs

* When preferredFloatingWidgetSize not set, will popout to content container size

* Update ui/appui-layout-react/src/appui-layout-react/state/NineZoneStateReducer.ts

Co-authored-by: Raphaël LEMIEUX <[email protected]>

* Update joeh-resizePopout_2023-11-02-18-19.json

* Update NextVersion.md

* Change inital size of popout in test

* Update joeh-resizePopout_2023-11-02-18-19.json

* Update joeh-resizePopout_2023-11-02-18-19.json

* Update NextVersion.md

* Update NextVersion.md

* Updated screenshot for failing test

* Fix broken screenshot

---------

Co-authored-by: Raphaël LEMIEUX <[email protected]>
  • Loading branch information
joehenry9498 and raplemie authored Nov 6, 2023
1 parent d1b1293 commit e65756f
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/appui-layout-react",
"comment": "",
"type": "none"
}
],
"packageName": "@itwin/appui-layout-react"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/appui-react",
"comment": "Popout widgets will now popout to preferredFloatingWidgetSize. Will popout to container size if preferredFloatingWidgetSize is not set",
"type": "none"
}
],
"packageName": "@itwin/appui-react"
}
1 change: 1 addition & 0 deletions docs/changehistory/NextVersion.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Table of contents:
### Changes

- `AppNotificationManager` no longer requires `StatusBar` to be rendered in the active frontstage to show messages.
- Popout widgets will now popout to `preferredFloatingWidgetSize`. Will popout to container size if `preferredFloatingWidgetSize` is not set.

### Fixes

Expand Down
4 changes: 2 additions & 2 deletions full-stack-tests/ui/tests/popout-widget.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ test.describe("popout widget", () => {
await expect(popoutPage).toHaveTitle(/View Attributes/);

expect(popoutPage.viewportSize()).toEqual({
height: 800,
width: 600,
height: 270,
width: 218,
});

// Update widget size and close the popout.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -530,9 +530,31 @@ export function NineZoneStateReducer(
if (location && isPopoutTabLocation(location)) return state;

const savedTab = state.savedTabs.byId[id];

const tab = state.tabs[id];

let contentHeight = 800;
let contentWidth = 600;

if (tab.preferredFloatingWidgetSize) {
contentWidth = tab.preferredFloatingWidgetSize.width;
contentHeight = tab.preferredFloatingWidgetSize.height;
} else {
const popoutContentContainer = document.getElementById(
`content-container:${id}`
);
if (popoutContentContainer !== null) {
contentWidth = popoutContentContainer.offsetWidth + 20;
contentHeight = popoutContentContainer.offsetHeight + 20;
}
}

let preferredBounds = savedTab?.popoutBounds
? Rectangle.create(savedTab.popoutBounds)
: Rectangle.createFromSize({ height: 800, width: 600 });
: Rectangle.createFromSize({
height: contentHeight,
width: contentWidth,
});
if (size) preferredBounds = preferredBounds.setSize(size);
if (position) preferredBounds = preferredBounds.setPosition(position);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,14 @@ export function WidgetContentRenderer(props: WidgetContentRendererProps) {
};
}, [renderTo, widgetContentManager, props.tabId]);
return ReactDOM.createPortal(
<TabIdContext.Provider value={props.tabId}>
{props.children}
</TabIdContext.Provider>,
<div
style={{ height: "100%", width: "100%" }}
id={`content-container:${props.tabId}`}
>
<TabIdContext.Provider value={props.tabId}>
{props.children}
</TabIdContext.Provider>
</div>,
container.current
);
}
Expand Down
47 changes: 47 additions & 0 deletions ui/appui-layout-react/src/test/state/NineZoneStateReducer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { addTabs } from "../Utils";
import { createDraggedTabState } from "../../appui-layout-react/state/internal/TabStateHelpers";
import { updatePanelState } from "../../appui-layout-react/state/internal/PanelStateHelpers";
import { assert } from "@itwin/core-bentley";
import { stub } from "sinon";

describe("NineZoneStateReducer", () => {
it("should not update for unhandled action", () => {
Expand Down Expand Up @@ -1619,6 +1620,52 @@ describe("NineZoneStateReducer", () => {
widgetIndex: 0,
});
});

it("should popout a tab and fit to preferredFloatingWidgetSize if bounds are not set", () => {
let state = createNineZoneState();
state = addTab(state, "t1", {
preferredFloatingWidgetSize: { width: 50, height: 50 },
});
state = addPanelWidget(state, "left", "w1", ["t1"]);

const newState = NineZoneStateReducer(state, {
type: "WIDGET_TAB_POPOUT",
id: "t1",
});
newState.popoutWidgets.allIds.should.length(1);
const popoutWidgetId = newState.popoutWidgets.allIds[0];
newState.popoutWidgets.byId[popoutWidgetId].bounds.should.eql({
left: 0,
top: 0,
bottom: 50,
right: 50,
});
});

it("should popout a tab and fit to content container if preferredFloatingWidgetSize is not set", () => {
let state = createNineZoneState();

const blankHTML = document.createElement("div");

stub(document, "getElementById").returns(blankHTML);
state = addTab(state, "t1");
state = addPanelWidget(state, "left", "w1", ["t1"]);

const newState = NineZoneStateReducer(state, {
type: "WIDGET_TAB_POPOUT",
id: "t1",
});

newState.popoutWidgets.allIds.should.length(1);
const popoutWidgetId = newState.popoutWidgets.allIds[0];

newState.popoutWidgets.byId[popoutWidgetId].bounds.should.eql({
left: 0,
top: 0,
bottom: 20,
right: 20,
});
});
});

describe("WIDGET_TAB_HIDE", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface PopoutWidgetProps {
widgetDef: WidgetDef;
}

/** Component used to wrap a widget for use is a child window.
/** Component used to wrap a widget for use in a child window.
* @internal
*/
export function PopoutWidget({
Expand Down

0 comments on commit e65756f

Please sign in to comment.