@jimka/typescript-ui 0.6.0 → 0.7.0
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.
- package/dist/lib/{AbstractInput-sRNPzWel.js → AbstractInput-W2PLJV5_.js} +2 -2
- package/dist/lib/{AbstractInput-sRNPzWel.js.map → AbstractInput-W2PLJV5_.js.map} +1 -1
- package/dist/lib/{Anchor-CwRhdP2J.js → Anchor-iZhsvMlT.js} +2 -2
- package/dist/lib/{Anchor-CwRhdP2J.js.map → Anchor-iZhsvMlT.js.map} +1 -1
- package/dist/lib/AnimatedDropdown-D0RhVgv3.js +2 -0
- package/dist/lib/AnimatedDropdown-D0RhVgv3.js.map +1 -0
- package/dist/lib/Border-6GsTNV-2.js +2 -0
- package/dist/lib/Border-6GsTNV-2.js.map +1 -0
- package/dist/lib/Button-CnFAiQuV.js +2 -0
- package/dist/lib/Button-CnFAiQuV.js.map +1 -0
- package/dist/lib/{Card-QYo27r5b.js → Card-C20k2YHU.js} +2 -2
- package/dist/lib/{Card-QYo27r5b.js.map → Card-C20k2YHU.js.map} +1 -1
- package/dist/lib/Checkbox-CM1z8keM.js +2 -0
- package/dist/lib/Checkbox-CM1z8keM.js.map +1 -0
- package/dist/lib/{CheckboxMenuRow-CesLhSnp.js → CheckboxMenuRow-C1h4LPHR.js} +2 -2
- package/dist/lib/{CheckboxMenuRow-CesLhSnp.js.map → CheckboxMenuRow-C1h4LPHR.js.map} +1 -1
- package/dist/lib/{CodeEditor-N1FQodcF.js → CodeEditor-CTL2WjF8.js} +2 -2
- package/dist/lib/{CodeEditor-N1FQodcF.js.map → CodeEditor-CTL2WjF8.js.map} +1 -1
- package/dist/lib/ComboBox-PZ5YPL0X.js +2 -0
- package/dist/lib/ComboBox-PZ5YPL0X.js.map +1 -0
- package/dist/lib/Component-D99-15Zt.js +2 -0
- package/dist/lib/Component-D99-15Zt.js.map +1 -0
- package/dist/lib/Container-FWRjgF6T.js +2 -0
- package/dist/lib/{Container-abY5Ww3W.js.map → Container-FWRjgF6T.js.map} +1 -1
- package/dist/lib/DOM-Cjh7_7TF.js +2 -0
- package/dist/lib/DOM-Cjh7_7TF.js.map +1 -0
- package/dist/lib/Dialog-DN78RaVH.js +2 -0
- package/dist/lib/Dialog-DN78RaVH.js.map +1 -0
- package/dist/lib/{FieldDecorator-BlYMfZ9L.js → FieldDecorator-DyPX8CFh.js} +2 -2
- package/dist/lib/{FieldDecorator-BlYMfZ9L.js.map → FieldDecorator-DyPX8CFh.js.map} +1 -1
- package/dist/lib/{Fit-BhlB-HAo.js → Fit-CaPMj7Up.js} +2 -2
- package/dist/lib/{Fit-BhlB-HAo.js.map → Fit-CaPMj7Up.js.map} +1 -1
- package/dist/lib/{FloatingPanel-DkJXsZ2D.js → FloatingPanel-Dsy_vJxi.js} +2 -2
- package/dist/lib/{FloatingPanel-DkJXsZ2D.js.map → FloatingPanel-Dsy_vJxi.js.map} +1 -1
- package/dist/lib/Glyph-DiEpD3gy.js +2 -0
- package/dist/lib/Glyph-DiEpD3gy.js.map +1 -0
- package/dist/lib/{Grid-Daiz7F5d.js → Grid-ft_UUpj8.js} +2 -2
- package/dist/lib/{Grid-Daiz7F5d.js.map → Grid-ft_UUpj8.js.map} +1 -1
- package/dist/lib/{GridConstraints-C58LuTqM.js → GridConstraints-CvZ0Nzaw.js} +2 -2
- package/dist/lib/{GridConstraints-C58LuTqM.js.map → GridConstraints-CvZ0Nzaw.js.map} +1 -1
- package/dist/lib/{Header-Dql3Zxc6.js → Header-Osm3IjDw.js} +2 -2
- package/dist/lib/{Header-Dql3Zxc6.js.map → Header-Osm3IjDw.js.map} +1 -1
- package/dist/lib/{IconText-PUjhTLlp.js → IconText-BBaYJ2Fx.js} +2 -2
- package/dist/lib/{IconText-PUjhTLlp.js.map → IconText-BBaYJ2Fx.js.map} +1 -1
- package/dist/lib/{LayoutSerialization-CMxunLfV.js → LayoutSerialization-BC64__O7.js} +2 -2
- package/dist/lib/{LayoutSerialization-CMxunLfV.js.map → LayoutSerialization-BC64__O7.js.map} +1 -1
- package/dist/lib/List-CQbZK_pT.js +2 -0
- package/dist/lib/List-CQbZK_pT.js.map +1 -0
- package/dist/lib/{Menu-Q0bpXXze.js → Menu-CwHluLGT.js} +2 -2
- package/dist/lib/{Menu-Q0bpXXze.js.map → Menu-CwHluLGT.js.map} +1 -1
- package/dist/lib/{MenuButton-DCXi0tsP.js → MenuButton-BqCT-1yv.js} +2 -2
- package/dist/lib/{MenuButton-DCXi0tsP.js.map → MenuButton-BqCT-1yv.js.map} +1 -1
- package/dist/lib/{OverlayFade-3pof2AJH.js → OverlayFade-CuEXgimf.js} +2 -2
- package/dist/lib/{OverlayFade-3pof2AJH.js.map → OverlayFade-CuEXgimf.js.map} +1 -1
- package/dist/lib/{Panel-Cy1pdlWO.js → Panel-CtViePqY.js} +2 -2
- package/dist/lib/{Panel-Cy1pdlWO.js.map → Panel-CtViePqY.js.map} +1 -1
- package/dist/lib/{Position-BwtxouxK.js → Position-BIEU1Eze.js} +2 -2
- package/dist/lib/Position-BIEU1Eze.js.map +1 -0
- package/dist/lib/{ProgressSpinner-DK8xEQ9y.js → ProgressSpinner-BuBvC1FY.js} +2 -2
- package/dist/lib/{ProgressSpinner-DK8xEQ9y.js.map → ProgressSpinner-BuBvC1FY.js.map} +1 -1
- package/dist/lib/RadioButton-Df5J-H6m.js +2 -0
- package/dist/lib/RadioButton-Df5J-H6m.js.map +1 -0
- package/dist/lib/RadioMenuRow-Cfv0x6Qj.js +2 -0
- package/dist/lib/RadioMenuRow-Cfv0x6Qj.js.map +1 -0
- package/dist/lib/{RovingTabIndex-pHEv5oLD.js → RovingTabIndex--w28AnXc.js} +2 -2
- package/dist/lib/{RovingTabIndex-pHEv5oLD.js.map → RovingTabIndex--w28AnXc.js.map} +1 -1
- package/dist/lib/Scrollbar-DcnueNJd.js +2 -0
- package/dist/lib/Scrollbar-DcnueNJd.js.map +1 -0
- package/dist/lib/SelectableText-DZNxjKXR.js +2 -0
- package/dist/lib/SelectableText-DZNxjKXR.js.map +1 -0
- package/dist/lib/{Slider-CTbwR6HR.js → Slider-DNfd8Lxz.js} +2 -2
- package/dist/lib/{Slider-CTbwR6HR.js.map → Slider-DNfd8Lxz.js.map} +1 -1
- package/dist/lib/{Spacer-srdN2d2b.js → Spacer-BznfGbwG.js} +2 -2
- package/dist/lib/{Spacer-srdN2d2b.js.map → Spacer-BznfGbwG.js.map} +1 -1
- package/dist/lib/TabButton-CAACsMov.js +2 -0
- package/dist/lib/TabButton-CAACsMov.js.map +1 -0
- package/dist/lib/{TabCloseButton-CY7BGitY.js → TabCloseButton-CCiqsX3y.js} +2 -2
- package/dist/lib/{TabCloseButton-CY7BGitY.js.map → TabCloseButton-CCiqsX3y.js.map} +1 -1
- package/dist/lib/Text-O-FWa5Cy.js +2 -0
- package/dist/lib/Text-O-FWa5Cy.js.map +1 -0
- package/dist/lib/{Tooltip-CUOJOqQi.js → Tooltip-CyICVu15.js} +2 -2
- package/dist/lib/Tooltip-CyICVu15.js.map +1 -0
- package/dist/lib/{Tree-C64JNPWJ.js → Tree-CSEguhlk.js} +2 -2
- package/dist/lib/{Tree-C64JNPWJ.js.map → Tree-CSEguhlk.js.map} +1 -1
- package/dist/lib/{VBox-DfJPWXqc.js → VBox-DVe4UXwX.js} +2 -2
- package/dist/lib/{VBox-DfJPWXqc.js.map → VBox-DVe4UXwX.js.map} +1 -1
- package/dist/lib/{VirtualScroller-DTIn19o1.js → VirtualScroller-ggPTCQb0.js} +2 -2
- package/dist/lib/{VirtualScroller-DTIn19o1.js.map → VirtualScroller-ggPTCQb0.js.map} +1 -1
- package/dist/lib/component/button.es.js +1 -1
- package/dist/lib/component/chart.es.js +1 -1
- package/dist/lib/component/chart.es.js.map +1 -1
- package/dist/lib/component/container.es.js +1 -1
- package/dist/lib/component/diagram.es.js +1 -1
- package/dist/lib/component/display.es.js +1 -1
- package/dist/lib/component/display.es.js.map +1 -1
- package/dist/lib/component/editor.es.js +2 -2
- package/dist/lib/component/editor.es.js.map +1 -1
- package/dist/lib/component/input.es.js +1 -1
- package/dist/lib/component/input.es.js.map +1 -1
- package/dist/lib/component/list.es.js +1 -1
- package/dist/lib/component/menubar.es.js +1 -1
- package/dist/lib/component/table.es.js +6 -6
- package/dist/lib/component/table.es.js.map +1 -1
- package/dist/lib/component/tree.es.js +1 -1
- package/dist/lib/core.es.js +1 -1
- package/dist/lib/core.es.js.map +1 -1
- package/dist/lib/glyphs/solid/index.es.js +1 -1
- package/dist/lib/layout.es.js +1 -1
- package/dist/lib/overlay.es.js +1 -1
- package/dist/lib/overlay.es.js.map +1 -1
- package/dist/lib/primitive.es.js +1 -1
- package/dist/lib/router.es.js +1 -1
- package/dist/lib/{selectionsEqual-gMG7gCVI.js → selectionsEqual-C7MrKMQr.js} +2 -2
- package/dist/lib/{selectionsEqual-gMG7gCVI.js.map → selectionsEqual-C7MrKMQr.js.map} +1 -1
- package/dist/lib/types/component/button/Button.d.ts +9 -0
- package/dist/lib/types/component/button/TabButton.d.ts +5 -0
- package/dist/lib/types/component/button/ToggleButton.d.ts +3 -0
- package/dist/lib/types/component/chart/AbstractChart.d.ts +2 -0
- package/dist/lib/types/component/display/Markdown.d.ts +2 -1
- package/dist/lib/types/component/input/AbstractCalendarDropdown.d.ts +2 -0
- package/dist/lib/types/component/input/AbstractPickerField.d.ts +2 -0
- package/dist/lib/types/component/input/AutoCompleteDropdown.d.ts +2 -0
- package/dist/lib/types/component/input/ComboBox.d.ts +3 -1
- package/dist/lib/types/component/input/Link.d.ts +2 -0
- package/dist/lib/types/component/input/PasswordField.d.ts +2 -0
- package/dist/lib/types/component/input/PickerInput.d.ts +2 -0
- package/dist/lib/types/component/input/SelectableText.d.ts +11 -0
- package/dist/lib/types/component/input/SpinButton.d.ts +2 -0
- package/dist/lib/types/component/input/Text.d.ts +16 -2
- package/dist/lib/types/component/input/TextArea.d.ts +2 -0
- package/dist/lib/types/component/input/TextField.d.ts +2 -0
- package/dist/lib/types/component/input/TextInput.d.ts +2 -0
- package/dist/lib/types/component/input/TimePickerDropdown.d.ts +3 -1
- package/dist/lib/types/component/input/UsernameField.d.ts +2 -0
- package/dist/lib/types/component/input/index.d.ts +2 -0
- package/dist/lib/types/component/list/AbstractSelectableList.d.ts +4 -2
- package/dist/lib/types/component/table/Body.d.ts +40 -14
- package/dist/lib/types/component/table/Header.d.ts +1 -1
- package/dist/lib/types/component/table/Row.d.ts +20 -2
- package/dist/lib/types/component/table/Table.d.ts +2 -0
- package/dist/lib/types/component/table/TableExporter.d.ts +3 -0
- package/dist/lib/types/component/table/TablePanel.d.ts +1 -0
- package/dist/lib/types/component/table/TreeTablePanel.d.ts +1 -0
- package/dist/lib/types/component/table/cell/Cell.d.ts +7 -2
- package/dist/lib/types/component/table/cell/Default.d.ts +1 -1
- package/dist/lib/types/component/table/cell/Header.d.ts +3 -0
- package/dist/lib/types/component/table/cell/ResizeHandle.d.ts +1 -1
- package/dist/lib/types/component/table/cell/renderer/CellRenderer.d.ts +2 -2
- package/dist/lib/types/component/table/cell/renderer/String.d.ts +3 -1
- package/dist/lib/types/component/table/index.d.ts +1 -1
- package/dist/lib/types/core/AnimatedDropdown.d.ts +2 -0
- package/dist/lib/types/core/ClassStyleRules.d.ts +46 -3
- package/dist/lib/types/core/Component.d.ts +30 -2
- package/dist/lib/types/core/DOM.d.ts +5 -1
- package/dist/lib/types/core/LayerManager.d.ts +1 -0
- package/dist/lib/types/core/StyleTarget.d.ts +2 -0
- package/dist/lib/types/core/Theme.d.ts +1 -0
- package/dist/lib/types/core/Util.d.ts +4 -0
- package/dist/lib/types/core/index.d.ts +1 -1
- package/dist/lib/types/layout/Table.d.ts +2 -0
- package/dist/lib/types/overlay/AbstractWindow.d.ts +3 -0
- package/dist/lib/types/overlay/PopupPanel.d.ts +2 -0
- package/dist/lib/validation.es.js +1 -1
- package/package.json +1 -1
- package/dist/lib/AnimatedDropdown-H3Rh-YMZ.js +0 -2
- package/dist/lib/AnimatedDropdown-H3Rh-YMZ.js.map +0 -1
- package/dist/lib/Border-0DJFDiij.js +0 -2
- package/dist/lib/Border-0DJFDiij.js.map +0 -1
- package/dist/lib/Button-MpMIYBYJ.js +0 -2
- package/dist/lib/Button-MpMIYBYJ.js.map +0 -1
- package/dist/lib/Checkbox-D0JYK-wc.js +0 -2
- package/dist/lib/Checkbox-D0JYK-wc.js.map +0 -1
- package/dist/lib/ComboBox-Dx8Tk9yg.js +0 -2
- package/dist/lib/ComboBox-Dx8Tk9yg.js.map +0 -1
- package/dist/lib/Component-B0ShfPVi.js +0 -2
- package/dist/lib/Component-B0ShfPVi.js.map +0 -1
- package/dist/lib/Container-abY5Ww3W.js +0 -2
- package/dist/lib/DOM-C-Edb3tA.js +0 -2
- package/dist/lib/DOM-C-Edb3tA.js.map +0 -1
- package/dist/lib/Dialog-cbA9V17e.js +0 -2
- package/dist/lib/Dialog-cbA9V17e.js.map +0 -1
- package/dist/lib/Glyph-_VeBacS2.js +0 -2
- package/dist/lib/Glyph-_VeBacS2.js.map +0 -1
- package/dist/lib/List-nx8220Fi.js +0 -2
- package/dist/lib/List-nx8220Fi.js.map +0 -1
- package/dist/lib/Position-BwtxouxK.js.map +0 -1
- package/dist/lib/RadioButton-BEwpqg1k.js +0 -2
- package/dist/lib/RadioButton-BEwpqg1k.js.map +0 -1
- package/dist/lib/RadioMenuRow-DP5qPyFR.js +0 -2
- package/dist/lib/RadioMenuRow-DP5qPyFR.js.map +0 -1
- package/dist/lib/Scrollbar-t8fFrUVQ.js +0 -2
- package/dist/lib/Scrollbar-t8fFrUVQ.js.map +0 -1
- package/dist/lib/TabButton-DLoMQzky.js +0 -2
- package/dist/lib/TabButton-DLoMQzky.js.map +0 -1
- package/dist/lib/Text-CMKnK9uB.js +0 -2
- package/dist/lib/Text-CMKnK9uB.js.map +0 -1
- package/dist/lib/Tooltip-CUOJOqQi.js.map +0 -1
- package/dist/lib/types/component/table/CellGeometry.d.ts +0 -6
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as e,o as t}from"./Position-BwtxouxK.js";import{f as n,h as r,m as i,p as a}from"./Component-B0ShfPVi.js";var BoxLayout=class extends n{_spacing=5;_itemAlign=`baseline`;_mode=`preferred`;_overflowSizing=`preferred`;_justify=`start`;constructor(e){super(),e&&this.applyOptions(e)}applyOptions(e){super.applyOptions(e),e.mode!==void 0&&this.setMode(e.mode),e.spacing!==void 0&&this.setComponentSpacing(e.spacing),e.stretching!==void 0&&this.setStretching(e.stretching),e.itemAlign!==void 0&&this.setItemAlign(e.itemAlign),e.overflowSizing!==void 0&&this.setOverflowSizing(e.overflowSizing),e.justify!==void 0&&this.setJustify(e.justify)}getComponentSpacing(){return this._spacing||0}setComponentSpacing(e){return this._spacing=e||0,this}isStretching(){return this._itemAlign===`stretch`}setStretching(e){return this.setItemAlign(e?`stretch`:`baseline`)}getItemAlign(){return this._itemAlign}setItemAlign(e){return this._itemAlign=e,this}getMode(){return this._mode}setMode(e){return this._mode=e,this}getOverflowSizing(){return this._overflowSizing}setOverflowSizing(e){return this._overflowSizing=e,this}getJustify(){return this._justify}setJustify(e){return this._justify=e,this}aggregateMaxSize(n){let r=this.getContainer();if(!r)return null;let i=r.getPerimeterSize(),a=r.getLaidOutComponents(),o=n?i.left+i.right:i.top+i.bottom,s=n?i.top+i.bottom:i.left+i.right,c=o,l=0,u=!1,d=!1,f=0;for(let e of a){let r=e.getMaxSize();if(!r){u=!0,d=!0;continue}let i=n?r.width:r.height,a=n?r.height:r.width;t(i)?u=!0:this._mode===`equal`?f=Math.max(f,i):c+=i,t(a)?d=!0:l=Math.max(l,a)}this._mode===`equal`?c+=a.length*f+this._spacing*Math.max(0,a.length-1):c+=this._spacing*Math.max(0,a.length-1),l+=s;let p=u?e:c,m=d?e:l;return{width:n?p:m,height:n?m:p}}computeShrink(e,t,n,r){if(e<=n||r)return{remaining:Math.max(0,n-e),shrinkRatio:0};let i=e-n,a=e-t;return{remaining:0,shrinkRatio:a>0?Math.min(1,i/a):1}}justifyOffsets(e,t,n){let r=Math.max(0,t-e);return r===0||this._justify===`start`?{lead:0,gap:0}:this._justify===`center`?{lead:r/2,gap:0}:this._justify===`end`?{lead:r,gap:0}:this._justify===`between`?{lead:0,gap:n>1?r/(n-1):0}:{lead:n>0?r/(2*n):0,gap:n>0?r/n:0}}crossItemOffset(e,t){return this._itemAlign===`center`?Math.max(0,(t-e)/2):this._itemAlign===`end`?Math.max(0,t-e):0}crossPlacement(e,t,n,r,a){let o=this.getLayoutConstraints(e),s=o?.fill??null,c=o?.anchor??null;if(a?s===i.VERTICAL||s===i.BOTH:s===i.HORIZONTAL||s===i.BOTH)return{offset:t,extent:n};let l=this.crossAnchorEdge(c,a);if(l===null)return null;let u=Math.min(r,n);return{offset:l===`lead`?t:t+(n-u),extent:u}}crossAnchorEdge(e,t){return e===null?null:t?e===a.NORTH||e===a.NORTHWEST||e===a.NORTHEAST?`lead`:e===a.SOUTH||e===a.SOUTHWEST||e===a.SOUTHEAST?`trail`:null:e===a.WEST||e===a.NORTHWEST||e===a.SOUTHWEST?`lead`:e===a.EAST||e===a.NORTHEAST||e===a.SOUTHEAST?`trail`:null}},HBox=class extends BoxLayout{_defaultComponentWidth=100;getContentBaseline(){if(this._itemAlign!==`baseline`)return null;let e=this.getContainer();if(!e)return null;let t=[],n=[];for(let r of e.getLaidOutComponents()){let e=r.getPreferredSize();t.push(e?e.height:0),n.push(r.getBaseline())}return this.computeRowMetrics(t,n).rowAscent}getPreferredSize(){let e=this.getContainer();if(!e)return null;let t=e.getPerimeterSize(),n=e.getLaidOutComponents(),r=t.left+t.right,i=[],a=[];if(this._mode===`equal`){let e=0;for(let t in n){let r=n[t],o=r.getPreferredSize();o&&(e=Math.max(e,o.width),i.push(o.height),a.push(r.getBaseline()))}r+=n.length*(e+this._spacing)-this._spacing}else{for(let e in n){let t=n[e],o=t.getPreferredSize();o&&(r+=o.width,i.push(o.height),a.push(t.getBaseline()))}r+=this._spacing*(n.length-1)}let o=this.computeRowHeight(i,a);return o+=t.top+t.bottom,{width:r,height:o}}getMinSize(){let e=this.getContainer();if(!e)return null;let t=e.getPerimeterSize(),n=e.getLaidOutComponents(),r=t.left+t.right,i=[],a=[];if(this._mode===`equal`){let e=0;for(let t in n){let r=n[t],o=r.getMinSize();o&&(e=Math.max(e,o.width),i.push(o.height),a.push(r.getBaseline()))}r+=n.length*(e+this._spacing)-this._spacing}else{for(let e in n){let t=n[e],o=t.getMinSize();o&&(r+=o.width,i.push(o.height),a.push(t.getBaseline()))}r+=this._spacing*(n.length-1)}let o=this.computeRowHeight(i,a);return o+=t.top+t.bottom,{width:r,height:o}}getMaxSize(){return this.aggregateMaxSize(!0)}computeTotalMinSize(){let e=this.getContainer();if(!e)return{width:0,height:0};let t=e.getLaidOutComponents();if(t.length===0)return{width:0,height:0};let n=0;if(this._mode===`equal`){let e=0;for(let r of t){let t=r.getMinSize();t&&(e=Math.max(e,t.width),n=Math.max(n,t.height))}return{width:t.length*(e+this._spacing)-this._spacing,height:n}}let r=this._spacing*(t.length-1);for(let e of t){let t=e.getMinSize();t&&(r+=t.width,n=Math.max(n,t.height))}return{width:r,height:n}}doLayout(){let e=this.getContainer();if(!e)return;let t=e.getInnerSize();if(!t)return;let n=e.getLaidOutComponents(),r=e.getContentInsets(),i=this.getComponentSpacing(),a=this.inflateForOverflow(t),o;o=this._mode===`equal`?this.layoutEqualMode(n,t,a,r,i):this.layoutPreferredMode(n,a,r,i),this.commitPlacements(o),this.reserveContentFrame()}layoutEqualMode(e,t,n,r,a){let o=this.computeEqualCellWidth(e,t.width,a);if(this.isStretching()){let t=r.getTop(),s=r.getLeft(),c=[];for(let r of e)c.push({component:r,...this.resolveBounds(r,s,t,o,n.height,i.BOTH)}),s+=o+a;return c}let s=[],c=[];for(let t of e){let e=t.getPreferredSize();s.push(e?e.height:0),c.push(t.getBaseline())}let{rowAscent:l,rowDescent:u}=this.computeRowMetrics(s,c),d=r.getTop(),f=n.height,p=r.getLeft(),m=[];for(let t=0;t<e.length;t+=1){let n=e[t],h=this.crossPlacement(n,d,f,s[t],!0);if(h)m.push({component:n,...this.resolveBounds(n,p,h.offset,o,h.extent,i.BOTH)});else if(this._itemAlign===`start`||this._itemAlign===`center`||this._itemAlign===`end`){let e=d+this.crossItemOffset(s[t],f);m.push({component:n,...this.resolveBounds(n,p,e,o,s[t],i.BOTH)})}else{let e=this.rowChildY(r.getTop(),s[t],c[t],l,u);m.push({component:n,...this.resolveBounds(n,p,e,o,s[t],i.BOTH)})}p+=o+a}return m}computeEqualCellWidth(e,t,n){let r=0,i=0;for(let t of e){let e=t.getMinSize();e&&(r=Math.max(r,e.width));let n=t.getPreferredSize();n&&(i=Math.max(i,n.width))}let a=(t-n*(e.length-1))/e.length;return a>=r?a:this.isOverflowingX()&&this._overflowSizing===`preferred`?Math.max(r,i):r}layoutPreferredMode(e,t,n,r){let{totalWeight:a,fixedPreferred:o,fixedMin:s}=this.measureFixedWidths(e,r),{remaining:c,shrinkRatio:l}=this.computeShrink(o,s,t.width,this.isOverflowingX()),u=[],d=[],f=[];for(let n of e){let e=this.getLayoutConstraints(n)?.weight??0,r=n.getPreferredSize(),i=n.getMinSize(),o=n.getMaxSize();u.push(this.resolveChildWidth(r,i,o,e,a,c,l));let s;s=!r||this.isStretching()?t.height:Math.min(r.height,t.height),o&&(s=Math.min(s,o.height)),d.push(s),f.push(n.getBaseline())}let{rowAscent:p,rowDescent:m}=this.isStretching()?{rowAscent:null,rowDescent:0}:this.computeRowMetrics(d,f),h=0,g=0;if(a===0){let i=r*(e.length-1);for(let e of u)i+=e;let a=t.width-(n.getLeft()+n.getRight());({lead:h,gap:g}=this.justifyOffsets(i,a,e.length))}let _=n.getTop(),v=t.height-(n.getTop()+n.getBottom()),y=n.getLeft()+h,b=[];for(let t=0;t<e.length;t+=1){let a=e[t],o=a.getPreferredSize(),s=a.getMaxSize(),c=o?Math.min(o.height,v):v;s&&(c=Math.min(c,s.height));let l=this.crossPlacement(a,_,v,c,!0);if(l)b.push({component:a,...this.resolveBounds(a,y,l.offset,u[t],l.extent,i.BOTH)});else if(this._itemAlign===`start`||this._itemAlign===`center`||this._itemAlign===`end`){let e=_+this.crossItemOffset(d[t],v);b.push({component:a,...this.resolveBounds(a,y,e,u[t],d[t],i.BOTH)})}else{let e=this.rowChildY(n.getTop(),d[t],f[t],p,m);b.push({component:a,...this.resolveBounds(a,y,e,u[t],d[t],i.BOTH)})}y+=u[t],y+=r+g}return b}measureFixedWidths(e,t){let n=0,r=t*(e.length-1),i=t*(e.length-1);for(let t of e){let e=this.getLayoutConstraints(t)?.weight??0;if(e>0)n+=e;else{let e=t.getPreferredSize(),n=t.getMinSize();r+=this.preferredChildWidth(e,n),i+=n?n.width:0}}return{totalWeight:n,fixedPreferred:r,fixedMin:i}}preferredChildWidth(e,t){let n=(e?e.width:void 0)??(t&&t.width>0?t.width:void 0)??this._defaultComponentWidth;return t?Math.max(n,t.width):n}resolveChildWidth(e,t,n,r,i,a,o){let s;if(r>0&&i>0)s=r/i*a;else{let n=this.preferredChildWidth(e,t);s=n-o*(n-(t?t.width:0))}return n&&(s=Math.min(s,n.width)),t&&(s=Math.max(s,t.width)),s}rowChildY(e,t,n,r,i){return r===null?e:n===null?e+this.nullChildY(t,r,i):e+(r-n)}},o=r(HBox),VBox=class extends BoxLayout{_defaultComponentHeight=100;getContentBaseline(){let e=this.getContainer();if(!e)return null;let t=e.getLaidOutComponents();return t.length===0?null:t[0].getBaseline()}getPreferredSize(){let n=this.getContainer();if(!n)return null;let r=n.getPerimeterSize(),i=n.getLaidOutComponents();if(this._mode===`equal`){let e=0,t=0;for(let n in i){let r=i[n].getPreferredSize();r&&(e=Math.max(e,r.width),t=Math.max(t,r.height))}return{width:e+r.left+r.right,height:i.length*(t+this._spacing)-this._spacing+r.top+r.bottom}}let a=e,o=r.top+r.bottom;for(let e in i){let n=i[e].getPreferredSize();n&&(a=t(a)?Math.min(a,n.width):Math.max(a,n.width),o+=n.height)}return a+=r.left+r.right,o+=this._spacing*(i.length-1),{width:a,height:o}}getMinSize(){let e=this.getContainer();if(!e)return null;let t=e.getPerimeterSize(),n=e.getLaidOutComponents();if(this._mode===`equal`){let e=0,r=0;for(let t in n){let i=n[t].getMinSize();i&&(e=Math.max(e,i.width),r=Math.max(r,i.height))}return{width:e+t.left+t.right,height:n.length*(r+this._spacing)-this._spacing+t.top+t.bottom}}let r=0,i=t.top+t.bottom;for(let e in n){let t=n[e].getMinSize();t&&(r=Math.max(r,t.width),i+=t.height)}return r+=t.left+t.right,i+=this._spacing*(n.length-1),{width:r,height:i}}getMaxSize(){return this.aggregateMaxSize(!1)}computeTotalMinSize(){let e=this.getContainer();if(!e)return{width:0,height:0};let t=e.getLaidOutComponents();if(t.length===0)return{width:0,height:0};let n=0;if(this._mode===`equal`){let e=0;for(let r of t){let t=r.getMinSize();t&&(n=Math.max(n,t.width),e=Math.max(e,t.height))}return{width:n,height:t.length*(e+this._spacing)-this._spacing}}let r=this._spacing*(t.length-1);for(let e of t){let t=e.getMinSize();t&&(n=Math.max(n,t.width),r+=t.height)}return{width:n,height:r}}doLayout(){let e=this.getContainer();if(!e)return;let t=e.getInnerSize();if(!t)return;let n=e.getLaidOutComponents(),r=e.getContentInsets(),i=this.getComponentSpacing(),a=this.inflateForOverflow(t),o;o=this._mode===`equal`?this.layoutEqualMode(n,t,a,r,i):this.layoutPreferredMode(n,a,r,i),this.commitPlacements(o),this.reserveContentFrame()}layoutEqualMode(e,t,n,r,a){let o=this.computeEqualCellHeight(e,t.height,a),s=r.getLeft(),c=r.getTop();if(this.isStretching()){let t=n.width,r=[];for(let n of e)r.push({component:n,...this.resolveBounds(n,s,c,t,o,i.BOTH)}),c+=o+a;return r}let l=r.getLeft(),u=n.width,d=[];for(let t of e){let e=t.getPreferredSize(),n=e?e.width:0,r=this.crossPlacement(t,l,u,n,!1);if(r)d.push({component:t,...this.resolveBounds(t,r.offset,c,r.extent,o,i.BOTH)});else if(this._itemAlign===`start`||this._itemAlign===`center`||this._itemAlign===`end`){let e=l+this.crossItemOffset(n,u);d.push({component:t,...this.resolveBounds(t,e,c,n,o,i.BOTH)})}else d.push({component:t,...this.resolveBounds(t,s,c,n,o,i.BOTH)});c+=o+a}return d}computeEqualCellHeight(e,t,n){let r=0,i=0;for(let t of e){let e=t.getMinSize();e&&(r=Math.max(r,e.height));let n=t.getPreferredSize();n&&(i=Math.max(i,n.height))}let a=(t-n*(e.length-1))/e.length;return a>=r?a:this.isOverflowingY()&&this._overflowSizing===`preferred`?Math.max(r,i):r}layoutPreferredMode(e,t,n,r){let{totalWeight:a,fixedPreferred:o,fixedMin:s}=this.measureFixedHeights(e,r),{remaining:c,shrinkRatio:l}=this.computeShrink(o,s,t.height,this.isOverflowingY()),u=[];for(let t of e){let e=this.getLayoutConstraints(t)?.weight??0,n=t.getPreferredSize(),r=t.getMinSize(),i=t.getMaxSize();u.push(this.resolveChildHeight(n,r,i,e,a,c,l))}let d=0,f=0;if(a===0){let i=r*(e.length-1);for(let e of u)i+=e;let a=t.height-(n.getTop()+n.getBottom());({lead:d,gap:f}=this.justifyOffsets(i,a,e.length))}let p=n.getLeft(),m=t.width-(n.getLeft()+n.getRight()),h=n.getLeft(),g=n.getTop()+d,_=[];for(let n=0;n<e.length;n+=1){let a=e[n],o=a.getPreferredSize(),s=a.getMaxSize(),c;c=!o||this.isStretching()?t.width:Math.min(o.width,t.width),s&&(c=Math.min(c,s.width));let l=o?Math.min(o.width,m):m;s&&(l=Math.min(l,s.width));let d=this.crossPlacement(a,p,m,l,!1);if(d)_.push({component:a,...this.resolveBounds(a,d.offset,g,d.extent,u[n],i.BOTH)});else if(this._itemAlign===`start`||this._itemAlign===`center`||this._itemAlign===`end`){let e=p+this.crossItemOffset(l,m);_.push({component:a,...this.resolveBounds(a,e,g,l,u[n],i.BOTH)})}else _.push({component:a,...this.resolveBounds(a,h,g,c,u[n],i.BOTH)});g+=u[n],g+=r+f}return _}measureFixedHeights(e,t){let n=0,r=t*(e.length-1),i=t*(e.length-1);for(let t of e){let e=this.getLayoutConstraints(t)?.weight??0;if(e>0)n+=e;else{let e=t.getPreferredSize(),n=t.getMinSize();r+=this.preferredChildHeight(e,n),i+=n?n.height:0}}return{totalWeight:n,fixedPreferred:r,fixedMin:i}}preferredChildHeight(e,t){let n=(e?e.height:void 0)??(t&&t.height>0?t.height:void 0)??this._defaultComponentHeight;return t?Math.max(n,t.height):n}resolveChildHeight(e,t,n,r,i,a,o){let s;if(r>0&&i>0)s=r/i*a;else{let n=this.preferredChildHeight(e,t);s=n-o*(n-(t?t.height:0))}return n&&(s=Math.min(s,n.height)),t&&(s=Math.max(s,t.height)),s}},s=r(VBox);export{BoxLayout as i,s as n,o as r,VBox as t};
|
|
2
|
-
//# sourceMappingURL=VBox-
|
|
1
|
+
import{a as e,o as t}from"./Position-BIEU1Eze.js";import{f as n,h as r,m as i,p as a}from"./Component-D99-15Zt.js";var BoxLayout=class extends n{_spacing=5;_itemAlign=`baseline`;_mode=`preferred`;_overflowSizing=`preferred`;_justify=`start`;constructor(e){super(),e&&this.applyOptions(e)}applyOptions(e){super.applyOptions(e),e.mode!==void 0&&this.setMode(e.mode),e.spacing!==void 0&&this.setComponentSpacing(e.spacing),e.stretching!==void 0&&this.setStretching(e.stretching),e.itemAlign!==void 0&&this.setItemAlign(e.itemAlign),e.overflowSizing!==void 0&&this.setOverflowSizing(e.overflowSizing),e.justify!==void 0&&this.setJustify(e.justify)}getComponentSpacing(){return this._spacing||0}setComponentSpacing(e){return this._spacing=e||0,this}isStretching(){return this._itemAlign===`stretch`}setStretching(e){return this.setItemAlign(e?`stretch`:`baseline`)}getItemAlign(){return this._itemAlign}setItemAlign(e){return this._itemAlign=e,this}getMode(){return this._mode}setMode(e){return this._mode=e,this}getOverflowSizing(){return this._overflowSizing}setOverflowSizing(e){return this._overflowSizing=e,this}getJustify(){return this._justify}setJustify(e){return this._justify=e,this}aggregateMaxSize(n){let r=this.getContainer();if(!r)return null;let i=r.getPerimeterSize(),a=r.getLaidOutComponents(),o=n?i.left+i.right:i.top+i.bottom,s=n?i.top+i.bottom:i.left+i.right,c=o,l=0,u=!1,d=!1,f=0;for(let e of a){let r=e.getMaxSize();if(!r){u=!0,d=!0;continue}let i=n?r.width:r.height,a=n?r.height:r.width;t(i)?u=!0:this._mode===`equal`?f=Math.max(f,i):c+=i,t(a)?d=!0:l=Math.max(l,a)}this._mode===`equal`?c+=a.length*f+this._spacing*Math.max(0,a.length-1):c+=this._spacing*Math.max(0,a.length-1),l+=s;let p=u?e:c,m=d?e:l;return{width:n?p:m,height:n?m:p}}computeShrink(e,t,n,r){if(e<=n||r)return{remaining:Math.max(0,n-e),shrinkRatio:0};let i=e-n,a=e-t;return{remaining:0,shrinkRatio:a>0?Math.min(1,i/a):1}}justifyOffsets(e,t,n){let r=Math.max(0,t-e);return r===0||this._justify===`start`?{lead:0,gap:0}:this._justify===`center`?{lead:r/2,gap:0}:this._justify===`end`?{lead:r,gap:0}:this._justify===`between`?{lead:0,gap:n>1?r/(n-1):0}:{lead:n>0?r/(2*n):0,gap:n>0?r/n:0}}crossItemOffset(e,t){return this._itemAlign===`center`?Math.max(0,(t-e)/2):this._itemAlign===`end`?Math.max(0,t-e):0}crossPlacement(e,t,n,r,a){let o=this.getLayoutConstraints(e),s=o?.fill??null,c=o?.anchor??null;if(a?s===i.VERTICAL||s===i.BOTH:s===i.HORIZONTAL||s===i.BOTH)return{offset:t,extent:n};let l=this.crossAnchorEdge(c,a);if(l===null)return null;let u=Math.min(r,n);return{offset:l===`lead`?t:t+(n-u),extent:u}}crossAnchorEdge(e,t){return e===null?null:t?e===a.NORTH||e===a.NORTHWEST||e===a.NORTHEAST?`lead`:e===a.SOUTH||e===a.SOUTHWEST||e===a.SOUTHEAST?`trail`:null:e===a.WEST||e===a.NORTHWEST||e===a.SOUTHWEST?`lead`:e===a.EAST||e===a.NORTHEAST||e===a.SOUTHEAST?`trail`:null}},HBox=class extends BoxLayout{_defaultComponentWidth=100;getContentBaseline(){if(this._itemAlign!==`baseline`)return null;let e=this.getContainer();if(!e)return null;let t=[],n=[];for(let r of e.getLaidOutComponents()){let e=r.getPreferredSize();t.push(e?e.height:0),n.push(r.getBaseline())}return this.computeRowMetrics(t,n).rowAscent}getPreferredSize(){let e=this.getContainer();if(!e)return null;let t=e.getPerimeterSize(),n=e.getLaidOutComponents(),r=t.left+t.right,i=[],a=[];if(this._mode===`equal`){let e=0;for(let t in n){let r=n[t],o=r.getPreferredSize();o&&(e=Math.max(e,o.width),i.push(o.height),a.push(r.getBaseline()))}r+=n.length*(e+this._spacing)-this._spacing}else{for(let e in n){let t=n[e],o=t.getPreferredSize();o&&(r+=o.width,i.push(o.height),a.push(t.getBaseline()))}r+=this._spacing*(n.length-1)}let o=this.computeRowHeight(i,a);return o+=t.top+t.bottom,{width:r,height:o}}getMinSize(){let e=this.getContainer();if(!e)return null;let t=e.getPerimeterSize(),n=e.getLaidOutComponents(),r=t.left+t.right,i=[],a=[];if(this._mode===`equal`){let e=0;for(let t in n){let r=n[t],o=r.getMinSize();o&&(e=Math.max(e,o.width),i.push(o.height),a.push(r.getBaseline()))}r+=n.length*(e+this._spacing)-this._spacing}else{for(let e in n){let t=n[e],o=t.getMinSize();o&&(r+=o.width,i.push(o.height),a.push(t.getBaseline()))}r+=this._spacing*(n.length-1)}let o=this.computeRowHeight(i,a);return o+=t.top+t.bottom,{width:r,height:o}}getMaxSize(){return this.aggregateMaxSize(!0)}computeTotalMinSize(){let e=this.getContainer();if(!e)return{width:0,height:0};let t=e.getLaidOutComponents();if(t.length===0)return{width:0,height:0};let n=0;if(this._mode===`equal`){let e=0;for(let r of t){let t=r.getMinSize();t&&(e=Math.max(e,t.width),n=Math.max(n,t.height))}return{width:t.length*(e+this._spacing)-this._spacing,height:n}}let r=this._spacing*(t.length-1);for(let e of t){let t=e.getMinSize();t&&(r+=t.width,n=Math.max(n,t.height))}return{width:r,height:n}}doLayout(){let e=this.getContainer();if(!e)return;let t=e.getInnerSize();if(!t)return;let n=e.getLaidOutComponents(),r=e.getContentInsets(),i=this.getComponentSpacing(),a=this.inflateForOverflow(t),o;o=this._mode===`equal`?this.layoutEqualMode(n,t,a,r,i):this.layoutPreferredMode(n,a,r,i),this.commitPlacements(o),this.reserveContentFrame()}layoutEqualMode(e,t,n,r,a){let o=this.computeEqualCellWidth(e,t.width,a);if(this.isStretching()){let t=r.getTop(),s=r.getLeft(),c=[];for(let r of e)c.push({component:r,...this.resolveBounds(r,s,t,o,n.height,i.BOTH)}),s+=o+a;return c}let s=[],c=[];for(let t of e){let e=t.getPreferredSize();s.push(e?e.height:0),c.push(t.getBaseline())}let{rowAscent:l,rowDescent:u}=this.computeRowMetrics(s,c),d=r.getTop(),f=n.height,p=r.getLeft(),m=[];for(let t=0;t<e.length;t+=1){let n=e[t],h=this.crossPlacement(n,d,f,s[t],!0);if(h)m.push({component:n,...this.resolveBounds(n,p,h.offset,o,h.extent,i.BOTH)});else if(this._itemAlign===`start`||this._itemAlign===`center`||this._itemAlign===`end`){let e=d+this.crossItemOffset(s[t],f);m.push({component:n,...this.resolveBounds(n,p,e,o,s[t],i.BOTH)})}else{let e=this.rowChildY(r.getTop(),s[t],c[t],l,u);m.push({component:n,...this.resolveBounds(n,p,e,o,s[t],i.BOTH)})}p+=o+a}return m}computeEqualCellWidth(e,t,n){let r=0,i=0;for(let t of e){let e=t.getMinSize();e&&(r=Math.max(r,e.width));let n=t.getPreferredSize();n&&(i=Math.max(i,n.width))}let a=(t-n*(e.length-1))/e.length;return a>=r?a:this.isOverflowingX()&&this._overflowSizing===`preferred`?Math.max(r,i):r}layoutPreferredMode(e,t,n,r){let{totalWeight:a,fixedPreferred:o,fixedMin:s}=this.measureFixedWidths(e,r),{remaining:c,shrinkRatio:l}=this.computeShrink(o,s,t.width,this.isOverflowingX()),u=[],d=[],f=[];for(let n of e){let e=this.getLayoutConstraints(n)?.weight??0,r=n.getPreferredSize(),i=n.getMinSize(),o=n.getMaxSize();u.push(this.resolveChildWidth(r,i,o,e,a,c,l));let s;s=!r||this.isStretching()?t.height:Math.min(r.height,t.height),o&&(s=Math.min(s,o.height)),d.push(s),f.push(n.getBaseline())}let{rowAscent:p,rowDescent:m}=this.isStretching()?{rowAscent:null,rowDescent:0}:this.computeRowMetrics(d,f),h=0,g=0;if(a===0){let i=r*(e.length-1);for(let e of u)i+=e;let a=t.width-(n.getLeft()+n.getRight());({lead:h,gap:g}=this.justifyOffsets(i,a,e.length))}let _=n.getTop(),v=t.height-(n.getTop()+n.getBottom()),y=n.getLeft()+h,b=[];for(let t=0;t<e.length;t+=1){let a=e[t],o=a.getPreferredSize(),s=a.getMaxSize(),c=o?Math.min(o.height,v):v;s&&(c=Math.min(c,s.height));let l=this.crossPlacement(a,_,v,c,!0);if(l)b.push({component:a,...this.resolveBounds(a,y,l.offset,u[t],l.extent,i.BOTH)});else if(this._itemAlign===`start`||this._itemAlign===`center`||this._itemAlign===`end`){let e=_+this.crossItemOffset(d[t],v);b.push({component:a,...this.resolveBounds(a,y,e,u[t],d[t],i.BOTH)})}else{let e=this.rowChildY(n.getTop(),d[t],f[t],p,m);b.push({component:a,...this.resolveBounds(a,y,e,u[t],d[t],i.BOTH)})}y+=u[t],y+=r+g}return b}measureFixedWidths(e,t){let n=0,r=t*(e.length-1),i=t*(e.length-1);for(let t of e){let e=this.getLayoutConstraints(t)?.weight??0;if(e>0)n+=e;else{let e=t.getPreferredSize(),n=t.getMinSize();r+=this.preferredChildWidth(e,n),i+=n?n.width:0}}return{totalWeight:n,fixedPreferred:r,fixedMin:i}}preferredChildWidth(e,t){let n=(e?e.width:void 0)??(t&&t.width>0?t.width:void 0)??this._defaultComponentWidth;return t?Math.max(n,t.width):n}resolveChildWidth(e,t,n,r,i,a,o){let s;if(r>0&&i>0)s=r/i*a;else{let n=this.preferredChildWidth(e,t);s=n-o*(n-(t?t.width:0))}return n&&(s=Math.min(s,n.width)),t&&(s=Math.max(s,t.width)),s}rowChildY(e,t,n,r,i){return r===null?e:n===null?e+this.nullChildY(t,r,i):e+(r-n)}},o=r(HBox),VBox=class extends BoxLayout{_defaultComponentHeight=100;getContentBaseline(){let e=this.getContainer();if(!e)return null;let t=e.getLaidOutComponents();return t.length===0?null:t[0].getBaseline()}getPreferredSize(){let n=this.getContainer();if(!n)return null;let r=n.getPerimeterSize(),i=n.getLaidOutComponents();if(this._mode===`equal`){let e=0,t=0;for(let n in i){let r=i[n].getPreferredSize();r&&(e=Math.max(e,r.width),t=Math.max(t,r.height))}return{width:e+r.left+r.right,height:i.length*(t+this._spacing)-this._spacing+r.top+r.bottom}}let a=e,o=r.top+r.bottom;for(let e in i){let n=i[e].getPreferredSize();n&&(a=t(a)?Math.min(a,n.width):Math.max(a,n.width),o+=n.height)}return a+=r.left+r.right,o+=this._spacing*(i.length-1),{width:a,height:o}}getMinSize(){let e=this.getContainer();if(!e)return null;let t=e.getPerimeterSize(),n=e.getLaidOutComponents();if(this._mode===`equal`){let e=0,r=0;for(let t in n){let i=n[t].getMinSize();i&&(e=Math.max(e,i.width),r=Math.max(r,i.height))}return{width:e+t.left+t.right,height:n.length*(r+this._spacing)-this._spacing+t.top+t.bottom}}let r=0,i=t.top+t.bottom;for(let e in n){let t=n[e].getMinSize();t&&(r=Math.max(r,t.width),i+=t.height)}return r+=t.left+t.right,i+=this._spacing*(n.length-1),{width:r,height:i}}getMaxSize(){return this.aggregateMaxSize(!1)}computeTotalMinSize(){let e=this.getContainer();if(!e)return{width:0,height:0};let t=e.getLaidOutComponents();if(t.length===0)return{width:0,height:0};let n=0;if(this._mode===`equal`){let e=0;for(let r of t){let t=r.getMinSize();t&&(n=Math.max(n,t.width),e=Math.max(e,t.height))}return{width:n,height:t.length*(e+this._spacing)-this._spacing}}let r=this._spacing*(t.length-1);for(let e of t){let t=e.getMinSize();t&&(n=Math.max(n,t.width),r+=t.height)}return{width:n,height:r}}doLayout(){let e=this.getContainer();if(!e)return;let t=e.getInnerSize();if(!t)return;let n=e.getLaidOutComponents(),r=e.getContentInsets(),i=this.getComponentSpacing(),a=this.inflateForOverflow(t),o;o=this._mode===`equal`?this.layoutEqualMode(n,t,a,r,i):this.layoutPreferredMode(n,a,r,i),this.commitPlacements(o),this.reserveContentFrame()}layoutEqualMode(e,t,n,r,a){let o=this.computeEqualCellHeight(e,t.height,a),s=r.getLeft(),c=r.getTop();if(this.isStretching()){let t=n.width,r=[];for(let n of e)r.push({component:n,...this.resolveBounds(n,s,c,t,o,i.BOTH)}),c+=o+a;return r}let l=r.getLeft(),u=n.width,d=[];for(let t of e){let e=t.getPreferredSize(),n=e?e.width:0,r=this.crossPlacement(t,l,u,n,!1);if(r)d.push({component:t,...this.resolveBounds(t,r.offset,c,r.extent,o,i.BOTH)});else if(this._itemAlign===`start`||this._itemAlign===`center`||this._itemAlign===`end`){let e=l+this.crossItemOffset(n,u);d.push({component:t,...this.resolveBounds(t,e,c,n,o,i.BOTH)})}else d.push({component:t,...this.resolveBounds(t,s,c,n,o,i.BOTH)});c+=o+a}return d}computeEqualCellHeight(e,t,n){let r=0,i=0;for(let t of e){let e=t.getMinSize();e&&(r=Math.max(r,e.height));let n=t.getPreferredSize();n&&(i=Math.max(i,n.height))}let a=(t-n*(e.length-1))/e.length;return a>=r?a:this.isOverflowingY()&&this._overflowSizing===`preferred`?Math.max(r,i):r}layoutPreferredMode(e,t,n,r){let{totalWeight:a,fixedPreferred:o,fixedMin:s}=this.measureFixedHeights(e,r),{remaining:c,shrinkRatio:l}=this.computeShrink(o,s,t.height,this.isOverflowingY()),u=[];for(let t of e){let e=this.getLayoutConstraints(t)?.weight??0,n=t.getPreferredSize(),r=t.getMinSize(),i=t.getMaxSize();u.push(this.resolveChildHeight(n,r,i,e,a,c,l))}let d=0,f=0;if(a===0){let i=r*(e.length-1);for(let e of u)i+=e;let a=t.height-(n.getTop()+n.getBottom());({lead:d,gap:f}=this.justifyOffsets(i,a,e.length))}let p=n.getLeft(),m=t.width-(n.getLeft()+n.getRight()),h=n.getLeft(),g=n.getTop()+d,_=[];for(let n=0;n<e.length;n+=1){let a=e[n],o=a.getPreferredSize(),s=a.getMaxSize(),c;c=!o||this.isStretching()?t.width:Math.min(o.width,t.width),s&&(c=Math.min(c,s.width));let l=o?Math.min(o.width,m):m;s&&(l=Math.min(l,s.width));let d=this.crossPlacement(a,p,m,l,!1);if(d)_.push({component:a,...this.resolveBounds(a,d.offset,g,d.extent,u[n],i.BOTH)});else if(this._itemAlign===`start`||this._itemAlign===`center`||this._itemAlign===`end`){let e=p+this.crossItemOffset(l,m);_.push({component:a,...this.resolveBounds(a,e,g,l,u[n],i.BOTH)})}else _.push({component:a,...this.resolveBounds(a,h,g,c,u[n],i.BOTH)});g+=u[n],g+=r+f}return _}measureFixedHeights(e,t){let n=0,r=t*(e.length-1),i=t*(e.length-1);for(let t of e){let e=this.getLayoutConstraints(t)?.weight??0;if(e>0)n+=e;else{let e=t.getPreferredSize(),n=t.getMinSize();r+=this.preferredChildHeight(e,n),i+=n?n.height:0}}return{totalWeight:n,fixedPreferred:r,fixedMin:i}}preferredChildHeight(e,t){let n=(e?e.height:void 0)??(t&&t.height>0?t.height:void 0)??this._defaultComponentHeight;return t?Math.max(n,t.height):n}resolveChildHeight(e,t,n,r,i,a,o){let s;if(r>0&&i>0)s=r/i*a;else{let n=this.preferredChildHeight(e,t);s=n-o*(n-(t?t.height:0))}return n&&(s=Math.min(s,n.height)),t&&(s=Math.max(s,t.height)),s}},s=r(VBox);export{BoxLayout as i,s as n,o as r,VBox as t};
|
|
2
|
+
//# sourceMappingURL=VBox-DVe4UXwX.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VBox-DfJPWXqc.js","names":[],"sources":["../../src/typescript/lib/layout/BoxLayout.ts","../../src/typescript/lib/layout/HBox.ts","../../src/typescript/lib/layout/VBox.ts"],"sourcesContent":["// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { LayoutManager, LayoutManagerOptions } from \"~/layout/LayoutManager.js\";\nimport { FillType } from \"~/layout/FillType.js\";\nimport { AnchorType } from \"~/layout/AnchorType.js\";\nimport type { AxisPosition, AxisSpread } from \"~/primitive/Axis.js\";\nimport { Component } from \"~/core/Component.js\";\nimport { Size, UNBOUNDED, isUnbounded } from \"~/primitive/Size.js\";\n\n/**\n * Sizing strategy along an {@link HBox} or {@link VBox}'s main axis.\n *\n * - `\"preferred\"` — each child gets its preferred width (height for VBox);\n * `weight`-constrained children split the remaining space; an overflow\n * shrinks non-weighted children proportionally toward their min sizes.\n * - `\"equal\"` — children split the container's inner extent equally; the\n * per-cell floor is `max(child.minSize.width)` (height for VBox);\n * `weight` constraints are ignored.\n *\n * @category Layouts\n */\nexport type BoxMode = \"preferred\" | \"equal\";\n\n/**\n * How an `\"equal\"`-mode {@link HBox}/{@link VBox} sizes its cells when the\n * row/column overflows the host's inner extent and the host has opted into\n * scrolling (`Panel.setAutoScroll`).\n *\n * - `\"preferred\"` (the default) — every cell takes the widest/tallest child's\n * preferred extent, so cells keep their preferred size and the host scrolls.\n * - `\"min\"` — every cell stays at the min floor (`max(child.minSize)`), so the\n * row/column scrolls at the minimum cell size instead of growing.\n *\n * Has no effect outside `\"equal\"` mode, nor when the cells fit (the equal share\n * clears the min floor), nor when the host does not scroll (cells always clamp\n * to the min floor and the host's `overflow: hidden` clips the surplus).\n *\n * @category Layouts\n */\nexport type BoxOverflowSizing = \"preferred\" | \"min\";\n\n/**\n * How a `\"preferred\"`-mode {@link HBox}/{@link VBox} distributes the leftover\n * main-axis space when its children are shorter than the inner main extent and\n * no `weight` cells consume the slack. Mirrors CSS `justify-content`.\n *\n * A single line makes exactly one main-axis slack decision, so the two shared\n * axis concepts fuse into this one field: the {@link AxisPosition} half\n * (`\"start\"`/`\"center\"`/`\"end\"`) positions the whole child block as a unit,\n * while the {@link AxisSpread} half (`\"between\"`/`\"around\"`) spreads the slack\n * into the inter-child gaps. `justifyOffsets` reflects the split — position\n * values yield a leading offset (`lead`, `gap: 0`) and spread values yield an\n * inter-child `gap`. `\"start\"` is the shared identity of both halves, so the\n * union collapses to these five distinct values.\n *\n * - `\"start\"` (the default) — children pack at the leading edge; the slack sits\n * at the trailing edge.\n * - `\"center\"` — the child block is centred; equal slack on both ends.\n * - `\"end\"` — children pack at the trailing edge; the slack sits at the leading\n * edge.\n * - `\"between\"` — the first child sits at the leading edge, the last at the\n * trailing edge, and the slack is split evenly into the gaps between them.\n * - `\"around\"` — every child gets equal space around it: a half-unit before the\n * first and after the last, a full unit between neighbours.\n *\n * Has no effect outside `\"preferred\"` mode, nor when `weight` cells absorb the\n * slack, nor when the content fills or overflows the inner extent (the row\n * clamps to `\"start\"` so the leading child is never pushed out of view).\n *\n * @category Layouts\n */\nexport type BoxJustify = AxisPosition | AxisSpread;\n\n/**\n * Cross-axis alignment of a child within an {@link HBox} row / {@link VBox}\n * column, when the child sets no explicit per-child cross intent (fill/anchor\n * align-self). Mirrors {@link FlowLayout}'s `FlowItemAlign`, with the extra\n * `\"stretch\"` a box can do.\n *\n * - `\"start\"` — leading cross-edge (HBox top, VBox left).\n * - `\"center\"` — centred in the cross band.\n * - `\"end\"` — trailing cross-edge (HBox bottom, VBox right).\n * - `\"baseline\"` — HBox: shared text baseline (the default). VBox has no cross\n * text baseline, so it degrades to `\"start\"`.\n * - `\"stretch\"` — fill the cross band (equivalent to the deprecated\n * `stretching`).\n *\n * @category Layouts\n */\nexport type BoxItemAlign = \"start\" | \"center\" | \"end\" | \"baseline\" | \"stretch\";\n\n/**\n * Construction-time options shared by {@link HBox} and {@link VBox}.\n *\n * @remarks `mode` selects the sizing strategy along the box's main axis.\n * `\"preferred\"` (the default) honours each child's preferred main-axis extent\n * and supports `weight` cells. `\"equal\"` divides the container's main axis\n * equally and ignores `weight`. `mode` is independent of `stretching`, which\n * governs the cross axis: `stretching` defaults to `false` in both modes, so\n * `\"equal\"` divides the main axis but leaves children at their preferred\n * cross-axis extent unless `stretching: true` is passed.\n *\n * @category Layouts\n */\nexport interface BoxLayoutOptions extends LayoutManagerOptions {\n spacing?: number;\n /** @deprecated Use `itemAlign` — `stretching: true` ≡ `itemAlign: \"stretch\"`. */\n stretching?: boolean;\n itemAlign?: BoxItemAlign;\n mode?: BoxMode;\n overflowSizing?: BoxOverflowSizing;\n justify?: BoxJustify;\n}\n\n/**\n * Abstract base for the single-axis box layouts {@link HBox} and {@link VBox}.\n * Holds the axis-agnostic configuration plumbing — spacing, stretching, sizing\n * mode, and overflow sizing — and dispatches a {@link BoxLayoutOptions} bag.\n * The geometric algorithms (`getPreferredSize`, `getMinSize`, `getMaxSize`,\n * `computeTotalMinSize`, `doLayout`) are mirror-image per axis and stay\n * concrete on each subclass.\n *\n * @category Layouts\n */\nexport abstract class BoxLayout extends LayoutManager {\n\n // `protected`, not `private`: the subclasses' geometric methods\n // (getPreferredSize/getMinSize/getMaxSize/computeTotalMinSize/doLayout)\n // read these fields directly, so they must be visible to HBox/VBox.\n protected _spacing: number = 5;\n protected _itemAlign: BoxItemAlign = \"baseline\";\n protected _mode: BoxMode = \"preferred\";\n protected _overflowSizing: BoxOverflowSizing = \"preferred\";\n protected _justify: BoxJustify = \"start\";\n\n constructor(options?: BoxLayoutOptions) {\n // LayoutManager's constructor takes no options; applied via applyOptions below.\n // eslint-disable-next-line local/forward-super-options\n super();\n\n if (options) {\n this.applyOptions(options);\n }\n }\n\n /**\n * Applies a {@link BoxLayoutOptions} bag, dispatching mode, spacing, and\n * stretching after the inherited LayoutManager defaults.\n *\n * @param options - The options bag carrying the values to apply.\n *\n * @remarks `mode` and `stretching` are independent axes: `mode` governs the\n * main-axis sizing strategy, `stretching` governs whether children fill the\n * cross axis. Neither defaults from the other — `stretching` is `false`\n * unless the options bag passes it explicitly, in both `\"preferred\"` and\n * `\"equal\"` mode.\n */\n protected applyOptions(options: BoxLayoutOptions): void {\n super.applyOptions(options);\n\n if (options.mode !== undefined) {\n this.setMode(options.mode);\n }\n\n if (options.spacing !== undefined) {\n this.setComponentSpacing(options.spacing);\n }\n\n if (options.stretching !== undefined) {\n this.setStretching(options.stretching);\n }\n\n if (options.itemAlign !== undefined) {\n this.setItemAlign(options.itemAlign);\n }\n\n if (options.overflowSizing !== undefined) {\n this.setOverflowSizing(options.overflowSizing);\n }\n\n if (options.justify !== undefined) {\n this.setJustify(options.justify);\n }\n }\n\n /**\n * Returns the pixel spacing between child components.\n *\n * @returns The current spacing in pixels.\n */\n getComponentSpacing(): number {\n return this._spacing || 0;\n }\n\n /**\n * Sets the pixel spacing between child components.\n *\n * @param spacing - Spacing in pixels.\n *\n * @returns This layout manager, for method chaining.\n */\n setComponentSpacing(spacing: number): this {\n this._spacing = spacing || 0;\n\n return this;\n }\n\n /**\n * Returns whether children stretch to fill the container's cross axis.\n *\n * @returns `true` if stretching is enabled.\n *\n * @deprecated Use `getItemAlign() === \"stretch\"`.\n */\n isStretching(): boolean {\n return this._itemAlign === \"stretch\";\n }\n\n /**\n * Sets whether children stretch to fill the container's cross axis.\n *\n * @param stretching - Pass `true` to enable cross-axis stretching.\n *\n * @returns This layout manager, for method chaining.\n *\n * @deprecated Use `setItemAlign(\"stretch\" | \"baseline\")`.\n */\n setStretching(stretching: boolean): this {\n return this.setItemAlign(stretching ? \"stretch\" : \"baseline\");\n }\n\n /**\n * Returns how a child is aligned within the cross axis when it sets no\n * explicit per-child cross intent (fill/anchor align-self).\n *\n * @returns The current {@link BoxItemAlign}.\n */\n getItemAlign(): BoxItemAlign {\n return this._itemAlign;\n }\n\n /**\n * Sets how a child is aligned within the cross axis when it sets no\n * explicit per-child cross intent (fill/anchor align-self).\n *\n * @param itemAlign - `\"start\"`/`\"center\"`/`\"end\"` pin to or centre within\n * the cross band, `\"baseline\"` (the default) aligns HBox rows on their\n * shared text baseline (degrading to `\"start\"` on VBox), and `\"stretch\"`\n * fills the cross band. See {@link BoxItemAlign}.\n *\n * @returns This layout manager, for method chaining.\n */\n setItemAlign(itemAlign: BoxItemAlign): this {\n this._itemAlign = itemAlign;\n\n return this;\n }\n\n /**\n * Returns the current sizing mode along the main axis.\n *\n * @returns Either `\"preferred\"` or `\"equal\"`.\n */\n getMode(): BoxMode {\n return this._mode;\n }\n\n /**\n * Sets the sizing mode along the main axis.\n *\n * @param mode - `\"preferred\"` honours each child's preferred main-axis\n * extent; `\"equal\"` divides the container's main axis equally among\n * children.\n *\n * @returns This layout manager, for method chaining.\n */\n setMode(mode: BoxMode): this {\n this._mode = mode;\n\n return this;\n }\n\n /**\n * Returns the cell-sizing strategy used when an `\"equal\"`-mode row/column\n * overflows a scrolling host.\n *\n * @returns Either `\"preferred\"` or `\"min\"`.\n */\n getOverflowSizing(): BoxOverflowSizing {\n return this._overflowSizing;\n }\n\n /**\n * Sets the cell-sizing strategy used when an `\"equal\"`-mode row/column\n * overflows a scrolling host.\n *\n * @param overflowSizing - `\"preferred\"` grows every cell to the largest\n * child's preferred extent and scrolls; `\"min\"` keeps cells at the min\n * floor and scrolls at the minimum cell size. See {@link BoxOverflowSizing}.\n *\n * @returns This layout manager, for method chaining.\n */\n setOverflowSizing(overflowSizing: BoxOverflowSizing): this {\n this._overflowSizing = overflowSizing;\n\n return this;\n }\n\n /**\n * Returns how leftover main-axis space is distributed in `\"preferred\"` mode.\n *\n * @returns The current {@link BoxJustify} mode.\n */\n getJustify(): BoxJustify {\n return this._justify;\n }\n\n /**\n * Sets how leftover main-axis space is distributed in `\"preferred\"` mode.\n *\n * @param justify - `\"start\"` packs children at the leading edge (the\n * default), `\"center\"`/`\"end\"` shift the block, and `\"between\"`/`\"around\"`\n * spread the slack into the inter-child gaps. See {@link BoxJustify}.\n *\n * @returns This layout manager, for method chaining.\n */\n setJustify(justify: BoxJustify): this {\n this._justify = justify;\n\n return this;\n }\n\n /**\n * Aggregates the children's maximum sizes per the box contract: main axis =\n * sum of child maxima (+ spacing; in `\"equal\"` mode count * widest-child-max),\n * cross axis = max of child maxima, a null or unbounded child max making that\n * axis unbounded. Saturated to {@link UNBOUNDED}. Includes the container\n * perimeter.\n *\n * @param horizontal - `true` for {@link HBox} (main = width), `false` for\n * {@link VBox} (main = height).\n * @returns The aggregated maximum `{width, height}`, or `null` if no\n * container is attached.\n */\n protected aggregateMaxSize(horizontal: boolean): Size | null {\n const container = this.getContainer();\n if (!container) {\n return null;\n }\n\n const perimeterSize = container.getPerimeterSize();\n const components = container.getLaidOutComponents();\n\n const mainStart = horizontal ? perimeterSize.left + perimeterSize.right : perimeterSize.top + perimeterSize.bottom;\n const crossExtra = horizontal ? perimeterSize.top + perimeterSize.bottom : perimeterSize.left + perimeterSize.right;\n\n let main = mainStart;\n let cross = 0;\n let mainUnbounded = false;\n let crossUnbounded = false;\n let maxChildMain = 0;\n\n for (const component of components) {\n const size = component.getMaxSize();\n\n if (!size) {\n mainUnbounded = true;\n crossUnbounded = true;\n continue;\n }\n\n const mainExtent = horizontal ? size.width : size.height;\n const crossExtent = horizontal ? size.height : size.width;\n\n if (isUnbounded(mainExtent)) {\n mainUnbounded = true;\n } else if (this._mode === \"equal\") {\n maxChildMain = Math.max(maxChildMain, mainExtent);\n } else {\n main += mainExtent;\n }\n\n if (isUnbounded(crossExtent)) {\n crossUnbounded = true;\n } else {\n cross = Math.max(cross, crossExtent);\n }\n }\n\n if (this._mode === \"equal\") {\n main += components.length * maxChildMain + this._spacing * Math.max(0, components.length - 1);\n } else {\n main += this._spacing * Math.max(0, components.length - 1);\n }\n\n cross += crossExtra;\n\n const mainValue = mainUnbounded ? UNBOUNDED : main;\n const crossValue = crossUnbounded ? UNBOUNDED : cross;\n\n return {\n width: horizontal ? mainValue : crossValue,\n height: horizontal ? crossValue : mainValue\n };\n }\n\n /**\n * Resolves how much main-axis space the weight cells share and how hard the\n * non-weighted children must shrink. When the non-weighted children's\n * preferred extents fit (or the host scrolls on this axis), nothing shrinks\n * and the leftover is the weight remainder. Otherwise the children shrink\n * proportionally toward their min extents so the last child's far edge lands\n * inside the container.\n *\n * @param fixedPreferred - Summed preferred main-axis extent of the\n * non-weighted children, including inter-child spacing.\n * @param fixedMin - Summed minimum main-axis extent of the same children,\n * including spacing.\n * @param available - The working container's inner extent on the main axis.\n * @param overflowing - Whether the host has opted into scrolling on this\n * axis; when `true` the shrink is skipped so the host's CSS overflow\n * engages instead.\n * @returns `remaining` — the main-axis space left for weight cells — and\n * `shrinkRatio` — `0` (no shrink) through `1` (shrink fully to min).\n */\n protected computeShrink(fixedPreferred: number, fixedMin: number, available: number, overflowing: boolean): { remaining: number; shrinkRatio: number } {\n if (fixedPreferred <= available || overflowing) {\n return { remaining: Math.max(0, available - fixedPreferred), shrinkRatio: 0 };\n }\n\n const excess = fixedPreferred - available;\n const shrinkable = fixedPreferred - fixedMin;\n\n return { remaining: 0, shrinkRatio: shrinkable > 0 ? Math.min(1, excess / shrinkable) : 1 };\n }\n\n /**\n * Distributes the trailing main-axis slack per {@link BoxJustify}, returning\n * a leading offset and an extra inter-child gap. The subclass adds `lead` to\n * the placement cursor's start and `gap` to the inter-child spacing. A row\n * that fills or overflows the inner extent (`residual === 0`) and the\n * `\"start\"` fast path both return `{ lead: 0, gap: 0 }`, leaving placement\n * byte-identical to the un-justified loop. Generalises\n * {@link FlowLayout.alignLead}, which only produces a leading offset, by also\n * spreading slack into the gaps for `\"between\"`/`\"around\"`.\n *\n * @param contentMain - Summed placed child main-extents plus inter-child\n * spacing — the block's total main extent.\n * @param innerMain - The container's inner extent along the main axis.\n * @param count - The number of children sharing the axis.\n * @returns `lead` — pixels added before the first child — and `gap` — pixels\n * added to the spacing after each child. Both are non-negative.\n */\n protected justifyOffsets(contentMain: number, innerMain: number, count: number): { lead: number; gap: number } {\n const residual = Math.max(0, innerMain - contentMain);\n\n if (residual === 0 || this._justify === \"start\") {\n return { lead: 0, gap: 0 };\n }\n\n if (this._justify === \"center\") {\n return { lead: residual / 2, gap: 0 };\n }\n\n if (this._justify === \"end\") {\n return { lead: residual, gap: 0 };\n }\n\n if (this._justify === \"between\") {\n return { lead: 0, gap: count > 1 ? residual / (count - 1) : 0 };\n }\n\n // \"around\"\n return { lead: count > 0 ? residual / (2 * count) : 0, gap: count > 0 ? residual / count : 0 };\n }\n\n /**\n * Computes the leading cross-axis offset for the `\"start\"`/`\"center\"`/\n * `\"end\"` {@link BoxItemAlign} fallback — consulted only when a child sets\n * no explicit per-child cross intent and `itemAlign` is not `\"baseline\"` or\n * `\"stretch\"` (those keep their own, unchanged, placement paths). Mirrors\n * {@link FlowLayout.crossOffset}'s `center`/`end` arms.\n *\n * @param childCross - The child's own cross extent.\n * @param crossExtent - The full cross band extent.\n * @returns The leading offset in pixels — `0` for `\"start\"`, and never negative.\n */\n protected crossItemOffset(childCross: number, crossExtent: number): number {\n if (this._itemAlign === \"center\") {\n return Math.max(0, (crossExtent - childCross) / 2);\n }\n\n if (this._itemAlign === \"end\") {\n return Math.max(0, crossExtent - childCross);\n }\n\n return 0; // \"start\"\n }\n\n /**\n * Resolves a child's cross-axis offset and extent within the full cross\n * band, honouring an explicit per-child cross `fill`/`anchor` (align-self).\n * A cross-axis `fill` (`VERTICAL`/`BOTH` in an {@link HBox}, `HORIZONTAL`/\n * `BOTH` in a {@link VBox}) stretches the child to the whole band; a\n * cross-axis `anchor` edge (NORTH/SOUTH for HBox, WEST/EAST for VBox, plus\n * the corners carrying that component) pins the child's natural cross extent\n * to the leading or trailing edge. The main-axis `anchor` component and\n * `CENTER` are deliberately inert — the box owns main-axis sequencing, and\n * when `itemAlign` is `\"baseline\"` (the default) each box's default cross\n * placement (HBox baseline, VBox WEST origin) is more specific than\n * geometric centring; other `itemAlign` values choose the cross offset in\n * the caller.\n *\n * @param component - The child whose constraints supply the cross intent.\n * @param crossLead - The band's leading edge (`insets.top` for HBox,\n * `insets.left` for VBox).\n * @param crossExtent - The full cross band extent.\n * @param naturalCross - The child's preferred cross extent, already capped to\n * the band and the child's maximum; the anchored child sits at this extent.\n * @param horizontal - `true` for {@link HBox} (cross axis is vertical),\n * `false` for {@link VBox} (cross axis is horizontal).\n * @returns `{ offset, extent }` when the child sets an explicit cross intent,\n * or `null` to signal the caller to keep its default cross placement.\n */\n protected crossPlacement(component: Component, crossLead: number, crossExtent: number, naturalCross: number, horizontal: boolean): { offset: number; extent: number } | null {\n const constraints = this.getLayoutConstraints(component);\n const fill = constraints?.fill ?? null;\n const anchor = constraints?.anchor ?? null;\n\n const crossFill = horizontal\n ? (fill === FillType.VERTICAL || fill === FillType.BOTH)\n : (fill === FillType.HORIZONTAL || fill === FillType.BOTH);\n\n if (crossFill) {\n return { offset: crossLead, extent: crossExtent };\n }\n\n const edge = this.crossAnchorEdge(anchor, horizontal);\n\n if (edge === null) {\n return null;\n }\n\n const extent = Math.min(naturalCross, crossExtent);\n const offset = edge === \"lead\"\n ? crossLead\n : crossLead + (crossExtent - extent);\n\n return { offset, extent };\n }\n\n /**\n * Projects a child's `anchor` onto the cross axis as a leading/trailing edge.\n * CENTER and pure main-axis anchors carry no cross component and return\n * `null`, leaving the caller on its default cross placement.\n *\n * @param anchor - The child's anchor constraint, or `null`.\n * @param horizontal - `true` for {@link HBox} (cross = vertical: NORTH=lead,\n * SOUTH=trail), `false` for {@link VBox} (cross = horizontal: WEST=lead,\n * EAST=trail).\n * @returns `\"lead\"`/`\"trail\"` for an anchor with a cross component, else `null`.\n */\n private crossAnchorEdge(anchor: AnchorType | null, horizontal: boolean): \"lead\" | \"trail\" | null {\n if (anchor === null) {\n return null;\n }\n\n if (horizontal) {\n if (anchor === AnchorType.NORTH || anchor === AnchorType.NORTHWEST || anchor === AnchorType.NORTHEAST) {\n return \"lead\";\n }\n\n if (anchor === AnchorType.SOUTH || anchor === AnchorType.SOUTHWEST || anchor === AnchorType.SOUTHEAST) {\n return \"trail\";\n }\n\n return null;\n }\n\n if (anchor === AnchorType.WEST || anchor === AnchorType.NORTHWEST || anchor === AnchorType.SOUTHWEST) {\n return \"lead\";\n }\n\n if (anchor === AnchorType.EAST || anchor === AnchorType.NORTHEAST || anchor === AnchorType.SOUTHEAST) {\n return \"trail\";\n }\n\n return null;\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { BoxLayout, BoxLayoutOptions } from \"~/layout/BoxLayout.js\";\nimport type { ResolvedPlacement } from \"~/layout/LayoutManager.js\";\nimport { FillType } from \"~/layout/FillType.js\";\nimport { Size } from \"~/primitive/Size.js\";\nimport { Insets } from \"~/primitive/Insets.js\";\nimport { Component } from \"~/core/Component.js\";\nimport { callable } from \"~/core/Callable.js\";\n\n/**\n * Construction-time options for {@link HBox}.\n *\n * @remarks `mode` selects the sizing strategy along the horizontal axis.\n * `\"preferred\"` (the default) honours each child's preferred width and\n * supports `weight` cells. `\"equal\"` divides the container width equally\n * and ignores `weight`. `mode` is independent of `stretching` (the cross-axis\n * fill): `stretching` defaults to `false` in both modes, so `\"equal\"` divides\n * the width but leaves children at their preferred height unless\n * `stretching: true` is passed.\n *\n * @category Layouts\n */\nexport interface HBoxOptions extends BoxLayoutOptions {}\n\n/**\n * A layout manager that places children in a single horizontal row. The\n * `mode` option selects between preferred-width sequencing (with weight-cell\n * support) and equal-width division of the container.\n *\n * @category Layouts\n */\nclass HBox extends BoxLayout {\n\n private _defaultComponentWidth: number = 100;\n\n /**\n * Returns the row's baseline (the maximum child text baseline) measured from\n * the container's content-top, so a baseline-aware parent aligns this HBox\n * container by the same baseline its own children align to — rather than\n * auto-centring the whole container.\n *\n * @returns The inner baseline offset in pixels, or `null` when `itemAlign`\n * is not `\"baseline\"` (a centred/edge-aligned or stretched row exposes no\n * shared baseline) or when no child reports a baseline.\n */\n getContentBaseline(): number | null {\n if (this._itemAlign !== \"baseline\") {\n return null;\n }\n\n const container = this.getContainer();\n if (!container) {\n return null;\n }\n\n const heights: number[] = [];\n const baselines: Array<number | null> = [];\n\n for (const component of container.getLaidOutComponents()) {\n const size = component.getPreferredSize();\n heights.push(size ? size.height : 0);\n baselines.push(component.getBaseline());\n }\n\n return this.computeRowMetrics(heights, baselines).rowAscent;\n }\n\n /**\n * Returns the preferred size. In `\"preferred\"` mode this is the sum\n * of child widths plus spacing. In `\"equal\"` mode it is\n * `count * (maxChildWidth + spacing) - spacing`. Row height in both\n * modes is the baseline-aware row height of the children.\n *\n * @returns The preferred `{width, height}`, or `null` if no container is attached.\n */\n getPreferredSize(): Size | null {\n let container = this.getContainer();\n if (!container) {\n return null;\n }\n\n let perimeterSize = container.getPerimeterSize();\n let components = container.getLaidOutComponents();\n let width = perimeterSize.left + perimeterSize.right;\n\n const heights: number[] = [];\n const baselines: Array<number | null> = [];\n\n if (this._mode === \"equal\") {\n let maxChildWidth = 0;\n\n for (let idx in components) {\n let component = components[idx];\n let size = component.getPreferredSize();\n\n if (size) {\n maxChildWidth = Math.max(maxChildWidth, size.width);\n heights.push(size.height);\n baselines.push(component.getBaseline());\n }\n }\n\n width += components.length * (maxChildWidth + this._spacing) - this._spacing;\n } else {\n for (let idx in components) {\n let component = components[idx];\n let size = component.getPreferredSize();\n\n if (size) {\n width += size.width;\n heights.push(size.height);\n baselines.push(component.getBaseline());\n }\n }\n\n width += this._spacing * (components.length - 1);\n }\n\n let height = this.computeRowHeight(heights, baselines);\n\n height += perimeterSize.top + perimeterSize.bottom;\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Returns the minimum size. In `\"preferred\"` mode this is the sum of\n * child min widths plus spacing. In `\"equal\"` mode it is\n * `count * (maxChildMinWidth + spacing) - spacing`. Row height in\n * both modes is the baseline-aware row height of the children's\n * minimums.\n *\n * @returns The minimum `{width, height}`, or `null` if no container is attached.\n */\n getMinSize(): Size | null {\n let container = this.getContainer();\n if (!container) {\n return null;\n }\n\n let perimeterSize = container.getPerimeterSize();\n let components = container.getLaidOutComponents();\n let width = perimeterSize.left + perimeterSize.right;\n\n const heights: number[] = [];\n const baselines: Array<number | null> = [];\n\n if (this._mode === \"equal\") {\n let maxChildMinWidth = 0;\n\n for (let idx in components) {\n let component = components[idx];\n let size = component.getMinSize();\n\n if (size) {\n maxChildMinWidth = Math.max(maxChildMinWidth, size.width);\n heights.push(size.height);\n baselines.push(component.getBaseline());\n }\n }\n\n width += components.length * (maxChildMinWidth + this._spacing) - this._spacing;\n } else {\n for (let idx in components) {\n let component = components[idx];\n let size = component.getMinSize();\n\n if (size) {\n width += size.width;\n heights.push(size.height);\n baselines.push(component.getBaseline());\n }\n }\n\n width += this._spacing * (components.length - 1);\n }\n\n let height = this.computeRowHeight(heights, baselines);\n\n height += perimeterSize.top + perimeterSize.bottom;\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Returns the maximum size the row can usefully occupy. Along the main axis\n * (width) it sums the children's *maximum* widths plus spacing; in `\"equal\"`\n * mode it is `count * maxChildMaxWidth` plus spacing, since every cell shares\n * the widest child's allowance. The cross axis (height) takes the *largest*\n * child maximum — the tallest a child permits the row to grow to. A child\n * whose maximum is `null` or at the unbounded sentinel makes that axis\n * unbounded.\n *\n * @returns The maximum `{width, height}`, or `null` if no container is attached.\n */\n getMaxSize(): Size | null {\n return this.aggregateMaxSize(true);\n }\n\n /**\n * Computes the children's combined minSize along this manager's geometry.\n * In `\"preferred\"` mode width is the sum of per-child `minSize.width`\n * plus spacing. In `\"equal\"` mode width is\n * `count * maxChildMinWidth + spacing*(n-1)` (HBox distributes width\n * equally so the per-cell floor is the max of every child's min width).\n * Height in both modes is the max per-child `minSize.height`. Used by\n * `doLayout` to inflate the working size when the host has opted into\n * `setOverflowing` on the corresponding axis.\n *\n * @returns The total min-size; `{ width: 0, height: 0 }` when the\n * container is absent or has no children.\n */\n protected computeTotalMinSize(): Size {\n const container = this.getContainer();\n if (!container) {\n return { width: 0, height: 0 };\n }\n\n const components = container.getLaidOutComponents();\n if (components.length === 0) {\n return { width: 0, height: 0 };\n }\n\n let height = 0;\n\n if (this._mode === \"equal\") {\n let maxWidth = 0;\n\n for (const component of components) {\n const min = component.getMinSize();\n if (min) {\n maxWidth = Math.max(maxWidth, min.width);\n height = Math.max(height, min.height);\n }\n }\n\n return {\n width: components.length * (maxWidth + this._spacing) - this._spacing,\n height,\n };\n }\n\n let width = this._spacing * (components.length - 1);\n\n for (const component of components) {\n const min = component.getMinSize();\n if (min) {\n width += min.width;\n height = Math.max(height, min.height);\n }\n }\n\n return { width, height };\n }\n\n /**\n * Lays out the children left-to-right, dispatching to `layoutEqualMode` or\n * `layoutPreferredMode` per the sizing mode after inflating the working\n * size for any scroll-enabled axis.\n */\n doLayout(): void {\n const container = this.getContainer();\n if (!container) {\n return;\n }\n\n const innerSize = container.getInnerSize();\n if (!innerSize) {\n return;\n }\n\n const components = container.getLaidOutComponents();\n const containerInsets = container.getContentInsets();\n const spacing = this.getComponentSpacing();\n\n // Universal scroll: when the host has opted into per-axis overflow, lay\n // out against the children's combined minSize so trailing children land\n // past the viewport and the host's CSS `overflow: auto` scrolls.\n // `innerSize` stays the real viewport for equal mode's overflow test.\n const containerSize = this.inflateForOverflow(innerSize);\n\n let placements: ResolvedPlacement[];\n\n if (this._mode === \"equal\") {\n placements = this.layoutEqualMode(components, innerSize, containerSize, containerInsets, spacing);\n } else {\n placements = this.layoutPreferredMode(components, containerSize, containerInsets, spacing);\n }\n\n this.commitPlacements(placements);\n\n this.reserveContentFrame();\n }\n\n /**\n * Places children in equal-width cells. Every cell takes the same width\n * (see {@link HBox.computeEqualCellWidth}); when stretching, cells fill the\n * container height, otherwise children keep their preferred height and are\n * baseline-aligned within the row.\n *\n * @param components - The children to place, in order.\n * @param innerSize - The host's real inner size (pre-inflation), used to\n * measure the equal share against the true viewport.\n * @param containerSize - The working size, possibly inflated for overflow.\n * @param insets - The container's content insets.\n * @param spacing - Inter-child spacing in pixels.\n * @returns The resolved placements, ready for {@link LayoutManager.commitPlacements}.\n */\n private layoutEqualMode(components: Component[], innerSize: Size, containerSize: Size, insets: Insets, spacing: number): ResolvedPlacement[] {\n const cellWidth = this.computeEqualCellWidth(components, innerSize.width, spacing);\n\n if (this.isStretching()) {\n const y = insets.getTop();\n let x = insets.getLeft();\n const placements: ResolvedPlacement[] = [];\n\n for (const component of components) {\n placements.push({ component, ...this.resolveBounds(component, x, y, cellWidth, containerSize.height, FillType.BOTH) });\n\n x += cellWidth + spacing;\n }\n\n return placements;\n }\n\n const heights: number[] = [];\n const baselines: Array<number | null> = [];\n\n for (const component of components) {\n const size = component.getPreferredSize();\n\n heights.push(size ? size.height : 0);\n baselines.push(component.getBaseline());\n }\n\n const { rowAscent, rowDescent } = this.computeRowMetrics(heights, baselines);\n\n // Match the equal-stretch band exactly: the stretch branch fills\n // containerSize.height from insets.top with no bottom-inset subtraction,\n // so an EAST/fill align-self child reaches the same trailing edge.\n const crossLead = insets.getTop();\n const crossExtent = containerSize.height;\n\n let x = insets.getLeft();\n const placements: ResolvedPlacement[] = [];\n\n for (let idx = 0; idx < components.length; idx += 1) {\n const component = components[idx];\n\n const cross = this.crossPlacement(component, crossLead, crossExtent, heights[idx], true);\n\n if (cross) {\n placements.push({ component, ...this.resolveBounds(component, x, cross.offset, cellWidth, cross.extent, FillType.BOTH) });\n } else if (this._itemAlign === \"start\" || this._itemAlign === \"center\" || this._itemAlign === \"end\") {\n const y = crossLead + this.crossItemOffset(heights[idx], crossExtent);\n\n placements.push({ component, ...this.resolveBounds(component, x, y, cellWidth, heights[idx], FillType.BOTH) });\n } else {\n const y = this.rowChildY(insets.getTop(), heights[idx], baselines[idx], rowAscent, rowDescent);\n\n placements.push({ component, ...this.resolveBounds(component, x, y, cellWidth, heights[idx], FillType.BOTH) });\n }\n\n x += cellWidth + spacing;\n }\n\n return placements;\n }\n\n /**\n * Computes the shared cell width for equal mode: the equal share of the\n * inner width, floored at the widest child's min width.\n *\n * @param components - The children sharing the row.\n * @param innerWidth - The host's real inner width (pre-inflation).\n * @param spacing - Inter-child spacing in pixels.\n * @returns The width every equal-mode cell receives.\n *\n * @remarks Three cases drive the floor: (1) the share clears the widest\n * child's min width → the row fits, divide equally; (2) the share is below\n * the min floor, the host scrolls on this axis, and `overflowSizing` is\n * `\"preferred\"` → every cell takes the widest child's preferred width so\n * cells regain preferred size instead of sticking at min while scrolling;\n * (3) otherwise → clamp to the min floor (a non-scrolling host's\n * `overflow: hidden` clips the surplus).\n */\n private computeEqualCellWidth(components: Component[], innerWidth: number, spacing: number): number {\n let maxChildMinWidth = 0;\n let maxChildPreferredWidth = 0;\n\n for (const component of components) {\n const min = component.getMinSize();\n if (min) {\n maxChildMinWidth = Math.max(maxChildMinWidth, min.width);\n }\n\n const pref = component.getPreferredSize();\n if (pref) {\n maxChildPreferredWidth = Math.max(maxChildPreferredWidth, pref.width);\n }\n }\n\n const equalShare = (innerWidth - spacing * (components.length - 1)) / components.length;\n\n if (equalShare >= maxChildMinWidth) {\n return equalShare;\n }\n\n if (this.isOverflowingX() && this._overflowSizing === \"preferred\") {\n return Math.max(maxChildMinWidth, maxChildPreferredWidth);\n }\n\n return maxChildMinWidth;\n }\n\n /**\n * Places children at their preferred widths. Weight cells split the space\n * left after the non-weighted children; when the row overflows, the\n * non-weighted children shrink proportionally toward their min widths.\n * Children keep their preferred height (or fill the row height when\n * stretching) and are baseline-aligned unless stretching.\n *\n * @param components - The children to place, in order.\n * @param containerSize - The working size, possibly inflated for overflow.\n * @param insets - The container's content insets.\n * @param spacing - Inter-child spacing in pixels.\n * @returns The resolved placements, ready for {@link LayoutManager.commitPlacements}.\n */\n private layoutPreferredMode(components: Component[], containerSize: Size, insets: Insets, spacing: number): ResolvedPlacement[] {\n const { totalWeight, fixedPreferred, fixedMin } = this.measureFixedWidths(components, spacing);\n\n const { remaining: remainingWidth, shrinkRatio } = this.computeShrink(\n fixedPreferred,\n fixedMin,\n containerSize.width,\n this.isOverflowingX()\n );\n\n const widths: number[] = [];\n const heights: number[] = [];\n const baselines: Array<number | null> = [];\n\n for (const component of components) {\n const weight = this.getLayoutConstraints(component)?.weight ?? 0;\n const size = component.getPreferredSize();\n const minSize = component.getMinSize();\n const maxSize = component.getMaxSize();\n\n widths.push(this.resolveChildWidth(size, minSize, maxSize, weight, totalWeight, remainingWidth, shrinkRatio));\n\n // Cross-axis (height): give the child the row's available height —\n // the full inner height when stretching or sizeless, otherwise its\n // preferred height capped to the row. Cap to the child's maximum, but\n // do NOT floor to its minimum: enforcing the minimum here would\n // dogmatically inflate a child back up to its content size even when\n // the row is shorter, defeating a scrolling/clipping child. The\n // child's own setHeight → clampHeight applies its minimum (its\n // content minimum for a general component, or nothing for a Panel,\n // which fits its allocation and scrolls). When the host opts into\n // vertical scroll, `containerSize` is already inflated to the content\n // extent upstream, so `min(pref, containerSize)` still yields the full\n // height without a floor here.\n let height: number;\n\n if (!size || this.isStretching()) {\n height = containerSize.height;\n } else {\n height = Math.min(size.height, containerSize.height);\n }\n\n if (maxSize) {\n height = Math.min(height, maxSize.height);\n }\n\n heights.push(height);\n\n baselines.push(component.getBaseline());\n }\n\n // Stretching forces every child to fill the row vertically, which makes\n // baseline alignment meaningless — fall back to top-alignment. rowAscent\n // is driven only by text-bearing children; tall null-baseline children\n // (a List, TextArea, etc.) must NOT drag the baseline down or every text\n // label in the row would be pushed off the top.\n const { rowAscent, rowDescent } = this.isStretching()\n ? { rowAscent: null, rowDescent: 0 }\n : this.computeRowMetrics(heights, baselines);\n\n // Sum the placed main extents to find the trailing slack, then ask the\n // shared helper how to distribute it. Weight cells already consume all\n // slack, so justify is a no-op when any are present.\n let lead = 0;\n let gap = 0;\n\n if (totalWeight === 0) {\n let contentWidth = spacing * (components.length - 1);\n\n for (const w of widths) {\n contentWidth += w;\n }\n\n const innerWidth = containerSize.width - (insets.getLeft() + insets.getRight());\n\n ({ lead, gap } = this.justifyOffsets(contentWidth, innerWidth, components.length));\n }\n\n // Cross band for per-child align-self: the same vertical band the\n // stretch path fills, trimmed by both insets.\n const crossLead = insets.getTop();\n const crossExtent = containerSize.height - (insets.getTop() + insets.getBottom());\n\n let x = insets.getLeft() + lead;\n const placements: ResolvedPlacement[] = [];\n\n for (let idx = 0; idx < components.length; idx += 1) {\n const component = components[idx];\n\n // Align-self sizes from the child's *preferred* height (capped to the\n // band + max), independent of the stretch-inflated heights[idx], so an\n // anchored child shrinks-and-anchors even under global stretching.\n const pref = component.getPreferredSize();\n const maxSize = component.getMaxSize();\n let naturalCross = pref ? Math.min(pref.height, crossExtent) : crossExtent;\n\n if (maxSize) {\n naturalCross = Math.min(naturalCross, maxSize.height);\n }\n\n const cross = this.crossPlacement(component, crossLead, crossExtent, naturalCross, true);\n\n if (cross) {\n placements.push({ component, ...this.resolveBounds(component, x, cross.offset, widths[idx], cross.extent, FillType.BOTH) });\n } else if (this._itemAlign === \"start\" || this._itemAlign === \"center\" || this._itemAlign === \"end\") {\n const y = crossLead + this.crossItemOffset(heights[idx], crossExtent);\n\n placements.push({ component, ...this.resolveBounds(component, x, y, widths[idx], heights[idx], FillType.BOTH) });\n } else {\n const y = this.rowChildY(insets.getTop(), heights[idx], baselines[idx], rowAscent, rowDescent);\n\n placements.push({ component, ...this.resolveBounds(component, x, y, widths[idx], heights[idx], FillType.BOTH) });\n }\n\n // Advance by the resolved width, not getWidth(): the gap is measured\n // against the same extent contentWidth summed, so a placeComponent\n // clamp must not skew the trailing edge.\n x += widths[idx];\n x += spacing + gap;\n }\n\n return placements;\n }\n\n /**\n * Sums the non-weighted children's preferred and minimum widths (each\n * including inter-child spacing) and the total weight of the weight cells.\n *\n * @param components - The children sharing the row.\n * @param spacing - Inter-child spacing in pixels.\n * @returns `totalWeight` of the weight cells, plus the `fixedPreferred` and\n * `fixedMin` width totals of the non-weighted children.\n */\n private measureFixedWidths(components: Component[], spacing: number): { totalWeight: number; fixedPreferred: number; fixedMin: number } {\n let totalWeight = 0;\n let fixedPreferred = spacing * (components.length - 1);\n let fixedMin = spacing * (components.length - 1);\n\n for (const component of components) {\n const weight = this.getLayoutConstraints(component)?.weight ?? 0;\n\n if (weight > 0) {\n totalWeight += weight;\n } else {\n const size = component.getPreferredSize();\n const minSize = component.getMinSize();\n\n fixedPreferred += this.preferredChildWidth(size, minSize);\n fixedMin += minSize ? minSize.width : 0;\n }\n }\n\n return { totalWeight, fixedPreferred, fixedMin };\n }\n\n /**\n * Resolves a non-weighted child's preferred width, falling back through min\n * width to `_defaultComponentWidth`.\n *\n * @param size - The child's preferred size, or `null`.\n * @param minSize - The child's minimum size, or `null`.\n * @returns The width the child contributes before shrinking.\n *\n * @remarks Nullish-coalesce, not `||`: a component with an explicit\n * preferred width of 0 (e.g. an empty `Text` label) must contribute 0, not\n * fall through to `_defaultComponentWidth` and inflate the row's fixed total\n * past the container, which would force the shrink path to squeeze every\n * non-weighted child (including glyphs) toward its min size. The\n * `minSize.width > 0` guard prevents `LayoutManager._defaultMinSize =\n * {0,0}` from short-circuiting the chain into a 0 width (which would land a\n * layout-managed Table on width 0 even though no preferred size was set).\n *\n * The result is floored at the child's own min width: a child placed at\n * `max(preferred, min)` (see {@link HBox.resolveChildWidth}) must reserve\n * that same width in the fixed total, or a child reporting `preferred < min`\n * (a `min ≤ preferred` invariant violation) would be under-reserved and push\n * the weighted cells out, overflowing the row.\n */\n private preferredChildWidth(size: Size | null, minSize: Size | null): number {\n const preferred = (size ? size.width : undefined)\n ?? (minSize && minSize.width > 0 ? minSize.width : undefined)\n ?? this._defaultComponentWidth;\n\n return minSize ? Math.max(preferred, minSize.width) : preferred;\n }\n\n /**\n * Resolves a child's final width within the row, clamped to its min/max —\n * the minimum wins when the two conflict. Weight cells take a share of\n * `remainingWidth`; non-weighted children take their preferred width\n * reduced by the shrink ratio toward their min width.\n *\n * @param size - The child's preferred size, or `null`.\n * @param minSize - The child's minimum size, or `null`.\n * @param maxSize - The child's maximum size, or `null`.\n * @param weight - The child's weight constraint (0 when non-weighted).\n * @param totalWeight - The summed weight of all weight cells.\n * @param remainingWidth - The space available to weight cells.\n * @param shrinkRatio - How far (0–1) non-weighted children shrink to min.\n * @returns The child's width.\n */\n private resolveChildWidth(size: Size | null, minSize: Size | null, maxSize: Size | null, weight: number, totalWeight: number, remainingWidth: number, shrinkRatio: number): number {\n let width: number;\n\n if (weight > 0 && totalWeight > 0) {\n width = (weight / totalWeight) * remainingWidth;\n } else {\n const pref = this.preferredChildWidth(size, minSize);\n const min = minSize ? minSize.width : 0;\n\n width = pref - shrinkRatio * (pref - min);\n }\n\n if (maxSize) {\n width = Math.min(width, maxSize.width);\n }\n\n if (minSize) {\n width = Math.max(width, minSize.width);\n }\n\n return width;\n }\n\n /**\n * Computes a child's y within the row, aligning text-bearing children on the\n * shared baseline and centring null-baseline children in the text line.\n *\n * @param top - The row's content-top (inside the insets).\n * @param height - The child's height.\n * @param baseline - The child's baseline, or `null` for graphical/replaced children.\n * @param rowAscent - The row's text baseline, or `null` when no child reports one.\n * @param rowDescent - The row's text descent.\n * @returns The child's y position.\n */\n private rowChildY(top: number, height: number, baseline: number | null, rowAscent: number | null, rowDescent: number): number {\n if (rowAscent === null) {\n return top;\n }\n\n if (baseline !== null) {\n return top + (rowAscent - baseline);\n }\n\n return top + this.nullChildY(height, rowAscent, rowDescent);\n }\n}\n\nconst HBoxCallable = callable(HBox);\ntype HBoxCallable = HBox;\nexport {\n HBox as _HBox,\n HBoxCallable as HBox\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { FillType } from \"~/layout/FillType.js\";\nimport { Size, UNBOUNDED, isUnbounded } from \"~/primitive/Size.js\";\nimport { Insets } from \"~/primitive/Insets.js\";\nimport { Component } from \"~/core/Component.js\";\nimport { BoxLayout, BoxLayoutOptions } from \"~/layout/BoxLayout.js\";\nimport type { ResolvedPlacement } from \"~/layout/LayoutManager.js\";\nimport { callable } from \"~/core/Callable.js\";\n\n/**\n * Construction-time options for {@link VBox}.\n *\n * @remarks `mode` selects the sizing strategy along the vertical axis.\n * `\"preferred\"` (the default) honours each child's preferred height and\n * supports `weight` cells. `\"equal\"` divides the container height equally\n * and ignores `weight`. `mode` is independent of `stretching` (the cross-axis\n * fill): `stretching` defaults to `false` in both modes, so `\"equal\"` divides\n * the height but leaves children at their preferred width unless\n * `stretching: true` is passed.\n *\n * @category Layouts\n */\nexport interface VBoxOptions extends BoxLayoutOptions {}\n\n/**\n * A layout manager that places children in a single vertical column. The\n * `mode` option selects between preferred-height sequencing (with weight-cell\n * support) and equal-height division of the container.\n *\n * @category Layouts\n */\nclass VBox extends BoxLayout {\n\n private _defaultComponentHeight: number = 100;\n\n /**\n * Returns the column's baseline — the first laid-out child's baseline,\n * measured from the container's content-top — so a baseline-aware parent\n * aligns this VBox container by its first row's text baseline rather than\n * auto-centring the whole container.\n *\n * @returns The first child's baseline offset in pixels, or `null` when there\n * is no container, no laid-out children, or the first child reports no\n * baseline of its own.\n *\n * @remarks Forwards the **first** child's baseline verbatim — unlike\n * {@link HBox}, which takes the maximum baseline across the row's children.\n * A column has a single well-defined first row, so forwarding it (including\n * a `null` when that first row is graphical) is the most predictable\n * contract. The first child stacks at the container's content-top in every\n * mode, so its own baseline is already content-relative — `Component`'s\n * `getBaseline` then adds the container's chrome. Unlike `HBox`, this is not\n * disabled while stretching: VBox `stretching` fills the cross (width) axis\n * and leaves each child's height and intrinsic baseline untouched.\n */\n getContentBaseline(): number | null {\n const container = this.getContainer();\n if (!container) {\n return null;\n }\n\n const components = container.getLaidOutComponents();\n if (components.length === 0) {\n return null;\n }\n\n return components[0].getBaseline();\n }\n\n /**\n * Returns the preferred size. In `\"preferred\"` mode this is the widest\n * child width and the sum of child heights plus spacing. In `\"equal\"`\n * mode height is `count * (maxChildHeight + spacing) - spacing`.\n *\n * @returns The preferred `{width, height}`, or `null` if no container is attached.\n */\n getPreferredSize(): Size | null {\n let container = this.getContainer();\n if (!container) {\n return null;\n }\n\n let perimeterSize = container.getPerimeterSize();\n let components = container.getLaidOutComponents();\n\n if (this._mode === \"equal\") {\n let innerWidth = 0;\n let innerHeight = 0;\n\n for (let idx in components) {\n let component = components[idx];\n let size = component.getPreferredSize();\n\n if (size) {\n innerWidth = Math.max(innerWidth, size.width);\n innerHeight = Math.max(innerHeight, size.height);\n }\n }\n\n const width = innerWidth + perimeterSize.left + perimeterSize.right;\n const height = components.length * (innerHeight + this._spacing) - this._spacing\n + perimeterSize.top + perimeterSize.bottom;\n\n return { width, height };\n }\n\n let width = UNBOUNDED;\n let height = perimeterSize.top + perimeterSize.bottom;\n\n for (let idx in components) {\n let component = components[idx];\n let size = component.getPreferredSize();\n\n if (size) {\n width = isUnbounded(width) ? Math.min(width, size.width) : Math.max(width, size.width);\n height += size.height;\n }\n }\n\n width += perimeterSize.left + perimeterSize.right;\n height += this._spacing * (components.length - 1);\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Returns the minimum size. In `\"preferred\"` mode this is the widest\n * child minimum width and the sum of child minimum heights plus\n * spacing. In `\"equal\"` mode height is\n * `count * (maxChildMinHeight + spacing) - spacing`.\n *\n * @returns The minimum `{width, height}`, or `null` if no container is attached.\n */\n getMinSize(): Size | null {\n let container = this.getContainer();\n if (!container) {\n return null;\n }\n\n let perimeterSize = container.getPerimeterSize();\n let components = container.getLaidOutComponents();\n\n if (this._mode === \"equal\") {\n let innerWidth = 0;\n let innerHeight = 0;\n\n for (let idx in components) {\n let component = components[idx];\n let size = component.getMinSize();\n\n if (size) {\n innerWidth = Math.max(innerWidth, size.width);\n innerHeight = Math.max(innerHeight, size.height);\n }\n }\n\n const width = innerWidth + perimeterSize.left + perimeterSize.right;\n const height = components.length * (innerHeight + this._spacing) - this._spacing\n + perimeterSize.top + perimeterSize.bottom;\n\n return { width, height };\n }\n\n let width = 0;\n let height = perimeterSize.top + perimeterSize.bottom;\n\n for (let idx in components) {\n let component = components[idx];\n let size = component.getMinSize();\n\n if (size) {\n width = Math.max(width, size.width);\n height += size.height;\n }\n }\n\n width += perimeterSize.left + perimeterSize.right;\n height += this._spacing * (components.length - 1);\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Returns the maximum size the column can usefully occupy. Along the main\n * axis (height) it sums the children's *maximum* heights plus spacing; in\n * `\"equal\"` mode it is `count * maxChildMaxHeight` plus spacing, since every\n * cell shares the tallest child's allowance. The cross axis (width) takes\n * the *largest* child maximum — the widest a child permits the column to\n * grow to. A child whose maximum is `null` or at the unbounded sentinel\n * makes that axis unbounded.\n *\n * @returns The maximum `{width, height}`, or `null` if no container is attached.\n */\n getMaxSize(): Size | null {\n return this.aggregateMaxSize(false);\n }\n\n /**\n * Computes the children's combined minSize along this manager's geometry.\n * In `\"preferred\"` mode height is the sum of per-child `minSize.height`\n * plus spacing. In `\"equal\"` mode height is\n * `count * maxChildMinHeight + spacing*(n-1)` (VBox distributes height\n * equally so the per-cell floor is the max of every child's min height).\n * Width in both modes is the max per-child `minSize.width`. Used by\n * `doLayout` to inflate the working size when the host has opted into\n * `setOverflowing` on the corresponding axis.\n *\n * @returns The total min-size; `{ width: 0, height: 0 }` when the\n * container is absent or has no children.\n */\n protected computeTotalMinSize(): Size {\n const container = this.getContainer();\n if (!container) {\n return { width: 0, height: 0 };\n }\n\n const components = container.getLaidOutComponents();\n if (components.length === 0) {\n return { width: 0, height: 0 };\n }\n\n let width = 0;\n\n if (this._mode === \"equal\") {\n let maxHeight = 0;\n\n for (const component of components) {\n const min = component.getMinSize();\n if (min) {\n width = Math.max(width, min.width);\n maxHeight = Math.max(maxHeight, min.height);\n }\n }\n\n return {\n width,\n height: components.length * (maxHeight + this._spacing) - this._spacing,\n };\n }\n\n let height = this._spacing * (components.length - 1);\n\n for (const component of components) {\n const min = component.getMinSize();\n if (min) {\n width = Math.max(width, min.width);\n height += min.height;\n }\n }\n\n return { width, height };\n }\n\n /**\n * Lays out the children top-to-bottom, dispatching to `layoutEqualMode` or\n * `layoutPreferredMode` per the sizing mode after inflating the working\n * size for any scroll-enabled axis.\n */\n doLayout(): void {\n const container = this.getContainer();\n if (!container) {\n return;\n }\n\n const innerSize = container.getInnerSize();\n if (!innerSize) {\n return;\n }\n\n const components = container.getLaidOutComponents();\n const containerInsets = container.getContentInsets();\n const spacing = this.getComponentSpacing();\n\n // Universal scroll: when the host has opted into per-axis overflow, lay\n // out against the children's combined minSize so trailing children land\n // past the viewport and the host's CSS `overflow: auto` scrolls.\n // `innerSize` stays the real viewport for equal mode's overflow test.\n const containerSize = this.inflateForOverflow(innerSize);\n\n let placements: ResolvedPlacement[];\n\n if (this._mode === \"equal\") {\n placements = this.layoutEqualMode(components, innerSize, containerSize, containerInsets, spacing);\n } else {\n placements = this.layoutPreferredMode(components, containerSize, containerInsets, spacing);\n }\n\n this.commitPlacements(placements);\n\n this.reserveContentFrame();\n }\n\n /**\n * Places children in equal-height cells stacked top-to-bottom. Every cell\n * takes the same height (see {@link VBox.computeEqualCellHeight}); when\n * stretching, cells fill the container width, otherwise children keep their\n * preferred width and are left-aligned within the column.\n *\n * @param components - The children to place, in order.\n * @param innerSize - The host's real inner size (pre-inflation), used to\n * measure the equal share against the true viewport.\n * @param containerSize - The working size, possibly inflated for overflow.\n * @param insets - The container's content insets.\n * @param spacing - Inter-child spacing in pixels.\n * @returns The resolved placements, ready for {@link LayoutManager.commitPlacements}.\n */\n private layoutEqualMode(components: Component[], innerSize: Size, containerSize: Size, insets: Insets, spacing: number): ResolvedPlacement[] {\n const cellHeight = this.computeEqualCellHeight(components, innerSize.height, spacing);\n\n const x = insets.getLeft();\n let y = insets.getTop();\n\n if (this.isStretching()) {\n const cellWidth = containerSize.width;\n const placements: ResolvedPlacement[] = [];\n\n for (const component of components) {\n placements.push({ component, ...this.resolveBounds(component, x, y, cellWidth, cellHeight, FillType.BOTH) });\n\n y += cellHeight + spacing;\n }\n\n return placements;\n }\n\n // Match the equal-stretch band exactly: the stretch branch fills\n // containerSize.width from insets.left with no right-inset subtraction,\n // so an EAST/fill align-self child reaches the same trailing edge.\n const crossLead = insets.getLeft();\n const crossExtent = containerSize.width;\n const placements: ResolvedPlacement[] = [];\n\n for (const component of components) {\n const size = component.getPreferredSize();\n const width = size ? size.width : 0;\n\n const cross = this.crossPlacement(component, crossLead, crossExtent, width, false);\n\n if (cross) {\n placements.push({ component, ...this.resolveBounds(component, cross.offset, y, cross.extent, cellHeight, FillType.BOTH) });\n } else if (this._itemAlign === \"start\" || this._itemAlign === \"center\" || this._itemAlign === \"end\") {\n const cx = crossLead + this.crossItemOffset(width, crossExtent);\n\n placements.push({ component, ...this.resolveBounds(component, cx, y, width, cellHeight, FillType.BOTH) });\n } else {\n placements.push({ component, ...this.resolveBounds(component, x, y, width, cellHeight, FillType.BOTH) });\n }\n\n y += cellHeight + spacing;\n }\n\n return placements;\n }\n\n /**\n * Computes the shared cell height for equal mode: the equal share of the\n * inner height, floored at the tallest child's min height.\n *\n * @param components - The children sharing the column.\n * @param innerHeight - The host's real inner height (pre-inflation).\n * @param spacing - Inter-child spacing in pixels.\n * @returns The height every equal-mode cell receives.\n *\n * @remarks Three cases drive the floor: (1) the share clears the tallest\n * child's min height → the column fits, divide equally; (2) the share is\n * below the min floor, the host scrolls on this axis, and `overflowSizing`\n * is `\"preferred\"` → every cell takes the tallest child's preferred height\n * so cells regain preferred size instead of sticking at min while\n * scrolling; (3) otherwise → clamp to the min floor (a non-scrolling host's\n * `overflow: hidden` clips the surplus).\n */\n private computeEqualCellHeight(components: Component[], innerHeight: number, spacing: number): number {\n let maxChildMinHeight = 0;\n let maxChildPreferredHeight = 0;\n\n for (const component of components) {\n const min = component.getMinSize();\n if (min) {\n maxChildMinHeight = Math.max(maxChildMinHeight, min.height);\n }\n\n const pref = component.getPreferredSize();\n if (pref) {\n maxChildPreferredHeight = Math.max(maxChildPreferredHeight, pref.height);\n }\n }\n\n const equalShare = (innerHeight - spacing * (components.length - 1)) / components.length;\n\n if (equalShare >= maxChildMinHeight) {\n return equalShare;\n }\n\n if (this.isOverflowingY() && this._overflowSizing === \"preferred\") {\n return Math.max(maxChildMinHeight, maxChildPreferredHeight);\n }\n\n return maxChildMinHeight;\n }\n\n /**\n * Places children at their preferred heights stacked top-to-bottom. Weight\n * cells split the space left after the non-weighted children; when the\n * column overflows, the non-weighted children shrink proportionally toward\n * their min heights. Children keep their preferred width, or fill the\n * container width when stretching.\n *\n * @param components - The children to place, in order.\n * @param containerSize - The working size, possibly inflated for overflow.\n * @param insets - The container's content insets.\n * @param spacing - Inter-child spacing in pixels.\n * @returns The resolved placements, ready for {@link LayoutManager.commitPlacements}.\n */\n private layoutPreferredMode(components: Component[], containerSize: Size, insets: Insets, spacing: number): ResolvedPlacement[] {\n const { totalWeight, fixedPreferred, fixedMin } = this.measureFixedHeights(components, spacing);\n\n const { remaining: remainingHeight, shrinkRatio } = this.computeShrink(\n fixedPreferred,\n fixedMin,\n containerSize.height,\n this.isOverflowingY()\n );\n\n // Pre-pass: resolve each child's height into an array so the trailing\n // slack can be measured before placement (mirrors HBox's widths[]).\n const heights: number[] = [];\n\n for (const component of components) {\n const weight = this.getLayoutConstraints(component)?.weight ?? 0;\n const size = component.getPreferredSize();\n const minSize = component.getMinSize();\n const maxSize = component.getMaxSize();\n\n heights.push(this.resolveChildHeight(size, minSize, maxSize, weight, totalWeight, remainingHeight, shrinkRatio));\n }\n\n // Sum the placed main extents to find the trailing slack, then ask the\n // shared helper how to distribute it. Weight cells already consume all\n // slack, so justify is a no-op when any are present.\n let lead = 0;\n let gap = 0;\n\n if (totalWeight === 0) {\n let contentHeight = spacing * (components.length - 1);\n\n for (const h of heights) {\n contentHeight += h;\n }\n\n const innerHeight = containerSize.height - (insets.getTop() + insets.getBottom());\n\n ({ lead, gap } = this.justifyOffsets(contentHeight, innerHeight, components.length));\n }\n\n // Cross band for per-child align-self: the horizontal band trimmed by\n // both insets. The default path keeps reading containerSize.width\n // (un-trimmed) to stay byte-identical with today's body.\n const crossLead = insets.getLeft();\n const crossExtent = containerSize.width - (insets.getLeft() + insets.getRight());\n\n const x = insets.getLeft();\n let y = insets.getTop() + lead;\n const placements: ResolvedPlacement[] = [];\n\n for (let idx = 0; idx < components.length; idx += 1) {\n const component = components[idx];\n const size = component.getPreferredSize();\n const maxSize = component.getMaxSize();\n\n // Cross-axis (width): give the child the column's available width —\n // the full inner width when stretching or sizeless, otherwise its\n // preferred width capped to the column. Cap to the child's maximum,\n // but do NOT floor to its minimum: enforcing the minimum here would\n // dogmatically inflate a child back up to its content size even when\n // the column is narrower, defeating a scrolling/clipping child. The\n // child's own setWidth → clampWidth applies its minimum (its content\n // minimum for a general component, or nothing for a Panel, which fits\n // its allocation and scrolls). When the host opts into horizontal\n // scroll, `containerSize` is already inflated to the content extent\n // upstream, so `min(pref, containerSize)` still yields the full width\n // without a floor here.\n let defaultWidth: number;\n\n if (!size || this.isStretching()) {\n defaultWidth = containerSize.width;\n } else {\n defaultWidth = Math.min(size.width, containerSize.width);\n }\n\n if (maxSize) {\n defaultWidth = Math.min(defaultWidth, maxSize.width);\n }\n\n // Align-self sizes from the child's *preferred* width (capped to the\n // band + max), independent of global stretching, so an anchored child\n // shrinks-and-anchors even when the column is stretching.\n let naturalWidth = size ? Math.min(size.width, crossExtent) : crossExtent;\n\n if (maxSize) {\n naturalWidth = Math.min(naturalWidth, maxSize.width);\n }\n\n const cross = this.crossPlacement(component, crossLead, crossExtent, naturalWidth, false);\n\n if (cross) {\n placements.push({ component, ...this.resolveBounds(component, cross.offset, y, cross.extent, heights[idx], FillType.BOTH) });\n } else if (this._itemAlign === \"start\" || this._itemAlign === \"center\" || this._itemAlign === \"end\") {\n const cx = crossLead + this.crossItemOffset(naturalWidth, crossExtent);\n\n placements.push({ component, ...this.resolveBounds(component, cx, y, naturalWidth, heights[idx], FillType.BOTH) });\n } else {\n placements.push({ component, ...this.resolveBounds(component, x, y, defaultWidth, heights[idx], FillType.BOTH) });\n }\n\n // Advance by the resolved height, not getHeight(): the gap is\n // measured against the same extent contentHeight summed, so a\n // placeComponent clamp must not skew the trailing edge.\n y += heights[idx];\n y += spacing + gap;\n }\n\n return placements;\n }\n\n /**\n * Sums the non-weighted children's preferred and minimum heights (each\n * including inter-child spacing) and the total weight of the weight cells.\n *\n * @param components - The children sharing the column.\n * @param spacing - Inter-child spacing in pixels.\n * @returns `totalWeight` of the weight cells, plus the `fixedPreferred` and\n * `fixedMin` height totals of the non-weighted children.\n */\n private measureFixedHeights(components: Component[], spacing: number): { totalWeight: number; fixedPreferred: number; fixedMin: number } {\n let totalWeight = 0;\n let fixedPreferred = spacing * (components.length - 1);\n let fixedMin = spacing * (components.length - 1);\n\n for (const component of components) {\n const weight = this.getLayoutConstraints(component)?.weight ?? 0;\n\n if (weight > 0) {\n totalWeight += weight;\n } else {\n const size = component.getPreferredSize();\n const minSize = component.getMinSize();\n\n fixedPreferred += this.preferredChildHeight(size, minSize);\n fixedMin += minSize ? minSize.height : 0;\n }\n }\n\n return { totalWeight, fixedPreferred, fixedMin };\n }\n\n /**\n * Resolves a non-weighted child's preferred height, falling back through min\n * height to `_defaultComponentHeight`.\n *\n * @param size - The child's preferred size, or `null`.\n * @param minSize - The child's minimum size, or `null`.\n * @returns The height the child contributes before shrinking.\n *\n * @remarks Nullish-coalesce, not `||`: a component with an explicit\n * preferred height of 0 must contribute 0, not fall through to\n * `_defaultComponentHeight`. The `minSize.height > 0` guard prevents\n * `LayoutManager._defaultMinSize = {0,0}` from short-circuiting the chain\n * into a 0 height (which would land a layout-managed Table on a 0 height\n * even though no preferred size was set).\n *\n * The result is floored at the child's own min height: a child placed at\n * `max(preferred, min)` (see {@link VBox.resolveChildHeight}) must reserve\n * that same height in the fixed total, or a child reporting `preferred < min`\n * (a `min ≤ preferred` invariant violation) would be under-reserved and push\n * the weighted cells out, overflowing the column.\n */\n private preferredChildHeight(size: Size | null, minSize: Size | null): number {\n const preferred = (size ? size.height : undefined)\n ?? (minSize && minSize.height > 0 ? minSize.height : undefined)\n ?? this._defaultComponentHeight;\n\n return minSize ? Math.max(preferred, minSize.height) : preferred;\n }\n\n /**\n * Resolves a child's final height within the column, clamped to its\n * min/max — the minimum wins when the two conflict. Weight cells take a\n * share of `remainingHeight`; non-weighted children take their preferred\n * height reduced by the shrink ratio toward their min height.\n *\n * @param size - The child's preferred size, or `null`.\n * @param minSize - The child's minimum size, or `null`.\n * @param maxSize - The child's maximum size, or `null`.\n * @param weight - The child's weight constraint (0 when non-weighted).\n * @param totalWeight - The summed weight of all weight cells.\n * @param remainingHeight - The space available to weight cells.\n * @param shrinkRatio - How far (0–1) non-weighted children shrink to min.\n * @returns The child's height.\n */\n private resolveChildHeight(size: Size | null, minSize: Size | null, maxSize: Size | null, weight: number, totalWeight: number, remainingHeight: number, shrinkRatio: number): number {\n let height: number;\n\n if (weight > 0 && totalWeight > 0) {\n height = (weight / totalWeight) * remainingHeight;\n } else {\n const pref = this.preferredChildHeight(size, minSize);\n const min = minSize ? minSize.height : 0;\n\n height = pref - shrinkRatio * (pref - min);\n }\n\n if (maxSize) {\n height = Math.min(height, maxSize.height);\n }\n\n if (minSize) {\n height = Math.max(height, minSize.height);\n }\n\n return height;\n }\n}\n\nconst VBoxCallable = callable(VBox);\ntype VBoxCallable = VBox;\nexport {\n VBox as _VBox,\n VBoxCallable as VBox\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VBox-DVe4UXwX.js","names":[],"sources":["../../src/typescript/lib/layout/BoxLayout.ts","../../src/typescript/lib/layout/HBox.ts","../../src/typescript/lib/layout/VBox.ts"],"sourcesContent":["// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { LayoutManager, LayoutManagerOptions } from \"~/layout/LayoutManager.js\";\nimport { FillType } from \"~/layout/FillType.js\";\nimport { AnchorType } from \"~/layout/AnchorType.js\";\nimport type { AxisPosition, AxisSpread } from \"~/primitive/Axis.js\";\nimport { Component } from \"~/core/Component.js\";\nimport { Size, UNBOUNDED, isUnbounded } from \"~/primitive/Size.js\";\n\n/**\n * Sizing strategy along an {@link HBox} or {@link VBox}'s main axis.\n *\n * - `\"preferred\"` — each child gets its preferred width (height for VBox);\n * `weight`-constrained children split the remaining space; an overflow\n * shrinks non-weighted children proportionally toward their min sizes.\n * - `\"equal\"` — children split the container's inner extent equally; the\n * per-cell floor is `max(child.minSize.width)` (height for VBox);\n * `weight` constraints are ignored.\n *\n * @category Layouts\n */\nexport type BoxMode = \"preferred\" | \"equal\";\n\n/**\n * How an `\"equal\"`-mode {@link HBox}/{@link VBox} sizes its cells when the\n * row/column overflows the host's inner extent and the host has opted into\n * scrolling (`Panel.setAutoScroll`).\n *\n * - `\"preferred\"` (the default) — every cell takes the widest/tallest child's\n * preferred extent, so cells keep their preferred size and the host scrolls.\n * - `\"min\"` — every cell stays at the min floor (`max(child.minSize)`), so the\n * row/column scrolls at the minimum cell size instead of growing.\n *\n * Has no effect outside `\"equal\"` mode, nor when the cells fit (the equal share\n * clears the min floor), nor when the host does not scroll (cells always clamp\n * to the min floor and the host's `overflow: hidden` clips the surplus).\n *\n * @category Layouts\n */\nexport type BoxOverflowSizing = \"preferred\" | \"min\";\n\n/**\n * How a `\"preferred\"`-mode {@link HBox}/{@link VBox} distributes the leftover\n * main-axis space when its children are shorter than the inner main extent and\n * no `weight` cells consume the slack. Mirrors CSS `justify-content`.\n *\n * A single line makes exactly one main-axis slack decision, so the two shared\n * axis concepts fuse into this one field: the {@link AxisPosition} half\n * (`\"start\"`/`\"center\"`/`\"end\"`) positions the whole child block as a unit,\n * while the {@link AxisSpread} half (`\"between\"`/`\"around\"`) spreads the slack\n * into the inter-child gaps. `justifyOffsets` reflects the split — position\n * values yield a leading offset (`lead`, `gap: 0`) and spread values yield an\n * inter-child `gap`. `\"start\"` is the shared identity of both halves, so the\n * union collapses to these five distinct values.\n *\n * - `\"start\"` (the default) — children pack at the leading edge; the slack sits\n * at the trailing edge.\n * - `\"center\"` — the child block is centred; equal slack on both ends.\n * - `\"end\"` — children pack at the trailing edge; the slack sits at the leading\n * edge.\n * - `\"between\"` — the first child sits at the leading edge, the last at the\n * trailing edge, and the slack is split evenly into the gaps between them.\n * - `\"around\"` — every child gets equal space around it: a half-unit before the\n * first and after the last, a full unit between neighbours.\n *\n * Has no effect outside `\"preferred\"` mode, nor when `weight` cells absorb the\n * slack, nor when the content fills or overflows the inner extent (the row\n * clamps to `\"start\"` so the leading child is never pushed out of view).\n *\n * @category Layouts\n */\nexport type BoxJustify = AxisPosition | AxisSpread;\n\n/**\n * Cross-axis alignment of a child within an {@link HBox} row / {@link VBox}\n * column, when the child sets no explicit per-child cross intent (fill/anchor\n * align-self). Mirrors {@link FlowLayout}'s `FlowItemAlign`, with the extra\n * `\"stretch\"` a box can do.\n *\n * - `\"start\"` — leading cross-edge (HBox top, VBox left).\n * - `\"center\"` — centred in the cross band.\n * - `\"end\"` — trailing cross-edge (HBox bottom, VBox right).\n * - `\"baseline\"` — HBox: shared text baseline (the default). VBox has no cross\n * text baseline, so it degrades to `\"start\"`.\n * - `\"stretch\"` — fill the cross band (equivalent to the deprecated\n * `stretching`).\n *\n * @category Layouts\n */\nexport type BoxItemAlign = \"start\" | \"center\" | \"end\" | \"baseline\" | \"stretch\";\n\n/**\n * Construction-time options shared by {@link HBox} and {@link VBox}.\n *\n * @remarks `mode` selects the sizing strategy along the box's main axis.\n * `\"preferred\"` (the default) honours each child's preferred main-axis extent\n * and supports `weight` cells. `\"equal\"` divides the container's main axis\n * equally and ignores `weight`. `mode` is independent of `stretching`, which\n * governs the cross axis: `stretching` defaults to `false` in both modes, so\n * `\"equal\"` divides the main axis but leaves children at their preferred\n * cross-axis extent unless `stretching: true` is passed.\n *\n * @category Layouts\n */\nexport interface BoxLayoutOptions extends LayoutManagerOptions {\n spacing?: number;\n /** @deprecated Use `itemAlign` — `stretching: true` ≡ `itemAlign: \"stretch\"`. */\n stretching?: boolean;\n itemAlign?: BoxItemAlign;\n mode?: BoxMode;\n overflowSizing?: BoxOverflowSizing;\n justify?: BoxJustify;\n}\n\n/**\n * Abstract base for the single-axis box layouts {@link HBox} and {@link VBox}.\n * Holds the axis-agnostic configuration plumbing — spacing, stretching, sizing\n * mode, and overflow sizing — and dispatches a {@link BoxLayoutOptions} bag.\n * The geometric algorithms (`getPreferredSize`, `getMinSize`, `getMaxSize`,\n * `computeTotalMinSize`, `doLayout`) are mirror-image per axis and stay\n * concrete on each subclass.\n *\n * @category Layouts\n */\nexport abstract class BoxLayout extends LayoutManager {\n\n // `protected`, not `private`: the subclasses' geometric methods\n // (getPreferredSize/getMinSize/getMaxSize/computeTotalMinSize/doLayout)\n // read these fields directly, so they must be visible to HBox/VBox.\n protected _spacing: number = 5;\n protected _itemAlign: BoxItemAlign = \"baseline\";\n protected _mode: BoxMode = \"preferred\";\n protected _overflowSizing: BoxOverflowSizing = \"preferred\";\n protected _justify: BoxJustify = \"start\";\n\n constructor(options?: BoxLayoutOptions) {\n // LayoutManager's constructor takes no options; applied via applyOptions below.\n // eslint-disable-next-line local/forward-super-options\n super();\n\n if (options) {\n this.applyOptions(options);\n }\n }\n\n /**\n * Applies a {@link BoxLayoutOptions} bag, dispatching mode, spacing, and\n * stretching after the inherited LayoutManager defaults.\n *\n * @param options - The options bag carrying the values to apply.\n *\n * @remarks `mode` and `stretching` are independent axes: `mode` governs the\n * main-axis sizing strategy, `stretching` governs whether children fill the\n * cross axis. Neither defaults from the other — `stretching` is `false`\n * unless the options bag passes it explicitly, in both `\"preferred\"` and\n * `\"equal\"` mode.\n */\n protected applyOptions(options: BoxLayoutOptions): void {\n super.applyOptions(options);\n\n if (options.mode !== undefined) {\n this.setMode(options.mode);\n }\n\n if (options.spacing !== undefined) {\n this.setComponentSpacing(options.spacing);\n }\n\n if (options.stretching !== undefined) {\n this.setStretching(options.stretching);\n }\n\n if (options.itemAlign !== undefined) {\n this.setItemAlign(options.itemAlign);\n }\n\n if (options.overflowSizing !== undefined) {\n this.setOverflowSizing(options.overflowSizing);\n }\n\n if (options.justify !== undefined) {\n this.setJustify(options.justify);\n }\n }\n\n /**\n * Returns the pixel spacing between child components.\n *\n * @returns The current spacing in pixels.\n */\n getComponentSpacing(): number {\n return this._spacing || 0;\n }\n\n /**\n * Sets the pixel spacing between child components.\n *\n * @param spacing - Spacing in pixels.\n *\n * @returns This layout manager, for method chaining.\n */\n setComponentSpacing(spacing: number): this {\n this._spacing = spacing || 0;\n\n return this;\n }\n\n /**\n * Returns whether children stretch to fill the container's cross axis.\n *\n * @returns `true` if stretching is enabled.\n *\n * @deprecated Use `getItemAlign() === \"stretch\"`.\n */\n isStretching(): boolean {\n return this._itemAlign === \"stretch\";\n }\n\n /**\n * Sets whether children stretch to fill the container's cross axis.\n *\n * @param stretching - Pass `true` to enable cross-axis stretching.\n *\n * @returns This layout manager, for method chaining.\n *\n * @deprecated Use `setItemAlign(\"stretch\" | \"baseline\")`.\n */\n setStretching(stretching: boolean): this {\n return this.setItemAlign(stretching ? \"stretch\" : \"baseline\");\n }\n\n /**\n * Returns how a child is aligned within the cross axis when it sets no\n * explicit per-child cross intent (fill/anchor align-self).\n *\n * @returns The current {@link BoxItemAlign}.\n */\n getItemAlign(): BoxItemAlign {\n return this._itemAlign;\n }\n\n /**\n * Sets how a child is aligned within the cross axis when it sets no\n * explicit per-child cross intent (fill/anchor align-self).\n *\n * @param itemAlign - `\"start\"`/`\"center\"`/`\"end\"` pin to or centre within\n * the cross band, `\"baseline\"` (the default) aligns HBox rows on their\n * shared text baseline (degrading to `\"start\"` on VBox), and `\"stretch\"`\n * fills the cross band. See {@link BoxItemAlign}.\n *\n * @returns This layout manager, for method chaining.\n */\n setItemAlign(itemAlign: BoxItemAlign): this {\n this._itemAlign = itemAlign;\n\n return this;\n }\n\n /**\n * Returns the current sizing mode along the main axis.\n *\n * @returns Either `\"preferred\"` or `\"equal\"`.\n */\n getMode(): BoxMode {\n return this._mode;\n }\n\n /**\n * Sets the sizing mode along the main axis.\n *\n * @param mode - `\"preferred\"` honours each child's preferred main-axis\n * extent; `\"equal\"` divides the container's main axis equally among\n * children.\n *\n * @returns This layout manager, for method chaining.\n */\n setMode(mode: BoxMode): this {\n this._mode = mode;\n\n return this;\n }\n\n /**\n * Returns the cell-sizing strategy used when an `\"equal\"`-mode row/column\n * overflows a scrolling host.\n *\n * @returns Either `\"preferred\"` or `\"min\"`.\n */\n getOverflowSizing(): BoxOverflowSizing {\n return this._overflowSizing;\n }\n\n /**\n * Sets the cell-sizing strategy used when an `\"equal\"`-mode row/column\n * overflows a scrolling host.\n *\n * @param overflowSizing - `\"preferred\"` grows every cell to the largest\n * child's preferred extent and scrolls; `\"min\"` keeps cells at the min\n * floor and scrolls at the minimum cell size. See {@link BoxOverflowSizing}.\n *\n * @returns This layout manager, for method chaining.\n */\n setOverflowSizing(overflowSizing: BoxOverflowSizing): this {\n this._overflowSizing = overflowSizing;\n\n return this;\n }\n\n /**\n * Returns how leftover main-axis space is distributed in `\"preferred\"` mode.\n *\n * @returns The current {@link BoxJustify} mode.\n */\n getJustify(): BoxJustify {\n return this._justify;\n }\n\n /**\n * Sets how leftover main-axis space is distributed in `\"preferred\"` mode.\n *\n * @param justify - `\"start\"` packs children at the leading edge (the\n * default), `\"center\"`/`\"end\"` shift the block, and `\"between\"`/`\"around\"`\n * spread the slack into the inter-child gaps. See {@link BoxJustify}.\n *\n * @returns This layout manager, for method chaining.\n */\n setJustify(justify: BoxJustify): this {\n this._justify = justify;\n\n return this;\n }\n\n /**\n * Aggregates the children's maximum sizes per the box contract: main axis =\n * sum of child maxima (+ spacing; in `\"equal\"` mode count * widest-child-max),\n * cross axis = max of child maxima, a null or unbounded child max making that\n * axis unbounded. Saturated to {@link UNBOUNDED}. Includes the container\n * perimeter.\n *\n * @param horizontal - `true` for {@link HBox} (main = width), `false` for\n * {@link VBox} (main = height).\n * @returns The aggregated maximum `{width, height}`, or `null` if no\n * container is attached.\n */\n protected aggregateMaxSize(horizontal: boolean): Size | null {\n const container = this.getContainer();\n if (!container) {\n return null;\n }\n\n const perimeterSize = container.getPerimeterSize();\n const components = container.getLaidOutComponents();\n\n const mainStart = horizontal ? perimeterSize.left + perimeterSize.right : perimeterSize.top + perimeterSize.bottom;\n const crossExtra = horizontal ? perimeterSize.top + perimeterSize.bottom : perimeterSize.left + perimeterSize.right;\n\n let main = mainStart;\n let cross = 0;\n let mainUnbounded = false;\n let crossUnbounded = false;\n let maxChildMain = 0;\n\n for (const component of components) {\n const size = component.getMaxSize();\n\n if (!size) {\n mainUnbounded = true;\n crossUnbounded = true;\n continue;\n }\n\n const mainExtent = horizontal ? size.width : size.height;\n const crossExtent = horizontal ? size.height : size.width;\n\n if (isUnbounded(mainExtent)) {\n mainUnbounded = true;\n } else if (this._mode === \"equal\") {\n maxChildMain = Math.max(maxChildMain, mainExtent);\n } else {\n main += mainExtent;\n }\n\n if (isUnbounded(crossExtent)) {\n crossUnbounded = true;\n } else {\n cross = Math.max(cross, crossExtent);\n }\n }\n\n if (this._mode === \"equal\") {\n main += components.length * maxChildMain + this._spacing * Math.max(0, components.length - 1);\n } else {\n main += this._spacing * Math.max(0, components.length - 1);\n }\n\n cross += crossExtra;\n\n const mainValue = mainUnbounded ? UNBOUNDED : main;\n const crossValue = crossUnbounded ? UNBOUNDED : cross;\n\n return {\n width: horizontal ? mainValue : crossValue,\n height: horizontal ? crossValue : mainValue\n };\n }\n\n /**\n * Resolves how much main-axis space the weight cells share and how hard the\n * non-weighted children must shrink. When the non-weighted children's\n * preferred extents fit (or the host scrolls on this axis), nothing shrinks\n * and the leftover is the weight remainder. Otherwise the children shrink\n * proportionally toward their min extents so the last child's far edge lands\n * inside the container.\n *\n * @param fixedPreferred - Summed preferred main-axis extent of the\n * non-weighted children, including inter-child spacing.\n * @param fixedMin - Summed minimum main-axis extent of the same children,\n * including spacing.\n * @param available - The working container's inner extent on the main axis.\n * @param overflowing - Whether the host has opted into scrolling on this\n * axis; when `true` the shrink is skipped so the host's CSS overflow\n * engages instead.\n * @returns `remaining` — the main-axis space left for weight cells — and\n * `shrinkRatio` — `0` (no shrink) through `1` (shrink fully to min).\n */\n protected computeShrink(fixedPreferred: number, fixedMin: number, available: number, overflowing: boolean): { remaining: number; shrinkRatio: number } {\n if (fixedPreferred <= available || overflowing) {\n return { remaining: Math.max(0, available - fixedPreferred), shrinkRatio: 0 };\n }\n\n const excess = fixedPreferred - available;\n const shrinkable = fixedPreferred - fixedMin;\n\n return { remaining: 0, shrinkRatio: shrinkable > 0 ? Math.min(1, excess / shrinkable) : 1 };\n }\n\n /**\n * Distributes the trailing main-axis slack per {@link BoxJustify}, returning\n * a leading offset and an extra inter-child gap. The subclass adds `lead` to\n * the placement cursor's start and `gap` to the inter-child spacing. A row\n * that fills or overflows the inner extent (`residual === 0`) and the\n * `\"start\"` fast path both return `{ lead: 0, gap: 0 }`, leaving placement\n * byte-identical to the un-justified loop. Generalises\n * {@link FlowLayout.alignLead}, which only produces a leading offset, by also\n * spreading slack into the gaps for `\"between\"`/`\"around\"`.\n *\n * @param contentMain - Summed placed child main-extents plus inter-child\n * spacing — the block's total main extent.\n * @param innerMain - The container's inner extent along the main axis.\n * @param count - The number of children sharing the axis.\n * @returns `lead` — pixels added before the first child — and `gap` — pixels\n * added to the spacing after each child. Both are non-negative.\n */\n protected justifyOffsets(contentMain: number, innerMain: number, count: number): { lead: number; gap: number } {\n const residual = Math.max(0, innerMain - contentMain);\n\n if (residual === 0 || this._justify === \"start\") {\n return { lead: 0, gap: 0 };\n }\n\n if (this._justify === \"center\") {\n return { lead: residual / 2, gap: 0 };\n }\n\n if (this._justify === \"end\") {\n return { lead: residual, gap: 0 };\n }\n\n if (this._justify === \"between\") {\n return { lead: 0, gap: count > 1 ? residual / (count - 1) : 0 };\n }\n\n // \"around\"\n return { lead: count > 0 ? residual / (2 * count) : 0, gap: count > 0 ? residual / count : 0 };\n }\n\n /**\n * Computes the leading cross-axis offset for the `\"start\"`/`\"center\"`/\n * `\"end\"` {@link BoxItemAlign} fallback — consulted only when a child sets\n * no explicit per-child cross intent and `itemAlign` is not `\"baseline\"` or\n * `\"stretch\"` (those keep their own, unchanged, placement paths). Mirrors\n * {@link FlowLayout.crossOffset}'s `center`/`end` arms.\n *\n * @param childCross - The child's own cross extent.\n * @param crossExtent - The full cross band extent.\n * @returns The leading offset in pixels — `0` for `\"start\"`, and never negative.\n */\n protected crossItemOffset(childCross: number, crossExtent: number): number {\n if (this._itemAlign === \"center\") {\n return Math.max(0, (crossExtent - childCross) / 2);\n }\n\n if (this._itemAlign === \"end\") {\n return Math.max(0, crossExtent - childCross);\n }\n\n return 0; // \"start\"\n }\n\n /**\n * Resolves a child's cross-axis offset and extent within the full cross\n * band, honouring an explicit per-child cross `fill`/`anchor` (align-self).\n * A cross-axis `fill` (`VERTICAL`/`BOTH` in an {@link HBox}, `HORIZONTAL`/\n * `BOTH` in a {@link VBox}) stretches the child to the whole band; a\n * cross-axis `anchor` edge (NORTH/SOUTH for HBox, WEST/EAST for VBox, plus\n * the corners carrying that component) pins the child's natural cross extent\n * to the leading or trailing edge. The main-axis `anchor` component and\n * `CENTER` are deliberately inert — the box owns main-axis sequencing, and\n * when `itemAlign` is `\"baseline\"` (the default) each box's default cross\n * placement (HBox baseline, VBox WEST origin) is more specific than\n * geometric centring; other `itemAlign` values choose the cross offset in\n * the caller.\n *\n * @param component - The child whose constraints supply the cross intent.\n * @param crossLead - The band's leading edge (`insets.top` for HBox,\n * `insets.left` for VBox).\n * @param crossExtent - The full cross band extent.\n * @param naturalCross - The child's preferred cross extent, already capped to\n * the band and the child's maximum; the anchored child sits at this extent.\n * @param horizontal - `true` for {@link HBox} (cross axis is vertical),\n * `false` for {@link VBox} (cross axis is horizontal).\n * @returns `{ offset, extent }` when the child sets an explicit cross intent,\n * or `null` to signal the caller to keep its default cross placement.\n */\n protected crossPlacement(component: Component, crossLead: number, crossExtent: number, naturalCross: number, horizontal: boolean): { offset: number; extent: number } | null {\n const constraints = this.getLayoutConstraints(component);\n const fill = constraints?.fill ?? null;\n const anchor = constraints?.anchor ?? null;\n\n const crossFill = horizontal\n ? (fill === FillType.VERTICAL || fill === FillType.BOTH)\n : (fill === FillType.HORIZONTAL || fill === FillType.BOTH);\n\n if (crossFill) {\n return { offset: crossLead, extent: crossExtent };\n }\n\n const edge = this.crossAnchorEdge(anchor, horizontal);\n\n if (edge === null) {\n return null;\n }\n\n const extent = Math.min(naturalCross, crossExtent);\n const offset = edge === \"lead\"\n ? crossLead\n : crossLead + (crossExtent - extent);\n\n return { offset, extent };\n }\n\n /**\n * Projects a child's `anchor` onto the cross axis as a leading/trailing edge.\n * CENTER and pure main-axis anchors carry no cross component and return\n * `null`, leaving the caller on its default cross placement.\n *\n * @param anchor - The child's anchor constraint, or `null`.\n * @param horizontal - `true` for {@link HBox} (cross = vertical: NORTH=lead,\n * SOUTH=trail), `false` for {@link VBox} (cross = horizontal: WEST=lead,\n * EAST=trail).\n * @returns `\"lead\"`/`\"trail\"` for an anchor with a cross component, else `null`.\n */\n private crossAnchorEdge(anchor: AnchorType | null, horizontal: boolean): \"lead\" | \"trail\" | null {\n if (anchor === null) {\n return null;\n }\n\n if (horizontal) {\n if (anchor === AnchorType.NORTH || anchor === AnchorType.NORTHWEST || anchor === AnchorType.NORTHEAST) {\n return \"lead\";\n }\n\n if (anchor === AnchorType.SOUTH || anchor === AnchorType.SOUTHWEST || anchor === AnchorType.SOUTHEAST) {\n return \"trail\";\n }\n\n return null;\n }\n\n if (anchor === AnchorType.WEST || anchor === AnchorType.NORTHWEST || anchor === AnchorType.SOUTHWEST) {\n return \"lead\";\n }\n\n if (anchor === AnchorType.EAST || anchor === AnchorType.NORTHEAST || anchor === AnchorType.SOUTHEAST) {\n return \"trail\";\n }\n\n return null;\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { BoxLayout, BoxLayoutOptions } from \"~/layout/BoxLayout.js\";\nimport type { ResolvedPlacement } from \"~/layout/LayoutManager.js\";\nimport { FillType } from \"~/layout/FillType.js\";\nimport { Size } from \"~/primitive/Size.js\";\nimport { Insets } from \"~/primitive/Insets.js\";\nimport { Component } from \"~/core/Component.js\";\nimport { callable } from \"~/core/Callable.js\";\n\n/**\n * Construction-time options for {@link HBox}.\n *\n * @remarks `mode` selects the sizing strategy along the horizontal axis.\n * `\"preferred\"` (the default) honours each child's preferred width and\n * supports `weight` cells. `\"equal\"` divides the container width equally\n * and ignores `weight`. `mode` is independent of `stretching` (the cross-axis\n * fill): `stretching` defaults to `false` in both modes, so `\"equal\"` divides\n * the width but leaves children at their preferred height unless\n * `stretching: true` is passed.\n *\n * @category Layouts\n */\nexport interface HBoxOptions extends BoxLayoutOptions {}\n\n/**\n * A layout manager that places children in a single horizontal row. The\n * `mode` option selects between preferred-width sequencing (with weight-cell\n * support) and equal-width division of the container.\n *\n * @category Layouts\n */\nclass HBox extends BoxLayout {\n\n private _defaultComponentWidth: number = 100;\n\n /**\n * Returns the row's baseline (the maximum child text baseline) measured from\n * the container's content-top, so a baseline-aware parent aligns this HBox\n * container by the same baseline its own children align to — rather than\n * auto-centring the whole container.\n *\n * @returns The inner baseline offset in pixels, or `null` when `itemAlign`\n * is not `\"baseline\"` (a centred/edge-aligned or stretched row exposes no\n * shared baseline) or when no child reports a baseline.\n */\n getContentBaseline(): number | null {\n if (this._itemAlign !== \"baseline\") {\n return null;\n }\n\n const container = this.getContainer();\n if (!container) {\n return null;\n }\n\n const heights: number[] = [];\n const baselines: Array<number | null> = [];\n\n for (const component of container.getLaidOutComponents()) {\n const size = component.getPreferredSize();\n heights.push(size ? size.height : 0);\n baselines.push(component.getBaseline());\n }\n\n return this.computeRowMetrics(heights, baselines).rowAscent;\n }\n\n /**\n * Returns the preferred size. In `\"preferred\"` mode this is the sum\n * of child widths plus spacing. In `\"equal\"` mode it is\n * `count * (maxChildWidth + spacing) - spacing`. Row height in both\n * modes is the baseline-aware row height of the children.\n *\n * @returns The preferred `{width, height}`, or `null` if no container is attached.\n */\n getPreferredSize(): Size | null {\n let container = this.getContainer();\n if (!container) {\n return null;\n }\n\n let perimeterSize = container.getPerimeterSize();\n let components = container.getLaidOutComponents();\n let width = perimeterSize.left + perimeterSize.right;\n\n const heights: number[] = [];\n const baselines: Array<number | null> = [];\n\n if (this._mode === \"equal\") {\n let maxChildWidth = 0;\n\n for (let idx in components) {\n let component = components[idx];\n let size = component.getPreferredSize();\n\n if (size) {\n maxChildWidth = Math.max(maxChildWidth, size.width);\n heights.push(size.height);\n baselines.push(component.getBaseline());\n }\n }\n\n width += components.length * (maxChildWidth + this._spacing) - this._spacing;\n } else {\n for (let idx in components) {\n let component = components[idx];\n let size = component.getPreferredSize();\n\n if (size) {\n width += size.width;\n heights.push(size.height);\n baselines.push(component.getBaseline());\n }\n }\n\n width += this._spacing * (components.length - 1);\n }\n\n let height = this.computeRowHeight(heights, baselines);\n\n height += perimeterSize.top + perimeterSize.bottom;\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Returns the minimum size. In `\"preferred\"` mode this is the sum of\n * child min widths plus spacing. In `\"equal\"` mode it is\n * `count * (maxChildMinWidth + spacing) - spacing`. Row height in\n * both modes is the baseline-aware row height of the children's\n * minimums.\n *\n * @returns The minimum `{width, height}`, or `null` if no container is attached.\n */\n getMinSize(): Size | null {\n let container = this.getContainer();\n if (!container) {\n return null;\n }\n\n let perimeterSize = container.getPerimeterSize();\n let components = container.getLaidOutComponents();\n let width = perimeterSize.left + perimeterSize.right;\n\n const heights: number[] = [];\n const baselines: Array<number | null> = [];\n\n if (this._mode === \"equal\") {\n let maxChildMinWidth = 0;\n\n for (let idx in components) {\n let component = components[idx];\n let size = component.getMinSize();\n\n if (size) {\n maxChildMinWidth = Math.max(maxChildMinWidth, size.width);\n heights.push(size.height);\n baselines.push(component.getBaseline());\n }\n }\n\n width += components.length * (maxChildMinWidth + this._spacing) - this._spacing;\n } else {\n for (let idx in components) {\n let component = components[idx];\n let size = component.getMinSize();\n\n if (size) {\n width += size.width;\n heights.push(size.height);\n baselines.push(component.getBaseline());\n }\n }\n\n width += this._spacing * (components.length - 1);\n }\n\n let height = this.computeRowHeight(heights, baselines);\n\n height += perimeterSize.top + perimeterSize.bottom;\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Returns the maximum size the row can usefully occupy. Along the main axis\n * (width) it sums the children's *maximum* widths plus spacing; in `\"equal\"`\n * mode it is `count * maxChildMaxWidth` plus spacing, since every cell shares\n * the widest child's allowance. The cross axis (height) takes the *largest*\n * child maximum — the tallest a child permits the row to grow to. A child\n * whose maximum is `null` or at the unbounded sentinel makes that axis\n * unbounded.\n *\n * @returns The maximum `{width, height}`, or `null` if no container is attached.\n */\n getMaxSize(): Size | null {\n return this.aggregateMaxSize(true);\n }\n\n /**\n * Computes the children's combined minSize along this manager's geometry.\n * In `\"preferred\"` mode width is the sum of per-child `minSize.width`\n * plus spacing. In `\"equal\"` mode width is\n * `count * maxChildMinWidth + spacing*(n-1)` (HBox distributes width\n * equally so the per-cell floor is the max of every child's min width).\n * Height in both modes is the max per-child `minSize.height`. Used by\n * `doLayout` to inflate the working size when the host has opted into\n * `setOverflowing` on the corresponding axis.\n *\n * @returns The total min-size; `{ width: 0, height: 0 }` when the\n * container is absent or has no children.\n */\n protected computeTotalMinSize(): Size {\n const container = this.getContainer();\n if (!container) {\n return { width: 0, height: 0 };\n }\n\n const components = container.getLaidOutComponents();\n if (components.length === 0) {\n return { width: 0, height: 0 };\n }\n\n let height = 0;\n\n if (this._mode === \"equal\") {\n let maxWidth = 0;\n\n for (const component of components) {\n const min = component.getMinSize();\n if (min) {\n maxWidth = Math.max(maxWidth, min.width);\n height = Math.max(height, min.height);\n }\n }\n\n return {\n width: components.length * (maxWidth + this._spacing) - this._spacing,\n height,\n };\n }\n\n let width = this._spacing * (components.length - 1);\n\n for (const component of components) {\n const min = component.getMinSize();\n if (min) {\n width += min.width;\n height = Math.max(height, min.height);\n }\n }\n\n return { width, height };\n }\n\n /**\n * Lays out the children left-to-right, dispatching to `layoutEqualMode` or\n * `layoutPreferredMode` per the sizing mode after inflating the working\n * size for any scroll-enabled axis.\n */\n doLayout(): void {\n const container = this.getContainer();\n if (!container) {\n return;\n }\n\n const innerSize = container.getInnerSize();\n if (!innerSize) {\n return;\n }\n\n const components = container.getLaidOutComponents();\n const containerInsets = container.getContentInsets();\n const spacing = this.getComponentSpacing();\n\n // Universal scroll: when the host has opted into per-axis overflow, lay\n // out against the children's combined minSize so trailing children land\n // past the viewport and the host's CSS `overflow: auto` scrolls.\n // `innerSize` stays the real viewport for equal mode's overflow test.\n const containerSize = this.inflateForOverflow(innerSize);\n\n let placements: ResolvedPlacement[];\n\n if (this._mode === \"equal\") {\n placements = this.layoutEqualMode(components, innerSize, containerSize, containerInsets, spacing);\n } else {\n placements = this.layoutPreferredMode(components, containerSize, containerInsets, spacing);\n }\n\n this.commitPlacements(placements);\n\n this.reserveContentFrame();\n }\n\n /**\n * Places children in equal-width cells. Every cell takes the same width\n * (see {@link HBox.computeEqualCellWidth}); when stretching, cells fill the\n * container height, otherwise children keep their preferred height and are\n * baseline-aligned within the row.\n *\n * @param components - The children to place, in order.\n * @param innerSize - The host's real inner size (pre-inflation), used to\n * measure the equal share against the true viewport.\n * @param containerSize - The working size, possibly inflated for overflow.\n * @param insets - The container's content insets.\n * @param spacing - Inter-child spacing in pixels.\n * @returns The resolved placements, ready for {@link LayoutManager.commitPlacements}.\n */\n private layoutEqualMode(components: Component[], innerSize: Size, containerSize: Size, insets: Insets, spacing: number): ResolvedPlacement[] {\n const cellWidth = this.computeEqualCellWidth(components, innerSize.width, spacing);\n\n if (this.isStretching()) {\n const y = insets.getTop();\n let x = insets.getLeft();\n const placements: ResolvedPlacement[] = [];\n\n for (const component of components) {\n placements.push({ component, ...this.resolveBounds(component, x, y, cellWidth, containerSize.height, FillType.BOTH) });\n\n x += cellWidth + spacing;\n }\n\n return placements;\n }\n\n const heights: number[] = [];\n const baselines: Array<number | null> = [];\n\n for (const component of components) {\n const size = component.getPreferredSize();\n\n heights.push(size ? size.height : 0);\n baselines.push(component.getBaseline());\n }\n\n const { rowAscent, rowDescent } = this.computeRowMetrics(heights, baselines);\n\n // Match the equal-stretch band exactly: the stretch branch fills\n // containerSize.height from insets.top with no bottom-inset subtraction,\n // so an EAST/fill align-self child reaches the same trailing edge.\n const crossLead = insets.getTop();\n const crossExtent = containerSize.height;\n\n let x = insets.getLeft();\n const placements: ResolvedPlacement[] = [];\n\n for (let idx = 0; idx < components.length; idx += 1) {\n const component = components[idx];\n\n const cross = this.crossPlacement(component, crossLead, crossExtent, heights[idx], true);\n\n if (cross) {\n placements.push({ component, ...this.resolveBounds(component, x, cross.offset, cellWidth, cross.extent, FillType.BOTH) });\n } else if (this._itemAlign === \"start\" || this._itemAlign === \"center\" || this._itemAlign === \"end\") {\n const y = crossLead + this.crossItemOffset(heights[idx], crossExtent);\n\n placements.push({ component, ...this.resolveBounds(component, x, y, cellWidth, heights[idx], FillType.BOTH) });\n } else {\n const y = this.rowChildY(insets.getTop(), heights[idx], baselines[idx], rowAscent, rowDescent);\n\n placements.push({ component, ...this.resolveBounds(component, x, y, cellWidth, heights[idx], FillType.BOTH) });\n }\n\n x += cellWidth + spacing;\n }\n\n return placements;\n }\n\n /**\n * Computes the shared cell width for equal mode: the equal share of the\n * inner width, floored at the widest child's min width.\n *\n * @param components - The children sharing the row.\n * @param innerWidth - The host's real inner width (pre-inflation).\n * @param spacing - Inter-child spacing in pixels.\n * @returns The width every equal-mode cell receives.\n *\n * @remarks Three cases drive the floor: (1) the share clears the widest\n * child's min width → the row fits, divide equally; (2) the share is below\n * the min floor, the host scrolls on this axis, and `overflowSizing` is\n * `\"preferred\"` → every cell takes the widest child's preferred width so\n * cells regain preferred size instead of sticking at min while scrolling;\n * (3) otherwise → clamp to the min floor (a non-scrolling host's\n * `overflow: hidden` clips the surplus).\n */\n private computeEqualCellWidth(components: Component[], innerWidth: number, spacing: number): number {\n let maxChildMinWidth = 0;\n let maxChildPreferredWidth = 0;\n\n for (const component of components) {\n const min = component.getMinSize();\n if (min) {\n maxChildMinWidth = Math.max(maxChildMinWidth, min.width);\n }\n\n const pref = component.getPreferredSize();\n if (pref) {\n maxChildPreferredWidth = Math.max(maxChildPreferredWidth, pref.width);\n }\n }\n\n const equalShare = (innerWidth - spacing * (components.length - 1)) / components.length;\n\n if (equalShare >= maxChildMinWidth) {\n return equalShare;\n }\n\n if (this.isOverflowingX() && this._overflowSizing === \"preferred\") {\n return Math.max(maxChildMinWidth, maxChildPreferredWidth);\n }\n\n return maxChildMinWidth;\n }\n\n /**\n * Places children at their preferred widths. Weight cells split the space\n * left after the non-weighted children; when the row overflows, the\n * non-weighted children shrink proportionally toward their min widths.\n * Children keep their preferred height (or fill the row height when\n * stretching) and are baseline-aligned unless stretching.\n *\n * @param components - The children to place, in order.\n * @param containerSize - The working size, possibly inflated for overflow.\n * @param insets - The container's content insets.\n * @param spacing - Inter-child spacing in pixels.\n * @returns The resolved placements, ready for {@link LayoutManager.commitPlacements}.\n */\n private layoutPreferredMode(components: Component[], containerSize: Size, insets: Insets, spacing: number): ResolvedPlacement[] {\n const { totalWeight, fixedPreferred, fixedMin } = this.measureFixedWidths(components, spacing);\n\n const { remaining: remainingWidth, shrinkRatio } = this.computeShrink(\n fixedPreferred,\n fixedMin,\n containerSize.width,\n this.isOverflowingX()\n );\n\n const widths: number[] = [];\n const heights: number[] = [];\n const baselines: Array<number | null> = [];\n\n for (const component of components) {\n const weight = this.getLayoutConstraints(component)?.weight ?? 0;\n const size = component.getPreferredSize();\n const minSize = component.getMinSize();\n const maxSize = component.getMaxSize();\n\n widths.push(this.resolveChildWidth(size, minSize, maxSize, weight, totalWeight, remainingWidth, shrinkRatio));\n\n // Cross-axis (height): give the child the row's available height —\n // the full inner height when stretching or sizeless, otherwise its\n // preferred height capped to the row. Cap to the child's maximum, but\n // do NOT floor to its minimum: enforcing the minimum here would\n // dogmatically inflate a child back up to its content size even when\n // the row is shorter, defeating a scrolling/clipping child. The\n // child's own setHeight → clampHeight applies its minimum (its\n // content minimum for a general component, or nothing for a Panel,\n // which fits its allocation and scrolls). When the host opts into\n // vertical scroll, `containerSize` is already inflated to the content\n // extent upstream, so `min(pref, containerSize)` still yields the full\n // height without a floor here.\n let height: number;\n\n if (!size || this.isStretching()) {\n height = containerSize.height;\n } else {\n height = Math.min(size.height, containerSize.height);\n }\n\n if (maxSize) {\n height = Math.min(height, maxSize.height);\n }\n\n heights.push(height);\n\n baselines.push(component.getBaseline());\n }\n\n // Stretching forces every child to fill the row vertically, which makes\n // baseline alignment meaningless — fall back to top-alignment. rowAscent\n // is driven only by text-bearing children; tall null-baseline children\n // (a List, TextArea, etc.) must NOT drag the baseline down or every text\n // label in the row would be pushed off the top.\n const { rowAscent, rowDescent } = this.isStretching()\n ? { rowAscent: null, rowDescent: 0 }\n : this.computeRowMetrics(heights, baselines);\n\n // Sum the placed main extents to find the trailing slack, then ask the\n // shared helper how to distribute it. Weight cells already consume all\n // slack, so justify is a no-op when any are present.\n let lead = 0;\n let gap = 0;\n\n if (totalWeight === 0) {\n let contentWidth = spacing * (components.length - 1);\n\n for (const w of widths) {\n contentWidth += w;\n }\n\n const innerWidth = containerSize.width - (insets.getLeft() + insets.getRight());\n\n ({ lead, gap } = this.justifyOffsets(contentWidth, innerWidth, components.length));\n }\n\n // Cross band for per-child align-self: the same vertical band the\n // stretch path fills, trimmed by both insets.\n const crossLead = insets.getTop();\n const crossExtent = containerSize.height - (insets.getTop() + insets.getBottom());\n\n let x = insets.getLeft() + lead;\n const placements: ResolvedPlacement[] = [];\n\n for (let idx = 0; idx < components.length; idx += 1) {\n const component = components[idx];\n\n // Align-self sizes from the child's *preferred* height (capped to the\n // band + max), independent of the stretch-inflated heights[idx], so an\n // anchored child shrinks-and-anchors even under global stretching.\n const pref = component.getPreferredSize();\n const maxSize = component.getMaxSize();\n let naturalCross = pref ? Math.min(pref.height, crossExtent) : crossExtent;\n\n if (maxSize) {\n naturalCross = Math.min(naturalCross, maxSize.height);\n }\n\n const cross = this.crossPlacement(component, crossLead, crossExtent, naturalCross, true);\n\n if (cross) {\n placements.push({ component, ...this.resolveBounds(component, x, cross.offset, widths[idx], cross.extent, FillType.BOTH) });\n } else if (this._itemAlign === \"start\" || this._itemAlign === \"center\" || this._itemAlign === \"end\") {\n const y = crossLead + this.crossItemOffset(heights[idx], crossExtent);\n\n placements.push({ component, ...this.resolveBounds(component, x, y, widths[idx], heights[idx], FillType.BOTH) });\n } else {\n const y = this.rowChildY(insets.getTop(), heights[idx], baselines[idx], rowAscent, rowDescent);\n\n placements.push({ component, ...this.resolveBounds(component, x, y, widths[idx], heights[idx], FillType.BOTH) });\n }\n\n // Advance by the resolved width, not getWidth(): the gap is measured\n // against the same extent contentWidth summed, so a placeComponent\n // clamp must not skew the trailing edge.\n x += widths[idx];\n x += spacing + gap;\n }\n\n return placements;\n }\n\n /**\n * Sums the non-weighted children's preferred and minimum widths (each\n * including inter-child spacing) and the total weight of the weight cells.\n *\n * @param components - The children sharing the row.\n * @param spacing - Inter-child spacing in pixels.\n * @returns `totalWeight` of the weight cells, plus the `fixedPreferred` and\n * `fixedMin` width totals of the non-weighted children.\n */\n private measureFixedWidths(components: Component[], spacing: number): { totalWeight: number; fixedPreferred: number; fixedMin: number } {\n let totalWeight = 0;\n let fixedPreferred = spacing * (components.length - 1);\n let fixedMin = spacing * (components.length - 1);\n\n for (const component of components) {\n const weight = this.getLayoutConstraints(component)?.weight ?? 0;\n\n if (weight > 0) {\n totalWeight += weight;\n } else {\n const size = component.getPreferredSize();\n const minSize = component.getMinSize();\n\n fixedPreferred += this.preferredChildWidth(size, minSize);\n fixedMin += minSize ? minSize.width : 0;\n }\n }\n\n return { totalWeight, fixedPreferred, fixedMin };\n }\n\n /**\n * Resolves a non-weighted child's preferred width, falling back through min\n * width to `_defaultComponentWidth`.\n *\n * @param size - The child's preferred size, or `null`.\n * @param minSize - The child's minimum size, or `null`.\n * @returns The width the child contributes before shrinking.\n *\n * @remarks Nullish-coalesce, not `||`: a component with an explicit\n * preferred width of 0 (e.g. an empty `Text` label) must contribute 0, not\n * fall through to `_defaultComponentWidth` and inflate the row's fixed total\n * past the container, which would force the shrink path to squeeze every\n * non-weighted child (including glyphs) toward its min size. The\n * `minSize.width > 0` guard prevents `LayoutManager._defaultMinSize =\n * {0,0}` from short-circuiting the chain into a 0 width (which would land a\n * layout-managed Table on width 0 even though no preferred size was set).\n *\n * The result is floored at the child's own min width: a child placed at\n * `max(preferred, min)` (see {@link HBox.resolveChildWidth}) must reserve\n * that same width in the fixed total, or a child reporting `preferred < min`\n * (a `min ≤ preferred` invariant violation) would be under-reserved and push\n * the weighted cells out, overflowing the row.\n */\n private preferredChildWidth(size: Size | null, minSize: Size | null): number {\n const preferred = (size ? size.width : undefined)\n ?? (minSize && minSize.width > 0 ? minSize.width : undefined)\n ?? this._defaultComponentWidth;\n\n return minSize ? Math.max(preferred, minSize.width) : preferred;\n }\n\n /**\n * Resolves a child's final width within the row, clamped to its min/max —\n * the minimum wins when the two conflict. Weight cells take a share of\n * `remainingWidth`; non-weighted children take their preferred width\n * reduced by the shrink ratio toward their min width.\n *\n * @param size - The child's preferred size, or `null`.\n * @param minSize - The child's minimum size, or `null`.\n * @param maxSize - The child's maximum size, or `null`.\n * @param weight - The child's weight constraint (0 when non-weighted).\n * @param totalWeight - The summed weight of all weight cells.\n * @param remainingWidth - The space available to weight cells.\n * @param shrinkRatio - How far (0–1) non-weighted children shrink to min.\n * @returns The child's width.\n */\n private resolveChildWidth(size: Size | null, minSize: Size | null, maxSize: Size | null, weight: number, totalWeight: number, remainingWidth: number, shrinkRatio: number): number {\n let width: number;\n\n if (weight > 0 && totalWeight > 0) {\n width = (weight / totalWeight) * remainingWidth;\n } else {\n const pref = this.preferredChildWidth(size, minSize);\n const min = minSize ? minSize.width : 0;\n\n width = pref - shrinkRatio * (pref - min);\n }\n\n if (maxSize) {\n width = Math.min(width, maxSize.width);\n }\n\n if (minSize) {\n width = Math.max(width, minSize.width);\n }\n\n return width;\n }\n\n /**\n * Computes a child's y within the row, aligning text-bearing children on the\n * shared baseline and centring null-baseline children in the text line.\n *\n * @param top - The row's content-top (inside the insets).\n * @param height - The child's height.\n * @param baseline - The child's baseline, or `null` for graphical/replaced children.\n * @param rowAscent - The row's text baseline, or `null` when no child reports one.\n * @param rowDescent - The row's text descent.\n * @returns The child's y position.\n */\n private rowChildY(top: number, height: number, baseline: number | null, rowAscent: number | null, rowDescent: number): number {\n if (rowAscent === null) {\n return top;\n }\n\n if (baseline !== null) {\n return top + (rowAscent - baseline);\n }\n\n return top + this.nullChildY(height, rowAscent, rowDescent);\n }\n}\n\nconst HBoxCallable = callable(HBox);\ntype HBoxCallable = HBox;\nexport {\n HBox as _HBox,\n HBoxCallable as HBox\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { FillType } from \"~/layout/FillType.js\";\nimport { Size, UNBOUNDED, isUnbounded } from \"~/primitive/Size.js\";\nimport { Insets } from \"~/primitive/Insets.js\";\nimport { Component } from \"~/core/Component.js\";\nimport { BoxLayout, BoxLayoutOptions } from \"~/layout/BoxLayout.js\";\nimport type { ResolvedPlacement } from \"~/layout/LayoutManager.js\";\nimport { callable } from \"~/core/Callable.js\";\n\n/**\n * Construction-time options for {@link VBox}.\n *\n * @remarks `mode` selects the sizing strategy along the vertical axis.\n * `\"preferred\"` (the default) honours each child's preferred height and\n * supports `weight` cells. `\"equal\"` divides the container height equally\n * and ignores `weight`. `mode` is independent of `stretching` (the cross-axis\n * fill): `stretching` defaults to `false` in both modes, so `\"equal\"` divides\n * the height but leaves children at their preferred width unless\n * `stretching: true` is passed.\n *\n * @category Layouts\n */\nexport interface VBoxOptions extends BoxLayoutOptions {}\n\n/**\n * A layout manager that places children in a single vertical column. The\n * `mode` option selects between preferred-height sequencing (with weight-cell\n * support) and equal-height division of the container.\n *\n * @category Layouts\n */\nclass VBox extends BoxLayout {\n\n private _defaultComponentHeight: number = 100;\n\n /**\n * Returns the column's baseline — the first laid-out child's baseline,\n * measured from the container's content-top — so a baseline-aware parent\n * aligns this VBox container by its first row's text baseline rather than\n * auto-centring the whole container.\n *\n * @returns The first child's baseline offset in pixels, or `null` when there\n * is no container, no laid-out children, or the first child reports no\n * baseline of its own.\n *\n * @remarks Forwards the **first** child's baseline verbatim — unlike\n * {@link HBox}, which takes the maximum baseline across the row's children.\n * A column has a single well-defined first row, so forwarding it (including\n * a `null` when that first row is graphical) is the most predictable\n * contract. The first child stacks at the container's content-top in every\n * mode, so its own baseline is already content-relative — `Component`'s\n * `getBaseline` then adds the container's chrome. Unlike `HBox`, this is not\n * disabled while stretching: VBox `stretching` fills the cross (width) axis\n * and leaves each child's height and intrinsic baseline untouched.\n */\n getContentBaseline(): number | null {\n const container = this.getContainer();\n if (!container) {\n return null;\n }\n\n const components = container.getLaidOutComponents();\n if (components.length === 0) {\n return null;\n }\n\n return components[0].getBaseline();\n }\n\n /**\n * Returns the preferred size. In `\"preferred\"` mode this is the widest\n * child width and the sum of child heights plus spacing. In `\"equal\"`\n * mode height is `count * (maxChildHeight + spacing) - spacing`.\n *\n * @returns The preferred `{width, height}`, or `null` if no container is attached.\n */\n getPreferredSize(): Size | null {\n let container = this.getContainer();\n if (!container) {\n return null;\n }\n\n let perimeterSize = container.getPerimeterSize();\n let components = container.getLaidOutComponents();\n\n if (this._mode === \"equal\") {\n let innerWidth = 0;\n let innerHeight = 0;\n\n for (let idx in components) {\n let component = components[idx];\n let size = component.getPreferredSize();\n\n if (size) {\n innerWidth = Math.max(innerWidth, size.width);\n innerHeight = Math.max(innerHeight, size.height);\n }\n }\n\n const width = innerWidth + perimeterSize.left + perimeterSize.right;\n const height = components.length * (innerHeight + this._spacing) - this._spacing\n + perimeterSize.top + perimeterSize.bottom;\n\n return { width, height };\n }\n\n let width = UNBOUNDED;\n let height = perimeterSize.top + perimeterSize.bottom;\n\n for (let idx in components) {\n let component = components[idx];\n let size = component.getPreferredSize();\n\n if (size) {\n width = isUnbounded(width) ? Math.min(width, size.width) : Math.max(width, size.width);\n height += size.height;\n }\n }\n\n width += perimeterSize.left + perimeterSize.right;\n height += this._spacing * (components.length - 1);\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Returns the minimum size. In `\"preferred\"` mode this is the widest\n * child minimum width and the sum of child minimum heights plus\n * spacing. In `\"equal\"` mode height is\n * `count * (maxChildMinHeight + spacing) - spacing`.\n *\n * @returns The minimum `{width, height}`, or `null` if no container is attached.\n */\n getMinSize(): Size | null {\n let container = this.getContainer();\n if (!container) {\n return null;\n }\n\n let perimeterSize = container.getPerimeterSize();\n let components = container.getLaidOutComponents();\n\n if (this._mode === \"equal\") {\n let innerWidth = 0;\n let innerHeight = 0;\n\n for (let idx in components) {\n let component = components[idx];\n let size = component.getMinSize();\n\n if (size) {\n innerWidth = Math.max(innerWidth, size.width);\n innerHeight = Math.max(innerHeight, size.height);\n }\n }\n\n const width = innerWidth + perimeterSize.left + perimeterSize.right;\n const height = components.length * (innerHeight + this._spacing) - this._spacing\n + perimeterSize.top + perimeterSize.bottom;\n\n return { width, height };\n }\n\n let width = 0;\n let height = perimeterSize.top + perimeterSize.bottom;\n\n for (let idx in components) {\n let component = components[idx];\n let size = component.getMinSize();\n\n if (size) {\n width = Math.max(width, size.width);\n height += size.height;\n }\n }\n\n width += perimeterSize.left + perimeterSize.right;\n height += this._spacing * (components.length - 1);\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Returns the maximum size the column can usefully occupy. Along the main\n * axis (height) it sums the children's *maximum* heights plus spacing; in\n * `\"equal\"` mode it is `count * maxChildMaxHeight` plus spacing, since every\n * cell shares the tallest child's allowance. The cross axis (width) takes\n * the *largest* child maximum — the widest a child permits the column to\n * grow to. A child whose maximum is `null` or at the unbounded sentinel\n * makes that axis unbounded.\n *\n * @returns The maximum `{width, height}`, or `null` if no container is attached.\n */\n getMaxSize(): Size | null {\n return this.aggregateMaxSize(false);\n }\n\n /**\n * Computes the children's combined minSize along this manager's geometry.\n * In `\"preferred\"` mode height is the sum of per-child `minSize.height`\n * plus spacing. In `\"equal\"` mode height is\n * `count * maxChildMinHeight + spacing*(n-1)` (VBox distributes height\n * equally so the per-cell floor is the max of every child's min height).\n * Width in both modes is the max per-child `minSize.width`. Used by\n * `doLayout` to inflate the working size when the host has opted into\n * `setOverflowing` on the corresponding axis.\n *\n * @returns The total min-size; `{ width: 0, height: 0 }` when the\n * container is absent or has no children.\n */\n protected computeTotalMinSize(): Size {\n const container = this.getContainer();\n if (!container) {\n return { width: 0, height: 0 };\n }\n\n const components = container.getLaidOutComponents();\n if (components.length === 0) {\n return { width: 0, height: 0 };\n }\n\n let width = 0;\n\n if (this._mode === \"equal\") {\n let maxHeight = 0;\n\n for (const component of components) {\n const min = component.getMinSize();\n if (min) {\n width = Math.max(width, min.width);\n maxHeight = Math.max(maxHeight, min.height);\n }\n }\n\n return {\n width,\n height: components.length * (maxHeight + this._spacing) - this._spacing,\n };\n }\n\n let height = this._spacing * (components.length - 1);\n\n for (const component of components) {\n const min = component.getMinSize();\n if (min) {\n width = Math.max(width, min.width);\n height += min.height;\n }\n }\n\n return { width, height };\n }\n\n /**\n * Lays out the children top-to-bottom, dispatching to `layoutEqualMode` or\n * `layoutPreferredMode` per the sizing mode after inflating the working\n * size for any scroll-enabled axis.\n */\n doLayout(): void {\n const container = this.getContainer();\n if (!container) {\n return;\n }\n\n const innerSize = container.getInnerSize();\n if (!innerSize) {\n return;\n }\n\n const components = container.getLaidOutComponents();\n const containerInsets = container.getContentInsets();\n const spacing = this.getComponentSpacing();\n\n // Universal scroll: when the host has opted into per-axis overflow, lay\n // out against the children's combined minSize so trailing children land\n // past the viewport and the host's CSS `overflow: auto` scrolls.\n // `innerSize` stays the real viewport for equal mode's overflow test.\n const containerSize = this.inflateForOverflow(innerSize);\n\n let placements: ResolvedPlacement[];\n\n if (this._mode === \"equal\") {\n placements = this.layoutEqualMode(components, innerSize, containerSize, containerInsets, spacing);\n } else {\n placements = this.layoutPreferredMode(components, containerSize, containerInsets, spacing);\n }\n\n this.commitPlacements(placements);\n\n this.reserveContentFrame();\n }\n\n /**\n * Places children in equal-height cells stacked top-to-bottom. Every cell\n * takes the same height (see {@link VBox.computeEqualCellHeight}); when\n * stretching, cells fill the container width, otherwise children keep their\n * preferred width and are left-aligned within the column.\n *\n * @param components - The children to place, in order.\n * @param innerSize - The host's real inner size (pre-inflation), used to\n * measure the equal share against the true viewport.\n * @param containerSize - The working size, possibly inflated for overflow.\n * @param insets - The container's content insets.\n * @param spacing - Inter-child spacing in pixels.\n * @returns The resolved placements, ready for {@link LayoutManager.commitPlacements}.\n */\n private layoutEqualMode(components: Component[], innerSize: Size, containerSize: Size, insets: Insets, spacing: number): ResolvedPlacement[] {\n const cellHeight = this.computeEqualCellHeight(components, innerSize.height, spacing);\n\n const x = insets.getLeft();\n let y = insets.getTop();\n\n if (this.isStretching()) {\n const cellWidth = containerSize.width;\n const placements: ResolvedPlacement[] = [];\n\n for (const component of components) {\n placements.push({ component, ...this.resolveBounds(component, x, y, cellWidth, cellHeight, FillType.BOTH) });\n\n y += cellHeight + spacing;\n }\n\n return placements;\n }\n\n // Match the equal-stretch band exactly: the stretch branch fills\n // containerSize.width from insets.left with no right-inset subtraction,\n // so an EAST/fill align-self child reaches the same trailing edge.\n const crossLead = insets.getLeft();\n const crossExtent = containerSize.width;\n const placements: ResolvedPlacement[] = [];\n\n for (const component of components) {\n const size = component.getPreferredSize();\n const width = size ? size.width : 0;\n\n const cross = this.crossPlacement(component, crossLead, crossExtent, width, false);\n\n if (cross) {\n placements.push({ component, ...this.resolveBounds(component, cross.offset, y, cross.extent, cellHeight, FillType.BOTH) });\n } else if (this._itemAlign === \"start\" || this._itemAlign === \"center\" || this._itemAlign === \"end\") {\n const cx = crossLead + this.crossItemOffset(width, crossExtent);\n\n placements.push({ component, ...this.resolveBounds(component, cx, y, width, cellHeight, FillType.BOTH) });\n } else {\n placements.push({ component, ...this.resolveBounds(component, x, y, width, cellHeight, FillType.BOTH) });\n }\n\n y += cellHeight + spacing;\n }\n\n return placements;\n }\n\n /**\n * Computes the shared cell height for equal mode: the equal share of the\n * inner height, floored at the tallest child's min height.\n *\n * @param components - The children sharing the column.\n * @param innerHeight - The host's real inner height (pre-inflation).\n * @param spacing - Inter-child spacing in pixels.\n * @returns The height every equal-mode cell receives.\n *\n * @remarks Three cases drive the floor: (1) the share clears the tallest\n * child's min height → the column fits, divide equally; (2) the share is\n * below the min floor, the host scrolls on this axis, and `overflowSizing`\n * is `\"preferred\"` → every cell takes the tallest child's preferred height\n * so cells regain preferred size instead of sticking at min while\n * scrolling; (3) otherwise → clamp to the min floor (a non-scrolling host's\n * `overflow: hidden` clips the surplus).\n */\n private computeEqualCellHeight(components: Component[], innerHeight: number, spacing: number): number {\n let maxChildMinHeight = 0;\n let maxChildPreferredHeight = 0;\n\n for (const component of components) {\n const min = component.getMinSize();\n if (min) {\n maxChildMinHeight = Math.max(maxChildMinHeight, min.height);\n }\n\n const pref = component.getPreferredSize();\n if (pref) {\n maxChildPreferredHeight = Math.max(maxChildPreferredHeight, pref.height);\n }\n }\n\n const equalShare = (innerHeight - spacing * (components.length - 1)) / components.length;\n\n if (equalShare >= maxChildMinHeight) {\n return equalShare;\n }\n\n if (this.isOverflowingY() && this._overflowSizing === \"preferred\") {\n return Math.max(maxChildMinHeight, maxChildPreferredHeight);\n }\n\n return maxChildMinHeight;\n }\n\n /**\n * Places children at their preferred heights stacked top-to-bottom. Weight\n * cells split the space left after the non-weighted children; when the\n * column overflows, the non-weighted children shrink proportionally toward\n * their min heights. Children keep their preferred width, or fill the\n * container width when stretching.\n *\n * @param components - The children to place, in order.\n * @param containerSize - The working size, possibly inflated for overflow.\n * @param insets - The container's content insets.\n * @param spacing - Inter-child spacing in pixels.\n * @returns The resolved placements, ready for {@link LayoutManager.commitPlacements}.\n */\n private layoutPreferredMode(components: Component[], containerSize: Size, insets: Insets, spacing: number): ResolvedPlacement[] {\n const { totalWeight, fixedPreferred, fixedMin } = this.measureFixedHeights(components, spacing);\n\n const { remaining: remainingHeight, shrinkRatio } = this.computeShrink(\n fixedPreferred,\n fixedMin,\n containerSize.height,\n this.isOverflowingY()\n );\n\n // Pre-pass: resolve each child's height into an array so the trailing\n // slack can be measured before placement (mirrors HBox's widths[]).\n const heights: number[] = [];\n\n for (const component of components) {\n const weight = this.getLayoutConstraints(component)?.weight ?? 0;\n const size = component.getPreferredSize();\n const minSize = component.getMinSize();\n const maxSize = component.getMaxSize();\n\n heights.push(this.resolveChildHeight(size, minSize, maxSize, weight, totalWeight, remainingHeight, shrinkRatio));\n }\n\n // Sum the placed main extents to find the trailing slack, then ask the\n // shared helper how to distribute it. Weight cells already consume all\n // slack, so justify is a no-op when any are present.\n let lead = 0;\n let gap = 0;\n\n if (totalWeight === 0) {\n let contentHeight = spacing * (components.length - 1);\n\n for (const h of heights) {\n contentHeight += h;\n }\n\n const innerHeight = containerSize.height - (insets.getTop() + insets.getBottom());\n\n ({ lead, gap } = this.justifyOffsets(contentHeight, innerHeight, components.length));\n }\n\n // Cross band for per-child align-self: the horizontal band trimmed by\n // both insets. The default path keeps reading containerSize.width\n // (un-trimmed) to stay byte-identical with today's body.\n const crossLead = insets.getLeft();\n const crossExtent = containerSize.width - (insets.getLeft() + insets.getRight());\n\n const x = insets.getLeft();\n let y = insets.getTop() + lead;\n const placements: ResolvedPlacement[] = [];\n\n for (let idx = 0; idx < components.length; idx += 1) {\n const component = components[idx];\n const size = component.getPreferredSize();\n const maxSize = component.getMaxSize();\n\n // Cross-axis (width): give the child the column's available width —\n // the full inner width when stretching or sizeless, otherwise its\n // preferred width capped to the column. Cap to the child's maximum,\n // but do NOT floor to its minimum: enforcing the minimum here would\n // dogmatically inflate a child back up to its content size even when\n // the column is narrower, defeating a scrolling/clipping child. The\n // child's own setWidth → clampWidth applies its minimum (its content\n // minimum for a general component, or nothing for a Panel, which fits\n // its allocation and scrolls). When the host opts into horizontal\n // scroll, `containerSize` is already inflated to the content extent\n // upstream, so `min(pref, containerSize)` still yields the full width\n // without a floor here.\n let defaultWidth: number;\n\n if (!size || this.isStretching()) {\n defaultWidth = containerSize.width;\n } else {\n defaultWidth = Math.min(size.width, containerSize.width);\n }\n\n if (maxSize) {\n defaultWidth = Math.min(defaultWidth, maxSize.width);\n }\n\n // Align-self sizes from the child's *preferred* width (capped to the\n // band + max), independent of global stretching, so an anchored child\n // shrinks-and-anchors even when the column is stretching.\n let naturalWidth = size ? Math.min(size.width, crossExtent) : crossExtent;\n\n if (maxSize) {\n naturalWidth = Math.min(naturalWidth, maxSize.width);\n }\n\n const cross = this.crossPlacement(component, crossLead, crossExtent, naturalWidth, false);\n\n if (cross) {\n placements.push({ component, ...this.resolveBounds(component, cross.offset, y, cross.extent, heights[idx], FillType.BOTH) });\n } else if (this._itemAlign === \"start\" || this._itemAlign === \"center\" || this._itemAlign === \"end\") {\n const cx = crossLead + this.crossItemOffset(naturalWidth, crossExtent);\n\n placements.push({ component, ...this.resolveBounds(component, cx, y, naturalWidth, heights[idx], FillType.BOTH) });\n } else {\n placements.push({ component, ...this.resolveBounds(component, x, y, defaultWidth, heights[idx], FillType.BOTH) });\n }\n\n // Advance by the resolved height, not getHeight(): the gap is\n // measured against the same extent contentHeight summed, so a\n // placeComponent clamp must not skew the trailing edge.\n y += heights[idx];\n y += spacing + gap;\n }\n\n return placements;\n }\n\n /**\n * Sums the non-weighted children's preferred and minimum heights (each\n * including inter-child spacing) and the total weight of the weight cells.\n *\n * @param components - The children sharing the column.\n * @param spacing - Inter-child spacing in pixels.\n * @returns `totalWeight` of the weight cells, plus the `fixedPreferred` and\n * `fixedMin` height totals of the non-weighted children.\n */\n private measureFixedHeights(components: Component[], spacing: number): { totalWeight: number; fixedPreferred: number; fixedMin: number } {\n let totalWeight = 0;\n let fixedPreferred = spacing * (components.length - 1);\n let fixedMin = spacing * (components.length - 1);\n\n for (const component of components) {\n const weight = this.getLayoutConstraints(component)?.weight ?? 0;\n\n if (weight > 0) {\n totalWeight += weight;\n } else {\n const size = component.getPreferredSize();\n const minSize = component.getMinSize();\n\n fixedPreferred += this.preferredChildHeight(size, minSize);\n fixedMin += minSize ? minSize.height : 0;\n }\n }\n\n return { totalWeight, fixedPreferred, fixedMin };\n }\n\n /**\n * Resolves a non-weighted child's preferred height, falling back through min\n * height to `_defaultComponentHeight`.\n *\n * @param size - The child's preferred size, or `null`.\n * @param minSize - The child's minimum size, or `null`.\n * @returns The height the child contributes before shrinking.\n *\n * @remarks Nullish-coalesce, not `||`: a component with an explicit\n * preferred height of 0 must contribute 0, not fall through to\n * `_defaultComponentHeight`. The `minSize.height > 0` guard prevents\n * `LayoutManager._defaultMinSize = {0,0}` from short-circuiting the chain\n * into a 0 height (which would land a layout-managed Table on a 0 height\n * even though no preferred size was set).\n *\n * The result is floored at the child's own min height: a child placed at\n * `max(preferred, min)` (see {@link VBox.resolveChildHeight}) must reserve\n * that same height in the fixed total, or a child reporting `preferred < min`\n * (a `min ≤ preferred` invariant violation) would be under-reserved and push\n * the weighted cells out, overflowing the column.\n */\n private preferredChildHeight(size: Size | null, minSize: Size | null): number {\n const preferred = (size ? size.height : undefined)\n ?? (minSize && minSize.height > 0 ? minSize.height : undefined)\n ?? this._defaultComponentHeight;\n\n return minSize ? Math.max(preferred, minSize.height) : preferred;\n }\n\n /**\n * Resolves a child's final height within the column, clamped to its\n * min/max — the minimum wins when the two conflict. Weight cells take a\n * share of `remainingHeight`; non-weighted children take their preferred\n * height reduced by the shrink ratio toward their min height.\n *\n * @param size - The child's preferred size, or `null`.\n * @param minSize - The child's minimum size, or `null`.\n * @param maxSize - The child's maximum size, or `null`.\n * @param weight - The child's weight constraint (0 when non-weighted).\n * @param totalWeight - The summed weight of all weight cells.\n * @param remainingHeight - The space available to weight cells.\n * @param shrinkRatio - How far (0–1) non-weighted children shrink to min.\n * @returns The child's height.\n */\n private resolveChildHeight(size: Size | null, minSize: Size | null, maxSize: Size | null, weight: number, totalWeight: number, remainingHeight: number, shrinkRatio: number): number {\n let height: number;\n\n if (weight > 0 && totalWeight > 0) {\n height = (weight / totalWeight) * remainingHeight;\n } else {\n const pref = this.preferredChildHeight(size, minSize);\n const min = minSize ? minSize.height : 0;\n\n height = pref - shrinkRatio * (pref - min);\n }\n\n if (maxSize) {\n height = Math.min(height, maxSize.height);\n }\n\n if (minSize) {\n height = Math.max(height, minSize.height);\n }\n\n return height;\n }\n}\n\nconst VBoxCallable = callable(VBox);\ntype VBoxCallable = VBox;\nexport {\n VBox as _VBox,\n VBoxCallable as VBox\n};\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./DOM-
|
|
2
|
-
//# sourceMappingURL=VirtualScroller-
|
|
1
|
+
import{t as e}from"./DOM-Cjh7_7TF.js";import{l as t}from"./Position-BIEU1Eze.js";import{S as n,_ as r,g as i}from"./Component-D99-15Zt.js";import{a,o,s,t as c}from"./Scrollbar-DcnueNJd.js";var VirtualScroller=class{_owner;_onScroll;_clipBox;_rowsContainer;_scrollbarV;_scrollbarH;_scrollX=0;_scrollY=0;_contentWidth=0;_contentHeight=0;_smooth;_shadowOverlay;_shadowEdges={top:0,bottom:0,left:0,right:0};constructor(t,r,o){this._owner=t,this._onScroll=o;let s=e.sink.createElement(`div`);e.sink.apply(s,{style:{position:`absolute`,top:`0`,left:`0`,width:`100%`,height:`100%`,overflow:`hidden`}}),e.sink.appendChild(r,s),this._clipBox=s;let l=e.sink.createElement(`div`);e.sink.apply(l,{style:{position:`absolute`,top:`0`,left:`0`,width:`100%`,transform:`translate3d(0, 0, 0)`,willChange:`transform`}}),e.sink.appendChild(s,l),this._rowsContainer=l;let u=e.sink.createElement(`div`);e.sink.apply(u,{style:{position:`absolute`,top:`0`,left:`0`,width:`100%`,height:`100%`,pointerEvents:`none`,boxShadow:a()}}),e.sink.appendChild(s,u),this._shadowOverlay=u,this._smooth=new i({read:e=>e===`x`?this._scrollX:this._scrollY,write:(e,t)=>e===`x`?this.setScrollX(t):this.setScrollY(t),clamp:(e,t)=>this.clampAxis(e,t)}),this._scrollbarV=new c(`vertical`),e.sink.appendChild(r,this._scrollbarV.getElement(!0)),this._scrollbarV.on(`scroll`,e=>{this._smooth.reset(),this.setScrollY(e)}),this._scrollbarH=new c(`horizontal`),e.sink.appendChild(r,this._scrollbarH.getElement(!0)),this._scrollbarH.on(`scroll`,e=>{this._smooth.reset(),this.setScrollX(e)}),this._owner.setTouchAction(`none`),n.addSubtreeListener(this._owner,`wheel`,{passive:!1,handler:e=>this.onWheel(e)}),this.attachTouchHandlers()}dispose(){this._scrollbarV.dispose(),this._scrollbarH.dispose()}ownedHandles(){return[this._clipBox,this._rowsContainer,this._shadowOverlay]}getRowsContainer(){return this._rowsContainer}getScrollY(){return this._scrollY}getScrollX(){return this._scrollX}setScrollY(e){let n=Math.max(0,this._contentHeight-this.effectiveViewportH()),r=t.clamp(e,0,n);return r===this._scrollY?this:(this._scrollY=r,this.updateTransform(),this._onScroll(),this)}setScrollX(e){let n=Math.max(0,this._contentWidth-this.effectiveViewportW()),r=t.clamp(e,0,n);return r===this._scrollX?this:(this._scrollX=r,this.updateTransform(),this._onScroll(),this)}clampAxis(e,n){let r=e===`x`?Math.max(0,this._contentWidth-this.effectiveViewportW()):Math.max(0,this._contentHeight-this.effectiveViewportH());return t.clamp(n,0,r)}resetWheelEase(){this._smooth.reset()}computeScrollbarVisibility(e,t){let n=this._owner.getContentBounds()??{x:0,y:0,width:this._owner.getWidth()||0,height:this._owner.getHeight()||0},r=n.height||0,i=n.width||0,a=this._scrollbarV.getTrackWidth(),o=!1,s=!1;for(let n=0;n<2;n++){let n=r-(s?a:0),c=i-(o?a:0);o=t>n,s=e>c}let c=r-(s?a:0),l=i-(o?a:0);return{vVisible:o,hVisible:s,effW:l,effH:c}}effectiveViewportH(){return this.computeScrollbarVisibility(this._contentWidth,this._contentHeight).effH}effectiveViewportW(){return this.computeScrollbarVisibility(this._contentWidth,this._contentHeight).effW}getViewportWidth(){return this.effectiveViewportW()}clampToContent(e,t){this._contentWidth=e,this._contentHeight=t;let n=Math.max(0,t-this.effectiveViewportH()),r=Math.max(0,e-this.effectiveViewportW()),i=!1;this._scrollY>n&&(this._scrollY=n,i=!0),this._scrollX>r&&(this._scrollX=r,i=!0),i&&this.updateTransform()}layoutScrollbars(t,n){this._contentWidth=t,this._contentHeight=n;let r=this._owner.getContentBounds()??{x:0,y:0,width:this._owner.getWidth()||0,height:this._owner.getHeight()||0},i=this._scrollbarV.getTrackWidth(),{effW:a,effH:o}=this.computeScrollbarVisibility(t,n),s=Math.max(0,n-o),c=Math.max(0,t-a);(this._scrollY>s||this._scrollX>c)&&(this._scrollY>s&&(this._scrollY=s),this._scrollX>c&&(this._scrollX=c),this.updateTransform()),this._scrollbarV.setX(r.x+Math.max(0,r.width-i)),this._scrollbarV.setY(r.y),this._scrollbarV.setHeight(o),this._scrollbarV.setMetrics(o,n,this._scrollY),this._scrollbarH.setX(r.x),this._scrollbarH.setY(r.y+Math.max(0,r.height-i)),this._scrollbarH.setWidth(a),this._scrollbarH.setMetrics(a,t,this._scrollX),e.sink.apply(this._clipBox,{style:{left:r.x+`px`,top:r.y+`px`,width:a+`px`,height:o+`px`}}),this.updateShadows()}updateTransform(){e.sink.apply(this._rowsContainer,{style:{transform:`translate3d(${-this._scrollX}px, ${-this._scrollY}px, 0)`}}),this.updateShadows()}updateShadows(){let{effW:e,effH:t}=this.computeScrollbarVisibility(this._contentWidth,this._contentHeight),n=Math.max(0,this._contentWidth-e),r=Math.max(0,this._contentHeight-t);this.setShadowEdge(`top`,`--ts-ss-top`,s(this._scrollY)),this.setShadowEdge(`bottom`,`--ts-ss-bottom`,s(r-this._scrollY)),this.setShadowEdge(`left`,`--ts-ss-left`,s(this._scrollX)),this.setShadowEdge(`right`,`--ts-ss-right`,s(n-this._scrollX))}setShadowEdge(t,n,r){let i=Math.round(r*100);this._shadowEdges[t]!==i&&(this._shadowEdges[t]=i,e.sink.apply(this._shadowOverlay,{style:{[n]:o(i)}}))}onWheel(e){if(r(e))return e.shiftKey&&e.deltaY!==0&&e.deltaX===0?(this._smooth.scrollBy(e.deltaY,0),{prevent:!0}):(this._smooth.scrollBy(e.deltaX,e.deltaY),{prevent:!0})}attachTouchHandlers(){let t=!1,r=0,i=0,a=0,o=0,s=[],c=null,cancelMomentum=()=>{c!==null&&(e.sink.cancelAnimationFrame(c),c=null)};n.addSubtreeListener(this._owner,`touchstart`,e=>{e.touches.length===1&&(cancelMomentum(),this._smooth.reset(),t=!0,r=e.touches[0].clientY,i=e.touches[0].clientX,a=this._scrollY,o=this._scrollX,s=[{time:performance.now(),x:i,y:r}])}),n.addSubtreeListener(this._owner,`touchmove`,e=>{if(!t||e.touches.length!==1)return;let n=e.touches[0].clientY,c=e.touches[0].clientX,l=performance.now();for(s.push({time:l,x:c,y:n});s.length>1&&s[0].time<l-150;)s.shift();this.setScrollY(a+(r-n)),this.setScrollX(o+(i-c))});let startMomentum=()=>{if(s.length<2)return;let t=s[s.length-1];if(performance.now()-t.time>50)return;let n=t.time-80,r=s.length-1;for(;r>0&&s[r-1].time>=n;)r--;let i=s[r],a=t.time-i.time;if(a<=0)return;let o=(i.y-t.y)/a,l=(i.x-t.x)/a;if(Math.sqrt(l*l+o*o)<.1)return;let u=performance.now(),step=()=>{let t=performance.now(),n=t-u;u=t;let r=.95**(n/16.667);if(o*=r,l*=r,Math.sqrt(l*l+o*o)<.02){c=null;return}let i=this._scrollY,a=this._scrollX;if(this.setScrollY(this._scrollY+o*n),this.setScrollX(this._scrollX+l*n),this._scrollY===i&&(o=0),this._scrollX===a&&(l=0),o===0&&l===0){c=null;return}c=e.sink.requestAnimationFrame(step)};c=e.sink.requestAnimationFrame(step)};n.addSubtreeListener(this._owner,`touchend`,()=>{t&&(t=!1,startMomentum())}),n.addSubtreeListener(this._owner,`touchcancel`,()=>{t=!1,cancelMomentum()})}};export{VirtualScroller as t};
|
|
2
|
+
//# sourceMappingURL=VirtualScroller-ggPTCQb0.js.map
|