Skip to content

Commit 8a9e057

Browse files
committed
Correctly apply row flex mode to Card header objects
1 parent f02cf2d commit 8a9e057

1 file changed

Lines changed: 79 additions & 0 deletions

File tree

panel/models/card.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import type {StyleSheetLike} from "@bokehjs/core/dom"
22
import * as DOM from "@bokehjs/core/dom"
3+
import {Container} from "@bokehjs/core/layout/grid"
34
import type * as p from "@bokehjs/core/properties"
5+
import {GridAlignmentLayout} from "@bokehjs/models/layouts/alignments"
6+
import {LayoutDOMView} from "@bokehjs/models/layouts/layout_dom"
47

58
import {Column, ColumnView} from "./column"
69

@@ -120,6 +123,82 @@ export class CardView extends ColumnView {
120123
this.invalidate_layout()
121124
}
122125

126+
override _update_layout(): void {
127+
super._update_layout()
128+
129+
this.style.append(":host", {
130+
flex_direction: this._direction,
131+
gap: DOM.px(this.model.spacing),
132+
})
133+
134+
const layoutable = new Container<LayoutDOMView>()
135+
let r0 = 0
136+
let c0 = 0
137+
138+
for (let i = 0; i < this.child_views.length; i++) {
139+
const view = this.child_views[i];
140+
if (!(view instanceof LayoutDOMView)) {
141+
continue
142+
}
143+
144+
const is_row = i == 0
145+
const sizing = view.box_sizing()
146+
const flex = (() => {
147+
const policy = is_row ? sizing.width_policy : sizing.height_policy
148+
const size = is_row ? sizing.width : sizing.height
149+
const basis = size != null ? DOM.px(size) : "auto"
150+
switch (policy) {
151+
case "auto":
152+
case "fixed": return `0 0 ${basis}`
153+
case "fit": return "1 1 auto"
154+
case "min": return "0 1 auto"
155+
case "max": return "1 0 0px"
156+
}
157+
})()
158+
159+
const align_self = (() => {
160+
const policy = is_row ? sizing.height_policy : sizing.width_policy
161+
switch (policy) {
162+
case "auto":
163+
case "fixed":
164+
case "fit":
165+
case "min": return is_row ? sizing.valign : sizing.halign
166+
case "max": return "stretch"
167+
}
168+
})()
169+
170+
view.parent_style.append(":host", {flex, align_self})
171+
172+
// undo `width/height: 100%` and let `align-self: stretch` do the work
173+
if (is_row) {
174+
if (sizing.height_policy == "max") {
175+
view.parent_style.append(":host", {height: "auto"})
176+
}
177+
} else {
178+
if (sizing.width_policy == "max") {
179+
view.parent_style.append(":host", {width: "auto"})
180+
}
181+
}
182+
183+
if (view.layout != null) {
184+
layoutable.add({r0, c0, r1: r0 + 1, c1: c0 + 1}, view)
185+
186+
if (is_row) {
187+
c0 += 1
188+
} else {
189+
r0 += 1
190+
}
191+
}
192+
}
193+
194+
if (layoutable.size != 0) {
195+
this.layout = new GridAlignmentLayout(layoutable)
196+
this.layout.set_sizing()
197+
} else {
198+
delete this.layout
199+
}
200+
}
201+
123202
_toggle_button(e: MouseEvent): void {
124203
for (const path of e.composedPath()) {
125204
if (path instanceof HTMLInputElement) {

0 commit comments

Comments
 (0)