blueprint
blueprint copied to clipboard
Are panel stacks fixed height?
Environment
- Package version(s): 3.2.0
- Browser and OS versions: Firefox 61, Ubuntu 18.04
Question
In the example, the panel-stack has a height of 300px.
http://blueprintjs.com/docs/#core/components/panel-stack
[data-example-id="PanelStackExample"] .docs-panel-stack-example has explicit width and height styling.
This isn't mentioned in the documentation and when the panel-stack lacks a height then it isn't displayed at all (it has a height of zero.)
Can you provide guidance? Is there a way to use a panel-stack that isn't a fixed height?
@ihsw my goodness, of course it's not fixed height! it's a block element that will fill its parent.
that selector is just for the docs site (hence the very specific data attribute). we must set a height on the docs site otherwise it'll get squished to minimum (due to flex styles in examples; try disabling the height rule).
@giladgray Thank you for that clarification.
I know this is closed, but I'm running into a similar problem with the PanelStack.
TLDR: I think setting PanelStack height explicitly is necessary... or I'm doing it wrong :(
I'm trying to implement the component inside a Dialog so that I can allow users multiple sign-in workflows. At first, I thought that nesting the PanelStack so deep in the DOM tree or my (needlessly complicated) component hierarchy may have introduced some adverse effects.
So, to try and duplicate the issue, I made this CodeSandbox:
Potential fix 1
In trying to find a fix, I thought about @ihsw's comment. Using Chrome (68.0.3440.84) DevTools, I saw that .bp3-panel-stack had a height of 0. If I set the height explicitly...

Potential fix 2
Then, I tried messing with the position of .bp3-panel-stack and .bp3-panel-stack-view.

Theory:
I think there may be an issue with the method BlueprintJS uses to have the PanelStack fill its container. I've used { position: absolute; top: 0; right: 0; bottom: 0; left: 0; } before, but I never really understood why it works.
If this answer is correct and the answer applies to height as well as width, then we need to explicitly set the hight of the parent container aka the PanelStack, don't we? Here's the spec, in case someone can grok it better than I can.
Let me know if there's anything I can do to help out.
PS: CSS is silly.
@jsprow I've tried to use PanelStack for the same purpose -- multi-step dialogs.
I settled on creating a custom PanelHeader component and putting it at the top of my Dialog components, using it simply as a navigational element.
https://github.com/ihsw/sotah-client/blob/master/app/src/components/util/PanelHeader.tsx
PanelStack is nice but I couldn't be bothered to implement it properly. I will eventually but at this point it doesn't work in Dialog elements.
@ihsw @jsprow ah yes seems like setting the height would be necessary given the CSS. at some point i'll see if it can be done in a more reliable way.
Thanks for taking a look, guys!
@ihsw I tried using an implementation similar to what you were doing (nice job, BTW), but it ended up being too difficult for me to shoehorn into the rest of my nonsense. I opted to just toggle some children in and out, instead.
@giladgray Not sure which direction I'd go... maybe just min-height: 80px;? That way it'd fit the header and a medium-sized button with 10px of padding.
Any updates on this?
@giladgray should this be re-opened? It seems to be an on-going issue -- using a PanelStack component within a Dialog doesn't seem to work as intended.
yeah sure so we don't forget.
Hello, thanks for an excellent framework. I am running into this issue at the moment. I tried a bunch of CSS settings but could not get the height issue fixed. Here is my current workaround in React for a variable height panel stack.
/**
* Renders a panel stack and re-calculates its height on each render
*/
function VariableHeightPanelStack(props: { initialPanel: BP3.IPanel }) {
const ref = useRef()
const [height, setHeight] = useState(0)
useLayoutEffect(calcualteHeight)
return (
<div ref={ref} className='transition-200ms' style={{ height: `${height}px` }}>
<BP3.PanelStack className='h-100' {...props} onOpen={calcualteHeight} onClose={calcualteHeight} />
</div>
)
// Called by PanelStack hooks and also on each render
function calcualteHeight(panelAddedOrRemoved?: any) {
if (!ref.current) return
const childrenSelector = '.bp3-panel-stack-view:not(.bp3-panel-stack-exit) > *'
const contentHeight = sumChildrenHeights(ref.current, childrenSelector) + 1
// Conditionally setHeight to avoid infinite loop
const triggeredByCallback = Boolean(panelAddedOrRemoved)
const heightChanged = height !== contentHeight
if (triggeredByCallback || heightChanged) setHeight(contentHeight)
}
}
function sumChildrenHeights(element: any, selector: string) {
const nodeList = element.querySelectorAll(selector)
const addHeights = (sum: number, el: any) => sum + (!el ? 0 : el.clientHeight)
return Array.prototype.slice.call(nodeList).reduce(addHeights, 0)
}
Add these two CSS classes
.h-100 { height: 100% }
.transition-200ms { transition: 200ms }
Usage:
<VariableHeightPanelStack initialPanel={{ title: 'Your title', component: YourComponent }} />
Regards; once again thank you.
Edit: formatting
@ihsw use a specific pixel height like height: 400px instead of 100%
@a-s-o Your suggestion is currently not usable with latest releases of React. Hooks are only available in the alpha versions of React 16.7+.
I know this is an old one but im still running into this. Here's a minimal example: https://codesandbox.io/embed/async-darkness-1wpjf
The gist of https://github.com/palantir/blueprint/issues/2777#issuecomment-440832130 is that PanelView is absolutely positioned to enable a transition where both panels are temporarily visible. If you wanted PanelStack to assume the current panel’s height, you would have to calculate and adapt to PanelView’s height. Even then, one has to think about the height-transition of the stack itself.
Hi, bumping this issue as I came across the other day. I spent hours trying to find the cause since the PanelStack2 wasn't showing properly. I only accidentally fixed it by setting an explicit height property.
I never saw any mention in the documentation about this issue or the need to set an explicit height. It would save people lots of time if this was indicated in the docs.