@jimka/typescript-ui 0.2.0 → 0.3.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/README.md +4 -0
- package/THIRD-PARTY-NOTICES.md +7 -3
- package/dist/lib/{AbstractBooleanInput-BGesvIZy.js → AbstractBooleanInput-C3O4kv7_.js} +2 -2
- package/dist/lib/{AbstractBooleanInput-BGesvIZy.js.map → AbstractBooleanInput-C3O4kv7_.js.map} +1 -1
- package/dist/lib/{AbstractInput-BxOtFrER.js → AbstractInput-DFWniHqq.js} +2 -2
- package/dist/lib/{AbstractInput-BxOtFrER.js.map → AbstractInput-DFWniHqq.js.map} +1 -1
- package/dist/lib/AnchorConstraints-CSUcj8Wx.js +2 -0
- package/dist/lib/AnchorConstraints-CSUcj8Wx.js.map +1 -0
- package/dist/lib/{AnimatedDropdown-CZQEqQi-.js → AnimatedDropdown-e9urCXK1.js} +2 -2
- package/dist/lib/{AnimatedDropdown-CZQEqQi-.js.map → AnimatedDropdown-e9urCXK1.js.map} +1 -1
- package/dist/lib/Border-Dq6dXkmS.js +2 -0
- package/dist/lib/{Border-BgaZkc1R.js.map → Border-Dq6dXkmS.js.map} +1 -1
- package/dist/lib/{Button-U1rsP4v8.js → Button-B36rBMKC.js} +2 -2
- package/dist/lib/{Button-U1rsP4v8.js.map → Button-B36rBMKC.js.map} +1 -1
- package/dist/lib/{Card-BVwOS8AG.js → Card-P8iUH2-C.js} +2 -2
- package/dist/lib/{Card-BVwOS8AG.js.map → Card-P8iUH2-C.js.map} +1 -1
- package/dist/lib/{ComboBox-B9EDPu6T.js → ComboBox-BjAhXXkY.js} +2 -2
- package/dist/lib/{ComboBox-B9EDPu6T.js.map → ComboBox-BjAhXXkY.js.map} +1 -1
- package/dist/lib/Component-CHTzJxEf.js +2 -0
- package/dist/lib/Component-CHTzJxEf.js.map +1 -0
- package/dist/lib/Container-xUbHk6l_.js +2 -0
- package/dist/lib/{Container-D5H8VxJK.js.map → Container-xUbHk6l_.js.map} +1 -1
- package/dist/lib/DOM-BeR95tE8.js +2 -0
- package/dist/lib/DOM-BeR95tE8.js.map +1 -0
- package/dist/lib/{DragManager-CI4mZQFy.js → DragManager-T5Oljd0F.js} +2 -2
- package/dist/lib/{DragManager-CI4mZQFy.js.map → DragManager-T5Oljd0F.js.map} +1 -1
- package/dist/lib/{FieldDecorator-CJs9gwqH.js → FieldDecorator-BaTGfKiW.js} +2 -2
- package/dist/lib/{FieldDecorator-CJs9gwqH.js.map → FieldDecorator-BaTGfKiW.js.map} +1 -1
- package/dist/lib/{Fit-DjRsiwlg.js → Fit-E-EIZv1k.js} +2 -2
- package/dist/lib/{Fit-DjRsiwlg.js.map → Fit-E-EIZv1k.js.map} +1 -1
- package/dist/lib/{Glyph-KEf4nIv2.js → Glyph-CnNslL95.js} +2 -2
- package/dist/lib/{Glyph-KEf4nIv2.js.map → Glyph-CnNslL95.js.map} +1 -1
- package/dist/lib/{Grid-DdL9TVeJ.js → Grid-BXS2T8MT.js} +2 -2
- package/dist/lib/{Grid-DdL9TVeJ.js.map → Grid-BXS2T8MT.js.map} +1 -1
- package/dist/lib/{GridConstraints-DkLueyrf.js → GridConstraints-D_kbd-h2.js} +2 -2
- package/dist/lib/{GridConstraints-DkLueyrf.js.map → GridConstraints-D_kbd-h2.js.map} +1 -1
- package/dist/lib/HBox-Dm3xgsDE.js +2 -0
- package/dist/lib/{HBox-Ce0GTCJP.js.map → HBox-Dm3xgsDE.js.map} +1 -1
- package/dist/lib/{Header-BQIVpBte.js → Header-CqFc2OUx.js} +2 -2
- package/dist/lib/{Header-BQIVpBte.js.map → Header-CqFc2OUx.js.map} +1 -1
- package/dist/lib/{IconText-Bo4Qcnot.js → IconText-CTM2r0Tv.js} +2 -2
- package/dist/lib/{IconText-Bo4Qcnot.js.map → IconText-CTM2r0Tv.js.map} +1 -1
- package/dist/lib/{LayoutSerialization-BT66TY83.js → LayoutSerialization-D1OHmxSB.js} +2 -2
- package/dist/lib/{LayoutSerialization-BT66TY83.js.map → LayoutSerialization-D1OHmxSB.js.map} +1 -1
- package/dist/lib/LayoutSizes-CvMmMgHJ.js +2 -0
- package/dist/lib/LayoutSizes-CvMmMgHJ.js.map +1 -0
- package/dist/lib/List-DHeOPAK2.js +2 -0
- package/dist/lib/List-DHeOPAK2.js.map +1 -0
- package/dist/lib/MemoryStore-DT6iWWco.js +2 -0
- package/dist/lib/MemoryStore-DT6iWWco.js.map +1 -0
- package/dist/lib/{Menu-Dz4L7EKJ.js → Menu-B6ippw-p.js} +2 -2
- package/dist/lib/{Menu-Dz4L7EKJ.js.map → Menu-B6ippw-p.js.map} +1 -1
- package/dist/lib/{MenuButton-VJ5uC3c1.js → MenuButton-Bjm1OyB-.js} +2 -2
- package/dist/lib/{MenuButton-VJ5uC3c1.js.map → MenuButton-Bjm1OyB-.js.map} +1 -1
- package/dist/lib/{Panel-DzWdYwq1.js → Panel-D9lTLGqP.js} +2 -2
- package/dist/lib/{Panel-DzWdYwq1.js.map → Panel-D9lTLGqP.js.map} +1 -1
- package/dist/lib/Position-DRSlWn4Z.js +2 -0
- package/dist/lib/Position-DRSlWn4Z.js.map +1 -0
- package/dist/lib/{ProgressSpinner-zJKtGyNJ.js → ProgressSpinner-glv-29eK.js} +2 -2
- package/dist/lib/{ProgressSpinner-zJKtGyNJ.js.map → ProgressSpinner-glv-29eK.js.map} +1 -1
- package/dist/lib/{RadioButton-CYSSv4nV.js → RadioButton-R4S3c9WD.js} +2 -2
- package/dist/lib/{RadioButton-CYSSv4nV.js.map → RadioButton-R4S3c9WD.js.map} +1 -1
- package/dist/lib/{RovingTabIndex-BSZ31Vp5.js → RovingTabIndex-Dgt01LOE.js} +2 -2
- package/dist/lib/{RovingTabIndex-BSZ31Vp5.js.map → RovingTabIndex-Dgt01LOE.js.map} +1 -1
- package/dist/lib/{Scrollbar-BhtOjqkG.js → Scrollbar-CiVV3axj.js} +2 -2
- package/dist/lib/{Scrollbar-BhtOjqkG.js.map → Scrollbar-CiVV3axj.js.map} +1 -1
- package/dist/lib/{Slider-CdXm7E64.js → Slider-_JVvuQ8M.js} +2 -2
- package/dist/lib/{Slider-CdXm7E64.js.map → Slider-_JVvuQ8M.js.map} +1 -1
- package/dist/lib/{Spacer-D9NGW4QG.js → Spacer-B57i2-_G.js} +2 -2
- package/dist/lib/{Spacer-D9NGW4QG.js.map → Spacer-B57i2-_G.js.map} +1 -1
- package/dist/lib/{TabButton-CThevdY_.js → TabButton-DEypdlZf.js} +2 -2
- package/dist/lib/{TabButton-CThevdY_.js.map → TabButton-DEypdlZf.js.map} +1 -1
- package/dist/lib/Text-Bni4icFY.js +2 -0
- package/dist/lib/Text-Bni4icFY.js.map +1 -0
- package/dist/lib/{Tooltip-tkXDk5Bo.js → Tooltip-BUy6uFKN.js} +2 -2
- package/dist/lib/{Tooltip-tkXDk5Bo.js.map → Tooltip-BUy6uFKN.js.map} +1 -1
- package/dist/lib/VBox-Dr7Ge9M6.js +2 -0
- package/dist/lib/VBox-Dr7Ge9M6.js.map +1 -0
- package/dist/lib/{VirtualScroller-DwEEJE1_.js → VirtualScroller-BPy6KmSX.js} +2 -2
- package/dist/lib/{VirtualScroller-DwEEJE1_.js.map → VirtualScroller-BPy6KmSX.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/diagram.es.js.map +1 -1
- package/dist/lib/component/display.es.js +1 -1
- package/dist/lib/component/editor.es.js +3 -3
- 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 +2 -2
- package/dist/lib/component/table.es.js.map +1 -1
- package/dist/lib/component/tree.es.js +1 -1
- package/dist/lib/component/tree.es.js.map +1 -1
- package/dist/lib/core.es.js +1 -1
- package/dist/lib/core.es.js.map +1 -1
- package/dist/lib/data.es.js +1 -1
- package/dist/lib/data.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/layout.es.js.map +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/router.es.js.map +1 -1
- package/dist/lib/{VirtualRowView-BxpHQ_u8.js → selectionsEqual-2PJrcimg.js} +2 -2
- package/dist/lib/{VirtualRowView-BxpHQ_u8.js.map → selectionsEqual-2PJrcimg.js.map} +1 -1
- package/dist/lib/types/component/diagram/DiagramEdgeLayer.d.ts +14 -1
- package/dist/lib/types/component/diagram/DiagramModel.d.ts +1 -0
- package/dist/lib/types/component/diagram/DiagramNode.d.ts +4 -0
- package/dist/lib/types/component/diagram/DiagramView.d.ts +76 -5
- package/dist/lib/types/component/diagram/ElkLayoutEngine.d.ts +14 -1
- package/dist/lib/types/component/diagram/index.d.ts +2 -2
- package/dist/lib/types/component/editor/CodeEditor.d.ts +3 -2
- package/dist/lib/types/component/input/Text.d.ts +3 -1
- package/dist/lib/types/component/shared/selectionsEqual.d.ts +1 -0
- package/dist/lib/types/component/table/Column.d.ts +2 -0
- package/dist/lib/types/component/table/ColumnConfig.d.ts +1 -0
- package/dist/lib/types/component/table/Header.d.ts +1 -0
- package/dist/lib/types/component/table/Table.d.ts +20 -0
- package/dist/lib/types/component/table/cell/Header.d.ts +1 -0
- package/dist/lib/types/component/table/index.d.ts +1 -1
- package/dist/lib/types/component/tree/Tree.d.ts +1 -0
- package/dist/lib/types/core/Aria.d.ts +0 -2
- package/dist/lib/types/core/Body.d.ts +1 -0
- package/dist/lib/types/core/ClassStyleRules.d.ts +17 -0
- package/dist/lib/types/core/Component.d.ts +10 -2
- package/dist/lib/types/core/ComponentDefaults.d.ts +1 -0
- package/dist/lib/types/core/DOM.d.ts +11 -2
- package/dist/lib/types/core/ElementAttributes.d.ts +15 -0
- package/dist/lib/types/core/PendingTransitions.d.ts +4 -0
- package/dist/lib/types/core/StyleTarget.d.ts +1 -0
- package/dist/lib/types/core/Util.d.ts +2 -0
- package/dist/lib/types/core/index.d.ts +1 -0
- package/dist/lib/types/layout/Border.d.ts +1 -0
- package/dist/lib/types/layout/Tab.d.ts +4 -1
- package/dist/lib/types/layout/Table.d.ts +1 -0
- package/dist/lib/types/overlay/AbstractWindow.d.ts +1 -0
- package/dist/lib/types/router/RoutePattern.d.ts +7 -0
- package/dist/lib/types/router/Router.d.ts +13 -2
- package/dist/lib/types/router/index.d.ts +1 -1
- package/dist/lib/validation.es.js +1 -1
- package/llms.txt +1 -1
- package/package.json +4 -8
- package/dist/lib/Border-BgaZkc1R.js +0 -2
- package/dist/lib/BoxLayout-DrKGfsup.js +0 -2
- package/dist/lib/BoxLayout-DrKGfsup.js.map +0 -1
- package/dist/lib/Component-DXf5a3g0.js +0 -2
- package/dist/lib/Component-DXf5a3g0.js.map +0 -1
- package/dist/lib/Container-D5H8VxJK.js +0 -2
- package/dist/lib/DOM-CGn7xyTw.js +0 -2
- package/dist/lib/DOM-CGn7xyTw.js.map +0 -1
- package/dist/lib/HBox-Ce0GTCJP.js +0 -2
- package/dist/lib/LayoutSizes-DU3qSq0w.js +0 -2
- package/dist/lib/LayoutSizes-DU3qSq0w.js.map +0 -1
- package/dist/lib/List-DtTVTyWW.js +0 -2
- package/dist/lib/List-DtTVTyWW.js.map +0 -1
- package/dist/lib/Position-A39T7-_1.js +0 -2
- package/dist/lib/Position-A39T7-_1.js.map +0 -1
- package/dist/lib/Text-gz6qjFfP.js +0 -2
- package/dist/lib/Text-gz6qjFfP.js.map +0 -1
- package/dist/lib/VBox-EIqw85Rh.js +0 -2
- package/dist/lib/VBox-EIqw85Rh.js.map +0 -1
package/dist/lib/layout.es.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as e,o as t}from"./Position-
|
|
1
|
+
import{a as e,o as t}from"./Position-DRSlWn4Z.js";import{d as n,f as r,m as i,p as a,u as o}from"./Component-CHTzJxEf.js";import{t as s}from"./Fit-E-EIZv1k.js";import{n as c,r as l}from"./VBox-Dr7Ge9M6.js";import{t as u}from"./HBox-Dm3xgsDE.js";import{o as d}from"./LayoutSizes-CvMmMgHJ.js";import{t as f}from"./Border-Dq6dXkmS.js";import{t as p}from"./LayoutConstraints-DkctJZXB.js";import{a as m,n as h,r as g,t as _}from"./LayoutSerialization-D1OHmxSB.js";import{n as v,t as y}from"./AnchorConstraints-CSUcj8Wx.js";import{n as b,r as x,t as S}from"./GridConstraints-D_kbd-h2.js";import{t as C}from"./Grid-BXS2T8MT.js";import{t as w}from"./Card-P8iUH2-C.js";var FlowLayout=class extends n{_spacing=5;_lineSpacing=5;_uniform=`none`;_align=`start`;_itemAlign=`start`;_justify=`start`;constructor(e){super(),e&&this.applyOptions(e)}applyOptions(e){super.applyOptions(e),e.spacing!==void 0&&this.setComponentSpacing(e.spacing),e.lineSpacing!==void 0&&this.setLineSpacing(e.lineSpacing),e.uniform!==void 0&&this.setUniform(e.uniform),e.align!==void 0&&this.setAlign(e.align),e.itemAlign!==void 0&&this.setItemAlign(e.itemAlign),e.justify!==void 0&&this.setJustify(e.justify)}getComponentSpacing(){return this._spacing||0}setComponentSpacing(e){return this._spacing=e||0,this}getLineSpacing(){return this._lineSpacing||0}setLineSpacing(e){return this._lineSpacing=e||0,this}getUniform(){return this._uniform}setUniform(e){return this._uniform=e,this}getAlign(){return this._align}setAlign(e){return this._align=e,this}getItemAlign(){return this._itemAlign}setItemAlign(e){return this._itemAlign=e,this}getJustify(){return this._justify}setJustify(e){return this._justify=e,this}isUniformWidth(){return this._uniform===`width`||this._uniform===`both`}isUniformHeight(){return this._uniform===`height`||this._uniform===`both`}computeUniformExtents(e){let t=0,n=0;for(let r of e){let e=this.clampedPreferredSize(r);t=Math.max(t,e.width),n=Math.max(n,e.height)}return{width:t,height:n}}clampedPreferredSize(e){let t=e.getPreferredSize(),n=e.getMinSize(),r=e.getMaxSize(),i=t?t.width:0,a=t?t.height:0;return n&&(i=Math.max(i,n.width),a=Math.max(a,n.height)),r&&(i=Math.min(i,r.width),a=Math.min(a,r.height)),{width:i,height:a}}alignLead(e,t){let n=Math.max(0,t-e);return this._align===`center`?n/2:this._align===`end`?n:0}crossOffset(e,t,n,r,i){switch(this._itemAlign){case`center`:return Math.max(0,(t-e)/2);case`end`:return Math.max(0,t-e);case`baseline`:return r===null?0:n===null?this.nullChildY(e,r,i):r-n;default:return 0}}justifyGaps(e,t,n,r){let i=t+r*Math.max(0,e-1);if(this._justify===`start`||e<2||i>=n)return{lead:0,gap:r};let a=n-t;if(this._justify===`between`)return{lead:0,gap:a/(e-1)};let o=a/e;return{lead:o/2,gap:o}}},HFlow=class extends FlowLayout{getPreferredSize(){let e=this.getContainer();if(!e)return null;let t=e.getPerimeterSize(),n=e.getLaidOutComponents(),r=this.isUniformWidth(),i=this.isUniformHeight(),a=r||i?this.computeUniformExtents(n):{width:0,height:0},o=t.left+t.right,s=[],c=[];for(let e of n){let t=e.getPreferredSize();t&&(r||(o+=t.width),s.push(t.height),c.push(e.getBaseline()))}r&&(o+=n.length*a.width),o+=this._spacing*Math.max(0,n.length-1);let l=i?a.height:this.computeRowHeight(s,c);return l+=t.top+t.bottom,{width:o,height:l}}getMinSize(){let e=this.getContainer();if(!e)return null;let t=e.getPerimeterSize(),n=e.getLaidOutComponents(),r=0,i=[],a=[];for(let e of n){let t=e.getMinSize();t&&(r=Math.max(r,t.width),i.push(t.height),a.push(e.getBaseline()))}let o=t.left+t.right+r,s=this.computeRowHeight(i,a);return s+=t.top+t.bottom,{width:o,height:s}}getMaxSize(){let n=this.getContainer();if(!n)return null;let r=n.getPerimeterSize(),i=n.getLaidOutComponents(),a=this.isUniformWidth(),o=a?this.computeUniformExtents(i):{width:0,height:0},s=r.left+r.right,c=0,l=!1,u=!1;for(let e of i){let n=e.getMaxSize();if(!n){a||(l=!0),u=!0;continue}a||(t(n.width)?l=!0:s+=n.width),t(n.height)?u=!0:c=Math.max(c,n.height)}return a&&(s+=i.length*o.width),s+=this._spacing*Math.max(0,i.length-1),c+=r.top+r.bottom,{width:l?e:s,height:u?e:c}}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.getLineSpacing(),o=this.isUniformWidth(),s=this.isUniformHeight(),c=o||s?this.computeUniformExtents(n):{width:0,height:0},l=this.groupIntoRows(n,t.width,r.getTop(),i,a,o,s,c);this.placeRows(l,r.getLeft(),t.width,i),this.reserveContentFrame()}groupIntoRows(e,t,n,r,i,a,o,s){let c=[],l=n,u=null;for(let n of e){let e=this.clampedPreferredSize(n),d=a?s.width:e.width,f=o?s.height:e.height;u&&u.contentWidth+r+d>t&&(l+=u.rowHeight+i,u=null),u||(u={cells:[],contentWidth:0,rowHeight:0,y:l},c.push(u));let p=u.cells.length===0?Math.min(d,t):d;u.contentWidth+=u.cells.length===0?p:r+p,u.cells.push({component:n,width:p,height:f,baseline:n.getBaseline()}),u.rowHeight=Math.max(u.rowHeight,f)}return c}placeRows(e,t,n,r){for(let i of e){let e=i.cells.map(e=>e.height),o=i.cells.map(e=>e.baseline),{rowAscent:s,rowDescent:c}=this.computeRowMetrics(e,o),{lead:l,gap:u}=this.justifyGaps(i.cells.length,this.cellsMainExtent(i),n,r),d=t+(this._justify===`start`?this.alignLead(i.contentWidth,n):0)+l;for(let e of i.cells){let t=i.y+this.crossOffset(e.height,i.rowHeight,e.baseline,s,c);this.placeComponent(e.component,d,t,e.width,e.height,a.NONE),d+=e.width+u}}}cellsMainExtent(e){return e.cells.reduce((e,t)=>e+t.width,0)}},T=i(HFlow),VFlow=class extends FlowLayout{getPreferredSize(){let e=this.getContainer();if(!e)return null;let t=e.getPerimeterSize(),n=e.getLaidOutComponents(),r=this.isUniformWidth(),i=this.isUniformHeight(),a=r||i?this.computeUniformExtents(n):{width:0,height:0},o=t.top+t.bottom,s=0;for(let e of n){let t=e.getPreferredSize();t&&(i||(o+=t.height),s=Math.max(s,t.width))}i&&(o+=n.length*a.height),o+=this._spacing*Math.max(0,n.length-1);let c=r?a.width:s;return c+=t.left+t.right,{width:c,height:o}}getMinSize(){let e=this.getContainer();if(!e)return null;let t=e.getPerimeterSize(),n=e.getLaidOutComponents(),r=0,i=0;for(let e of n){let t=e.getMinSize();t&&(r=Math.max(r,t.height),i=Math.max(i,t.width))}return{width:t.left+t.right+i,height:t.top+t.bottom+r}}getMaxSize(){let n=this.getContainer();if(!n)return null;let r=n.getPerimeterSize(),i=n.getLaidOutComponents(),a=this.isUniformHeight(),o=a?this.computeUniformExtents(i):{width:0,height:0},s=r.top+r.bottom,c=0,l=!1,u=!1;for(let e of i){let n=e.getMaxSize();if(!n){a||(u=!0),l=!0;continue}a||(t(n.height)?u=!0:s+=n.height),t(n.width)?l=!0:c=Math.max(c,n.width)}return a&&(s+=i.length*o.height),s+=this._spacing*Math.max(0,i.length-1),c+=r.left+r.right,{width:l?e:c,height:u?e:s}}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.getLineSpacing(),o=this.isUniformWidth(),s=this.isUniformHeight(),c=o||s?this.computeUniformExtents(n):{width:0,height:0},l=this.groupIntoColumns(n,t.height,r.getLeft(),i,a,o,s,c);this.placeColumns(l,r.getTop(),t.height,i),this.reserveContentFrame()}groupIntoColumns(e,t,n,r,i,a,o,s){let c=[],l=n,u=null;for(let n of e){let e=this.clampedPreferredSize(n),d=a?s.width:e.width,f=o?s.height:e.height;u&&u.contentHeight+r+f>t&&(l+=u.columnWidth+i,u=null),u||(u={cells:[],contentHeight:0,columnWidth:0,x:l},c.push(u));let p=u.cells.length===0?Math.min(f,t):f;u.contentHeight+=u.cells.length===0?p:r+p,u.cells.push({component:n,width:d,height:p,baseline:null}),u.columnWidth=Math.max(u.columnWidth,d)}return c}placeColumns(e,t,n,r){for(let i of e){let{lead:e,gap:o}=this.justifyGaps(i.cells.length,this.cellsMainExtent(i),n,r),s=t+(this._justify===`start`?this.alignLead(i.contentHeight,n):0)+e;for(let e of i.cells){let t=i.x+this.crossOffset(e.width,i.columnWidth,null,null,0);this.placeComponent(e.component,t,s,e.width,e.height,a.NONE),s+=e.height+o}}}cellsMainExtent(e){return e.cells.reduce((e,t)=>e+t.height,0)}},E=i(VFlow);export{o as Absolute,x as Accordion,b as AccordionConstraints,v as Anchor,y as AnchorConstraints,r as AnchorType,f as Border,l as BoxLayout,w as Card,g as DockRegion,a as FillType,s as Fit,FlowLayout,C as Grid,S as GridConstraints,u as HBox,T as HFlow,p as LayoutConstraints,n as LayoutManager,m as Split,d as Tab,c as VBox,E as VFlow,_ as restoreLayout,h as serializeLayout};
|
|
2
2
|
//# sourceMappingURL=layout.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.es.js","names":[],"sources":["../../src/typescript/lib/layout/Anchor.ts","../../src/typescript/lib/layout/AnchorConstraints.ts","../../src/typescript/lib/layout/FlowLayout.ts","../../src/typescript/lib/layout/HFlow.ts","../../src/typescript/lib/layout/VFlow.ts"],"sourcesContent":["// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { LayoutManager, LayoutManagerOptions } from \"~/layout/LayoutManager.js\";\nimport { AnchorConstraints } from \"~/layout/AnchorConstraints.js\";\nimport { callable } from \"~/core/Callable.js\";\n\n/**\n * A length used by an {@link Anchor} constraint, expressed either in **pixels**\n * (a bare `number`) or as a **percentage** of the container's inner extent\n * (`{ percent }`, on a 0–100 scale). The percentage resolves against inner width\n * for horizontal fields (`left` / `right` / `width`) and inner height for\n * vertical fields (`top` / `bottom` / `height`).\n *\n * @category Layouts\n */\nexport type AnchorValue = number | { percent: number };\n\n/**\n * Construction-time options for {@link Anchor}.\n *\n * @category Layouts\n */\nexport interface AnchorOptions extends LayoutManagerOptions {\n}\n\n/**\n * The resolved placement of a child along one axis: a `start` offset in the\n * container's coordinate space and the `extent` (width or height) to commit.\n */\ninterface AxisResult {\n start: number;\n extent: number;\n}\n\n/**\n * A resize-reactive layout manager that positions each child by edge-relative\n * and proportional offsets, re-resolving them on every `doLayout` pass so a\n * child stays pinned to a container edge — or stretched between two edges — as\n * the container resizes. It is the reactive counterpart to the static\n * [`Absolute`](/api/layout/classes/Absolute) manager, which never reads the\n * container's inner size.\n *\n * Per child (via {@link AnchorConstraints}) an axis can: pin a fixed distance\n * from one edge (`left` / `right` / `top` / `bottom`), derive its extent from\n * the container when both opposing edges are set (stretch), or take an explicit\n * `width` / `height`. Any offset or size may be a pixel `number` or an\n * {@link AnchorValue} percentage of the container's inner extent.\n *\n * Like `Absolute`, `Anchor` commits rects directly through `commitBounds`,\n * bypassing the cell clamp — a child sized larger than the container is\n * committed at its computed size and may overflow, which a host `Panel` with\n * `autoScroll: \"auto\"` scrolls natively. It imposes no intrinsic preferred,\n * min, or max size on its host.\n *\n * @category Layouts\n */\nclass Anchor extends LayoutManager {\n\n constructor(options?: AnchorOptions) {\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 * Resolves an {@link AnchorValue} to pixels against the given extent.\n * Returns the number unchanged for a pixel value, `extent * percent / 100`\n * for a percentage tag, and `undefined` when the field is unset.\n *\n * @param value - The pixel-or-percent value, or `undefined` if unset.\n * @param extent - The container inner extent the percentage resolves against.\n * @returns The resolved pixel value, or `undefined` when `value` is unset.\n */\n private resolve(value: AnchorValue | undefined, extent: number): number | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n if (typeof value === \"number\") {\n return value;\n }\n\n // Percent is on a 0–100 (CSS-style) scale, resolved against the inner extent.\n return extent * value.percent / 100;\n }\n\n /**\n * Resolves one axis's placement from its near edge, far edge, and explicit\n * size against the container inner extent, applying the precedence rules:\n * both edges stretch (size ignored); near edge pins the start; far edge pins\n * the end; neither edge falls back to the child's own start. The `origin`\n * (the inset on this axis) is added for every anchored row but **not** for\n * the no-edge fallback, matching {@link Absolute}, which commits the child's\n * own `getX` / `getY` without an inset offset.\n *\n * @param near - Resolved `left` / `top` offset, or `undefined` if unset.\n * @param far - Resolved `right` / `bottom` offset, or `undefined` if unset.\n * @param size - Resolved explicit `width` / `height`, or `undefined` if unset.\n * @param inner - The container's inner extent on this axis.\n * @param preferred - The child's preferred extent on this axis.\n * @param ownStart - The child's own `getX` / `getY` on this axis.\n * @param origin - The inset on this axis added to anchored placements.\n * @returns The `{ start, extent }` to commit on this axis.\n */\n private resolveAxis(near: number | undefined, far: number | undefined, size: number | undefined,\n inner: number, preferred: number, ownStart: number, origin: number): AxisResult {\n if (near !== undefined && far !== undefined) {\n // Stretch between both edges; explicit size is ignored. Clamp the\n // derived extent at 0 so an over-constrained pair never goes negative.\n const extent = Math.max(0, inner - near - far);\n\n return { start: origin + near, extent };\n }\n\n const extent = size ?? preferred;\n\n if (near !== undefined) {\n return { start: origin + near, extent };\n }\n\n if (far !== undefined) {\n return { start: origin + inner - far - extent, extent };\n }\n\n // No edge constrained: keep the child's own position, like Absolute, and\n // do not add the inset origin so mixed Anchor/Absolute usage is consistent.\n return { start: ownStart, extent };\n }\n\n /**\n * Resolves each child's rect from its {@link AnchorConstraints} against the\n * container's current inner size and insets, then commits via the base\n * `commitBounds` (bypassing the cell clamp). Bails before the container\n * connects, when `getInnerSize` is still `null`.\n */\n doLayout(): void {\n const container = this.getContainer();\n\n if (!container) {\n return;\n }\n\n const inner = container.getInnerSize();\n\n if (!inner) {\n return;\n }\n\n const insets = container.getContentInsets();\n const originX = insets.getLeft();\n const originY = insets.getTop();\n\n for (const component of container.getLaidOutComponents()) {\n const cons = this.getLayoutConstraints(component) as AnchorConstraints | undefined;\n\n const preferredSize = component.getPreferredSize();\n const size = component.getSize();\n const prefW = preferredSize?.width ?? size?.width ?? 0;\n const prefH = preferredSize?.height ?? size?.height ?? 0;\n\n const xAxis = this.resolveAxis(this.resolve(cons?.left, inner.width),\n this.resolve(cons?.right, inner.width), this.resolve(cons?.width, inner.width),\n inner.width, prefW, component.getX(), originX);\n\n const yAxis = this.resolveAxis(this.resolve(cons?.top, inner.height),\n this.resolve(cons?.bottom, inner.height), this.resolve(cons?.height, inner.height),\n inner.height, prefH, component.getY(), originY);\n\n this.commitBounds(component, xAxis.start, yAxis.start, xAxis.extent, yAxis.extent);\n }\n }\n}\n\nconst AnchorCallable = callable(Anchor);\ntype AnchorCallable = Anchor;\nexport {\n Anchor as _Anchor,\n AnchorCallable as Anchor\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { LayoutConstraints } from \"~/layout/LayoutConstraints.js\";\nimport { AnchorValue } from \"~/layout/Anchor.js\";\n\n/**\n * Per-child layout constraints for components added to an {@link Anchor}\n * container. Each edge offset pins the child a fixed distance (pixels) or a\n * proportion ({@link AnchorValue} `{ percent }`, on a 0–100 scale) from that\n * side of the container's inner box; setting **both** opposing edges of an axis\n * stretches the child between them. `width` / `height` give an explicit extent\n * (pixels or percent) used when at most one edge of an axis is constrained.\n *\n * @remarks Each axis resolves independently from three inputs — the near edge,\n * the far edge, and the explicit size — against the container's inner extent\n * (post-insets) for that axis. When both edges of an axis are set, the explicit\n * size for that axis is ignored (the pair derives the extent), mirroring CSS\n * `position: absolute`. When neither edge of an axis is set, the child keeps its\n * own `getX` / `getY` on that axis, behaving like {@link Absolute} there, so an\n * application can anchor one axis and hand-place the other.\n *\n * Percentages resolve against the container's **inner** size (the same\n * coordinate space the committed rect lives in), not its border box.\n *\n * @category Layouts\n */\nexport class AnchorConstraints extends LayoutConstraints {\n\n /** Distance from the container's inner left edge to the child's left edge. */\n left?: AnchorValue;\n\n /** Distance from the container's inner right edge to the child's right edge. */\n right?: AnchorValue;\n\n /** Distance from the container's inner top edge to the child's top edge. */\n top?: AnchorValue;\n\n /** Distance from the container's inner bottom edge to the child's bottom edge. */\n bottom?: AnchorValue;\n\n /**\n * Explicit width; used when at most one horizontal edge is constrained.\n * Ignored when both {@link AnchorConstraints.left} and\n * {@link AnchorConstraints.right} are set (the pair derives the width).\n */\n width?: AnchorValue;\n\n /**\n * Explicit height; used when at most one vertical edge is constrained.\n * Ignored when both {@link AnchorConstraints.top} and\n * {@link AnchorConstraints.bottom} are set (the pair derives the height).\n */\n height?: AnchorValue;\n\n constructor() {\n super();\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { LayoutManager, LayoutManagerOptions } from \"~/layout/LayoutManager.js\";\nimport { Size } from \"~/primitive/Size.js\";\nimport { Component } from \"~/core/Component.js\";\nimport type { AxisPosition, AxisSpread } from \"~/primitive/Axis.js\";\n\n/**\n * Which axes of a {@link FlowLayout}'s cells are made uniform so wrapped items\n * line up into a grid.\n *\n * - `\"none\"` (the default) — each item keeps its own preferred size and lines\n * pack independently, so columns do not align across lines.\n * - `\"width\"` — every cell takes the widest item's width, so columns align\n * horizontally; each line still uses its own (tallest-item) height.\n * - `\"height\"` — every cell takes the tallest item's height, so lines align\n * vertically; widths still vary per item.\n * - `\"both\"` — every cell is identical (widest × tallest), a full grid.\n *\n * @category Layouts\n */\nexport type FlowUniformity = \"none\" | \"width\" | \"height\" | \"both\";\n\n/**\n * Cross-axis alignment of an item within its wrapped line's cross extent — the\n * row height for {@link HFlow}, the column width for {@link VFlow}.\n *\n * - `\"start\"` (the default) — leading cross-edge (HFlow top, VFlow left). This\n * is the original placement.\n * - `\"center\"` — centred in the line's cross extent.\n * - `\"end\"` — trailing cross-edge (HFlow bottom, VFlow right).\n * - `\"baseline\"` — {@link HFlow} only: items are aligned on their shared text\n * baseline across the row; null-baseline (graphical) items centre in the text\n * line. {@link VFlow} has no shared text baseline, so it degrades to\n * `\"start\"`.\n *\n * @remarks This positions the *cell* within the line; a child's\n * {@link AnchorType} still positions the child within its (possibly uniform)\n * cell — both apply. Flow never resizes cells, so alignment only moves them.\n *\n * @category Layouts\n */\nexport type FlowItemAlign = \"start\" | \"center\" | \"end\" | \"baseline\";\n\n/**\n * Construction-time options shared by {@link HFlow} and {@link VFlow}.\n *\n * @category Layouts\n */\nexport interface FlowLayoutOptions extends LayoutManagerOptions {\n spacing?: number;\n lineSpacing?: number;\n uniform?: FlowUniformity;\n align?: AxisPosition;\n itemAlign?: FlowItemAlign;\n justify?: AxisSpread;\n}\n\n/**\n * Abstract base for the wrapping flow layouts {@link HFlow} and {@link VFlow}.\n * Holds the axis-agnostic configuration plumbing — item spacing, line spacing,\n * cell uniformity, and line alignment — and the shared cell-measurement\n * helpers, and dispatches a {@link FlowLayoutOptions} bag.\n *\n * @remarks This deliberately does not extend {@link BoxLayout}. That base models\n * a non-wrapping single-axis box — `mode`, `stretching`, `weight`, proportional\n * shrink, and a min-total overflow inflation — none of which a wrapping flow\n * uses. The geometric algorithms (`getPreferredSize`, `getMinSize`,\n * `getMaxSize`, `doLayout`) are mirror-image per axis and stay concrete on each\n * subclass.\n *\n * @category Layouts\n */\nexport abstract class FlowLayout extends LayoutManager {\n\n // `protected`, not `private`: the subclasses' geometric methods\n // (getPreferredSize/getMinSize/getMaxSize/doLayout) read these fields\n // directly, so they must be visible to HFlow/VFlow.\n protected _spacing: number = 5;\n protected _lineSpacing: number = 5;\n protected _uniform: FlowUniformity = \"none\";\n protected _align: AxisPosition = \"start\";\n protected _itemAlign: FlowItemAlign = \"start\";\n protected _justify: AxisSpread = \"start\";\n\n /**\n * Constructs the layout manager, applying any supplied options.\n *\n * @param options - Optional construction-time configuration.\n */\n constructor(options?: FlowLayoutOptions) {\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 FlowLayoutOptions} bag after the inherited LayoutManager\n * defaults, dispatching the item and line spacings, the uniformity mode, and\n * the line alignment.\n *\n * @param options - The options bag carrying the values to apply.\n */\n protected applyOptions(options: FlowLayoutOptions): void {\n super.applyOptions(options);\n\n if (options.spacing !== undefined) {\n this.setComponentSpacing(options.spacing);\n }\n\n if (options.lineSpacing !== undefined) {\n this.setLineSpacing(options.lineSpacing);\n }\n\n if (options.uniform !== undefined) {\n this.setUniform(options.uniform);\n }\n\n if (options.align !== undefined) {\n this.setAlign(options.align);\n }\n\n if (options.itemAlign !== undefined) {\n this.setItemAlign(options.itemAlign);\n }\n\n if (options.justify !== undefined) {\n this.setJustify(options.justify);\n }\n }\n\n /**\n * Returns the pixel spacing between items along a line.\n *\n * @returns The current item spacing in pixels.\n */\n getComponentSpacing(): number {\n return this._spacing || 0;\n }\n\n /**\n * Sets the pixel spacing between items along a line.\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 the pixel spacing between wrapped lines.\n *\n * @returns The current line spacing in pixels.\n */\n getLineSpacing(): number {\n return this._lineSpacing || 0;\n }\n\n /**\n * Sets the pixel spacing between wrapped lines.\n *\n * @param lineSpacing - Spacing in pixels.\n *\n * @returns This layout manager, for method chaining.\n */\n setLineSpacing(lineSpacing: number): this {\n this._lineSpacing = lineSpacing || 0;\n\n return this;\n }\n\n /**\n * Returns which axes are made uniform so wrapped items align into a grid.\n *\n * @returns The current uniformity mode.\n */\n getUniform(): FlowUniformity {\n return this._uniform;\n }\n\n /**\n * Sets which axes are made uniform so wrapped items align into a grid.\n *\n * @param uniform - `\"width\"` aligns columns, `\"height\"` aligns rows,\n * `\"both\"` produces a full grid, `\"none\"` packs each item at its own\n * size. See {@link FlowUniformity}.\n *\n * @returns This layout manager, for method chaining.\n */\n setUniform(uniform: FlowUniformity): this {\n this._uniform = uniform;\n\n return this;\n }\n\n /**\n * Returns how each wrapped line's content block is packed along the main\n * axis within the container's inner main extent.\n *\n * @returns The current line alignment.\n */\n getAlign(): AxisPosition {\n return this._align;\n }\n\n /**\n * Sets how each wrapped line's content block is packed along the main axis.\n *\n * @param align - `\"start\"` packs at the leading edge (the default),\n * `\"center\"` centres the block, `\"end\"` packs at the trailing edge. The\n * leading/trailing edges are west/east for {@link HFlow} and north/south\n * for {@link VFlow}. See {@link AxisPosition}.\n *\n * @returns This layout manager, for method chaining.\n */\n setAlign(align: AxisPosition): this {\n this._align = align;\n\n return this;\n }\n\n /**\n * Returns how each item is aligned within its wrapped line's cross extent.\n *\n * @returns The current cross-axis item alignment.\n */\n getItemAlign(): FlowItemAlign {\n return this._itemAlign;\n }\n\n /**\n * Sets how each item is aligned within its wrapped line's cross extent — the\n * row height for {@link HFlow}, the column width for {@link VFlow}.\n *\n * @param itemAlign - `\"start\"` aligns to the leading cross-edge (the\n * default), `\"center\"` centres, `\"end\"` aligns to the trailing cross-edge,\n * `\"baseline\"` aligns text baselines across an {@link HFlow} row.\n * `\"baseline\"` degrades to `\"start\"` on {@link VFlow}, which has no shared\n * text baseline. See {@link FlowItemAlign}.\n *\n * @returns This layout manager, for method chaining.\n */\n setItemAlign(itemAlign: FlowItemAlign): this {\n this._itemAlign = itemAlign;\n\n return this;\n }\n\n /**\n * Returns how each wrapped line's items are distributed along the main axis.\n *\n * @returns The current main-axis distribution.\n */\n getJustify(): AxisSpread {\n return this._justify;\n }\n\n /**\n * Sets how each wrapped line's items are distributed along the main axis by\n * growing the inter-item gaps.\n *\n * @param justify - `\"start\"` packs items with the fixed `spacing` (the\n * default), `\"between\"` makes the first/last items flush to the edges with\n * equal interior gaps, `\"around\"` puts an equal gap around every item. See\n * {@link AxisSpread}.\n *\n * @returns This layout manager, for method chaining.\n *\n * @remarks When `justify` is `\"between\"` or `\"around\"` the line fills the\n * inner main extent, so it owns the residual and {@link AxisPosition} (the\n * `align` option) is ignored. A single-item or over-long line degrades to\n * `\"start\"`.\n */\n setJustify(justify: AxisSpread): this {\n this._justify = justify;\n\n return this;\n }\n\n /**\n * Whether cells are made uniform on the horizontal axis (columns align).\n *\n * @returns `true` for the `\"width\"` and `\"both\"` uniformity modes.\n */\n protected isUniformWidth(): boolean {\n return this._uniform === \"width\" || this._uniform === \"both\";\n }\n\n /**\n * Whether cells are made uniform on the vertical axis (rows align).\n *\n * @returns `true` for the `\"height\"` and `\"both\"` uniformity modes.\n */\n protected isUniformHeight(): boolean {\n return this._uniform === \"height\" || this._uniform === \"both\";\n }\n\n /**\n * Computes the uniform cell extent: the widest and tallest clamped preferred\n * size across the children, used to size cells in a `uniform` mode.\n *\n * @param components - The children sharing the flow.\n * @returns The `{width, height}` every uniform cell uses on its axis.\n */\n protected computeUniformExtents(components: Component[]): Size {\n let width = 0;\n let height = 0;\n\n for (const component of components) {\n const cell = this.clampedPreferredSize(component);\n\n width = Math.max(width, cell.width);\n height = Math.max(height, cell.height);\n }\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Resolves a child's placed size: its preferred size clamped to its own\n * min and max sizes.\n *\n * @param component - The child to measure.\n * @returns The clamped `{width, height}`.\n */\n protected clampedPreferredSize(component: Component): Size {\n const pref = component.getPreferredSize();\n const min = component.getMinSize();\n const max = component.getMaxSize();\n\n let width = pref ? pref.width : 0;\n let height = pref ? pref.height : 0;\n\n if (min) {\n width = Math.max(width, min.width);\n height = Math.max(height, min.height);\n }\n\n if (max) {\n width = Math.min(width, max.width);\n height = Math.min(height, max.height);\n }\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Computes the per-line leading offset that packs a content block of the\n * given main extent within the inner main extent per the alignment mode.\n *\n * @param contentMain - The line's content main-extent (sum of placed cell\n * main-extents plus inter-item spacing).\n * @param innerMain - The container's inner extent along the main axis.\n * @returns The leading offset in pixels — `0` for `\"start\"`, half the\n * residual for `\"center\"`, the full residual for `\"end\"`. An over-long\n * line (content exceeding the inner extent) clamps to `0`.\n */\n protected alignLead(contentMain: number, innerMain: number): number {\n const residual = Math.max(0, innerMain - contentMain);\n\n if (this._align === \"center\") {\n return residual / 2;\n }\n\n if (this._align === \"end\") {\n return residual;\n }\n\n return 0;\n }\n\n /**\n * Computes the leading cross-axis offset that positions a cell within its\n * line's cross extent per the {@link FlowItemAlign} mode. The caller adds\n * this to the line's leading cross-edge (the row top for {@link HFlow}, the\n * column left for {@link VFlow}).\n *\n * @param cellExtent - The cell's own cross extent (its height for HFlow, its\n * width for VFlow).\n * @param lineExtent - The line's cross extent (the row height for HFlow, the\n * column width for VFlow); always at least `cellExtent`.\n * @param baseline - The cell's own baseline, or `null` for a graphical cell.\n * Only consulted for `\"baseline\"`.\n * @param rowAscent - The line's text baseline from `computeRowMetrics`, or\n * `null` when no cell reports one (always `null` for VFlow). Only consulted\n * for `\"baseline\"`.\n * @param rowDescent - The line's text descent from `computeRowMetrics`. Only\n * consulted for `\"baseline\"`.\n * @returns The leading offset in pixels — `0` for `\"start\"`, and never\n * negative.\n *\n * @remarks The `\"baseline\"` arm mirrors HBox's per-child baseline placement:\n * a text-bearing cell aligns on `rowAscent - baseline`, a null-baseline cell\n * centres in the text line, and a baseline-less line (`rowAscent === null`,\n * the VFlow case) falls back to `\"start\"`.\n */\n protected crossOffset(cellExtent: number, lineExtent: number, baseline: number | null, rowAscent: number | null, rowDescent: number): number {\n switch (this._itemAlign) {\n case \"center\":\n return Math.max(0, (lineExtent - cellExtent) / 2);\n\n case \"end\":\n return Math.max(0, lineExtent - cellExtent);\n\n case \"baseline\":\n if (rowAscent === null) {\n return 0;\n }\n\n return baseline !== null\n ? rowAscent - baseline\n : this.nullChildY(cellExtent, rowAscent, rowDescent);\n\n case \"start\":\n default:\n return 0;\n }\n }\n\n /**\n * Computes the per-line main-axis spacing under the active\n * {@link AxisSpread} mode.\n *\n * @param itemCount - The number of cells in the line.\n * @param contentMain - The sum of the cells' main extents (no spacing).\n * @param innerMain - The container's inner extent along the main axis.\n * @param spacing - The fixed inter-item spacing in pixels.\n * @returns `{ lead, gap }` — `lead` is the offset before the first item and\n * `gap` the spacing between successive items.\n *\n * @remarks Degrades to the fixed `spacing` (and `lead` `0`) for `\"start\"`,\n * single-item lines, and over-long lines, so the gaps are never negative. For\n * the distribution modes the line fills the inner extent, so the caller must\n * skip the `align` block move.\n */\n protected justifyGaps(itemCount: number, contentMain: number, innerMain: number, spacing: number): { lead: number; gap: number } {\n // Degrade to fixed spacing: start mode, fewer than two items, or content\n // already filling (or exceeding) the inner extent — no positive residual\n // to distribute.\n const fixedTotal = contentMain + spacing * Math.max(0, itemCount - 1);\n\n if (this._justify === \"start\" || itemCount < 2 || fixedTotal >= innerMain) {\n return { lead: 0, gap: spacing };\n }\n\n // The total gap budget to distribute, always positive here.\n const free = innerMain - contentMain;\n\n if (this._justify === \"between\") {\n return { lead: 0, gap: free / (itemCount - 1) };\n }\n\n // \"around\": one whole gap per item, split as half-gaps at the two ends.\n const unit = free / itemCount;\n\n return { lead: unit / 2, gap: unit };\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { FlowLayout, FlowLayoutOptions } from \"~/layout/FlowLayout.js\";\nimport { FillType } from \"~/layout/FillType.js\";\nimport { Size, UNBOUNDED, isUnbounded } from \"~/primitive/Size.js\";\nimport { Component } from \"~/core/Component.js\";\nimport { callable } from \"~/core/Callable.js\";\n\n/**\n * Construction-time options for {@link HFlow}.\n *\n * @remarks Inherits every flow field (`spacing`, `lineSpacing`, `uniform`,\n * `align`, `itemAlign`, `justify`) from {@link FlowLayoutOptions}; `HFlow` adds\n * none of its own.\n *\n * @category Layouts\n */\nexport interface HFlowOptions extends FlowLayoutOptions {}\n\n/**\n * One wrapped row of an {@link HFlow}: its ordered cells (each with the width it\n * was placed at, its own cell height, and its baseline for `\"baseline\"`\n * item-alignment), the row's total content width, the row height (tallest cell),\n * and the row's top in the container's coordinate space.\n */\ninterface HFlowRow {\n cells: Array<{ component: Component; width: number; height: number; baseline: number | null }>;\n contentWidth: number;\n rowHeight: number;\n y: number;\n}\n\n/**\n * A layout manager that packs children in horizontal rows, wrapping to a new\n * line when the next child would exceed the container's inner width. Unlike\n * {@link HBox} it never shrinks or stretches children: each keeps its preferred\n * size and lines stack downward. A scroll-enabled host (`Panel.setAutoScroll`)\n * gains a vertical scrollbar once the stacked lines exceed its inner height.\n *\n * @remarks Shares its flow configuration (item/line spacing, cell uniformity,\n * line alignment) with {@link VFlow} through the {@link FlowLayout} base. The\n * `uniform` option grows every cell to the widest and/or tallest item so wrapped\n * items line up into a grid; each item is positioned within its cell by its own\n * {@link AnchorType} constraint (default centre). The `align` option packs each\n * row's content block at the west edge (`\"start\"`, the default), centred, or the\n * east edge; `justify` instead spreads the row's items across the inner width\n * (`\"between\"`/`\"around\"`), and `itemAlign` positions each item within the row\n * height (including `\"baseline\"`, which aligns text baselines across the row) —\n * the scroll extent comes entirely from the children's committed positions read\n * by `reserveContentFrame`.\n *\n * @category Layouts\n */\nclass HFlow extends FlowLayout {\n\n /**\n * Returns the preferred size: the single-line shape of the children — the\n * sum of their preferred widths plus item spacing, and the baseline-aware\n * row height of the tallest child. In a `uniform` width mode the width is\n * instead `count * columnWidth`; in a `uniform` height mode the height is\n * the tallest cell.\n *\n * @returns The preferred `{width, height}`, or `null` if no container is attached.\n *\n * @remarks This is an approximation. The real height depends on how many\n * lines the children wrap into, which is only known once the parent assigns\n * a width — unavailable when the hint is queried. The parent absorbs the\n * difference: a scroll-enabled host scrolls vertically when the real wrapped\n * height exceeds this single-line estimate.\n */\n getPreferredSize(): 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 const uniformWidth = this.isUniformWidth();\n const uniformHeight = this.isUniformHeight();\n const extents = (uniformWidth || uniformHeight) ? this.computeUniformExtents(components) : { width: 0, height: 0 };\n\n let width = perimeterSize.left + perimeterSize.right;\n const heights: number[] = [];\n const baselines: Array<number | null> = [];\n\n for (const component of components) {\n const size = component.getPreferredSize();\n\n if (size) {\n if (!uniformWidth) {\n width += size.width;\n }\n\n heights.push(size.height);\n baselines.push(component.getBaseline());\n }\n }\n\n if (uniformWidth) {\n width += components.length * extents.width;\n }\n\n width += this._spacing * Math.max(0, components.length - 1);\n\n let height = uniformHeight ? extents.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: the widest child's min width (the floor below\n * which not even one child per line fits) and the baseline-aware row height\n * of the children's min heights.\n *\n * @returns The minimum `{width, height}`, or `null` if no container is attached.\n */\n getMinSize(): 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 let maxChildMinWidth = 0;\n const heights: number[] = [];\n const baselines: Array<number | null> = [];\n\n for (const component of components) {\n const 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 const width = perimeterSize.left + perimeterSize.right + maxChildMinWidth;\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 flow can usefully occupy: with every child on\n * one line the width is the sum of the children's *maximum* widths (or\n * `count * columnWidth` in a `uniform` width mode) plus item spacing, and the\n * height is the *largest* child maximum — the tallest a single row can grow\n * to. A child whose maximum is `null` or at the unbounded sentinel makes that\n * axis unbounded.\n *\n * @returns The maximum `{width, height}`, or `null` if no container is attached.\n */\n getMaxSize(): 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 const uniformWidth = this.isUniformWidth();\n const extents = uniformWidth ? this.computeUniformExtents(components) : { width: 0, height: 0 };\n\n let width = perimeterSize.left + perimeterSize.right;\n let height = 0;\n let widthUnbounded = false;\n let heightUnbounded = false;\n\n for (const component of components) {\n const max = component.getMaxSize();\n\n if (!max) {\n if (!uniformWidth) {\n widthUnbounded = true;\n }\n heightUnbounded = true;\n continue;\n }\n\n if (!uniformWidth) {\n if (isUnbounded(max.width)) {\n widthUnbounded = true;\n } else {\n width += max.width;\n }\n }\n\n if (isUnbounded(max.height)) {\n heightUnbounded = true;\n } else {\n height = Math.max(height, max.height);\n }\n }\n\n if (uniformWidth) {\n width += components.length * extents.width;\n }\n\n width += this._spacing * Math.max(0, components.length - 1);\n height += perimeterSize.top + perimeterSize.bottom;\n\n return {\n width: widthUnbounded ? UNBOUNDED : width,\n height: heightUnbounded ? UNBOUNDED : height\n };\n }\n\n /**\n * Packs the children left-to-right at their cell size, wrapping to a new\n * line when the next cell's right edge would exceed the inner width, then\n * places each row's content block per the `align` mode. In a `uniform` mode\n * every cell grows to the widest and/or tallest item so the wrapped items\n * line up into a grid. A scroll-enabled host then scrolls the overflow via\n * `reserveContentFrame`, which sizes the content frame to the children's\n * committed extent.\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 insets = container.getContentInsets();\n const spacing = this.getComponentSpacing();\n const lineSpacing = this.getLineSpacing();\n\n const uniformWidth = this.isUniformWidth();\n const uniformHeight = this.isUniformHeight();\n const extents = (uniformWidth || uniformHeight) ? this.computeUniformExtents(components) : { width: 0, height: 0 };\n\n const rows = this.groupIntoRows(components, innerSize.width, insets.getTop(), spacing, lineSpacing, uniformWidth, uniformHeight, extents);\n\n this.placeRows(rows, insets.getLeft(), innerSize.width, spacing);\n\n this.reserveContentFrame();\n }\n\n /**\n * Phase 1 of {@link HFlow.doLayout}: walks the children left-to-right,\n * wrapping into rows, and records each row's cells, content width, height,\n * and top — without committing any bounds. A first cell wider than the inner\n * width is clamped to that width so its right edge stays inside a scrolling\n * host.\n *\n * @param components - The children to place, in order.\n * @param innerWidth - The container's inner width (the wrap threshold).\n * @param topInset - The container's top content inset (the first row's top).\n * @param spacing - Inter-item horizontal spacing in pixels.\n * @param lineSpacing - Inter-row vertical spacing in pixels.\n * @param uniformWidth - Whether cells take the uniform width.\n * @param uniformHeight - Whether cells take the uniform height.\n * @param extents - The uniform cell extents, when a uniform mode is active.\n * @returns The ordered rows ready for {@link HFlow.placeRows}.\n */\n private groupIntoRows(components: Component[], innerWidth: number, topInset: number, spacing: number, lineSpacing: number, uniformWidth: boolean, uniformHeight: boolean, extents: Size): HFlowRow[] {\n const rows: HFlowRow[] = [];\n let y = topInset;\n let current: HFlowRow | null = null;\n\n for (const component of components) {\n const cell = this.clampedPreferredSize(component);\n const cellWidth = uniformWidth ? extents.width : cell.width;\n const cellHeight = uniformHeight ? extents.height : cell.height;\n\n // Wrap before placing when the current row is non-empty and this\n // cell's right edge (including the joining spacing) would spill past\n // the inner width.\n if (current && current.contentWidth + spacing + cellWidth > innerWidth) {\n y += current.rowHeight + lineSpacing;\n current = null;\n }\n\n if (!current) {\n current = { cells: [], contentWidth: 0, rowHeight: 0, y: y };\n\n rows.push(current);\n }\n\n // A cell wider than the inner width occupies its own line clamped to\n // that width, so its right edge stays inside a scrolling host.\n const placedWidth = (current.cells.length === 0) ? Math.min(cellWidth, innerWidth) : cellWidth;\n\n current.contentWidth += (current.cells.length === 0) ? placedWidth : spacing + placedWidth;\n current.cells.push({ component: component, width: placedWidth, height: cellHeight, baseline: component.getBaseline() });\n current.rowHeight = Math.max(current.rowHeight, cellHeight);\n }\n\n return rows;\n }\n\n /**\n * Phase 2 of {@link HFlow.doLayout}: distributes each row's cells along the\n * main axis per the `justify` mode (or packs them at the `align` offset when\n * `justify` is `\"start\"`), and positions each cell within the row height per\n * the `itemAlign` mode. Each child keeps its preferred size (`FillType.NONE`);\n * its own {@link AnchorType} positions it within its cell.\n *\n * @param rows - The rows produced by {@link HFlow.groupIntoRows}.\n * @param leftInset - The container's left content inset (the row's leading edge).\n * @param innerWidth - The container's inner width (for the alignment residual).\n * @param spacing - Inter-item horizontal spacing in pixels.\n */\n private placeRows(rows: HFlowRow[], leftInset: number, innerWidth: number, spacing: number): void {\n for (const row of rows) {\n // Row text metrics for \"baseline\" itemAlign (cheap; only used then).\n const heights = row.cells.map(cell => cell.height);\n const baselines = row.cells.map(cell => cell.baseline);\n\n const { rowAscent, rowDescent } = this.computeRowMetrics(heights, baselines);\n\n const { lead, gap } = this.justifyGaps(row.cells.length, this.cellsMainExtent(row), innerWidth, spacing);\n\n // A justify mode fills the inner extent and owns the residual, so the\n // align block move only applies when justify === \"start\".\n const blockLead = this._justify === \"start\"\n ? this.alignLead(row.contentWidth, innerWidth)\n : 0;\n\n let x = leftInset + blockLead + lead;\n\n for (const cell of row.cells) {\n const y = row.y + this.crossOffset(cell.height, row.rowHeight, cell.baseline, rowAscent, rowDescent);\n\n this.placeComponent(cell.component, x, y, cell.width, cell.height, FillType.NONE);\n\n x += cell.width + gap;\n }\n }\n }\n\n /**\n * Sums a row's cell widths without the inter-item spacing — the content\n * main-extent {@link FlowLayout.justifyGaps} distributes the residual around.\n *\n * @param row - The row to measure.\n * @returns The total cell width in pixels.\n */\n private cellsMainExtent(row: HFlowRow): number {\n return row.cells.reduce((sum, cell) => sum + cell.width, 0);\n }\n}\n\nconst HFlowCallable = callable(HFlow);\ntype HFlowCallable = HFlow;\nexport {\n HFlow as _HFlow,\n HFlowCallable as HFlow\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { FlowLayout, FlowLayoutOptions } from \"~/layout/FlowLayout.js\";\nimport { FillType } from \"~/layout/FillType.js\";\nimport { Size, UNBOUNDED, isUnbounded } from \"~/primitive/Size.js\";\nimport { Component } from \"~/core/Component.js\";\nimport { callable } from \"~/core/Callable.js\";\n\n/**\n * Construction-time options for {@link VFlow}.\n *\n * @remarks Inherits every flow field (`spacing`, `lineSpacing`, `uniform`,\n * `align`, `itemAlign`, `justify`) from {@link FlowLayoutOptions}; `VFlow` adds\n * none of its own. `spacing` is the vertical gap between items in a column;\n * `lineSpacing` is the horizontal gap between wrapped columns.\n *\n * @category Layouts\n */\nexport interface VFlowOptions extends FlowLayoutOptions {}\n\n/**\n * One wrapped column of a {@link VFlow}: its ordered cells (each with its own\n * cell width and the height it was placed at; `baseline` is always `null` since\n * a column exposes no shared text baseline), the column's total content height,\n * the column width (widest cell), and the column's left in the container's\n * coordinate space.\n */\ninterface VFlowColumn {\n cells: Array<{ component: Component; width: number; height: number; baseline: number | null }>;\n contentHeight: number;\n columnWidth: number;\n x: number;\n}\n\n/**\n * A layout manager that packs children in vertical columns, wrapping to a new\n * column when the next child would exceed the container's inner height. The\n * vertical transpose of {@link HFlow}: where `HFlow` packs rows left-to-right\n * and wraps downward, `VFlow` packs columns top-to-bottom and wraps rightward.\n * Like `HFlow` it never shrinks or stretches children — each keeps its preferred\n * size. A scroll-enabled host (`Panel.setAutoScroll`) gains a horizontal\n * scrollbar once the columns exceed its inner width.\n *\n * @remarks Shares its flow configuration (item/line spacing, cell uniformity,\n * line alignment) with `HFlow` through the {@link FlowLayout} base. Here\n * `spacing` is the vertical gap between items in a column and `lineSpacing` the\n * horizontal gap between columns. The `align` option packs each column's content\n * block at the north edge (`\"start\"`, the default), centred, or the south edge;\n * `justify` instead spreads the column's items across the inner height\n * (`\"between\"`/`\"around\"`), and `itemAlign` positions each item within the\n * column width. A wrapped column exposes no shared text baseline, so the cross\n * axis (width) uses a plain widest-cell measure and `itemAlign: \"baseline\"`\n * degrades to `\"start\"`.\n *\n * @category Layouts\n */\nclass VFlow extends FlowLayout {\n\n /**\n * Returns the preferred size: the single-column shape of the children — the\n * sum of their preferred heights plus item spacing, and the widest child's\n * width. In a `uniform` height mode the height is instead `count * rowHeight`;\n * in a `uniform` width mode the width is the widest cell.\n *\n * @returns The preferred `{width, height}`, or `null` if no container is attached.\n *\n * @remarks This is an approximation. The real width depends on how many\n * columns the children wrap into, which is only known once the parent\n * assigns a height — unavailable when the hint is queried. A scroll-enabled\n * host scrolls horizontally when the real wrapped width exceeds this\n * single-column estimate.\n */\n getPreferredSize(): 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 const uniformWidth = this.isUniformWidth();\n const uniformHeight = this.isUniformHeight();\n const extents = (uniformWidth || uniformHeight) ? this.computeUniformExtents(components) : { width: 0, height: 0 };\n\n let height = perimeterSize.top + perimeterSize.bottom;\n let maxWidth = 0;\n\n for (const component of components) {\n const size = component.getPreferredSize();\n\n if (size) {\n if (!uniformHeight) {\n height += size.height;\n }\n\n maxWidth = Math.max(maxWidth, size.width);\n }\n }\n\n if (uniformHeight) {\n height += components.length * extents.height;\n }\n\n height += this._spacing * Math.max(0, components.length - 1);\n\n let width = uniformWidth ? extents.width : maxWidth;\n\n width += perimeterSize.left + perimeterSize.right;\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Returns the minimum size: the tallest child's min height (the floor below\n * which not even one child per column fits) and the widest child's min\n * width.\n *\n * @returns The minimum `{width, height}`, or `null` if no container is attached.\n */\n getMinSize(): 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 let maxChildMinHeight = 0;\n let maxWidth = 0;\n\n for (const component of components) {\n const size = component.getMinSize();\n\n if (size) {\n maxChildMinHeight = Math.max(maxChildMinHeight, size.height);\n maxWidth = Math.max(maxWidth, size.width);\n }\n }\n\n const width = perimeterSize.left + perimeterSize.right + maxWidth;\n const height = perimeterSize.top + perimeterSize.bottom + maxChildMinHeight;\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Returns the maximum size the flow can usefully occupy: with every child in\n * one column the height is the sum of the children's *maximum* heights (or\n * `count * rowHeight` in a `uniform` height mode) plus item spacing, and the\n * width is the *largest* child maximum — the widest a single column can grow\n * to. A child whose maximum is `null` or at the unbounded sentinel makes that\n * axis unbounded.\n *\n * @returns The maximum `{width, height}`, or `null` if no container is attached.\n */\n getMaxSize(): 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 const uniformHeight = this.isUniformHeight();\n const extents = uniformHeight ? this.computeUniformExtents(components) : { width: 0, height: 0 };\n\n let height = perimeterSize.top + perimeterSize.bottom;\n let width = 0;\n let widthUnbounded = false;\n let heightUnbounded = false;\n\n for (const component of components) {\n const max = component.getMaxSize();\n\n if (!max) {\n if (!uniformHeight) {\n heightUnbounded = true;\n }\n widthUnbounded = true;\n continue;\n }\n\n if (!uniformHeight) {\n if (isUnbounded(max.height)) {\n heightUnbounded = true;\n } else {\n height += max.height;\n }\n }\n\n if (isUnbounded(max.width)) {\n widthUnbounded = true;\n } else {\n width = Math.max(width, max.width);\n }\n }\n\n if (uniformHeight) {\n height += components.length * extents.height;\n }\n\n height += this._spacing * Math.max(0, components.length - 1);\n width += perimeterSize.left + perimeterSize.right;\n\n return {\n width: widthUnbounded ? UNBOUNDED : width,\n height: heightUnbounded ? UNBOUNDED : height\n };\n }\n\n /**\n * Packs the children top-to-bottom at their cell size, wrapping to a new\n * column when the next cell's bottom edge would exceed the inner height, then\n * places each column's content block per the `align` mode. In a `uniform`\n * mode every cell grows to the widest and/or tallest item so the wrapped\n * items line up into a grid. A scroll-enabled host then scrolls the overflow\n * via `reserveContentFrame`, which sizes the content frame to the children's\n * committed extent.\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 insets = container.getContentInsets();\n const spacing = this.getComponentSpacing();\n const lineSpacing = this.getLineSpacing();\n\n const uniformWidth = this.isUniformWidth();\n const uniformHeight = this.isUniformHeight();\n const extents = (uniformWidth || uniformHeight) ? this.computeUniformExtents(components) : { width: 0, height: 0 };\n\n const columns = this.groupIntoColumns(components, innerSize.height, insets.getLeft(), spacing, lineSpacing, uniformWidth, uniformHeight, extents);\n\n this.placeColumns(columns, insets.getTop(), innerSize.height, spacing);\n\n this.reserveContentFrame();\n }\n\n /**\n * Phase 1 of {@link VFlow.doLayout}: walks the children top-to-bottom,\n * wrapping into columns, and records each column's cells, content height,\n * width, and left — without committing any bounds. A first cell taller than\n * the inner height is clamped to that height so its bottom edge stays inside\n * a scrolling host.\n *\n * @param components - The children to place, in order.\n * @param innerHeight - The container's inner height (the wrap threshold).\n * @param leftInset - The container's left content inset (the first column's left).\n * @param spacing - Inter-item vertical spacing in pixels.\n * @param lineSpacing - Inter-column horizontal spacing in pixels.\n * @param uniformWidth - Whether cells take the uniform width.\n * @param uniformHeight - Whether cells take the uniform height.\n * @param extents - The uniform cell extents, when a uniform mode is active.\n * @returns The ordered columns ready for {@link VFlow.placeColumns}.\n */\n private groupIntoColumns(components: Component[], innerHeight: number, leftInset: number, spacing: number, lineSpacing: number, uniformWidth: boolean, uniformHeight: boolean, extents: Size): VFlowColumn[] {\n const columns: VFlowColumn[] = [];\n let x = leftInset;\n let current: VFlowColumn | null = null;\n\n for (const component of components) {\n const cell = this.clampedPreferredSize(component);\n const cellWidth = uniformWidth ? extents.width : cell.width;\n const cellHeight = uniformHeight ? extents.height : cell.height;\n\n // Wrap before placing when the current column is non-empty and this\n // cell's bottom edge (including the joining spacing) would spill past\n // the inner height.\n if (current && current.contentHeight + spacing + cellHeight > innerHeight) {\n x += current.columnWidth + lineSpacing;\n current = null;\n }\n\n if (!current) {\n current = { cells: [], contentHeight: 0, columnWidth: 0, x: x };\n\n columns.push(current);\n }\n\n // A cell taller than the inner height occupies its own column clamped\n // to that height, so its bottom edge stays inside a scrolling host.\n const placedHeight = (current.cells.length === 0) ? Math.min(cellHeight, innerHeight) : cellHeight;\n\n current.contentHeight += (current.cells.length === 0) ? placedHeight : spacing + placedHeight;\n current.cells.push({ component: component, width: cellWidth, height: placedHeight, baseline: null });\n current.columnWidth = Math.max(current.columnWidth, cellWidth);\n }\n\n return columns;\n }\n\n /**\n * Phase 2 of {@link VFlow.doLayout}: distributes each column's cells along\n * the main axis per the `justify` mode (or packs them at the `align` offset\n * when `justify` is `\"start\"`), and positions each cell within the column\n * width per the `itemAlign` mode. The cross axis is width, which has no text\n * baseline, so `\"baseline\"` degrades to `\"start\"`. Each child keeps its\n * preferred size (`FillType.NONE`); its own {@link AnchorType} positions it\n * within its cell.\n *\n * @param columns - The columns produced by {@link VFlow.groupIntoColumns}.\n * @param topInset - The container's top content inset (the column's leading edge).\n * @param innerHeight - The container's inner height (for the alignment residual).\n * @param spacing - Inter-item vertical spacing in pixels.\n */\n private placeColumns(columns: VFlowColumn[], topInset: number, innerHeight: number, spacing: number): void {\n for (const column of columns) {\n const { lead, gap } = this.justifyGaps(column.cells.length, this.cellsMainExtent(column), innerHeight, spacing);\n\n // A justify mode fills the inner extent and owns the residual, so the\n // align block move only applies when justify === \"start\".\n const blockLead = this._justify === \"start\"\n ? this.alignLead(column.contentHeight, innerHeight)\n : 0;\n\n let y = topInset + blockLead + lead;\n\n for (const cell of column.cells) {\n // rowAscent null → \"baseline\" degrades to \"start\"; cross axis is width.\n const x = column.x + this.crossOffset(cell.width, column.columnWidth, null, null, 0);\n\n this.placeComponent(cell.component, x, y, cell.width, cell.height, FillType.NONE);\n\n y += cell.height + gap;\n }\n }\n }\n\n /**\n * Sums a column's cell heights without the inter-item spacing — the content\n * main-extent {@link FlowLayout.justifyGaps} distributes the residual around.\n *\n * @param column - The column to measure.\n * @returns The total cell height in pixels.\n */\n private cellsMainExtent(column: VFlowColumn): number {\n return column.cells.reduce((sum, cell) => sum + cell.height, 0);\n }\n}\n\nconst VFlowCallable = callable(VFlow);\ntype VFlowCallable = VFlow;\nexport {\n VFlow as _VFlow,\n VFlowCallable as VFlow\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"layout.es.js","names":[],"sources":["../../src/typescript/lib/layout/FlowLayout.ts","../../src/typescript/lib/layout/HFlow.ts","../../src/typescript/lib/layout/VFlow.ts"],"sourcesContent":["// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { LayoutManager, LayoutManagerOptions } from \"~/layout/LayoutManager.js\";\nimport { Size } from \"~/primitive/Size.js\";\nimport { Component } from \"~/core/Component.js\";\nimport type { AxisPosition, AxisSpread } from \"~/primitive/Axis.js\";\n\n/**\n * Which axes of a {@link FlowLayout}'s cells are made uniform so wrapped items\n * line up into a grid.\n *\n * - `\"none\"` (the default) — each item keeps its own preferred size and lines\n * pack independently, so columns do not align across lines.\n * - `\"width\"` — every cell takes the widest item's width, so columns align\n * horizontally; each line still uses its own (tallest-item) height.\n * - `\"height\"` — every cell takes the tallest item's height, so lines align\n * vertically; widths still vary per item.\n * - `\"both\"` — every cell is identical (widest × tallest), a full grid.\n *\n * @category Layouts\n */\nexport type FlowUniformity = \"none\" | \"width\" | \"height\" | \"both\";\n\n/**\n * Cross-axis alignment of an item within its wrapped line's cross extent — the\n * row height for {@link HFlow}, the column width for {@link VFlow}.\n *\n * - `\"start\"` (the default) — leading cross-edge (HFlow top, VFlow left). This\n * is the original placement.\n * - `\"center\"` — centred in the line's cross extent.\n * - `\"end\"` — trailing cross-edge (HFlow bottom, VFlow right).\n * - `\"baseline\"` — {@link HFlow} only: items are aligned on their shared text\n * baseline across the row; null-baseline (graphical) items centre in the text\n * line. {@link VFlow} has no shared text baseline, so it degrades to\n * `\"start\"`.\n *\n * @remarks This positions the *cell* within the line; a child's\n * {@link AnchorType} still positions the child within its (possibly uniform)\n * cell — both apply. Flow never resizes cells, so alignment only moves them.\n *\n * @category Layouts\n */\nexport type FlowItemAlign = \"start\" | \"center\" | \"end\" | \"baseline\";\n\n/**\n * Construction-time options shared by {@link HFlow} and {@link VFlow}.\n *\n * @category Layouts\n */\nexport interface FlowLayoutOptions extends LayoutManagerOptions {\n spacing?: number;\n lineSpacing?: number;\n uniform?: FlowUniformity;\n align?: AxisPosition;\n itemAlign?: FlowItemAlign;\n justify?: AxisSpread;\n}\n\n/**\n * Abstract base for the wrapping flow layouts {@link HFlow} and {@link VFlow}.\n * Holds the axis-agnostic configuration plumbing — item spacing, line spacing,\n * cell uniformity, and line alignment — and the shared cell-measurement\n * helpers, and dispatches a {@link FlowLayoutOptions} bag.\n *\n * @remarks This deliberately does not extend {@link BoxLayout}. That base models\n * a non-wrapping single-axis box — `mode`, `stretching`, `weight`, proportional\n * shrink, and a min-total overflow inflation — none of which a wrapping flow\n * uses. The geometric algorithms (`getPreferredSize`, `getMinSize`,\n * `getMaxSize`, `doLayout`) are mirror-image per axis and stay concrete on each\n * subclass.\n *\n * @category Layouts\n */\nexport abstract class FlowLayout extends LayoutManager {\n\n // `protected`, not `private`: the subclasses' geometric methods\n // (getPreferredSize/getMinSize/getMaxSize/doLayout) read these fields\n // directly, so they must be visible to HFlow/VFlow.\n protected _spacing: number = 5;\n protected _lineSpacing: number = 5;\n protected _uniform: FlowUniformity = \"none\";\n protected _align: AxisPosition = \"start\";\n protected _itemAlign: FlowItemAlign = \"start\";\n protected _justify: AxisSpread = \"start\";\n\n /**\n * Constructs the layout manager, applying any supplied options.\n *\n * @param options - Optional construction-time configuration.\n */\n constructor(options?: FlowLayoutOptions) {\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 FlowLayoutOptions} bag after the inherited LayoutManager\n * defaults, dispatching the item and line spacings, the uniformity mode, and\n * the line alignment.\n *\n * @param options - The options bag carrying the values to apply.\n */\n protected applyOptions(options: FlowLayoutOptions): void {\n super.applyOptions(options);\n\n if (options.spacing !== undefined) {\n this.setComponentSpacing(options.spacing);\n }\n\n if (options.lineSpacing !== undefined) {\n this.setLineSpacing(options.lineSpacing);\n }\n\n if (options.uniform !== undefined) {\n this.setUniform(options.uniform);\n }\n\n if (options.align !== undefined) {\n this.setAlign(options.align);\n }\n\n if (options.itemAlign !== undefined) {\n this.setItemAlign(options.itemAlign);\n }\n\n if (options.justify !== undefined) {\n this.setJustify(options.justify);\n }\n }\n\n /**\n * Returns the pixel spacing between items along a line.\n *\n * @returns The current item spacing in pixels.\n */\n getComponentSpacing(): number {\n return this._spacing || 0;\n }\n\n /**\n * Sets the pixel spacing between items along a line.\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 the pixel spacing between wrapped lines.\n *\n * @returns The current line spacing in pixels.\n */\n getLineSpacing(): number {\n return this._lineSpacing || 0;\n }\n\n /**\n * Sets the pixel spacing between wrapped lines.\n *\n * @param lineSpacing - Spacing in pixels.\n *\n * @returns This layout manager, for method chaining.\n */\n setLineSpacing(lineSpacing: number): this {\n this._lineSpacing = lineSpacing || 0;\n\n return this;\n }\n\n /**\n * Returns which axes are made uniform so wrapped items align into a grid.\n *\n * @returns The current uniformity mode.\n */\n getUniform(): FlowUniformity {\n return this._uniform;\n }\n\n /**\n * Sets which axes are made uniform so wrapped items align into a grid.\n *\n * @param uniform - `\"width\"` aligns columns, `\"height\"` aligns rows,\n * `\"both\"` produces a full grid, `\"none\"` packs each item at its own\n * size. See {@link FlowUniformity}.\n *\n * @returns This layout manager, for method chaining.\n */\n setUniform(uniform: FlowUniformity): this {\n this._uniform = uniform;\n\n return this;\n }\n\n /**\n * Returns how each wrapped line's content block is packed along the main\n * axis within the container's inner main extent.\n *\n * @returns The current line alignment.\n */\n getAlign(): AxisPosition {\n return this._align;\n }\n\n /**\n * Sets how each wrapped line's content block is packed along the main axis.\n *\n * @param align - `\"start\"` packs at the leading edge (the default),\n * `\"center\"` centres the block, `\"end\"` packs at the trailing edge. The\n * leading/trailing edges are west/east for {@link HFlow} and north/south\n * for {@link VFlow}. See {@link AxisPosition}.\n *\n * @returns This layout manager, for method chaining.\n */\n setAlign(align: AxisPosition): this {\n this._align = align;\n\n return this;\n }\n\n /**\n * Returns how each item is aligned within its wrapped line's cross extent.\n *\n * @returns The current cross-axis item alignment.\n */\n getItemAlign(): FlowItemAlign {\n return this._itemAlign;\n }\n\n /**\n * Sets how each item is aligned within its wrapped line's cross extent — the\n * row height for {@link HFlow}, the column width for {@link VFlow}.\n *\n * @param itemAlign - `\"start\"` aligns to the leading cross-edge (the\n * default), `\"center\"` centres, `\"end\"` aligns to the trailing cross-edge,\n * `\"baseline\"` aligns text baselines across an {@link HFlow} row.\n * `\"baseline\"` degrades to `\"start\"` on {@link VFlow}, which has no shared\n * text baseline. See {@link FlowItemAlign}.\n *\n * @returns This layout manager, for method chaining.\n */\n setItemAlign(itemAlign: FlowItemAlign): this {\n this._itemAlign = itemAlign;\n\n return this;\n }\n\n /**\n * Returns how each wrapped line's items are distributed along the main axis.\n *\n * @returns The current main-axis distribution.\n */\n getJustify(): AxisSpread {\n return this._justify;\n }\n\n /**\n * Sets how each wrapped line's items are distributed along the main axis by\n * growing the inter-item gaps.\n *\n * @param justify - `\"start\"` packs items with the fixed `spacing` (the\n * default), `\"between\"` makes the first/last items flush to the edges with\n * equal interior gaps, `\"around\"` puts an equal gap around every item. See\n * {@link AxisSpread}.\n *\n * @returns This layout manager, for method chaining.\n *\n * @remarks When `justify` is `\"between\"` or `\"around\"` the line fills the\n * inner main extent, so it owns the residual and {@link AxisPosition} (the\n * `align` option) is ignored. A single-item or over-long line degrades to\n * `\"start\"`.\n */\n setJustify(justify: AxisSpread): this {\n this._justify = justify;\n\n return this;\n }\n\n /**\n * Whether cells are made uniform on the horizontal axis (columns align).\n *\n * @returns `true` for the `\"width\"` and `\"both\"` uniformity modes.\n */\n protected isUniformWidth(): boolean {\n return this._uniform === \"width\" || this._uniform === \"both\";\n }\n\n /**\n * Whether cells are made uniform on the vertical axis (rows align).\n *\n * @returns `true` for the `\"height\"` and `\"both\"` uniformity modes.\n */\n protected isUniformHeight(): boolean {\n return this._uniform === \"height\" || this._uniform === \"both\";\n }\n\n /**\n * Computes the uniform cell extent: the widest and tallest clamped preferred\n * size across the children, used to size cells in a `uniform` mode.\n *\n * @param components - The children sharing the flow.\n * @returns The `{width, height}` every uniform cell uses on its axis.\n */\n protected computeUniformExtents(components: Component[]): Size {\n let width = 0;\n let height = 0;\n\n for (const component of components) {\n const cell = this.clampedPreferredSize(component);\n\n width = Math.max(width, cell.width);\n height = Math.max(height, cell.height);\n }\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Resolves a child's placed size: its preferred size clamped to its own\n * min and max sizes.\n *\n * @param component - The child to measure.\n * @returns The clamped `{width, height}`.\n */\n protected clampedPreferredSize(component: Component): Size {\n const pref = component.getPreferredSize();\n const min = component.getMinSize();\n const max = component.getMaxSize();\n\n let width = pref ? pref.width : 0;\n let height = pref ? pref.height : 0;\n\n if (min) {\n width = Math.max(width, min.width);\n height = Math.max(height, min.height);\n }\n\n if (max) {\n width = Math.min(width, max.width);\n height = Math.min(height, max.height);\n }\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Computes the per-line leading offset that packs a content block of the\n * given main extent within the inner main extent per the alignment mode.\n *\n * @param contentMain - The line's content main-extent (sum of placed cell\n * main-extents plus inter-item spacing).\n * @param innerMain - The container's inner extent along the main axis.\n * @returns The leading offset in pixels — `0` for `\"start\"`, half the\n * residual for `\"center\"`, the full residual for `\"end\"`. An over-long\n * line (content exceeding the inner extent) clamps to `0`.\n */\n protected alignLead(contentMain: number, innerMain: number): number {\n const residual = Math.max(0, innerMain - contentMain);\n\n if (this._align === \"center\") {\n return residual / 2;\n }\n\n if (this._align === \"end\") {\n return residual;\n }\n\n return 0;\n }\n\n /**\n * Computes the leading cross-axis offset that positions a cell within its\n * line's cross extent per the {@link FlowItemAlign} mode. The caller adds\n * this to the line's leading cross-edge (the row top for {@link HFlow}, the\n * column left for {@link VFlow}).\n *\n * @param cellExtent - The cell's own cross extent (its height for HFlow, its\n * width for VFlow).\n * @param lineExtent - The line's cross extent (the row height for HFlow, the\n * column width for VFlow); always at least `cellExtent`.\n * @param baseline - The cell's own baseline, or `null` for a graphical cell.\n * Only consulted for `\"baseline\"`.\n * @param rowAscent - The line's text baseline from `computeRowMetrics`, or\n * `null` when no cell reports one (always `null` for VFlow). Only consulted\n * for `\"baseline\"`.\n * @param rowDescent - The line's text descent from `computeRowMetrics`. Only\n * consulted for `\"baseline\"`.\n * @returns The leading offset in pixels — `0` for `\"start\"`, and never\n * negative.\n *\n * @remarks The `\"baseline\"` arm mirrors HBox's per-child baseline placement:\n * a text-bearing cell aligns on `rowAscent - baseline`, a null-baseline cell\n * centres in the text line, and a baseline-less line (`rowAscent === null`,\n * the VFlow case) falls back to `\"start\"`.\n */\n protected crossOffset(cellExtent: number, lineExtent: number, baseline: number | null, rowAscent: number | null, rowDescent: number): number {\n switch (this._itemAlign) {\n case \"center\":\n return Math.max(0, (lineExtent - cellExtent) / 2);\n\n case \"end\":\n return Math.max(0, lineExtent - cellExtent);\n\n case \"baseline\":\n if (rowAscent === null) {\n return 0;\n }\n\n return baseline !== null\n ? rowAscent - baseline\n : this.nullChildY(cellExtent, rowAscent, rowDescent);\n\n case \"start\":\n default:\n return 0;\n }\n }\n\n /**\n * Computes the per-line main-axis spacing under the active\n * {@link AxisSpread} mode.\n *\n * @param itemCount - The number of cells in the line.\n * @param contentMain - The sum of the cells' main extents (no spacing).\n * @param innerMain - The container's inner extent along the main axis.\n * @param spacing - The fixed inter-item spacing in pixels.\n * @returns `{ lead, gap }` — `lead` is the offset before the first item and\n * `gap` the spacing between successive items.\n *\n * @remarks Degrades to the fixed `spacing` (and `lead` `0`) for `\"start\"`,\n * single-item lines, and over-long lines, so the gaps are never negative. For\n * the distribution modes the line fills the inner extent, so the caller must\n * skip the `align` block move.\n */\n protected justifyGaps(itemCount: number, contentMain: number, innerMain: number, spacing: number): { lead: number; gap: number } {\n // Degrade to fixed spacing: start mode, fewer than two items, or content\n // already filling (or exceeding) the inner extent — no positive residual\n // to distribute.\n const fixedTotal = contentMain + spacing * Math.max(0, itemCount - 1);\n\n if (this._justify === \"start\" || itemCount < 2 || fixedTotal >= innerMain) {\n return { lead: 0, gap: spacing };\n }\n\n // The total gap budget to distribute, always positive here.\n const free = innerMain - contentMain;\n\n if (this._justify === \"between\") {\n return { lead: 0, gap: free / (itemCount - 1) };\n }\n\n // \"around\": one whole gap per item, split as half-gaps at the two ends.\n const unit = free / itemCount;\n\n return { lead: unit / 2, gap: unit };\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { FlowLayout, FlowLayoutOptions } from \"~/layout/FlowLayout.js\";\nimport { FillType } from \"~/layout/FillType.js\";\nimport { Size, UNBOUNDED, isUnbounded } from \"~/primitive/Size.js\";\nimport { Component } from \"~/core/Component.js\";\nimport { callable } from \"~/core/Callable.js\";\n\n/**\n * Construction-time options for {@link HFlow}.\n *\n * @remarks Inherits every flow field (`spacing`, `lineSpacing`, `uniform`,\n * `align`, `itemAlign`, `justify`) from {@link FlowLayoutOptions}; `HFlow` adds\n * none of its own.\n *\n * @category Layouts\n */\nexport interface HFlowOptions extends FlowLayoutOptions {}\n\n/**\n * One wrapped row of an {@link HFlow}: its ordered cells (each with the width it\n * was placed at, its own cell height, and its baseline for `\"baseline\"`\n * item-alignment), the row's total content width, the row height (tallest cell),\n * and the row's top in the container's coordinate space.\n */\ninterface HFlowRow {\n cells: Array<{ component: Component; width: number; height: number; baseline: number | null }>;\n contentWidth: number;\n rowHeight: number;\n y: number;\n}\n\n/**\n * A layout manager that packs children in horizontal rows, wrapping to a new\n * line when the next child would exceed the container's inner width. Unlike\n * {@link HBox} it never shrinks or stretches children: each keeps its preferred\n * size and lines stack downward. A scroll-enabled host (`Panel.setAutoScroll`)\n * gains a vertical scrollbar once the stacked lines exceed its inner height.\n *\n * @remarks Shares its flow configuration (item/line spacing, cell uniformity,\n * line alignment) with {@link VFlow} through the {@link FlowLayout} base. The\n * `uniform` option grows every cell to the widest and/or tallest item so wrapped\n * items line up into a grid; each item is positioned within its cell by its own\n * {@link AnchorType} constraint (default centre). The `align` option packs each\n * row's content block at the west edge (`\"start\"`, the default), centred, or the\n * east edge; `justify` instead spreads the row's items across the inner width\n * (`\"between\"`/`\"around\"`), and `itemAlign` positions each item within the row\n * height (including `\"baseline\"`, which aligns text baselines across the row) —\n * the scroll extent comes entirely from the children's committed positions read\n * by `reserveContentFrame`.\n *\n * @category Layouts\n */\nclass HFlow extends FlowLayout {\n\n /**\n * Returns the preferred size: the single-line shape of the children — the\n * sum of their preferred widths plus item spacing, and the baseline-aware\n * row height of the tallest child. In a `uniform` width mode the width is\n * instead `count * columnWidth`; in a `uniform` height mode the height is\n * the tallest cell.\n *\n * @returns The preferred `{width, height}`, or `null` if no container is attached.\n *\n * @remarks This is an approximation. The real height depends on how many\n * lines the children wrap into, which is only known once the parent assigns\n * a width — unavailable when the hint is queried. The parent absorbs the\n * difference: a scroll-enabled host scrolls vertically when the real wrapped\n * height exceeds this single-line estimate.\n */\n getPreferredSize(): 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 const uniformWidth = this.isUniformWidth();\n const uniformHeight = this.isUniformHeight();\n const extents = (uniformWidth || uniformHeight) ? this.computeUniformExtents(components) : { width: 0, height: 0 };\n\n let width = perimeterSize.left + perimeterSize.right;\n const heights: number[] = [];\n const baselines: Array<number | null> = [];\n\n for (const component of components) {\n const size = component.getPreferredSize();\n\n if (size) {\n if (!uniformWidth) {\n width += size.width;\n }\n\n heights.push(size.height);\n baselines.push(component.getBaseline());\n }\n }\n\n if (uniformWidth) {\n width += components.length * extents.width;\n }\n\n width += this._spacing * Math.max(0, components.length - 1);\n\n let height = uniformHeight ? extents.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: the widest child's min width (the floor below\n * which not even one child per line fits) and the baseline-aware row height\n * of the children's min heights.\n *\n * @returns The minimum `{width, height}`, or `null` if no container is attached.\n */\n getMinSize(): 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 let maxChildMinWidth = 0;\n const heights: number[] = [];\n const baselines: Array<number | null> = [];\n\n for (const component of components) {\n const 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 const width = perimeterSize.left + perimeterSize.right + maxChildMinWidth;\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 flow can usefully occupy: with every child on\n * one line the width is the sum of the children's *maximum* widths (or\n * `count * columnWidth` in a `uniform` width mode) plus item spacing, and the\n * height is the *largest* child maximum — the tallest a single row can grow\n * to. A child whose maximum is `null` or at the unbounded sentinel makes that\n * axis unbounded.\n *\n * @returns The maximum `{width, height}`, or `null` if no container is attached.\n */\n getMaxSize(): 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 const uniformWidth = this.isUniformWidth();\n const extents = uniformWidth ? this.computeUniformExtents(components) : { width: 0, height: 0 };\n\n let width = perimeterSize.left + perimeterSize.right;\n let height = 0;\n let widthUnbounded = false;\n let heightUnbounded = false;\n\n for (const component of components) {\n const max = component.getMaxSize();\n\n if (!max) {\n if (!uniformWidth) {\n widthUnbounded = true;\n }\n heightUnbounded = true;\n continue;\n }\n\n if (!uniformWidth) {\n if (isUnbounded(max.width)) {\n widthUnbounded = true;\n } else {\n width += max.width;\n }\n }\n\n if (isUnbounded(max.height)) {\n heightUnbounded = true;\n } else {\n height = Math.max(height, max.height);\n }\n }\n\n if (uniformWidth) {\n width += components.length * extents.width;\n }\n\n width += this._spacing * Math.max(0, components.length - 1);\n height += perimeterSize.top + perimeterSize.bottom;\n\n return {\n width: widthUnbounded ? UNBOUNDED : width,\n height: heightUnbounded ? UNBOUNDED : height\n };\n }\n\n /**\n * Packs the children left-to-right at their cell size, wrapping to a new\n * line when the next cell's right edge would exceed the inner width, then\n * places each row's content block per the `align` mode. In a `uniform` mode\n * every cell grows to the widest and/or tallest item so the wrapped items\n * line up into a grid. A scroll-enabled host then scrolls the overflow via\n * `reserveContentFrame`, which sizes the content frame to the children's\n * committed extent.\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 insets = container.getContentInsets();\n const spacing = this.getComponentSpacing();\n const lineSpacing = this.getLineSpacing();\n\n const uniformWidth = this.isUniformWidth();\n const uniformHeight = this.isUniformHeight();\n const extents = (uniformWidth || uniformHeight) ? this.computeUniformExtents(components) : { width: 0, height: 0 };\n\n const rows = this.groupIntoRows(components, innerSize.width, insets.getTop(), spacing, lineSpacing, uniformWidth, uniformHeight, extents);\n\n this.placeRows(rows, insets.getLeft(), innerSize.width, spacing);\n\n this.reserveContentFrame();\n }\n\n /**\n * Phase 1 of {@link HFlow.doLayout}: walks the children left-to-right,\n * wrapping into rows, and records each row's cells, content width, height,\n * and top — without committing any bounds. A first cell wider than the inner\n * width is clamped to that width so its right edge stays inside a scrolling\n * host.\n *\n * @param components - The children to place, in order.\n * @param innerWidth - The container's inner width (the wrap threshold).\n * @param topInset - The container's top content inset (the first row's top).\n * @param spacing - Inter-item horizontal spacing in pixels.\n * @param lineSpacing - Inter-row vertical spacing in pixels.\n * @param uniformWidth - Whether cells take the uniform width.\n * @param uniformHeight - Whether cells take the uniform height.\n * @param extents - The uniform cell extents, when a uniform mode is active.\n * @returns The ordered rows ready for {@link HFlow.placeRows}.\n */\n private groupIntoRows(components: Component[], innerWidth: number, topInset: number, spacing: number, lineSpacing: number, uniformWidth: boolean, uniformHeight: boolean, extents: Size): HFlowRow[] {\n const rows: HFlowRow[] = [];\n let y = topInset;\n let current: HFlowRow | null = null;\n\n for (const component of components) {\n const cell = this.clampedPreferredSize(component);\n const cellWidth = uniformWidth ? extents.width : cell.width;\n const cellHeight = uniformHeight ? extents.height : cell.height;\n\n // Wrap before placing when the current row is non-empty and this\n // cell's right edge (including the joining spacing) would spill past\n // the inner width.\n if (current && current.contentWidth + spacing + cellWidth > innerWidth) {\n y += current.rowHeight + lineSpacing;\n current = null;\n }\n\n if (!current) {\n current = { cells: [], contentWidth: 0, rowHeight: 0, y: y };\n\n rows.push(current);\n }\n\n // A cell wider than the inner width occupies its own line clamped to\n // that width, so its right edge stays inside a scrolling host.\n const placedWidth = (current.cells.length === 0) ? Math.min(cellWidth, innerWidth) : cellWidth;\n\n current.contentWidth += (current.cells.length === 0) ? placedWidth : spacing + placedWidth;\n current.cells.push({ component: component, width: placedWidth, height: cellHeight, baseline: component.getBaseline() });\n current.rowHeight = Math.max(current.rowHeight, cellHeight);\n }\n\n return rows;\n }\n\n /**\n * Phase 2 of {@link HFlow.doLayout}: distributes each row's cells along the\n * main axis per the `justify` mode (or packs them at the `align` offset when\n * `justify` is `\"start\"`), and positions each cell within the row height per\n * the `itemAlign` mode. Each child keeps its preferred size (`FillType.NONE`);\n * its own {@link AnchorType} positions it within its cell.\n *\n * @param rows - The rows produced by {@link HFlow.groupIntoRows}.\n * @param leftInset - The container's left content inset (the row's leading edge).\n * @param innerWidth - The container's inner width (for the alignment residual).\n * @param spacing - Inter-item horizontal spacing in pixels.\n */\n private placeRows(rows: HFlowRow[], leftInset: number, innerWidth: number, spacing: number): void {\n for (const row of rows) {\n // Row text metrics for \"baseline\" itemAlign (cheap; only used then).\n const heights = row.cells.map(cell => cell.height);\n const baselines = row.cells.map(cell => cell.baseline);\n\n const { rowAscent, rowDescent } = this.computeRowMetrics(heights, baselines);\n\n const { lead, gap } = this.justifyGaps(row.cells.length, this.cellsMainExtent(row), innerWidth, spacing);\n\n // A justify mode fills the inner extent and owns the residual, so the\n // align block move only applies when justify === \"start\".\n const blockLead = this._justify === \"start\"\n ? this.alignLead(row.contentWidth, innerWidth)\n : 0;\n\n let x = leftInset + blockLead + lead;\n\n for (const cell of row.cells) {\n const y = row.y + this.crossOffset(cell.height, row.rowHeight, cell.baseline, rowAscent, rowDescent);\n\n this.placeComponent(cell.component, x, y, cell.width, cell.height, FillType.NONE);\n\n x += cell.width + gap;\n }\n }\n }\n\n /**\n * Sums a row's cell widths without the inter-item spacing — the content\n * main-extent {@link FlowLayout.justifyGaps} distributes the residual around.\n *\n * @param row - The row to measure.\n * @returns The total cell width in pixels.\n */\n private cellsMainExtent(row: HFlowRow): number {\n return row.cells.reduce((sum, cell) => sum + cell.width, 0);\n }\n}\n\nconst HFlowCallable = callable(HFlow);\ntype HFlowCallable = HFlow;\nexport {\n HFlow as _HFlow,\n HFlowCallable as HFlow\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { FlowLayout, FlowLayoutOptions } from \"~/layout/FlowLayout.js\";\nimport { FillType } from \"~/layout/FillType.js\";\nimport { Size, UNBOUNDED, isUnbounded } from \"~/primitive/Size.js\";\nimport { Component } from \"~/core/Component.js\";\nimport { callable } from \"~/core/Callable.js\";\n\n/**\n * Construction-time options for {@link VFlow}.\n *\n * @remarks Inherits every flow field (`spacing`, `lineSpacing`, `uniform`,\n * `align`, `itemAlign`, `justify`) from {@link FlowLayoutOptions}; `VFlow` adds\n * none of its own. `spacing` is the vertical gap between items in a column;\n * `lineSpacing` is the horizontal gap between wrapped columns.\n *\n * @category Layouts\n */\nexport interface VFlowOptions extends FlowLayoutOptions {}\n\n/**\n * One wrapped column of a {@link VFlow}: its ordered cells (each with its own\n * cell width and the height it was placed at; `baseline` is always `null` since\n * a column exposes no shared text baseline), the column's total content height,\n * the column width (widest cell), and the column's left in the container's\n * coordinate space.\n */\ninterface VFlowColumn {\n cells: Array<{ component: Component; width: number; height: number; baseline: number | null }>;\n contentHeight: number;\n columnWidth: number;\n x: number;\n}\n\n/**\n * A layout manager that packs children in vertical columns, wrapping to a new\n * column when the next child would exceed the container's inner height. The\n * vertical transpose of {@link HFlow}: where `HFlow` packs rows left-to-right\n * and wraps downward, `VFlow` packs columns top-to-bottom and wraps rightward.\n * Like `HFlow` it never shrinks or stretches children — each keeps its preferred\n * size. A scroll-enabled host (`Panel.setAutoScroll`) gains a horizontal\n * scrollbar once the columns exceed its inner width.\n *\n * @remarks Shares its flow configuration (item/line spacing, cell uniformity,\n * line alignment) with `HFlow` through the {@link FlowLayout} base. Here\n * `spacing` is the vertical gap between items in a column and `lineSpacing` the\n * horizontal gap between columns. The `align` option packs each column's content\n * block at the north edge (`\"start\"`, the default), centred, or the south edge;\n * `justify` instead spreads the column's items across the inner height\n * (`\"between\"`/`\"around\"`), and `itemAlign` positions each item within the\n * column width. A wrapped column exposes no shared text baseline, so the cross\n * axis (width) uses a plain widest-cell measure and `itemAlign: \"baseline\"`\n * degrades to `\"start\"`.\n *\n * @category Layouts\n */\nclass VFlow extends FlowLayout {\n\n /**\n * Returns the preferred size: the single-column shape of the children — the\n * sum of their preferred heights plus item spacing, and the widest child's\n * width. In a `uniform` height mode the height is instead `count * rowHeight`;\n * in a `uniform` width mode the width is the widest cell.\n *\n * @returns The preferred `{width, height}`, or `null` if no container is attached.\n *\n * @remarks This is an approximation. The real width depends on how many\n * columns the children wrap into, which is only known once the parent\n * assigns a height — unavailable when the hint is queried. A scroll-enabled\n * host scrolls horizontally when the real wrapped width exceeds this\n * single-column estimate.\n */\n getPreferredSize(): 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 const uniformWidth = this.isUniformWidth();\n const uniformHeight = this.isUniformHeight();\n const extents = (uniformWidth || uniformHeight) ? this.computeUniformExtents(components) : { width: 0, height: 0 };\n\n let height = perimeterSize.top + perimeterSize.bottom;\n let maxWidth = 0;\n\n for (const component of components) {\n const size = component.getPreferredSize();\n\n if (size) {\n if (!uniformHeight) {\n height += size.height;\n }\n\n maxWidth = Math.max(maxWidth, size.width);\n }\n }\n\n if (uniformHeight) {\n height += components.length * extents.height;\n }\n\n height += this._spacing * Math.max(0, components.length - 1);\n\n let width = uniformWidth ? extents.width : maxWidth;\n\n width += perimeterSize.left + perimeterSize.right;\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Returns the minimum size: the tallest child's min height (the floor below\n * which not even one child per column fits) and the widest child's min\n * width.\n *\n * @returns The minimum `{width, height}`, or `null` if no container is attached.\n */\n getMinSize(): 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 let maxChildMinHeight = 0;\n let maxWidth = 0;\n\n for (const component of components) {\n const size = component.getMinSize();\n\n if (size) {\n maxChildMinHeight = Math.max(maxChildMinHeight, size.height);\n maxWidth = Math.max(maxWidth, size.width);\n }\n }\n\n const width = perimeterSize.left + perimeterSize.right + maxWidth;\n const height = perimeterSize.top + perimeterSize.bottom + maxChildMinHeight;\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Returns the maximum size the flow can usefully occupy: with every child in\n * one column the height is the sum of the children's *maximum* heights (or\n * `count * rowHeight` in a `uniform` height mode) plus item spacing, and the\n * width is the *largest* child maximum — the widest a single column can grow\n * to. A child whose maximum is `null` or at the unbounded sentinel makes that\n * axis unbounded.\n *\n * @returns The maximum `{width, height}`, or `null` if no container is attached.\n */\n getMaxSize(): 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 const uniformHeight = this.isUniformHeight();\n const extents = uniformHeight ? this.computeUniformExtents(components) : { width: 0, height: 0 };\n\n let height = perimeterSize.top + perimeterSize.bottom;\n let width = 0;\n let widthUnbounded = false;\n let heightUnbounded = false;\n\n for (const component of components) {\n const max = component.getMaxSize();\n\n if (!max) {\n if (!uniformHeight) {\n heightUnbounded = true;\n }\n widthUnbounded = true;\n continue;\n }\n\n if (!uniformHeight) {\n if (isUnbounded(max.height)) {\n heightUnbounded = true;\n } else {\n height += max.height;\n }\n }\n\n if (isUnbounded(max.width)) {\n widthUnbounded = true;\n } else {\n width = Math.max(width, max.width);\n }\n }\n\n if (uniformHeight) {\n height += components.length * extents.height;\n }\n\n height += this._spacing * Math.max(0, components.length - 1);\n width += perimeterSize.left + perimeterSize.right;\n\n return {\n width: widthUnbounded ? UNBOUNDED : width,\n height: heightUnbounded ? UNBOUNDED : height\n };\n }\n\n /**\n * Packs the children top-to-bottom at their cell size, wrapping to a new\n * column when the next cell's bottom edge would exceed the inner height, then\n * places each column's content block per the `align` mode. In a `uniform`\n * mode every cell grows to the widest and/or tallest item so the wrapped\n * items line up into a grid. A scroll-enabled host then scrolls the overflow\n * via `reserveContentFrame`, which sizes the content frame to the children's\n * committed extent.\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 insets = container.getContentInsets();\n const spacing = this.getComponentSpacing();\n const lineSpacing = this.getLineSpacing();\n\n const uniformWidth = this.isUniformWidth();\n const uniformHeight = this.isUniformHeight();\n const extents = (uniformWidth || uniformHeight) ? this.computeUniformExtents(components) : { width: 0, height: 0 };\n\n const columns = this.groupIntoColumns(components, innerSize.height, insets.getLeft(), spacing, lineSpacing, uniformWidth, uniformHeight, extents);\n\n this.placeColumns(columns, insets.getTop(), innerSize.height, spacing);\n\n this.reserveContentFrame();\n }\n\n /**\n * Phase 1 of {@link VFlow.doLayout}: walks the children top-to-bottom,\n * wrapping into columns, and records each column's cells, content height,\n * width, and left — without committing any bounds. A first cell taller than\n * the inner height is clamped to that height so its bottom edge stays inside\n * a scrolling host.\n *\n * @param components - The children to place, in order.\n * @param innerHeight - The container's inner height (the wrap threshold).\n * @param leftInset - The container's left content inset (the first column's left).\n * @param spacing - Inter-item vertical spacing in pixels.\n * @param lineSpacing - Inter-column horizontal spacing in pixels.\n * @param uniformWidth - Whether cells take the uniform width.\n * @param uniformHeight - Whether cells take the uniform height.\n * @param extents - The uniform cell extents, when a uniform mode is active.\n * @returns The ordered columns ready for {@link VFlow.placeColumns}.\n */\n private groupIntoColumns(components: Component[], innerHeight: number, leftInset: number, spacing: number, lineSpacing: number, uniformWidth: boolean, uniformHeight: boolean, extents: Size): VFlowColumn[] {\n const columns: VFlowColumn[] = [];\n let x = leftInset;\n let current: VFlowColumn | null = null;\n\n for (const component of components) {\n const cell = this.clampedPreferredSize(component);\n const cellWidth = uniformWidth ? extents.width : cell.width;\n const cellHeight = uniformHeight ? extents.height : cell.height;\n\n // Wrap before placing when the current column is non-empty and this\n // cell's bottom edge (including the joining spacing) would spill past\n // the inner height.\n if (current && current.contentHeight + spacing + cellHeight > innerHeight) {\n x += current.columnWidth + lineSpacing;\n current = null;\n }\n\n if (!current) {\n current = { cells: [], contentHeight: 0, columnWidth: 0, x: x };\n\n columns.push(current);\n }\n\n // A cell taller than the inner height occupies its own column clamped\n // to that height, so its bottom edge stays inside a scrolling host.\n const placedHeight = (current.cells.length === 0) ? Math.min(cellHeight, innerHeight) : cellHeight;\n\n current.contentHeight += (current.cells.length === 0) ? placedHeight : spacing + placedHeight;\n current.cells.push({ component: component, width: cellWidth, height: placedHeight, baseline: null });\n current.columnWidth = Math.max(current.columnWidth, cellWidth);\n }\n\n return columns;\n }\n\n /**\n * Phase 2 of {@link VFlow.doLayout}: distributes each column's cells along\n * the main axis per the `justify` mode (or packs them at the `align` offset\n * when `justify` is `\"start\"`), and positions each cell within the column\n * width per the `itemAlign` mode. The cross axis is width, which has no text\n * baseline, so `\"baseline\"` degrades to `\"start\"`. Each child keeps its\n * preferred size (`FillType.NONE`); its own {@link AnchorType} positions it\n * within its cell.\n *\n * @param columns - The columns produced by {@link VFlow.groupIntoColumns}.\n * @param topInset - The container's top content inset (the column's leading edge).\n * @param innerHeight - The container's inner height (for the alignment residual).\n * @param spacing - Inter-item vertical spacing in pixels.\n */\n private placeColumns(columns: VFlowColumn[], topInset: number, innerHeight: number, spacing: number): void {\n for (const column of columns) {\n const { lead, gap } = this.justifyGaps(column.cells.length, this.cellsMainExtent(column), innerHeight, spacing);\n\n // A justify mode fills the inner extent and owns the residual, so the\n // align block move only applies when justify === \"start\".\n const blockLead = this._justify === \"start\"\n ? this.alignLead(column.contentHeight, innerHeight)\n : 0;\n\n let y = topInset + blockLead + lead;\n\n for (const cell of column.cells) {\n // rowAscent null → \"baseline\" degrades to \"start\"; cross axis is width.\n const x = column.x + this.crossOffset(cell.width, column.columnWidth, null, null, 0);\n\n this.placeComponent(cell.component, x, y, cell.width, cell.height, FillType.NONE);\n\n y += cell.height + gap;\n }\n }\n }\n\n /**\n * Sums a column's cell heights without the inter-item spacing — the content\n * main-extent {@link FlowLayout.justifyGaps} distributes the residual around.\n *\n * @param column - The column to measure.\n * @returns The total cell height in pixels.\n */\n private cellsMainExtent(column: VFlowColumn): number {\n return column.cells.reduce((sum, cell) => sum + cell.height, 0);\n }\n}\n\nconst VFlowCallable = callable(VFlow);\ntype VFlowCallable = VFlow;\nexport {\n VFlow as _VFlow,\n VFlowCallable as VFlow\n};\n"],"mappings":"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"}
|