@jimka/typescript-ui 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/{AbstractInput-B10DfLOf.js → AbstractInput-W2PLJV5_.js} +2 -2
- package/dist/lib/{AbstractInput-B10DfLOf.js.map → AbstractInput-W2PLJV5_.js.map} +1 -1
- package/dist/lib/Anchor-iZhsvMlT.js +2 -0
- package/dist/lib/Anchor-iZhsvMlT.js.map +1 -0
- package/dist/lib/AnimatedDropdown-D0RhVgv3.js +2 -0
- package/dist/lib/AnimatedDropdown-D0RhVgv3.js.map +1 -0
- package/dist/lib/Border-6GsTNV-2.js +2 -0
- package/dist/lib/Border-6GsTNV-2.js.map +1 -0
- package/dist/lib/Button-CnFAiQuV.js +2 -0
- package/dist/lib/Button-CnFAiQuV.js.map +1 -0
- package/dist/lib/{Card-CD3jxshU.js → Card-C20k2YHU.js} +2 -2
- package/dist/lib/{Card-CD3jxshU.js.map → Card-C20k2YHU.js.map} +1 -1
- package/dist/lib/Checkbox-CM1z8keM.js +2 -0
- package/dist/lib/Checkbox-CM1z8keM.js.map +1 -0
- package/dist/lib/CheckboxMenuRow-C1h4LPHR.js +2 -0
- package/dist/lib/CheckboxMenuRow-C1h4LPHR.js.map +1 -0
- package/dist/lib/{CodeEditor-BGlB232h.js → CodeEditor-CTL2WjF8.js} +2 -2
- package/dist/lib/CodeEditor-CTL2WjF8.js.map +1 -0
- package/dist/lib/ComboBox-PZ5YPL0X.js +2 -0
- package/dist/lib/ComboBox-PZ5YPL0X.js.map +1 -0
- package/dist/lib/Component-D99-15Zt.js +2 -0
- package/dist/lib/Component-D99-15Zt.js.map +1 -0
- package/dist/lib/Container-FWRjgF6T.js +2 -0
- package/dist/lib/{Container-C7RPLQEc.js.map → Container-FWRjgF6T.js.map} +1 -1
- package/dist/lib/DOM-Cjh7_7TF.js +2 -0
- package/dist/lib/DOM-Cjh7_7TF.js.map +1 -0
- package/dist/lib/Dialog-DN78RaVH.js +2 -0
- package/dist/lib/Dialog-DN78RaVH.js.map +1 -0
- package/dist/lib/{FieldDecorator-HG65hEtk.js → FieldDecorator-DyPX8CFh.js} +2 -2
- package/dist/lib/{FieldDecorator-HG65hEtk.js.map → FieldDecorator-DyPX8CFh.js.map} +1 -1
- package/dist/lib/{Fit-Cg3dPyZg.js → Fit-CaPMj7Up.js} +2 -2
- package/dist/lib/{Fit-Cg3dPyZg.js.map → Fit-CaPMj7Up.js.map} +1 -1
- package/dist/lib/{FloatingPanel-D5buuVrQ.js → FloatingPanel-Dsy_vJxi.js} +2 -2
- package/dist/lib/{FloatingPanel-D5buuVrQ.js.map → FloatingPanel-Dsy_vJxi.js.map} +1 -1
- package/dist/lib/Glyph-DiEpD3gy.js +2 -0
- package/dist/lib/Glyph-DiEpD3gy.js.map +1 -0
- package/dist/lib/{Grid-BYBohJIA.js → Grid-ft_UUpj8.js} +2 -2
- package/dist/lib/Grid-ft_UUpj8.js.map +1 -0
- package/dist/lib/GridConstraints-CvZ0Nzaw.js +2 -0
- package/dist/lib/{GridConstraints-Bts284FI.js.map → GridConstraints-CvZ0Nzaw.js.map} +1 -1
- package/dist/lib/{Header-BIFJK9nR.js → Header-Osm3IjDw.js} +2 -2
- package/dist/lib/{Header-BIFJK9nR.js.map → Header-Osm3IjDw.js.map} +1 -1
- package/dist/lib/{IconText-Dsb1xS-E.js → IconText-BBaYJ2Fx.js} +2 -2
- package/dist/lib/{IconText-Dsb1xS-E.js.map → IconText-BBaYJ2Fx.js.map} +1 -1
- package/dist/lib/LayoutSerialization-BC64__O7.js +2 -0
- package/dist/lib/LayoutSerialization-BC64__O7.js.map +1 -0
- package/dist/lib/List-CQbZK_pT.js +2 -0
- package/dist/lib/List-CQbZK_pT.js.map +1 -0
- package/dist/lib/MemoryStore-DhPoU-7X.js +2 -0
- package/dist/lib/MemoryStore-DhPoU-7X.js.map +1 -0
- package/dist/lib/Menu-CwHluLGT.js +2 -0
- package/dist/lib/Menu-CwHluLGT.js.map +1 -0
- package/dist/lib/{MenuButton-BR4KOFld.js → MenuButton-BqCT-1yv.js} +2 -2
- package/dist/lib/{MenuButton-BR4KOFld.js.map → MenuButton-BqCT-1yv.js.map} +1 -1
- package/dist/lib/OverlayFade-CuEXgimf.js +2 -0
- package/dist/lib/OverlayFade-CuEXgimf.js.map +1 -0
- package/dist/lib/{Panel-CpNQTLNF.js → Panel-CtViePqY.js} +2 -2
- package/dist/lib/{Panel-CpNQTLNF.js.map → Panel-CtViePqY.js.map} +1 -1
- package/dist/lib/{Position-PBVBW1JS.js → Position-BIEU1Eze.js} +2 -2
- package/dist/lib/Position-BIEU1Eze.js.map +1 -0
- package/dist/lib/{ProgressSpinner-lAsK26C-.js → ProgressSpinner-BuBvC1FY.js} +2 -2
- package/dist/lib/{ProgressSpinner-lAsK26C-.js.map → ProgressSpinner-BuBvC1FY.js.map} +1 -1
- package/dist/lib/RadioButton-Df5J-H6m.js +2 -0
- package/dist/lib/RadioButton-Df5J-H6m.js.map +1 -0
- package/dist/lib/RadioMenuRow-Cfv0x6Qj.js +2 -0
- package/dist/lib/RadioMenuRow-Cfv0x6Qj.js.map +1 -0
- package/dist/lib/{RovingTabIndex-C2Vzq0IX.js → RovingTabIndex--w28AnXc.js} +2 -2
- package/dist/lib/{RovingTabIndex-C2Vzq0IX.js.map → RovingTabIndex--w28AnXc.js.map} +1 -1
- package/dist/lib/Scrollbar-DcnueNJd.js +2 -0
- package/dist/lib/Scrollbar-DcnueNJd.js.map +1 -0
- package/dist/lib/SelectableText-DZNxjKXR.js +2 -0
- package/dist/lib/SelectableText-DZNxjKXR.js.map +1 -0
- package/dist/lib/{Slider-DZ9drUxn.js → Slider-DNfd8Lxz.js} +2 -2
- package/dist/lib/{Slider-DZ9drUxn.js.map → Slider-DNfd8Lxz.js.map} +1 -1
- package/dist/lib/{Spacer-SDhOMp2g.js → Spacer-BznfGbwG.js} +2 -2
- package/dist/lib/{Spacer-SDhOMp2g.js.map → Spacer-BznfGbwG.js.map} +1 -1
- package/dist/lib/TabButton-CAACsMov.js +2 -0
- package/dist/lib/TabButton-CAACsMov.js.map +1 -0
- package/dist/lib/TabCloseButton-CCiqsX3y.js +2 -0
- package/dist/lib/TabCloseButton-CCiqsX3y.js.map +1 -0
- package/dist/lib/Text-O-FWa5Cy.js +2 -0
- package/dist/lib/Text-O-FWa5Cy.js.map +1 -0
- package/dist/lib/Tooltip-CyICVu15.js +3 -0
- package/dist/lib/Tooltip-CyICVu15.js.map +1 -0
- package/dist/lib/Tree-CSEguhlk.js +2 -0
- package/dist/lib/Tree-CSEguhlk.js.map +1 -0
- package/dist/lib/VBox-DVe4UXwX.js +2 -0
- package/dist/lib/VBox-DVe4UXwX.js.map +1 -0
- package/dist/lib/VirtualScroller-ggPTCQb0.js +2 -0
- package/dist/lib/VirtualScroller-ggPTCQb0.js.map +1 -0
- package/dist/lib/assets/StoreWorker-B5NwRM2I.js +2 -0
- package/dist/lib/assets/StoreWorker-B5NwRM2I.js.map +1 -0
- package/dist/lib/component/button.es.js +1 -1
- package/dist/lib/component/button.es.js.map +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/container.es.js.map +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/display.es.js.map +1 -1
- package/dist/lib/component/editor.es.js +2 -2
- package/dist/lib/component/editor.es.js.map +1 -1
- package/dist/lib/component/input.es.js +1 -1
- package/dist/lib/component/input.es.js.map +1 -1
- package/dist/lib/component/list.es.js +1 -1
- package/dist/lib/component/list.es.js.map +1 -1
- package/dist/lib/component/menubar.es.js +1 -1
- package/dist/lib/component/menubar.es.js.map +1 -1
- package/dist/lib/component/table.es.js +6 -3
- package/dist/lib/component/table.es.js.map +1 -1
- package/dist/lib/component/tree.es.js +1 -1
- package/dist/lib/core.es.js +1 -1
- package/dist/lib/core.es.js.map +1 -1
- package/dist/lib/data.es.js +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/selectionsEqual-C7MrKMQr.js +2 -0
- package/dist/lib/selectionsEqual-C7MrKMQr.js.map +1 -0
- package/dist/lib/types/component/button/Button.d.ts +22 -0
- package/dist/lib/types/component/button/MenuButton.d.ts +1 -0
- package/dist/lib/types/component/button/PopupButton.d.ts +22 -0
- package/dist/lib/types/component/button/TabButton.d.ts +9 -0
- package/dist/lib/types/component/button/ToggleButton.d.ts +3 -0
- package/dist/lib/types/component/button/index.d.ts +2 -0
- package/dist/lib/types/component/chart/AbstractChart.d.ts +2 -0
- package/dist/lib/types/component/container/CheckboxMenuRow.d.ts +33 -0
- package/dist/lib/types/component/container/CollapseButton.d.ts +11 -3
- package/dist/lib/types/component/container/MenuItem.d.ts +15 -5
- package/dist/lib/types/component/container/MenuRow.d.ts +24 -0
- package/dist/lib/types/component/container/MenuSeparator.d.ts +4 -2
- package/dist/lib/types/component/container/RadioMenuRow.d.ts +33 -0
- package/dist/lib/types/component/container/Scrollbar.d.ts +5 -0
- package/dist/lib/types/component/container/SplitGutter.d.ts +7 -2
- package/dist/lib/types/component/container/TabBar.d.ts +2 -0
- package/dist/lib/types/component/container/WindowBorder.d.ts +1 -1
- package/dist/lib/types/component/container/index.d.ts +6 -1
- package/dist/lib/types/component/display/Markdown.d.ts +2 -1
- package/dist/lib/types/component/display/WebGLCanvas.d.ts +1 -0
- package/dist/lib/types/component/input/AbstractCalendarDropdown.d.ts +4 -0
- package/dist/lib/types/component/input/AbstractPickerField.d.ts +5 -2
- package/dist/lib/types/component/input/AutoCompleteDropdown.d.ts +2 -0
- package/dist/lib/types/component/input/ComboBox.d.ts +3 -1
- package/dist/lib/types/component/input/Link.d.ts +2 -0
- package/dist/lib/types/component/input/PasswordField.d.ts +2 -0
- package/dist/lib/types/component/input/PickerInput.d.ts +2 -0
- package/dist/lib/types/component/input/SelectableText.d.ts +11 -0
- package/dist/lib/types/component/input/SpinButton.d.ts +2 -0
- package/dist/lib/types/component/input/Text.d.ts +16 -2
- package/dist/lib/types/component/input/TextArea.d.ts +2 -0
- package/dist/lib/types/component/input/TextField.d.ts +2 -0
- package/dist/lib/types/component/input/TextInput.d.ts +2 -0
- package/dist/lib/types/component/input/TimePickerDropdown.d.ts +3 -1
- package/dist/lib/types/component/input/UsernameField.d.ts +2 -0
- package/dist/lib/types/component/input/index.d.ts +2 -0
- package/dist/lib/types/component/list/AbstractSelectableList.d.ts +5 -3
- package/dist/lib/types/component/list/MultiSelectList.d.ts +2 -1
- package/dist/lib/types/component/shared/VirtualRowView.d.ts +2 -0
- package/dist/lib/types/component/table/Body.d.ts +52 -5
- package/dist/lib/types/component/table/Column.d.ts +3 -1
- package/dist/lib/types/component/table/ColumnConfig.d.ts +2 -0
- package/dist/lib/types/component/table/ColumnFilter.d.ts +27 -0
- package/dist/lib/types/component/table/Header.d.ts +31 -4
- package/dist/lib/types/component/table/Row.d.ts +24 -2
- package/dist/lib/types/component/table/Table.d.ts +31 -0
- package/dist/lib/types/component/table/TableExporter.d.ts +7 -3
- package/dist/lib/types/component/table/TablePanel.d.ts +1 -0
- package/dist/lib/types/component/table/TreeBody.d.ts +2 -1
- package/dist/lib/types/component/table/TreeTablePanel.d.ts +1 -0
- package/dist/lib/types/component/table/cell/Cell.d.ts +7 -2
- package/dist/lib/types/component/table/cell/CellText.d.ts +9 -0
- package/dist/lib/types/component/table/cell/Default.d.ts +1 -1
- package/dist/lib/types/component/table/cell/Filter.d.ts +54 -0
- package/dist/lib/types/component/table/cell/FilterClauseBadge.d.ts +21 -0
- package/dist/lib/types/component/table/cell/GroupSeparator.d.ts +9 -0
- package/dist/lib/types/component/table/cell/Header.d.ts +4 -0
- package/dist/lib/types/component/table/cell/ResizeHandle.d.ts +1 -1
- package/dist/lib/types/component/table/cell/editor/CellEditor.d.ts +1 -0
- package/dist/lib/types/component/table/cell/renderer/CellRenderer.d.ts +3 -2
- package/dist/lib/types/component/table/cell/renderer/Combo.d.ts +2 -0
- package/dist/lib/types/component/table/cell/renderer/Date.d.ts +2 -0
- package/dist/lib/types/component/table/cell/renderer/DateTime.d.ts +2 -0
- package/dist/lib/types/component/table/cell/renderer/Filter.d.ts +16 -0
- package/dist/lib/types/component/table/cell/renderer/Glyph.d.ts +1 -0
- package/dist/lib/types/component/table/cell/renderer/Link.d.ts +2 -0
- package/dist/lib/types/component/table/cell/renderer/Number.d.ts +3 -1
- package/dist/lib/types/component/table/cell/renderer/String.d.ts +5 -1
- package/dist/lib/types/component/table/cell/renderer/Time.d.ts +2 -0
- package/dist/lib/types/component/table/cell/renderer/TreeCell.d.ts +1 -0
- package/dist/lib/types/component/table/index.d.ts +7 -1
- package/dist/lib/types/component/tree/Tree.d.ts +17 -1
- package/dist/lib/types/component/tree/index.d.ts +1 -1
- package/dist/lib/types/core/AnimatedDropdown.d.ts +2 -9
- package/dist/lib/types/core/Body.d.ts +4 -0
- package/dist/lib/types/core/ClassStyleRules.d.ts +47 -3
- package/dist/lib/types/core/Component.d.ts +30 -2
- package/dist/lib/types/core/DOM.d.ts +15 -1
- package/dist/lib/types/core/Event.d.ts +11 -2
- package/dist/lib/types/core/LayerManager.d.ts +1 -0
- package/dist/lib/types/core/OverlayFade.d.ts +12 -0
- package/dist/lib/types/core/OverlayPosition.d.ts +6 -0
- package/dist/lib/types/core/StyleTarget.d.ts +2 -0
- package/dist/lib/types/core/Theme.d.ts +9 -0
- package/dist/lib/types/core/Util.d.ts +4 -0
- package/dist/lib/types/core/index.d.ts +6 -4
- package/dist/lib/types/data/AbstractStore.d.ts +3 -0
- package/dist/lib/types/data/FilterDescriptor.d.ts +13 -0
- package/dist/lib/types/data/index.d.ts +2 -1
- package/dist/lib/types/data/temporalText.d.ts +2 -0
- package/dist/lib/types/layout/BoxLayout.d.ts +6 -1
- package/dist/lib/types/layout/Grid.d.ts +1 -0
- package/dist/lib/types/layout/HFlow.d.ts +1 -1
- package/dist/lib/types/layout/Split.d.ts +10 -1
- package/dist/lib/types/layout/Tab.d.ts +7 -1
- package/dist/lib/types/layout/Table.d.ts +2 -0
- package/dist/lib/types/layout/VFlow.d.ts +1 -1
- package/dist/lib/types/layout/index.d.ts +1 -1
- package/dist/lib/types/overlay/AbstractWindow.d.ts +3 -0
- package/dist/lib/types/overlay/Dock.d.ts +1 -0
- package/dist/lib/types/overlay/Menu.d.ts +1 -1
- package/dist/lib/types/overlay/Popover.d.ts +3 -0
- package/dist/lib/types/overlay/PopupPanel.d.ts +19 -0
- package/dist/lib/types/overlay/Window.d.ts +2 -0
- package/dist/lib/types/overlay/index.d.ts +2 -0
- package/dist/lib/types/router/RoutePattern.d.ts +7 -0
- package/dist/lib/types/router/Router.d.ts +6 -2
- package/dist/lib/types/router/index.d.ts +1 -1
- package/dist/lib/validation.es.js +1 -1
- package/llms.txt +4 -0
- package/package.json +1 -1
- package/dist/lib/AbstractBooleanInput-CbW7ZrDT.js +0 -2
- package/dist/lib/AbstractBooleanInput-CbW7ZrDT.js.map +0 -1
- package/dist/lib/Anchor-BsblS5it.js +0 -2
- package/dist/lib/Anchor-BsblS5it.js.map +0 -1
- package/dist/lib/AnimatedDropdown-kL47HPGP.js +0 -2
- package/dist/lib/AnimatedDropdown-kL47HPGP.js.map +0 -1
- package/dist/lib/Border-CNS6aEXB.js +0 -2
- package/dist/lib/Border-CNS6aEXB.js.map +0 -1
- package/dist/lib/Button-T16zSZip.js +0 -2
- package/dist/lib/Button-T16zSZip.js.map +0 -1
- package/dist/lib/CodeEditor-BGlB232h.js.map +0 -1
- package/dist/lib/ComboBox-C9FYMuLv.js +0 -2
- package/dist/lib/ComboBox-C9FYMuLv.js.map +0 -1
- package/dist/lib/Component-w65rPK75.js +0 -2
- package/dist/lib/Component-w65rPK75.js.map +0 -1
- package/dist/lib/Container-C7RPLQEc.js +0 -2
- package/dist/lib/DOM-Ba8YRVel.js +0 -2
- package/dist/lib/DOM-Ba8YRVel.js.map +0 -1
- package/dist/lib/DragManager-UvPHSoRm.js +0 -2
- package/dist/lib/DragManager-UvPHSoRm.js.map +0 -1
- package/dist/lib/Glyph-DeJF_zsR.js +0 -2
- package/dist/lib/Glyph-DeJF_zsR.js.map +0 -1
- package/dist/lib/Grid-BYBohJIA.js.map +0 -1
- package/dist/lib/GridConstraints-Bts284FI.js +0 -2
- package/dist/lib/LayoutSerialization-ySzY1h2l.js +0 -2
- package/dist/lib/LayoutSerialization-ySzY1h2l.js.map +0 -1
- package/dist/lib/LayoutSizes-DKDK1Cle.js +0 -2
- package/dist/lib/LayoutSizes-DKDK1Cle.js.map +0 -1
- package/dist/lib/List-BPd-IXZR.js +0 -2
- package/dist/lib/List-BPd-IXZR.js.map +0 -1
- package/dist/lib/MemoryStore-BgP7-Uzn.js +0 -2
- package/dist/lib/MemoryStore-BgP7-Uzn.js.map +0 -1
- package/dist/lib/Menu-C0roOCY7.js +0 -2
- package/dist/lib/Menu-C0roOCY7.js.map +0 -1
- package/dist/lib/Position-PBVBW1JS.js.map +0 -1
- package/dist/lib/RadioButton-CCcIaL54.js +0 -2
- package/dist/lib/RadioButton-CCcIaL54.js.map +0 -1
- package/dist/lib/Scrollbar-C3ZZyZ1e.js +0 -2
- package/dist/lib/Scrollbar-C3ZZyZ1e.js.map +0 -1
- package/dist/lib/TabButton-DNo4ZgV8.js +0 -2
- package/dist/lib/TabButton-DNo4ZgV8.js.map +0 -1
- package/dist/lib/Text-CdHf3B-1.js +0 -2
- package/dist/lib/Text-CdHf3B-1.js.map +0 -1
- package/dist/lib/Tooltip-B_UF5bXD.js +0 -3
- package/dist/lib/Tooltip-B_UF5bXD.js.map +0 -1
- package/dist/lib/Tree-C7qLbIYH.js +0 -2
- package/dist/lib/Tree-C7qLbIYH.js.map +0 -1
- package/dist/lib/VBox-32fxpkDl.js +0 -2
- package/dist/lib/VBox-32fxpkDl.js.map +0 -1
- package/dist/lib/VirtualScroller-cvFNMS7U.js +0 -2
- package/dist/lib/VirtualScroller-cvFNMS7U.js.map +0 -1
- package/dist/lib/assets/StoreWorker-CgOBYoai.js +0 -2
- package/dist/lib/assets/StoreWorker-CgOBYoai.js.map +0 -1
- package/dist/lib/selectionsEqual-BrTxPMmK.js +0 -2
- package/dist/lib/selectionsEqual-BrTxPMmK.js.map +0 -1
- package/dist/lib/types/component/table/CellGeometry.d.ts +0 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Component-D99-15Zt.js","names":[],"sources":["../../src/typescript/lib/core/Event.ts","../../src/typescript/lib/core/StyleTarget.ts","../../src/typescript/lib/core/PendingTransitions.ts","../../src/typescript/lib/core/Animation.ts","../../src/typescript/lib/core/SmoothScroller.ts","../../src/typescript/lib/core/Callable.ts","../../src/typescript/lib/layout/FillType.ts","../../src/typescript/lib/layout/AnchorType.ts","../../src/typescript/lib/layout/LayoutManager.ts","../../src/typescript/lib/layout/Absolute.ts","../../src/typescript/lib/core/FirstLayoutGate.ts","../../src/typescript/lib/core/Type.ts","../../src/typescript/lib/core/Aria.ts","../../src/typescript/lib/core/ElementAttributes.ts","../../../../node_modules/@fontsource-variable/manrope/files/manrope-latin-ext-wght-normal.woff2","../../../../node_modules/@fontsource-variable/manrope/files/manrope-latin-wght-normal.woff2","../../src/typescript/lib/core/themes/BaseTheme.ts","../../src/typescript/lib/core/themes/ModernTheme.ts","../../src/typescript/lib/core/Theme.ts","../../src/typescript/lib/core/ComponentDefaults.ts","../../src/typescript/lib/core/ClassStyleRules.ts","../../src/typescript/lib/core/BorderWidths.ts","../../src/typescript/lib/core/Component.ts"],"sourcesContent":["// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport { DOM } from \"~/core/DOM.js\";\nimport type { Handle } from \"~/core/DOM.js\";\n\n/**\n * Event routing system that manages DOM event listeners on behalf of components.\n * Uses a single window-level capture handler per event type to avoid per-element listeners.\n *\n * @category Core\n */\nexport namespace Event {\n /** A registered listener paired with the options it was registered with. */\n interface ListenerEntry {\n listener: Listener,\n options?: ListenerOptions,\n }\n\n interface CompFunc {\n component: Component,\n listeners: ListenerEntry[]\n };\n\n /**\n * Per-call override of the default registration options for a listener.\n *\n * @remarks `passive` is a per-*type* setting: once a type has been\n * registered with a given `passive` value, subsequent registrations for\n * the same type must agree — `addListener` / `addSubtreeListener` throw\n * on conflict, since the window-level capture handler is installed once\n * per type and locks that setting for its lifetime. `button` is a\n * per-*listener* setting with no such conflict — different listeners on\n * the same type may set it independently.\n */\n export interface ListenerOptions {\n /**\n * Override the type's default passive setting. When `false`, listeners\n * for this type may call `preventDefault()` on the received event.\n */\n passive?: boolean;\n\n /**\n * Restricts which button state — see {@link isPrimaryButton} — this\n * listener fires for:\n * - `\"primary\"` — only a primary (left) press, or an event with no\n * `button` property at all (touch, hand-built fixtures).\n * - `\"aux\"` — only a defined, non-zero button (right/middle/back/\n * forward); never fires for touch. Named after the `auxclick`\n * event, which fires under this same condition — any non-primary\n * button, not just the middle button despite the DOM's\n * `MouseEvent.button` value `1` also being labelled \"auxiliary\".\n * - `\"any\"` — every button, regardless of state. Use this for a\n * listener that reacts to a button-agnostic gesture (dismissing a\n * tooltip on any press, bringing a window to front on any press,\n * …) rather than *initiating* a primary-button interaction.\n *\n * Unset resolves to `\"primary\"` for a short list of press-initiating\n * types (`mousedown`, `mouseup`, `click`, `dblclick`, `pointerdown`,\n * `pointerup` — see the internal `PRIMARY_BUTTON_TYPES` set in\n * Event.ts) and `\"any\"` for every other type, since only those few\n * types actually represent an initiating press. Set this explicitly\n * to override the default either way.\n *\n * `\"click\"` is unaffected by any of this — the dispatcher gates it\n * to the primary button unconditionally regardless of this option.\n */\n button?: \"primary\" | \"aux\" | \"any\";\n\n /**\n * Unconditionally halts DOM propagation (`stopPropagation`) after\n * this listener runs, OR'd with whatever the listener itself\n * returns — it is a floor, not an override, so a listener cannot\n * un-set it by returning `false`/`void`. Set this only when EVERY\n * code path through the listener wants the same outcome; a\n * listener whose disposition depends on runtime state (an early\n * guard-clause return, a conditional check) must leave this unset\n * and keep returning its {@link EventDisposition} instead.\n */\n stop?: boolean;\n\n /**\n * Unconditionally suppresses the default action (`preventDefault`)\n * after this listener runs. Same floor semantics as {@link stop}.\n */\n prevent?: boolean;\n }\n\n /**\n * A listener bundled with its registration options into a single\n * argument, for the {@link addListener} / {@link addSubtreeListener}\n * overload that takes options.\n */\n export interface ListenerRegistration extends ListenerOptions {\n /** The callback invoked when the event fires. See {@link addListener}. */\n handler: Listener;\n }\n\n /**\n * What a listener asks the dispatcher to do with the event it handled.\n */\n export interface EventDisposition {\n /** Halt DOM propagation (`stopPropagation`). */\n stop?: boolean;\n /** Suppress the browser's default action (`preventDefault`). */\n prevent?: boolean;\n }\n\n /** `true` is shorthand for `{ stop: true }`. Returning nothing leaves the event alone. */\n export type ListenerResult = boolean | EventDisposition | void;\n\n /** A DOM-routed listener registered through the `Event` API. */\n export type Listener = (event: any) => ListenerResult;\n\n /**\n * Reports whether a mouse/pointer event represents a primary-button\n * press. Share this rather than re-deriving it: `button === undefined`\n * (a hand-built test fixture, or a `TouchEvent`, which carries no\n * `button` at all) is treated as primary, matching the DOM's own\n * `MouseEventInit.button` default of `0` — only a defined, non-zero\n * value (right/middle/back/forward) is rejected.\n *\n * @remarks A bare `addListener`/`addSubtreeListener` registration already\n * gets primary-only filtering for free from the dispatcher's default —\n * see {@link ListenerOptions.button}. This helper remains useful for two\n * cases the default doesn't cover: a listener registered `button: \"any\"`\n * that still needs a primary check for part of its own logic (e.g. a\n * viewport listener, which isn't button-filtered at all), and a public\n * method (a drag-initiating entry point a subclass or consumer can call\n * directly, bypassing the dispatcher) validating its own precondition.\n *\n * @param e - A mouse, pointer, or touch event.\n * @returns True when the event should be treated as a primary-button press.\n */\n export function isPrimaryButton(e: MouseEvent | PointerEvent | TouchEvent): boolean {\n const button = (e as MouseEvent | PointerEvent).button;\n\n return button === undefined || button === 0;\n }\n\n /**\n * Event types whose bare registration means \"primary button only\" — the\n * gestures that actually initiate a press. Every other type defaults to\n * `\"any\"`: `contextmenu` (already the button-agnostic \"open a menu\"\n * signal — right-click, a keyboard context-menu key, a touch\n * long-press), the pointer move/cancel/capture-loss family (the Pointer\n * Events spec reports `button: -1`, \"no button change\", for all of\n * them), the mouse-flavoured half of that same family (`mousemove` /\n * `mouseover` / `mouseout` / `mouseenter` / `mouseleave`, whose `button`\n * likewise never represents a press), and `auxclick` (which by\n * definition never carries `button: 0`, so a `\"primary\"` default would\n * mean a bare registration on it could never fire).\n */\n const PRIMARY_BUTTON_TYPES: ReadonlySet<string> = new Set([\n \"mousedown\", \"mouseup\", \"click\", \"dblclick\", \"pointerdown\", \"pointerup\",\n ]);\n\n /**\n * Applies a {@link ListenerOptions.button} filter to a dispatched event.\n * `undefined` (unset) resolves to `\"primary\"` for a type in\n * {@link PRIMARY_BUTTON_TYPES}, `\"any\"` for every other type.\n */\n function passesButtonFilter(evnt: Event, type: string, filter: ListenerOptions[\"button\"]): boolean {\n const effective = filter ?? (PRIMARY_BUTTON_TYPES.has(type) ? \"primary\" : \"any\");\n\n if (effective === \"any\") {\n return true;\n }\n\n const primary = isPrimaryButton(evnt as MouseEvent);\n\n return effective === \"aux\" ? !primary : primary;\n }\n\n let listenerMap = new Map<String, Map<String, CompFunc>>();\n let viewportListenerMap = new Map<String, Map<String, CompFunc>>();\n let subtreeListenerMap = new Map<String, Map<String, CompFunc>>();\n let installedListenerTypes = new Set<string>();\n let installedListenerOpts = new Map<string, AddEventListenerOptions>();\n\n const PASSIVE_TYPES: Set<string> = new Set([\"scroll\", \"wheel\", \"touchstart\", \"touchmove\"]);\n\n function captureOpts(type: string, override?: ListenerOptions): AddEventListenerOptions {\n const passive = override?.passive ?? PASSIVE_TYPES.has(type);\n\n return { capture: true, passive };\n }\n\n /**\n * Applies a listener's returned disposition to the event, OR'd with its\n * registration's {@link ListenerOptions.stop} / {@link\n * ListenerOptions.prevent} floor, if any — either source alone is\n * enough to trigger the corresponding action.\n *\n * @returns `true` when propagation was stopped, so a dispatcher can end its walk.\n */\n function applyDisposition(evnt: Event, result: ListenerResult, options?: ListenerOptions): boolean {\n const stop = !!options?.stop || result === true || (typeof result === \"object\" && !!result?.stop);\n const prevent = !!options?.prevent || (typeof result === \"object\" && !!result?.prevent);\n\n if (prevent) {\n evnt.preventDefault();\n }\n\n if (stop) {\n evnt.stopPropagation();\n\n return true;\n }\n\n return false;\n }\n\n function installBaseListener(type: string, options?: ListenerOptions): void {\n if (!installedListenerTypes.has(type)) {\n const opts = captureOpts(type, options);\n\n installedListenerTypes.add(type);\n installedListenerOpts.set(type, opts);\n DOM.sink.addListener(DOM.source.getWindow(), type, baseListener, opts);\n\n return;\n }\n\n if (!options) {\n return;\n }\n\n const prev = installedListenerOpts.get(type)!;\n const next = captureOpts(type, options);\n\n if (prev.passive !== next.passive || prev.capture !== next.capture) {\n throw new Error(\n \"Event listener options for '\" + type +\n \"' conflict with earlier registration\"\n );\n }\n }\n\n function uninstallBaseListener(type: string): void {\n const opts = installedListenerOpts.get(type) ?? captureOpts(type);\n\n installedListenerTypes.delete(type);\n installedListenerOpts.delete(type);\n DOM.sink.removeListener(DOM.source.getWindow(), type, baseListener, opts);\n }\n\n let baseListener = function (evnt: Event) {\n // \"click\" is the framework-wide activation event (buttons, links,\n // checkboxes, menu items, ...) and is meant to represent a primary\n // (left) mouse-button activation. Reject any other button here so\n // every consumer gets that guarantee for free. `fireEvent(component,\n // \"click\")` (a programmatic `.click()`) dispatches a plain\n // `CustomEvent`, which carries no `button` property at all —\n // `isPrimaryButton` treats that as primary rather than rejecting it.\n if (evnt.type === \"click\" && !isPrimaryButton(evnt as MouseEvent)) {\n return;\n }\n\n // The dispatcher does NOT stop propagation on a component's behalf: an\n // event is halted only when a handler's returned disposition asks for\n // it (see `applyDisposition`). An unconsumed event therefore keeps\n // propagating — through the bubble phase and on to any\n // `document`-level listener (e.g. a consumer's global keyboard\n // accelerator), which a proactive stop here used to swallow whenever\n // the focused element happened to carry a library listener.\n let propagationStopped = false;\n\n // Intern the raw browser target into a handle at the boundary so no\n // downstream code holds the live node; every read below climbs in\n // handle space.\n const targetHandle = evnt.target === null ? null : DOM.source.intern(evnt.target);\n\n let listeners = listenerMap.get(evnt.type);\n if (listeners && targetHandle !== null) {\n let elementId = DOM.source.getId(targetHandle);\n let compFunc = listeners.get(elementId);\n\n if (compFunc) {\n for (let entry of compFunc.listeners) {\n if (!passesButtonFilter(evnt, evnt.type, entry.options?.button)) {\n continue;\n }\n\n if (applyDisposition(evnt, entry.listener.apply(compFunc.component, [evnt]), entry.options)) {\n propagationStopped = true;\n }\n }\n }\n }\n\n if (propagationStopped) {\n return;\n }\n\n let subtreeListeners = subtreeListenerMap.get(evnt.type);\n if (!subtreeListeners) {\n return;\n }\n\n let handle: Handle | null = targetHandle;\n while (handle) {\n let id: string;\n\n try {\n id = DOM.source.getId(handle);\n } catch {\n // `handle` was released by a disposal that ran synchronously earlier\n // in this same event's dispatch — the exact-target listener phase\n // above (a click that disposes its own target, e.g. a tab's close\n // button), or a subtree listener on a nearer ancestor already\n // visited by this same walk, disposing itself or a not-yet-visited\n // ancestor. Nothing further up this chain can be resolved through\n // this handle either, so the walk ends here instead of throwing.\n // Mirrors FocusHistory.isLive's identical guard around a stale focus\n // handle (core/FocusHistory.ts:82-92).\n return;\n }\n\n if (id) {\n let compFunc = subtreeListeners.get(id);\n if (compFunc) {\n for (let entry of compFunc.listeners) {\n if (!passesButtonFilter(evnt, evnt.type, entry.options?.button)) {\n continue;\n }\n\n if (applyDisposition(evnt, entry.listener.apply(compFunc.component, [evnt]), entry.options)) {\n propagationStopped = true;\n }\n }\n }\n }\n\n if (propagationStopped) {\n return;\n }\n\n try {\n handle = DOM.source.getParentElement(handle);\n } catch {\n // Same reentrancy hazard as above, at the climb-to-parent step: the\n // listeners that just ran on `handle` (immediately above) can\n // themselves have disposed the component `handle` belongs to.\n return;\n }\n }\n };\n\n let baseViewportListener = function (evnt: Event) {\n let typeListeners = viewportListenerMap.get(evnt.type);\n if (!typeListeners) {\n return;\n }\n\n for (let listeners of typeListeners) {\n let compFunc = listeners[1];\n if (!compFunc) {\n continue;\n }\n\n let component = compFunc.component;\n\n for (let entry of compFunc.listeners) {\n applyDisposition(evnt, entry.listener.apply(component, [evnt]), entry.options);\n }\n }\n };\n\n /**\n * Initialises the event system (currently a no-op).\n */\n export function init() {\n\n }\n\n /**\n * Dispatches a CustomEvent of the given type on the component's DOM element.\n *\n * @param component - The component whose DOM element will dispatch the event.\n * @param type - The event type string (e.g. `\"click\"`).\n * @param payload - Optional. Arbitrary data attached as the CustomEvent detail.\n *\n * @remarks Throws an error if the component has no associated DOM element at the time of the call.\n */\n export function fireEvent(component: Component, type: string, payload?: any): void;\n\n /**\n * Dispatches a pre-built event on the component's DOM element.\n *\n * @param component - The component whose DOM element will dispatch the event.\n * @param event - A pre-built DOM event to dispatch as-is.\n *\n * @remarks Useful when the event type and its properties must be preserved exactly\n * (e.g. proxying a KeyboardEvent). Throws an error if the component has no DOM element.\n */\n export function fireEvent(component: Component, event: globalThis.Event): void;\n\n export function fireEvent(component: Component, typeOrEvent: string | globalThis.Event, payload?: any): void {\n const element = component.getElement();\n if (!element) {\n const type = typeof typeOrEvent === 'string' ? typeOrEvent : typeOrEvent.type;\n throw new Error(\"Cannot fire event '\" + type + \"'. Component '\" + component.getId() + \"' is not in the DOM.\");\n }\n\n if (typeof typeOrEvent === 'string') {\n DOM.sink.dispatchCustomEvent(element, typeOrEvent, payload);\n } else {\n DOM.sink.dispatchEvent(element, typeOrEvent);\n }\n }\n\n /**\n * Resolves the `addListener` / `addSubtreeListener` overload argument\n * into a handler and its options, splitting `handler` back out of a\n * {@link ListenerRegistration} so `entry.options` never carries a\n * redundant self-reference to the same function as `entry.listener`.\n */\n function resolveRegistration(\n listenerOrRegistration: Listener | ListenerRegistration,\n ): [Listener | undefined, ListenerOptions | undefined] {\n if (!listenerOrRegistration || typeof listenerOrRegistration === \"function\") {\n return [listenerOrRegistration as Listener | undefined, undefined];\n }\n\n const { handler, ...options } = listenerOrRegistration;\n\n return [handler, options];\n }\n\n /**\n * Finds or creates the `CompFunc` for `(type, component)` in `map` and\n * appends `{ listener, options }` unless that exact `listener` reference\n * is already registered there. Shared by `addListener` and\n * `addSubtreeListener`, which differ only in which map they write to.\n */\n function registerEntry(\n map: Map<String, Map<String, CompFunc>>,\n component: Component,\n type: string,\n listener: Listener,\n options: ListenerOptions | undefined,\n ): void {\n // Validate BEFORE touching `map`: `installBaseListener` throws on a\n // passive-option conflict, and it must do so before a fresh, empty\n // `typeMap` is inserted — otherwise a failed registration leaves a\n // stale `type -> emptyMap` entry behind, which later cleanup paths\n // (e.g. `purgeComponent`'s plain `.has(type)` check) mistake for a\n // live registration and never uninstall the base listener for.\n installBaseListener(type, options);\n\n let typeMap = map.get(type);\n if (!typeMap) {\n typeMap = new Map<String, CompFunc>();\n map.set(type, typeMap);\n }\n\n let compFunc = typeMap.get(component.getId());\n if (!compFunc) {\n compFunc = { component, listeners: [] };\n typeMap.set(component.getId(), compFunc);\n }\n\n if (!compFunc.listeners.some((entry) => entry.listener === listener)) {\n compFunc.listeners.push({ listener, options });\n }\n }\n\n /**\n * Removes the entry for `listener` from `map`'s `(type, component)`\n * `CompFunc`, and cleans up the map/type-map entries it leaves empty.\n * Shared by `removeListener` and `removeSubtreeListener` — each still\n * runs its own cross-map `uninstallBaseListener` check afterward, since\n * exact-target and subtree registrations share one window-level handler\n * per type.\n */\n function unregisterEntry(\n map: Map<String, Map<String, CompFunc>>,\n component: Component,\n type: string,\n listener: Listener,\n ): void {\n let typeMap = map.get(type);\n if (!typeMap) {\n return;\n }\n\n let compFunc = typeMap.get(component.getId());\n if (!compFunc) {\n return;\n }\n\n let idx = compFunc.listeners.findIndex((entry) => entry.listener === listener);\n if (idx >= 0) {\n compFunc.listeners.splice(idx, 1);\n }\n\n if (compFunc.listeners.length === 0) {\n typeMap.delete(component.getId());\n }\n\n if (typeMap.size === 0) {\n map.delete(type);\n }\n }\n\n /**\n * Registers a listener for a DOM event type on the given component, using a single window-level handler per type.\n *\n * @param component - The component to associate the listener with.\n * @param type - The DOM event type string to listen for.\n * @param listener - The callback invoked when the event fires on this\n * component. Its return value tells the dispatcher what to do with the\n * event: `true` stops propagation, `{ prevent: true }` suppresses the\n * default action, `{ stop: true, prevent: true }` does both, and nothing\n * (or `false`) leaves the event untouched.\n *\n * @remarks A capture-phase window listener is installed the first time a given event type is registered,\n * and removed automatically when the last listener for that type is unregistered.\n */\n export function addListener(component: Component, type: string, listener: Listener): void;\n\n /**\n * Registers a listener for a DOM event type, bundled with explicit\n * registration options into a single argument.\n *\n * @param component - The component to associate the listener with.\n * @param type - The DOM event type string to listen for.\n * @param registration - The handler plus overrides for the default\n * registration options. `handler` — see the two-argument overload.\n * `passive` is native-listener-level: once a type has been registered\n * with a given `passive` value, subsequent registrations for the same\n * type must agree, or this function throws. `button` is per-listener —\n * see {@link ListenerOptions.button}. `stop` / `prevent` are an\n * unconditional floor applied regardless of `handler`'s return value —\n * see {@link ListenerOptions.stop}.\n */\n export function addListener(component: Component, type: string, registration: ListenerRegistration): void;\n\n export function addListener(\n component: Component,\n type: string,\n listenerOrRegistration: Listener | ListenerRegistration,\n ): void {\n const [listener, options] = resolveRegistration(listenerOrRegistration);\n\n if (!listener || !component) {\n return;\n }\n\n registerEntry(listenerMap, component, type, listener, options);\n }\n\n /**\n * Removes a previously registered component event listener.\n *\n * @param component - The component whose listener should be removed.\n * @param type - The DOM event type string the listener was registered for.\n * @param listener - The exact callback function reference that was passed to `addListener`.\n *\n * @remarks If removing the listener leaves a component or event type with no remaining listeners,\n * the corresponding map entries and the window-level handler are cleaned up automatically.\n */\n export function removeListener(component: Component, type: string, listener: Listener) {\n if (!listener || !component) {\n return;\n }\n\n unregisterEntry(listenerMap, component, type, listener);\n\n const subtreeMap = subtreeListenerMap.get(type);\n const bothEmpty = !listenerMap.has(type) && (!subtreeMap || subtreeMap.size === 0);\n if (bothEmpty && installedListenerTypes.has(type)) {\n uninstallBaseListener(type);\n }\n }\n\n /**\n * Registers a listener that fires whenever the given event type targets this component\n * or any of its DOM descendants.\n *\n * @param component - The ancestor component to watch.\n * @param type - The DOM event type string to listen for.\n * @param listener - The callback invoked when a matching event bubbles\n * through this component's subtree. Its return value tells the\n * dispatcher what to do with the event: `true` stops propagation (ending\n * the walk after every listener on this component has run — no further\n * ancestor is visited), `{ prevent: true }` suppresses the default\n * action, `{ stop: true, prevent: true }` does both, and nothing (or\n * `false`) leaves the event untouched.\n *\n * @remarks Unlike `addListener`, which only matches the exact event target, this fires for\n * any event whose target is a descendant of the component's element. Multiple components\n * may register subtree listeners for the same event type; all matching ancestors are notified.\n */\n export function addSubtreeListener(component: Component, type: string, listener: Listener): void;\n\n /**\n * Registers a subtree listener, bundled with explicit registration\n * options into a single argument.\n *\n * @param component - The ancestor component to watch.\n * @param type - The DOM event type string to listen for.\n * @param registration - See {@link addListener}'s registration overload.\n */\n export function addSubtreeListener(component: Component, type: string, registration: ListenerRegistration): void;\n\n export function addSubtreeListener(\n component: Component,\n type: string,\n listenerOrRegistration: Listener | ListenerRegistration,\n ): void {\n const [listener, options] = resolveRegistration(listenerOrRegistration);\n\n if (!listener || !component) {\n return;\n }\n\n registerEntry(subtreeListenerMap, component, type, listener, options);\n }\n\n /**\n * Removes a previously registered subtree event listener.\n *\n * @param component - The component whose subtree listener should be removed.\n * @param type - The DOM event type string the listener was registered for.\n * @param listener - The exact callback function reference that was passed to `addSubtreeListener`.\n */\n export function removeSubtreeListener(component: Component, type: string, listener: Listener): void {\n if (!listener || !component) {\n return;\n }\n\n unregisterEntry(subtreeListenerMap, component, type, listener);\n\n const exactMap = listenerMap.get(type);\n const bothEmpty = (!exactMap || exactMap.size === 0) && !subtreeListenerMap.has(type);\n if (bothEmpty && installedListenerTypes.has(type)) {\n uninstallBaseListener(type);\n }\n }\n\n /**\n * @internal Migrates a component's exact-target and subtree listener\n * registrations from `oldId` to `newId` after its id changes. No-op when the\n * ids are equal or the component has no registrations. Does not touch viewport\n * listeners (dispatched by whole-map iteration, not by id).\n */\n export function reindexComponent(oldId: string, newId: string): void {\n if (oldId === newId) {\n return;\n }\n\n for (const typeMap of listenerMap.values()) {\n const compFunc = typeMap.get(oldId);\n if (compFunc) {\n typeMap.set(newId, compFunc);\n typeMap.delete(oldId);\n }\n }\n\n for (const typeMap of subtreeListenerMap.values()) {\n const compFunc = typeMap.get(oldId);\n if (compFunc) {\n typeMap.set(newId, compFunc);\n typeMap.delete(oldId);\n }\n }\n }\n\n /**\n * @internal Drops every exact-target, subtree and viewport listener\n * registration held under `componentId`, and uninstalls each window-level\n * base listener whose last registration this removed. Called from\n * `Component.destructor`. No-op for an id with no registrations.\n */\n export function purgeComponent(componentId: string): void {\n const touched = new Set<string>();\n\n // The maps are declared with `String` (object) keys throughout this\n // module while every write passes a primitive, so normalise on the\n // way out (same reasoning as `_registeredComponentIds` below).\n for (const [type, typeMap] of listenerMap) {\n if (typeMap.delete(componentId)) {\n touched.add(String(type));\n\n if (typeMap.size === 0) {\n listenerMap.delete(type);\n }\n }\n }\n\n for (const [type, typeMap] of subtreeListenerMap) {\n if (typeMap.delete(componentId)) {\n touched.add(String(type));\n\n if (typeMap.size === 0) {\n subtreeListenerMap.delete(type);\n }\n }\n }\n\n // Both id-routed maps share one window-level base listener per type, so the\n // uninstall check runs once per touched type after both loops — mirroring\n // the `bothEmpty` test in removeListener / removeSubtreeListener.\n for (const type of touched) {\n if (!listenerMap.has(type) && !subtreeListenerMap.has(type) && installedListenerTypes.has(type)) {\n uninstallBaseListener(type);\n }\n }\n\n // The viewport map has its own base listener, installed and removed with\n // the type-map itself rather than through installedListenerTypes.\n for (const [type, typeMap] of viewportListenerMap) {\n if (!typeMap.delete(componentId) || typeMap.size > 0) {\n continue;\n }\n\n viewportListenerMap.delete(type);\n\n const typeStr = String(type);\n DOM.sink.removeListener(DOM.source.getWindow(), typeStr, baseViewportListener, captureOpts(typeStr));\n }\n }\n\n /** Ids currently holding any listener registration; for tests only. @internal */\n export function _registeredComponentIds(): readonly string[] {\n const ids = new Set<string>();\n\n for (const map of [listenerMap, subtreeListenerMap, viewportListenerMap]) {\n for (const typeMap of map.values()) {\n // The maps are declared with `String` (object) keys throughout this\n // module while every write passes a primitive, so normalise here.\n for (const id of typeMap.keys()) {\n ids.add(String(id));\n }\n }\n }\n\n return Array.from(ids);\n }\n\n /**\n * Registers a viewport-level listener that fires for all matching events regardless of target element.\n *\n * @param component - The component to associate the listener with.\n * @param type - The DOM event type string to listen for globally.\n * @param listener - The callback invoked on every matching event. Its\n * return value tells the dispatcher what to do with the event: `true`\n * stops propagation, `{ prevent: true }` suppresses the default action,\n * `{ stop: true, prevent: true }` does both, and nothing (or `false`)\n * leaves the event untouched.\n *\n * @remarks Unlike `addListener`, viewport listeners are not filtered by element id — every\n * registered component receives the event, regardless of dispatch order, and a component\n * whose listener returns a stop disposition does not prevent the others from running. The\n * dispatcher does not stop propagation on a component's behalf: an unconsumed event keeps\n * propagating to the page (e.g. a consumer's `document`-level accelerator) unless a handler's\n * returned disposition asks for a stop. Logs a console trace and returns early if either\n * argument is falsy.\n */\n export function addViewportListener(component: Component, type: string, listener: Listener) {\n if (!listener || !component) {\n console.trace();\n return;\n }\n\n let typeMap = viewportListenerMap.get(type);\n if (!typeMap) {\n typeMap = new Map<String, CompFunc>();\n viewportListenerMap.set(type, typeMap);\n\n DOM.sink.addListener(DOM.source.getWindow(), type, baseViewportListener, captureOpts(type));\n }\n\n let compFunc = typeMap.get(component.getId());\n if (!compFunc) {\n compFunc = {\n component: component,\n listeners: []\n }\n\n typeMap.set(component.getId(), compFunc);\n }\n\n compFunc.listeners.push({ listener });\n }\n\n /**\n * Removes a previously registered viewport-level listener.\n *\n * @param component - The component whose viewport listener should be removed.\n * @param type - The DOM event type string the listener was registered for.\n * @param listener - The exact callback function reference that was passed to `addViewportListener`.\n *\n * @remarks Cleans up empty map entries and the window-level handler when no listeners remain\n * for a given event type, mirroring the behaviour of `removeListener`.\n */\n export function removeViewportListener(component: Component, type: string, listener: Listener) {\n if (!listener || !component) {\n return;\n }\n\n let typeMap = viewportListenerMap.get(type);\n if (!typeMap) {\n return;\n }\n\n let compFunc = typeMap.get(component.getId());\n if (!compFunc) {\n return;\n }\n\n let idx = compFunc.listeners.findIndex((entry) => entry.listener === listener);\n if (idx >= 0) {\n compFunc.listeners.splice(idx, 1);\n }\n\n if (compFunc.listeners.length == 0) {\n typeMap.delete(component.getId());\n }\n\n if (typeMap.size == 0) {\n viewportListenerMap.delete(type);\n DOM.sink.removeListener(DOM.source.getWindow(), type, baseViewportListener, captureOpts(type));\n }\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { DOM } from \"~/core/DOM.js\";\nimport type { Handle } from \"~/core/DOM.js\";\n\n/**\n * Shared base for a deferred-write style buffer. Either flushes into a\n * [`CSSStyleRule`](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleRule)\n * (see {@link StyleRule}) or an element behind a {@link Handle}\n * (see {@link InlineStyle}).\n *\n * @remarks Before the target exists, writes accumulate in `dirty`. Once\n * `materialize` runs, queued entries flush onto the target's\n * `style` declaration and subsequent {@link StyleTarget.set} calls write\n * through directly. {@link StyleTarget.queue} is a write-to-dirty-only path\n * used by callers that need to batch their own commits (see Component's\n * `autoCommitStyle` switch).\n *\n * @typeParam T - The materialised target kind: a `CSSStyleRule` for\n * {@link StyleRule}, or a {@link Handle} for {@link InlineStyle}.\n *\n * @category Core\n */\nabstract class StyleTarget<T> {\n protected _target: T | null = null;\n protected _dirty: Record<string, string | null> = {};\n\n /**\n * Writes a single style property. Flushes immediately when the target is\n * attached; otherwise queues the entry into the dirty bag.\n *\n * @param key - The CSS property name (camelCase).\n * @param value - The value to set, or null to remove the property.\n */\n set(key: string, value: string | null): void {\n if (this._target) {\n this.writeStyle(key, value);\n } else {\n this._dirty[key] = value;\n }\n }\n\n /**\n * Bulk variant of {@link StyleTarget.set}.\n *\n * @param values - Camel-cased property keys mapped to string values (or null to clear).\n */\n setMany(values: Record<string, string | null>): void {\n for (const key of Object.keys(values)) this.set(key, values[key]);\n }\n\n /**\n * Writes a single style property into the dirty bag without flushing,\n * even when the target is already attached. Callers that own their own\n * batching gate (e.g. `autoCommitStyle = false`) use this to accumulate\n * writes that {@link StyleTarget.flush} will drain later.\n *\n * @param key - The CSS property name (camelCase).\n * @param value - The value to set, or null to remove the property.\n */\n queue(key: string, value: string | null): void {\n this._dirty[key] = value;\n }\n\n /**\n * Bulk variant of {@link StyleTarget.queue}.\n *\n * @param values - Camel-cased property keys mapped to string values (or null to clear).\n */\n queueMany(values: Record<string, string | null>): void {\n Object.assign(this._dirty, values);\n }\n\n /**\n * Drains the dirty bag onto the live target. No-op when the target is\n * not yet attached — the dirty entries stay queued for the next flush\n * after `materialize`.\n */\n flush(): void {\n if (!this._target) return;\n this.flushDirty(this._dirty);\n this._dirty = {};\n }\n\n /**\n * Returns whether the underlying target has been materialised.\n */\n isMaterialized(): boolean {\n return this._target !== null;\n }\n\n /**\n * Returns whether any write is waiting in the dirty bag. Owners that decide\n * whether the target is worth materialising at all read this first.\n */\n hasQueuedWrites(): boolean {\n return Object.keys(this._dirty).length > 0;\n }\n\n /**\n * Returns whether the dirty bag holds at least one entry that would produce\n * a real CSS declaration if flushed — a queued value that isn't a no-op\n * `null` removal. Distinct from {@link StyleTarget.hasQueuedWrites}, which\n * only asks whether the bag is non-empty and can't tell a real declaration\n * from a bag holding only `null` entries queued before the target ever\n * existed.\n */\n hasQueuedDeclarations(): boolean {\n for (const key of Object.keys(this._dirty)) {\n if (this._dirty[key] !== null) {\n return true;\n }\n }\n\n return false;\n }\n\n protected materialize(target: T): void {\n this._target = target;\n this.flushDirty(this._dirty);\n this._dirty = {};\n }\n\n /**\n * Terminal write for a single property onto the now-attached target. Each\n * subclass resolves its own target kind through the seam — an element via\n * {@link DOMSink.apply}, a rule via {@link DOMSink.setRuleStyles} — so the\n * base never touches a `.style` declaration directly.\n *\n * @param key - The CSS property name (camelCase, or `--custom-property`).\n * @param value - The value to set, or null to remove the property.\n */\n protected abstract writeStyle(key: string, value: string | null): void;\n\n /**\n * Drains a bag of accumulated writes onto the now-attached target. Both\n * subclasses batch the whole bag into one seam write.\n *\n * @param dirty - The accumulated property writes to flush.\n */\n protected abstract flushDirty(dirty: Record<string, string | null>): void;\n}\n\n/**\n * Scope discriminator for the {@link StyleRule} constructor.\n *\n * - `class` — leading `.` is prepended; `name: \"Foo\"` selects `.Foo`. An\n * optional `suffix` (e.g. `\".pressed\"`, `\":hover:not(.pressed)\"`) is\n * appended verbatim, after the class name, so it stays live selector syntax.\n * - `component` — leading `#` is prepended and the id is CSS-escaped (so a `.`\n * or `:` in a consumer-supplied id does not break the selector); `name: \"id\"`\n * selects `#id`. An optional `suffix` (e.g. `\":hover\"`, `\".selected\"`) is\n * appended verbatim, after the escaped id, so it stays live selector syntax.\n * - `selector` — verbatim selector text; the escape hatch for pseudo-classes\n * (`\":hover\"`), compound selectors (`\".A.B\"`), pseudo-elements\n * (`\".X::-webkit-scrollbar\"`), and any other shape outside the first two.\n *\n * @category Core\n */\nexport type StyleRuleScope =\n | { scope: \"class\"; name: string; suffix?: string }\n | { scope: \"component\"; name: string; suffix?: string }\n | { scope: \"selector\"; name: string };\n\n/**\n * Construction config for a {@link StyleRule}. Combines a {@link StyleRuleScope}\n * (selector shape) with optional initial CSS body and an optional defer-flush\n * flag.\n *\n * - `styles` — initial style body, applied via `setMany` from the constructor.\n * Omit for imperative builders that write later via `set`.\n * - `materialize` — defaults to `true`. Set to `false` to skip the auto\n * `ensure()` call. Used by `Component`'s internal `_styleRule` and\n * `createStyleRule` allocations to keep construction JS-only and let the\n * render pipeline materialise the stylesheet entry on first `applyStyle`.\n *\n * @category Core\n */\nexport type StyleRuleSpec = StyleRuleScope & {\n styles?: Record<string, string | null>;\n materialize?: boolean;\n};\n\n// Module-level cache of materialised `CSSStyleRule`s keyed by selector text.\n// Two `StyleRule` instances constructed with the same scope+name share the\n// underlying `CSSStyleRule`. Survives across hot reloads because the module\n// reference is the single source of truth.\nconst _ruleCache: Map<string, CSSStyleRule> = new Map();\n\n/**\n * Translates a {@link StyleRuleScope} into its CSS selector string.\n */\nfunction _selectorOf(spec: StyleRuleScope): string {\n switch (spec.scope) {\n case \"class\": return \".\" + spec.name + (spec.suffix ?? \"\");\n case \"component\": return \"#\" + DOM.source.escapeSelector(spec.name) + (spec.suffix ?? \"\");\n case \"selector\": return spec.name;\n }\n}\n\n/**\n * Returns the shared-stylesheet `CSSStyleRule` for the selector, warming the\n * module cache. The `cssRules` scan and `insertRule` live behind the seam\n * ({@link DOMSink.ensureStyleRule}); the cache here spares repeat lookups when\n * two `StyleRule` instances share a selector.\n */\nfunction _ruleFor(selector: string): CSSStyleRule {\n const cached = _ruleCache.get(selector);\n\n if (cached) {\n return cached;\n }\n\n const rule = DOM.sink.ensureStyleRule(selector);\n _ruleCache.set(selector, rule);\n\n return rule;\n}\n\n/**\n * Deletes the shared-stylesheet `CSSStyleRule` for a selector, if materialised,\n * and evicts it from the module cache. The inverse of {@link _ruleFor}. A\n * no-op when the selector was never materialised — the `_ruleCache.has` guard\n * is the materialisation signal, so this never scans `cssRules` for a\n * selector that was never inserted.\n *\n * @param selector - The CSS selector text to remove.\n */\nexport function disposeStyleRule(selector: string): void {\n if (!_ruleCache.has(selector)) return;\n\n DOM.sink.deleteStyleRule(selector);\n _ruleCache.delete(selector);\n}\n\n/** Whether the module rule cache holds a rule for the selector; for tests only. @internal */\nexport function _ruleCacheHas(selector: string): boolean {\n return _ruleCache.has(selector);\n}\n\n/** Snapshot of the module rule cache's selectors; for tests only. @internal */\nexport function _ruleCacheKeys(): readonly string[] {\n return Array.from(_ruleCache.keys());\n}\n\n/**\n * Deferred-write buffer that materialises into a\n * [`CSSStyleRule`](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleRule)\n * on the framework's shared `<style id=\"Base\">` stylesheet the first time\n * {@link StyleRule.ensure} is called.\n *\n * @remarks Construction is cheap — no stylesheet insertion happens until\n * `ensure()` runs, so detached construction stays JS-only. Once materialised,\n * the rule object is stable for the lifetime of this `StyleRule`. Two\n * `StyleRule` instances constructed with the same scope+name share the\n * underlying `CSSStyleRule` via the module-level cache.\n *\n * Inherited {@link StyleTarget.set} queues writes into a dirty bag while the\n * target is null and writes through once `ensure()` has materialised the rule.\n * Owners that need the rule on the stylesheet at first render (rather than at\n * first write) register the rule via Component's `registerStyleRule`, which\n * calls `ensure()` from `applyStyle` and flushes the dirty bag onto the live\n * `CSSStyleRule`.\n *\n * @category Core\n */\nclass StyleRule extends StyleTarget<CSSStyleRule> {\n private _factory: () => CSSStyleRule;\n private _selector: string;\n\n /**\n * Constructs a `StyleRule` for the given scoped selector and, optionally,\n * an initial style body.\n *\n * @param spec - The {@link StyleRuleSpec} describing the rule's selector,\n * optional initial styles, and optional `materialize` flag.\n *\n * @remarks When `spec.styles` is present, the styles are queued via\n * `setMany` before any materialisation runs (the target is still null at\n * that point, so the writes land in `_dirty`). When `spec.materialize`\n * is not explicitly `false`, the constructor calls `ensure()` so the\n * underlying `CSSStyleRule` is created and the queued styles flush onto\n * it in one step. Internal callers that need to keep construction\n * JS-only — e.g. `Component`'s per-id `_styleRule` and `createStyleRule`\n * allocations — pass `materialize: false` and rely on the render\n * pipeline to call `ensure()` later.\n */\n constructor(spec: StyleRuleSpec) {\n super();\n const selector = _selectorOf(spec);\n this._factory = () => _ruleFor(selector);\n this._selector = selector;\n\n if (spec.styles) {\n this.setMany(spec.styles);\n }\n\n if (spec.materialize !== false) {\n this.ensure();\n }\n }\n\n /**\n * Materialises the underlying `CSSStyleRule` on first access and returns\n * it. Pending dirty entries are flushed in the same call.\n */\n ensure(): CSSStyleRule {\n if (!this._target) {\n this.materialize(this._factory());\n }\n return this._target!;\n }\n\n /** Returns this rule's CSS selector text. */\n getSelector(): string {\n return this._selector;\n }\n\n /**\n * Deletes the materialised `CSSStyleRule` from the shared stylesheet and\n * evicts it from the module cache, then resets to the unmaterialised state\n * so a later {@link ensure} re-materialises. No-op if never materialised.\n * Idempotent.\n */\n dispose(): void {\n disposeStyleRule(this._selector);\n this._target = null;\n this._dirty = {};\n }\n\n /** @inheritDoc */\n protected writeStyle(key: string, value: string | null): void {\n DOM.sink.setRuleStyles(this._target!, { [key]: value });\n }\n\n /** @inheritDoc */\n protected flushDirty(dirty: Record<string, string | null>): void {\n if (Object.keys(dirty).length === 0) {\n return;\n }\n\n DOM.sink.setRuleStyles(this._target!, dirty);\n }\n\n /**\n * Inserts a `@keyframes` block into the framework's shared `<style id=\"Base\">`\n * stylesheet if no rule with the given name already exists.\n *\n * @param name - The keyframe animation name (no `@keyframes` prefix).\n * @param body - The keyframe body, e.g. `\"from { transform: rotate(0deg) } to { transform: rotate(360deg) }\"`.\n *\n * @remarks Idempotent: safe to call from module-level initialisers across\n * hot reloads. `@keyframes` rules are not selector-keyed `CSSStyleRule`s\n * and so do not flow through the `StyleRule` instance cache.\n */\n static ensureKeyframes(name: string, body: string): void {\n DOM.sink.ensureKeyframes(name, body);\n }\n}\n\n/**\n * Deferred-write buffer for inline `element.style` writes. Stays detached\n * until {@link InlineStyle.attach} runs — typically from `Component.init`\n * once the root element exists.\n *\n * @category Core\n */\nclass InlineStyle extends StyleTarget<Handle> {\n /**\n * Binds this buffer to a live element handle and flushes any queued writes.\n *\n * @param handle - The element handle to attach to.\n */\n attach(handle: Handle): void {\n this.materialize(handle);\n }\n\n /** @inheritDoc */\n protected writeStyle(key: string, value: string | null): void {\n DOM.sink.apply(this._target!, { style: { [key]: value } });\n }\n\n /**\n * Flushes the whole dirty bag as one batched {@link DOMSink.apply} — the\n * per-frame layout-commit hot path, where one handle resolve covers every\n * queued style write.\n *\n * @param dirty - The accumulated style writes to flush.\n */\n protected flushDirty(dirty: Record<string, string | null>): void {\n DOM.sink.apply(this._target!, { style: dirty });\n }\n}\n\nexport { StyleTarget, StyleRule, InlineStyle };\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\n// Framework-internal registry mapping a live element `Handle` to the cancel\n// functions of the `Animation.play` transitions still running against it.\n// `Component.destructor()` consults this immediately before it releases its\n// handles, so a deferred write queued by `play`'s two-frame entrance dance —\n// or the `transition: null` reset its completion performs — never lands on a\n// handle already returned to the pool. Not exported from `core/index.ts`:\n// this module exists purely to let `Animation.ts` and `Component.ts` share\n// this bookkeeping without importing each other, mirroring\n// `core/ClassStyleRules.ts` and `core/ComponentDefaults.ts`.\n\nimport type { Handle } from \"~/core/DOM.js\";\n\n/** Cancel functions of the transitions still running against each handle. */\nconst running: Map<Handle, Set<() => void>> = new Map();\n\n/**\n * Records a transition's cancel function against the handle it animates.\n *\n * @param handle - The element handle the transition is writing to.\n * @param cancel - The transition's own cancel function.\n */\nexport function registerTransition(handle: Handle, cancel: () => void): void {\n let cancels = running.get(handle);\n\n if (!cancels) {\n cancels = new Set();\n running.set(handle, cancels);\n }\n\n cancels.add(cancel);\n}\n\n/**\n * Forgets a transition's cancel function, called once it finishes or is\n * cancelled through its own handle so completed work never accumulates.\n *\n * @param handle - The element handle the transition was writing to.\n * @param cancel - The transition's own cancel function.\n */\nexport function unregisterTransition(handle: Handle, cancel: () => void): void {\n const cancels = running.get(handle);\n\n if (!cancels) {\n return;\n }\n\n cancels.delete(cancel);\n\n if (cancels.size === 0) {\n running.delete(handle);\n }\n}\n\n/**\n * Invokes and forgets every cancel function registered for `handle`. Called\n * by `Component.destructor()` immediately before the handle is released.\n *\n * @param handle - The element handle about to be released.\n */\nexport function cancelTransitions(handle: Handle): void {\n const cancels = running.get(handle);\n\n if (!cancels) {\n return;\n }\n\n running.delete(handle);\n\n for (const cancel of cancels) {\n cancel();\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport type { ComponentFactory } from \"~/core/Component.js\";\nimport { DOM } from \"~/core/DOM.js\";\nimport type { Handle, TimerId } from \"~/core/DOM.js\";\nimport { InlineStyle } from \"~/core/StyleTarget.js\";\nimport { registerTransition, unregisterTransition } from \"~/core/PendingTransitions.js\";\n\n/**\n * Small helpers for playing CSS transitions on raw DOM elements.\n *\n * @remarks\n * The framework's animation surface today is intentionally narrow: a single\n * `play(element, config)` function that drives an entrance OR exit transition\n * on one element, plus an `isReducedMotion()` predicate the call sites use\n * to short-circuit. Both [`Notification`](/api/overlay/classes/Notification) and\n * [`Dialog`](/api/overlay/classes/Dialog) build their entrance/dismiss flows\n * on top of this utility so the two-RAF flush, transition wiring, and\n * `transitionend`-with-fallback bookkeeping live in one place.\n *\n * @category Core\n */\nexport namespace Animation {\n\n /**\n * Configuration for {@link Animation.play}.\n *\n * @category Core\n */\n export interface PlayConfig {\n /**\n * Optional styles applied to the element BEFORE the transition kicks\n * in. Use this for entrance animations to set the off-screen / invisible\n * \"from\" state. Omit for exit transitions whose start state is whatever\n * the element currently renders.\n */\n from?: Partial<CSSStyleDeclaration>;\n\n /** Styles applied with the transition active — the \"to\" state. */\n to: Partial<CSSStyleDeclaration>;\n\n /** Transition duration in milliseconds. */\n durationMs: number;\n\n /**\n * CSS property names included in the generated `transition` shorthand.\n * Example: `[\"opacity\", \"transform\"]`.\n */\n properties: string[];\n\n /** CSS easing function. Defaults to `\"ease-out\"`. */\n easing?: string;\n\n /**\n * Called when the transition completes (or is skipped because of\n * reduced motion). Always fires exactly once.\n */\n onComplete?: () => void;\n\n /**\n * Milliseconds added to {@link PlayConfig.durationMs} for the fallback\n * `setTimeout` that fires if `transitionend` never arrives (tab switch,\n * interrupted transition, …). Defaults to 40 ms.\n */\n fallbackBufferMs?: number;\n }\n\n /**\n * Returns `true` when the user has requested reduced motion via\n * `prefers-reduced-motion: reduce`.\n *\n * @returns Whether motion-reducing UI rules should apply.\n */\n export function isReducedMotion(): boolean {\n return DOM.source.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n }\n\n /**\n * Plays a CSS transition on the given element.\n *\n * @param el - Target element.\n * @param config - Animation parameters.\n *\n * @remarks\n * When {@link PlayConfig.from} is supplied the helper applies it first,\n * lets the browser settle for two animation frames (one alone still races\n * layout in Firefox), then applies the transition shorthand and the `to`\n * styles. Without `from` the transition fires immediately, taking the\n * element's current inline styles as the start state.\n *\n * Honours `prefers-reduced-motion: reduce`: when set, the `to` styles are\n * applied synchronously and `onComplete` fires on the same tick.\n *\n * @returns A handle whose `cancel()` abandons the animation and suppresses\n * `onComplete`. Cancelling touches no DOM, so it stays safe once the\n * element's handle has been released. The transition also registers\n * itself, for the `el` it targets, with a framework-internal pending-\n * transition registry that a component's teardown consults to cancel any\n * transition still running against a handle it is about to release —\n * so a caller never needs to track this handle purely to avoid a stray\n * deferred write into a torn-down element.\n */\n export function play(el: Handle, config: PlayConfig): CancelHandle {\n const easing = config.easing ?? \"ease-out\";\n const fallback = config.fallbackBufferMs ?? 40;\n\n // Route every write through the framework's deferred inline-style\n // buffer rather than touching `el.style` directly. `attach()` flushes\n // synchronously so subsequent `set` / `setMany` calls land on the\n // live element. The buffer is scoped to this `play()` invocation;\n // each call gets a fresh wrapper bound to `el`.\n const buf = new InlineStyle();\n buf.attach(el);\n\n if (isReducedMotion()) {\n buf.setMany(config.to as Record<string, string | null>);\n config.onComplete?.();\n return NOOP_HANDLE;\n }\n\n let done = false;\n let cancelled = false;\n let frameId: number | null = null;\n let timerId: TimerId | null = null;\n\n // Declared before `finish` so both it and the two-frame yield below\n // can register/unregister the same reference with the pending-\n // transition registry — the mechanism `Component.destructor()` uses\n // to abandon a still-running transition before releasing `el`.\n const cancel = (): void => {\n if (done || cancelled) {\n return;\n }\n\n cancelled = true;\n\n if (frameId !== null) {\n DOM.sink.cancelAnimationFrame(frameId);\n frameId = null;\n }\n\n if (timerId !== null) {\n DOM.sink.clearTimeout(timerId);\n timerId = null;\n }\n\n unregisterTransition(el, cancel);\n };\n\n const finish = (): void => {\n if (done || cancelled) {\n return;\n }\n done = true;\n\n unregisterTransition(el, cancel);\n\n // transitionend won the race: disarm the fallback so it can never\n // run against an element that may be torn down by then.\n if (timerId !== null) {\n DOM.sink.clearTimeout(timerId);\n timerId = null;\n }\n\n // Clear the transition rule so subsequent style changes\n // (e.g. a Window drag setting `transform: translate(...)`\n // after the entrance fade) aren't retroactively animated\n // through it. Done before `onComplete` so callers that\n // start a fresh `play()` from the callback can install\n // their own transition without it being clobbered.\n buf.set(\"transition\", null);\n\n config.onComplete?.();\n };\n\n const applyTransitionAndTo = (): void => {\n frameId = null;\n\n if (cancelled) {\n return;\n }\n\n buf.set(\n \"transition\",\n config.properties\n .map(p => `${p} ${config.durationMs}ms ${easing}`)\n .join(\", \"),\n );\n\n buf.setMany(config.to as Record<string, string | null>);\n\n DOM.sink.addListener(el, \"transitionend\", finish, { once: true });\n timerId = DOM.sink.setTimeout(finish, config.durationMs + fallback);\n };\n\n registerTransition(el, cancel);\n\n if (config.from) {\n buf.setMany(config.from as Record<string, string | null>);\n frameId = DOM.sink.requestAnimationFrame(() => {\n frameId = DOM.sink.requestAnimationFrame(applyTransitionAndTo);\n });\n } else {\n applyTransitionAndTo();\n }\n\n return { cancel };\n }\n\n /**\n * Configuration for {@link Animation.afterTransition}.\n *\n * @category Core\n */\n export interface AfterTransitionConfig {\n /**\n * Component whose `transitionend` event to listen for. The event must\n * fire on this component's own element (not a descendant) for the\n * filter to match.\n */\n component: Component;\n\n /**\n * Optional CSS property filter — `onComplete` fires only when the\n * transition of the named property ends. Other property completions\n * (e.g. a concurrent `top` transition on a multi-property declaration)\n * are ignored. Omit to fire on the first transitionend of any property.\n */\n property?: string;\n\n /**\n * Transition duration in milliseconds, used to size the fallback timer\n * that guarantees `onComplete` fires even when `transitionend` doesn't\n * (toggling between identical values, tab switch mid-transition, …).\n */\n durationMs: number;\n\n /**\n * Milliseconds added to {@link AfterTransitionConfig.durationMs} for\n * the fallback `setTimeout`. Defaults to 40 ms.\n */\n fallbackBufferMs?: number;\n\n /**\n * Invoked when the transition completes (via `transitionend`) or when\n * the fallback timer fires. Always called exactly once.\n */\n onComplete: () => void;\n }\n\n /**\n * Wires up a one-shot completion handler for a CSS transition installed\n * on a Component out-of-band — i.e. when the \"to\" styles are written by\n * something other than this helper, so {@link Animation.play} doesn't fit.\n *\n * @param config - The component, property filter, duration, and callback.\n *\n * @remarks Mirrors the `transitionend`-with-`setTimeout`-fallback\n * bookkeeping in {@link Animation.play} so layouts that install\n * transitions outside `play()` (notably the\n * [`Accordion`](/api/layout/classes/Accordion), whose section heights are\n * written by the parent layout's `getPreferredSize` query) stay\n * consistent with the framework's one-finish-only contract.\n *\n * @returns A handle whose `cancel()` abandons the wait and suppresses\n * `onComplete`. Like `play`'s, cancelling touches no DOM — it leaves the\n * `transitionend` listener attached but inert.\n */\n export function afterTransition(config: AfterTransitionConfig): CancelHandle {\n const el = config.component.getElement();\n\n if (!el) {\n config.onComplete();\n return NOOP_HANDLE;\n }\n\n let done = false;\n let cancelled = false;\n let timerId: TimerId | null = null;\n\n const finish = (): void => {\n if (done || cancelled) {\n return;\n }\n done = true;\n\n // transitionend won the race: disarm the fallback before it can\n // fire against an element that may be torn down by then.\n if (timerId !== null) {\n DOM.sink.clearTimeout(timerId);\n timerId = null;\n }\n\n DOM.sink.removeListener(el, \"transitionend\", onEnd);\n config.onComplete();\n };\n const onEnd = (event: TransitionEvent): void => {\n if (config.property !== undefined && event.propertyName !== config.property) {\n return;\n }\n finish();\n };\n\n DOM.sink.addListener(el, \"transitionend\", onEnd);\n timerId = DOM.sink.setTimeout(finish, config.durationMs + (config.fallbackBufferMs ?? 40));\n\n return {\n cancel: (): void => {\n if (done || cancelled) {\n return;\n }\n\n cancelled = true;\n\n if (timerId !== null) {\n DOM.sink.clearTimeout(timerId);\n timerId = null;\n }\n },\n };\n }\n\n /**\n * Configuration for {@link Animation.tween}.\n *\n * @category Core\n */\n export interface TweenConfig<T extends { [K in keyof T]: number }> {\n /** Starting values, keyed by property name. */\n from: T;\n\n /** Ending values. Must carry the same keys as `from`. */\n to: T;\n\n /** Tween duration in milliseconds. */\n durationMs: number;\n\n /**\n * Easing function mapping linear progress `t` (0..1) to eased progress.\n * Defaults to cubic ease-out (`1 - (1 - t)^3`).\n */\n easing?: (t: number) => number;\n\n /**\n * Invoked on every frame with the interpolated values for that tick.\n * Use this to route the values through typed setters or any other\n * write channel — `tween` does not assume DOM access.\n */\n onStep: (values: T) => void;\n\n /** Invoked once when the tween completes naturally. Not called on cancel. */\n onComplete?: () => void;\n }\n\n /**\n * Handle returned by every animation helper here. Call `cancel()` to\n * abandon the animation mid-flight: its completion callback is suppressed\n * and any pending frame or fallback timer is disarmed.\n *\n * @remarks Cancelling performs no DOM write, so an owner may call it from\n * teardown without caring whether the animated element's handle has already\n * been released. It is idempotent, and a no-op once the animation has\n * completed.\n *\n * @category Core\n */\n export interface CancelHandle {\n /** Abandons the animation. Idempotent; a no-op after completion. */\n cancel(): void;\n }\n\n /** Shared handle for the paths that finish before there is anything to cancel. */\n const NOOP_HANDLE: CancelHandle = { cancel: (): void => {} };\n\n /**\n * Drives a JS-side numeric tween via `requestAnimationFrame`, interpolating\n * every key in `from` toward the matching key in `to` over `durationMs`.\n *\n * @param config - Start/end values, duration, easing, step / complete hooks.\n * @returns A handle whose `cancel()` aborts the rAF loop.\n *\n * @remarks Honours `prefers-reduced-motion: reduce` by invoking\n * `onStep(to)` and `onComplete` synchronously, then returning a no-op\n * handle. Each frame's interpolated values are passed as a freshly\n * allocated object — callers may keep the reference. Use this for\n * numeric tweens that have to route through the framework's typed setters\n * (window-rect transitions, scroll-to, animated layout swaps); for raw\n * CSS-property transitions use {@link Animation.play} instead.\n */\n export function tween<T extends { [K in keyof T]: number }>(config: TweenConfig<T>): CancelHandle {\n if (isReducedMotion()) {\n config.onStep(config.to);\n config.onComplete?.();\n\n return NOOP_HANDLE;\n }\n\n const startTime = performance.now();\n const ease = config.easing ?? defaultTweenEase;\n\n let frameId: number | null = null;\n\n const step = (now: number): void => {\n const elapsed = now - startTime;\n const t = Math.min(1, elapsed / config.durationMs);\n const k = ease(t);\n\n const values = {} as T;\n for (const key in config.from) {\n const f = config.from[key];\n const target = config.to[key];\n values[key] = (f + (target - f) * k) as T[Extract<keyof T, string>];\n }\n\n config.onStep(values);\n\n if (t < 1) {\n frameId = DOM.sink.requestAnimationFrame(step);\n\n return;\n }\n\n frameId = null;\n config.onComplete?.();\n };\n\n frameId = DOM.sink.requestAnimationFrame(step);\n\n return {\n cancel: (): void => {\n if (frameId === null) {\n return;\n }\n\n DOM.sink.cancelAnimationFrame(frameId);\n frameId = null;\n },\n };\n }\n\n const defaultTweenEase = (t: number): number => {\n const u = 1 - t;\n\n return 1 - u * u * u;\n };\n\n /** Default duration of the cross-fade between spinner and materialized content. */\n const MATERIALIZE_FADE_DURATION_MS = 160;\n\n /**\n * Configuration for {@link Animation.materialize}.\n *\n * @category Core\n */\n export interface MaterializeConfig {\n /**\n * Container that hosts the spinner during the yield and receives the\n * factory's output once it has been built. The spinner is added as a\n * child of this component and removed once the cross-fade completes.\n */\n host: Component;\n\n /**\n * Component factory. Runs after the two-rAF yield so the spinner has\n * reached the screen before the main-thread build cost is incurred.\n * May be asynchronous: a factory returning a promise is awaited after\n * that yield, and the spinner stays mounted for the whole wait.\n */\n factory: ComponentFactory;\n\n /**\n * Caller-constructed spinner component (typically a `ProgressSpinner`\n * wrapped in a centring layout). Passed in rather than created here\n * so `~/core/Animation` stays free of `~/component/display` imports\n * — and so call sites can customise the spinner shape per surface.\n */\n spinnerComponent: Component;\n\n /**\n * Duration of the opacity transition that fades the built component\n * in over the spinner.\n *\n * @defaultValue 160\n */\n fadeMs?: number;\n\n /**\n * Fires after the materialized component's fade-in completes (or\n * immediately when reduced-motion is set). Receives the component\n * the factory returned so the caller can wire up post-attach state.\n */\n onReady?: (component: Component) => void;\n\n /**\n * Called when an async factory rejects, after the spinner has been\n * removed. Not called when {@link MaterializeConfig.isStale} reports the\n * caller has lost interest. The caller owns everything else about the\n * failure — this helper ships no error UI.\n */\n onError?: (error: unknown) => void;\n\n /**\n * Polled once per settled factory — just before the built component is\n * attached, and just before a rejection is reported. Returning `true`\n * means the caller no longer wants the result: the spinner is removed,\n * nothing is attached, and neither {@link MaterializeConfig.onReady} nor\n * {@link MaterializeConfig.onError} fires.\n */\n isStale?: () => boolean;\n }\n\n /**\n * Mounts the spinner, yields two animation frames so it actually reaches\n * the screen, runs the factory, then cross-fades the built component in\n * over the spinner. Both `Tab.materializeAsync` and `Window.show` (when\n * a content factory is set) drive activation through this helper so the\n * yield-and-fade lifecycle lives in one place.\n *\n * @param config - Host, factory, spinner, and fade options.\n *\n * @remarks Two `requestAnimationFrame` callbacks are needed because a\n * single rAF still races layout in Firefox — the same two-rAF dance\n * `play()` performs for entrance transitions. The spinner is removed in\n * the fade's `onComplete` so the brief overlap reads as \"spinner fades\n * into content\" without an extra animation.\n *\n * @returns A handle whose `cancel()` abandons the materialization: the\n * factory's eventual result is discarded and the cross-fade, if it has\n * started, is cancelled too.\n */\n export function materialize(config: MaterializeConfig): CancelHandle {\n const host = config.host;\n const factory = config.factory;\n const spinner = config.spinnerComponent;\n const fadeMs = config.fadeMs ?? MATERIALIZE_FADE_DURATION_MS;\n\n let cancelled = false;\n let fade: CancelHandle | null = null;\n\n const dropSpinner = (): void => {\n host.removeComponent(spinner);\n spinner.dispose();\n host.scheduleLayout();\n };\n\n const attach = (component: Component): void => {\n // The owner was torn down while the factory was in flight. Its own\n // teardown already disposed the spinner (a registered child), so\n // touch nothing on the host — just discard the built component.\n if (cancelled) {\n component.dispose();\n\n return;\n }\n\n // The caller lost interest during the yield or the await (e.g. its\n // tab was closed): drop the spinner and discard the built component.\n if (config.isStale?.()) {\n dropSpinner();\n component.dispose();\n\n return;\n }\n\n host.addComponent(component);\n\n const el = component.getElement(true)!;\n host.scheduleLayout();\n\n fade = play(el, {\n from: { opacity: \"0\" },\n to: { opacity: \"1\" },\n durationMs: fadeMs,\n properties: [\"opacity\"],\n onComplete: () => {\n dropSpinner();\n config.onReady?.(component);\n },\n });\n };\n\n const fail = (error: unknown): void => {\n // The owner was torn down mid-flight; its teardown already disposed\n // the spinner, and there is nobody left to report the failure to.\n if (cancelled) {\n return;\n }\n\n dropSpinner();\n\n // The caller lost interest during the await (its tab was closed):\n // there is nothing left to tear down and nobody left to report to.\n if (config.isStale?.()) {\n return;\n }\n\n config.onError?.(error);\n };\n\n host.addComponent(spinner);\n host.scheduleLayout();\n\n DOM.sink.requestAnimationFrame(() => {\n DOM.sink.requestAnimationFrame(() => {\n if (cancelled) {\n return;\n }\n\n const result = factory();\n\n // Only a thenable takes the async branch, so a synchronous\n // factory still attaches inside this same frame with no\n // microtask tick — its timing is unchanged.\n if (result instanceof Promise) {\n result.then(attach, fail);\n } else {\n attach(result);\n }\n });\n });\n\n return {\n cancel: (): void => {\n cancelled = true;\n fade?.cancel();\n },\n };\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Animation } from \"~/core/Animation.js\";\nimport { DOM } from \"~/core/DOM.js\";\n\n/**\n * The axis a {@link SmoothScroller} position applies to.\n *\n * @category Core\n */\nexport type ScrollAxis = \"x\" | \"y\";\n\n/**\n * Claims a wheel event for the calling scroll container, returning whether the\n * claim succeeded (the event was not already claimed).\n *\n * @param e - The wheel event to claim.\n *\n * @returns `true` if this caller claimed the event; `false` if an inner\n * container already did.\n *\n * @remarks The framework dispatches subtree events descendant-first, so the\n * innermost scroll container under the pointer sees the wheel first. Claiming\n * it here lets ancestor containers — reached later in the same dispatch — skip a\n * wheel an inner container already handled, restoring the native \"inner element\n * traps the wheel\" behaviour that a single `preventDefault` used to provide\n * before more than one container processed wheel in JS.\n *\n * @category Core\n */\nexport function consumeWheel(e: WheelEvent): boolean {\n const marked = e as WheelEvent & { _tsScrollConsumed?: boolean };\n\n if (marked._tsScrollConsumed) {\n return false;\n }\n\n marked._tsScrollConsumed = true;\n\n return true;\n}\n\n/**\n * Per-axis read/write/clamp seam that a {@link SmoothScroller} drives. One\n * implementation writes a `translate3d` transform (the virtual-list scroller);\n * another writes `element.scrollLeft` / `element.scrollTop` (native overflow).\n *\n * @category Core\n */\nexport interface SmoothScrollTarget {\n\n /**\n * Reads the current live position for `axis`, in pixels.\n *\n * @param axis - The axis to read.\n *\n * @returns The current position in pixels.\n */\n read(axis: ScrollAxis): number;\n\n /**\n * Writes `value` px to `axis` immediately, without easing.\n *\n * @param axis - The axis to write.\n * @param value - The new position in pixels.\n */\n write(axis: ScrollAxis, value: number): void;\n\n /**\n * Clamps a requested position for `axis` to its valid `[0, max]` range.\n *\n * @param axis - The axis to clamp.\n * @param value - The requested position in pixels.\n *\n * @returns The clamped position in pixels.\n */\n clamp(axis: ScrollAxis, value: number): number;\n}\n\n// One 60 fps frame in milliseconds — the normaliser that makes the exponential\n// approach frame-rate independent. Matches the touch-fling loop in\n// VirtualScroller so both share one decay-constant family.\nconst FRAME_MS = 16.667;\n\n// Fraction of the remaining distance left UN-covered after one 60 fps frame.\n// 0.75 ⇒ each frame closes ~25% of the gap, settling a typical wheel notch in\n// a few frames — empirically tuned against the touch loop's feel; higher feels\n// laggy, lower feels like an instant jump.\nconst SMOOTH_FACTOR = 0.75;\n\n// Sub-pixel distance at which the loop snaps to the target and stops. Below one\n// half-pixel there is no visible difference, so continuing to animate only\n// wastes frames.\nconst STOP_PX = 0.5;\n\n/**\n * Re-targetable RAF easing loop that glides a current position toward an\n * accumulated target via frame-rate-independent exponential decay. Built for\n * smooth mouse-wheel scrolling: each wheel tick extends a moving target while\n * the loop is mid-flight, and the loop converges on wherever the target\n * currently is — no tween restart, no easing discontinuity across rapid ticks.\n *\n * Drives any {@link SmoothScrollTarget}, so the same loop serves both the\n * transform-based virtual scroller and native-overflow elements. Programmatic\n * jumps must call {@link reset} so a lingering ease can't snap the user back.\n *\n * @remarks Distinct from the velocity-fling momentum loop in the virtual\n * scroller's touch handler: this one chases a target position; that one decays\n * a release velocity. They intentionally stay separate models.\n *\n * @category Core\n */\nexport class SmoothScroller {\n\n private _target : SmoothScrollTarget;\n private _curX : number = 0;\n private _curY : number = 0;\n private _tgtX : number = 0;\n private _tgtY : number = 0;\n private _lastT : number = 0;\n private _raf : number | null = null;\n\n /**\n * Constructs a SmoothScroller bound to a target seam.\n *\n * @param target - The read/write/clamp seam this scroller drives.\n */\n constructor(target: SmoothScrollTarget) {\n this._target = target;\n }\n\n /**\n * Accumulates a wheel delta into the target and eases toward it. Under\n * `prefers-reduced-motion: reduce` the clamped target is written\n * immediately and no loop starts.\n *\n * @param deltaX - Horizontal delta in pixels to add to the target.\n * @param deltaY - Vertical delta in pixels to add to the target.\n *\n * @remarks On the first tick of a fresh gesture (loop idle) the current and\n * target seeds are re-read from the live position, so an ease started after\n * the position moved out-of-band (scrollbar drag, keyboard, a programmatic\n * jump, a layout clamp) begins from where the content actually is rather\n * than from stale internal state.\n */\n scrollBy(deltaX: number, deltaY: number): void {\n if (this._raf === null) {\n this._curX = this._tgtX = this._target.read(\"x\");\n this._curY = this._tgtY = this._target.read(\"y\");\n }\n\n this._tgtX = this._target.clamp(\"x\", this._tgtX + deltaX);\n this._tgtY = this._target.clamp(\"y\", this._tgtY + deltaY);\n\n if (Animation.isReducedMotion()) {\n this._target.write(\"x\", this._tgtX);\n this._target.write(\"y\", this._tgtY);\n\n return;\n }\n\n if (this._raf === null) {\n this._lastT = performance.now();\n this._raf = DOM.sink.requestAnimationFrame(now => this.step(now));\n }\n }\n\n /**\n * Aborts the in-flight loop and re-seeds the internal current/target from a\n * fresh read of the live position. Call from every programmatic jump so the\n * jump sticks and a lingering ease can't pull the position back.\n */\n reset(): void {\n if (this._raf !== null) {\n DOM.sink.cancelAnimationFrame(this._raf);\n this._raf = null;\n }\n\n this._curX = this._tgtX = this._target.read(\"x\");\n this._curY = this._tgtY = this._target.read(\"y\");\n }\n\n /**\n * Reports whether the easing loop is currently running.\n *\n * @returns `true` while the RAF loop is active.\n */\n isAnimating(): boolean {\n return this._raf !== null;\n }\n\n /**\n * One easing frame: advances each axis a frame-normalised fraction toward\n * its target, snaps and ends when both are within {@link STOP_PX}.\n *\n * @param now - The `requestAnimationFrame` timestamp in milliseconds.\n */\n private step(now: number): void {\n const frame = now - this._lastT;\n this._lastT = now;\n\n // Fraction of the remaining gap to close this frame. Normalising the\n // exponent by FRAME_MS makes the glide cover the same proportion of\n // distance per unit time regardless of the actual frame interval.\n const k = 1 - Math.pow(SMOOTH_FACTOR, frame / FRAME_MS);\n\n this._curX += (this._tgtX - this._curX) * k;\n this._curY += (this._tgtY - this._curY) * k;\n\n const settledX = Math.abs(this._tgtX - this._curX) < STOP_PX;\n const settledY = Math.abs(this._tgtY - this._curY) < STOP_PX;\n\n if (settledX) {\n this._curX = this._tgtX;\n }\n if (settledY) {\n this._curY = this._tgtY;\n }\n\n this._target.write(\"x\", this._curX);\n this._target.write(\"y\", this._curY);\n\n if (settledX && settledY) {\n this._raf = null;\n\n return;\n }\n\n this._raf = DOM.sink.requestAnimationFrame(next => this.step(next));\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\n/**\n * Class type intersected with a call signature whose arguments and return type\n * mirror its constructor. Allows callers to invoke a wrapped class without the\n * `new` keyword while preserving `new`, `instanceof`, and `extends` semantics.\n *\n * @category Util\n */\nexport type Callable<T extends new (...args: any[]) => any> =\n T & ((...args: ConstructorParameters<T>) => InstanceType<T>);\n\n/**\n * Wraps a class so it can be invoked without `new`. The returned value still\n * works with `new`, with `instanceof`, and as the right-hand side of `extends`.\n *\n * @param Cls - The class constructor to wrap.\n *\n * @returns A Proxy that forwards both `[[Call]]` and `[[Construct]]` to `Cls`.\n *\n * @remarks `instance.constructor` continues to point at the original class\n * because the Proxy forwards `[[Construct]]` via `Reflect.construct`, and\n * `instanceof` resolves through the default\n * `Function.prototype[Symbol.hasInstance]` which walks the prototype chain.\n *\n * @example\n * ```typescript\n * class Foo { constructor(public x: number) {} }\n * const FooCallable = callable(Foo);\n * const a = FooCallable(1); // no `new`\n * const b = new FooCallable(2); // still works\n * a instanceof FooCallable; // true\n * ```\n *\n * @category Util\n */\nexport function callable<T extends new (...args: any[]) => any>(Cls: T): Callable<T> {\n return new Proxy(Cls, {\n apply: (target, _thisArg, args) => Reflect.construct(target, args),\n }) as Callable<T>;\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\n/**\n * Controls how a component fills its allocated cell within a layout.\n *\n * @category Layouts\n */\nexport enum FillType {\n NONE = \"none\",\n BOTH = \"both\",\n HORIZONTAL = \"horizontal\",\n VERTICAL = \"vertical\"\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\n/**\n * Specifies the anchor point within a cell used to position a component\n * when it does not fill its allocated space.\n *\n * @category Layouts\n */\nexport enum AnchorType {\n NORTHWEST,\n SOUTHWEST,\n WEST,\n NORTHEAST,\n SOUTHEAST,\n EAST,\n NORTH,\n SOUTH,\n CENTER\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { FillType } from \"~/layout/FillType.js\";\nimport { AnchorType } from \"~/layout/AnchorType.js\";\nimport { LayoutConstraints } from \"~/layout/LayoutConstraints\";\nimport { Size, UNBOUNDED } from \"~/primitive/Size.js\";\nimport { Component } from \"~/core/Component.js\";\nimport type { ComponentFactory } from \"~/core/Component.js\";\nimport { BaseObject } from \"~/core/BaseObject.js\";\n\n/**\n * Construction-time options shared by every {@link LayoutManager}.\n *\n * @remarks Reserved for future cross-manager fields. Concrete layout managers\n * extend this interface (e.g. {@link HBoxOptions}) with their own fields and\n * dispatch them through `applyOptions`.\n *\n * @category Layouts\n */\nexport interface LayoutManagerOptions {\n}\n\n/**\n * A child's resolved bounds, paired with the component they belong to —\n * the hand-off between a placement loop's calc phase ({@link LayoutManager.resolveBounds})\n * and its commit phase ({@link LayoutManager.commitPlacements}).\n */\nexport interface ResolvedPlacement {\n component: Component;\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Abstract base class for all layout managers.\n * A layout manager is attached to a container component and is responsible for\n * computing size hints and positioning child components within the container.\n *\n * @category Layouts\n */\nexport abstract class LayoutManager extends BaseObject {\n\n private _container: Component | null = null;\n private _layoutConstraints: Map<string, LayoutConstraints> = new Map<string, LayoutConstraints>();\n private _defaultPreferredSize: Size | null = null;\n private _defaultMinSize: Size = { width: 0, height: 0 };\n private _defaultMaxSize: Size = { width: UNBOUNDED, height: UNBOUNDED };\n // Per-axis \"let children overflow the host\" flag. Driven by the host\n // `Panel.setAutoScroll`; consumed by each manager's `doLayout` to decide\n // whether the working size can grow past the host's `innerSize` when the\n // children's combined minSize exceeds it. Default `false` on both axes\n // matches today's clamp-and-clip behaviour.\n private _overflowing: { x: boolean; y: boolean } = { x: false, y: false };\n\n constructor() {\n super();\n }\n\n /**\n * Applies a {@link LayoutManagerOptions} bag to this layout manager.\n *\n * @param _options - The options bag carrying the values to apply.\n *\n * @remarks The base implementation is a no-op because [`LayoutManagerOptions`](/api/layout/interfaces/LayoutManagerOptions)\n * has no fields of its own. Subclasses override this method to dispatch\n * their additional fields (spacing, gap, stretching, etc.).\n */\n protected applyOptions(_options: LayoutManagerOptions): void {\n }\n\n /**\n * Offers an unbuilt child to this manager, before the container builds it.\n *\n * Returning `true` claims the factory: the container adds nothing, and this\n * manager owns when — and whether — the factory runs. The base\n * implementation declines, so the container builds the child immediately and\n * adds it like any other.\n *\n * @param _factory - The unbuilt child on offer.\n * @param _constraints - Optional. The layout constraints the caller passed.\n *\n * @returns `true` to claim the factory, `false` to let the container build it.\n */\n addDeferredComponent(_factory: ComponentFactory, _constraints?: LayoutConstraints): boolean {\n return false;\n }\n\n /**\n * Associates this layout manager with a container component.\n *\n * @param container - The container component to attach to.\n */\n attach(container: Component) : this {\n this._container = container;\n\n return this;\n }\n\n /**\n * Dissociates this layout manager from its container.\n */\n detach() : this {\n this._container = null;\n\n return this;\n }\n\n /**\n * Returns the container component this layout manager is attached to.\n *\n * @returns The attached container, or `null` if not attached.\n */\n getContainer(): Component | null {\n return this._container;\n }\n\n /**\n * Returns the default preferred size.\n * Subclasses may override this method to compute the preferred size dynamically.\n *\n * @returns The preferred size, or `null` if not set.\n */\n getPreferredSize(): Size | null {\n return this._defaultPreferredSize;\n }\n\n /**\n * Returns the minimum size this layout can produce.\n *\n * @returns The minimum size.\n */\n getMinSize(): Size | null {\n return this._defaultMinSize;\n }\n\n /**\n * Returns the maximum size this layout can produce.\n *\n * @returns The maximum size.\n */\n getMaxSize(): Size | null {\n return this._defaultMaxSize;\n }\n\n /**\n * Returns whether this layout manager is in \"let children overflow\" mode\n * on the X axis. Default `false`.\n *\n * @returns `true` when horizontal overflow is enabled.\n */\n protected isOverflowingX(): boolean {\n return this._overflowing.x;\n }\n\n /**\n * Returns whether this layout manager is in \"let children overflow\" mode\n * on the Y axis. Default `false`.\n *\n * @returns `true` when vertical overflow is enabled.\n */\n protected isOverflowingY(): boolean {\n return this._overflowing.y;\n }\n\n /**\n * Computes the children's combined minSize along this manager's geometry.\n * The default is a no-op (`{ width: 0, height: 0 }`); managers that support\n * host-driven overflow scrolling override it to report the min the working\n * size must inflate to. Consumed by {@link LayoutManager.inflateForOverflow}.\n *\n * @returns The total min-size of the children.\n */\n protected computeTotalMinSize(): Size {\n return { width: 0, height: 0 };\n }\n\n /**\n * Inflates a working container size to the children's combined minSize on\n * whichever axes the host has marked as overflowing (`Panel.setAutoScroll`),\n * so trailing children land past the host's inner rect and its CSS\n * `overflow: auto` produces the scrollbar. Axes the host has not opted into\n * keep the original extent and clamp as before.\n *\n * @param containerSize - The host's real inner size.\n * @returns The working size to lay out against — the original when neither\n * axis overflows, otherwise inflated to the min total on the active axes.\n */\n protected inflateForOverflow(containerSize: Size): Size {\n if (!this.isOverflowingX() && !this.isOverflowingY()) {\n return containerSize;\n }\n\n const totalMin = this.computeTotalMinSize();\n\n return {\n width: this.isOverflowingX() ? Math.max(containerSize.width, totalMin.width) : containerSize.width,\n height: this.isOverflowingY() ? Math.max(containerSize.height, totalMin.height) : containerSize.height,\n };\n }\n\n /**\n * Sets the per-axis overflow flags. Called by the host `Panel` whenever\n * its `autoScroll` mode changes; subclasses read the resulting state via\n * `isOverflowingX` / `isOverflowingY` in their `doLayout`. Triggers a\n * re-layout when either flag changes.\n *\n * Public so the host `Panel` can drive it; subclasses still consume the\n * resulting state via the `protected` `isOverflowingX` / `isOverflowingY`\n * getters.\n *\n * @param x - True to let children overflow horizontally.\n * @param y - True to let children overflow vertically.\n */\n public setOverflowing(x: boolean, y: boolean): void {\n if (this._overflowing.x === x && this._overflowing.y === y) {\n return;\n }\n\n this._overflowing = { x, y };\n\n this.getContainer()?.doLayout();\n }\n\n /**\n * Reserves the trailing inset in the scrollable area for a scroll-enabled\n * host. Box layouts place children from the leading inset but the trailing\n * inset is otherwise only implicit (the empty space `getInnerSize` leaves),\n * so once children overflow, the host's native scroll extent — driven by\n * the children's boxes — ends flush at the last child and the trailing\n * inset is lost. This wraps the children in a content frame (see\n * [`Component.setContentFrame`](/api/core/classes/Component#setcontentframe))\n * sized to their committed far edge plus the trailing inset, so the host\n * scrolls the frame and both insets are reserved symmetrically.\n *\n * The frame is **persistent** for any scroll-enabled host (either overflow\n * axis active): installed once and only resized thereafter, sized to the\n * children's extent so it shrinks below the viewport — showing no scrollbar\n * — when they fit, and grows past it when they don't. It is never removed\n * as the overflow state toggles. That matters because installing or\n * clearing the frame re-parents the whole child subtree, and moving DOM\n * nodes cancels any in-flight CSS transition on a descendant (e.g. an\n * Accordion section animating open/closed would snap the instant a\n * scrollbar appeared or disappeared). Non-scroll hosts clear any frame —\n * the trailing-inset reserve is only meaningful when scrolling.\n *\n * Call AFTER the placement loop: it reads each child's committed\n * `getX`/`getY`/`getWidth`/`getHeight`, plus `getTranslateX`/`getTranslateY`\n * to account for a child `commitBounds` placed via its size-stable\n * position fast path — such a child's `getX`/`getY` still report the\n * pre-move value, so the translate offset must be added back in to get\n * its true committed extent. The frame parks at the padding-box origin,\n * so the children's coordinates are identical whether they sit in the\n * frame or directly under the element — wrapping them after placement\n * does not move them visually.\n *\n * @returns This layout manager, for method chaining.\n */\n protected reserveContentFrame(): this {\n const container = this.getContainer();\n if (!container) {\n return this;\n }\n\n const inner = container.getInnerSize();\n const components = container.getLaidOutComponents();\n\n if (!inner || components.length === 0) {\n container.clearContentFrame();\n\n return this;\n }\n\n const insets = container.getContentInsets();\n\n let farRight = insets.getLeft();\n let farBottom = insets.getTop();\n\n for (const component of components) {\n farRight = Math.max(farRight, component.getX() + component.getTranslateX() + component.getWidth());\n farBottom = Math.max(farBottom, component.getY() + component.getTranslateY() + component.getHeight());\n }\n\n // Keep a *persistent* content frame for any scroll-enabled host, sized\n // to the children's committed extent — created once on the first pass,\n // only resized afterwards. Sizing it to the content extent (rather than\n // only when that extent exceeds `inner`) means it shrinks below the\n // viewport when the children fit, so no scrollbar shows, yet the frame\n // is never installed/removed as the overflow state toggles. That\n // matters because installing or clearing the frame re-parents the whole\n // child subtree, and moving DOM nodes cancels any in-flight CSS\n // transition on a descendant — e.g. an Accordion section animating\n // open/closed snaps the instant a scrollbar appears or disappears.\n // Non-scroll hosts clear the frame as before (the trailing-inset reserve\n // is only meaningful when scrolling).\n if (this.isOverflowingX() || this.isOverflowingY()) {\n container.setContentFrame(farRight + insets.getRight(), farBottom + insets.getBottom());\n } else {\n container.clearContentFrame();\n }\n\n return this;\n }\n\n /**\n * Positions and sizes a child component within the given bounds,\n * respecting fill and anchor constraints.\n *\n * @param component - The child component to position.\n * @param x - Left edge of the cell in the container's coordinate space.\n * @param y - Top edge of the cell in the container's coordinate space.\n * @param maxWidth - Available width for the component.\n * @param maxHeight - Available height for the component.\n * @param fill - Optional. Fill strategy overriding the component's own constraints.\n * @param anchor - Optional. Anchor point overriding the component's own constraints.\n *\n * @remarks The method checks the component's stored [`LayoutConstraints`](/api/layout/classes/LayoutConstraints) first;\n * the `fill` and `anchor` parameters serve as fallbacks. After positioning,\n * `doLayout` is called on the child so nested layouts are updated in a single pass.\n */\n placeComponent(component: Component, x: number, y: number, maxWidth: number, maxHeight: number, fill?: FillType | null, anchor?: AnchorType | null): void {\n const r = this.resolveBounds(component, x, y, maxWidth, maxHeight, fill, anchor);\n\n this.commitBounds(component, r.x, r.y, r.width, r.height);\n }\n\n /**\n * Pure resolution of a child's effective bounds within a cell.\n *\n * Reads the child's stored [`LayoutConstraints`](/api/layout/classes/LayoutConstraints), applies the\n * {@link FillType} / {@link AnchorType} policy, clamps the result to\n * `maxWidth`/`maxHeight` and the child's own min/max sizes, and computes\n * the anchor displacement that centres or pins the child within the cell.\n *\n * Does NOT mutate the [`Component`](/api/core/classes/Component). Layout managers that need to\n * place a child outside the cell (e.g. to let it overflow a scroll panel)\n * can skip this method and call {@link LayoutManager.commitBounds} directly.\n *\n * @param component - The child whose bounds are being resolved.\n * @param x - Left edge of the cell in the container's coordinate space.\n * @param y - Top edge of the cell in the container's coordinate space.\n * @param maxWidth - Available width for the child.\n * @param maxHeight - Available height for the child.\n * @param fill - Optional. Fill strategy overriding the child's own constraints.\n * @param anchor - Optional. Anchor point overriding the child's own constraints.\n * @returns The resolved `{ x, y, width, height }` ready for {@link LayoutManager.commitBounds}.\n */\n protected resolveBounds(component: Component, x: number, y: number, maxWidth: number, maxHeight: number, fill?: FillType | null, anchor?: AnchorType | null): { x: number; y: number; width: number; height: number } {\n const layoutConstraints = this.getLayoutConstraints(component);\n const preferredSize = component.getPreferredSize();\n const size = component.getSize();\n const maxSize = component.getMaxSize();\n const minSize = component.getMinSize();\n let width: number;\n let height: number;\n\n fill = ((layoutConstraints ? layoutConstraints.fill : undefined) || fill || FillType.NONE) as FillType;\n // `??`, not `||`: AnchorType.NORTHWEST is 0, which `||` would discard as\n // falsy and silently fall through to CENTER. Only null/undefined should\n // mean \"unset\" here.\n anchor = ((layoutConstraints ? layoutConstraints.anchor : undefined) ?? anchor ?? AnchorType.CENTER) as AnchorType;\n\n if (fill == FillType.BOTH) {\n width = maxWidth;\n height = maxHeight;\n } else {\n if (fill == FillType.HORIZONTAL) {\n width = maxWidth;\n } else {\n let sw = 0;\n\n if (preferredSize) {\n sw = preferredSize.width;\n } else if (size) {\n sw = size.width;\n }\n\n if (sw > maxWidth) {\n sw = maxWidth;\n } else if (sw < 0) {\n sw = 0;\n }\n\n if (maxSize && sw > maxSize.width) {\n sw = maxSize.width;\n } else if (minSize && sw < minSize.width) {\n sw = minSize.width;\n }\n\n width = sw;\n }\n\n if (fill == FillType.VERTICAL) {\n height = maxHeight;\n } else {\n let sh = 0;\n\n if (preferredSize) {\n sh = preferredSize.height;\n } else if (size) {\n sh = size.height;\n }\n\n if (sh > maxHeight) {\n sh = maxHeight;\n } else if (sh < 0) {\n sh = 0;\n }\n\n if (maxSize && sh > maxSize.height) {\n sh = maxSize.height;\n } else if (minSize && sh < minSize.height) {\n sh = minSize.height;\n }\n\n height = sh;\n }\n }\n\n if (width < maxWidth) {\n let displace;\n switch (anchor) {\n case AnchorType.NORTHWEST:\n case AnchorType.SOUTHWEST:\n case AnchorType.WEST:\n displace = 0;\n break;\n case AnchorType.NORTHEAST:\n case AnchorType.SOUTHEAST:\n case AnchorType.EAST:\n displace = maxWidth - width;\n break;\n case AnchorType.NORTH:\n case AnchorType.SOUTH:\n case AnchorType.CENTER:\n default:\n displace = (maxWidth - width) / 2;\n }\n\n x += displace;\n }\n\n if (height < maxHeight) {\n let displace;\n switch (anchor) {\n case AnchorType.NORTHWEST:\n case AnchorType.NORTHEAST:\n case AnchorType.NORTH:\n displace = 0;\n break;\n case AnchorType.SOUTHWEST:\n case AnchorType.SOUTHEAST:\n case AnchorType.SOUTH:\n displace = maxHeight - height;\n break;\n case AnchorType.WEST:\n case AnchorType.EAST:\n case AnchorType.CENTER:\n default:\n displace = (maxHeight - height) / 2;\n }\n\n y += displace;\n }\n\n return { x, y, width, height };\n }\n\n /**\n * Commits a resolved rect to the child, then recurses into the child's\n * `doLayout`, all wrapped in `setAutoCommitStyle(false/true)` so the\n * positional writes flush as a single DOM update.\n *\n * When the child's `[width, height]` are unchanged from its last commit\n * and it has no CSS transition configured, the position move is written\n * as a compositor-only `transform` (via `setTranslate`) instead of\n * `left`/`top` — cheaper for a size-stable move, measured ~24% faster\n * than a `left`/`top` write on a live microbenchmark. `getX()`/`getY()`\n * keep reporting the pre-move value while this fast path is active; the\n * true visual position is `getX() + getTranslateX()` / `getY() +\n * getTranslateY()`. Any component with a configured transition, or any\n * commit that also changes size, takes the slow path instead — writing\n * real `left`/`top`/`width`/`height` and folding any leftover translate\n * back to `(0, 0)` in the same batch.\n *\n * A commit whose target `(x, y)` already equals the child's true visual\n * position (size unchanged too) also takes the slow path, even though\n * nothing needs to move — a redundant re-layout pass (e.g. a parent\n * `doLayout` cascading through children whose bounds didn't actually\n * change) must not promote `will-change: transform` on a component that\n * isn't moving, and must release any leftover promotion from an earlier\n * move that has since settled. Every setter this branch calls with an\n * already-current value is a cheap no-op, so this costs nothing beyond\n * the comparison itself.\n *\n * Used by {@link LayoutManager.placeComponent} (via {@link LayoutManager.resolveBounds}) and by\n * layout managers that need to bypass the cell clamp — e.g. [`Absolute`](/api/layout/classes/Absolute)\n * places children at their own preferred size, even when that exceeds the\n * container, so a host `Panel` with `autoScroll: \"auto\"` can scroll the\n * overflow.\n *\n * @param component - The child to update.\n * @param x - Final left position in the container's coordinate space.\n * @param y - Final top position in the container's coordinate space.\n * @param width - Final width.\n * @param height - Final height.\n */\n protected commitBounds(component: Component, x: number, y: number, width: number, height: number): void {\n component.setAutoCommitStyle(false);\n\n const sizeUnchanged = component.getWidth() === width && component.getHeight() === height;\n const positionUnchanged = x === component.getX() + component.getTranslateX() && y === component.getY() + component.getTranslateY();\n const transition = component.getTransition();\n const canFastPath = sizeUnchanged && !positionUnchanged && (transition === null || transition === \"none\");\n\n if (canFastPath) {\n component.setWillChange(\"transform\");\n component.setTranslate(x - component.getX(), y - component.getY());\n } else {\n component.setX(x);\n component.setY(y);\n component.setTranslate(0, 0);\n component.setWillChange(null);\n }\n\n component.setWidth(width);\n component.setHeight(height);\n\n component.doLayout();\n\n component.setAutoCommitStyle(true);\n }\n\n /**\n * Commits a whole placement loop's resolved rects in order, one child at a\n * time. Pairs with a calc phase that pushed each child's {@link LayoutManager.resolveBounds}\n * result into a `ResolvedPlacement[]` instead of committing it immediately.\n *\n * @param placements - The resolved rects to commit, in placement order.\n */\n protected commitPlacements(placements: ResolvedPlacement[]): void {\n for (const placement of placements) {\n this.commitBounds(placement.component, placement.x, placement.y, placement.width, placement.height);\n }\n }\n\n /**\n * Stores layout constraints for a component, or removes them if `constraints` is `undefined`.\n *\n * @param component - The component whose constraints are being set.\n * @param constraints - Optional. The constraints to store; omit to delete existing constraints.\n *\n * @returns The stored constraints, or `undefined` if they were deleted.\n */\n setLayoutConstraints(component: Component, constraints?: LayoutConstraints): LayoutConstraints | undefined {\n if (!constraints) {\n return this.delLayoutConstraints(component);\n } else {\n this._layoutConstraints.set(component.getId(), constraints);\n return constraints;\n }\n }\n\n /**\n * Removes and returns the stored layout constraints for a component.\n *\n * @param component - The component whose constraints should be removed.\n *\n * @returns The removed constraints, or `undefined` if none were stored.\n */\n delLayoutConstraints(component: Component) {\n let constraints = this._layoutConstraints.get(component.getId());\n\n this._layoutConstraints.delete(component.getId());\n\n return constraints;\n }\n\n /**\n * Returns the stored layout constraints for a component.\n *\n * @param component - The component to look up.\n *\n * @returns The stored constraints, or `undefined` if none are set.\n */\n getLayoutConstraints(component: Component) {\n return this._layoutConstraints.get(component.getId());\n }\n\n /**\n * Computes the y-offset, relative to the row top, for a null-baseline child of the given height.\n *\n * @param height - The child's height.\n * @param rowAscent - The text baseline of the row (max baseline among text-bearing children).\n * @param rowDescent - The text descent of the row (max `height − baseline` among text-bearing children).\n * @returns The y-offset to use when placing the child.\n *\n * @remarks Vertically centres the child within the row's text line height.\n * Tall replaced elements (e.g. an inline [`ProgressSpinner`](/api/component/display/classes/ProgressSpinner)) clamp to 0 and\n * extend below the text. Components that want to align with the surrounding\n * text baseline should expose a real baseline via `getBaseline()` rather\n * than relying on this null-child placement.\n */\n protected nullChildY(height: number, rowAscent: number, rowDescent: number): number {\n const textLineHeight = rowAscent + rowDescent;\n\n return Math.max(0, (textLineHeight - height) / 2);\n }\n\n /**\n * Computes the row's text-line metrics from a set of child heights and baselines.\n *\n * @param heights - The per-child heights to consider.\n * @param baselines - The per-child baselines (`null` means \"no baseline of my own —\n * graphical or replaced element\").\n * @returns `{ rowAscent, rowDescent }`. `rowAscent` is the max baseline among\n * text-bearing children (`null` if none); `rowDescent` is the max\n * `height − baseline` among the same set.\n */\n protected computeRowMetrics(heights: number[], baselines: Array<number | null>): { rowAscent: number | null, rowDescent: number } {\n let rowAscent: number | null = null;\n let rowDescent = 0;\n\n for (let i = 0; i < baselines.length; i += 1) {\n const b = baselines[i];\n\n if (b !== null) {\n if (rowAscent === null || b > rowAscent) {\n rowAscent = b;\n }\n\n const below = heights[i] - b;\n if (below > rowDescent) {\n rowDescent = below;\n }\n }\n }\n\n return { rowAscent, rowDescent };\n }\n\n /**\n * Computes the row height required to fit all children when their baselines are aligned.\n *\n * @param heights - The per-child heights to consider.\n * @param baselines - The per-child baselines (`null` means \"no baseline of my own\").\n * @returns The row height, in pixels.\n *\n * @remarks Falls back to `max(heights)` when no child reports a real baseline.\n * Otherwise the row must fit text-bearing children's `rowAscent + rowDescent`\n * AND each null-baseline child's actual placed extent (`y + height`).\n */\n protected computeRowHeight(heights: number[], baselines: Array<number | null>): number {\n const { rowAscent, rowDescent } = this.computeRowMetrics(heights, baselines);\n\n if (rowAscent === null) {\n let maxAnyHeight = 0;\n\n for (const h of heights) {\n if (h > maxAnyHeight) {\n maxAnyHeight = h;\n }\n }\n\n return maxAnyHeight;\n }\n\n let result = rowAscent + rowDescent;\n\n for (let i = 0; i < heights.length; i += 1) {\n if (baselines[i] === null) {\n const y = this.nullChildY(heights[i], rowAscent, rowDescent);\n const extent = y + heights[i];\n\n if (extent > result) {\n result = extent;\n }\n }\n }\n\n return result;\n }\n\n /**\n * Returns the container's own baseline, measured from its content-top\n * (inside insets/border/padding), or `null` when this layout exposes no\n * meaningful baseline.\n *\n * @returns The inner baseline offset in pixels, or `null`.\n *\n * @remarks The default is `null` (no baseline). Baseline-aware layouts\n * override this so a container placed in a parent's baseline row aligns by\n * its content's baseline instead of auto-centring. `Component.getBaseline`\n * wraps the returned value with the container's chrome.\n */\n getContentBaseline(): number | null {\n return null;\n }\n\n abstract doLayout(): void;\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { LayoutManager, LayoutManagerOptions, ResolvedPlacement } from \"~/layout/LayoutManager.js\";\nimport { callable } from \"~/core/Callable.js\";\n\n/**\n * Construction-time options for {@link Absolute}.\n *\n * @category Layouts\n */\nexport interface AbsoluteOptions extends LayoutManagerOptions {\n}\n\n/**\n * A layout manager that places each child at its preferred (or current) size\n * at the position the application has already set on the child. No clamp is\n * applied — a child larger than the container is committed at its full size,\n * letting a host `Panel` with `autoScroll: \"auto\"` scroll the overflow.\n *\n * @category Layouts\n */\nclass Absolute extends LayoutManager {\n\n constructor(options?: AbsoluteOptions) {\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 * Places each child at the size declared by `preferredSize` (falling back\n * to `size`, then `0`) at the position declared by the child's own\n * `getX` / `getY`. Bypasses {@link LayoutManager.placeComponent} so the\n * cell clamp does not shrink an oversized child.\n */\n doLayout(): void {\n const container = this.getContainer();\n\n if (!container) {\n return;\n }\n\n const components = container.getLaidOutComponents();\n const placements: ResolvedPlacement[] = [];\n\n for (const component of components) {\n const preferredSize = component.getPreferredSize();\n const size = component.getSize();\n\n const width = preferredSize?.width ?? size?.width ?? 0;\n const height = preferredSize?.height ?? size?.height ?? 0;\n\n const x = component.getX();\n const y = component.getY();\n\n placements.push({ component, x, y, width, height });\n }\n\n this.commitPlacements(placements);\n }\n}\n\nconst AbsoluteCallable = callable(Absolute);\ntype AbsoluteCallable = Absolute;\nexport {\n Absolute as _Absolute,\n AbsoluteCallable as Absolute\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\n// Framework-internal state for the one-shot startup font gate. The coalesced\n// layout queue in `Component.ts` holds its very first flush while this gate is\n// held, so no text is committed at a size measured against the browser's\n// fallback font; `Theme.ts` arms the gate when it starts the web-font load and\n// releases it when the font set reports that load settled. Not exported from\n// `core/index.ts`: this module exists purely to let `Theme.ts`, `Component.ts`\n// and the virtualised row views share this bookkeeping without importing each\n// other, mirroring\n// `core/PendingTransitions.ts`, `core/ClassStyleRules.ts` and\n// `core/ComponentDefaults.ts`.\n\nimport { DOM } from \"~/core/DOM.js\";\nimport type { TimerId } from \"~/core/DOM.js\";\n\n/**\n * How long the gate may hold the first flush once the main thread is free.\n *\n * @remarks Measured against real activation cost: the framework's two inline\n * font subsets activate in ~1.4 ms and ~0 ms on an idle main thread, so this is\n * over an order of magnitude of headroom. It cannot usefully be much longer —\n * on the failure path this is exactly how long an unlaid-out tree stays on\n * screen, and 50 ms keeps that to roughly three frames.\n */\nexport const FIRST_LAYOUT_HOLD_MS = 50;\n\n/** Whether the layout queue must still defer its first flush. */\nlet _held: boolean = false;\n\n/** The bounded release deadline, once a held frame has started it. */\nlet _deadline: TimerId | null = null;\n\n/**\n * Arms the gate, so the layout queue defers its first flush.\n *\n * @remarks Called once per process, from the theme manager's font set-up, and\n * only when an asynchronous font load actually started — arming with nothing\n * able to release it would leave the gate shut until its deadline.\n */\nexport function holdFirstLayout(): void {\n _held = true;\n}\n\n/**\n * Whether the layout queue must defer its flush and retry on a later frame.\n *\n * @returns `true` while the gate is held.\n */\nexport function isFirstLayoutHeld(): boolean {\n return _held;\n}\n\n/**\n * Starts the bounded release deadline. A no-op once the deadline is running.\n *\n * @remarks Called by the first frame that finds the gate held, not by\n * {@link holdFirstLayout}. An animation frame cannot run until the synchronous\n * startup work has finished, so the first held frame is by construction the\n * first moment the main thread is free — anchoring the deadline there makes it\n * a budget of *available* time. A timer started at arming would instead expire\n * unnoticed during startup and fire the moment the thread yields, racing the\n * font activation it exists to outlast.\n */\nexport function startFirstLayoutDeadline(): void {\n if (_deadline !== null) {\n return;\n }\n\n _deadline = DOM.sink.setTimeout(releaseFirstLayout, FIRST_LAYOUT_HOLD_MS);\n}\n\n/**\n * Opens the gate and cancels any pending deadline. Idempotent.\n *\n * @remarks Does not kick a flush: while the queue is non-empty a retry frame is\n * always already pending, and when the queue is empty there is nothing to\n * flush.\n */\nexport function releaseFirstLayout(): void {\n _held = false;\n\n if (_deadline !== null) {\n DOM.sink.clearTimeout(_deadline);\n _deadline = null;\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\n/**\n * Runtime type-checking and assertion utilities.\n * Each type provides `is*`, `if*`, and `require*` variants.\n */\nexport namespace Type {\n /**\n * Throws if obj is null or undefined, using the provided message as the error text.\n *\n * @param obj - The value to test for nullability.\n * @param msg - The error message to use if the check fails. Defaults to \"Argument cannot be null.\"\n */\n export function requireNonNull(obj: object, msg: string) {\n if (obj !== null && obj !== undefined) {\n return;\n }\n\n if (!msg) {\n msg = \"Argument cannot be null.\";\n }\n\n throw new Error(msg)\n }\n\n /**\n * Returns true if value is a Boolean object or primitive.\n *\n * @param value - The value to test.\n *\n * @returns `true` if `value` is a boolean, `false` otherwise.\n */\n export function isBoolean(value: object) {\n return toString.call(value) === '[object Boolean]';\n }\n\n /**\n * Throws if value is not a boolean.\n *\n * @param value - The value to test.\n * @param msg - The error message to use if the check fails. Defaults to \"Argument must be a boolean.\"\n */\n export function requireBoolean(value: object, msg: string) {\n if (Type.isBoolean(value)) {\n return;\n }\n\n if (!msg) {\n msg = \"Argument must be a boolean.\";\n }\n\n throw new Error(msg);\n }\n\n /**\n * Returns true if value is an array.\n *\n * @param value - The value to test.\n *\n * @returns `true` if `value` is an array, `false` otherwise.\n */\n export function isArray(value: object) {\n return value && Array.isArray(value);\n }\n\n /**\n * Throws if value is not an array.\n *\n * @param value - The value to test.\n * @param msg - The error message to use if the check fails. Defaults to \"Argument must be an array.\"\n */\n export function requireArray(value: object, msg: string) {\n if (Type.isArray(value)) {\n return;\n }\n\n if (!msg) {\n msg = \"Argument must be an array.\";\n }\n\n throw new Error(msg);\n }\n\n /**\n * Returns true if value is a non-array, non-null Object instance.\n *\n * @param value - The value to test.\n *\n * @returns `true` if `value` is a plain object (not an array and not null), `false` otherwise.\n */\n export function isObject(value: object) {\n return value && !Type.isArray(value) && value instanceof Object;\n }\n\n /**\n * Throws if value is not an object.\n *\n * @param value - The value to test.\n * @param msg - The error message to use if the check fails. Defaults to \"Argument must be an object.\"\n */\n export function requireObject(value: object, msg: string) {\n if (Type.isObject(value)) {\n return;\n }\n\n if (!msg) {\n msg = \"Argument must be an object.\";\n }\n\n throw new Error(msg);\n }\n\n /**\n * Returns true if value is a function.\n *\n * @param value - The value to test.\n *\n * @returns `true` if `value` is a function, `false` otherwise.\n */\n export function isFunction(value: object) {\n return value && {}.toString.call(value) === '[object Function]';\n }\n\n /**\n * Throws if value is not a function.\n *\n * @param value - The value to test.\n * @param msg - The error message to use if the check fails. Defaults to \"Argument must be a function.\"\n */\n export function requireFunction(value: object, msg: string) {\n if (Type.isFunction(value)) {\n return;\n }\n\n if (!msg) {\n msg = \"Argument must be a function.\";\n }\n\n throw new Error(msg);\n }\n\n /**\n * Returns true if value is a string; also accepts null when allowNull is true.\n *\n * @param value - The value to test.\n * @param allowNull - Optional. When `true`, a `null` or `undefined` value is also considered valid.\n *\n * @returns `true` if `value` is a string (or null/undefined when `allowNull` is set), `false` otherwise.\n */\n export function isString(value: object, allowNull: boolean = false) {\n if (allowNull && value == null) {\n return true;\n }\n\n return typeof value === \"string\";\n }\n\n /**\n * Throws if value is not a string (or not null when allowNull is true).\n *\n * @param value - The value to test.\n * @param allowNull - Optional. When `true`, null/undefined passes the check.\n * @param msg - The error message to use if the check fails. Defaults to \"Argument must be a string.\"\n */\n export function requireString(value: object, allowNull: boolean = false, msg: string, ) {\n if (Type.isString(value, allowNull)) {\n return;\n }\n\n if (!msg) {\n msg = \"Argument must be a string.\";\n }\n\n throw new Error(msg);\n }\n\n /**\n * Returns true if value is a floating-point number (not an integer).\n *\n * @param value - The value to test.\n *\n * @returns `true` if `value` is a finite non-integer number, `false` otherwise.\n */\n export function isFloat(value: object) {\n if (!Type.isNumber(value)) {\n return false;\n }\n\n let n: number = (value as Number).valueOf();\n return n === +n && n !== (n | 0);\n }\n\n /**\n * Returns true if value is a whole-number integer; also accepts null/0 when allowNull is true.\n *\n * @param value - The value to test.\n * @param allowNull - Optional. When `true`, a falsy value (null, 0, undefined) is also considered valid.\n *\n * @returns `true` if `value` is an integer (or falsy when `allowNull` is set), `false` otherwise.\n */\n export function isInteger(value: object, allowNull: boolean = false) {\n if (allowNull && !value) {\n return true;\n }\n\n if (!Type.isNumber(value)) {\n return false;\n }\n\n let n: number = (value as Number).valueOf();\n return n === +n && n === (n | 0);\n }\n\n /**\n * Throws if value is not an integer (or not null when allowNull is true).\n *\n * @param value - The value to test.\n * @param allowNull - Optional. When `true`, null/undefined/0 passes the check.\n * @param msg - The error message to use if the check fails. Defaults to \"Argument must be an integer.\"\n */\n export function requireInteger(value: object, allowNull: boolean = false, msg: string) {\n if (Type.isInteger(value, allowNull)) {\n return;\n }\n\n if (!msg) {\n msg = \"Argument must be an integer.\";\n }\n\n throw new Error(msg);\n }\n\n /**\n * Returns true if value is of type number (including NaN and Infinity).\n *\n * @param value - The value to test.\n *\n * @returns `true` if `typeof value === 'number'`, `false` otherwise.\n */\n export function isNumber(value: object) {\n return typeof value == 'number';\n }\n\n /**\n * Throws if value is not a number.\n *\n * @param value - The value to test.\n * @param msg - The error message to use if the check fails. Defaults to \"Argument must be a number.\"\n */\n export function requireNumber(value: object, msg: string) {\n if (Type.isNumber(value)) {\n return;\n }\n\n if (!msg) {\n msg = \"Argument must be a number.\";\n }\n\n throw new Error(msg);\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\n\n/**\n * Valid WAI-ARIA landmark and widget roles used by this framework.\n *\n * @category Core\n */\nexport type AriaRole =\n | 'grid'\n | 'treegrid'\n | 'rowgroup'\n | 'row'\n | 'gridcell'\n | 'columnheader'\n | 'tablist'\n | 'tab'\n | 'tabpanel'\n | 'tree'\n | 'treeitem'\n | 'group'\n | 'button'\n | 'link'\n | 'region'\n | 'combobox'\n | 'listbox'\n | 'option'\n | 'menubar'\n | 'menuitem'\n | 'menu'\n | 'toolbar'\n | 'separator'\n | 'spinbutton'\n | 'progressbar'\n | 'status'\n | 'alert'\n | 'dialog'\n | 'checkbox'\n | 'radio'\n | 'slider'\n | 'switch'\n | 'list'\n | 'listitem';\n\n/**\n * Valid values for the `aria-sort` attribute.\n *\n * @category Core\n */\nexport type AriaSort = 'none' | 'ascending' | 'descending';\n\n/**\n * Valid values for the `aria-live` attribute, which controls how assistive\n * technology announces dynamic content updates.\n *\n * @category Core\n */\nexport type AriaLive = 'off' | 'polite' | 'assertive';\n\n/**\n * Valid values for the `aria-orientation` attribute.\n *\n * @category Core\n */\nexport type AriaOrientation = 'horizontal' | 'vertical';\n\n/**\n * Typed accessor for WAI-ARIA attributes on a {@link Component}.\n *\n * Obtained via {@link Component.getAria}. Each attribute has its own getter/setter\n * with a proper TypeScript type so that attribute names and values cannot be\n * misspelled. State is stored internally and each setter writes through the\n * component's attribute channel, which replays the value onto a freshly\n * created element.\n *\n * @example\n * ```typescript\n * this.getAria().setRole(\"grid\");\n * row.getAria().setSelected(true);\n * header.getAria().setSort(\"ascending\");\n * ```\n *\n * @category Core\n */\nexport class Aria {\n\n private _component: Component;\n private _role: AriaRole | null = null;\n private _tabIndex: number | null = null;\n private _attributes: Map<string, string> = new Map();\n\n /**\n * @param component - The component this helper manages ARIA state for.\n */\n constructor(component: Component) {\n this._component = component;\n }\n\n /**\n * Sets the WAI-ARIA `role` attribute.\n *\n * @param role - The ARIA role to assign.\n */\n setRole(role: AriaRole): this {\n this._role = role;\n this._component.applyAriaAttribute(\"role\", role);\n\n return this;\n }\n\n /**\n * Returns the current ARIA role, or null if none has been set.\n *\n * @returns The role, or null.\n */\n getRole(): AriaRole | null {\n return this._role;\n }\n\n /**\n * Removes the `role` attribute, clearing any role previously set with\n * {@link setRole}. The null companion to `setRole`, which accepts no null —\n * needed when a component drops an affordance it had claimed.\n *\n * @returns This Aria helper, for method chaining.\n */\n clearRole(): this {\n this._role = null;\n this._component.applyAriaAttribute(\"role\", null);\n\n return this;\n }\n\n /**\n * Sets the `tabindex` attribute, controlling keyboard focus order.\n *\n * @param value - 0 = focusable in document order, -1 = focusable by script only, null removes the attribute.\n */\n setTabIndex(value: number | null): this {\n this._tabIndex = value;\n this._component.applyAriaAttribute(\"tabindex\", value !== null ? String(value) : null);\n\n return this;\n }\n\n /**\n * Returns the current tabindex, or null if not set.\n *\n * @returns The tabindex value, or null.\n */\n getTabIndex(): number | null {\n return this._tabIndex;\n }\n\n /**\n * Sets `aria-live`, controlling how assistive technology announces updates\n * to a region's contents.\n *\n * @param value - `'off'`, `'polite'`, or `'assertive'`.\n */\n setLive(value: AriaLive): this {\n this.setAttribute(\"live\", value);\n\n return this;\n }\n\n /**\n * Returns the current `aria-live` value, or null if not set.\n *\n * @returns The live-region politeness, or null.\n */\n getLive(): AriaLive | null {\n return (this._attributes.get(\"live\") as AriaLive) ?? null;\n }\n\n /**\n * Sets `aria-sort` on a column header.\n *\n * @param value - The sort direction.\n */\n setSort(value: AriaSort): this {\n this.setAttribute(\"sort\", value);\n\n return this;\n }\n\n /**\n * Returns the current `aria-sort` value, or null if not set.\n *\n * @returns The sort direction, or null.\n */\n getSort(): AriaSort | null {\n return (this._attributes.get(\"sort\") as AriaSort) ?? null;\n }\n\n /**\n * Sets `aria-multiselectable`, indicating that the widget supports multiple\n * selection.\n *\n * @param value - Whether multiple items can be selected.\n */\n setMultiselectable(value: boolean): this {\n this.setAttribute(\"multiselectable\", String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-multiselectable` value, or null if not set.\n *\n * @returns The multiselectable state, or null.\n */\n getMultiselectable(): boolean | null {\n const v = this._attributes.get(\"multiselectable\");\n\n return v !== undefined ? v === \"true\" : null;\n }\n\n /**\n * Sets `aria-selected`.\n *\n * @param value - Whether the element is selected.\n */\n setSelected(value: boolean): this {\n this.setAttribute(\"selected\", String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-selected` value, or null if not set.\n *\n * @returns The selected state, or null.\n */\n getSelected(): boolean | null {\n const v = this._attributes.get(\"selected\");\n\n return v !== undefined ? v === \"true\" : null;\n }\n\n /**\n * Sets `aria-hidden`.\n *\n * @param value - Whether the element is hidden from assistive technology.\n */\n setHidden(value: boolean): this {\n this.setAttribute(\"hidden\", String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-hidden` value, or null if not set.\n *\n * @returns The hidden state, or null.\n */\n getHidden(): boolean | null {\n const v = this._attributes.get(\"hidden\");\n\n return v !== undefined ? v === \"true\" : null;\n }\n\n /**\n * Sets `aria-rowindex` (1-based position of a row within a grid).\n *\n * @param value - The 1-based row index.\n */\n setRowIndex(value: number): this {\n this.setAttribute(\"rowindex\", String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-rowindex`, or null if not set.\n *\n * @returns The row index, or null.\n */\n getRowIndex(): number | null {\n const v = this._attributes.get(\"rowindex\");\n\n return v !== undefined ? Number(v) : null;\n }\n\n /**\n * Sets `aria-rowcount` (total number of rows in a grid, used for virtual scrolling).\n *\n * @param value - The total row count.\n */\n setRowCount(value: number): this {\n this.setAttribute(\"rowcount\", String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-rowcount`, or null if not set.\n *\n * @returns The row count, or null.\n */\n getRowCount(): number | null {\n const v = this._attributes.get(\"rowcount\");\n\n return v !== undefined ? Number(v) : null;\n }\n\n /**\n * Sets `aria-expanded`.\n *\n * @param value - `true` if the element is expanded, `false` if collapsed, `null` to remove the attribute (e.g. for leaf nodes).\n */\n setExpanded(value: boolean | null): this {\n if (value !== null) {\n this.setAttribute(\"expanded\", String(value));\n } else {\n this._attributes.delete(\"expanded\");\n this._component.applyAriaAttribute(\"aria-expanded\", null);\n }\n\n return this;\n }\n\n /**\n * Returns the current `aria-expanded` value, or null if not set.\n *\n * @returns The expanded state, or null.\n */\n getExpanded(): boolean | null {\n const v = this._attributes.get(\"expanded\");\n\n return v !== undefined ? v === \"true\" : null;\n }\n\n /**\n * Sets `aria-level` (1-based nesting depth of a tree item).\n *\n * @param value - The 1-based level number.\n */\n setLevel(value: number): this {\n this.setAttribute(\"level\", String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-level`, or null if not set.\n *\n * @returns The level number, or null.\n */\n getLevel(): number | null {\n const v = this._attributes.get(\"level\");\n\n return v !== undefined ? Number(v) : null;\n }\n\n /**\n * Sets `aria-labelledby` to the ID of the element that labels this one.\n *\n * @param id - The ID of the labelling element.\n */\n setLabelledBy(id: string): this {\n this.setAttribute(\"labelledby\", id);\n\n return this;\n }\n\n /**\n * Returns the current `aria-labelledby` value, or null if not set.\n *\n * @returns The labelling element ID, or null.\n */\n getLabelledBy(): string | null {\n return this._attributes.get(\"labelledby\") ?? null;\n }\n\n /**\n * Sets `aria-controls` to the ID of the element this one controls.\n *\n * @param id - The ID of the controlled element.\n */\n setControls(id: string): this {\n this.setAttribute(\"controls\", id);\n\n return this;\n }\n\n /**\n * Returns the current `aria-controls` value, or null if not set.\n *\n * @returns The controlled element ID, or null.\n */\n getControls(): string | null {\n return this._attributes.get(\"controls\") ?? null;\n }\n\n /**\n * Sets `aria-autocomplete`, describing the kind of inline completion the field offers.\n *\n * @param value - `'none'`, `'list'`, `'inline'`, or `'both'`.\n */\n setAutoComplete(value: 'none' | 'list' | 'inline' | 'both'): this {\n this.setAttribute(\"autocomplete\", value);\n\n return this;\n }\n\n /**\n * Returns the current `aria-autocomplete` value, or null if not set.\n *\n * @returns The autocomplete hint, or null.\n */\n getAutoComplete(): string | null {\n return this._attributes.get(\"autocomplete\") ?? null;\n }\n\n /**\n * Sets `aria-activedescendant` to the ID of the currently active descendant element.\n *\n * Pass an empty string to clear the attribute.\n *\n * @param id - The element ID of the active descendant, or `\"\"` to clear.\n */\n setActiveDescendant(id: string): this {\n if (id === \"\") {\n this._attributes.delete(\"activedescendant\");\n this._component.applyAriaAttribute(\"aria-activedescendant\", null);\n } else {\n this.setAttribute(\"activedescendant\", id);\n }\n\n return this;\n }\n\n /**\n * Returns the current `aria-activedescendant` value, or null if not set.\n *\n * @returns The active descendant ID, or null.\n */\n getActiveDescendant(): string | null {\n return this._attributes.get(\"activedescendant\") ?? null;\n }\n\n /**\n * Sets `aria-colindex` (1-based column position of a cell within a grid row).\n *\n * @param value - The 1-based column index.\n */\n setColIndex(value: number): this {\n this.setAttribute(\"colindex\", String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-colindex`, or null if not set.\n *\n * @returns The column index, or null.\n */\n getColIndex(): number | null {\n const v = this._attributes.get(\"colindex\");\n\n return v !== undefined ? Number(v) : null;\n }\n\n /**\n * Sets `aria-colcount` (total number of columns in a grid).\n *\n * @param value - The total column count.\n */\n setColCount(value: number): this {\n this.setAttribute(\"colcount\", String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-colcount`, or null if not set.\n *\n * @returns The column count, or null.\n */\n getColCount(): number | null {\n const v = this._attributes.get(\"colcount\");\n\n return v !== undefined ? Number(v) : null;\n }\n\n /**\n * Sets `aria-setsize` (total number of items in the set this element belongs to).\n *\n * @param value - The total set size.\n */\n setSetSize(value: number): this {\n this.setAttribute(\"setsize\", String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-setsize`, or null if not set.\n *\n * @returns The set size, or null.\n */\n getSetSize(): number | null {\n const v = this._attributes.get(\"setsize\");\n\n return v !== undefined ? Number(v) : null;\n }\n\n /**\n * Sets `aria-posinset` (1-based position of this element within its set).\n *\n * @param value - The 1-based position.\n */\n setPosInSet(value: number): this {\n this.setAttribute(\"posinset\", String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-posinset`, or null if not set.\n *\n * @returns The position in set, or null.\n */\n getPosInSet(): number | null {\n const v = this._attributes.get(\"posinset\");\n\n return v !== undefined ? Number(v) : null;\n }\n\n /**\n * Sets `aria-pressed` on a toggle button.\n *\n * @param value - Whether the button is currently pressed.\n */\n setPressed(value: boolean): this {\n this.setAttribute(\"pressed\", String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-pressed` value, or null if not set.\n *\n * @returns The pressed state, or null.\n */\n getPressed(): boolean | null {\n const v = this._attributes.get(\"pressed\");\n\n return v !== undefined ? v === \"true\" : null;\n }\n\n /**\n * Sets `aria-haspopup`, indicating the element opens a popup.\n *\n * @param value - The popup type, or `false` to indicate no popup.\n */\n setHasPopup(value: 'false' | 'true' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog'): this {\n this.setAttribute(\"haspopup\", value);\n\n return this;\n }\n\n /**\n * Returns the current `aria-haspopup` value, or null if not set.\n *\n * @returns The popup type string, or null.\n */\n getHasPopup(): string | null {\n return this._attributes.get(\"haspopup\") ?? null;\n }\n\n /**\n * Sets `aria-disabled`.\n *\n * @param value - Whether the element is disabled.\n */\n setDisabled(value: boolean): this {\n this.setAttribute(\"disabled\", String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-disabled` value, or null if not set.\n *\n * @returns The disabled state, or null.\n */\n getDisabled(): boolean | null {\n const v = this._attributes.get(\"disabled\");\n\n return v !== undefined ? v === \"true\" : null;\n }\n\n /**\n * Sets `aria-valuenow` (the current value of a range or spinbutton widget).\n *\n * @param value - The current numeric value.\n */\n setValueNow(value: number): this {\n this.setAttribute(\"valuenow\", String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-valuenow`, or null if not set.\n *\n * @returns The current value, or null.\n */\n getValueNow(): number | null {\n const v = this._attributes.get(\"valuenow\");\n\n return v !== undefined ? Number(v) : null;\n }\n\n /**\n * Sets or clears `aria-valuemin` (the minimum value of a range or spinbutton widget).\n *\n * @param value - The minimum numeric value, or `null` to remove the attribute.\n */\n setValueMin(value: number | null): this {\n if (value === null) {\n this._attributes.delete(\"valuemin\");\n this._component.applyAriaAttribute(\"aria-valuemin\", null);\n } else {\n this.setAttribute(\"valuemin\", String(value));\n }\n\n return this;\n }\n\n /**\n * Returns the current `aria-valuemin`, or null if not set.\n *\n * @returns The minimum value, or null.\n */\n getValueMin(): number | null {\n const v = this._attributes.get(\"valuemin\");\n\n return v !== undefined ? Number(v) : null;\n }\n\n /**\n * Sets or clears `aria-valuemax` (the maximum value of a range or spinbutton widget).\n *\n * @param value - The maximum numeric value, or `null` to remove the attribute.\n */\n setValueMax(value: number | null): this {\n if (value === null) {\n this._attributes.delete(\"valuemax\");\n this._component.applyAriaAttribute(\"aria-valuemax\", null);\n } else {\n this.setAttribute(\"valuemax\", String(value));\n }\n\n return this;\n }\n\n /**\n * Returns the current `aria-valuemax`, or null if not set.\n *\n * @returns The maximum value, or null.\n */\n getValueMax(): number | null {\n const v = this._attributes.get(\"valuemax\");\n\n return v !== undefined ? Number(v) : null;\n }\n\n /**\n * Sets `aria-checked`. Accepts `\"mixed\"` for the indeterminate / tri-state\n * checkbox surface and a boolean for ordinary on/off widgets such as\n * `Checkbox` / `RadioButton` / `Toggle`.\n *\n * @param value - `true`, `false`, or `\"mixed\"`.\n */\n setChecked(value: boolean | \"mixed\"): this {\n this.setAttribute(\"checked\", typeof value === \"string\" ? value : String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-checked` value, or null if not set.\n *\n * @returns The checked state (boolean), `\"mixed\"`, or null.\n */\n getChecked(): boolean | \"mixed\" | null {\n const v = this._attributes.get(\"checked\");\n\n if (v === undefined) {\n return null;\n }\n\n if (v === \"mixed\") {\n return \"mixed\";\n }\n\n return v === \"true\";\n }\n\n /**\n * Sets `aria-readonly`.\n *\n * @param value - Whether the element is read-only.\n */\n setReadOnly(value: boolean): this {\n this.setAttribute(\"readonly\", String(value));\n\n return this;\n }\n\n /**\n * Returns the current `aria-readonly` value, or null if not set.\n *\n * @returns The read-only state, or null.\n */\n getReadOnly(): boolean | null {\n const v = this._attributes.get(\"readonly\");\n\n return v !== undefined ? v === \"true\" : null;\n }\n\n /**\n * Sets `aria-label`, providing an accessible label for the element.\n *\n * @param value - The label text.\n */\n setLabel(value: string): this {\n this.setAttribute(\"label\", value);\n\n return this;\n }\n\n /**\n * Returns the current `aria-label` value, or null if not set.\n *\n * @returns The label text, or null.\n */\n getLabel(): string | null {\n return this._attributes.get(\"label\") ?? null;\n }\n\n /**\n * Removes `aria-label`, clearing any accessible label previously set with\n * {@link setLabel}. The null companion to `setLabel` — distinct from\n * `setLabel(\"\")`, which would leave an empty `aria-label` that can suppress\n * the element's accessible name rather than fall back to its content.\n *\n * @returns This Aria helper, for method chaining.\n */\n clearLabel(): this {\n this._attributes.delete(\"label\");\n this._component.applyAriaAttribute(\"aria-label\", null);\n\n return this;\n }\n\n /**\n * Sets `aria-orientation`, indicating whether a composite widget (toolbar,\n * separator, scrollbar, slider, tablist) is laid out horizontally or\n * vertically.\n *\n * @param value - `'horizontal'` or `'vertical'`.\n */\n setOrientation(value: AriaOrientation): this {\n this.setAttribute(\"orientation\", value);\n\n return this;\n }\n\n /**\n * Returns the current `aria-orientation` value, or null if not set.\n *\n * @returns The orientation, or null.\n */\n getOrientation(): AriaOrientation | null {\n return (this._attributes.get(\"orientation\") as AriaOrientation) ?? null;\n }\n\n /**\n * Stores an aria-* attribute value locally and pushes it to the DOM if the element exists.\n *\n * @param name - The attribute name without the `aria-` prefix.\n * @param value - The string value to set.\n */\n private setAttribute(name: string, value: string): void {\n this._attributes.set(name, value);\n this._component.applyAriaAttribute(\"aria-\" + name, value);\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { DOM } from \"~/core/DOM.js\";\nimport type { Handle } from \"~/core/DOM.js\";\n\n/**\n * Deferred-write buffer for HTML element attributes. Sibling to\n * {@link InlineStyle}, but retains its full state rather than emptying it at\n * materialisation: {@link ElementAttributes.attach} writes the whole retained\n * set onto the element it binds to, so a component that releases its element\n * and renders a new one gets every attribute back from a single `attach`\n * call, the same rebuild property `InlineStyle` gets from `Component`'s\n * private fields via `applyStyle`.\n *\n * @category Core\n */\nclass ElementAttributes {\n private _handle: Handle | null = null;\n private _state: Map<string, string> = new Map();\n private _pending: Set<string> = new Set();\n\n /**\n * Writes a single attribute. Flushes immediately when the buffer is\n * attached to an element; otherwise queues the entry for the next attach\n * or flush.\n *\n * @param key - The attribute name.\n * @param value - The attribute value.\n */\n set(key: string, value: string): void {\n this._state.set(key, value);\n\n if (this._handle) {\n DOM.sink.apply(this._handle, { setAttr: { [key]: value } });\n } else {\n this._pending.add(key);\n }\n }\n\n /**\n * Removes a single attribute. Flushes immediately when the buffer is\n * attached to an element; otherwise queues the removal for the next\n * attach or flush.\n *\n * @param key - The attribute name to remove.\n */\n remove(key: string): void {\n this._state.delete(key);\n\n if (this._handle) {\n DOM.sink.apply(this._handle, { removeAttr: [key] });\n } else {\n this._pending.add(key);\n }\n }\n\n /**\n * Writes a single attribute into the retained state and the pending set\n * without flushing, even when the buffer is already attached. Callers\n * that own their own batching gate (e.g. `autoCommitAttributes = false`)\n * use this to accumulate writes that {@link ElementAttributes.flush} will\n * drain later.\n *\n * @param key - The attribute name.\n * @param value - The attribute value.\n */\n queue(key: string, value: string): void {\n this._state.set(key, value);\n this._pending.add(key);\n }\n\n /**\n * Queues a removal without flushing, even when the buffer is already\n * attached.\n *\n * @param key - The attribute name to remove.\n */\n queueRemove(key: string): void {\n this._state.delete(key);\n this._pending.add(key);\n }\n\n /**\n * Reads an attribute back from the retained state, not the DOM.\n *\n * @param key - The attribute name.\n *\n * @returns The stored value, or undefined if not set.\n */\n get(key: string): string | undefined {\n return this._state.get(key);\n }\n\n /**\n * Drains the pending set onto the attached element as one batched patch.\n * No-op when the buffer is not yet attached, or when nothing is pending.\n */\n flush(): void {\n if (!this._handle || this._pending.size === 0) return;\n\n const setAttr: Record<string, string> = {};\n const removeAttr: string[] = [];\n\n for (const key of this._pending) {\n const value = this._state.get(key);\n\n if (value === undefined) removeAttr.push(key);\n else setAttr[key] = value;\n }\n\n this._pending.clear();\n DOM.sink.apply(this._handle, { removeAttr, setAttr });\n }\n\n /**\n * Binds this buffer to a live element handle and writes the whole\n * retained state onto it as one patch, discarding any stale pending\n * entries from a previous attachment.\n *\n * @param handle - The element handle to attach to.\n */\n attach(handle: Handle): void {\n this._handle = handle;\n this._pending.clear();\n\n if (this._state.size === 0) return;\n\n const setAttr: Record<string, string> = {};\n\n for (const [key, value] of this._state) setAttr[key] = value;\n\n DOM.sink.apply(handle, { setAttr });\n }\n\n /**\n * Returns whether this buffer is attached to a live element handle.\n */\n isMaterialized(): boolean {\n return this._handle !== null;\n }\n}\n\nexport { ElementAttributes };\n","export default \"data:font/woff2;base64,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\"","export default \"data:font/woff2;base64,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\"","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport type { DeepPartial, Theme } from '~/core/Theme.js';\n\n/**\n * Scheme-invariant structural tokens shared by every built-in theme — sizes,\n * paddings, radii, gaps, thicknesses, durations, and font sizes. Not a usable\n * theme on its own (palette tokens are absent); wrap it with {@link defineTheme}.\n *\n * The one structural-shaped token that is *not* invariant carries its base\n * value here — `tab.underBorderFullWidth: true` (Modern and Dark override to\n * `false`, so only Classic keeps the base value).\n *\n * @category Theme\n */\nexport const BaseTheme: DeepPartial<Theme> = {\n font: {\n family : \"'Manrope Variable', sans-serif\",\n size : '14px',\n linePadding: '2px',\n },\n markdown: {\n // Looser than the UI's line box (font-size + 2px linePadding, ≈1.14 at\n // the 14px base) — prose read continuously wants more leading than a\n // scanned single-line control.\n lineHeight: '1.8',\n // Typographic convention places comfortable line length at roughly\n // 45-75 characters; 80ch runs a bit past that range, chosen after\n // trying a few values. A `ch` value tracks the reading measure rather\n // than pinning a pixel width.\n maxMeasure: '80ch',\n },\n border: {\n radius: '4px',\n },\n button: {\n padding: '0',\n font : { size: '-2px' }, // base − 2 → 12px at the 14px base\n description: {\n fontSize: '-3px', // base − 3 → 11px at the 14px base\n weight : 'normal',\n },\n },\n form: {\n toggle : { width: '36px', height: '20px' },\n slider : { thumbSize: '16px', trackThickness: '4px' },\n checkbox: { size: '16px', radius: '3px' },\n radio : { size: '16px' },\n },\n tab: {\n underBorderFullWidth: true,\n indicator: { thickness: '2px' },\n },\n window: {\n minDockWidth: '200px',\n },\n header: {\n font : { size: '-2px' }, // base − 2 → 12px at the 14px base\n },\n table: {\n header: {\n font : { size: '-1px' }, // base − 1 → 13px at the 14px base\n glyph: { gap: '4px' },\n },\n cell: {\n height : '22px',\n padding: 2,\n },\n resizeHandle: {\n width : '5px',\n cursor: 'ew-resize',\n },\n sortBadge: {\n fontSize: '-4px', // base − 4 → 10px at the 14px base\n },\n filterClauseBadge: {\n fontSize: '-4px', // base − 4 → 10px at the 14px base\n },\n },\n menuBar: {\n panel: { minWidth: '160px' },\n },\n statusBar: {\n height : '22px',\n padding: '6px',\n },\n toolBar: {\n padding: '4px',\n gap : '4px',\n },\n popover: {\n radius : '6px',\n padding : '12px',\n arrowSize: '8px',\n },\n dropdown: {\n fade: { duration: '120ms', translate: '4px' },\n },\n spinner: {\n buttonWidth: '18px',\n },\n progressBar: {\n track: { borderRadius: '4px' },\n },\n progressSpinner: {\n size: '32px',\n },\n glyph: {\n spinDuration : '2000ms',\n pulseDuration: '1000ms',\n beatDuration : '1000ms',\n },\n drag: {\n ghost: { opacity: '0.85' },\n },\n // Scheme-invariant charting structure: stroke widths and the point-marker\n // radius carry no palette meaning, so they live here rather than in each\n // per-scheme theme. `2px` line / `1px` axis mirror the framework's other\n // hairline rules (e.g. the tab under-border); `3px` points read at the\n // plan's modest data densities without crowding.\n chart: {\n lineWidth : '2px',\n axisWidth : '1px',\n pointRadius: '3px',\n },\n // The scale knob plus the font-coupled ratios. Each ratio is `current-px ÷\n // base`, chosen so `round(base × ratio)` recovers the exact historic px at\n // the default base of 14 (so nothing shifts until the base is raised), then\n // grows proportionally as the base scales. titleGlyph is `{ scale: 1 }` —\n // one base size — so the window/tab title glyph tracks the base 1:1.\n scale: {\n base : 14,\n titleGlyph : { scale: 1 }, // 14 ÷ 14 — title glyph == base\n tabClose : { scale: 16 / 14 }, // close-button box was 16px\n tabCloseGlyph : { scale: 8 / 14 }, // close-glyph ink was 8px\n tabButtonInset: { scale: 4 / 14 }, // tab-button inset was 4px\n },\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { BaseTheme } from '~/core/themes/BaseTheme.js';\nimport { defineTheme } from '~/core/Theme.js';\nimport type { Theme } from '~/core/Theme.js';\n\n/**\n * Opt-in modern light theme: flat, gradient-free buttons and a flatter table\n * header surface that read as a cleaner, more contemporary light scheme.\n *\n * Authored as `defineTheme(BaseTheme, …)`: it declares only its palette,\n * `colorScheme`, and the single structural divergence\n * `tab.underBorderFullWidth: false` (the base majority is `true`). Every other\n * structural token is inherited from {@link BaseTheme}; it deliberately does\n * not derive from any other concrete theme.\n *\n * @category Theme\n */\nexport const ModernTheme: Theme = defineTheme(BaseTheme, {\n colorScheme: 'light',\n text : { color: 'rgb(0, 0, 0)' },\n body : { background: 'rgb(255, 255, 255)' },\n border : { color: 'black' },\n button : {\n background: 'rgb(243, 244, 246)',\n border : 'rgb(214, 217, 222)',\n shadow : 'none',\n description: {\n foreground: 'rgb(110, 110, 110)',\n },\n pressed : {\n foreground: 'rgb(150, 150, 150)',\n background: 'linear-gradient(rgb(206, 210, 216), rgb(214, 217, 222))',\n shadow : 'inset 0 1px 3px rgba(0, 0, 0, 0.18)',\n },\n hover : {\n foreground: 'inherit',\n background: 'rgb(234, 236, 239)',\n shadow : 'none',\n },\n flat : {\n hover : {\n background: 'rgba(0, 0, 0, 0.06)',\n border : '1px solid rgb(200, 200, 200)',\n },\n pressed: {\n background: 'rgba(0, 0, 0, 0.10)',\n shadow : 'inset 1px 1px 3px rgba(0, 0, 0, 0.25)',\n border : '1px solid rgb(180, 180, 180)',\n },\n },\n },\n toggle : {\n selected: {\n background: 'rgb(200, 200, 200)',\n shadow : '2px 2px 1px inset grey',\n },\n },\n input : {\n background : 'rgb(255, 255, 255)',\n border : '1px solid rgb(160, 160, 160)',\n borderHover: '1px solid rgb(120, 120, 120)',\n },\n form : {\n background : 'rgb(255, 255, 255)',\n border : 'rgb(160, 160, 160)',\n color : 'rgb(40, 40, 40)',\n disabledBackground: 'rgb(240, 240, 240)',\n disabledColor : 'rgb(170, 170, 170)',\n focusRing : 'rgb(30, 100, 200)',\n toggle : {\n trackOffBackground: 'rgb(200, 200, 200)',\n trackOnBackground : 'rgb(30, 100, 200)',\n thumbBackground : 'rgb(255, 255, 255)',\n },\n slider : {\n trackBackground : 'rgb(220, 220, 220)',\n trackActiveBackground: 'rgb(30, 100, 200)',\n thumbBackground : 'rgb(255, 255, 255)',\n },\n checkbox: {\n background : 'rgb(255, 255, 255)',\n selectedBackground : 'rgb(30, 100, 200)',\n indeterminateBackground: 'rgb(160, 160, 160)',\n checkColor : 'rgb(255, 255, 255)',\n },\n radio : {\n background : 'rgb(255, 255, 255)',\n selectedBackground: 'rgb(30, 100, 200)',\n dotColor : 'rgb(255, 255, 255)',\n },\n },\n gutter: { background: '#AAAAAA' },\n collapse: {\n strip: { background: '#AAAAAA', size: '18px' },\n button: { color: 'rgb(100,100,100)' },\n },\n accordion: {\n border : '1px solid rgb(214, 217, 222)',\n header : {\n // Flat, gradient-free header matching this theme's buttons.\n background: 'rgb(243, 244, 246)',\n border : '1px solid rgb(214, 217, 222)',\n color : 'inherit',\n },\n panel : { border: 'rgb(214, 217, 222)' },\n indicator: { color: 'rgb(100,100,100)' },\n },\n tab : {\n underBorderFullWidth: false,\n toolbar: { background: '#eee', border: '#e1e1e8' },\n button : {\n background : 'rgb(226, 229, 233)',\n border : 'none',\n borderLeft : '1px solid rgb(214, 217, 222)',\n borderRight: '1px solid rgb(214, 217, 222)',\n hover : {\n background : 'rgb(234, 236, 239)',\n border : 'none',\n borderLeft : '1px solid rgb(206, 210, 216)',\n borderRight: '1px solid rgb(206, 210, 216)',\n },\n selected : {\n background : 'rgb(255, 255, 255)',\n border : 'none',\n borderLeft : '1px solid rgb(214, 217, 222)',\n borderRight: '1px solid rgb(214, 217, 222)',\n },\n },\n indicator: { color: '#1a73e8' },\n },\n window: {\n shadow : '3px 3px 2px rgba(0, 0, 0, 0.4)',\n snapGlow : '0 0 0 2px rgba(30, 100, 200, 0.7)',\n control : {\n background : 'rgb(255, 255, 255)',\n border : '1px solid transparent',\n shadow : 'none',\n hoverBackground : 'rgb(236, 238, 241)',\n activeBackground: 'rgb(226, 229, 233)',\n },\n header : { background: '#eee' },\n },\n table : {\n header: {\n background: 'rgb(248, 249, 250)',\n border: 'rgb(226, 229, 233)',\n glyph : { color: 'currentColor' },\n },\n row : {\n selected : 'rgba(30, 100, 200, 0.15)',\n selectedBorder: 'inset 0 0 0 1px rgba(30, 100, 200, 0.6)',\n new : 'rgba(70, 200, 70, 0.15)',\n dirty : 'rgba(255, 165, 0, 0.15)',\n stripe : 'rgba(0, 0, 0, 0.035)',\n },\n cell : {\n background : 'transparent',\n readonlyBackground : 'rgba(0, 0, 0, 0.04)',\n rangeSelectedBackground : 'rgba(30, 100, 200, 0.15)',\n requiredEmptyOutlineColor : 'rgba(220, 60, 60, 0.6)',\n color : 'inherit',\n border : 'none',\n editorBorderColor : 'rgba(30, 100, 200, 0.6)',\n },\n filterRow: {\n background: 'rgba(255, 200, 0, 0.2)',\n },\n resizeHandle: {\n color : 'rgba(0, 0, 0, 0.2)',\n },\n sortBadge: {\n background: 'rgba(0, 0, 0, 0.15)',\n color : 'inherit',\n },\n // Solid (not translucent) and independent of `color: inherit` — this\n // badge sits on the operator button's own glyph (`fill: currentColor`),\n // so inheriting `color` risks the digit rendering the same shade as\n // the glyph beneath/around it. The theme's own blue accent (matching\n // the focus ring — see the chart palette comment below) on white\n // gives a guaranteed ~5.7:1 contrast ratio, independent of whatever\n // sits behind it.\n filterClauseBadge: {\n background: 'rgb(30, 100, 200)',\n color : 'rgb(255, 255, 255)',\n },\n },\n contextMenu: {\n background : 'rgb(255, 255, 255)',\n border : 'rgb(200, 200, 200)',\n shadow : '2px 4px 8px rgba(0, 0, 0, 0.15)',\n item : {\n hoverBackground: 'rgba(30, 100, 200, 0.12)',\n disabledColor : 'rgb(170, 170, 170)',\n },\n separatorColor: 'rgb(220, 220, 220)',\n },\n menuBar: {\n // Menu bars share the tool bar's background by default (see toolBar below).\n background : 'rgb(245, 245, 245)',\n border : 'rgb(220, 220, 220)',\n button : {\n background : 'transparent',\n hoverBackground: 'rgba(30, 100, 200, 0.10)',\n foreground : 'inherit',\n },\n panel : {\n background: 'rgb(255, 255, 255)',\n border : 'rgb(200, 200, 200)',\n shadow : '2px 4px 8px rgba(0, 0, 0, 0.15)',\n },\n item : {\n hoverBackground: 'rgba(30, 100, 200, 0.12)',\n disabledColor : 'rgb(170, 170, 170)',\n shortcutColor : 'rgb(140, 140, 140)',\n },\n separatorColor: 'rgb(220, 220, 220)',\n },\n statusBar: {\n background: 'rgb(245, 245, 245)',\n color : 'rgb(60, 60, 60)',\n border : 'rgb(220, 220, 220)',\n },\n toolBar: {\n background : 'rgb(245, 245, 245)',\n border : 'rgb(220, 220, 220)',\n separatorColor: 'rgb(220, 220, 220)',\n },\n tooltip: {\n background: 'rgb(255, 255, 240)',\n color : 'rgb(0, 0, 0)',\n border : 'rgb(180, 180, 100)',\n shadow : '1px 2px 4px rgba(0, 0, 0, 0.2)',\n },\n popover: {\n background: 'rgb(255, 255, 255)',\n color : 'rgb(0, 0, 0)',\n border : 'rgb(200, 200, 200)',\n shadow : '2px 4px 12px rgba(0, 0, 0, 0.18)',\n },\n notification: {\n shadow : '2px 4px 8px rgba(0, 0, 0, 0.15)',\n info : { background: 'rgba(210, 224, 244, 0.75)', border: 'rgb(30, 100, 200)' },\n success: { background: 'rgba(210, 240, 220, 0.75)', border: 'rgb(30, 180, 80)' },\n warning: { background: 'rgba(248, 232, 204, 0.75)', border: 'rgb(220, 140, 0)' },\n error : { background: 'rgba(244, 214, 214, 0.75)', border: 'rgb(200, 50, 50)' },\n },\n validation: {\n error: {\n border : 'rgb(200, 50, 50)',\n tooltip: {\n background: 'rgb(180, 30, 30)',\n color : 'rgb(255, 255, 255)',\n border : 'rgb(140, 20, 20)',\n },\n },\n },\n autoComplete: {\n background: 'rgb(255, 255, 255)',\n border : 'rgb(200, 200, 200)',\n shadow : '2px 4px 8px rgba(0,0,0,0.15)',\n item: {\n hoverBackground : 'rgba(30, 100, 200, 0.08)',\n highlightBackground: 'rgba(30, 100, 200, 0.18)',\n highlightColor : 'inherit',\n disabledColor : 'rgb(170, 170, 170)',\n },\n },\n list: {\n background: 'rgb(255, 255, 255)',\n border : 'rgb(200, 200, 200)',\n row: {\n hoverBackground : 'rgba(30, 100, 200, 0.08)',\n selectedBackground: 'rgba(30, 100, 200, 0.18)',\n selectedColor : 'inherit',\n focusRing : 'rgb(30, 100, 200)',\n disabledColor : 'rgb(170, 170, 170)',\n separator : 'transparent',\n },\n },\n indicator: {\n focus : 'rgb(30, 100, 200)',\n selection: '1px dashed rgb(120, 170, 240)',\n },\n picker: {\n navForeground: 'var(--ts-ui-text-color)',\n navHoverBackground: 'rgba(30, 100, 200, 0.08)',\n cellDisabledBackground: 'transparent',\n },\n dialog: {\n backdrop: { background: 'rgba(0, 0, 0, 0.45)' },\n border : 'rgb(220, 220, 220)',\n shadow : '4px 8px 24px rgba(0, 0, 0, 0.35)',\n confirm : 'rgb(30, 180, 80)',\n cancel : 'rgb(200, 50, 50)',\n info : { background: 'rgba(30, 100, 200, 0.15)', foreground: 'rgb(30, 100, 200)' },\n affirm : { background: 'rgba(30, 180, 80, 0.15)', foreground: 'rgb(30, 180, 80)' },\n },\n drawer: {\n shadow : '4px 0 24px rgba(0, 0, 0, 0.25)',\n border : 'rgb(220, 220, 220)',\n },\n rail: {\n border : 'rgb(220, 220, 220)',\n shadow : '2px 0 12px rgba(0, 0, 0, 0.18)',\n handle: {\n hoverBackground : 'rgba(30, 100, 200, 0.08)',\n selectedBackground: 'rgba(30, 100, 200, 0.16)',\n },\n },\n spinner: {\n dividerColor: 'rgb(180, 180, 180)',\n },\n progressBar: {\n track : { background: 'rgb(220, 220, 220)' },\n fill : { background: 'rgb(30, 100, 200)' },\n indeterminate: { background: 'rgb(30, 100, 200)' },\n },\n progressSpinner: {\n color : 'rgb(30, 100, 200)',\n backdrop: 'rgba(255, 255, 255, 0.6)',\n },\n drag: {\n ghost: {\n background: 'rgba(200, 200, 200, 0.9)',\n border : 'rgb(150, 150, 150)',\n shadow : '2px 4px 12px rgba(0, 0, 0, 0.25)',\n },\n feedback: {\n valid : { background: 'rgba(30, 180, 80, 0.12)', border: 'rgb(30, 180, 80)' },\n invalid: { background: 'rgba(200, 50, 50, 0.10)', border: 'rgb(200, 50, 50)' },\n },\n reorderIndicator: {\n color: 'rgb(30, 100, 200)',\n },\n dropzone: {\n background : 'rgba(80, 140, 240, 0.10)',\n border : 'rgba(80, 140, 240, 0.40)',\n activeBackground : 'rgba(80, 140, 240, 0.28)',\n invalidBackground: 'rgba(200, 50, 50, 0.28)',\n },\n },\n fileDropZone: {\n background : 'rgba(80, 140, 240, 0.06)',\n border : '2px dashed rgba(80, 140, 240, 0.40)',\n activeBackground: 'rgba(80, 140, 240, 0.18)',\n activeBorder : '2px dashed rgba(80, 140, 240, 0.80)',\n },\n scroll: {\n shadowColor: 'rgba(0, 0, 0, 1)',\n },\n // Okabe–Ito colour-blind-safe categorical palette, tuned for a light\n // background. Axis/grid/label are neutral greys; the selection ring reuses\n // the theme's blue accent (matching the focus indicator).\n chart: {\n series: [\n '#0072B2', // blue\n '#E69F00', // orange\n '#009E73', // green\n '#D55E00', // vermilion\n '#CC79A7', // purple\n '#56B4E9', // sky\n '#8C6D1F', // gold\n '#555555', // grey\n ],\n axis : 'rgb(120, 120, 120)',\n grid : 'rgb(224, 224, 224)',\n label : 'rgb(85, 85, 85)',\n selection: '#1a73e8',\n },\n});\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\n// The OFL Manrope variable font (weight axis 200–800), shipped by\n// @fontsource-variable/manrope as unicode-range subsets. We bundle the Latin\n// and Latin-Ext subsets (the framework's Western chrome plus extended-Latin\n// coverage); each .woff2 is imported as a URL so Vite emits it as a build asset\n// served from the consumer's own origin — no Google Fonts <link>, no runtime\n// external request. Vite library mode inlines these assets as base64, so the\n// other subsets (Cyrillic, Greek, Vietnamese) are deliberately omitted to keep\n// the eagerly-bundled font payload small; text outside Latin/Latin-Ext falls\n// back to `sans-serif`. The matching @font-face rules are injected at runtime by\n// ensureFontLoaded() (see below) rather than via a CSS import, because the\n// framework ships no stylesheet: like Glyph's keyframes, shared assets are\n// injected from JS so they survive the library build, where a CSS side-effect\n// import would be extracted to an orphaned file the bundle never loads.\nimport manropeLatinExtUrl from '@fontsource-variable/manrope/files/manrope-latin-ext-wght-normal.woff2';\nimport manropeLatinUrl from '@fontsource-variable/manrope/files/manrope-latin-wght-normal.woff2';\n\nimport { InlineStyle } from '~/core/StyleTarget.js';\nimport { Util } from '~/core/Util.js';\nimport { DOM } from '~/core/DOM.js';\nimport { holdFirstLayout, releaseFirstLayout } from '~/core/FirstLayoutGate.js';\n// The three built-in theme literals live in their own files under\n// `core/themes/`; they are imported here so `ThemeManager` can default to\n// `ModernTheme`, and re-exported below so existing\n// `import { ClassicTheme } from '~/core/Theme.js'` paths and the core barrel\n// keep resolving unchanged.\nimport { BaseTheme } from '~/core/themes/BaseTheme.js';\nimport { ClassicTheme } from '~/core/themes/ClassicTheme.js';\nimport { DarkTheme } from '~/core/themes/DarkTheme.js';\nimport { ModernTheme } from '~/core/themes/ModernTheme.js';\n\n/**\n * A scaled size in the theme's {@link Theme.scale} block.\n *\n * `{ scale }` is a **ratio of the base** size — the resolved px grows with\n * `scale.base` (`round(base * scale)`). `{ fixed }` is **absolute px** that opts\n * out of scaling. Exactly one of the two is intended, and that is compile-time\n * enforced wherever a value is typed against `ScaleToken` directly. Inside a\n * theme literal the guarantee is weakened by\n * [`DeepPartial`](/api/core/type-aliases/DeepPartial) (which makes both arms\n * optional), so the resolution that produces {@link ResolvedScale} guards every\n * arm at runtime.\n *\n * @category Theme\n */\nexport type ScaleToken = { scale: number } | { fixed: number };\n\n/**\n * A theme font-size token, resolved to a CSS string by `themeToVars`. A bare\n * length string (`'13px'`, `'1.2rem'`) passes through unchanged; a signed pixel\n * offset string (`'+2px'`, `'-2px'`) becomes `calc(var(--ts-ui-font-size) ± Npx)`;\n * a `{ scale: n }` object becomes `calc(var(--ts-ui-font-size) * n)`. Omitting an\n * optional font token inherits the base font size ([`Theme`](/api/core/interfaces/Theme)'s\n * `font.size`, the `--ts-ui-font-size` anchor).\n *\n * Unlike the glyph {@link ScaleToken} — which resolves to a JS px number frozen\n * into {@link ResolvedScale} once per theme — a `FontSizeToken` resolves to a CSS\n * string and rides the cascade, so it re-resolves automatically when the base\n * font size changes.\n *\n * @category Theme\n */\nexport type FontSizeToken = string | { scale: number };\n\n/**\n * Defines the full set of design tokens that make up a UI theme.\n *\n * Background tokens (e.g. `button.bg`, `button.pressed.bg`, `toggle.selected.bg`) accept any\n * CSS `background-image` value such as a gradient, or any CSS `background-color` value such as\n * a plain colour. The framework applies the same variable to both `background-color` and\n * `background-image`, so CSS's \"invalid at computed-value time\" rule routes automatically:\n * a plain colour takes effect via `background-color`; a gradient via `background-image`.\n *\n * @category Theme\n */\nexport interface Theme {\n colorScheme: string;\n\n font: {\n family : string;\n size? : string;\n /**\n * Extra vertical leading added to a control's own font size to form its\n * line box, as a CSS length string, e.g. `\"2px\"`. The rendered line\n * height is `font-size + linePadding` (via `calc(1em + …)`), so the\n * leading scales with each control's font size instead of being a fixed\n * value — 12px text and 14px text get proportionate line boxes from the\n * one token. A control can still pin an explicit fixed line-height with\n * `Text.setLineHeight(px)`.\n */\n linePadding: string;\n };\n\n text: {\n color: string;\n };\n\n body: {\n background: string;\n };\n\n border: {\n color : string;\n radius: string;\n };\n\n button: {\n background: string;\n border : string;\n shadow : string;\n padding : string;\n font: {\n size?: FontSizeToken;\n };\n description: {\n fontSize? : FontSizeToken;\n foreground: string;\n weight : string;\n };\n pressed: {\n foreground: string;\n background: string;\n shadow : string;\n };\n hover: {\n foreground: string;\n background: string;\n shadow : string;\n };\n flat: {\n hover: {\n background: string;\n border : string;\n };\n pressed: {\n background: string;\n shadow : string;\n border : string;\n };\n };\n };\n\n toggle: {\n selected: {\n background: string;\n shadow : string;\n };\n };\n\n input: {\n background: string;\n /**\n * Complete CSS border shorthand string consumed via `setBorder(string)`.\n * Applied to `TextInput`, the three picker fields, `ComboBox`, the\n * picker dropdown panels, the autocomplete dropdown, and `FieldSet`.\n */\n border: string;\n /**\n * Complete CSS border shorthand string for the hover state. Provisioned\n * for follow-up work that adds `:hover` rules to the listed inputs; not\n * consumed at present.\n */\n borderHover: string;\n };\n\n /**\n * Cross-cutting affordance tokens — surfaces that mark a focused / selected\n * cell or row use this bucket rather than per-component colour-only tokens.\n */\n indicator: {\n /**\n * Colour-only token for the keyboard-focus indicator. Consumed by\n * every `:focus` / `:focus-within` rule the framework exposes —\n * `TextField` / `TextArea` / `PasswordField`, the composite inputs\n * (`AutoCompleteField`, the picker fields, `NumberSpinner`), the\n * list root, the row focus mark, and the table cell focus mark.\n * The width / style is fixed at `2px solid` framework-side so the\n * same colour works through both the `border:` shorthand (on\n * pseudo-element overlays) and the `box-shadow: inset 0 0 0 2px`\n * recipe (used on `<input>` elements, which don't render\n * pseudo-elements).\n */\n focus: string;\n /**\n * Complete CSS outline shorthand string for the \"selection mark\"\n * affordance — reserved for callers that need an outline-shaped\n * selection cue distinct from background-tint selection. Currently\n * unconsumed; provisioned so a future plan can wire it without\n * re-touching `Theme.ts`.\n */\n selection: string;\n };\n\n form: {\n background : string;\n border : string;\n color : string;\n disabledBackground: string;\n disabledColor : string;\n focusRing : string;\n\n toggle: {\n trackOffBackground: string;\n trackOnBackground : string;\n thumbBackground : string;\n width : string;\n height : string;\n };\n\n slider: {\n trackBackground : string;\n trackActiveBackground: string;\n thumbBackground : string;\n thumbSize : string;\n trackThickness : string;\n };\n\n checkbox: {\n background : string;\n selectedBackground : string;\n indeterminateBackground: string;\n checkColor : string;\n size : string;\n radius : string;\n };\n\n radio: {\n background : string;\n selectedBackground: string;\n dotColor : string;\n size : string;\n };\n };\n\n gutter: {\n background: string;\n };\n\n collapse: {\n strip: {\n /** Background fill of a collapsed pane/region's tucked strip. */\n background: string;\n /** Strip thickness along its short axis (CSS length). */\n size: string;\n };\n button: {\n /** Colour of the collapse/restore chevron glyph. */\n color: string;\n };\n };\n\n tab: {\n /**\n * Whether the tab strip draws the edge-to-edge 1px rule under the toolbar.\n * Read by the [`Tab`](/api/layout/classes/Tab) layout manager as the default\n * for its under-border; an explicit `tabUnderBorderFullWidth` option overrides it.\n */\n underBorderFullWidth: boolean;\n toolbar: {\n background: string;\n border : string;\n };\n button: {\n background: string;\n /** CSS `border` shorthand applied to all four sides (e.g. `'1px solid rgb(...)'` or `'none'`); the uniform fallback for the per-side overrides. */\n border : string;\n /** Optional CSS `border-top` override for the normal state; falls back to `border`. */\n borderTop? : string;\n /** Optional CSS `border-right` override for the normal state; falls back to `border`. */\n borderRight? : string;\n /** Optional CSS `border-bottom` override for the normal state; falls back to `border`. */\n borderBottom?: string;\n /** Optional CSS `border-left` override for the normal state; falls back to `border`. */\n borderLeft? : string;\n hover: {\n background: string;\n border : string;\n borderTop? : string;\n borderRight? : string;\n borderBottom?: string;\n borderLeft? : string;\n };\n selected: {\n background: string;\n border : string;\n borderTop? : string;\n borderRight? : string;\n borderBottom?: string;\n borderLeft? : string;\n };\n };\n indicator: {\n /** Fill colour of the sliding active-tab selection bar. */\n color : string;\n /** Thickness (CSS length) of the indicator bar. */\n thickness: string;\n };\n };\n\n window: {\n shadow : string;\n snapGlow : string;\n minDockWidth: string;\n /**\n * Window control buttons (minimize / maximize / close), shared by a\n * `TabWindow`'s tab bar and an ordinary `Window`'s `WindowHeader`\n * (both build them from the same `windowControls` factory). Flat themes\n * blend them into the surface; the classic theme renders them as standard\n * raised buttons.\n */\n control: {\n background : string;\n border : string;\n shadow : string;\n hoverBackground : string;\n activeBackground: string;\n };\n /**\n * Focused fill of an ordinary `Window`'s `WindowHeader`. Independently\n * themeable from the tab strip, but valued equal to `tab.toolbar.background`\n * so a header `Window` and a headerless `TabWindow` share one\n * window-chrome colour. The blurred fill is the shared `gutter.background`.\n */\n header: {\n background: string;\n };\n };\n\n header: {\n font: {\n size?: FontSizeToken;\n };\n };\n\n table: {\n header: {\n /** Header surface fill; accepts any CSS `background-image` (gradient) or `background-color` value. */\n background: string;\n border: string;\n font: {\n size?: FontSizeToken;\n };\n glyph: {\n gap : string;\n color: string;\n };\n };\n row: {\n selected : string;\n selectedBorder: string;\n new : string;\n dirty : string;\n stripe : string;\n };\n cell: {\n height : string;\n padding : number;\n background : string;\n readonlyBackground : string;\n rangeSelectedBackground : string;\n requiredEmptyOutlineColor : string;\n color : string;\n border : string;\n editorBorderColor : string;\n };\n filterRow: {\n /** Tint applied to the filter row's text inputs and operator buttons. */\n background: string;\n };\n resizeHandle: {\n width : string;\n color : string;\n cursor: string;\n };\n sortBadge: {\n background: string;\n color : string;\n fontSize? : FontSizeToken;\n };\n filterClauseBadge: {\n background: string;\n color : string;\n fontSize? : FontSizeToken;\n };\n };\n\n contextMenu: {\n background: string;\n border : string;\n shadow : string;\n item: {\n hoverBackground: string;\n disabledColor : string;\n };\n separatorColor: string;\n };\n\n menuBar: {\n background: string;\n border : string;\n button: {\n background : string;\n hoverBackground: string;\n foreground : string;\n };\n panel: {\n background: string;\n border : string;\n shadow : string;\n minWidth : string;\n };\n item: {\n hoverBackground: string;\n disabledColor : string;\n shortcutColor : string;\n };\n separatorColor: string;\n };\n\n statusBar: {\n background: string;\n color : string;\n border : string;\n height : string;\n padding : string;\n },\n toolBar: {\n background : string;\n border : string;\n padding : string;\n gap : string;\n separatorColor: string;\n };\n\n tooltip: {\n background: string;\n color : string;\n border : string;\n shadow : string;\n };\n\n popover: {\n background: string;\n color : string;\n border : string;\n shadow : string;\n radius : string;\n padding : string;\n arrowSize : string;\n };\n\n notification: {\n shadow : string;\n info: {\n background: string;\n border : string;\n };\n success: {\n background: string;\n border : string;\n };\n warning: {\n background: string;\n border : string;\n };\n error: {\n background: string;\n border : string;\n };\n };\n\n dialog: {\n backdrop: {\n background: string;\n };\n border: string;\n shadow: string;\n confirm: string;\n cancel: string;\n /**\n * Title-bar wash for an informational dialog (one `confirm`-result\n * button). Background is a low-opacity tint of the same hue as\n * `notification.info.border`; foreground is the saturated form,\n * applied to both the title text and the leading `circle-info`\n * glyph the dialog injects for this variant.\n */\n info: {\n background: string;\n foreground: string;\n };\n /**\n * Title-bar wash for an affirmative-action dialog (both `confirm`\n * and `cancel` buttons). Background mirrors the low-opacity tint of\n * `notification.success.border`; foreground is the saturated form,\n * applied to the title text only — this variant carries no leading\n * glyph.\n */\n affirm: {\n background: string;\n foreground: string;\n };\n };\n\n drawer: {\n shadow: string;\n border: string;\n };\n\n rail: {\n border: string;\n shadow: string;\n handle: {\n hoverBackground: string;\n selectedBackground: string;\n };\n };\n\n accordion: {\n /** Full CSS border shorthand (width style colour) for the container box. */\n border: string;\n header: {\n background: string;\n /** Full CSS border shorthand (width style colour) for the header's bottom divider. */\n border : string;\n color : string;\n };\n panel: {\n border: string;\n };\n indicator: {\n color: string;\n };\n };\n\n validation: {\n error: {\n border : string;\n tooltip: {\n background: string;\n color : string;\n border : string;\n };\n };\n };\n\n autoComplete: {\n background: string;\n border : string;\n shadow : string;\n item: {\n hoverBackground : string;\n highlightBackground: string;\n highlightColor : string;\n disabledColor : string;\n };\n };\n\n list: {\n background: string;\n border : string;\n row: {\n hoverBackground : string;\n selectedBackground: string;\n selectedColor : string;\n focusRing : string;\n disabledColor : string;\n separator : string;\n };\n };\n\n dropdown: {\n fade: {\n duration : string;\n translate: string;\n };\n };\n\n /**\n * Tokens used by the picker dropdowns\n * ([`DatePickerDropdown`](/api/component/input/classes/DatePickerDropdown),\n * [`DateTimePickerDropdown`](/api/component/input/classes/DateTimePickerDropdown)).\n * The cell hover and selection highlight keep tracking `autoComplete.item.*`\n * numerically because both surfaces share the\n * [`PickerCell`](/api/component/input/classes/PickerCell) class — a theme\n * that customises one gets the other matching automatically. These three\n * tokens cover the surfaces the autoComplete tokens cannot: a\n * navigation-chevron / header-as-button affordance and the dim background\n * for out-of-range day cells.\n */\n picker: {\n /** Foreground colour for the header chevron glyph and the year-scroller toggle. */\n navForeground: string;\n /** Background applied to the navigation chevron / header-toggle under hover. */\n navHoverBackground: string;\n /** Background applied to a day cell that falls outside `minDate`/`maxDate`. */\n cellDisabledBackground: string;\n };\n\n spinner: {\n buttonWidth : string;\n dividerColor: string;\n };\n\n progressBar: {\n track: {\n background : string;\n borderRadius: string;\n };\n fill: {\n background: string;\n };\n indeterminate: {\n background: string;\n };\n };\n\n progressSpinner: {\n color : string;\n backdrop: string;\n size : string;\n };\n\n glyph: {\n spinDuration : string;\n pulseDuration: string;\n beatDuration : string;\n };\n\n /**\n * Tokens consumed by the drag-and-drop overlays — the ghost that\n * follows the cursor, the per-target validity tint applied by\n * [`DragFeedback`](/api/overlay/classes/DragFeedback), and the\n * insertion-line bar drawn by\n * [`ReorderIndicator`](/api/overlay/classes/ReorderIndicator).\n */\n drag: {\n ghost: {\n background: string;\n border : string;\n shadow : string;\n opacity : string;\n };\n feedback: {\n valid : { background: string; border: string; };\n invalid: { background: string; border: string; };\n };\n reorderIndicator: {\n color: string;\n };\n dropzone: {\n background : string;\n border : string;\n activeBackground : string;\n invalidBackground: string;\n };\n };\n\n /**\n * Tokens consumed by the [`FileDropZone`](/api/component/input/classes/FileDropZone)\n * surface — the dashed border and tinted background of its resting state\n * and the brighter wash while a valid OS file drag hovers. Deliberately\n * separate from the {@link Theme.drag} `dropzone` tokens, which belong to\n * the internal pointer-drag overlay: the two mechanisms are unrelated.\n */\n fileDropZone: {\n background : string;\n border : string;\n activeBackground: string;\n activeBorder : string;\n };\n\n scroll: {\n /**\n * Start colour of the edge-fade gradient a scrolling {@link Panel}\n * paints on each side where hidden content can still be scrolled into\n * view. Each fade runs from this colour to `transparent`; the fade\n * depth is a framework constant, so only the colour is themed.\n */\n shadowColor: string;\n };\n\n /**\n * Tokens consumed by [`Markdown`](/api/component/display/classes/Markdown).\n * Scheme-invariant, so the value lives in {@link BaseTheme}, not the\n * per-scheme palettes.\n */\n markdown: {\n /**\n * Unitless line-height for flowed prose (paragraphs, list items,\n * headings, blockquotes). Deliberately looser than the framework's\n * UI line-height, which is tuned for scanned single-line controls\n * rather than continuously read text. Code/pre keep the UA's\n * `normal` line-height regardless of this token.\n */\n lineHeight: string;\n /**\n * Max width of the prose column, as a CSS length — typically a `ch`\n * value so it tracks the reading measure (comfortable line length is\n * roughly 45–75 characters) rather than a fixed pixel width. Caps the\n * root element, so it also bounds oversized tables/code blocks, which\n * fall back to their own horizontal scroll within the capped column.\n */\n maxMeasure: string;\n };\n\n /**\n * Charting tokens consumed by the [`component/chart`](/api/component/chart) family.\n * `series` is the ordered categorical palette — emitted as\n * `--ts-ui-chart-series-1 … --ts-ui-chart-series-N`, one custom property per\n * slot — that series marks bind to by index; the remaining colour tokens\n * dress the axes, gridlines, tick labels, and the selection ring. The\n * scheme-invariant structural widths and the point radius live in\n * {@link BaseTheme}, not the per-scheme palettes.\n */\n chart: {\n /** Ordered categorical series palette; at least 8 entries. */\n series: string[];\n /** Axis line and tick-mark colour. */\n axis: string;\n /** Gridline colour. */\n grid: string;\n /** Axis/tick label text colour. */\n label: string;\n /** Selection-ring colour for a clicked point. */\n selection: string;\n /** Series line/area stroke width (CSS length). */\n lineWidth: string;\n /** Axis/tick/gridline stroke width (CSS length). */\n axisWidth: string;\n /** Point-marker radius (CSS length). */\n pointRadius: string;\n };\n\n /**\n * The framework's global scale knob plus the font-coupled size ratios that\n * follow it. `base` is the root size in px, mirrored to CSS as\n * `--ts-ui-base-size`; SVG glyph boxes and JS layout constants size off it\n * (CSS `font-size` does not reach an SVG glyph). Each non-`base` token is a\n * {@link ScaleToken}; the block is resolved to a numeric\n * {@link ResolvedScale} once per {@link ThemeManager.setTheme} and read by\n * layout code via {@link ThemeManager.getResolvedScale}.\n */\n scale: {\n /** Root base size in px; the global scale knob. Mirror of `--ts-ui-base-size`. */\n base : number;\n /** Window/tab title-glyph ink size. */\n titleGlyph : ScaleToken;\n /** Tab close-button box. */\n tabClose : ScaleToken;\n /** Tab close-glyph ink size. */\n tabCloseGlyph : ScaleToken;\n /** Tab-button inset (the compact inset derives as half of this). */\n tabButtonInset: ScaleToken;\n };\n}\n\nexport { BaseTheme, ClassicTheme, DarkTheme, ModernTheme };\n\n/**\n * Recursively-optional view of a type: every property optional at every depth,\n * recursing into plain object properties. Used for the partial overrides bag\n * passed to {@link defineTheme}.\n */\nexport type DeepPartial<T> = {\n [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];\n};\n\n/**\n * Narrows a value to a plain object — an object that is neither `null` nor an\n * array. Used by {@link defineTheme}'s merge to decide recurse-vs-replace.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a non-null, non-array object.\n */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Recursively merges `overrides` onto `base`: recurse into plain objects,\n * replace primitive/array leaves wholesale, and skip `undefined` override\n * values so an absent override key never blanks a base value.\n *\n * @param base - The value being layered onto.\n * @param overrides - The value layered on top.\n * @returns The merged value — a new object when both sides are plain objects, otherwise `overrides`.\n */\nfunction deepMerge(base: unknown, overrides: unknown): unknown {\n if (!isPlainObject(base) || !isPlainObject(overrides)) {\n return overrides;\n }\n\n const result: Record<string, unknown> = { ...base };\n\n for (const key of Object.keys(overrides)) {\n const ov = overrides[key];\n\n if (ov === undefined) {\n continue;\n }\n\n result[key] = key in base ? deepMerge(base[key], ov) : ov;\n }\n\n return result;\n}\n\n/**\n * Produces a fully-resolved {@link Theme} by deep-merging `overrides` onto `base`.\n *\n * `base` is typically {@link BaseTheme} (the structural scaffold), but may be any\n * full `Theme` to deliberately derive one theme from another (e.g.\n * `defineTheme(ClassicTheme, { …dark palette… })`). The caller is responsible for\n * `base` + `overrides` together covering every `Theme` key; completeness is\n * enforced by the theme regression test, not the type system.\n *\n * Merge rule: recurse into plain objects, replace primitive/array leaves wholesale,\n * skip `undefined` override values.\n *\n * @param base - The scaffold or full theme to layer onto.\n * @param overrides - Tokens that differ from `base`.\n * @returns A complete, resolved `Theme`.\n */\nexport function defineTheme(base: DeepPartial<Theme>, overrides: DeepPartial<Theme>): Theme {\n return deepMerge(base, overrides) as Theme;\n}\n\n/**\n * The theme's {@link Theme.scale} block with every {@link ScaleToken} resolved\n * to a px number against the base size. Computed once per\n * [`setTheme`](/api/core/classes/ThemeManager#settheme) and read by layout code\n * via [`getResolvedScale`](/api/core/classes/ThemeManager#getresolvedscale), so\n * SVG glyph boxes and JS layout constants read a plain number instead of\n * resolving a token on every layout pass.\n *\n * @category Theme\n */\nexport type ResolvedScale = { readonly [K in keyof Theme[\"scale\"]]: number };\n\n/**\n * Resolves a {@link ScaleToken} to px against `base`. `{ scale }` is a ratio of\n * the base (`round(base * scale)`, grows with it); `{ fixed }` is absolute px\n * that stays put.\n *\n * Every arm is guarded because\n * [`DeepPartial`](/api/core/type-aliases/DeepPartial) weakens the union to\n * `{ scale? } | { fixed? }` inside a theme literal, so an authored token can be\n * malformed (`{}`, both-present) without a compile error. `scale` wins when both\n * are somehow present; a token missing both falls back to `base` so a malformed\n * theme degrades visibly (base px) rather than producing `NaN` or crashing.\n */\nfunction resolveScaleToken(token: ScaleToken, base: number): number {\n const t = token as { scale?: number; fixed?: number };\n\n if (typeof t.scale === 'number') return Math.round(base * t.scale);\n if (typeof t.fixed === 'number') return t.fixed;\n\n return base;\n}\n\n/**\n * Resolves a theme's whole `scale` block to a numeric {@link ResolvedScale}\n * snapshot. Runs once per {@link ThemeManager.setTheme} (and once at module load\n * for the default theme), reading `scale.base` directly off the theme object —\n * no `getComputedStyle` — so layout code never resolves a token itself.\n */\nfunction resolveScale(theme: Theme): ResolvedScale {\n const base = theme.scale.base;\n\n return {\n base,\n titleGlyph : resolveScaleToken(theme.scale.titleGlyph, base),\n tabClose : resolveScaleToken(theme.scale.tabClose, base),\n tabCloseGlyph : resolveScaleToken(theme.scale.tabCloseGlyph, base),\n tabButtonInset: resolveScaleToken(theme.scale.tabButtonInset, base),\n };\n}\n\n/**\n * Emits the four per-side tab-button border custom properties for one state,\n * keyed `<base>-top` / `-right` / `-bottom` / `-left`, each resolving to the\n * side's own value or falling back to the uniform `border`. All four are always\n * emitted with a concrete value so switching to a theme that leaves the per-side\n * fields unset overwrites (rather than leaks) the previous theme's per-side vars.\n *\n * @param base - The uniform border var name for the state (e.g. `'--ts-ui-tab-button-border'`).\n * @param side - The tab-button (sub-)object carrying the uniform `border` plus optional per-side fields.\n *\n * @returns A map of all four per-side custom properties.\n */\nfunction tabButtonSideVars(\n base: string,\n side: { border: string; borderTop?: string; borderRight?: string; borderBottom?: string; borderLeft?: string }\n): Record<string, string> {\n return {\n [`${base}-top`]: side.borderTop ?? side.border,\n [`${base}-right`]: side.borderRight ?? side.border,\n [`${base}-bottom`]: side.borderBottom ?? side.border,\n [`${base}-left`]: side.borderLeft ?? side.border,\n };\n}\n\n/**\n * Emits the categorical series palette as one custom property per slot, keyed\n * `<base>-1 … <base>-N`. A spread helper in the shape of {@link tabButtonSideVars},\n * so a chart mark can bind `var(--ts-ui-chart-series-3)` directly and a theme\n * switch recolours every series with no JS.\n *\n * @param base - The palette var-name prefix (e.g. `'--ts-ui-chart-series'`).\n * @param palette - The ordered colour list.\n *\n * @returns A map of the per-slot custom properties.\n */\nfunction chartSeriesVars(base: string, palette: string[]): Record<string, string> {\n const vars: Record<string, string> = {};\n\n palette.forEach((color, index) => {\n vars[`${base}-${index + 1}`] = color;\n });\n\n return vars;\n}\n\n// Matches a signed pixel offset: '+2px', '-2px', '+0.5px'. Whole/decimal, px only.\nconst FONT_SIZE_OFFSET = /^([+-])(\\d+(?:\\.\\d+)?)px$/;\n\n/**\n * Resolves a {@link FontSizeToken} (or its absence) to the CSS string\n * `themeToVars` emits for a font var.\n *\n * - A signed pixel offset string (`'+2px'` / `'-2px'`) becomes\n * `calc(var(--ts-ui-font-size) ± Npx)`.\n * - A `{ scale: n }` object becomes `calc(var(--ts-ui-font-size) * n)`.\n * - Any other string (a bare length like `'13px'` / `'1.2rem'`) passes through\n * unchanged.\n * - `undefined` (an omitted optional token) and any unrecognised shape fall back\n * to `var(--ts-ui-font-size)`, so a malformed theme degrades to the base font\n * size — visibly, never `NaN`/crash. `DeepPartial<Theme>` weakens the\n * `{ scale }` arm to `{ scale?: number }` inside a theme literal, so the\n * `typeof token.scale === 'number'` guard is what keeps `{}` from emitting a\n * broken `calc(... * undefined)`.\n */\nfunction resolveFontSizeToken(token: FontSizeToken | undefined): string {\n if (token === undefined) return 'var(--ts-ui-font-size)';\n\n if (typeof token === 'object') {\n return typeof token.scale === 'number'\n ? `calc(var(--ts-ui-font-size) * ${token.scale})`\n : 'var(--ts-ui-font-size)';\n }\n\n if (typeof token === 'string') {\n const m = FONT_SIZE_OFFSET.exec(token.trim());\n // Whitespace around the operator is required — calc() rejects `14px-2px`\n // but accepts `14px - 2px`.\n return m ? `calc(var(--ts-ui-font-size) ${m[1]} ${m[2]}px)` : token;\n }\n\n return 'var(--ts-ui-font-size)';\n}\n\n/**\n * Converts a Theme object into a map of CSS custom property names to values.\n */\nfunction themeToVars(theme: Theme): Record<string, string> {\n return {\n '--ts-ui-font-family' : theme.font.family,\n // `'14px'` mirrors BaseTheme.font.size — the fallback only applies when a\n // theme omits font.size entirely (the built-ins never do); it keeps the\n // base anchor every relative font token references from being unemitted.\n '--ts-ui-font-size' : theme.font.size ?? '14px',\n '--ts-ui-base-size' : String(theme.scale.base) + 'px',\n '--ts-ui-line-padding' : String(theme.font.linePadding),\n '--ts-ui-text-color' : theme.text.color,\n '--ts-ui-body-bg' : theme.body.background,\n '--ts-ui-border-color' : theme.border.color,\n '--ts-ui-border-radius' : theme.border.radius,\n '--ts-ui-button-bg' : theme.button.background,\n '--ts-ui-button-border' : theme.button.border,\n '--ts-ui-button-shadow' : theme.button.shadow,\n '--ts-ui-button-padding' : theme.button.padding,\n '--ts-ui-button-font-size' : resolveFontSizeToken(theme.button.font.size),\n '--ts-ui-button-description-font-size' : resolveFontSizeToken(theme.button.description.fontSize),\n '--ts-ui-button-description-fg' : theme.button.description.foreground,\n '--ts-ui-button-description-weight' : theme.button.description.weight,\n '--ts-ui-button-pressed-fg' : theme.button.pressed.foreground,\n '--ts-ui-button-pressed-bg' : theme.button.pressed.background,\n '--ts-ui-button-pressed-shadow' : theme.button.pressed.shadow,\n '--ts-ui-button-hover-fg' : theme.button.hover.foreground,\n '--ts-ui-button-hover-bg' : theme.button.hover.background,\n '--ts-ui-button-hover-shadow' : theme.button.hover.shadow,\n '--ts-ui-button-flat-hover-bg' : theme.button.flat.hover.background,\n '--ts-ui-button-flat-hover-border' : theme.button.flat.hover.border,\n '--ts-ui-button-flat-pressed-bg' : theme.button.flat.pressed.background,\n '--ts-ui-button-flat-pressed-shadow' : theme.button.flat.pressed.shadow,\n '--ts-ui-button-flat-pressed-border' : theme.button.flat.pressed.border,\n '--ts-ui-toggle-selected-bg' : theme.toggle.selected.background,\n '--ts-ui-toggle-selected-shadow' : theme.toggle.selected.shadow,\n '--ts-ui-input-bg' : theme.input.background,\n '--ts-ui-input-border' : theme.input.border,\n '--ts-ui-input-border-hover' : theme.input.borderHover,\n '--ts-ui-form-bg' : theme.form.background,\n '--ts-ui-form-border' : theme.form.border,\n '--ts-ui-form-color' : theme.form.color,\n '--ts-ui-form-disabled-bg' : theme.form.disabledBackground,\n '--ts-ui-form-disabled-color' : theme.form.disabledColor,\n '--ts-ui-focus-ring' : theme.form.focusRing,\n '--ts-ui-toggle-track-bg-off' : theme.form.toggle.trackOffBackground,\n '--ts-ui-toggle-track-bg-on' : theme.form.toggle.trackOnBackground,\n '--ts-ui-toggle-thumb-bg' : theme.form.toggle.thumbBackground,\n '--ts-ui-toggle-width' : theme.form.toggle.width,\n '--ts-ui-toggle-height' : theme.form.toggle.height,\n '--ts-ui-slider-track-bg' : theme.form.slider.trackBackground,\n '--ts-ui-slider-track-active-bg' : theme.form.slider.trackActiveBackground,\n '--ts-ui-slider-thumb-bg' : theme.form.slider.thumbBackground,\n '--ts-ui-slider-thumb-size' : theme.form.slider.thumbSize,\n '--ts-ui-slider-track-thickness' : theme.form.slider.trackThickness,\n '--ts-ui-checkbox-bg' : theme.form.checkbox.background,\n '--ts-ui-checkbox-bg-selected' : theme.form.checkbox.selectedBackground,\n '--ts-ui-checkbox-bg-indeterminate' : theme.form.checkbox.indeterminateBackground,\n '--ts-ui-checkbox-check-color' : theme.form.checkbox.checkColor,\n '--ts-ui-checkbox-size' : theme.form.checkbox.size,\n '--ts-ui-checkbox-radius' : theme.form.checkbox.radius,\n '--ts-ui-radio-bg' : theme.form.radio.background,\n '--ts-ui-radio-bg-selected' : theme.form.radio.selectedBackground,\n '--ts-ui-radio-dot-color' : theme.form.radio.dotColor,\n '--ts-ui-radio-size' : theme.form.radio.size,\n '--ts-ui-gutter-bg' : theme.gutter.background,\n '--ts-ui-collapse-strip-bg' : theme.collapse.strip.background,\n '--ts-ui-collapse-strip-size' : theme.collapse.strip.size,\n '--ts-ui-collapse-button-color' : theme.collapse.button.color,\n '--ts-ui-accordion-border' : theme.accordion.border,\n '--ts-ui-accordion-header-bg' : theme.accordion.header.background,\n '--ts-ui-accordion-header-border' : theme.accordion.header.border,\n '--ts-ui-accordion-header-color' : theme.accordion.header.color,\n '--ts-ui-accordion-panel-border' : theme.accordion.panel.border,\n '--ts-ui-accordion-indicator-color' : theme.accordion.indicator.color,\n '--ts-ui-tab-toolbar-bg' : theme.tab.toolbar.background,\n '--ts-ui-tab-toolbar-border' : theme.tab.toolbar.border,\n '--ts-ui-tab-button-bg' : theme.tab.button.background,\n '--ts-ui-tab-button-border' : theme.tab.button.border,\n ...tabButtonSideVars('--ts-ui-tab-button-border', theme.tab.button),\n '--ts-ui-tab-button-hover-bg' : theme.tab.button.hover.background,\n '--ts-ui-tab-button-hover-border' : theme.tab.button.hover.border,\n ...tabButtonSideVars('--ts-ui-tab-button-hover-border', theme.tab.button.hover),\n '--ts-ui-tab-button-selected-bg' : theme.tab.button.selected.background,\n '--ts-ui-tab-button-selected-border' : theme.tab.button.selected.border,\n ...tabButtonSideVars('--ts-ui-tab-button-selected-border', theme.tab.button.selected),\n '--ts-ui-tab-indicator-color' : theme.tab.indicator.color,\n '--ts-ui-tab-indicator-thickness' : theme.tab.indicator.thickness,\n '--ts-ui-window-shadow' : theme.window.shadow,\n '--ts-ui-window-snap-glow' : theme.window.snapGlow,\n '--ts-ui-window-min-dock-width' : theme.window.minDockWidth,\n '--ts-ui-window-control-bg' : theme.window.control.background,\n '--ts-ui-window-control-border' : theme.window.control.border,\n '--ts-ui-window-control-shadow' : theme.window.control.shadow,\n '--ts-ui-window-control-hover-bg' : theme.window.control.hoverBackground,\n '--ts-ui-window-control-active-bg' : theme.window.control.activeBackground,\n '--ts-ui-window-header-bg' : theme.window.header.background,\n '--ts-ui-header-font-size' : resolveFontSizeToken(theme.header.font.size),\n '--ts-ui-table-header-bg' : theme.table.header.background,\n '--ts-ui-table-header-border' : theme.table.header.border,\n '--ts-ui-table-header-font-size' : resolveFontSizeToken(theme.table.header.font.size),\n '--ts-ui-table-header-glyph-gap' : theme.table.header.glyph.gap,\n '--ts-ui-table-header-glyph-color' : theme.table.header.glyph.color,\n '--ts-ui-table-row-selected' : theme.table.row.selected,\n '--ts-ui-table-row-selected-border' : theme.table.row.selectedBorder,\n '--ts-ui-table-row-new' : theme.table.row.new,\n '--ts-ui-table-row-dirty' : theme.table.row.dirty,\n '--ts-ui-table-row-stripe' : theme.table.row.stripe,\n '--ts-ui-table-cell-height' : theme.table.cell.height,\n '--ts-ui-table-cell-bg' : theme.table.cell.background,\n '--ts-ui-table-cell-readonly-bg' : theme.table.cell.readonlyBackground,\n '--ts-ui-table-cell-range-selected' : theme.table.cell.rangeSelectedBackground,\n '--ts-ui-table-cell-required-outline' : theme.table.cell.requiredEmptyOutlineColor,\n '--ts-ui-table-cell-color' : theme.table.cell.color,\n '--ts-ui-table-cell-border' : theme.table.cell.border,\n '--ts-ui-table-cell-editor-border' : theme.table.cell.editorBorderColor,\n '--ts-ui-table-filter-row-bg' : theme.table.filterRow.background,\n '--ts-ui-table-resize-handle-width' : theme.table.resizeHandle.width,\n '--ts-ui-table-resize-handle-color' : theme.table.resizeHandle.color,\n '--ts-ui-table-resize-handle-cursor' : theme.table.resizeHandle.cursor,\n '--ts-ui-sort-badge-bg' : theme.table.sortBadge.background,\n '--ts-ui-sort-badge-color' : theme.table.sortBadge.color,\n '--ts-ui-sort-badge-font-size' : resolveFontSizeToken(theme.table.sortBadge.fontSize),\n '--ts-ui-filter-clause-badge-bg' : theme.table.filterClauseBadge.background,\n '--ts-ui-filter-clause-badge-color' : theme.table.filterClauseBadge.color,\n '--ts-ui-filter-clause-badge-font-size' : resolveFontSizeToken(theme.table.filterClauseBadge.fontSize),\n '--ts-ui-color-scheme' : theme.colorScheme,\n '--ts-ui-context-menu-bg' : theme.contextMenu.background,\n '--ts-ui-context-menu-border' : theme.contextMenu.border,\n '--ts-ui-context-menu-shadow' : theme.contextMenu.shadow,\n '--ts-ui-context-menu-item-hover-bg' : theme.contextMenu.item.hoverBackground,\n '--ts-ui-context-menu-item-disabled-color' : theme.contextMenu.item.disabledColor,\n '--ts-ui-context-menu-separator-color' : theme.contextMenu.separatorColor,\n '--ts-ui-tooltip-bg' : theme.tooltip.background,\n '--ts-ui-tooltip-color' : theme.tooltip.color,\n '--ts-ui-tooltip-border' : theme.tooltip.border,\n '--ts-ui-tooltip-shadow' : theme.tooltip.shadow,\n '--ts-ui-popover-bg' : theme.popover.background,\n '--ts-ui-popover-color' : theme.popover.color,\n '--ts-ui-popover-border' : theme.popover.border,\n '--ts-ui-popover-shadow' : theme.popover.shadow,\n '--ts-ui-popover-radius' : theme.popover.radius,\n '--ts-ui-popover-padding' : theme.popover.padding,\n '--ts-ui-popover-arrow-size' : theme.popover.arrowSize,\n '--ts-ui-notification-shadow' : theme.notification.shadow,\n '--ts-ui-notification-info-bg' : theme.notification.info.background,\n '--ts-ui-notification-info-border' : theme.notification.info.border,\n '--ts-ui-notification-success-bg' : theme.notification.success.background,\n '--ts-ui-notification-success-border' : theme.notification.success.border,\n '--ts-ui-notification-warning-bg' : theme.notification.warning.background,\n '--ts-ui-notification-warning-border' : theme.notification.warning.border,\n '--ts-ui-notification-error-bg' : theme.notification.error.background,\n '--ts-ui-notification-error-border' : theme.notification.error.border,\n '--ts-ui-validation-error-border' : theme.validation.error.border,\n '--ts-ui-validation-error-tooltip-bg' : theme.validation.error.tooltip.background,\n '--ts-ui-validation-error-tooltip-color' : theme.validation.error.tooltip.color,\n '--ts-ui-validation-error-tooltip-border' : theme.validation.error.tooltip.border,\n '--ts-ui-autocomplete-bg' : theme.autoComplete.background,\n '--ts-ui-autocomplete-border' : theme.autoComplete.border,\n '--ts-ui-autocomplete-shadow' : theme.autoComplete.shadow,\n '--ts-ui-autocomplete-item-hover-bg' : theme.autoComplete.item.hoverBackground,\n '--ts-ui-autocomplete-item-highlight-bg' : theme.autoComplete.item.highlightBackground,\n '--ts-ui-autocomplete-item-highlight-color': theme.autoComplete.item.highlightColor,\n '--ts-ui-autocomplete-item-disabled-color' : theme.autoComplete.item.disabledColor,\n '--ts-ui-list-bg' : theme.list.background,\n '--ts-ui-list-border' : theme.list.border,\n '--ts-ui-list-row-hover-bg' : theme.list.row.hoverBackground,\n '--ts-ui-list-row-selected-bg' : theme.list.row.selectedBackground,\n '--ts-ui-list-row-selected-color' : theme.list.row.selectedColor,\n '--ts-ui-list-row-focus-ring' : theme.list.row.focusRing,\n '--ts-ui-list-row-disabled-color' : theme.list.row.disabledColor,\n '--ts-ui-list-row-separator' : theme.list.row.separator,\n '--ts-ui-indicator-focus' : theme.indicator.focus,\n '--ts-ui-indicator-selection' : theme.indicator.selection,\n '--ts-ui-dropdown-fade-duration' : theme.dropdown.fade.duration,\n '--ts-ui-dropdown-fade-translate' : theme.dropdown.fade.translate,\n '--ts-ui-picker-nav-fg' : theme.picker.navForeground,\n '--ts-ui-picker-nav-hover-bg' : theme.picker.navHoverBackground,\n '--ts-ui-picker-cell-disabled-bg' : theme.picker.cellDisabledBackground,\n '--ts-ui-menu-bar-bg' : theme.menuBar.background,\n '--ts-ui-menu-bar-border' : theme.menuBar.border,\n '--ts-ui-menu-bar-btn-bg' : theme.menuBar.button.background,\n '--ts-ui-menu-bar-btn-hover-bg' : theme.menuBar.button.hoverBackground,\n '--ts-ui-menu-bar-btn-fg' : theme.menuBar.button.foreground,\n '--ts-ui-menu-bar-panel-bg' : theme.menuBar.panel.background,\n '--ts-ui-menu-bar-panel-border' : theme.menuBar.panel.border,\n '--ts-ui-menu-bar-panel-shadow' : theme.menuBar.panel.shadow,\n '--ts-ui-menu-bar-panel-min-width' : theme.menuBar.panel.minWidth,\n '--ts-ui-menu-bar-item-hover-bg' : theme.menuBar.item.hoverBackground,\n '--ts-ui-menu-bar-item-disabled-color' : theme.menuBar.item.disabledColor,\n '--ts-ui-menu-bar-item-shortcut-color' : theme.menuBar.item.shortcutColor,\n '--ts-ui-menu-bar-separator-color' : theme.menuBar.separatorColor,\n '--ts-ui-statusbar-bg' : theme.statusBar.background,\n '--ts-ui-statusbar-color' : theme.statusBar.color,\n '--ts-ui-statusbar-border' : theme.statusBar.border,\n '--ts-ui-statusbar-height' : theme.statusBar.height,\n '--ts-ui-statusbar-padding' : theme.statusBar.padding,\n '--ts-ui-toolbar-bg' : theme.toolBar.background,\n '--ts-ui-toolbar-border' : theme.toolBar.border,\n '--ts-ui-toolbar-padding' : theme.toolBar.padding,\n '--ts-ui-toolbar-gap' : theme.toolBar.gap,\n '--ts-ui-toolbar-separator-color' : theme.toolBar.separatorColor,\n '--ts-ui-dialog-backdrop-bg' : theme.dialog.backdrop.background,\n '--ts-ui-dialog-border' : theme.dialog.border,\n '--ts-ui-dialog-shadow' : theme.dialog.shadow,\n '--ts-ui-dialog-confirm-color' : theme.dialog.confirm,\n '--ts-ui-dialog-cancel-color' : theme.dialog.cancel,\n '--ts-ui-dialog-info-bg' : theme.dialog.info.background,\n '--ts-ui-dialog-info-fg' : theme.dialog.info.foreground,\n '--ts-ui-dialog-affirm-bg' : theme.dialog.affirm.background,\n '--ts-ui-dialog-affirm-fg' : theme.dialog.affirm.foreground,\n '--ts-ui-drawer-shadow' : theme.drawer.shadow,\n '--ts-ui-drawer-border' : theme.drawer.border,\n '--ts-ui-rail-border' : theme.rail.border,\n '--ts-ui-rail-shadow' : theme.rail.shadow,\n '--ts-ui-rail-handle-hover-bg' : theme.rail.handle.hoverBackground,\n '--ts-ui-rail-handle-selected-bg' : theme.rail.handle.selectedBackground,\n '--ts-ui-spinner-btn-width' : theme.spinner.buttonWidth,\n '--ts-ui-spinner-divider' : theme.spinner.dividerColor,\n '--ts-ui-progress-track-bg' : theme.progressBar.track.background,\n '--ts-ui-progress-track-radius' : theme.progressBar.track.borderRadius,\n '--ts-ui-progress-fill-bg' : theme.progressBar.fill.background,\n '--ts-ui-progress-indeterminate-bg' : theme.progressBar.indeterminate.background,\n '--ts-ui-progress-spinner-color' : theme.progressSpinner.color,\n '--ts-ui-progress-spinner-backdrop' : theme.progressSpinner.backdrop,\n '--ts-ui-progress-spinner-size' : theme.progressSpinner.size,\n '--ts-ui-glyph-spin-duration' : theme.glyph.spinDuration,\n '--ts-ui-glyph-pulse-duration' : theme.glyph.pulseDuration,\n '--ts-ui-glyph-beat-duration' : theme.glyph.beatDuration,\n '--ts-ui-drag-ghost-bg' : theme.drag.ghost.background,\n '--ts-ui-drag-ghost-border' : theme.drag.ghost.border,\n '--ts-ui-drag-ghost-shadow' : theme.drag.ghost.shadow,\n '--ts-ui-drag-ghost-opacity' : theme.drag.ghost.opacity,\n '--ts-ui-drag-feedback-valid-bg' : theme.drag.feedback.valid.background,\n '--ts-ui-drag-feedback-valid-border' : theme.drag.feedback.valid.border,\n '--ts-ui-drag-feedback-invalid-bg' : theme.drag.feedback.invalid.background,\n '--ts-ui-drag-feedback-invalid-border' : theme.drag.feedback.invalid.border,\n '--ts-ui-drag-reorder-color' : theme.drag.reorderIndicator.color,\n '--ts-ui-drag-dropzone-bg' : theme.drag.dropzone.background,\n '--ts-ui-drag-dropzone-border' : theme.drag.dropzone.border,\n '--ts-ui-drag-dropzone-active-bg' : theme.drag.dropzone.activeBackground,\n '--ts-ui-drag-dropzone-invalid-bg' : theme.drag.dropzone.invalidBackground,\n '--ts-ui-filedropzone-bg' : theme.fileDropZone.background,\n '--ts-ui-filedropzone-border' : theme.fileDropZone.border,\n '--ts-ui-filedropzone-active-bg' : theme.fileDropZone.activeBackground,\n '--ts-ui-filedropzone-active-border' : theme.fileDropZone.activeBorder,\n '--ts-ui-scroll-shadow-color' : theme.scroll.shadowColor,\n '--ts-ui-md-line-height' : theme.markdown.lineHeight,\n '--ts-ui-md-max-measure' : theme.markdown.maxMeasure,\n '--ts-ui-chart-axis' : theme.chart.axis,\n '--ts-ui-chart-grid' : theme.chart.grid,\n '--ts-ui-chart-label' : theme.chart.label,\n '--ts-ui-chart-selection' : theme.chart.selection,\n '--ts-ui-chart-line-width' : theme.chart.lineWidth,\n '--ts-ui-chart-axis-width' : theme.chart.axisWidth,\n '--ts-ui-chart-point-radius' : theme.chart.pointRadius,\n ...chartSeriesVars('--ts-ui-chart-series', theme.chart.series),\n };\n}\n\n/**\n * The Manrope subsets to register, pairing each bundled `.woff2` asset URL with\n * the `unicode-range` it covers. The URLs and ranges mirror the `index.css`\n * shipped by `@fontsource-variable/manrope`; the ranges are carried here\n * verbatim because the framework injects the `@font-face` rules from JS (see\n * {@link ensureFontLoaded}) rather than importing the package's stylesheet. Only\n * the Latin and Latin-Ext subsets are bundled — `unicode-range` still routes\n * each glyph to the right face, and codepoints outside these ranges fall back to\n * `sans-serif`.\n */\nconst MANROPE_SUBSETS: ReadonlyArray<{ url: string; unicodeRange: string }> = [\n { url: manropeLatinExtUrl, unicodeRange: 'U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF' },\n { url: manropeLatinUrl, unicodeRange: 'U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD' },\n];\n\n// The family every bundled subset is registered under. Shared by the injected\n// rules and the load kick-off, which have to name the same family to match.\nconst MANROPE_FAMILY = 'Manrope Variable';\n\n// Module-level guard so the @font-face block is injected exactly once, no matter\n// how many times setTheme runs. Mirrors Glyph.ts's _keyframesInjected pattern.\nlet _fontInjected = false;\n\n/**\n * Injects the bundled Manrope `@font-face` rules into `<head>` on first call.\n *\n * Idempotent — guarded by the module-level `_fontInjected` flag, mirroring\n * `Glyph.ts`'s keyframe injection. The face registers as `'Manrope Variable'`\n * (the value carried by the `font.family` theme token), spans the full 200–800\n * weight axis (Manrope's variable-font axis bounds, carried verbatim from the\n * package's `@font-face`), and uses `font-display: swap` so text stays visible\n * during the load. Each subset's `.woff2` is a Vite-bundled asset, so the font\n * self-hosts from the consumer's origin with no external request.\n *\n * @returns `true` when this call started an asynchronous font load, so the\n * caller can expect the font set to report back once it settles. `false` on\n * every later call (the rules are already installed) and wherever the active\n * `DOMSource` cannot load fonts asynchronously.\n */\nfunction ensureFontLoaded(): boolean {\n if (_fontInjected) {\n return false;\n }\n\n _fontInjected = true;\n\n const rules = MANROPE_SUBSETS.map(subset =>\n `@font-face{`\n + `font-family:'${MANROPE_FAMILY}';`\n + `font-style:normal;`\n + `font-display:swap;`\n + `font-weight:200 800;`\n + `src:url(${subset.url}) format('woff2-variations');`\n + `unicode-range:${subset.unicodeRange}`\n + `}`\n ).join('');\n\n const style = DOM.sink.createElement('style');\n DOM.sink.apply(style, { text: rules });\n DOM.sink.appendChild(DOM.source.getHead(), style);\n\n // The rules are live in the CSSOM now, but installing them fetches nothing:\n // a face is only downloaded and activated once rendered content uses it,\n // which would put that work after the entire first layout. Start it here\n // instead, so it runs while the component tree is still being built.\n return DOM.source.startFontLoad(MANROPE_FAMILY);\n}\n\n/**\n * Singleton manager that applies a theme by writing CSS custom properties and\n * inline styles onto the document root and body elements.\n *\n * @example\n * ```typescript\n * import { ThemeManager, ClassicTheme, DarkTheme } from '@jimka/typescript-ui/core';\n*\n * ThemeManager.setTheme(ClassicTheme); // classic light\n * ThemeManager.setTheme(DarkTheme); // dark\n * ```\n *\n * @category Theme\n */\nexport class ThemeManager {\n private static current: Theme = ModernTheme;\n private static resolvedScale: ResolvedScale = resolveScale(ModernTheme);\n private static themeListeners: Array<() => void> = [];\n\n /**\n * Subscribes a listener that is called whenever the active theme changes.\n *\n * @param listener - Called after CSS variables have been updated, so `getComputedStyle` returns new values.\n * @returns A cleanup function that removes the listener when called.\n */\n static onThemeChange(listener: () => void): () => void {\n ThemeManager.themeListeners.push(listener);\n return () => {\n ThemeManager.themeListeners = ThemeManager.themeListeners.filter(l => l !== listener);\n };\n }\n\n /** Number of currently-registered theme-change listeners; for tests only. @internal */\n static _themeListenerCount(): number {\n return ThemeManager.themeListeners.length;\n }\n\n /**\n * Applies a theme by writing CSS variables onto `:root` and updating body/html styles.\n *\n * @param theme - The theme object to activate.\n *\n * @remarks Sets `document.documentElement.style.colorScheme`, `color`, `fontFamily`,\n * `fontSize`, and `document.body.style.backgroundColor` / `color` in addition to the CSS\n * custom properties, so both CSS-variable consumers and direct inline-style consumers\n * are updated. `<html>` is targeted (in addition to `<body>`) because [`Window`](/api/overlay/classes/Window) components\n * are appended to `document.documentElement`, so text in floating windows must inherit\n * from `<html>`.\n */\n static setTheme(theme: Theme): void {\n const fontLoadStarted = ensureFontLoaded();\n\n ThemeManager.scheduleFontReflow();\n\n // Only a load that actually started will report back, so only that case\n // may hold the first layout — arming otherwise would leave the gate\n // shut until its deadline with nothing on the way to open it.\n if (fontLoadStarted) {\n holdFirstLayout();\n }\n\n ThemeManager.current = theme;\n ThemeManager.resolvedScale = resolveScale(theme);\n\n const rootStyle = new InlineStyle();\n rootStyle.setMany(themeToVars(theme));\n rootStyle.attach(DOM.source.getDocumentElement());\n\n DOM.sink.apply(DOM.source.getDocumentElement(), {\n style: {\n colorScheme: theme.colorScheme,\n color: theme.text.color,\n fontFamily: theme.font.family,\n fontSize: theme.font.size ?? '14px', // mirrors BaseTheme.font.size; font.size is optional\n lineHeight: `calc(1em + ${theme.font.linePadding})`,\n },\n });\n DOM.sink.apply(DOM.source.getBody(), {\n style: {\n backgroundColor: theme.body.background,\n color: theme.text.color,\n },\n });\n\n ThemeManager.reflowText();\n }\n\n // Guards the `onFontsReady` subscription across repeated setTheme calls —\n // one subscription per process, not one per theme.\n private static fontReflowScheduled = false;\n\n /**\n * Subscribes a re-measure that runs whenever web-font loading settles.\n * Text measured against the fallback font before a `font-display: swap`\n * swap-in caches a stale preferred size; refreshing the metrics and\n * re-flowing every subscribed Text corrects boxes that would otherwise clip\n * the wider real glyphs (e.g. content-sized tab labels). The callback may\n * fire more than once — a page can load faces in several batches — and each\n * fire is idempotent.\n */\n private static scheduleFontReflow(): void {\n if (ThemeManager.fontReflowScheduled) {\n return;\n }\n\n ThemeManager.fontReflowScheduled = true;\n DOM.source.onFontsReady(ThemeManager.onFontsSettled);\n }\n\n /**\n * Runs when a batch of web-font loading settles: refreshes the text metrics,\n * then opens the startup layout gate so the first flush measures against the\n * face that just activated.\n *\n * @remarks The order is load-bearing. `reflowText` marks every cached text\n * size stale and re-queues the subscribed components; releasing first would\n * let the freed flush run against the sizes measured before activation, and\n * with nothing queued to lay out.\n */\n private static onFontsSettled(): void {\n ThemeManager.reflowText();\n releaseFirstLayout();\n }\n\n /**\n * Invalidates the cached text-measurement metrics and notifies every\n * subscribed listener so each Text re-measures against the current font and\n * scale. Shared by {@link setTheme} and the font-load reflow.\n */\n private static reflowText(): void {\n Util.invalidateTextMetricsCache();\n\n ThemeManager.themeListeners.forEach(l => l());\n }\n\n /**\n * Returns the currently active theme.\n *\n * @returns The `Theme` object that was last passed to `setTheme`, defaulting to [`ModernTheme`](/api/core/variables/ModernTheme).\n */\n static getTheme(): Theme {\n return ThemeManager.current;\n }\n\n /**\n * Returns the active theme's `scale` block resolved to px numbers — the snapshot\n * computed by the last `setTheme` (defaulting to [`ModernTheme`](/api/core/variables/ModernTheme)'s).\n * Layout code reads these numbers directly instead of resolving a {@link ScaleToken}\n * per pass; a base or token change re-resolves on the next `setTheme`.\n *\n * @returns The resolved scale snapshot for the active theme.\n */\n static getResolvedScale(): ResolvedScale {\n return ThemeManager.resolvedScale;\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\n// Internal helper backing `Component._defaultOptions`. Not exported from\n// `core/index.ts` — this module exists purely to give every concrete\n// `Component` subclass one shared, frozen defaults bag instead of a fresh\n// object literal per instance. See\n// plans/implemented/per-class-component-defaults.md for the rationale.\n\nimport { UNBOUNDED } from \"~/primitive/Size.js\";\nimport { Insets } from \"~/primitive/Insets.js\";\n\nconst ZERO_INSETS = Object.freeze(new Insets(0, 0, 0, 0));\nconst ZERO_MIN_SIZE = Object.freeze({ width: 0, height: 0 });\nconst UNBOUNDED_MAX = Object.freeze({ width: UNBOUNDED, height: UNBOUNDED });\n\nconst BASE_DEFAULTS = Object.freeze({\n cursor : \"default\",\n // Framework-wide \"chrome is not selectable\" default, the peer of `cursor`\n // above: `getUserSelect()` folds `_defaultOptions` and is read at render by\n // `applyMiscInlineStyles`, so the base value has to live here rather than in\n // a constructor seed — otherwise every stock component reports null and the\n // `:where(.ts-ui-component)` rule's `user-select: none` is the only thing\n // holding the behaviour up. A class that wants selectable text overrides it\n // through its own defaults bag (see `SelectableText`, `Link`, `Markdown`).\n userSelect: \"none\",\n insets : ZERO_INSETS,\n minSize : ZERO_MIN_SIZE,\n maxSize : UNBOUNDED_MAX,\n // `hidden` is deliberate and load-bearing beyond just clipping: it\n // visually EXPOSES layout-calculation bugs. When a layout lays a\n // child out larger than the box its parent sized for it — i.e. when\n // `getPreferredSize`/`getMinSize` under-report what `doLayout`\n // actually produces — the overflow is clipped rather than silently\n // spilling, so the size-negotiation mistake shows up on screen\n // instead of hiding. Don't relax this to \"fix\" a clip; find the\n // preferred-vs-doLayout discrepancy it revealed.\n overflow : \"hidden\",\n zIndex : 0,\n displayed : true,\n});\n\ninterface CacheEntry { bag: object; keys: string[]; }\n\n// Keyed on the class constructor itself, not `constructor.name` — class\n// names are not unique in this tree (e.g. `class Body` is declared twice)\n// and a name key would also depend on minifier `keepNames` settings. See\n// the plan's `[^ctor-key]` footnote.\nconst cache = new Map<Function, CacheEntry>();\n\n/**\n * Returns `true` when `supplied` carries exactly the same defaulted keys as\n * `entry`, each equal by reference/value to what `entry.bag` already holds —\n * i.e. `entry.bag` is safe to reuse for this construction. The length check\n * matters: without it, a class that supplies a key on one construction and\n * omits it on the next would silently inherit the stale value from the\n * cached bag.\n */\nfunction matches(entry: CacheEntry, supplied: Record<string, unknown>, keys: string[]): boolean {\n if (entry.keys.length !== keys.length) {\n return false;\n }\n\n return keys.every(key => (entry.bag as Record<string, unknown>)[key] === supplied[key]);\n}\n\n/**\n * Resolves the shared, frozen `_defaultOptions` bag for a `Component`\n * subclass, caching the first bag built for each class constructor so every\n * later instance of that class reuses the same object instead of allocating\n * a fresh literal.\n *\n * @param ctor - The concrete class constructor (`this.constructor` from the\n * `Component` constructor), used as the cache key.\n * @param subclassDefaults - The subclass's own default bag, as passed to\n * `super(options, subclassDefaults)`. `layoutManager` is excluded from both\n * the cache key and the returned bag — it never shares across instances,\n * see `Component._defaultLayoutManager`.\n *\n * @returns A frozen defaults bag: the base `Component` defaults overlaid\n * with `subclassDefaults`. Reused across instances of the same class when\n * `subclassDefaults` is identical to the first construction's; a class\n * whose `subclassDefaults` vary per instance (e.g. `Panel`'s `flush`\n * option) gets its own private frozen bag on a mismatch, without\n * disturbing the cached entry.\n */\nexport function resolveClassDefaults<TOptions>(\n ctor: Function,\n subclassDefaults: Partial<TOptions> | undefined,\n): Readonly<TOptions> {\n const supplied = (subclassDefaults ?? {}) as Record<string, unknown>;\n const keys = Object.keys(supplied).filter(k => k !== \"layoutManager\");\n const entry = cache.get(ctor);\n\n if (entry && matches(entry, supplied, keys)) {\n return entry.bag as Readonly<TOptions>;\n }\n\n const bag: Record<string, unknown> = { ...BASE_DEFAULTS };\n for (const key of keys) {\n bag[key] = supplied[key];\n }\n Object.freeze(bag);\n\n if (!entry) {\n cache.set(ctor, { bag, keys });\n }\n\n return bag as Readonly<TOptions>;\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\n// Internal helper backing Component's three-tier style-rule split (framework\n// / class / instance). Not exported from `core/index.ts` — this module\n// exists purely to derive and register the framework-wide and per-class\n// shared `StyleRule`s that `Component.applyStyle` consults through\n// `writeRuleDeclaration`. See\n// plans/implemented/class-scoped-style-rules.md for the rationale.\n//\n// Also backs Button/ToggleButton's state-rule (`.pressed` / `:hover` /\n// `.selected`) dedup, via the `ensureClassStateRule` / `writeClassStateDeclaration`\n// / `writeManyClassStateDeclarations` sibling mechanism below — see\n// plans/implemented/hoist-button-tabbar-state-chrome-rules.md. This module\n// also exposes `StateStyleRule`, the wrapper `Component.createStateStyleRule`\n// returns — see plans/implemented/state-style-rule-auto-dedup.md.\n\nimport { StyleRule } from \"~/core/StyleTarget.js\";\nimport { DOM } from \"~/core/DOM.js\";\nimport { Position } from \"~/primitive/Position.js\";\nimport { isUnbounded } from \"~/primitive/Size.js\";\nimport { type BorderOptions, borderToStyle } from \"~/primitive/Border.js\";\n\n/** The CSS class every rendered component element carries. */\nexport const COMPONENT_CLASS = \"ts-ui-component\";\n\n// `:where()` computes to zero specificity, so both `.ClassName` and `#id`\n// outrank this rule whatever order the sheet ends up in.\nconst FRAMEWORK_SELECTOR = \":where(.\" + COMPONENT_CLASS + \")\";\n\n/**\n * The class-default fields a rule body is derived from — the subset of\n * `Component._defaultOptions` that feeds the hoistable declarations, some\n * unconditional and some (the chrome group and `font`) only present when the\n * class actually defaults them. Typed structurally rather than as\n * `ComponentOptions` so this module does not import from `core/Component.ts`\n * and no import cycle forms.\n */\nexport interface ClassStyleDefaults {\n visible?: boolean | null;\n displayed?: boolean;\n minSize?: { width: number; height: number } | null;\n maxSize?: { width: number; height: number } | null;\n overflow?: string | null;\n cursor?: string | null;\n userSelect?: string | null;\n outline?: string | null;\n foregroundColor?: string | null;\n font?: TextClassStyleDefaults | null;\n backgroundColor?: string | null;\n backgroundImage?: string | null;\n shadow?: string | null;\n borderRadius?: string | null;\n border?: BorderOptions | string | null;\n}\n\n/**\n * The class-uniform font/text declarations a `Text`-family class produces\n * from its own defaults alone. Namespaced under `ClassStyleDefaults.font`\n * rather than added as flat keys: `Glyph` (component/display/Glyph.ts),\n * `TabBar` (component/container/TabBar.ts), and `TextInput`\n * (component/input/TextInput.ts) each declare their own, differently-typed\n * `fontSize`/`lineHeight`/`textAlign` options — flat keys of the same name\n * would silently leak their unrelated defaults into this bag, since\n * `Component.applyStyle`'s default `getClassStyleDefaults()` passes\n * `_defaultOptions` through verbatim for every class that doesn't override\n * it. Only `Text.getClassStyleDefaults()` ever sets `font`.\n */\ninterface TextClassStyleDefaults {\n fontFamily?: string | null;\n fontKerning?: string | null;\n fontSize?: string | null; // CSS-ready value, e.g. \"var(--ts-ui-font-size, 14px)\"\n fontSizeAdjust?: string | null;\n fontStretch?: string | null;\n fontStyle?: string | null;\n fontVariant?: string | null;\n fontWeight?: string | null;\n textAlign?: string | null;\n textShadow?: string | null;\n lineHeight?: string | null; // CSS-ready value, e.g. \"calc(1em + var(--ts-ui-line-padding, 2px))\"\n textOverflow?: string | null; // pre-resolved from `truncate`; see Text.getClassStyleDefaults\n}\n\ntype ClassStyleBag = Readonly<Record<string, string | null>>;\n\n// The fifteen hoistable keys at the value Component's own defaults resolve to.\nconst FRAMEWORK_DECLARATIONS: ClassStyleBag = Object.freeze({\n boxSizing: \"border-box\",\n position: Position.ABSOLUTE,\n display: \"block\",\n visibility: \"inherit\",\n whiteSpace: \"nowrap\",\n userSelect: \"none\",\n cursor: \"default\",\n border: null,\n margin: \"0px 0px 0px 0px\",\n minWidth: \"0px\",\n minHeight: \"0px\",\n maxWidth: \"none\",\n maxHeight: \"none\",\n overflowX: \"hidden\",\n overflowY: \"hidden\",\n});\n\n// The `ClassStyleDefaults` input that reproduces `FRAMEWORK_DECLARATIONS` via\n// `resolveDeclarations` — i.e. `Component`'s own true base defaults, used as\n// the hierarchy walk's base case (the \"ancestor\" above `Component` itself).\n// Every hoistable field's absent-value fallback inside `resolveDeclarations`\n// already coincides with `FRAMEWORK_DECLARATIONS` *except* `minSize` and\n// `overflow`, whose fallbacks (`\"auto\"` / `\"visible\"`) diverge from the\n// framework's hoisted baseline (`\"0px\"` / `\"hidden\"`) — those two are\n// restated here so a participating class that leaves them untouched (e.g.\n// `Cell`, which customises only colour/background/border) still resolves\n// them to the framework baseline instead of spuriously \"deviating\" on them,\n// matching what an un-migrated (flat) class's own `_defaultOptions` merge\n// chain already produces automatically via `Component`'s real base bag.\nconst FRAMEWORK_DEFAULTS: ClassStyleDefaults = Object.freeze({\n minSize: { width: 0, height: 0 },\n overflow: \"hidden\",\n});\n\n// Per-class inherited declarations: the framework body with this class's\n// deviations merged over it. A `null` entry means the class opted out (its\n// selector is owned by a different constructor, or it is anonymous).\nconst _bags: Map<Function, ClassStyleBag | null> = new Map();\n\n// Selector owner, so a name shared by two classes is detected.\nconst _owners: Map<string, Function> = new Map();\n\n// The `Component` class itself, registered once by `core/Component.ts` at\n// module load via `registerStyleChainRoot` — this module cannot import\n// `Component` directly (it would form an import cycle, since Component\n// imports this module). Every hierarchy walk (`resolveClassLevel`,\n// `getStyleClassChain`) treats this constructor as the top: it never\n// recurses past it (so `BaseObject` and anything above are never visited),\n// and its own name never joins a DOM class list or claims a `.ClassName`\n// rule — `Component` was never a meaningful CSS-styling target before this\n// plan (only a concrete subclass's `this.constructor.name` was ever added),\n// and this mechanism preserves that.\nlet _rootCtor: Function | null = null;\n\n/**\n * Registers the topmost class the hierarchy walk should ever visit. Called\n * once, by `core/Component.ts` at module load. Canonicalized (see\n * `canonicalCtor`) so it matches regardless of whether the caller passes the\n * raw class or its `callable()` wrapper.\n */\nexport function registerStyleChainRoot(ctor: Function): void {\n _rootCtor = canonicalCtor(ctor);\n}\n\nlet _frameworkRuleCreated = false;\n\nfunction ensureFrameworkStyleRule(): void {\n if (_frameworkRuleCreated) {\n return;\n }\n\n _frameworkRuleCreated = true;\n\n new StyleRule({ scope: \"selector\", name: FRAMEWORK_SELECTOR, styles: { ...FRAMEWORK_DECLARATIONS } });\n}\n\n/**\n * The declarations an instance of this class produces from defaults alone. A\n * key the phase would *not* write gets the value that reproduces \"no\n * declaration\", so the framework rule's value is undone rather than inherited.\n *\n * Exported (module otherwise stays internal) so `core/Component.ts`'s\n * `resolveInstanceStyleDeclarations` can reuse it unchanged to resolve one\n * *instance's* own hoistable style for `ensureStyleGroupRule`, instead of a\n * class's plain `getClassStyleDefaults()` bag — see\n * plans/implemented/shared-instance-style-groups.md.\n */\nexport function resolveDeclarations(defaults: ClassStyleDefaults): Record<string, string | null> {\n const minSize = defaults.minSize ?? null;\n const maxSize = defaults.maxSize ?? null;\n const overflow = defaults.overflow ?? null;\n\n const declarations: Record<string, string | null> = {\n boxSizing: \"border-box\",\n position: Position.ABSOLUTE,\n display: (defaults.displayed ?? true) ? \"block\" : \"none\",\n visibility: (defaults.visible ?? null) === false ? \"hidden\" : \"inherit\",\n whiteSpace: \"nowrap\",\n userSelect: defaults.userSelect ?? \"none\",\n cursor: defaults.cursor ?? \"default\",\n border: null,\n margin: \"0px 0px 0px 0px\",\n minWidth: minSize ? minSize.width + \"px\" : \"auto\",\n minHeight: minSize ? minSize.height + \"px\" : \"auto\",\n maxWidth: maxSize ? (isUnbounded(maxSize.width) ? \"none\" : maxSize.width + \"px\") : \"none\",\n maxHeight: maxSize ? (isUnbounded(maxSize.height) ? \"none\" : maxSize.height + \"px\") : \"none\",\n overflowX: overflow ?? \"visible\",\n overflowY: overflow ?? \"visible\",\n };\n\n // outline/color are conditional: most classes declare neither, and\n // Component only ever writes them when non-null (see applyChromeStyles /\n // applyBoxAndVisibilityStyles), so an absent key here must stay absent —\n // never introduce a key with value `undefined`.\n if (defaults.outline) declarations.outline = defaults.outline;\n if (defaults.foregroundColor) declarations.color = defaults.foregroundColor;\n\n if (defaults.backgroundColor) declarations.backgroundColor = defaults.backgroundColor;\n if (defaults.backgroundImage) declarations.backgroundImage = defaults.backgroundImage;\n if (defaults.shadow) declarations.boxShadow = defaults.shadow;\n if (defaults.borderRadius) declarations.borderRadius = defaults.borderRadius;\n\n const border = defaults.border;\n if (border) {\n // `borderToStyle` always yields all four longhands, resolving each side\n // through `side ?? border ?? \"none\"` — the same expansion Component's own\n // border writers use, so the two tiers compare key for key.\n Object.assign(declarations, borderToStyle(typeof border === \"string\" ? { border } : border));\n }\n\n const font = defaults.font;\n if (font?.fontFamily) declarations.fontFamily = font.fontFamily;\n if (font?.fontKerning) declarations.fontKerning = font.fontKerning;\n if (font?.fontSize) declarations.fontSize = font.fontSize;\n if (font?.fontSizeAdjust) declarations.fontSizeAdjust = font.fontSizeAdjust;\n if (font?.fontStretch) declarations.fontStretch = font.fontStretch;\n if (font?.fontStyle) declarations.fontStyle = font.fontStyle;\n if (font?.fontVariant) declarations.fontVariant = font.fontVariant;\n if (font?.fontWeight) declarations.fontWeight = font.fontWeight;\n if (font?.textAlign) declarations.textAlign = font.textAlign;\n if (font?.textShadow) declarations.textShadow = font.textShadow;\n if (font?.lineHeight) declarations.lineHeight = font.lineHeight;\n if (font?.textOverflow) declarations.textOverflow = font.textOverflow;\n\n return declarations;\n}\n\n/** The subset of `resolveDeclarations` that differs from the framework rule. */\nfunction classDeviations(defaults: ClassStyleDefaults): Record<string, string | null> {\n const resolved = resolveDeclarations(defaults);\n const out: Record<string, string | null> = {};\n\n for (const key of Object.keys(resolved)) {\n if (resolved[key] !== FRAMEWORK_DECLARATIONS[key]) {\n out[key] = resolved[key];\n }\n }\n\n return out;\n}\n\n/**\n * A class's own, subclass-independent contribution to the hoistable style\n * defaults — the same shape as `ClassStyleDefaults`, but declared once per\n * class (not resolved per instance). A class that adds no hoistable default\n * of its own declares no field at all; `Component` declares none.\n *\n * Read only via an own-property check (`Object.prototype.hasOwnProperty`) —\n * never via a plain property read, which would report an inherited value\n * from whichever ancestor last declared the field. See\n * plans/implemented/class-hierarchy-cascade.md's Architecture Decisions.\n */\ninterface ClassStyleLevelHost {\n ownClassStyleDefaults?: ClassStyleDefaults;\n}\n\n/**\n * Normalizes a constructor reference — the raw class or its `callable()`\n * wrapper — to the same canonical (raw) reference, via\n * `ctor.prototype.constructor`. A `callable()` Proxy only traps `apply`;\n * every other operation (including a `prototype` read) forwards to the\n * wrapped target by default, and `callable()` never reassigns\n * `prototype.constructor`, so this always lands on the original class\n * regardless of which reference was passed in.\n *\n * This matters because the *same* conceptual class is reached through\n * *different* references depending on the path: `this.constructor` (an\n * instance's own leaf class) is always raw, but `Object.getPrototypeOf` on a\n * subclass returns whatever reference appeared in that subclass's `extends`\n * clause — always the callable, per ARCHITECTURE.md's \"Imports always use\n * the callable name... This holds even for extends clauses.\" Without\n * normalizing, a class constructed directly (raw reference) and the same\n * class reached as a subclass's ancestor (callable reference) would be keyed\n * under two different `Map` entries, silently splitting its registration and\n * defeating the `_owners` name-collision check.\n */\nfunction canonicalCtor(ctor: Function): Function {\n const proto = (ctor as { prototype?: { constructor?: Function } }).prototype;\n\n return proto?.constructor ?? ctor;\n}\n\n/** This class's fully-merged declaration bag plus the resolved CSS it\n * produces — see {@link resolveClassLevel}. */\ninterface ResolvedClassLevel {\n /** This class's fully-merged `ClassStyleDefaults` — its own contribution\n * layered onto every ancestor's, in the same shape `resolveDeclarations`\n * consumes. */\n defaults: ClassStyleDefaults;\n /** `resolveDeclarations(defaults)` — this class's full resolved CSS bag,\n * used both to diff the next level down and, at the leaf, as the\n * instance-comparison bag `_inheritedStyleBag` needs. */\n resolved: ClassStyleBag;\n}\n\n// (ctor -> resolved level). Memoizes the hierarchy walk so a deep chain is\n// only ever traversed once per constructor across the whole process.\nconst _levels: Map<Function, ResolvedClassLevel> = new Map();\n\n/**\n * Own-property read of a class's `ownClassStyleDefaults` field — `null` when\n * this exact class doesn't declare one, regardless of what an ancestor\n * declares. A plain property read would silently return the nearest\n * ancestor's field once any ancestor defines one (normal JS static-member\n * inheritance), making every subclass that doesn't override it look like it\n * declares its parent's fields all over again — exactly wrong for a delta\n * computation.\n */\nfunction ownDefaultsOf(ctor: Function): ClassStyleDefaults | null {\n return Object.prototype.hasOwnProperty.call(ctor, \"ownClassStyleDefaults\")\n ? ((ctor as unknown as ClassStyleLevelHost).ownClassStyleDefaults ?? null)\n : null;\n}\n\n/** Shallow merge — a subclass that redeclares `border` or `font` replaces\n * the whole sub-value, matching how `_default<Name>Options` bags already\n * merge through `subclassDefaults` object-spread forwarding. */\nfunction mergeClassStyleDefaults(parent: ClassStyleDefaults, child: ClassStyleDefaults): ClassStyleDefaults {\n return { ...parent, ...child };\n}\n\n/** The subset of `resolved` that differs from `against` — `classDeviations`,\n * generalised to diff against any resolved bag, not only the framework one. */\nfunction deviationsFrom(resolved: ClassStyleBag, against: ClassStyleBag): Record<string, string | null> {\n const out: Record<string, string | null> = {};\n\n for (const key of Object.keys(resolved)) {\n if (resolved[key] !== against[key]) {\n out[key] = resolved[key];\n }\n }\n\n return out;\n}\n\n/**\n * Whether `ctor` or any ancestor up its `Object.getPrototypeOf` chain\n * declares an `ownClassStyleDefaults` field. A class outside this set is\n * untouched by this hierarchy mechanism — `ensureClassStyleRule` falls back\n * to its pre-hierarchy flat behaviour for it, since only a participating\n * chain's static fields can be trusted to reproduce a caller-supplied\n * instance's actual defaults (see `ensureClassStyleRule`'s own comment).\n */\nfunction chainParticipates(ctor: Function): boolean {\n let cur: Function | null = canonicalCtor(ctor);\n\n while (typeof cur === \"function\" && cur.name) {\n if (ownDefaultsOf(cur) !== null) {\n return true;\n }\n\n const parent = Object.getPrototypeOf(cur) as Function | null;\n\n cur = parent ? canonicalCtor(parent) : null;\n }\n\n return false;\n}\n\n/**\n * Hierarchy-aware resolution of `ctor`'s class-tier declarations. Walks\n * `Object.getPrototypeOf(ctor)` upward, resolving (and, for a class that owns\n * a genuine deviation, inserting) each ancestor's `.ClassName` rule before\n * this class's own — so a plain, unweighted `.ClassName` selector is always\n * correct with no `:where()` needed between hierarchy levels (an ancestor's\n * rule is always in the stylesheet before a descendant's by the time either\n * could match a rendered element). Memoized per `ctor`.\n *\n * A class with no own contribution (`ownDefaultsOf` returns null) resolves to\n * exactly its parent's level — no new rule, no new cache work beyond\n * memoizing the pass-through. Every level, participating or not, still claims\n * its own name in `_owners` (when unclaimed) so a later same-named class is\n * detected as colliding even if this level itself inserted no rule.\n */\nfunction resolveClassLevel(rawCtor: Function): ResolvedClassLevel {\n const ctor = canonicalCtor(rawCtor);\n const cached = _levels.get(ctor);\n\n if (cached) {\n return cached;\n }\n\n // `_rootCtor` (Component) is a terminal node for this walk — never\n // recurse above it, regardless of which class the walk started from.\n const rawParentCtor = ctor === _rootCtor ? null : (Object.getPrototypeOf(ctor) as Function | null);\n const parentCtor = rawParentCtor ? canonicalCtor(rawParentCtor) : null;\n const parent = (typeof parentCtor === \"function\" && parentCtor.name)\n ? resolveClassLevel(parentCtor)\n : { defaults: FRAMEWORK_DEFAULTS, resolved: FRAMEWORK_DECLARATIONS };\n\n const name = ctor.name;\n const owner = _owners.get(name);\n const collides = !name || (owner !== undefined && owner !== ctor);\n\n const own = collides ? null : ownDefaultsOf(ctor);\n\n if (!own) {\n const level = { defaults: parent.defaults, resolved: parent.resolved };\n\n _levels.set(ctor, level);\n\n if (!collides && name) {\n _owners.set(name, ctor);\n }\n\n return level;\n }\n\n ensureFrameworkStyleRule();\n _owners.set(name, ctor);\n\n const defaults = mergeClassStyleDefaults(parent.defaults, own);\n const resolved = resolveDeclarations(defaults);\n const deviations = deviationsFrom(resolved, parent.resolved);\n\n if (Object.keys(deviations).length > 0) {\n new StyleRule({ scope: \"class\", name, styles: deviations });\n }\n\n const level = Object.freeze({ defaults, resolved: Object.freeze(resolved) });\n\n _levels.set(ctor, level);\n\n return level;\n}\n\n/** A class's own resolved declarations for one state suffix — see\n * {@link resolveClassStateLevel}. */\ninterface ResolvedClassStateLevel {\n resolved: ClassStyleBag;\n}\n\n/** A `protected static` extraction method's shape — e.g.\n * `Button.extractPressedClassDeclarations`. Takes a plain defaults bag\n * (never an instance) so the hierarchy walk can call it against any\n * ancestor's own `ownClassStyleDefaults`, not just a live instance's\n * merged `_defaultOptions`. */\ntype StaticExtractor = (defaults: ClassStyleDefaults) => Record<string, string | null>;\n\n// (ctor -> (suffix -> resolved level)). State-tier sibling of `_levels`,\n// memoizing `resolveClassStateLevel`'s walk per class *and* per suffix,\n// since one class can own several state rules (Button: .pressed,\n// :hover:not(.pressed)).\nconst _stateLevels: Map<Function, Map<string, ResolvedClassStateLevel>> = new Map();\n\n/**\n * Hierarchy-aware resolution of `ctor`'s class-tier declarations for one\n * state suffix (`.pressed`, `.selected:not(:hover)`, …) — the state-tier\n * sibling of {@link resolveClassLevel}, mirroring its recursive shape\n * (resolve the parent first, merge this level's own contribution over it,\n * diff, insert only a genuine deviation) and reusing its `_owners`\n * collision registry, so a name claimed by one tier is respected by the\n * other regardless of which one claims it first.\n *\n * The one place this walk cannot simply reuse {@link resolveClassLevel}'s\n * shape verbatim: \"this level's own contribution\" is not a fixed field\n * (`ownClassStyleDefaults`) but a *named* `protected static` method\n * (`extractorMethodName`) that only some levels declare, and — critically —\n * whether a level declares a *resting*-tier `ownClassStyleDefaults` is\n * independent of whether it declares a *state*-tier extractor for a given\n * suffix (`ToggleButton` declares `extractSelectedClassDeclarations` but no\n * `ownClassStyleDefaults` of its own — it contributes nothing new to the\n * resting tier, see `button-family-hierarchy-cascade.md`'s Architecture\n * Decisions). Gating a level's own contribution on `ownClassStyleDefaults`\n * being non-null (as well as owning the extractor) would therefore wrongly\n * report `ToggleButton` as having no `.selected` contribution at all. The\n * own-property check on `extractorMethodName` is the *sole* gate for\n * whether this level contributes; `ownDefaultsOf(ctor) ?? {}` is only the\n * *argument* handed to that extractor (empty when this level has no\n * resting-tier defaults of its own to read from) — never a second\n * precondition.\n */\nfunction resolveClassStateLevel(\n rawCtor: Function,\n suffix: string,\n extractorMethodName: string,\n): ResolvedClassStateLevel {\n const ctor = canonicalCtor(rawCtor);\n\n let bySuffix = _stateLevels.get(ctor);\n if (!bySuffix) {\n bySuffix = new Map();\n _stateLevels.set(ctor, bySuffix);\n }\n\n const cached = bySuffix.get(suffix);\n if (cached) {\n return cached;\n }\n\n // `_rootCtor` (Component) is a terminal node for this walk too, exactly\n // like `resolveClassLevel` — Component and whatever it extends never\n // declare a state extractor, so there is nothing to gain by walking\n // further, and stopping here keeps the two tiers' walks symmetric.\n const rawParentCtor = ctor === _rootCtor ? null : (Object.getPrototypeOf(ctor) as Function | null);\n const parentCtor = rawParentCtor ? canonicalCtor(rawParentCtor) : null;\n const parent = (typeof parentCtor === \"function\" && parentCtor.name)\n ? resolveClassStateLevel(parentCtor, suffix, extractorMethodName)\n : { resolved: Object.freeze({}) as ClassStyleBag };\n\n const name = ctor.name;\n const owner = _owners.get(name);\n const collides = !name || (owner !== undefined && owner !== ctor);\n\n // Own-property checked, exactly like `ownDefaultsOf` — a level that\n // doesn't declare `extractorMethodName` itself contributes nothing for\n // this suffix, regardless of what an ancestor or a same-named method\n // inherited from further up the static prototype chain would answer.\n const hasOwnExtractor = !collides && Object.prototype.hasOwnProperty.call(ctor, extractorMethodName);\n const own: Record<string, string | null> = hasOwnExtractor\n ? (ctor as unknown as Record<string, StaticExtractor>)[extractorMethodName](ownDefaultsOf(ctor) ?? {})\n : {};\n\n if (Object.keys(own).length === 0) {\n const level = { resolved: parent.resolved };\n\n bySuffix.set(suffix, level);\n\n // Every level, participating or not, still claims its own name in\n // `_owners` (when unclaimed) so a later same-named class is\n // detected as colliding even if this level itself inserted no\n // rule — mirrors `resolveClassLevel`'s pass-through branch.\n if (!collides && name) {\n _owners.set(name, ctor);\n }\n\n return level;\n }\n\n const resolved = { ...parent.resolved, ...own };\n const deviations = deviationsFrom(resolved, parent.resolved);\n\n _owners.set(name, ctor);\n if (Object.keys(deviations).length > 0) {\n new StyleRule({ scope: \"class\", name, suffix, styles: deviations });\n }\n\n const level = Object.freeze({ resolved: Object.freeze(resolved) });\n\n bySuffix.set(suffix, level);\n\n return level;\n}\n\n/**\n * Ensures the framework-wide `:where(.ts-ui-component)` rule exists and,\n * when `ctor`'s resolved defaults deviate from it, ensures a `.ClassName`\n * rule carrying only those deviations. Idempotent per `ctor` — the first\n * call for a class computes and registers the rule(s); every later call\n * (including from other instances of the same class) returns the cached\n * result without touching the stylesheet again.\n *\n * For a class participating in the hierarchy mechanism (`ctor` or an\n * ancestor declares `ownClassStyleDefaults`), the returned bag is\n * `resolveClassLevel(ctor).resolved` — a delta against the nearest\n * ancestor's rule rather than the framework tier directly, so a subclass\n * that changes nothing shares its ancestor's rule instead of repeating it.\n * A class outside the hierarchy mechanism falls back to the original flat\n * behaviour: `defaults` (the caller's own fully-merged\n * `getClassStyleDefaults()` result) diffed directly against\n * `FRAMEWORK_DECLARATIONS`, unchanged from before this mechanism existed —\n * this is what keeps every not-yet-migrated class, and any subclass that\n * customises a hoistable field without registering its own\n * `ownClassStyleDefaults`, exactly as correct as it was before.\n *\n * @param ctor - The concrete component class constructor (`this.constructor`\n * from `Component`), used as the cache key. `ctor.name` is not unique in\n * this tree, so the constructor itself — not its name — is what identifies\n * the class; the name is only used to derive the CSS selector.\n * @param defaults - The class's frozen `_defaultOptions` bag (or a\n * structurally-compatible subset of it) — for a participating class, must\n * agree with its `ownClassStyleDefaults` chain (see\n * plans/implemented/class-hierarchy-cascade.md's Internal Structure).\n *\n * @returns The inherited declaration bag — the framework declarations with\n * this class's (and, for a participating class, every ancestor's)\n * deviations merged over them, mirroring what the cascade delivers to one\n * of its elements from the lower tiers. `null` when `ctor`'s name is empty\n * (an anonymous class) or already claimed by a different constructor — the\n * name-collision opt-out — in which case the caller must write every\n * hoistable declaration to its own `#id` rule.\n */\nexport function ensureClassStyleRule(\n rawCtor: Function,\n defaults: ClassStyleDefaults,\n): ClassStyleBag | null {\n const ctor = canonicalCtor(rawCtor);\n const existing = _bags.get(ctor);\n\n if (existing !== undefined) {\n return existing;\n }\n\n ensureFrameworkStyleRule();\n\n const name = ctor.name;\n const owner = _owners.get(name);\n\n if (!name || (owner !== undefined && owner !== ctor)) {\n _bags.set(ctor, null);\n\n return null;\n }\n\n if (!chainParticipates(ctor)) {\n const deviations = classDeviations(defaults);\n\n // Claim the selector whether or not a rule is inserted, so a second\n // class of the same name still opts out. An empty body would insert\n // a rule that declares nothing, so skip it.\n _owners.set(name, ctor);\n\n if (Object.keys(deviations).length > 0) {\n new StyleRule({ scope: \"class\", name, styles: deviations });\n }\n\n const inherited = Object.freeze({ ...FRAMEWORK_DECLARATIONS, ...deviations });\n\n _bags.set(ctor, inherited);\n\n return inherited;\n }\n\n const level = resolveClassLevel(ctor);\n\n _bags.set(ctor, level.resolved);\n\n return level.resolved;\n}\n\nconst _classChains: Map<Function, readonly string[]> = new Map();\n\n/**\n * Every ancestor's own class name, from the topmost ancestor down to `ctor`\n * itself — the full list `Component.init()` adds to the element. Memoized\n * per constructor; independent of which *level* has registered\n * `ownClassStyleDefaults`, so a chain that has opted in anywhere gets its\n * full ancestor chain even through a non-contributing middle level (e.g.\n * `DefaultCell`, between `Cell` and `HeaderCell`).\n *\n * Gated on `chainParticipates`, though, at the top: a chain with **no**\n * `ownClassStyleDefaults` *anywhere* keeps today's exact pre-hierarchy\n * behaviour — this class's own name only, not its ancestors'. Widening such\n * a chain would be actively unsafe, not merely useless: `Button` /\n * `ToggleButton` / `TabButton` / `SpinButton` (and `MenuButton` /\n * `PopupButton`) each still have their own independent flat `.ClassName`\n * rule (including an independently-created state-tier `.pressed` rule) via\n * the pre-hierarchy mechanism, at the same `(0,1,0)` specificity as every\n * other level's rule. Widening their DOM classes without also making the\n * state tier hierarchy-aware would let two same-specificity rules start\n * matching one element, with the winner decided by stylesheet insertion\n * order — the exact hazard `plans/implemented/class-hierarchy-cascade.md`'s\n * \"Rollout is scoped to the confirmed-safe chains\" decision documents for\n * that family specifically; `chainParticipates` generalises the exclusion to\n * every non-participating chain rather than naming `Button`'s family only,\n * since the same hazard recurs for any other pre-existing multi-level flat\n * hierarchy this plan doesn't touch.\n */\nexport function getStyleClassChain(rawCtor: Function): readonly string[] {\n const ctor = canonicalCtor(rawCtor);\n const cached = _classChains.get(ctor);\n\n if (cached) {\n return cached;\n }\n\n // `_rootCtor` (Component) is excluded from every chain — a bare\n // `Component` instance's chain is `[]`, matching every concrete\n // subclass never seeing \"Component\" as an ancestor's own class name.\n if (ctor === _rootCtor) {\n const chain: readonly string[] = [];\n\n _classChains.set(ctor, chain);\n\n return chain;\n }\n\n if (!chainParticipates(ctor)) {\n const chain: readonly string[] = ctor.name ? Object.freeze([ctor.name]) : [];\n\n _classChains.set(ctor, chain);\n\n return chain;\n }\n\n const parentCtor = canonicalCtor(Object.getPrototypeOf(ctor) as Function);\n const parentChain = (typeof parentCtor === \"function\" && parentCtor.name)\n ? getStyleClassChain(parentCtor)\n : [];\n\n const chain = ctor.name ? Object.freeze([...parentChain, ctor.name]) : parentChain;\n\n _classChains.set(ctor, chain);\n\n return chain;\n}\n\n// (ctor -> (suffix -> bag)). Parallel to `_bags`, but keyed on suffix too, since\n// one class can own several state rules (Button: .pressed, :hover:not(.pressed)).\nconst _stateBags: Map<Function, Map<string, ClassStyleBag | null>> = new Map();\n\n/**\n * State-rule sibling of {@link ensureClassStyleRule}. Ensures a shared\n * `.ClassName<suffix>` rule exists carrying `declarations` and returns the\n * bag, so the caller's setters can skip a write that already matches it.\n * Cached per `(ctor, suffix)` — the first call for a given class+suffix\n * computes and registers the rule; every later call (any instance, any\n * suffix already seen for that class) returns the cached result.\n *\n * Unlike `ensureClassStyleRule`, there is no framework-level tier beneath a\n * state rule to diff against — `declarations` is the caller's own fully\n * resolved bag, not a set of deviations from a lower tier.\n *\n * @param ctor - The concrete component class constructor.\n * @param suffix - The selector suffix, verbatim (e.g. `\".pressed\"`,\n * `\":hover:not(.pressed)\"`), matching whatever the instance rule's own\n * `createStyleRule(suffix)` call uses.\n * @param declarations - This class's resolved declarations for the\n * suffixed state — the non-hierarchy-aware fallback bag, used only when\n * `extractorMethodName` is omitted or `ctor`'s chain doesn't participate\n * in the hierarchy mechanism (see `extractorMethodName` below).\n * @param extractorMethodName - The name of the `protected static`\n * extraction method (e.g. `\"extractPressedClassDeclarations\"`) each\n * participating ancestor may declare its own copy of. When supplied and\n * `ctor`'s chain participates in the hierarchy mechanism (i.e.\n * {@link chainParticipates}), resolution delegates to\n * {@link resolveClassStateLevel} instead of the flat per-`(ctor, suffix)`\n * cache below — this is what makes a subclass sharing its nearest\n * contributing ancestor's rule (rather than always creating its own)\n * safe now that `class-hierarchy-cascade.md`'s DOM widening applies to\n * this chain too. Omitted (or `ctor` non-participating) keeps today's\n * exact flat behaviour, so every other `createStateStyleRule` call site\n * in the library needs no change.\n *\n * @returns The declarations bag, or `null` when `ctor`'s name is empty or\n * already claimed by a different constructor (the same name-collision\n * opt-out `ensureClassStyleRule` uses) — the caller must then write every\n * declaration to its own instance rule.\n */\nexport function ensureClassStateRule(\n ctor: Function,\n suffix: string,\n declarations: Record<string, string | null>,\n extractorMethodName?: string,\n): ClassStyleBag | null {\n if (extractorMethodName && chainParticipates(ctor)) {\n const name = ctor.name;\n const owner = _owners.get(name);\n\n if (!name || (owner !== undefined && owner !== ctor)) {\n return null;\n }\n\n return resolveClassStateLevel(ctor, suffix, extractorMethodName).resolved;\n }\n\n let bySuffix = _stateBags.get(ctor);\n if (!bySuffix) {\n bySuffix = new Map();\n _stateBags.set(ctor, bySuffix);\n }\n\n const existing = bySuffix.get(suffix);\n if (existing !== undefined) {\n return existing;\n }\n\n const name = ctor.name;\n const owner = _owners.get(name);\n\n if (!name || (owner !== undefined && owner !== ctor)) {\n bySuffix.set(suffix, null);\n\n return null;\n }\n\n _owners.set(name, ctor);\n\n if (Object.keys(declarations).length > 0) {\n new StyleRule({ scope: \"class\", name, suffix, styles: declarations });\n }\n\n const bag = Object.freeze({ ...declarations });\n bySuffix.set(suffix, bag);\n\n return bag;\n}\n\n// (ctor -> (group -> bag)). Parallel to `_stateBags`, but keyed by a\n// caller-supplied `styleGroup` token instead of a framework-defined state\n// suffix — see plans/implemented/shared-instance-style-groups.md.\nconst _groupBags: Map<Function, Map<string, ClassStyleBag | null>> = new Map();\n\n/**\n * The safe `ClassName--<suffix>` contribution a `styleGroup` token makes to a\n * literal DOM class name. Unlike a component id (only ever written through\n * `DOM.sink.setId`/an escaped selector string, never through `classList`), a\n * `styleGroup` token becomes part of a literal token `core/Component.ts`'s\n * `init()` passes straight to `classList.add` — and CSS-escaping alone (see\n * {@link ensureStyleGroupRule}'s selector construction) does not help there:\n * `CSS.escape` backslash-prefixes a space rather than removing it, so an\n * escaped token can still contain a raw ASCII space character and\n * `classList.add` still rejects it. ASCII whitespace is replaced with `-` so\n * the token is always a valid single class; `core/Component.ts`'s `init()`\n * and {@link ensureStyleGroupRule} both call this before building their\n * respective class name / selector, so the two always agree on the same\n * literal suffix regardless of what characters the caller's token contains.\n */\nexport function styleGroupClassSuffix(group: string): string {\n return group.replace(/\\s+/g, \"-\");\n}\n\n/**\n * Ensures a shared `.ClassName--<group>` rule exists carrying `declarations`\n * — the first instance in this `(ctor, group)` pair to call this function\n * determines the shared content; every later instance compares against it.\n * Mirrors {@link ensureClassStateRule}'s cache shape, keyed by a\n * caller-supplied token instead of a framework-defined state suffix. Always\n * keyed on the concrete class alone — never an ancestor, regardless of\n * whether `ctor`'s chain participates in the hierarchy mechanism above.\n *\n * @param ctor - The concrete component class constructor.\n * @param group - The caller-supplied `styleGroup` token, verbatim (not yet\n * escaped — see the selector construction below).\n * @param declarations - This instance's own fully resolved hoistable\n * declarations (`core/Component.ts`'s `resolveInstanceStyleDeclarations`)\n * — the *first* call for a given `(ctor, group)` pair determines what every\n * later instance in the same group compares against.\n *\n * @returns The group's declaration bag, or `null` when the selector name\n * (`ClassName--group`) is already claimed by a different constructor — the\n * same name-collision opt-out the base and state tiers use, in which case\n * the caller must write every declaration to its own `#id` rule.\n */\nexport function ensureStyleGroupRule(\n ctor: Function,\n group: string,\n declarations: Record<string, string | null>,\n): ClassStyleBag | null {\n // Cached by the *normalised* suffix (see `styleGroupClassSuffix`), not\n // the raw token — the DOM class and CSS selector this function produces\n // are both derived from the normalised form, so two raw tokens that\n // normalise to the same suffix (e.g. \"brand warning\" and \"brand-warning\")\n // must be treated as the same group, not two independent cache entries\n // racing to overwrite one rule.\n const normalizedGroup = styleGroupClassSuffix(group);\n\n let byGroup = _groupBags.get(ctor);\n if (!byGroup) {\n byGroup = new Map();\n _groupBags.set(ctor, byGroup);\n }\n\n const existing = byGroup.get(normalizedGroup);\n if (existing !== undefined) {\n return existing;\n }\n\n const className = ctor.name;\n if (!className) {\n byGroup.set(normalizedGroup, null);\n\n return null;\n }\n\n // The group token is caller-supplied (unlike a state suffix, which the\n // framework itself defines) and becomes part of a `.ClassName--<group>`\n // selector, so it is CSS-escaped here — the same treatment a component id\n // already gets in `core/StyleTarget.ts`'s `component`-scope selector.\n const selectorName = className + \"--\" + DOM.source.escapeSelector(normalizedGroup);\n const owner = _owners.get(selectorName);\n\n if (owner !== undefined && owner !== ctor) {\n byGroup.set(normalizedGroup, null);\n\n return null;\n }\n\n _owners.set(selectorName, ctor);\n\n if (Object.keys(declarations).length > 0) {\n new StyleRule({ scope: \"class\", name: selectorName, styles: declarations });\n }\n\n const bag = Object.freeze({ ...declarations });\n byGroup.set(normalizedGroup, bag);\n\n return bag;\n}\n\n/**\n * Routes one state-rule declaration to the rule that should carry it:\n * dropped when `bag` already delivers the same key/value, written to `rule`\n * otherwise. `writeRuleDeclaration`'s shape, generalised to take the target\n * rule and comparison bag as parameters instead of reading `this._styleRule`\n * / `this._inheritedStyleBag` — a state-rule setter can fire from many call\n * sites (construction, a runtime setter, a chrome-mode toggle), not from one\n * `applyStyle` pass, so there is no single per-render cache to read from.\n *\n * @remarks A `null` write can never itself win the cascade over a *non-null*\n * class-bag value for `key`: `null` maps to a CSSOM `removeProperty`, and a\n * declaration block that never declares `key` doesn't compete for it at\n * all — an unmaterialised (or materialised-but-empty) instance rule leaves\n * the class-tier rule's value in sole possession of the property regardless\n * of the instance rule's higher specificity. This routing function cannot\n * fix that generically (it has no per-property \"neutral value\" table to\n * substitute); the one concrete case this surfaces (`Button`'s\n * `pressedShadow`/`pressedBackgroundColor`/`pressedBackgroundImage`, cleared\n * by `SpinButton`/`Dialog`/`Notification`'s close buttons) stays correct by\n * having each caller pin the current resting value instead of writing\n * `null` — see `Button.clearPressedShadow`, `clearPressedBackgroundColor`,\n * and `clearPressedBackgroundImage`.\n */\nexport function writeClassStateDeclaration(\n rule: StyleRule,\n bag: ClassStyleBag | null,\n key: string,\n value: string | null,\n): void {\n if (bag !== null && bag[key] === value) {\n return;\n }\n\n rule.set(key, value);\n}\n\n/** Bulk form of {@link writeClassStateDeclaration}, one call per key of `values`. */\nexport function writeManyClassStateDeclarations(\n rule: StyleRule,\n bag: ClassStyleBag | null,\n values: Record<string, string | null>,\n): void {\n for (const key of Object.keys(values)) {\n writeClassStateDeclaration(rule, bag, key, values[key]);\n }\n}\n\n/**\n * Wraps a per-instance state `StyleRule` together with the class-tier\n * comparison bag `ensureClassStateRule` resolves for it. `set()` / `setMany()`\n * skip a write that already matches the class rule and materialise the\n * underlying rule when a real write just queued on an already-rendered\n * component — exactly like `writeClassStateDeclaration` /\n * `writeManyClassStateDeclarations` plus a materialisation nudge — so a\n * caller gets both by calling the object's own write methods, with nothing\n * else to opt into.\n *\n * Constructed via `Component.createStateStyleRule`; not intended for direct\n * construction elsewhere.\n */\nexport class StateStyleRule {\n private readonly _rule: StyleRule;\n private readonly _bag: ClassStyleBag | null;\n private readonly _hasElement: () => boolean;\n\n constructor(\n ctor: Function,\n suffix: string,\n rule: StyleRule,\n resolveDefaults: () => Record<string, string | null>,\n hasElement: () => boolean,\n extractorMethodName?: string,\n ) {\n this._rule = rule;\n this._bag = ensureClassStateRule(ctor, suffix, resolveDefaults(), extractorMethodName);\n this._hasElement = hasElement;\n }\n\n /**\n * The resolved class-tier bag `set()` / `setMany()` compare against;\n * `null` when this class opted out of dedup (see `ensureClassStateRule`).\n * Read-only — a caller that needs the bag's own keys (`Button.pinPressedToResting`\n * is the one in-repo example) reads this instead of bypassing the\n * comparison `set()` / `setMany()` perform.\n */\n get classBag(): ClassStyleBag | null {\n return this._bag;\n }\n\n /**\n * Writes a single state-rule declaration, deduping against the class-tier\n * bag and materialising the underlying rule when this write just queued a\n * real declaration on an already-rendered component.\n *\n * @param key - The CSS property name (camelCase).\n * @param value - The value to set, or null to remove the property.\n */\n set(key: string, value: string | null): void {\n writeClassStateDeclaration(this._rule, this._bag, key, value);\n this._materialise();\n }\n\n /**\n * Bulk variant of {@link StateStyleRule.set}.\n *\n * @param values - Camel-cased property keys mapped to string values (or null to clear).\n */\n setMany(values: Record<string, string | null>): void {\n writeManyClassStateDeclarations(this._rule, this._bag, values);\n this._materialise();\n }\n\n /**\n * Inserts the rule when a write just queued a real declaration and the\n * component is already rendered — the choke point `Button`'s\n * `materialisePressedRule` used to be, generalised so no future caller\n * can forget it. A rule that never queued anything real (every write so\n * far matched the class bag) is left unmaterialised, same as any other\n * deferred rule.\n */\n private _materialise(): void {\n if (this._hasElement() && this._rule.hasQueuedDeclarations()) {\n this._rule.ensure();\n }\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\n// Internal helper backing Component's border-width measurement. A style read\n// (getComputedStyle) that follows a stylesheet-rule write in the same task\n// makes every later rule write in that task dramatically more expensive (the\n// \"read-after-write penalty\" — see docs/concepts/performance.md). A wide\n// table's column-window slide issues one getComputedStyle-backed border read\n// per rendered cell, all sharing the same border spec, so measuring the spec\n// once and sharing the result turns ~30 reads into (at most) one. Not\n// exported from `core/index.ts` — mirrors `core/ClassStyleRules.ts`, which\n// solves the same shape of problem (a module-level cache serving\n// `Component`) the same way. See plans/implemented/table-scroll-forced-reflow.md.\n\nimport { DOM, type Handle } from \"~/core/DOM.js\";\nimport { type BorderOptions, borderToStyle, borderSideWidth } from \"~/primitive/Border.js\";\nimport { ThemeManager } from \"~/core/Theme.js\";\n\n/**\n * Per-side pixel widths. Structural twin of `Component`'s `PerimeterSize` —\n * declared locally rather than imported so this module never imports\n * `core/Component.ts`, mirroring `ClassStyleRules.ts`'s own `ClassStyleDefaults`.\n */\ninterface SideWidths {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\n// A side value whose width is font-relative (em/ex/ch/lh) resolves against the\n// element's own font size, so two components with the same spec can measure\n// differently — such a spec must never be shared. A digit immediately before\n// the unit distinguishes it from `rem`, which is root-relative and safe to share.\nconst FONT_RELATIVE_UNIT = /[\\d.](?:em|ex|ch|lh)\\b/i;\n\n// Resolved-side-string key -> measured widths. Cleared on theme change.\nconst _widths: Map<string, SideWidths> = new Map();\n\n/**\n * Derives the shared-cache key for a border spec: its four resolved side\n * values joined by `|`, so two specs that resolve to the same four sides\n * share one entry. Returns `null` when any side is font-relative — such a\n * spec must be measured per component and never cached.\n *\n * @param spec - The border specification to key.\n *\n * @returns The cache key, or `null` when the spec opts out of sharing.\n */\nfunction cacheKey(spec: BorderOptions): string | null {\n const style = borderToStyle(spec);\n const sides = [style.borderTop, style.borderRight, style.borderBottom, style.borderLeft];\n\n if (sides.some((side) => side !== null && FONT_RELATIVE_UNIT.test(side))) {\n return null;\n }\n\n return sides.join(\"|\");\n}\n\n/**\n * Returns the browser-measured per-side border widths for `spec`, measuring\n * `element` only when this spec has not already been measured under the\n * active theme. A font-relative spec (see {@link cacheKey}) is always\n * measured and never cached, since it can resolve differently per element.\n *\n * @param spec - The border specification to measure.\n * @param element - The connected element to measure it against.\n *\n * @returns The measured per-side pixel widths.\n */\nexport function measureBorderWidths(spec: BorderOptions, element: Handle): SideWidths {\n const key = cacheKey(spec);\n\n if (key !== null) {\n const cached = _widths.get(key);\n\n if (cached) {\n return cached;\n }\n }\n\n const cs = DOM.source.getBorderWidths(element);\n\n const widths: SideWidths = {\n top: borderSideWidth(cs.top),\n right: borderSideWidth(cs.right),\n bottom: borderSideWidth(cs.bottom),\n left: borderSideWidth(cs.left),\n };\n\n if (key !== null) {\n _widths.set(key, widths);\n }\n\n return widths;\n}\n\n/** Drops every entry. Called on theme change and by the test harness. @internal */\nexport function clearBorderWidths(): void {\n _widths.clear();\n}\n\n/** Number of cached entries; for tests only. @internal */\nexport function _borderWidthCacheSize(): number {\n return _widths.size;\n}\n\n// Registered at import — ahead of every per-component theme listener, since no\n// component can exist before `core/Component.ts` has imported this module —\n// so no component can observe a stale shared entry while a theme change is\n// still being delivered (see plans/implemented/table-scroll-forced-reflow.md).\nThemeManager.onThemeChange(clearBorderWidths);\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { LayoutManager } from \"~/layout/LayoutManager.js\";\nimport { Absolute } from \"~/layout/Absolute.js\";\nimport { DOM } from \"~/core/DOM.js\";\nimport type { Handle } from \"~/core/DOM.js\";\nimport { isFirstLayoutHeld, startFirstLayoutDeadline } from \"~/core/FirstLayoutGate.js\";\nimport { BorderOptions, borderToStyle, borderSideWidth } from \"~/primitive/Border.js\";\nimport { Size, UNBOUNDED, isUnbounded } from \"~/primitive/Size.js\";\nimport { Insets } from \"~/primitive/Insets.js\";\nimport { BaseObject } from \"~/core/BaseObject.js\";\nimport { LayoutConstraints } from \"~/layout/LayoutConstraints.js\";\nimport { Type } from \"~/core/Type.js\";\nimport { Util } from \"~/core/Util.js\";\nimport { Position } from \"~/primitive/Position.js\";\nimport { Aria } from \"~/core/Aria.js\";\nimport { Event } from \"~/core/Event.js\";\nimport { SmoothScroller, consumeWheel, type ScrollAxis } from \"~/core/SmoothScroller.js\";\nimport { StyleRule, InlineStyle, disposeStyleRule } from \"~/core/StyleTarget.js\";\nimport { ElementAttributes } from \"~/core/ElementAttributes.js\";\nimport { ThemeManager } from \"~/core/Theme.js\";\nimport { callable } from \"~/core/Callable.js\";\nimport { resolveClassDefaults } from \"~/core/ComponentDefaults.js\";\nimport { COMPONENT_CLASS, ensureClassStyleRule, ensureStyleGroupRule, getStyleClassChain, registerStyleChainRoot, resolveDeclarations, styleGroupClassSuffix, type ClassStyleDefaults, StateStyleRule } from \"~/core/ClassStyleRules.js\";\nimport { cancelTransitions } from \"~/core/PendingTransitions.js\";\nimport { measureBorderWidths } from \"~/core/BorderWidths.js\";\n\n//import { FastDom } from \"~/FastDom.js\";\n\n/**\n * Generic two-argument comparator returning a sort-order number.\n *\n * @category Core\n */\nexport interface Comparator<V, U> {\n (a: V, b: U): number;\n}\n\n/**\n * Map of CSS property names to string values (or `null` to clear). Used by\n * `Component.setElementCSSRules` for bulk style updates.\n *\n * @category Core\n */\nexport interface Style {\n [key: string]: string | null\n}\n\n/**\n * Width of a component's outer perimeter on each side, in pixels.\n *\n * Returned by [`Component.getPerimeterSize`](/api/core/classes/Component#getperimetersize) — the sum of border width and\n * padding for each edge.\n *\n * @category Core\n */\nexport interface PerimeterSize {\n top: number,\n right: number,\n bottom: number,\n left: number\n}\n\n/**\n * A zero-argument function producing a child component on demand, either\n * immediately or once its promise resolves. An async factory is only accepted\n * by a layout manager that defers it (today: [`Tab`](/api/layout/classes/Tab)).\n *\n * @category Core\n */\nexport type ComponentFactory = () => Component | Promise<Component>;\n\n/**\n * A child component paired with optional layout constraints, as accepted by\n * [`Component.addComponents`](/api/core/classes/Component#addcomponents).\n *\n * @category Core\n */\nexport interface ConstrainedComponent {\n component: Component | ComponentFactory;\n constraints?: LayoutConstraints;\n}\n\n/**\n * Declarative spec for a per-component state rule installed at construction\n * time via {@link ComponentOptions.styleRules}.\n *\n * Each entry produces (or fetches) a `StyleRule` whose selector is\n * `#<id><suffix>` (e.g. `#cmp-12:hover`, `#cmp-12.selected`) and applies the\n * given style body. The `suffix` is the dedupe key inside the component's\n * `_deferredStyleRules` map — repeated entries with the same suffix write\n * into the same wrapper.\n *\n * Subclasses that want to layer rules on top of caller-supplied entries\n * use the standard array-merge idiom on the bag:\n *\n * ```typescript\n * super({\n * ...options,\n * styleRules: [\n * ...(options?.styleRules ?? []),\n * { suffix: \":hover\", styles: { backgroundColor: \"var(--…)\" } },\n * ],\n * }, _defaultXOptions);\n * ```\n *\n * @category Core\n */\nexport interface ComponentStyleRuleSpec {\n suffix: string;\n styles: Record<string, string | null>;\n}\n\n/**\n * Construction-time options for {@link Component}.\n *\n * Every field is optional and maps to an existing setter on `Component`. Pass\n * an `options` object as the trailing constructor argument to configure a\n * component declaratively instead of issuing chained setter calls.\n *\n * @category Core\n */\nexport interface ComponentOptions {\n tag?: string;\n visible?: boolean;\n displayed?: boolean;\n zIndex?: number;\n insets?: Insets;\n padding?: Insets;\n backgroundColor?: string;\n backgroundImage?: string;\n /** CSS `background` shorthand — a color, gradient, or image (all layers). */\n background?: string;\n foregroundColor?: string;\n colorScheme?: string;\n border?: BorderOptions | string;\n borderRadius?: string;\n shadow?: string;\n outline?: string;\n cursor?: string;\n userSelect?: string;\n preferredSize?: Size;\n minSize?: Size;\n maxSize?: Size;\n transform?: string;\n transformOrigin?: string;\n transition?: string;\n willChange?: string | null;\n opacity?: number;\n overflow?: string;\n pointerEvents?: string;\n writingMode?: string;\n touchAction?: string;\n layoutManager?: LayoutManager;\n id?: string;\n /** Human-readable title for the component; read by the [`Tab`](/api/layout/classes/Tab) layout for the tab/window label. */\n name?: string | null;\n attributes?: Record<string, string>;\n components?: Array<Component | ComponentFactory | ConstrainedComponent>;\n styleRules?: ComponentStyleRuleSpec[];\n /**\n * Opt-in token that lets several instances of the same concrete class\n * share one generated `.ClassName--<group>` CSS rule instead of each\n * carrying its own.\n */\n styleGroup?: string | null;\n}\n\n// Module-level state for the rAF-coalesced layout queue. Setters and event handlers call\n// `scheduleLayout()` instead of `doLayout()`; the queue flushes once per animation frame and\n// prunes any component whose ancestor is also dirty (the ancestor's layout will recurse into\n// it). `flushLayout()` provides a synchronous escape hatch for callers that need a layout\n// commit before reading layout-derived state.\nlet pendingLayouts: Set<Component> = new Set();\n// Callbacks queued via Component.afterNextLayout, drained once after the next\n// flush lays out every dirty component — see afterNextLayout for the contract.\nlet afterLayoutCallbacks: Array<() => void> = [];\nlet rafHandle: number | null = null;\n\n/** Schedules a layout-flush frame if one is not already pending. */\nfunction ensureFlushScheduled(): void {\n if (rafHandle === null) {\n rafHandle = DOM.sink.requestAnimationFrame(flushPendingLayouts);\n }\n}\n\nfunction flushPendingLayouts() {\n rafHandle = null;\n\n // Startup font gate: hold the very first flush until the web font has\n // activated, so no text is committed at a fallback-derived size. The queues\n // are left intact and retried next frame; the gate opens on activation or\n // on its own bounded deadline.\n if (isFirstLayoutHeld()) {\n startFirstLayoutDeadline();\n ensureFlushScheduled();\n\n return;\n }\n\n // Snapshot and clear both queues so re-entrant scheduleLayout / afterNextLayout\n // calls (from a doLayout side effect or a post-layout callback) queue into the\n // next frame instead of mutating these during iteration.\n const dirty = Array.from(pendingLayouts);\n pendingLayouts.clear();\n\n const callbacks = afterLayoutCallbacks;\n afterLayoutCallbacks = [];\n\n for (const c of dirty) {\n let hasDirtyAncestor = false;\n let p = c.getParentComponent();\n while (p) {\n if (dirty.indexOf(p) !== -1) {\n hasDirtyAncestor = true;\n break;\n }\n p = p.getParentComponent();\n }\n\n // An earlier entry's doLayout() can synchronously dispose a component\n // still waiting later in this same snapshot — e.g. a table's real\n // layout (Body.renderWindow) discarding a pooled cell whose renderer\n // had already scheduled a layout during construction. `pendingLayouts.\n // delete(this)` in destructor() only protects against the *next*\n // flush; a disposal mid-flush leaves this snapshot stale. Skip a\n // disposed (or never-rendered) component rather than laying out a\n // corpse — mirrors flushPendingVisibility's same guard, above.\n if (!hasDirtyAncestor && c.getElement()) {\n c.doLayout();\n }\n }\n\n // Post-layout callbacks run after every dirty component has settled, so a\n // consumer that scheduled layout work (revealing a view, opening a section)\n // can act on the final geometry — e.g. focus a now-laid-out element.\n for (const cb of callbacks) {\n cb();\n }\n}\n\n// Module-level state for the rAF-coalesced effective-visibility reconcile.\n// `setVisible` / `setDisplayed` add their component to this queue instead of\n// walking the subtree synchronously; the queue flushes once per animation\n// frame, recomputing each queued root's *net* effective visibility once —\n// mirroring `pendingLayouts` above. `flushEffectiveVisibility()` provides a\n// synchronous escape hatch (the offline `RecordingDOMSink.requestAnimationFrame`\n// drops its callback, so tests must call it to observe a coalesced flush).\nlet pendingVisibility: Set<Component> = new Set();\nlet visibilityRafHandle: number | null = null;\n\n/** Schedules an effective-visibility flush frame if one is not already pending. */\nfunction ensureVisibilityFlushScheduled(): void {\n if (visibilityRafHandle === null) {\n visibilityRafHandle = DOM.sink.requestAnimationFrame(flushPendingVisibility);\n }\n}\n\nfunction flushPendingVisibility(): void {\n visibilityRafHandle = null;\n\n const dirty = Array.from(pendingVisibility);\n pendingVisibility.clear();\n\n for (const c of dirty) {\n if (!c.getElement()) continue; // skip disposed / never-rendered\n c.propagateEffectiveVisibility(c.isEffectivelyVisible());\n }\n}\n\n/**\n * Serialises one size term for a debug `data-*` size attribute: `\"inf\"` when the\n * extent is unbounded, else its rounded pixel string.\n *\n * @param value - The extent to serialise.\n * @returns `\"inf\"` for an unbounded extent, else `\"<rounded>px\"`.\n */\nfunction formatSizeTerm(value: number): string {\n return isUnbounded(value) ? \"inf\" : Math.round(value) + \"px\";\n}\n\n/**\n * Serialises a width/height pair for a debug `data-*` size attribute, testing\n * each axis independently so an unbounded width paired with a bounded height (or\n * vice versa) renders correctly.\n *\n * @param width - The width extent.\n * @param height - The height extent.\n * @returns The space-separated `\"<width> <height>\"` term pair.\n */\nfunction formatSizeAttr(width: number, height: number): string {\n return formatSizeTerm(width) + \" \" + formatSizeTerm(height);\n}\n\n/**\n * The declarations a specific instance's own resolved hoistable style\n * produces — read through the same per-field getters a caller would use\n * (`getBackgroundColor()`, `getBorder()`, ...), then passed through\n * `resolveDeclarations` exactly as `getClassStyleDefaults()`'s class-only\n * bag is. Seeds `ensureStyleGroupRule` with what *this instance* would\n * actually render, not the class's plain default — see\n * plans/implemented/shared-instance-style-groups.md. Scoped to the same\n * fields the class tier hoists via `ClassStyleDefaults`, minus\n * `backgroundImage`/`borderRadius`/`visible`/`displayed`/`font`, which a\n * `styleGroup` does not cover.\n */\nfunction resolveInstanceStyleDeclarations(component: Component): Record<string, string | null> {\n return resolveDeclarations({\n backgroundColor: component.getBackgroundColor(),\n border: component.getBorder(),\n cursor: component.getCursor(),\n foregroundColor: component.getForegroundColor(),\n outline: component.getOutline(),\n userSelect: component.getUserSelect(),\n shadow: component.getShadow(),\n minSize: component.getMinSizeConstraint(),\n maxSize: component.getMaxSizeConstraint(),\n overflow: component.getOverflow(),\n });\n}\n\n/**\n * Base class for all UI components in the framework.\n *\n * Manages the component's DOM element lifecycle, CSS style rule, layout manager,\n * child component tree, and all visual properties (size, position, color, border, etc.).\n * Subclasses override `render()` and `init()` to produce specialised elements.\n *\n * Components are positioned absolutely. Sizes are explicit (preferred / min / max);\n * positions are computed by the parent's {@link LayoutManager} on each `doLayout()` pass.\n * See the Mental model guide on the documentation site for the architectural overview.\n *\n * @category Core\n */\n/**\n * Releases a discarded component's retained handles once the `Component`\n * instance is garbage-collected — restoring the pre-handle lifecycle where a\n * node lived exactly as long as its `Component`.\n *\n * @remarks A component removed via `removeComponent` (the shared primitive that\n * `moveComponent` is built on) detaches its element but cannot release the\n * handle there — releasing would break a move, which re-inserts the same\n * instance. Reachability is the move-vs-discard signal: a moved component stays\n * referenced; a discarded one becomes unreachable. So the release is keyed on GC\n * of the `Component`. The held value is the owned-handle array (numbers only,\n * with no back-reference to the `Component`, so the `Component` stays\n * collectable). `release` is idempotent, so a handle already freed by the eager\n * `destructor` or an explicit dispose is a harmless no-op here.\n */\ntype OwnedResources = {\n readonly handles: readonly Handle[];\n readonly selectors: readonly string[];\n};\n\nconst _componentFinalizer = new FinalizationRegistry<OwnedResources>(({ handles, selectors }) => {\n for (const handle of handles) {\n DOM.sink.release(handle);\n }\n\n for (const selector of selectors) {\n disposeStyleRule(selector);\n }\n});\n\n// The chrome properties the resting-isolation mechanism intercepts. Fixed —\n// see Architecture Decisions for why this isn't per-component configurable.\n// Moved here from Button.ts's RESTING_RECONCILED_KEYS, unchanged in content.\nconst RESTING_ISOLATION_KEYS: ReadonlySet<string> = new Set([\n \"backgroundColor\",\n \"backgroundImage\",\n \"boxShadow\",\n]);\n\nclass Component<TOptions extends ComponentOptions = ComponentOptions> extends BaseObject {\n\n // Structural state that is NOT option-backed — runtime references, render\n // caches, lifecycle flags, and constants. Option-backed values (border,\n // layoutManager, insets, padding, ...) live in `this._options` instead.\n private _components: Array<Component>;\n\n // Callbacks queued via onFirstLayout, drained the first time this component\n // completes a doLayout while its element is connected. Null once fired (or\n // never registered) so the common case allocates nothing.\n private _firstLayoutCallbacks : Array<() => void> | null = null;\n\n private _element : Handle | undefined;\n // Handles for every element this component created — root, clip / content\n // frames, and subclass-created children (registered via trackHandle).\n // Released eagerly in destructor, or by _componentFinalizer when a discarded\n // component is garbage-collected. Safe with a plain initializer: this is a\n // base-class field, set before the constructor body runs applyOptions, so no\n // cascade-dispatched render can clobber it.\n private readonly _ownedHandles : Handle[] = [];\n // Component-scope selectors (#<uuid>[<suffix>]) this component allocated,\n // for teardown deletion. Strings only (no back-reference to Component) so\n // the GC finalizer can hold it without pinning the instance. Mirror of\n // _ownedHandles.\n private readonly _ownedSelectors : string[] = [];\n // Disposers for every ThemeManager.onThemeChange subscription this\n // component holds, released eagerly in destructor. Safe with a plain\n // initializer for the same reason as _ownedHandles above: a base-class\n // field set before applyOptions runs, so no cascade-dispatched setter can\n // clobber it.\n private readonly _themeCleanups : Array<() => void> = [];\n private _tag : string = \"div\";\n // Every attribute the component currently intends its element to carry —\n // from setElementAttribute/removeElementAttribute, setDataAttribute/\n // delDataAttribute, the `attributes` options bag, setDisabledAttribute,\n // and Aria's mutators (which all route through applyAriaAttribute). One\n // channel, so init() replays it onto a freshly created element with a\n // single attach() call. Assigned in the constructor body (not a field\n // initializer) because applyOptions dispatches setters — including the\n // `attributes` bag itself — that write it from inside super().\n private _elementAttributes : ElementAttributes;\n private _boxSizing : string | null;\n\n // Geometry: NaN sentinels mean \"never assigned\", so equality guards on\n // setX/setY/setWidth/setHeight short-circuit only AFTER a real write —\n // the first call always reaches the DOM even when its target value is 0.\n private _left : number = NaN;\n private _top : number = NaN;\n private _width : number = NaN;\n private _height : number = NaN;\n /**\n * Backing field. Declared bare — see the `declare` rule in CODE_CONVENTIONS.md.\n * Framework-managed bookkeeping, so it gets no `ComponentOptions` field, per\n * ARCHITECTURE.md's third DOM-write rule.\n */\n declare private _layoutDirty : boolean;\n private _translateX : number = 0;\n private _translateY : number = 0;\n private _scrollLeft : number = 0;\n private _scrollTop : number = 0;\n private _willChange : string | null = null;\n private _transition : string | null = null;\n\n // Derived / runtime-only fields that have no direct ComponentOptions counterpart.\n // `_position` is intentionally NOT in `ComponentOptions` — the framework\n // positions every component absolutely (see ARCHITECTURE.md). Subclasses\n // that need `FIXED` for a floating overlay or `STATIC` for a semantic\n // HTML carve-out (e.g. `Legend`) call the protected `setPosition` setter\n // post-`super()`. Public callers cannot reach it.\n private _position : Position = Position.ABSOLUTE;\n private _onPreferredSizeChange: (() => void) | null = null;\n // Fired when this component's min/max constraint changes, so the parent\n // layout manager can re-clamp/relayout. Parallels `_onPreferredSizeChange`;\n // bound by the parent in add/insert, nulled on remove. `setMinSize`/\n // `setMaxSize` (not `applyOptions`) write it, so no `declare` is needed.\n private _onConstraintSizeChange: (() => void) | null = null;\n private _overflowX : string | null = null;\n private _overflowY : string | null = null;\n // Eased wheel-scroll controller, lazily attached while an overflow axis is\n // scrollable (auto/scroll). Null otherwise — most components never scroll.\n private _wheelScroller : SmoothScroller | null = null;\n private _contain : string | null = null;\n private _animation : string | null = null;\n // Edge-trigger cache for the effective-visibility walk; null = not yet\n // evaluated. Plain initializer: only propagateEffectiveVisibility\n // (post-render) writes it, never a cascade setter.\n private _lastEffectiveVisible : boolean | null = null;\n // Set by release(), consumed at the end of the next init() to queue the\n // scroll/focus restore. Plain initializer: only release() and init() write\n // it, never a cascade setter.\n private _pendingRematerialize : boolean = false;\n // Captured at release(), consumed by restoreReleasedState() on rebuild.\n private _refocusOnRematerialize : boolean = false;\n // Cache for setAnimationPlayState. Plain initializer for the same reason.\n private _animationPlayState : string | null = null;\n private _outline : string | null = null;\n private _appearance : string | null = null;\n private _borderImage : string | null = null;\n private _transform : string | null = null;\n private _transformOrigin : string | null = null;\n private _opacity : number | null = null;\n private _disabledAttribute : boolean = false;\n private _border : BorderOptions | null = null;\n private _borderWidths : PerimeterSize | null = null;\n private _borderThemeSubscribed : boolean = false;\n private _autoCommitStyle : boolean = true;\n private _autoCommitAttributes : boolean = true;\n private _layoutPaused : boolean = false;\n private _aria : Aria | null = null;\n private _whiteSpace : string | null;\n private _verticalAlign : string | null;\n // Deferred-write style buffers. `styleRule` lazily materialises the\n // component's per-id `CSSStyleRule` on first `ensure()` call; `inlineStyle`\n // queues `element.style.X = ...` writes until `init()` attaches it.\n private _styleRule : StyleRule = new StyleRule({ scope: \"component\", name: this.getId(), materialize: false });\n private _inlineStyle : InlineStyle = new InlineStyle();\n // Per-render cache of what the framework and class rules already deliver\n // for this concrete class — the merged bag `ensureClassStyleRule` returns.\n // Set at the top of `applyStyle` and consulted by `writeRuleDeclaration`\n // so each phase can skip a write already served by a lower tier.\n private _inheritedStyleBag : Readonly<Record<string, string | null>> | null = null;\n // Per-render cache of what this instance's `styleGroup` (if any) already\n // delivers — the bag `ensureStyleGroupRule` returns, or `null` when no\n // group is set. Checked by `matchesClassStyle` ahead of\n // `_inheritedStyleBag`; see plans/implemented/shared-instance-style-groups.md.\n private _styleGroupBag : Readonly<Record<string, string | null>> | null = null;\n // Optional clip frame: a presentational wrapper element interposed between\n // this component's element and its DOM parent, sized to a cell rect with\n // `overflow: hidden` so a layout manager can visually clip an element that\n // is wider/taller than its allotted cell (e.g. a `Grid` fixed column). The\n // frame carries no id and no listeners — it is a non-interactive sheath, so\n // it stays runtime-only state off the options bag. `_clipFrameStyle` buffers\n // the wrapper's geometry writes through the framework's deferred-write seam.\n private _clipFrame : Handle | null = null;\n private _clipFrameStyle : InlineStyle = new InlineStyle();\n // Optional content frame: a presentational wrapper interposed between this\n // component's element and ITS children, sized to the full content extent\n // (leading inset + children + trailing inset) so the host's native scroll\n // reserves both insets symmetrically when the children overflow. The mirror\n // image of the clip frame — that one clips a single oversized child, this\n // one exposes an oversized child set for scrolling. Same runtime-only,\n // id-less, listener-free discipline; the geometry writes buffer through\n // `_contentFrameStyle`.\n private _contentFrame : Handle | null = null;\n private _contentFrameStyle : InlineStyle = new InlineStyle();\n // Subclass-owned state rules (e.g. Button's `.pressed` / `:hover:not(.pressed)`,\n // ToggleButton's `.selected`) keyed by selector suffix and materialised\n // at first render. Assigned in the constructor body (not via a field\n // initializer) so the map is in place before subclass field initializers\n // run and before the `applyOptions` cascade fires — letting cascade-time\n // setters dedupe through `createStyleRule` regardless of any later slot\n // clobber on the caller side.\n private _deferredStyleRules! : Map<string, StyleRule>;\n\n // Tracks the single parent this component belongs to. Exposed read-only via\n // getParentComponent() for structural queries (e.g. FieldDecorator insertion).\n // Do NOT use this reference to propagate information upward from child to parent —\n // that direction of communication creates tight coupling and circular dependencies.\n // Parent-to-child communication (layout, sizing) is the only intended flow.\n private _parent : Component | null = null;\n\n // Two bags. `_options` holds values supplied by the caller or written by a\n // setter — i.e. the *explicit* state for this component. `_defaultOptions`\n // holds class-level defaults consulted as a fallback by getters. It is a\n // single frozen object **shared by every instance of the concrete class**,\n // cached on the class constructor by `resolveClassDefaults` — nothing\n // writes into it after it is built, and the freeze turns an accidental\n // write into a runtime throw. Splitting the two bags lets subclass guards\n // of the form `if (this._options.X === undefined)` detect \"the caller\n // didn't supply X\" without false-firing on defaults that base classes\n // pre-seeded. Both are initialized in the constructor body (not via field\n // initializers) so subclass field initializers can't clobber them. See\n // `plans/options-bag-state-refactor.md` and\n // `plans/implemented/per-class-component-defaults.md` for rationale.\n //\n // `layoutManager` never enters this bag — a layout manager holds\n // per-instance `_container` state, so sharing one across every instance\n // of a class would have each instance's layout stomp the others'.\n // `_defaultLayoutManager` is the per-instance slot: seeded from\n // `subclassDefaults.layoutManager` when the subclass supplied one,\n // otherwise lazily filled with `new Absolute()` the first time\n // `getLayoutManager()` resolves it.\n protected _options!: TOptions;\n protected _defaultOptions!: Readonly<TOptions>;\n private _defaultLayoutManager: LayoutManager | null;\n\n /**\n * @param options - Caller-supplied options bag.\n * @param subclassDefaults - Per-subclass default bag merged on top of the\n * built-in Component defaults to produce `_defaultOptions`. Subclasses\n * that extend Component (or any further-derived class) pass their\n * `_default<Name>Options` constant here. The defaults are a pure\n * fallback: getters and `applyStyle` consult `_defaultOptions` directly\n * when the caller omitted a field, so a default is never dispatched into\n * `_options`. Replaces the older pattern of spreading defaults into the\n * options arg at the call site — that pattern populated `_options`\n * directly and broke whenever `applyOptions` was re-invoked, because\n * Component's own defaults would silently override values set in the\n * subclass constructor body. Subclasses-of-subclasses accept their own\n * `subclassDefaults` parameter and forward it as\n * `{ ..._myDefaults, ...(subclassDefaults ?? {}) }` so the deepest\n * class's defaults win.\n */\n constructor(options?: TOptions, subclassDefaults?: Partial<TOptions>) {\n // BaseObject's constructor takes no options; this constructor applies them via applyOptions below.\n // eslint-disable-next-line local/forward-super-options\n super();\n\n // Structural setup that doesn't map to ComponentOptions.\n // `styleRule` stays unmaterialised until the element actually needs to\n // render; the dirty-style path queues writes until then. See\n // `ensureCSSRule`.\n this._components = [];\n this._elementAttributes = new ElementAttributes();\n this._deferredStyleRules = new Map<string, StyleRule>();\n this.trackSelector(this._styleRule.getSelector());\n\n // Constants without ComponentOptions counterpart.\n this._boxSizing = \"border-box\";\n this._whiteSpace = \"nowrap\";\n this._verticalAlign = \"baseline\";\n\n // Class-level defaults — fallback values consulted by getters when the\n // caller (or a setter) hasn't written to `_options`, and the source\n // every `applyOptions` cascade merges over before dispatching setters.\n // Subclass defaults are layered on top of the Component defaults by\n // `resolveClassDefaults`, which also caches the frozen result on\n // `this.constructor` so every instance of this concrete class shares\n // one bag. `layoutManager` is resolved separately into a per-instance\n // slot — see `_defaultLayoutManager`'s field comment.\n this._defaultLayoutManager = (subclassDefaults?.layoutManager as LayoutManager | undefined) ?? null;\n this._defaultOptions = resolveClassDefaults<TOptions>(this.constructor, subclassDefaults);\n\n // Explicit state — starts empty. Only values the caller passed or that\n // setters wrote ever land here. This is what `if (this._options.X ===\n // undefined)` checks against in subclass constructors.\n this._options = {} as TOptions;\n\n // `tag` has no setter — apply the option directly here. Subclasses\n // commonly forward this from `super({ tag: \"...\" })`.\n if (options?.tag !== undefined) {\n this._tag = options.tag;\n } else if (this._defaultOptions.tag !== undefined) {\n this._tag = this._defaultOptions.tag;\n }\n\n // Dispatch the caller-supplied options through virtual `applyOptions`.\n // The leaf-most override runs first and chains back up via\n // `super.applyOptions`, so every level along the chain gets a chance\n // to apply its own option-backed setters. No leaf gate — setters are\n // bag-mutating, so subclass field initializers can't clobber them.\n // `applyOptions` is `!== undefined` gated per-field, so omitting\n // `options` is safe and produces zero setter calls.\n this.applyOptions((options ?? ({} as TOptions)));\n }\n\n /**\n * Applies a {@link ComponentOptions} bag to this component by dispatching\n * each present field to its corresponding setter.\n *\n * @param options - The options bag carrying the values to apply.\n *\n * @returns This component, for method chaining.\n *\n * @remarks Option-backed state lives in `this._options`; each setter\n * dispatched here mutates the bag and triggers the necessary DOM /\n * attribute side effects. Subclass overrides typically call\n * `super.applyOptions(options)` first so inherited fields are applied\n * before subclass-specific ones, then dispatch their own option-backed\n * setters.\n */\n protected applyOptions(options: TOptions): this {\n // Dispatch only the caller-supplied options — class-level defaults are a\n // pure fallback consulted by the getters (and `applyStyle`), never\n // written into `_options`. See the per-field getters and the\n // `_defaultOptions` seed in the constructor.\n if (options.id !== undefined) this.setId(options.id);\n if (options.name !== undefined) this.setName(options.name);\n if (options.layoutManager !== undefined) this.setLayoutManager(options.layoutManager);\n if (options.visible !== undefined) this.setVisible(options.visible);\n if (options.displayed !== undefined) this.setDisplayed(options.displayed);\n if (options.zIndex !== undefined) this.setZIndex(options.zIndex);\n if (options.insets !== undefined) this.setInsets(options.insets);\n if (options.padding !== undefined) this.setPadding(options.padding);\n if (options.backgroundColor !== undefined) this.setBackgroundColor(options.backgroundColor);\n if (options.background !== undefined) this.setBackground(options.background);\n if (options.foregroundColor !== undefined) this.setForegroundColor(options.foregroundColor);\n if (options.colorScheme !== undefined) this.setColorScheme(options.colorScheme);\n this.applyChromeOptions(options);\n if (options.outline !== undefined) this.setOutline(options.outline);\n if (options.cursor !== undefined) this.setCursor(options.cursor);\n if (options.userSelect !== undefined) this.setUserSelect(options.userSelect);\n if (options.preferredSize !== undefined) this.setPreferredSize(options.preferredSize);\n if (options.minSize !== undefined) this.setMinSize(options.minSize);\n if (options.maxSize !== undefined) this.setMaxSize(options.maxSize);\n if (options.transform !== undefined) this.setTransform(options.transform);\n if (options.transformOrigin !== undefined) this.setTransformOrigin(options.transformOrigin);\n if (options.transition !== undefined) this.setTransition(options.transition);\n if (options.willChange !== undefined) this.setWillChange(options.willChange);\n if (options.opacity !== undefined) this.setOpacity(options.opacity);\n if (options.overflow !== undefined) this.setOverflow(options.overflow);\n if (options.pointerEvents !== undefined) this.setPointerEvents(options.pointerEvents);\n if (options.writingMode !== undefined) this.setWritingMode(options.writingMode);\n if (options.touchAction !== undefined) this.setTouchAction(options.touchAction);\n if (options.styleGroup !== undefined) this.setStyleGroup(options.styleGroup);\n\n if (options.attributes !== undefined) {\n // The options bag's `attributes` is a raw-HTML-attribute escape\n // hatch — callers pass arbitrary attribute names (`placeholder`,\n // `data-foo`, `aria-bar`) and expect a literal write. Route each\n // entry through the typed seam so the channel is the only store:\n // it writes through when the element already exists and replays\n // at render when it does not.\n for (const key of Object.keys(options.attributes)) {\n this.setElementAttribute(key, options.attributes[key]);\n }\n }\n\n if (options.styleRules !== undefined) {\n // Route every entry through `createStyleRule` so the wrapper is\n // registered in `_deferredStyleRules` and materialised at render\n // time, matching how the lazy state-rule getters in Button /\n // ToggleButton / WindowBorder allocate. Bare `new StyleRule(...)`\n // would skip the deferral and force-insert the stylesheet rule\n // before the element exists.\n for (const spec of options.styleRules) {\n this.createStyleRule(spec.suffix).setMany(spec.styles);\n }\n }\n\n if (options.components !== undefined) this.addComponents(options.components);\n\n return this;\n }\n\n /**\n * Dispatches the visual-chrome subset of a {@link ComponentOptions} bag —\n * `border`, `borderRadius`, `shadow`, and `backgroundImage`. Called from\n * {@link applyOptions}.\n *\n * @param options - The raw caller options bag. Unlike the rest of\n * `applyOptions`, the chrome fields fold in `this._defaultOptions` here so\n * their class-level defaults are still *dispatched* (e.g.\n * `options.border ?? this._defaultOptions.border`). They are kept on the\n * dispatch path — rather than resolved lazily by their getters — because\n * `border`'s parsed state (`_border`) feeds the layout border-width path\n * and a theme re-measure listener, and because `borderRadius`/`shadow`\n * must let a deeper subclass `clear*()` suppress an inherited default\n * (e.g. TabButton flattening Button's chrome) rather than fall back to it.\n * None of these four fields is consulted by a `_options.X === undefined`\n * guard, so dispatching their default does not violate the clean-bag\n * invariant.\n *\n * @remarks\n * Subclasses override this hook when they need to gate or extend the\n * chrome dispatch — e.g. [`Button`](/api/component/button/classes/Button)\n * gates on its `chromeless` option and appends its pressed/hover chrome\n * fields after the base call.\n */\n protected applyChromeOptions(options: TOptions): void {\n const border = options.border ?? this._defaultOptions.border;\n const borderRadius = options.borderRadius ?? this._defaultOptions.borderRadius;\n const shadow = options.shadow ?? this._defaultOptions.shadow;\n const backgroundImage = options.backgroundImage ?? this._defaultOptions.backgroundImage;\n\n if (border !== undefined) this.setBorder(border);\n if (borderRadius !== undefined) this.setBorderRadius(borderRadius);\n if (shadow !== undefined) this.setShadow(shadow);\n if (backgroundImage !== undefined) this.setBackgroundImage(backgroundImage);\n }\n\n /**\n * Wires a closed `listeners` bag via `this.on()` — the declarative form of\n * the component's typed `on()` surface. A host that exposes `on()` calls\n * this once from its constructor body after `super()` returns (when its\n * `ListenerBag` field has initialised). The base never calls it — base\n * `Component` has no `on`, so the `(this as any).on` cast is sound only\n * because the helper is invoked exclusively from hosts that define one.\n *\n * @param listeners - The component's `options.listeners` bag, or `undefined`.\n */\n protected applyListeners(\n listeners: Record<string, ((...args: any[]) => void) | undefined> | undefined\n ): void {\n if (!listeners) {\n return;\n }\n\n for (const event of Object.keys(listeners)) {\n const fn = listeners[event];\n\n if (fn) {\n (this as any).on(event, fn);\n }\n }\n }\n\n /**\n * Subscribes to theme changes and records the disposer so it is released\n * on teardown. Prefer this over calling `ThemeManager.onThemeChange`\n * directly — a discarded disposer leaks the component, because the\n * listener closure pins `this` in the static listener array for the life\n * of the process.\n *\n * @param listener - Called after CSS variables have been updated, so `getComputedStyle` returns new values.\n */\n protected subscribeTheme(listener: () => void): void {\n this._themeCleanups.push(ThemeManager.onThemeChange(listener));\n }\n\n /**\n * Tears this component down: the public call entry point for teardown.\n * The entire body defers to `destructor()`, which recursively destroys\n * this component's children, releases every tracked theme subscription,\n * unregisters every DOM listener it registered through the `Event` API,\n * detaches its layout manager, removes the DOM element, deletes the\n * component's per-instance stylesheet rules, and releases tracked\n * handles.\n *\n * @remarks Idempotent — calling this more than once is a harmless no-op.\n * Never override this method — override `destructor()` instead, so an\n * ancestor's own teardown recursing into this component still reaches\n * your cleanup.\n */\n dispose(): void {\n this.destructor();\n }\n\n /**\n * Destroys this component: recursively destroys its children, releases\n * every tracked theme subscription, unregisters every DOM listener it\n * registered through the `Event` API, detaches its layout manager,\n * removes the DOM element, deletes the component's per-instance\n * stylesheet rules, and releases tracked handles.\n *\n * @remarks Idempotent — calling this more than once is a harmless no-op.\n * This is the override hook — a subclass releasing its own resources\n * MUST end the override with `super.destructor()` or its share of the\n * work is silently skipped. Reached both from `dispose()` (the public\n * entry point) and, recursively, from an ancestor's own `destructor()` —\n * never call it directly from outside a `Component` subclass.\n */\n protected destructor() {\n // Drop any queued layout before this component's handles are released\n // below. `pendingLayouts` is module-level and outlives the component, so\n // a teardown landing between `scheduleLayout()` and the next animation\n // frame would otherwise leave the flush to lay out a corpse: `doLayout`\n // writes through handles this destructor has already released, which\n // throws against the production sink and aborts the rest of that flush,\n // leaving every component queued behind it unlaid. Descendants are\n // covered by the child recursion below, which reaches this same line for\n // each of them.\n pendingLayouts.delete(this);\n\n // Same reason as the line above: a module-level registration keyed by this\n // component's id outlives it, and each entry holds the component itself. An\n // entry left behind pins the whole instance (disarming the GC finalizer), and\n // a stale viewport entry keeps firing its handler against handles released at\n // the bottom of this method.\n Event.purgeComponent(this.getId());\n\n // Tear any active clip frame down, then remove this component's own\n // element — before recursing into children below, rather than after.\n // A still-connected element's removal here is the one call in this\n // subtree that costs a live style/layout invalidation; it also\n // natively detaches the whole subtree from the document in one step.\n // Every descendant reached afterward (through the `_components`\n // recursion below, or through any other component-owned disposal loop\n // elsewhere) still runs its own `DOM.sink.removeElement()` call — never\n // skipped, since a descendant can be reached by a path (e.g.\n // `disposeAllComponents()` on the still-live children of a container\n // that is itself merely detached-and-cached, not being disposed —\n // see `Menu.showAnchored()`) where nothing above it in *this* call\n // ever actually performed the removal — but that call now runs\n // against an already-detached node, which is a cheap pointer unlink,\n // not a rendering-affecting operation. `clearContentFrame()` stays\n // below, after the child recursion clears `_components` — unlike the\n // clip frame, its wrapper teardown re-parents every child (via\n // `getAttachNode()`) back onto this element first, which would be\n // real, wasted DOM work against every about-to-be-destroyed child\n // still in `_components` if it ran here.\n this.clearClipFrame();\n\n let element = this.getElement();\n if (element) {\n DOM.sink.removeElement(element);\n }\n\n // Discard the subtree eagerly — a destroyed container destroys its\n // children too. `removeComponent` never calls destructor (a removed\n // child may be re-parented by a move), so recursion here only reaches\n // descendants still present in `_components` at close time.\n for (const child of this._components) {\n child.destructor();\n }\n this._components = [];\n\n // Tear down any active content frame now that `_components` is empty\n // (mirroring `removeElement()`) so the wrapper is removed from the DOM\n // and its handle untracked and released, without its child-reparenting\n // loop doing pointless work against children this method just destroyed.\n this.clearContentFrame();\n\n // Detach the layout manager after the element is removed above.\n // Detaching before removal, as this method originally did, was a\n // defensive choice, not a proven-necessary one: a `LayoutManager.detach()`\n // override could touch the container's element through `getElement()`\n // — whose `getElementById` fallback needs a connected document — which\n // is what motivated running detach first. But no current override\n // demonstrably requires a connected element at\n // detach time: `Accordion.detach()` and `Split.detach()` (the two\n // overrides three successive review cycles pointed to as the reason)\n // both resolve their header / panel-wrapper / gutter elements through\n // `getElement()` calls that never reach the fallback, because those\n // components cache `_element` at creation via `getElement(true)`\n // (`Accordion.ts:1357-1358`, `Split.ts:1185`). The offline test\n // harness cannot settle the question either way: its modelled\n // `getElementById` (`TestHandleTable._byId`) is never evicted on\n // `removeElement`, so a stale id keeps resolving regardless of\n // ordering. A prior investigation into this exact ordering question\n // reordered detach to run after element removal and left the full\n // suite green, so detach running after removal — as it now does — is\n // not known to require an override. This is also what makes\n // `Tab.detach()` reachable on this path at all — it disposes the\n // raw-appended `TabBar` (`Tab.attach()` appends it directly to the\n // container element instead of registering it as a child), which the\n // child-destruction loop above cannot reach on its own. Resolved\n // directly against `_options` / `_defaultOptions`, rather than\n // through `getLayoutManager()`, whose lazy-attach branch would\n // re-attach (and then immediately re-detach) a manager that was never\n // actually in use — which would break idempotency on a second\n // `destructor()` call by re-attaching every time.\n const layoutManager = (this._options.layoutManager as LayoutManager | undefined)\n ?? (this._defaultLayoutManager ??= new Absolute());\n if (layoutManager && layoutManager.getContainer() === this) {\n layoutManager.detach();\n }\n\n // Release every recorded theme subscription (includes border\n // invalidation, folded into this bag by setBorder).\n for (const dispose of this._themeCleanups) {\n dispose();\n }\n this._themeCleanups.length = 0;\n\n // Dispose this component's own style rules before the handle-release\n // block below (rule disposal doesn't touch handles, so order relative\n // to it doesn't matter — grouped here to keep both eager-teardown\n // concerns together).\n this._styleRule.dispose();\n\n for (const rule of this._deferredStyleRules.values()) {\n rule.dispose();\n }\n\n // Eagerly release every remaining tracked handle (root and any\n // subclass-created children) and disarm the GC finalizer, then clear the\n // cache so a stale handle is never resolved.\n _componentFinalizer.unregister(this);\n\n // Abandon every transition still running against a handle released below. A\n // pending deferred write — Animation.play's two-frame entrance dance, or the\n // `transition: null` reset its completion performs — would otherwise resolve a\n // released handle and throw, exactly the stale-deferred-work hazard\n // `pendingLayouts.delete(this)` drops at the top of this method.\n for (const handle of this._ownedHandles) {\n cancelTransitions(handle);\n }\n\n for (const handle of this._ownedHandles) {\n DOM.sink.release(handle);\n }\n\n this._ownedHandles.length = 0;\n this._element = undefined;\n }\n\n /**\n * Records a handle for an element this component created so it is released\n * on teardown — eagerly by {@link destructor}, or by the module finalizer\n * when a discarded component is garbage-collected. The first tracked handle\n * arms the finalizer. Subclasses call this at every element-creation site.\n *\n * @param handle - The created element handle.\n * @returns The same handle, for chaining at the creation site.\n */\n protected trackHandle(handle: Handle): Handle {\n if (this._ownedHandles.length === 0) {\n _componentFinalizer.register(this, { handles: this._ownedHandles, selectors: this._ownedSelectors }, this);\n }\n\n this._ownedHandles.push(handle);\n\n return handle;\n }\n\n /** Records a component-scope selector so both teardown paths delete it. */\n private trackSelector(selector: string): void {\n this._ownedSelectors.push(selector);\n }\n\n /**\n * Stops tracking a handle that has already been released through an explicit\n * dispose path (a disposed frame, a removed scroll-shadow overlay), so the\n * owned-handle set does not accumulate stale entries across repeated toggles.\n *\n * @param handle - The handle to drop from the tracked set.\n */\n protected untrackHandle(handle: Handle): void {\n const idx = this._ownedHandles.indexOf(handle);\n\n if (idx !== -1) {\n this._ownedHandles.splice(idx, 1);\n }\n }\n\n /**\n * Returns the HTML tag name used when creating this component's element.\n *\n * @returns The HTML tag string (e.g. \"div\", \"button\").\n */\n getTag(): string {\n return this._tag;\n }\n\n /**\n * Returns the component's dedicated `#id` CSS style rule.\n *\n * @returns The CSSStyleRule scoped to this component's ID.\n *\n * @remarks Forces the underlying stylesheet rule to materialize on first\n * access. After {@link ensureCSSRule} runs, any pending writes queued in\n * `styleRule` are flushed onto the live rule so callers can read / mutate\n * it directly. This `#id` rule no longer holds a component's full\n * effective style: declarations that are uniform for this class are\n * served instead by a framework-wide rule shared by every component, and\n * a rule shared by every instance of this concrete class where its\n * defaults deviate from that; this rule carries only the declarations an\n * individual instance deviates on.\n */\n protected getCSSRule(): CSSStyleRule {\n return this.ensureCSSRule();\n }\n\n /**\n * Lazily creates the component's dedicated CSS rule and flushes any\n * dirty-style entries that accumulated before the rule existed.\n *\n * @returns The live `CSSStyleRule` scoped to this component's ID.\n *\n * @remarks Until this is called the component has no stylesheet entry —\n * setters queue into `styleRule` only. Defers the stylesheet insertion\n * (which would force a paint) to the moment the component renders, so\n * detached construction stays JS-only.\n */\n private ensureCSSRule(): CSSStyleRule {\n return this._styleRule.ensure();\n }\n\n /**\n * Returns the state-specific {@link StyleRule} for the given selector\n * suffix appended to this component's id (e.g. `\":hover\"`,\n * `\".pressed\"`, `\".selected\"`). The first call for a suffix\n * allocates a new wrapper and registers it for render-time materialisation\n * via {@link applyStyle}; subsequent calls with the same suffix return the\n * same wrapper, even across intervening backing-slot resets — so a lazy\n * getter that loses its cached reference (e.g. to TypeScript class-field\n * init clobber after super returns) still sees the original wrapper.\n *\n * @param selectorSuffix - CSS selector text appended to `#<id>` to form\n * the rule's selector. Must be unique per\n * component within this component's lifetime.\n *\n * @returns The `StyleRule` wrapper. Owners should cache it on a backing\n * slot for fast subsequent access; the slot is just a cache —\n * if it gets cleared, the next call to this method returns the\n * same wrapper from the deduping map.\n *\n * @remarks Safe to call from a lazy getter on the super-cascade path —\n * `deferredStyleRules` is initialised in Component's constructor body\n * before `applyOptions` fires, so cascade-time setters can allocate\n * through this builder.\n */\n protected createStyleRule(selectorSuffix: string): StyleRule {\n let rule = this._deferredStyleRules.get(selectorSuffix);\n if (!rule) {\n rule = new StyleRule({ scope: \"component\", name: this.getId(), suffix: selectorSuffix, materialize: false });\n this._deferredStyleRules.set(selectorSuffix, rule);\n this.trackSelector(rule.getSelector());\n }\n\n return rule;\n }\n\n /**\n * Sibling of {@link createStyleRule} for a per-instance state rule that has\n * class-level defaults to dedupe against. `resolveDefaults` is called once,\n * eagerly, at this call site — matching how `applyStyle` eagerly calls\n * `getClassStyleDefaults()` on every render regardless of whether the class\n * rule already exists. Cache the returned wrapper in a private `??=` getter,\n * the same idiom `createStyleRule` callers already use (see `Button.pressedStyleRule`),\n * so `resolveDefaults` runs at most once per instance.\n *\n * @param selectorSuffix - CSS selector text appended to `#<id>` to form\n * the instance rule's selector, and to `.ClassName`\n * to form the shared class-tier rule's selector.\n * @param resolveDefaults - Returns this class's resolved declarations for\n * the suffixed state, e.g. `() => this.getPressedClassDeclarations()`.\n * @param extractorMethodName - Name of the `protected static` extraction\n * method (e.g. `\"extractPressedClassDeclarations\"`)\n * each hierarchy-participating ancestor may\n * declare its own copy of. Omit to keep the flat,\n * non-hierarchy-aware behaviour every existing\n * caller already gets.\n *\n * @returns The `StateStyleRule` wrapper.\n */\n protected createStateStyleRule(\n selectorSuffix: string,\n resolveDefaults: () => Record<string, string | null>,\n extractorMethodName?: string,\n ): StateStyleRule {\n return new StateStyleRule(\n this.constructor,\n selectorSuffix,\n this.createStyleRule(selectorSuffix),\n resolveDefaults,\n () => !!this.getElement(),\n extractorMethodName,\n );\n }\n\n /**\n * Returns the DOM element, querying by ID; creates and renders it if createIfMissing is true.\n *\n * @param createIfMissing - Optional. When true, renders and returns a new element if none exists in the DOM.\n *\n * @returns The component's element handle, or undefined if it does not exist and createIfMissing is false.\n */\n getElement(createIfMissing: boolean = false): Handle | undefined {\n if (!this._element) {\n // The lookup may miss (null); getElement's callers treat the result\n // as present, gating on `createIfMissing` / their own null checks.\n let element = DOM.source.getElementById(this.getId()) as Handle;\n if (!element && createIfMissing) {\n element = this.render();\n }\n\n this._element = element;\n }\n\n return this._element;\n }\n\n /**\n * Returns the element that carries this component's native scroll — the\n * target every scroll read/write, the child host, and the content frame\n * resolve through. Defaults to the component's own element; a subclass whose\n * scroll happens on an inner element (see [`Panel`](/api/core/classes/Panel)'s overlay-scrollbar\n * mode) overrides this so all scroll plumbing follows the inner scroller\n * without each call site needing to know about it.\n *\n * @returns The scroll-owning element handle, or undefined before render.\n */\n protected getScrollElement(): Handle | undefined {\n return this.getElement();\n }\n\n /**\n * Removes the component's DOM element from the document.\n */\n removeElement(): this {\n let element = this.getElement();\n if (!element) {\n return this;\n }\n\n // Tear any active clip / content frame down first so the wrapper is\n // removed with the element rather than orphaned in the DOM once the\n // element leaves.\n this.clearClipFrame();\n this.clearContentFrame();\n\n DOM.sink.removeElement(element);\n\n return this;\n }\n\n /**\n * Releases this component's DOM element — detaches the node from the\n * document and clears the cached handle — while keeping the component\n * object alive and reusable. A fresh element is built lazily the next time\n * getElement(true) is called. Distinct from dispose(), which destroys the\n * component. Refused (returns false, no-op) unless the component opts in by\n * overriding the release gate; also a no-op when no element is materialised.\n *\n * @returns true if an element was released, false if refused or none was live.\n */\n release(): boolean {\n if (!this.canRelease()) {\n return false;\n }\n\n // Read the field directly — NOT getElement(), which would resurrect a\n // detached node by id.\n const element = this._element;\n if (!element) {\n return false;\n }\n\n // Capture focus intent before the node leaves the document.\n this._refocusOnRematerialize = DOM.source.getActiveElement() === element;\n\n // Tear any active clip / content frame down first so their fields reset\n // to null and the next layout re-frames the fresh element (mirrors\n // destructor()'s teardown, minus child/theme/style-rule disposal).\n this.clearClipFrame();\n this.clearContentFrame();\n\n // Detach the node so getElement()'s by-id lookup misses and render() runs.\n DOM.sink.removeElement(element);\n\n // Abandon any transition still running against the handle released below.\n // A pending deferred write — Animation.play's two-frame entrance dance, or\n // its completion — would otherwise resolve a released handle and throw.\n // Mirrors destructor()'s same guard.\n cancelTransitions(element);\n\n // Drop the outgoing handle so it can never be resolved again and\n // _ownedHandles does not accumulate a dead entry per release cycle.\n DOM.sink.release(element);\n this.untrackHandle(element);\n\n this._element = undefined;\n this._pendingRematerialize = true;\n\n return true;\n }\n\n /**\n * Wraps this component's element in a clip frame — a presentational wrapper\n * element positioned at `(x, y)`, sized `width`×`height`, with\n * `overflow: hidden` — and parks this element at `(0, 0)` inside it. Lets a\n * layout manager visually clip an element that is wider or taller than its\n * allotted cell without fighting the element's own `min-width` /\n * `min-height` CSS floor (which `overflow: hidden` on the element itself\n * cannot, since it clips only descendants, not the element's own box).\n *\n * @param x - Left edge of the frame in the parent's coordinate space.\n * @param y - Top edge of the frame in the parent's coordinate space.\n * @param width - Frame width in pixels; element content beyond it is clipped.\n * @param height - Frame height in pixels; element content beyond it is clipped.\n *\n * @returns This component, for method chaining.\n *\n * @remarks Idempotent: re-calling with a new rect resizes the existing\n * frame rather than creating a second one. No-op when the element is not\n * yet in the DOM — the layout manager drives this from a layout pass, by\n * which point the element exists. The frame carries no id and no listeners,\n * so subtree event delegation (which keys off element ids while walking\n * ancestors) routes through it unaffected.\n */\n setClipFrame(x: number, y: number, width: number, height: number): this {\n const element = this.getElement();\n if (!element) {\n return this;\n }\n\n if (!this._clipFrame) {\n const parent = DOM.source.getParentNode(element);\n\n // `position: absolute` (applied by createFrame) makes the frame the\n // containing block for the absolutely positioned element parked\n // inside it, so the element's `(0, 0)` resolves against the frame;\n // `overflow: hidden` clips a child larger than the cell rect.\n const frame = this.createFrame(this._clipFrameStyle, { overflow: \"hidden\" });\n this._clipFrame = frame;\n\n if (parent) {\n DOM.sink.insertBefore(parent, frame, element);\n }\n\n DOM.sink.appendChild(frame, element);\n }\n\n this._clipFrameStyle.setMany({\n left: x + \"px\",\n top: y + \"px\",\n width: width + \"px\",\n height: height + \"px\"\n });\n\n return this;\n }\n\n /**\n * Removes the clip frame installed by {@link setClipFrame}, re-parenting\n * this element back to the frame's parent at the frame's former DOM\n * position. No-op when no frame is active, so callers can invoke it\n * unconditionally on the non-clipped path.\n *\n * @returns This component, for method chaining.\n */\n clearClipFrame(): this {\n const frame = this._clipFrame;\n if (!frame) {\n return this;\n }\n\n const element = this.getElement();\n const parent = DOM.source.getParentNode(frame);\n\n if (element && parent) {\n DOM.sink.insertBefore(parent, element, frame);\n }\n\n // disposeFrame removes the wrapper and returns a fresh buffer — the old\n // one was bound to the now-removed frame.\n this._clipFrameStyle = this.disposeFrame(frame);\n this._clipFrame = null;\n\n return this;\n }\n\n /**\n * Creates a presentational frame `<div>` for {@link setClipFrame} /\n * {@link setContentFrame}: a non-interactive sheath with no id and no\n * listeners, positioned absolutely so it can act as a containing block.\n * The caller's {@link InlineStyle} buffer is attached and seeded with\n * `position: absolute` plus any `base` overrides (e.g. `overflow: hidden`\n * for a clip frame); the caller is responsible for the geometry writes and\n * for splicing the returned element into the DOM.\n *\n * @param style - The buffer to attach to the new frame and write through.\n * @param base - Extra CSS properties applied alongside `position: absolute`.\n *\n * @returns The freshly created, styled frame element handle.\n */\n private createFrame(style: InlineStyle, base: Record<string, string>): Handle {\n const frame = DOM.sink.createElement(\"div\");\n\n this.trackHandle(frame);\n style.attach(frame);\n style.setMany({ position: \"absolute\", ...base });\n\n return frame;\n }\n\n /**\n * Tears a frame created by {@link createFrame} down: removes it from the DOM\n * and returns a fresh {@link InlineStyle} for the caller to assign back to\n * its buffer field. A fresh buffer is required because the previous one was\n * bound to the now-removed frame. The caller must re-parent any wrapped\n * nodes out of the frame before calling this.\n *\n * @param frame - The frame element handle to remove.\n *\n * @returns A new, unattached InlineStyle buffer.\n */\n private disposeFrame(frame: Handle): InlineStyle {\n DOM.sink.removeElement(frame);\n this.untrackHandle(frame);\n DOM.sink.release(frame);\n\n return new InlineStyle();\n }\n\n /**\n * Wraps this container's children in a content frame sized to\n * `width`×`height` and re-parents every child into it, so the host's native\n * scroll extent equals the frame's box rather than the children's bounding\n * rect. A layout manager calls this when the children's content (including\n * both insets) overflows the container, sizing the frame to the full content\n * extent so the trailing inset is reserved as scrollable space — the mirror\n * of {@link setClipFrame}, which clips a single oversized child instead.\n *\n * Idempotent: when a frame already exists it is only resized. The frame is\n * id-less and carries no listeners, so it is transparent to subtree event\n * delegation (which walks the ancestor chain by id). No-op when the element\n * is not in the DOM.\n *\n * @param width - The content-frame width in pixels.\n * @param height - The content-frame height in pixels.\n *\n * @returns This component, for method chaining.\n */\n setContentFrame(width: number, height: number): this {\n const element = this.getScrollElement();\n if (!element) {\n return this;\n }\n\n if (!this._contentFrame) {\n // Re-parenting the child set can reset the host's native scroll\n // offset; capture and restore it around the move.\n const scrollLeft = DOM.source.getScrollLeft(element);\n const scrollTop = DOM.source.getScrollTop(element);\n\n // `left/top: 0` parks the frame at the container's padding-box\n // origin, so children keep their existing coordinates inside it.\n const frame = this.createFrame(this._contentFrameStyle, { left: \"0px\", top: \"0px\" });\n this._contentFrame = frame;\n\n // Move each child by its OUTERMOST node (its clip frame when one is\n // active, else its element) so a clip-framed child stays wrapped.\n for (const component of this._components) {\n const node = component.getAttachNode();\n\n if (node) {\n DOM.sink.appendChild(frame, node);\n }\n }\n\n DOM.sink.appendChild(element, frame);\n\n DOM.sink.apply(element, { scrollLeft, scrollTop });\n }\n\n this._contentFrameStyle.setMany({\n width: width + \"px\",\n height: height + \"px\"\n });\n\n return this;\n }\n\n /**\n * Removes the content frame installed by {@link setContentFrame},\n * re-parenting the children back onto the element. No-op when no frame is\n * active, so a layout manager can call it unconditionally on the\n * non-overflowing path.\n *\n * @returns This component, for method chaining.\n */\n clearContentFrame(): this {\n const frame = this._contentFrame;\n if (!frame) {\n return this;\n }\n\n const element = this.getScrollElement();\n\n if (element) {\n const scrollLeft = DOM.source.getScrollLeft(element);\n const scrollTop = DOM.source.getScrollTop(element);\n\n // Re-parent the children back onto the element by their outermost\n // node before the frame is removed.\n for (const component of this._components) {\n const node = component.getAttachNode();\n\n if (node) {\n DOM.sink.appendChild(element, node);\n }\n }\n\n DOM.sink.apply(element, { scrollLeft, scrollTop });\n }\n\n this._contentFrameStyle = this.disposeFrame(frame);\n this._contentFrame = null;\n\n return this;\n }\n\n /**\n * Returns the DOM node this component occupies in its parent's child list:\n * the clip frame when one is active (see {@link setClipFrame}), otherwise\n * the component's own element. Sibling DOM positioning must reference this\n * node rather than `getElement()`, because a clip-framed component's\n * element sits inside its frame, not directly under the container.\n *\n * @returns The frame element when clipped, else the component's element, or\n * undefined when the element is not yet in the DOM.\n */\n protected getAttachNode(): Handle | null | undefined {\n return this._clipFrame ?? this.getElement();\n }\n\n /**\n * Returns the DOM node this component's children attach to: its content\n * frame when one is active (see {@link setContentFrame}), otherwise its own\n * element. The mirror of {@link getAttachNode} — that answers \"what node do\n * I occupy in my parent\", this answers \"where do my children attach\".\n *\n * @returns The content frame when active, else the component's element, or\n * undefined when the element is not yet in the DOM.\n */\n private getChildHost(): Handle | undefined {\n return this._contentFrame ?? this.getScrollElement();\n }\n\n /**\n * Moves this component's rendered content from one host element to another,\n * preserving the source's native scroll offset across the move: the active\n * content frame as a unit when one exists (see {@link setContentFrame}), else\n * each child by its outermost {@link getAttachNode} node (so a clip-framed\n * child stays wrapped). Used by a subclass that relocates the scroll host —\n * see [`Panel`](/api/core/classes/Panel)'s overlay inner scroller, which shifts existing children\n * onto the inner element on install and back onto the panel element on\n * teardown — mirroring the re-parent dance {@link setContentFrame} performs.\n *\n * @param from - The element the content currently lives in (its scroll\n * offset is captured).\n * @param to - The element to move the content into (the captured offset is\n * restored here).\n */\n protected reparentContent(from: Handle, to: Handle): void {\n const scrollLeft = DOM.source.getScrollLeft(from);\n const scrollTop = DOM.source.getScrollTop(from);\n\n if (this._contentFrame) {\n DOM.sink.appendChild(to, this._contentFrame);\n } else {\n for (const component of this._components) {\n const node = component.getAttachNode();\n\n if (node) {\n DOM.sink.appendChild(to, node);\n }\n }\n }\n\n DOM.sink.apply(to, { scrollLeft, scrollTop });\n }\n\n /**\n * Returns whether the DOM element has the given attribute set.\n *\n * @param key - The attribute name to check.\n *\n * @returns True if the attribute exists, false otherwise, or undefined if the element is not in the DOM.\n */\n hasElementAttribute(key: string): boolean | undefined {\n let element = this.getElement();\n if (!element) {\n //console.warn(\"Component #\" + this.id + \" is not yet in the DOM.\");\n return;\n }\n\n return DOM.source.hasAttribute(element, key);\n }\n\n /**\n * Returns the value of a DOM element attribute, or undefined if the element is not in the DOM.\n *\n * @param key - The attribute name to retrieve.\n *\n * @returns The attribute value string, null if the attribute is absent, or undefined if the element is not in the DOM.\n */\n getElementAttribute(key: string): string | null | undefined {\n let element = this.getElement();\n if (!element) {\n //console.warn(\"Component #\" + this.id + \" is not yet in the DOM. Attribute '\" + key + \"' can not be retrieved.\");\n return;\n }\n\n return DOM.source.getAttribute(element, key);\n }\n\n /**\n * Sets a DOM element attribute; removes it if value is null/undefined.\n *\n * @param key - The attribute name.\n * @param value - The attribute value. Passing null or undefined removes the attribute.\n *\n * @returns This component, for method chaining.\n *\n * @remarks The value is held by a buffer that binds to the element at\n * render and writes through afterwards, so a value set while the\n * component is detached survives until the element is created (and any\n * later re-render). A write made after the element exists reaches it\n * immediately unless a batching window is open (see\n * {@link setAutoCommitAttributes}).\n */\n protected setElementAttribute(key: string, value: Object | null | undefined): this {\n if (value === null || value === undefined) {\n return this.removeElementAttribute(key);\n }\n\n const stringValue = String(value);\n\n if (this._autoCommitAttributes) this._elementAttributes.set(key, stringValue);\n else this._elementAttributes.queue(key, stringValue);\n\n return this;\n }\n\n /**\n * Removes an attribute from the DOM element.\n *\n * @param key - The attribute name to remove.\n *\n * @returns This component, for method chaining.\n *\n * @remarks Drops the cached entry the attribute buffer would otherwise\n * replay, in addition to removing the attribute from a live element\n * unless a batching window is open (see {@link setAutoCommitAttributes}).\n */\n protected removeElementAttribute(key: string): this {\n if (this._autoCommitAttributes) this._elementAttributes.remove(key);\n else this._elementAttributes.queueRemove(key);\n\n return this;\n }\n\n /**\n * Queues a single inline style property for commit to the DOM element.\n *\n * @param key - The CSS property name (camelCase).\n * @param value - The value to set, or null to remove the property.\n *\n * @remarks Immediately flushes to the DOM unless autoCommitStyle is false.\n */\n protected setElementStyle(key: string, value: Object | null): this {\n const v = value ? String(value) : null;\n\n if (this._autoCommitStyle) {\n this._inlineStyle.set(key, v);\n } else {\n this._inlineStyle.queue(key, v);\n }\n\n return this;\n }\n\n /**\n * Queues multiple inline style properties for commit to the DOM element.\n *\n * @param values - An object whose keys are camelCase CSS property names and values are strings or null.\n *\n * @remarks Immediately flushes to the DOM unless autoCommitStyle is false.\n */\n protected setElementStyles(values: Style): this {\n if (this._autoCommitStyle) {\n this._inlineStyle.setMany(values);\n } else {\n this._inlineStyle.queueMany(values);\n }\n\n return this;\n }\n\n /**\n * Returns whether style changes are immediately committed to the DOM.\n *\n * @returns True if auto-commit is enabled, false if changes are batched.\n */\n getAutoCommitStyle(): boolean {\n return this._autoCommitStyle;\n }\n\n /**\n * Enables or disables auto-commit; flushing all pending style and CSS rule changes when re-enabled.\n *\n * @param value - True to enable immediate commits; false to batch changes until manually flushed.\n */\n setAutoCommitStyle(value: boolean): this {\n this._autoCommitStyle = value;\n\n if (value) {\n this.commitElementStyle();\n this.commitCSSRule();\n }\n\n return this;\n }\n\n /**\n * Flushes all queued inline style changes to the DOM element and clears the dirty map.\n */\n protected commitElementStyle(): this {\n // `inlineStyle.flush()` is a no-op when the element isn't yet attached\n // — dirty entries stay queued for the next flush after `init()`.\n this._inlineStyle.flush();\n\n return this;\n }\n\n /**\n * Returns whether attribute changes are immediately committed to the DOM.\n *\n * @returns True if auto-commit is enabled, false if changes are batched.\n */\n getAutoCommitAttributes(): boolean {\n return this._autoCommitAttributes;\n }\n\n /**\n * Enables or disables auto-commit; flushing all pending attribute changes when re-enabled.\n *\n * @param value - True to enable immediate commits; false to batch changes until manually flushed.\n */\n setAutoCommitAttributes(value: boolean): this {\n this._autoCommitAttributes = value;\n\n if (value) {\n this.commitElementAttributes();\n }\n\n return this;\n }\n\n /**\n * Flushes all queued attribute changes to the DOM element and clears the pending set.\n */\n protected commitElementAttributes(): this {\n this._elementAttributes.flush();\n\n return this;\n }\n\n /**\n * Queues multiple CSS rule properties for commit to the component's CSS rule.\n *\n * @param values - An object whose keys are camelCase CSS property names and values are strings or null.\n *\n * @remarks Immediately flushes to the CSS rule unless autoCommitStyle is false.\n */\n protected setElementCSSRules(values: Style): this {\n // The rule is created lazily, so writes go through `queue` until the\n // element exists; `commitCSSRule` only flushes once an element is\n // attached, matching the prior `dirtyCSSRule` gating.\n this._styleRule.queueMany(values);\n\n if (this._autoCommitStyle) {\n this.commitCSSRule();\n }\n\n return this;\n }\n\n /**\n * Queues a single CSS rule property for commit to the component's CSS rule.\n *\n * @param key - The CSS property name (camelCase).\n * @param value - The value to set, or null to remove the property.\n *\n * @remarks Immediately flushes to the CSS rule unless autoCommitStyle is false.\n */\n protected setElementCSSRule(key: string, value: Object | null): this {\n this._styleRule.queue(key, value ? String(value) : null);\n\n if (this._autoCommitStyle) {\n this.commitCSSRule();\n }\n\n return this;\n }\n\n /**\n * Flushes all queued CSS rule changes to the component's CSS rule and clears the dirty map.\n *\n * @remarks Skips the flush entirely when the element has not yet been\n * rendered — the dirty entries stay queued and are picked up by the next\n * {@link ensureCSSRule} call (typically driven by `render()`).\n * Avoids inserting a stylesheet rule for components that are constructed\n * but never attached. Once attached, also skips inserting the rule when\n * nothing queued would produce a real declaration — see\n * {@link materialiseWhenNeeded}.\n */\n protected commitCSSRule(): this {\n // Gate on element existence (matches prior `dirtyCSSRule` behaviour):\n // avoids inserting a stylesheet rule for components that are\n // constructed but never attached.\n if (!this.getElement()) {\n return this;\n }\n\n this.materialiseWhenNeeded(this._styleRule);\n this._styleRule.flush();\n\n return this;\n }\n\n /**\n * Sets the component ID and updates the DOM element's id attribute if the element exists.\n *\n * @param id - The new unique identifier for this component.\n */\n setId(id: string): this {\n const oldId = this.getId();\n\n super.setId(id);\n\n Event.reindexComponent(oldId, id);\n\n // The per-component style rule is selector-scoped to `#<id>` and carries\n // `position: absolute` (plus every other rule-based style). It is created\n // from the initial id (the auto-UUID) before the constructor's\n // `applyOptions` can process an `id` option, so any id change — whether a\n // construction-time `{ id }` or a later `setId` — must re-point it, or\n // the rule stops matching the element and the component silently falls\n // back to `position: static`. Re-derive it here from the new id; the\n // values are replayed from the component's fields by `applyStyle` at\n // render (and immediately below when already rendered).\n this._styleRule = new StyleRule({ scope: \"component\", name: id, materialize: false });\n this.trackSelector(this._styleRule.getSelector());\n\n let element = this.getElement();\n if (!element) {\n return this;\n }\n\n DOM.sink.setId(element, id);\n this.applyStyle(element);\n\n return this;\n }\n\n /**\n * Returns the component's human-readable title — its intrinsic name,\n * distinct from the unique {@link getId} identifier. Set via the `name`\n * option or {@link setName}; `null` when unset. The\n * [`Tab`](/api/layout/classes/Tab) layout reads it for a tab button's label\n * (and a torn-off window's title) when no per-placement\n * `LayoutConstraints.name` override is present.\n *\n * @returns The component's name, or `null` when none has been set.\n */\n getName(): string | null {\n return this._options.name ?? null;\n }\n\n /**\n * Sets the component's human-readable title. Pure metadata — it writes no\n * DOM and does not affect layout; consumers such as the\n * [`Tab`](/api/layout/classes/Tab) layout read it to label the component.\n * The name travels with the component across re-parents (it lives on the\n * component, not on a parent's layout constraint).\n *\n * @param name - The new name, or `null` to clear it.\n *\n * @returns This component, for method chaining.\n */\n setName(name: string | null): this {\n this._options.name = name;\n\n return this;\n }\n\n /**\n * Returns this component's `styleGroup` token — the caller-supplied\n * string that lets several instances of the same concrete class share\n * one generated `.ClassName--<group>` CSS rule instead of each carrying\n * its own. `null` when unset.\n *\n * @returns The `styleGroup` token, or `null` when none has been set.\n */\n getStyleGroup(): string | null {\n return this._options.styleGroup ?? null;\n }\n\n /**\n * Sets this component's `styleGroup` token. Two instances of the same\n * concrete class constructed with the same token compare their resolved\n * hoistable style (background/border/cursor/foregroundColor/outline/\n * userSelect/shadow/minSize/maxSize/overflow) and share one rule for\n * whatever agrees; a genuine deviation still writes to that instance's\n * own rule, exactly as an ungrouped instance would.\n *\n * @remarks The group's shared content is fixed by whichever instance in\n * the group renders *first* — a later instance passing a different\n * value under the same token is treated as a per-instance deviation\n * (written to its own rule), not an error. Choose a token deliberately\n * for instances that are meant to look identical; the group's exact\n * resolved content is otherwise not predictable from source alone\n * without knowing render order.\n *\n * @param group - The new token, or `null` to clear it.\n *\n * @returns This component, for method chaining.\n */\n setStyleGroup(group: string | null): this {\n this._options.styleGroup = group;\n\n return this;\n }\n\n /**\n * Returns a data attribute value from the component's cached `data-*`\n * attribute map.\n *\n * @param key - The attribute name (with or without the `data-` prefix).\n *\n * @returns The stored attribute value, or undefined if not set.\n *\n * @remarks Symmetric with {@link setDataAttribute}: the key is normalised\n * with a leading `data-` (idempotent if already prefixed) before lookup.\n * Reads the component's attribute buffer, not the live DOM, so it stays\n * correct while detached and inside an open batching window.\n */\n getDataAttribute(key: string): string | undefined {\n const dataKey = key.startsWith(\"data-\") ? key : `data-${key}`;\n\n return this._elementAttributes.get(dataKey);\n }\n\n /**\n * Stores a component-level data attribute and mirrors it as `data-<key>`\n * on the DOM element.\n *\n * @param key - The attribute name (with or without the `data-` prefix).\n * @param value - The attribute value. Passing null delegates to {@link delDataAttribute}.\n *\n * @remarks `setDataAttribute` is for *data-carrying* attributes — debug\n * markers, framework-internal identity reflection (`data-layout`), and\n * other consumer-readable `data-*` tags. Behavioral HTML attributes the\n * browser interprets (placeholder, readonly, inputmode, …) use the\n * `setElementAttribute` low-level seam instead.\n */\n setDataAttribute(key: string, value: string): this {\n if (value === null) {\n return this.delDataAttribute(key);\n }\n\n const dataKey = key.startsWith(\"data-\") ? key : `data-${key}`;\n\n return this.setElementAttribute(dataKey, value);\n }\n\n /**\n * Removes a component-level data attribute from both the internal map and\n * the DOM element.\n *\n * @param key - The attribute name (with or without the `data-` prefix).\n */\n delDataAttribute(key: string): this {\n const dataKey = key.startsWith(\"data-\") ? key : `data-${key}`;\n\n return this.removeElementAttribute(dataKey);\n }\n\n /**\n * Returns the visibility state, or null if inherited from the parent.\n *\n * @returns True if explicitly visible, false if explicitly hidden, null if inheriting from the parent.\n */\n isVisible(): boolean | null {\n // Key-presence so a never-set component folds the class default (e.g.\n // AnimatedDropdown's `visible: false`), while an explicit\n // `setVisible(false)`/inherit still wins — mirrors getCursor/getPadding.\n return \"visible\" in this._options\n ? (this._options.visible ?? null)\n : (this._defaultOptions.visible ?? null);\n }\n\n /**\n * Sets visibility; true = visible, false = hidden, null/falsy = inherit from parent.\n *\n * @param value - True to show the component, false to hide it, or a falsy non-boolean to inherit.\n *\n * @remarks Throws an Error if value is a non-boolean truthy value.\n */\n setVisible(value: boolean | null): this {\n // `Type.isBoolean` runtime-checks arbitrary input (untyped callers can\n // still pass a non-boolean); the cast bridges its `object` parameter to\n // the narrowed `boolean | null` static type without altering behaviour.\n // Normalize to the tri-state target first (same branch logic as\n // before) so the idempotency guard below can compare against it.\n let normalized: boolean | undefined;\n if (Type.isBoolean(value as unknown as object)) {\n normalized = value as boolean;\n } else if (!value) {\n normalized = undefined;\n } else {\n throw new Error(\"Argument is not a boolean.\");\n }\n\n // Idempotent short-circuit, mirroring setDisplayed: skip the redundant\n // CSS write + reconcile enqueue when the normalized value is unchanged\n // and the element exists. A detached component (no element) falls\n // through to record the value at the `if (!element) return this;`\n // guard below, so the intended state is never lost.\n if (this._options.visible === normalized && this.getElement()) {\n return this;\n }\n\n this._options.visible = normalized;\n\n let element = this.getElement();\n if (!element) {\n return this;\n }\n\n let ruleValue;\n const visible = this._options.visible;\n if (visible != null) {\n ruleValue = visible ? \"inherit\" : \"hidden\";\n } else {\n ruleValue = \"inherit\";\n }\n\n this.setReconciledCSSRules({ visibility: ruleValue });\n this.scheduleEffectiveVisibilityReconcile();\n\n return this;\n }\n\n /**\n * Sets the CSS z-index of the component.\n *\n * @param value - The z-index value.\n */\n setZIndex(value: number): this {\n if (this._options.zIndex === value) {\n return this;\n }\n\n this._options.zIndex = value;\n this.setElementStyle(\"zIndex\", value);\n\n return this;\n }\n\n /**\n * Returns the effective z-index — the caller/setter value, else the\n * class-level default (0 for a plain Component).\n *\n * @returns The resolved z-index.\n */\n getZIndex(): number {\n return (this._options.zIndex ?? this._defaultOptions.zIndex ?? 0) as number;\n }\n\n /**\n * Returns the {@link Aria} helper for this component, creating it lazily on first access.\n *\n * @returns The ARIA helper instance.\n */\n getAria(): Aria {\n if (!this._aria) {\n this._aria = new Aria(this);\n }\n\n return this._aria;\n }\n\n /**\n * Shows or hides the component using CSS display; hidden components take no space.\n *\n * @param value - True to show the component, false to set display to \"none\".\n *\n * @returns This component, for method chaining.\n */\n setDisplayed(value: boolean): this {\n const v = !!value;\n if (this._options.displayed === v && this.getElement()) {\n return this;\n }\n\n this._options.displayed = v;\n\n let element = this.getElement();\n if (!element) {\n return this;\n }\n\n this.setElementStyle(\"display\", v ? \"block\" : \"none\");\n this.scheduleEffectiveVisibilityReconcile();\n\n return this;\n }\n\n /**\n * Returns whether the component participates in layout. A `false` value\n * (set via `setDisplayed`) maps the element to CSS `display: none`, so it\n * occupies no space and its parent's layout manager skips it (see\n * `getLaidOutComponents`).\n *\n * @returns `true` unless `setDisplayed(false)` was called; never null\n * (unlike `isVisible`, which is tri-state for inherited visibility).\n */\n isDisplayed(): boolean {\n return (this._options.displayed ?? this._defaultOptions.displayed) as boolean;\n }\n\n /**\n * Walks this component and its ancestor chain, returning whether it is\n * actually on-screen — as opposed to `isVisible()` / `isDisplayed()`, which\n * report only this component's own state and don't see an ancestor that\n * hides it. A `Tab` / `Card` hides an inactive panel with `setVisible(false)`\n * (CSS `visibility: hidden`) while keeping its layout slot, so a descendant's\n * own `isVisible()` stays `null` (inherit) even though it is not effectively\n * shown; this walks up to catch that case.\n *\n * @returns `false` if this component or any ancestor is explicitly hidden\n * (`isVisible() === false`) or undisplayed (`!isDisplayed()`); `true`\n * otherwise.\n */\n isEffectivelyVisible(): boolean {\n let node: Component | null = this;\n while (node) {\n if (node.isVisible() === false || !node.isDisplayed()) {\n return false;\n }\n node = node.getParentComponent();\n }\n return true;\n }\n\n /**\n * Override hook fired once per node whose effective visibility changed,\n * edge-triggered by {@link propagateEffectiveVisibility}. The base\n * implementation pauses this node's own CSS animation (via the\n * `animation-play-state` longhand on its `#uuid` rule) when it has one, and\n * resumes it when shown again — subclasses that need to react to the same\n * signal (e.g. a canvas render loop) override this and call `super`.\n *\n * @param effective - The component's new effective-visibility state.\n */\n protected onEffectiveVisibilityChange(effective: boolean): void {\n if (this.getAnimation() !== null) {\n this.setAnimationPlayState(effective ? null : \"paused\");\n }\n }\n\n /**\n * Recursively fans an effective-visibility change down the subtree,\n * short-circuiting at any node whose effective value is unchanged (an\n * independent descendant change is separately queued through its own\n * `setVisible`/`setDisplayed`, so an unchanged node never needs to recurse).\n * Called by the module-level coalesced flush on each queued root; public and\n * `@internal` because the flush needs to invoke it on arbitrary instances —\n * consumers react to {@link onEffectiveVisibilityChange} instead of calling\n * this directly.\n *\n * @param effective - This node's newly computed effective-visibility state.\n *\n * @internal\n */\n public propagateEffectiveVisibility(effective: boolean): void {\n if (effective === this._lastEffectiveVisible) {\n return;\n }\n this._lastEffectiveVisible = effective;\n this.onEffectiveVisibilityChange(effective);\n\n for (const child of this.getComponents()) {\n const childEffective =\n effective && child.isVisible() !== false && child.isDisplayed();\n child.propagateEffectiveVisibility(childEffective);\n }\n }\n\n /**\n * Queues this component for the next coalesced effective-visibility flush,\n * mirroring `scheduleLayout`. Called by `setVisible` / `setDisplayed` after\n * a real state change.\n */\n private scheduleEffectiveVisibilityReconcile(): void {\n pendingVisibility.add(this);\n ensureVisibilityFlushScheduled();\n }\n\n /**\n * Returns the component's insets (internal spacing used by layout managers).\n *\n * @returns The current Insets instance.\n */\n getInsets(): Insets {\n return (this._options.insets ?? this._defaultOptions.insets) as Insets;\n }\n\n /**\n * Sets the component's insets. Use {@link clearInsets} to reset to zero.\n *\n * @param insets - The new Insets.\n *\n * @returns This component, for method chaining.\n */\n setInsets(insets: Insets): this {\n this._options.insets = insets;\n this.setDataAttribute(\"insets\", insets.render());\n\n return this;\n }\n\n /**\n * Resets the component's insets to zero on all sides.\n *\n * @returns This component, for method chaining.\n *\n * @remarks Companion to {@link setInsets}. Resets to\n * `new Insets(0, 0, 0, 0)` — semantically a \"reset to default\" rather than\n * a CSS-level clear.\n */\n clearInsets(): this {\n const insets = new Insets(0, 0, 0, 0);\n this._options.insets = insets;\n this.setDataAttribute(\"insets\", insets.render());\n\n return this;\n }\n\n /**\n * Returns the CSS padding insets for this component.\n *\n * @returns The current padding Insets, or null if none are set.\n */\n getPadding(): Insets | null {\n return \"padding\" in this._options ? (this._options.padding ?? null) : (this._defaultOptions.padding ?? null);\n }\n\n /**\n * Sets the CSS padding. Use {@link clearPadding} to reset to `\"0px 0px 0px 0px\"`.\n *\n * @param padding - The new padding Insets.\n *\n * @returns This component, for method chaining.\n */\n setPadding(padding: Insets): this {\n const current = this._options.padding;\n if (current &&\n current.getTop() === padding.getTop() &&\n current.getRight() === padding.getRight() &&\n current.getBottom() === padding.getBottom() &&\n current.getLeft() === padding.getLeft()) {\n return this;\n }\n\n this._options.padding = padding;\n this.setElementCSSRule(\"padding\", padding.render() as string);\n\n return this;\n }\n\n /**\n * Resets the CSS padding to zero on all sides.\n *\n * @returns This component, for method chaining.\n *\n * @remarks Companion to {@link setPadding}. Writes\n * `\"0px 0px 0px 0px\"` rather than removing the property — preserves the\n * legacy `setPadding(null)` behaviour as a reset, not a CSS-level clear.\n */\n clearPadding(): this {\n this._options.padding = undefined;\n this.setElementCSSRule(\"padding\", \"0px 0px 0px 0px\");\n\n return this;\n }\n\n /**\n * Returns the per-side offset a layout manager must apply to a child's\n * origin: insets plus CSS padding, border excluded.\n *\n * @returns An Insets whose sides are `inset + padding`.\n *\n * @remarks Framework components are absolutely positioned, so a child's\n * containing block is its parent's padding box. A child placed at\n * `left: 0` therefore lands at the inner edge of the border — the outer\n * edge of the padding — and the browser does not shift it inward by the\n * padding. `getInnerSize` has already subtracted padding from the usable\n * width/height, so a layout manager must add padding back into the child\n * origin or the whole padding allowance piles onto the far side. Border is\n * deliberately omitted: the containing-block edge already sits inside it.\n * Derived on each call from {@link getInsets} and {@link getPadding}; no\n * stored field, mirroring {@link getPerimeterSize}.\n */\n getContentInsets(): Insets {\n const insets = this.getInsets();\n const padding = this.getPadding();\n\n if (!padding) {\n return new Insets(insets.getTop(), insets.getRight(), insets.getBottom(), insets.getLeft());\n }\n\n return new Insets(\n insets.getTop() + padding.getTop(),\n insets.getRight() + padding.getRight(),\n insets.getBottom() + padding.getBottom(),\n insets.getLeft() + padding.getLeft()\n );\n }\n\n /**\n * Returns the component's background color, or null if inherited.\n *\n * @returns The CSS color string, or null if none is set.\n */\n getBackgroundColor(): string | null {\n return \"backgroundColor\" in this._options ? (this._options.backgroundColor ?? null) : (this._defaultOptions.backgroundColor ?? null);\n }\n\n /**\n * Sets the background color CSS property. Use {@link clearBackgroundColor} to inherit.\n *\n * @param backgroundColor - A CSS color string.\n *\n * @returns This component, for method chaining.\n */\n setBackgroundColor(backgroundColor: string): this {\n if (this._options.backgroundColor === backgroundColor) {\n return this;\n }\n\n this._options.backgroundColor = backgroundColor;\n this.setReconciledCSSRules({ backgroundColor });\n\n return this;\n }\n\n /**\n * Removes the background-color CSS property so the element inherits from its parent.\n *\n * @returns This component, for method chaining.\n */\n clearBackgroundColor(): this {\n // Set (not skip) the key so `getBackgroundColor` sees an explicit clear\n // and returns null, suppressing a class-level default.\n this._options.backgroundColor = undefined;\n\n // A bare removal would hand the property to the class rule when the\n // class defaults it, repainting the background instead of clearing\n // it — assert the CSS initial value instead so \"clear\" always means\n // \"paint nothing\".\n this.setReconciledCSSRules({ backgroundColor: this._defaultOptions.backgroundColor ? \"transparent\" : null });\n\n return this;\n }\n\n /**\n * Returns the CSS `background` shorthand value, or null if none is set.\n *\n * @returns The CSS background shorthand string, or null.\n */\n getBackground(): string | null {\n return this._options.background ?? null;\n }\n\n /**\n * Sets the CSS `background` shorthand property — a color, gradient, or image\n * (resetting every background layer). Use {@link clearBackground} to remove.\n *\n * @param value - A CSS `background` shorthand string.\n *\n * @returns This component, for method chaining.\n */\n setBackground(value: string): this {\n if (this._options.background === value) {\n return this;\n }\n\n this._options.background = value;\n this.setElementCSSRule(\"background\", value);\n\n return this;\n }\n\n /**\n * Removes the `background` shorthand CSS property from the component's CSS rule.\n *\n * @returns This component, for method chaining.\n */\n clearBackground(): this {\n this._options.background = undefined;\n this.setElementCSSRule(\"background\", null);\n\n return this;\n }\n\n /**\n * Returns the background image CSS value, or null if none is set.\n *\n * @returns The CSS background-image string, or null.\n */\n getBackgroundImage(): string | null {\n return this._options.backgroundImage ?? null;\n }\n\n /**\n * Sets the CSS background-image property. Use {@link clearBackgroundImage} to remove.\n *\n * @param backgroundImage - A CSS background-image string.\n *\n * @returns This component, for method chaining.\n */\n setBackgroundImage(backgroundImage: string): this {\n this._options.backgroundImage = backgroundImage;\n this.setReconciledCSSRules({ backgroundImage });\n\n return this;\n }\n\n /**\n * Removes the background-image CSS property from the component's CSS rule.\n *\n * @returns This component, for method chaining.\n */\n clearBackgroundImage(): this {\n this._options.backgroundImage = undefined;\n\n // Same reasoning as `clearBackgroundColor`: a defaulting class would\n // repaint through a bare removal, so assert the CSS initial value.\n this.setReconciledCSSRules({ backgroundImage: this._defaultOptions.backgroundImage ? \"none\" : null });\n\n return this;\n }\n\n /**\n * Sets the CSS `clip-path` on the component's own element — the box stays at\n * its full layout size while the painted (and hit-tested) area is clipped to\n * the given shape. Pass `null` to remove the clip. A layout manager can\n * transition this to visually collapse an element that refuses to shrink\n * below its min-size. Unlike {@link setClipFrame} this clips the element's\n * own box rather than interposing a wrapper, so a `clip-path` transition\n * animates in place.\n *\n * @param clipPath - A CSS `clip-path` value (e.g. `\"inset(0 100% 0 0)\"`), or `null` to clear.\n *\n * @returns This component, for method chaining.\n */\n setClipPath(clipPath: string | null): this {\n this.setElementCSSRule(\"clipPath\", clipPath);\n\n return this;\n }\n\n /**\n * Returns the foreground (text) color, or null if inherited.\n *\n * @returns The CSS color string, or null if none is set.\n */\n getForegroundColor(): string | null {\n return \"foregroundColor\" in this._options ? (this._options.foregroundColor ?? null) : (this._defaultOptions.foregroundColor ?? null);\n }\n\n /**\n * Sets the CSS color (text color). Use {@link clearForegroundColor} to inherit.\n *\n * @param foregroundColor - A CSS color string.\n *\n * @returns This component, for method chaining.\n */\n setForegroundColor(foregroundColor: string): this {\n if (this._options.foregroundColor === foregroundColor) {\n return this;\n }\n\n this._options.foregroundColor = foregroundColor;\n this.setReconciledCSSRules({ color: foregroundColor });\n\n return this;\n }\n\n /**\n * Removes the color (foreground) CSS property so the element inherits from its parent.\n *\n * @returns This component, for method chaining.\n */\n clearForegroundColor(): this {\n // Set (not skip) the key so `getForegroundColor` sees an explicit clear\n // and returns null, suppressing a class-level default.\n this._options.foregroundColor = undefined;\n this.setElementCSSRule(\"color\", null);\n\n return this;\n }\n\n getColorScheme(): string | null {\n return this._options.colorScheme ?? null;\n }\n\n /**\n * @returns This component, for method chaining.\n */\n setColorScheme(colorScheme: string): this {\n this._options.colorScheme = colorScheme;\n\n this.setElementCSSRule(\"colorScheme\", colorScheme);\n\n return this;\n }\n\n /**\n * Removes the color-scheme CSS property from the element.\n *\n * @returns This component, for method chaining.\n */\n clearColorScheme(): this {\n if (this._options.colorScheme === undefined) {\n return this;\n }\n\n this._options.colorScheme = undefined;\n this.setElementCSSRule(\"colorScheme\", null);\n\n return this;\n }\n\n /**\n * Returns the current border specification, or null if no border is set.\n *\n * @returns The current {@link BorderOptions}, or null.\n */\n getBorder(): BorderOptions | null {\n return this._border;\n }\n\n /**\n * Clears the component's border. Applies an explicit `none` on every side so\n * the cleared state overrides any inherited, class-level, or UA `<button>`\n * border styling, and invalidates the cached per-side widths.\n *\n * @returns This component, for method chaining.\n */\n clearBorder(): this {\n this._border = { border: \"none\" };\n this._borderWidths = null;\n this.setReconciledCSSRules(borderToStyle(this._border));\n\n return this;\n }\n\n /**\n * Applies a border from a {@link BorderOptions} bag or a CSS `border` shorthand\n * string. A bare string is sugar for `{ border: <string> }`. The four CSS\n * longhands are written so a per-side value survives the {@link applyStyle}\n * replay; the cached per-side widths are invalidated and re-measured lazily at\n * layout time (see {@link getBorderSize}).\n *\n * @param options - Border configuration, or a CSS `border` shorthand string. Use {@link clearBorder} to clear the border explicitly.\n *\n * @returns This component, for method chaining.\n */\n setBorder(options: BorderOptions | string): this {\n this._border = typeof options === \"string\" ? { border: options } : options;\n this._borderWidths = null;\n\n if (!this._borderThemeSubscribed) {\n this._borderThemeSubscribed = true;\n this.subscribeTheme(() => this._borderWidths = null);\n }\n\n this.setReconciledCSSRules(borderToStyle(this._border));\n\n return this;\n }\n\n /**\n * Returns the current CSS cursor value.\n *\n * @returns The CSS cursor string, or null if not set.\n */\n getCursor(): string | null {\n return \"cursor\" in this._options ? (this._options.cursor ?? null) : (this._defaultOptions.cursor ?? null);\n }\n\n /**\n * Sets the CSS cursor style on the element.\n *\n * @param cursor - A CSS cursor value (e.g. \"pointer\", \"text\", \"default\").\n *\n * @returns This component, for method chaining.\n */\n setCursor(cursor: string): this {\n if (this._options.cursor === cursor) {\n return this;\n }\n this._options.cursor = cursor;\n this.setElementStyle(\"cursor\", cursor);\n\n return this;\n }\n\n /**\n * Removes the inline cursor style from the element.\n *\n * @returns This component, for method chaining.\n */\n clearCursor(): this {\n // Set (not skip) the key so `getCursor` sees an explicit clear and\n // returns null, suppressing the class default — distinct from the\n // never-set case where the key is absent and the default applies.\n this._options.cursor = undefined;\n this.setElementStyle(\"cursor\", null);\n\n return this;\n }\n\n /**\n * Returns the CSS `touch-action` value, or null if not set.\n *\n * @returns The CSS `touch-action` string, or null.\n */\n getTouchAction(): string | null {\n return \"touchAction\" in this._options ? (this._options.touchAction ?? null) : (this._defaultOptions.touchAction ?? null);\n }\n\n /**\n * Sets the CSS `touch-action` style on the element. Use\n * {@link clearTouchAction} to remove.\n *\n * @param touchAction - A CSS `touch-action` value (e.g. \"none\", \"pan-y\", \"manipulation\").\n *\n * @returns This component, for method chaining.\n */\n setTouchAction(touchAction: string): this {\n if (this._options.touchAction === touchAction) {\n return this;\n }\n this._options.touchAction = touchAction;\n this.setElementStyle(\"touchAction\", touchAction);\n\n return this;\n }\n\n /**\n * Removes the inline `touch-action` style from the element.\n *\n * @returns This component, for method chaining.\n */\n clearTouchAction(): this {\n // Set (not skip) the key so `getTouchAction` sees an explicit clear and\n // returns null, suppressing the class default — distinct from the\n // never-set case where the key is absent and the default applies.\n this._options.touchAction = undefined;\n this.setElementStyle(\"touchAction\", null);\n\n return this;\n }\n\n /**\n * Returns the CSS border-radius value, or null if not set.\n *\n * @returns The CSS border-radius string, or null.\n */\n getBorderRadius(): string | null {\n return this._options.borderRadius ?? null;\n }\n\n /**\n * Sets the CSS border-radius on the element. Use {@link clearBorderRadius} to remove.\n *\n * @param borderRadius - A CSS border-radius string (e.g. \"4px\").\n *\n * @returns This component, for method chaining.\n */\n setBorderRadius(borderRadius: string): this {\n if (this._options.borderRadius === borderRadius) {\n return this;\n }\n this._options.borderRadius = borderRadius;\n this.setReconciledCSSRules({ borderRadius });\n\n return this;\n }\n\n /**\n * Removes the border-radius CSS property from the element.\n *\n * @returns This component, for method chaining.\n */\n clearBorderRadius(): this {\n if (this._options.borderRadius === undefined) {\n return this;\n }\n this._options.borderRadius = undefined;\n this.setElementCSSRule(\"borderRadius\", null);\n\n return this;\n }\n\n /**\n * Returns the CSS box-shadow value, or null if not set.\n *\n * @returns The CSS box-shadow string, or null.\n */\n getShadow(): string | null {\n return this._options.shadow ?? null;\n }\n\n /**\n * Sets the CSS box-shadow. Use {@link clearShadow} to set the shadow to `\"none\"`.\n * Idempotent: a repeat call with the same value writes nothing.\n *\n * @param shadow - A CSS box-shadow string.\n *\n * @returns This component, for method chaining.\n */\n setShadow(shadow: string): this {\n if (this._options.shadow === shadow) {\n return this;\n }\n\n this._options.shadow = shadow;\n this.setReconciledCSSRules({ boxShadow: shadow });\n\n return this;\n }\n\n /**\n * Removes the box-shadow by writing `\"none\"` (preserving the legacy\n * `setShadow(null)` semantic — not a removeProperty). Idempotent: a\n * repeat call while already cleared writes nothing.\n *\n * @returns This component, for method chaining.\n */\n clearShadow(): this {\n if (this._options.shadow === undefined) {\n return this;\n }\n\n this._options.shadow = undefined;\n this.setReconciledCSSRules({ boxShadow: \"none\" });\n\n return this;\n }\n\n /**\n * Returns the CSS outline value last passed to {@link setOutline}, or `null`\n * if no outline is set.\n *\n * @returns The outline string, or null.\n */\n getOutline(): string | null {\n return this._outline ?? this._defaultOptions.outline ?? null;\n }\n\n /**\n * Sets the CSS outline on the element. Use {@link clearOutline} to remove.\n *\n * @param outline - A CSS outline value (e.g. \"none\", \"2px solid blue\").\n *\n * @returns This component, for method chaining.\n */\n setOutline(outline: string): this {\n this._outline = outline;\n\n this.setReconciledCSSRules({ outline });\n\n return this;\n }\n\n /**\n * Removes the outline CSS property from the element.\n *\n * @returns This component, for method chaining.\n */\n clearOutline(): this {\n this._outline = null;\n this.setElementCSSRule(\"outline\", null);\n\n return this;\n }\n\n /**\n * Returns the CSS appearance value last passed to {@link setAppearance}, or\n * `null` if no appearance override is set.\n *\n * @returns The appearance string, or null.\n */\n getAppearance(): string | null {\n return this._appearance;\n }\n\n /**\n * Sets the CSS appearance on the element. Use {@link clearAppearance} to remove.\n *\n * @param value - A CSS appearance value (e.g. \"none\", \"auto\").\n *\n * @returns This component, for method chaining.\n */\n setAppearance(value: string): this {\n this._appearance = value;\n\n this.setElementCSSRules({\n webkitAppearance: value,\n appearance: value\n });\n\n return this;\n }\n\n /**\n * Removes both the `-webkit-appearance` and `appearance` CSS properties.\n *\n * @returns This component, for method chaining.\n */\n clearAppearance(): this {\n this._appearance = null;\n this.setElementCSSRules({\n webkitAppearance: null,\n appearance: null\n });\n\n return this;\n }\n\n /**\n * Returns the CSS border-image value last passed to {@link setBorderImage},\n * or `null` if no border-image is set.\n *\n * @returns The border-image string, or null.\n */\n getBorderImage(): string | null {\n return this._borderImage;\n }\n\n /**\n * Sets the CSS border-image shorthand on the element. Use {@link clearBorderImage} to remove.\n *\n * @param value - A CSS border-image value (e.g. \"none\").\n *\n * @returns This component, for method chaining.\n */\n setBorderImage(value: string): this {\n this._borderImage = value;\n\n this.setElementCSSRule(\"borderImage\", value);\n\n return this;\n }\n\n /**\n * Removes the border-image CSS property from the element.\n *\n * @returns This component, for method chaining.\n */\n clearBorderImage(): this {\n this._borderImage = null;\n this.setElementCSSRule(\"borderImage\", null);\n\n return this;\n }\n\n /**\n * Returns the CSS transform value last passed to {@link setTransform}, or\n * `null` if no transform is set.\n *\n * @returns The transform string, or null.\n *\n * @remarks Reflects the value written to the component's CSS rule by\n * {@link setTransform}. {@link setTranslate} writes `transform` as an inline\n * style on a separate surface — its value is **not** reflected here. The\n * two transform surfaces (rule vs. inline) are independent; the cached\n * value here is the rule-side value only.\n */\n getTransform(): string | null {\n return this._transform;\n }\n\n /**\n * Sets the CSS transform on the element. Use {@link clearTransform} to remove.\n *\n * @param value - A CSS transform value (e.g. \"translateY(-1px)\").\n *\n * @returns This component, for method chaining.\n */\n setTransform(value: string): this {\n this._transform = value;\n\n this.setElementCSSRule(\"transform\", value);\n\n return this;\n }\n\n /**\n * Removes the transform CSS property from the element.\n *\n * @returns This component, for method chaining.\n */\n clearTransform(): this {\n this._transform = null;\n this.setElementCSSRule(\"transform\", null);\n\n return this;\n }\n\n /**\n * Returns the CSS transform-origin last passed to\n * {@link setTransformOrigin}, or `null` if none is set.\n *\n * @returns The transform-origin string, or null.\n */\n getTransformOrigin(): string | null {\n return this._transformOrigin;\n }\n\n /**\n * Sets the CSS transform-origin — the anchor point a {@link setTransform}\n * scales/rotates about. Use {@link clearTransformOrigin} to remove.\n *\n * @param value - A CSS transform-origin value (e.g. \"0 0\", \"50% 50%\").\n *\n * @returns This component, for method chaining.\n */\n setTransformOrigin(value: string): this {\n this._transformOrigin = value;\n\n this.setElementCSSRule(\"transformOrigin\", value);\n\n return this;\n }\n\n /**\n * Removes the transform-origin CSS property from the element.\n *\n * @returns This component, for method chaining.\n */\n clearTransformOrigin(): this {\n this._transformOrigin = null;\n this.setElementCSSRule(\"transformOrigin\", null);\n\n return this;\n }\n\n /**\n * Returns the component's current width and height.\n *\n * @returns A Size object with the current width and height in pixels.\n */\n getSize(): Size | null {\n return {\n width: this._width,\n height: this._height\n }\n }\n\n /**\n * Returns this component's own preferred-size *constraint* — the\n * caller/setter value, else the class default — without consulting the\n * layout manager or current size. {@link getPreferredSize} layers those on\n * when no explicit constraint is set.\n *\n * @returns The constraint Size, or null when none is set.\n */\n getPreferredSizeConstraint(): Size | null {\n return \"preferredSize\" in this._options\n ? (this._options.preferredSize ?? null)\n : (this._defaultOptions.preferredSize ?? null);\n }\n\n /**\n * Returns the preferred size from the explicit override, layout manager, or current size.\n *\n * @returns The preferred Size, determined in priority order: explicit override, layout manager, then current size.\n */\n getPreferredSize(): Size | null {\n let layoutManager = this.getLayoutManager();\n let preferredSize;\n\n const ownPreferred = this.getPreferredSizeConstraint();\n if (ownPreferred) {\n preferredSize = ownPreferred;\n } else if (!layoutManager) {\n preferredSize = this.getSize();\n } else {\n preferredSize = layoutManager.getPreferredSize();\n }\n\n if (!preferredSize) {\n return null;\n }\n\n // Clamp against the component's *own* explicit constraints only — not the\n // merged {@link getMinSize} / {@link getMaxSize}. `getPreferredSize` is a\n // hot path in the layout-gathering recursion, and the merged maximum runs\n // {@link Grid.measureContent}, which itself calls children's\n // `getPreferredSize`; clamping to it here would make the recursion\n // re-entrant and exponential in tree depth. The merged `[min, max]`\n // envelope is enforced instead on the committed size, in\n // {@link clampWidth} / {@link clampHeight}.\n const ownMin = this.getMinSizeConstraint();\n const ownMax = this.getMaxSizeConstraint();\n\n return this.clampPreferredToConstraints(preferredSize, ownMin, ownMax);\n }\n\n /**\n * Clamps a resolved preferred size into the supplied `[min, max]` range on\n * each axis. `min` wins over a smaller `max` (a degenerate `min > max`\n * constraint) and over a smaller `preferred`, because the floor is applied\n * last among the pair — so an explicit minimum is always honoured.\n *\n * @param preferred - The resolved preferred size to clamp.\n * @param min - The minimum size to floor to, or null when unconstrained.\n * @param max - The maximum size to cap to, or null when unconstrained.\n *\n * @returns The preferred size clamped into `[min, max]` per axis.\n */\n private clampPreferredToConstraints(preferred: Size, min: Size | null, max: Size | null): Size {\n let width = preferred.width;\n let height = preferred.height;\n\n if (max) {\n width = Math.min(width, max.width);\n height = Math.min(height, max.height);\n }\n\n if (min) {\n width = Math.max(width, min.width);\n height = Math.max(height, min.height);\n }\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Sets an explicit preferred size; triggers the onPreferredSizeChange callback if changed.\n *\n * @param size - The preferred size in pixels.\n *\n * @returns This component, for method chaining.\n */\n setPreferredSize(size: Size): this {\n const prev = this._options.preferredSize;\n if (prev && prev.width === size.width && prev.height === size.height) {\n return this;\n }\n\n const next: Size = { width: size.width, height: size.height };\n this._options.preferredSize = next;\n this.setDataAttribute(\"preferredSize\", formatSizeAttr(next.width, next.height));\n this._onPreferredSizeChange?.();\n\n return this;\n }\n\n /**\n * Drops this component's preferred-size constraint, including one that came\n * from a class default, so its size is derived from its content and layout\n * manager instead.\n *\n * @returns This component, for method chaining.\n *\n * @remarks The options bag cannot express this: `applyOptions` skips an\n * `undefined` entry, so `preferredSize: undefined` never reaches `_options`\n * and a class default (a `FieldSet`'s fixed square, say) keeps winning.\n * This writes the key with an `undefined` value, which is what tells\n * {@link getPreferredSizeConstraint} that the size was *cleared* rather than\n * *never set* — the same key-presence rule `clearPadding` follows.\n */\n clearPreferredSize(): this {\n if (\"preferredSize\" in this._options && this._options.preferredSize === undefined) {\n return this;\n }\n\n this._options.preferredSize = undefined;\n this.delDataAttribute(\"preferredSize\");\n this._onPreferredSizeChange?.();\n\n return this;\n }\n\n /**\n * Returns this component's own minimum-size *constraint* — the caller/setter\n * value, else the class default — without folding in the layout manager's\n * minimum. This is the raw author constraint written to CSS `min-*` and\n * clamped against; {@link getMinSize} layers the layout minimum on top.\n *\n * @returns The constraint Size, or null when none is set.\n */\n getMinSizeConstraint(): Size | null {\n return (this._options.minSize ?? this._defaultOptions.minSize) ?? null;\n }\n\n /**\n * Returns this component's own maximum-size *constraint* — the caller/setter\n * value, else the class default — without folding in the layout manager's\n * maximum. Companion to {@link getMinSizeConstraint}.\n *\n * @returns The constraint Size, or null when none is set.\n */\n getMaxSizeConstraint(): Size | null {\n return (this._options.maxSize ?? this._defaultOptions.maxSize) ?? null;\n }\n\n /**\n * Merges a component's own size *constraint* with its layout manager's size,\n * per axis, into a fresh {@link Size}. When both are present each axis is\n * combined with `merge` (the tighter bound: `Math.max` for minimums,\n * `Math.min` for maximums); when only one is present that source's values are\n * copied; when neither is present the axes fall back to `fallback`. Every\n * branch returns a new object, so callers never receive an alias of the\n * stored constraint or manager size.\n *\n * @param constraint - This component's own min/max size constraint, or null.\n * @param managerSize - The layout manager's reported min/max size, or null.\n * @param merge - The per-axis combiner applied when both sources are present.\n * @param fallback - The per-axis value used when neither source is present.\n * @returns The merged size as a fresh object.\n */\n private mergeConstraintSize(\n constraint: Size | null,\n managerSize: Size | null,\n merge: (a: number, b: number) => number,\n fallback: number,\n ): Size {\n if (constraint && managerSize) {\n return {\n width: merge(constraint.width, managerSize.width),\n height: merge(constraint.height, managerSize.height),\n };\n }\n\n if (constraint) {\n return { width: constraint.width, height: constraint.height };\n }\n\n if (managerSize) {\n return { width: managerSize.width, height: managerSize.height };\n }\n\n return { width: fallback, height: fallback };\n }\n\n /**\n * Returns the effective minimum size: the larger of the component and layout manager minimums.\n *\n * @returns A Size object whose width and height are the element-wise maximums of the component and layout manager minimums.\n */\n getMinSize(): Size | null {\n return this.mergeConstraintSize(this.getMinSizeConstraint(), this.getLayoutManager().getMinSize(), Math.max, 0);\n }\n\n /**\n * Sets the minimum size and applies it to the CSS rule.\n *\n * @param size - The minimum size in pixels.\n *\n * @returns This component, for method chaining.\n */\n setMinSize(size: Size): this {\n const current = this._options.minSize;\n if (current && current.width === size.width && current.height === size.height) {\n return this;\n }\n\n const next: Size = { width: size.width, height: size.height };\n this._options.minSize = next;\n\n this.setReconciledCSSRules({\n minWidth: next.width + \"px\",\n minHeight: next.height + \"px\"\n });\n\n this.setDataAttribute(\"minSize\", formatSizeAttr(next.width, next.height));\n\n this._onConstraintSizeChange?.();\n\n return this;\n }\n\n /**\n * Returns the effective maximum size: the *tighter* (smaller) of the\n * component's own maximum and its layout manager's maximum, per axis. A\n * component may exceed neither its own `setMaxSize` nor the ceiling its\n * layout manager imposes, so the binding constraint is the smaller of the\n * two — mirroring how {@link getMinSize} takes the larger (tighter) minimum.\n *\n * @returns A Size object whose width and height are the element-wise minimums of the component and layout manager maximums.\n */\n getMaxSize(): Size | null {\n return this.mergeConstraintSize(this.getMaxSizeConstraint(), this.getLayoutManager().getMaxSize(), Math.min, UNBOUNDED);\n }\n\n /**\n * Sets the maximum size and applies it to the CSS rule.\n *\n * @param size - The maximum size in pixels. Pass UNBOUNDED on either axis to remove that constraint.\n *\n * @returns This component, for method chaining.\n */\n setMaxSize(size: Size): this {\n const current = this._options.maxSize;\n if (current && current.width === size.width && current.height === size.height) {\n return this;\n }\n\n const next: Size = { width: size.width, height: size.height };\n this._options.maxSize = next;\n\n this.setReconciledCSSRules({\n maxWidth: isUnbounded(next.width) ? \"none\" : next.width + \"px\",\n maxHeight: isUnbounded(next.height) ? \"none\" : next.height + \"px\"\n });\n\n this.setDataAttribute(\"maxSize\", formatSizeAttr(next.width, next.height));\n\n this._onConstraintSizeChange?.();\n\n return this;\n }\n\n /**\n * Returns the usable inner size: component size minus insets and border widths.\n *\n * @returns The inner Size in pixels, or null if the element is not yet in the DOM.\n */\n getInnerSize(): Size | null {\n let element = this.getElement();\n if (!element) {\n return null;\n }\n\n let perimeterSize = this.getPerimeterSize();\n\n let width = this._width - perimeterSize.left - perimeterSize.right;\n let height = this._height - perimeterSize.top - perimeterSize.bottom;\n\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Returns the rectangle this component's children are laid out into: the\n * origin from {@link getContentInsets} and the size from\n * {@link getInnerSize}. A component that places its own children places\n * them inside this rectangle — from a `doLayout` override or from any other\n * method that positions them, such as a row renderer's `layoutChildren`.\n *\n * A border shrinks the rectangle but never moves its origin. Because every\n * component is absolutely positioned, a child's containing block is already\n * this component's padding box — a child at `left: 0` lands at the inner\n * edge of the border — so only the size has to account for it.\n *\n * @returns The content rectangle in pixels, or null if the element is not\n * yet in the DOM (mirroring {@link getInnerSize}).\n */\n getContentBounds(): { x: number; y: number; width: number; height: number } | null {\n const inner = this.getInnerSize();\n\n if (!inner) {\n return null;\n }\n\n const contentInsets = this.getContentInsets();\n\n return {\n x: contentInsets.getLeft(),\n y: contentInsets.getTop(),\n width: inner.width,\n height: inner.height,\n };\n }\n\n /**\n * Returns the per-side pixel widths of the component's border. Once the element\n * is connected to the document the widths are browser-measured (so `var()`,\n * `none`, and keywords all resolve) and cached until the next\n * `setBorder`/`clearBorder` or theme change. The measurement itself is shared\n * by every component carrying the same border specification — not repeated\n * per instance — and discarded on theme change; a border side whose width is\n * font-relative (`em`/`ex`/`ch`/`lh`) opts out of sharing and is measured per\n * component, since it can resolve differently on each element. Before the\n * element is connected, `getComputedStyle` can't resolve `var()` (the element\n * doesn't yet inherit from `:root`), so it falls back to an estimate from the\n * spec strings that resolves a leading `var(--name)` against `:root` directly.\n * The estimate is not cached, so it is re-measured authoritatively once the\n * element connects.\n *\n * @returns A PerimeterSize with zero values on each side when no border is set.\n */\n getBorderSize(): PerimeterSize {\n if (!this._border) {\n return { top: 0, right: 0, bottom: 0, left: 0 };\n }\n\n if (this._borderWidths) {\n return this._borderWidths;\n }\n\n const element = this.getElement();\n\n if (element && DOM.source.isConnected(element)) {\n // Authoritative: getComputedStyle resolves var()/none/keywords to \"<n>px\"\n // once the element is in the document and inherits :root's custom props.\n this._borderWidths = measureBorderWidths(this._border, element);\n\n return this._borderWidths;\n }\n\n // Pre-attach estimate from the spec strings, resolving a leading var()\n // against :root so themed var-borders report their width before connect.\n const all = this._border.border;\n\n return {\n top: this.estimateBorderSideWidth(this._border.borderTop ?? all),\n right: this.estimateBorderSideWidth(this._border.borderRight ?? all),\n bottom: this.estimateBorderSideWidth(this._border.borderBottom ?? all),\n left: this.estimateBorderSideWidth(this._border.borderLeft ?? all),\n };\n }\n\n /**\n * Estimates one border side's pixel width before the element is connected.\n * A leading `<n>px` wins outright; otherwise a leading `var(--name)` is\n * resolved against `:root`'s custom properties (recursing into the resolved\n * value) so themed var-borders report a width pre-attach. Returns `0` when no\n * width can be determined.\n *\n * @param value - A single side's CSS border value, or `undefined`.\n *\n * @returns The estimated pixel width, or `0`.\n */\n private estimateBorderSideWidth(value: string | undefined): number {\n if (!value) {\n return 0;\n }\n\n const trimmed = value.trim();\n const direct = borderSideWidth(trimmed);\n\n if (direct > 0) {\n return direct;\n }\n\n const varName = trimmed.match(/^var\\(\\s*(--[\\w-]+)/)?.[1];\n\n if (varName) {\n const resolved = DOM.source.getThemeVar(varName);\n\n if (resolved) {\n return this.estimateBorderSideWidth(resolved);\n }\n }\n\n return 0;\n }\n\n /**\n * Returns the total per-side consumed space: insets plus border widths plus\n * CSS padding. These are the three bands between the component's outer box\n * and the content area a layout manager may fill, so `getInnerSize`\n * subtracts all of them and the size-hint paths add them back. CSS padding\n * is real layout space the browser reserves inside the (border-box) element,\n * so omitting it left a layout manager believing it had more room than the\n * content box actually offers — the surplus surfaced as content spilling\n * past the far inset (e.g. a `FieldSet`'s bottom inset).\n *\n * @returns A PerimeterSize where each side is the sum of the inset, border width, and padding for that side.\n */\n getPerimeterSize() {\n let borderSize = this.getBorderSize();\n let insets = this.getInsets();\n let padding = this.getPadding();\n\n let perimeterSize: PerimeterSize = {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0\n }\n\n if (insets) {\n perimeterSize.top = insets.getTop();\n perimeterSize.right = insets.getRight();\n perimeterSize.bottom = insets.getBottom();\n perimeterSize.left = insets.getLeft();\n }\n\n if (borderSize) {\n perimeterSize.top += borderSize.top;\n perimeterSize.right += borderSize.right;\n perimeterSize.bottom += borderSize.bottom;\n perimeterSize.left += borderSize.left;\n }\n\n if (padding) {\n perimeterSize.top += padding.getTop();\n perimeterSize.right += padding.getRight();\n perimeterSize.bottom += padding.getBottom();\n perimeterSize.left += padding.getLeft();\n }\n\n return perimeterSize;\n }\n\n /**\n * Returns the offset, in pixels, from the top of this component to its visual baseline.\n *\n * @returns The baseline offset in pixels, or `null` when this component has no\n * intrinsic baseline (e.g. graphical or non-text components).\n *\n * @remarks Subclasses with a meaningful baseline override this method,\n * typically composing an inner baseline with the component's own chrome via\n * `wrapInnerBaseline`. The default delegates to the layout manager's\n * {@link LayoutManager.getContentBaseline} so a plain container laid out by\n * a baseline-aware layout (e.g. an `HBox` of controls) aligns by its row's\n * baseline rather than auto-centring; non-baseline layouts return `null`.\n * Used by horizontal layouts to align children of mixed heights so their\n * text baselines coincide. Components that return `null` are treated as if\n * their bottom edge were the baseline (CSS replaced-element behaviour).\n */\n getBaseline(): number | null {\n const inner = this.getLayoutManager().getContentBaseline();\n\n return inner === null ? null : this.wrapInnerBaseline(inner);\n }\n\n /**\n * Wraps a chrome-relative inner baseline with this component's outer chrome.\n *\n * @param inner - The baseline measured from the inner content top (inside\n * border, padding, and framework insets), or `null` when the component has\n * no meaningful baseline.\n * @returns The visual baseline measured from this component's outer top,\n * or `null` when `inner` is `null`.\n *\n * @remarks Adds `insets.top + border.top + padding.top` to `inner`. Use\n * when implementing `getBaseline()` on a composite component (delegating\n * to a child) or a CSS-rendered leaf (delegating to\n * `Util.measureTextBaseline()`). Centralises the chrome arithmetic that\n * would otherwise be repeated in every override.\n */\n protected wrapInnerBaseline(inner: number | null): number | null {\n if (inner === null) {\n return null;\n }\n\n const padding = this.getPadding();\n const paddingTop = padding ? padding.getTop() : 0;\n\n return this.getInsets().getTop()\n + this.getBorderSize().top\n + paddingTop\n + inner;\n }\n\n getVerticalAlign() {\n return this._verticalAlign\n }\n\n /**\n * @returns This component, for method chaining.\n */\n setVerticalAlign(align: string): this {\n this._verticalAlign = align;\n\n this.setElementCSSRule(\"verticalAlign\", align);\n\n return this;\n }\n\n /**\n * Removes the vertical-align CSS property from the element.\n *\n * @returns This component, for method chaining.\n */\n clearVerticalAlign(): this {\n if (this._verticalAlign === null) {\n return this;\n }\n\n this._verticalAlign = null;\n this.setElementCSSRule(\"verticalAlign\", null);\n\n return this;\n }\n\n // Currently commented out, probing if a scrollbar is visible or not seems to be unreliable with the below method.\n\n // hasHorizontalScrollBar() {\n // let element = this.getElement();\n\n // let overflowX = window.getComputedStyle(element)['overflow-x'];\n\n // return (overflowX === 'scroll' || overflowX === 'auto') && element.scrollWidth > element.clientWidth;\n // }\n\n // getHorizontalScrollBarSize() {\n // return this.hasHorizontalScrollBar() ? Base.getScrollBarWidth() : 0;\n // }\n\n // hasVerticalScrollBar() {\n // let element = this.getElement();\n\n // let overflowY = window.getComputedStyle(element)['overflow-y'];\n\n // return (overflowY === 'scroll' || overflowY === 'auto') && element.scrollHeight > element.clientHeight;\n // }\n\n // getVerticalScrollBarSize() {\n // return this.hasVerticalScrollBar() ? Base.getScrollBarWidth() : 0;\n // }\n\n /**\n * Sets width and height, updates the DOM element, and triggers doLayout.\n *\n * @param size - The new Size with width and height in pixels.\n *\n * @returns This component, for method chaining.\n */\n setSize(size: Size): this {\n const width = this.clampWidth(size.width);\n const height = this.clampHeight(size.height);\n\n this._width = width;\n this._height = height;\n\n let element = this.getElement();\n if (!element) {\n return this;\n }\n\n this.setElementStyles({\n \"width\": width + \"px\",\n \"height\": height + \"px\"\n });\n\n this.scheduleLayout();\n\n return this;\n }\n\n /**\n * Writes x / y / width / height as one batched DOM update.\n *\n * @param x - The new left position in pixels.\n * @param y - The new top position in pixels.\n * @param width - The new width in pixels.\n * @param height - The new height in pixels.\n *\n * @returns Whether the committed rectangle changed.\n */\n setBounds(x: number, y: number, width: number, height: number): boolean {\n this.setAutoCommitStyle(false);\n const changed = this.writeBounds(x, y, width, height);\n this.setAutoCommitStyle(true);\n\n return changed;\n }\n\n /**\n * Writes the rectangle, then lays this component out unless the rectangle\n * was unchanged and this component allows the pass to be skipped.\n *\n * @param x - The new left position in pixels.\n * @param y - The new top position in pixels.\n * @param width - The new width in pixels.\n * @param height - The new height in pixels.\n *\n * @returns This component, for method chaining.\n *\n * @remarks Keeps the batching window open across `doLayout()`, matching\n * `LayoutManager.commitBounds`'s behaviour exactly: any inline style the\n * component writes on itself during its own layout pass is flushed in the\n * same batch as the rectangle. The pass runs when the rectangle changed,\n * when this component has not opted into the skip (the protected\n * `canSkipUnchangedLayout` gate, default `false`), when\n * {@link isLayoutDirty} reports a pass is owed, or when this component\n * has no element yet — a cell with no element cannot lay out, so\n * recording that pass as done would skip it forever.\n */\n applyBounds(x: number, y: number, width: number, height: number): this {\n this.setAutoCommitStyle(false);\n\n const changed = this.writeBounds(x, y, width, height);\n\n if (changed || !this.canSkipUnchangedLayout() || this.isLayoutDirty() || !this.getElement()) {\n this.doLayout();\n }\n\n this.setAutoCommitStyle(true);\n\n return this;\n }\n\n /**\n * Opt-in gate for the unchanged-geometry skip {@link applyBounds} applies.\n * Default `false` — a component's `doLayout()` is withheld only when it\n * overrides this to `true`.\n *\n * @returns `true` to allow `applyBounds` to skip a `doLayout()` pass when\n * the rectangle it was handed is unchanged and this component is not\n * dirty; `false` to always recurse.\n */\n protected canSkipUnchangedLayout(): boolean {\n return false;\n }\n\n /**\n * Shared body of {@link setBounds} / {@link applyBounds}: writes x / y /\n * width / height and reports whether the committed rectangle changed.\n * Assumes the batching window is already open.\n *\n * @param x - The new left position in pixels.\n * @param y - The new top position in pixels.\n * @param width - The new width in pixels.\n * @param height - The new height in pixels.\n *\n * @returns Whether the committed rectangle changed.\n *\n * @remarks Reads the fields *after* the setters ran, so a `setWidth`/\n * `setHeight` that clamped to this component's min or max still reports\n * honestly.\n */\n private writeBounds(x: number, y: number, width: number, height: number): boolean {\n const px = this._left, py = this._top, pw = this._width, ph = this._height;\n\n this.setX(x);\n this.setY(y);\n this.setWidth(width);\n this.setHeight(height);\n\n return this._left !== px || this._top !== py || this._width !== pw || this._height !== ph;\n }\n\n /**\n * Returns the component's current width in pixels.\n *\n * @returns The width in pixels, or 0 if the size is unavailable.\n */\n getWidth(): number {\n let size = this.getSize();\n if (size) {\n return size.width;\n } else {\n return 0;\n }\n }\n\n /**\n * Sets the component width and updates the DOM element's inline style.\n *\n * @param width - The new width in pixels.\n *\n * @returns This component, for method chaining.\n *\n * @remarks The DOM write is rounded to the nearest device pixel — see\n * {@link setX}.\n */\n setWidth(width: number): this {\n width = this.clampWidth(width);\n\n if (this._width === width) {\n return this;\n }\n\n this._width = width;\n\n let element = this.getElement();\n if (!element) {\n return this;\n }\n\n this.setElementStyle(\"width\", Math.round(this._width) + \"px\");\n\n return this;\n }\n\n /**\n * Whether {@link clampWidth} / {@link clampHeight} clamp the committed size to\n * the merged, layout-calculated {@link getMinSize} / {@link getMaxSize} — the\n * size derived from this component's children — or only to its own explicit\n * {@link setMinSize} / {@link setMaxSize}.\n *\n * The default is `true`: most components adhere to their content-derived\n * size, so they never collapse below what their children need to render.\n * {@link Container} overrides this to `false` (inherited by {@link Panel}) —\n * such a container fits whatever space its parent allocates and lets the\n * overflow clip (or scroll, on a `Panel` with `autoScroll` configured)\n * instead of inflating itself back up to its content size. Then only an\n * explicit {@link setMinSize} / {@link setMaxSize} remains a hard floor or\n * ceiling.\n *\n * @returns `true` to clamp to the merged constraints; `false` for the\n * component's own explicit constraints only.\n */\n protected clampsToContentSize(): boolean {\n return true;\n }\n\n /**\n * Whether this component supports releasing its element without being\n * destroyed. Default false — a component becomes releasable only by\n * overriding this to true, and only once its own element-derived state is\n * provably rebuilt by render()/init() or absent.\n *\n * @returns `true` to allow {@link release} to detach and later rebuild this\n * component's element; `false` to refuse release.\n */\n protected canRelease(): boolean {\n return false;\n }\n\n /**\n * Clamps a width value to this component's `[minSize.width, maxSize.width]`\n * range so {@link setWidth}, {@link setHeight}, and {@link setSize} cannot\n * drive `_width` / `_height` outside it. The bounding constraints are the\n * merged {@link getMinSize} / {@link getMaxSize} when\n * {@link clampsToContentSize} is `true` (the default — adhere to the\n * content-derived size), or the component's own explicit `_options` (or\n * default) constraints when it is `false` ({@link Container} / {@link Panel},\n * which fit their allocation).\n */\n private clampWidth(width: number): number {\n const toContent = this.clampsToContentSize();\n\n const maxSize = toContent ? this.getMaxSize() : (this.getMaxSizeConstraint());\n if (maxSize && width > maxSize.width) {\n width = maxSize.width;\n }\n\n const minSize = toContent ? this.getMinSize() : (this.getMinSizeConstraint());\n if (minSize && width < minSize.width) {\n width = minSize.width;\n }\n\n return width;\n }\n\n /**\n * Returns the component's current height in pixels.\n *\n * @returns The height in pixels, or 0 if the size is unavailable.\n */\n getHeight(): number {\n let size = this.getSize();\n if (size) {\n return size.height;\n } else {\n return 0;\n }\n }\n\n /**\n * Sets the component height and updates the DOM element's inline style.\n *\n * @param height - The new height in pixels.\n *\n * @returns This component, for method chaining.\n *\n * @remarks The DOM write is rounded to the nearest device pixel — see\n * {@link setX}.\n */\n setHeight(height: number): this {\n height = this.clampHeight(height);\n\n if (this._height === height) {\n return this;\n }\n\n this._height = height;\n\n let element = this.getElement();\n if (!element) {\n return this;\n }\n\n this.setElementStyle(\"height\", Math.round(this._height) + \"px\");\n\n return this;\n }\n\n /**\n * Clamps a height value to this component's `[minSize.height,\n * maxSize.height]` range. Mirror of {@link clampWidth}; the bounding\n * constraints are the merged {@link getMinSize} / {@link getMaxSize} or the\n * component's own explicit constraints depending on\n * {@link clampsToContentSize}. See {@link clampWidth} for the rationale.\n */\n private clampHeight(height: number): number {\n const toContent = this.clampsToContentSize();\n\n const maxSize = toContent ? this.getMaxSize() : (this.getMaxSizeConstraint());\n if (maxSize && height > maxSize.height) {\n height = maxSize.height;\n }\n\n const minSize = toContent ? this.getMinSize() : (this.getMinSizeConstraint());\n if (minSize && height < minSize.height) {\n height = minSize.height;\n }\n\n return height;\n }\n\n /**\n * Returns the component's horizontal position (CSS left) in pixels.\n *\n * @returns The left offset in pixels.\n */\n getX(): number {\n return this._left;\n }\n\n /**\n * Sets the CSS left position and updates the DOM element's inline style.\n *\n * @param x - The horizontal offset in pixels.\n *\n * @returns This component, for method chaining.\n *\n * @remarks The DOM write is rounded to the nearest device pixel to avoid\n * sub-pixel edges and text re-rasterization; `getX()` still returns the\n * exact value passed in, so repeated relative layout math does not\n * accumulate rounding drift.\n */\n setX(x: number): this {\n if (this._left === x) {\n return this;\n }\n\n this._left = x;\n\n let element = this.getElement();\n if (!element) {\n return this;\n }\n\n this.setElementStyle(\"left\", Math.round(this._left) + \"px\");\n\n return this;\n }\n\n /**\n * Returns the component's vertical position (CSS top) in pixels.\n *\n * @returns The top offset in pixels.\n */\n getY(): number {\n return this._top;\n }\n\n /**\n * Sets the CSS top position and updates the DOM element's inline style.\n *\n * @param y - The vertical offset in pixels.\n *\n * @returns This component, for method chaining.\n *\n * @remarks The DOM write is rounded to the nearest device pixel — see\n * {@link setX}.\n */\n setY(y: number): this {\n if (this._top === y) {\n return this;\n }\n\n this._top = y;\n\n let element = this.getElement();\n if (!element) {\n return this;\n }\n\n this.setElementStyle(\"top\", Math.round(this._top) + \"px\");\n\n return this;\n }\n\n /**\n * Returns the element's horizontal scroll offset from the cached value, so\n * reads never touch the DOM (mirroring {@link getX}). The cache is the value\n * last written through {@link setScrollLeft}; it is authoritative as long as\n * the scroll is driven through these setters (the host owns it — e.g. a `Tab`\n * strip's clip frame, which the browser never scrolls on its own).\n *\n * @returns The cached `scrollLeft` in pixels.\n */\n getScrollLeft(): number {\n return this._scrollLeft;\n }\n\n /**\n * Returns the element's cached vertical scroll offset. See {@link getScrollLeft}.\n *\n * @returns The cached `scrollTop` in pixels.\n */\n getScrollTop(): number {\n return this._scrollTop;\n }\n\n /**\n * Sets the element's native horizontal scroll offset and caches it for\n * {@link getScrollLeft}. The value is read back after the write so the cache\n * holds the browser-clamped result, not the raw request (clamped to\n * `[0, getMaxScrollLeft()]`).\n *\n * @param value - The desired `scrollLeft` in pixels.\n *\n * @returns This component, for method chaining.\n */\n setScrollLeft(value: number): this {\n this._wheelScroller?.reset();\n\n const element = this.getScrollElement();\n\n if (element) {\n DOM.sink.apply(element, { scrollLeft: value });\n this._scrollLeft = DOM.source.getScrollLeft(element);\n } else {\n this._scrollLeft = value;\n }\n\n return this;\n }\n\n /**\n * Sets the element's native vertical scroll offset and caches it. See\n * {@link setScrollLeft}.\n *\n * @param value - The desired `scrollTop` in pixels.\n *\n * @returns This component, for method chaining.\n */\n setScrollTop(value: number): this {\n this._wheelScroller?.reset();\n\n const element = this.getScrollElement();\n\n if (element) {\n DOM.sink.apply(element, { scrollTop: value });\n this._scrollTop = DOM.source.getScrollTop(element);\n } else {\n this._scrollTop = value;\n }\n\n return this;\n }\n\n /**\n * Restores the scroll offset and focus a released element held, onto the\n * freshly rebuilt element — queued by {@link release} / `init()` into the\n * first-connected-layout drain, since neither lands on a still-detached\n * element.\n *\n * @param element - The freshly rebuilt element to restore state onto.\n */\n private restoreReleasedState(element: Handle): void {\n // Routed through getScrollElement() — not the raw root `element` — so a\n // subclass whose scroll happens on an inner element (see getScrollElement's\n // own doc) restores onto the same target every other scroll write uses.\n const scrollElement = this.getScrollElement();\n if (scrollElement && (this._scrollLeft !== 0 || this._scrollTop !== 0)) {\n DOM.sink.apply(scrollElement, { scrollLeft: this._scrollLeft, scrollTop: this._scrollTop });\n }\n\n if (this._refocusOnRematerialize) {\n this._refocusOnRematerialize = false;\n // preventScroll: avoid focus-scroll pollution of an overflow:hidden ancestor.\n DOM.sink.focus(element, { preventScroll: true });\n }\n }\n\n /**\n * Re-reads the element's native scroll offsets into the cache that backs\n * {@link getScrollLeft} / {@link getScrollTop}. That cache is authoritative\n * only while the scroll is driven through {@link setScrollLeft} /\n * {@link setScrollTop}; the browser also clamps the native offset on its own\n * when the scrollable range shrinks (e.g. content laid out smaller than the\n * current offset), bypassing those setters and leaving the cache stale. Call\n * this after such a layout so the cache matches the DOM again.\n *\n * @returns This component, for method chaining.\n */\n syncScrollOffsets(): this {\n this._wheelScroller?.reset();\n\n const element = this.getScrollElement();\n\n if (element) {\n this._scrollLeft = DOM.source.getScrollLeft(element);\n this._scrollTop = DOM.source.getScrollTop(element);\n }\n\n return this;\n }\n\n /**\n * Returns the maximum horizontal scroll offset — the content's overflow past\n * the element's viewport (`scrollWidth - clientWidth`).\n *\n * @returns The last-page `scrollLeft` in pixels, or 0 when nothing overflows.\n */\n getMaxScrollLeft(): number {\n const element = this.getScrollElement();\n if (!element) {\n return 0;\n }\n\n const metrics = DOM.source.getScrollMetrics(element);\n\n return metrics.scrollWidth - metrics.clientWidth;\n }\n\n /**\n * Returns the maximum vertical scroll offset — the content's overflow past\n * the element's viewport (`scrollHeight - clientHeight`).\n *\n * @returns The last-page `scrollTop` in pixels, or 0 when nothing overflows.\n */\n getMaxScrollTop(): number {\n const element = this.getScrollElement();\n if (!element) {\n return 0;\n }\n\n const metrics = DOM.source.getScrollMetrics(element);\n\n return metrics.scrollHeight - metrics.clientHeight;\n }\n\n /**\n * Returns the cached translate-X component of the element's `transform` (pixels).\n *\n * @returns The translate-X value last passed to setTranslate, or 0.\n */\n getTranslateX(): number {\n return this._translateX;\n }\n\n /**\n * Returns the cached translate-Y component of the element's `transform` (pixels).\n *\n * @returns The translate-Y value last passed to setTranslate, or 0.\n */\n getTranslateY(): number {\n return this._translateY;\n }\n\n /**\n * Writes the element's `transform` to translate3d(x, y, 0). This positions on the\n * compositor without triggering layout/paint, complementing setX/setY (left/top).\n * Visual position of the element is `left + translateX, top + translateY`.\n *\n * @param x - Translate-X in pixels.\n * @param y - Translate-Y in pixels.\n *\n * @returns This component, for method chaining.\n *\n * @remarks The DOM write is rounded to the nearest device pixel — see\n * {@link setX}.\n */\n setTranslate(x: number, y: number): this {\n if (this._translateX === x && this._translateY === y && this.getElement()) {\n return this;\n }\n\n this._translateX = x;\n this._translateY = y;\n\n if (x === 0 && y === 0) {\n this.setElementStyle(\"transform\", null);\n } else {\n this.setElementStyle(\"transform\", \"translate3d(\" + Math.round(x) + \"px,\" + Math.round(y) + \"px,0)\");\n }\n\n return this;\n }\n\n /**\n * Returns the CSS position mode for this component.\n *\n * @returns The current Position value; defaults to `Position.ABSOLUTE`.\n *\n * @remarks Position is framework-internal — see [`setPosition`](/api/core/classes/Component#setposition).\n * Application code never needs to read or set it.\n */\n protected getPosition(): Position {\n return this._position;\n }\n\n /**\n * Framework-internal CSS position setter. Application code should NOT\n * call this — every framework component is positioned absolutely, and\n * layout managers compute child coordinates against the parent's padding\n * box on that assumption. See [ARCHITECTURE.md](/ARCHITECTURE.md)\n * §Positioning for the rationale.\n *\n * Subclasses MAY call this with [`Position.FIXED`](/api/primitive/enums/Position#FIXED)\n * when they are floating overlays anchored to the viewport\n * ([`AnimatedDropdown`](/api/core/classes/AnimatedDropdown),\n * [`Popover`](/api/overlay/classes/Popover), [`Notification`](/api/overlay/classes/Notification),\n * [`Dialog`](/api/overlay/classes/Dialog), [`DialogBackdrop`](/api/core/classes/DialogBackdrop))\n * or with [`Position.STATIC`](/api/primitive/enums/Position#STATIC) when\n * the element's HTML semantics require in-flow rendering\n * ([`Legend`](/api/component/container/classes/Legend) needs the notch in\n * the parent fieldset border).\n *\n * @param position - The CSS position mode to apply.\n *\n * @returns This component, for method chaining.\n */\n protected setPosition(position: Position): this {\n this._position = position;\n\n this.setElementCSSRule(\"position\", position);\n\n return this;\n }\n\n\n /**\n * Restores the framework default (`Position.ABSOLUTE`). Framework-internal\n * companion to [`setPosition`](/api/core/classes/Component#setposition) —\n * application code does not need this.\n *\n * @returns This component, for method chaining.\n */\n protected clearPosition(): this {\n return this.setPosition(Position.ABSOLUTE);\n }\n\n /**\n * Returns the CSS overflow value when both axes agree, or null otherwise.\n *\n * @returns The shared overflow string, or null if the axes diverge or are unset.\n */\n getOverflow(): string | null {\n const overflowX = this.getOverflowX();\n const overflowY = this.getOverflowY();\n\n return overflowX !== null && overflowX === overflowY ? overflowX : null;\n }\n\n /**\n * Sets the CSS overflow property on both axes. Convenience for callers that\n * want the same value on x and y; routes through [`setOverflowX`](/api/core/classes/Component#setoverflowx)\n * and [`setOverflowY`](/api/core/classes/Component#setoverflowy) so the per-axis state stays canonical.\n *\n * @param overflow - A CSS overflow value (e.g. \"hidden\", \"auto\", \"visible\").\n *\n * @returns This component, for method chaining.\n */\n setOverflow(overflow: string): this {\n return this.setOverflowX(overflow)\n .setOverflowY(overflow);\n }\n\n /**\n * Clears both per-axis overflow values.\n *\n * @returns This component, for method chaining.\n */\n clearOverflow(): this {\n return this.clearOverflowX().clearOverflowY();\n }\n\n /**\n * Returns the CSS overflow-x value, or null if not set.\n *\n * @returns The CSS overflow-x string, or null.\n */\n getOverflowX(): string | null {\n return this._overflowX ?? this._defaultOptions.overflow ?? null;\n }\n\n /**\n * Sets the CSS overflow-x property on the component's CSS rule.\n *\n * @param value - A CSS overflow value (e.g. \"hidden\", \"auto\", \"visible\").\n *\n * @returns This component, for method chaining.\n */\n setOverflowX(value: string): this {\n if (this._overflowX === value) {\n return this;\n }\n\n this._overflowX = value;\n this.setReconciledCSSRules({ overflowX: value });\n this.refreshWheelScrolling();\n\n return this;\n }\n\n /**\n * Removes the overflow-x CSS property from the component's CSS rule.\n *\n * @returns This component, for method chaining.\n */\n clearOverflowX(): this {\n if (this._overflowX === null) {\n return this;\n }\n\n this._overflowX = null;\n this.setElementCSSRule(\"overflowX\", null);\n this.refreshWheelScrolling();\n\n return this;\n }\n\n /**\n * Returns the CSS overflow-y value, or null if not set.\n *\n * @returns The CSS overflow-y string, or null.\n */\n getOverflowY(): string | null {\n return this._overflowY ?? this._defaultOptions.overflow ?? null;\n }\n\n /**\n * Sets the CSS overflow-y property on the component's CSS rule.\n *\n * @param value - A CSS overflow value (e.g. \"hidden\", \"auto\", \"visible\").\n *\n * @returns This component, for method chaining.\n */\n setOverflowY(value: string): this {\n if (this._overflowY === value) {\n return this;\n }\n\n this._overflowY = value;\n this.setReconciledCSSRules({ overflowY: value });\n this.refreshWheelScrolling();\n\n return this;\n }\n\n /**\n * Removes the overflow-y CSS property from the component's CSS rule.\n *\n * @returns This component, for method chaining.\n */\n clearOverflowY(): this {\n if (this._overflowY === null) {\n return this;\n }\n\n this._overflowY = null;\n this.setElementCSSRule(\"overflowY\", null);\n this.refreshWheelScrolling();\n\n return this;\n }\n\n /**\n * Returns whether a CSS overflow value lets the browser scroll the axis —\n * i.e. `auto` or `scroll`.\n *\n * @param overflow - The per-axis overflow value, or null.\n *\n * @returns `true` when the axis is scrollable.\n */\n private isOverflowScrollable(overflow: string | null): boolean {\n return overflow === \"auto\" || overflow === \"scroll\";\n }\n\n /**\n * Lazily attaches the eased wheel-scroll controller when either overflow\n * axis becomes scrollable, and tears it down when neither does. Called from\n * every overflow setter/clearer; because Panel `autoScroll` routes through\n * those, this single hook covers `autoScroll` panels and direct\n * `setOverflow(\"auto\")` users alike.\n */\n private refreshWheelScrolling(): void {\n const scrollable = this.isOverflowScrollable(this.getOverflowX())\n || this.isOverflowScrollable(this.getOverflowY());\n\n if (scrollable && !this._wheelScroller) {\n this.attachWheelScrolling();\n } else if (!scrollable && this._wheelScroller) {\n this.detachWheelScrolling();\n }\n }\n\n /**\n * Builds the {@link SmoothScroller} over the element's native scroll offsets\n * and registers the non-passive subtree wheel listener that feeds it.\n *\n * @remarks Subtree because wheel fires on whichever descendant the pointer\n * is over, not the scroll container itself; `passive: false` so\n * {@link onWheelScroll} can `preventDefault` the native page scroll.\n */\n private attachWheelScrolling(): void {\n this._wheelScroller = new SmoothScroller({\n read: (axis) => {\n const element = this.getScrollElement();\n\n return element ? (axis === \"x\" ? DOM.source.getScrollLeft(element) : DOM.source.getScrollTop(element)) : 0;\n },\n write: (axis, value) => this.writeNativeScroll(axis, value),\n clamp: (axis, value) => Util.clamp(value, 0, axis === \"x\" ? this.getMaxScrollLeft() : this.getMaxScrollTop()),\n });\n\n Event.addSubtreeListener(this, \"wheel\", { passive: false, handler: this.onWheelScroll });\n }\n\n /**\n * Removes the wheel listener, cancels any in-flight ease, and drops the\n * controller once neither axis is scrollable.\n */\n private detachWheelScrolling(): void {\n Event.removeSubtreeListener(this, \"wheel\", this.onWheelScroll);\n this._wheelScroller?.reset();\n this._wheelScroller = null;\n }\n\n /**\n * Writes a native scroll offset for one axis and mirrors the browser-clamped\n * result into the {@link getScrollLeft} / {@link getScrollTop} cache, holding\n * the cache invariant the eased wheel loop would otherwise bypass.\n *\n * @param axis - The axis to write.\n * @param value - The new offset in pixels.\n */\n private writeNativeScroll(axis: ScrollAxis, value: number): void {\n const element = this.getScrollElement();\n if (!element) {\n return;\n }\n\n if (axis === \"x\") {\n DOM.sink.apply(element, { scrollLeft: value });\n this._scrollLeft = DOM.source.getScrollLeft(element);\n } else {\n DOM.sink.apply(element, { scrollTop: value });\n this._scrollTop = DOM.source.getScrollTop(element);\n }\n }\n\n /**\n * Eases a wheel gesture into the element's native scroll offset. Only a\n * scrollable axis receives delta, and shift+wheel with a bare vertical delta\n * is redirected to horizontal.\n *\n * @param e - The wheel event.\n *\n * @remarks An axis counts as scrollable only when it has somewhere to go:\n * a scrollable overflow style is necessary but not sufficient, since an\n * `auto` axis whose content fits has no extent to move through. Claiming\n * such an axis would strand the wheel — the dispatch is descendant-first,\n * so an ancestor scroll region that *can* move (the capped content area\n * around a Dialog's `autoScroll` panel, say) is reached later and would\n * find the event already consumed. Ignoring it lets the wheel chain\n * outward, as it does natively.\n */\n private onWheelScroll(e: WheelEvent): Event.ListenerResult {\n const canX = this.isOverflowScrollable(this.getOverflowX()) && this.getMaxScrollLeft() > 0;\n const canY = this.isOverflowScrollable(this.getOverflowY()) && this.getMaxScrollTop() > 0;\n\n let dx = canX ? e.deltaX : 0;\n let dy = canY ? e.deltaY : 0;\n\n if (e.shiftKey && canX && e.deltaY !== 0 && e.deltaX === 0) {\n dx = e.deltaY;\n dy = 0;\n }\n\n if (dx === 0 && dy === 0) {\n return;\n }\n\n if (!consumeWheel(e)) {\n return;\n }\n\n this._wheelScroller?.scrollBy(dx, dy);\n\n return { prevent: true };\n }\n\n /**\n * Returns the CSS `contain` value, or null if not set.\n *\n * @returns The CSS contain string, or null.\n */\n getContain(): string | null {\n return this._contain;\n }\n\n /**\n * Sets the CSS `contain` property on the component's CSS rule. Hints the\n * rendering engine that descendants are isolated from external layout/paint.\n *\n * @param value - A CSS contain value (e.g. \"layout\", \"strict\", \"layout paint\").\n *\n * @returns This component, for method chaining.\n */\n setContain(value: string): this {\n if (this._contain === value) {\n return this;\n }\n\n this._contain = value;\n this.setElementCSSRule(\"contain\", value);\n\n return this;\n }\n\n /**\n * Removes the `contain` CSS property from the component's CSS rule.\n *\n * @returns This component, for method chaining.\n */\n clearContain(): this {\n if (this._contain === null) {\n return this;\n }\n\n this._contain = null;\n this.setElementCSSRule(\"contain\", null);\n\n return this;\n }\n\n /**\n * Returns the CSS `animation` shorthand value, or null if not set.\n *\n * @returns The CSS animation string, or null.\n */\n getAnimation(): string | null {\n return this._animation;\n }\n\n /**\n * Sets the CSS `animation` shorthand on the component's CSS rule.\n *\n * @param value - A CSS animation shorthand (e.g. \"ts-ui-spin 0.8s linear infinite\").\n *\n * @returns This component, for method chaining.\n */\n setAnimation(value: string): this {\n if (this._animation === value) {\n return this;\n }\n\n this._animation = value;\n this.setElementCSSRule(\"animation\", value);\n\n return this;\n }\n\n /**\n * Removes the CSS `animation` property from the component's CSS rule.\n *\n * @returns This component, for method chaining.\n */\n clearAnimation(): this {\n if (this._animation === null) {\n return this;\n }\n\n this._animation = null;\n this.setElementCSSRule(\"animation\", null);\n\n return this;\n }\n\n /**\n * Writes the CSS `animation-play-state` longhand on the component's own\n * `#uuid` rule — framework-managed (not on the options bag), set by\n * {@link onEffectiveVisibilityChange} to pause/resume this node's own CSS\n * animation without touching layout, `display`, or CSS transitions.\n *\n * @param value - `\"paused\"` to freeze the animation, `null` to resume it.\n * @returns This component, for method chaining.\n */\n protected setAnimationPlayState(value: string | null): this {\n this._animationPlayState = value;\n this.setElementCSSRule(\"animationPlayState\", value);\n\n return this;\n }\n\n /**\n * Returns the current `animation-play-state` written when this\n * component's effective visibility changes, or `null` when not paused.\n *\n * @returns The cached play-state value, or null.\n */\n getAnimationPlayState(): string | null {\n return this._animationPlayState;\n }\n\n /**\n * Returns the current CSS `transition` shorthand, or `null` if none has\n * been set.\n *\n * @returns The cached transition value, or null.\n */\n getTransition(): string | null {\n return this._transition;\n }\n\n /**\n * Sets the CSS `transition` shorthand on the component's inline style. Use\n * this to declare a property-by-property crossfade ahead of state writes\n * (e.g. setting a `transition: background-color 120ms ease-out` and then\n * later calling `setBackgroundColor` to fire the crossfade).\n *\n * The value is written **inline**, not to the component's `#id` rule,\n * because the render-time style pass replays the cached transition inline\n * on every render — and inline beats an `#id` rule. Writing to the rule\n * here would let that inline replay of a construction-time value shadow\n * every later runtime change, so a component that declared a transition at\n * construction could never re-set it. Inline keeps the setter and the\n * replay on the same seam.\n *\n * @param value - A CSS transition shorthand (e.g. `\"transform 120ms ease-out\"`).\n *\n * @returns This component, for method chaining.\n */\n setTransition(value: string | null): this {\n if (this._transition === value) {\n return this;\n }\n\n this._transition = value;\n this.setElementStyle(\"transition\", value);\n\n return this;\n }\n\n /**\n * Removes the CSS `transition` property from the component's inline style.\n *\n * @returns This component, for method chaining.\n */\n clearTransition(): this {\n if (this._transition === null) {\n return this;\n }\n\n this._transition = null;\n this.setElementStyle(\"transition\", null);\n\n return this;\n }\n\n /**\n * Returns the cached state of the HTML `disabled` attribute on the element.\n *\n * @returns True when the `disabled` attribute is set, false otherwise.\n */\n getDisabledAttribute(): boolean {\n return this._disabledAttribute;\n }\n\n /**\n * Sets the HTML `disabled` attribute on the underlying element.\n *\n * Distinct from `setEnabled` on input subclasses, which carries semantic +\n * ARIA + visual state. This setter only toggles the HTML attribute.\n *\n * @param value - True to add `disabled`, false to remove it.\n *\n * @returns This component, for method chaining.\n */\n setDisabledAttribute(value: boolean): this {\n if (this._disabledAttribute === value) {\n return this;\n }\n\n this._disabledAttribute = value;\n\n if (value) {\n this.setElementAttribute(\"disabled\", \"\");\n } else {\n this.removeElementAttribute(\"disabled\");\n }\n\n return this;\n }\n\n /**\n * Applies an ARIA attribute on this component's element. Used by the\n * {@link Aria} helper.\n *\n * @param name - The full attribute name (e.g. `\"aria-label\"`, `\"role\"`, `\"tabindex\"`).\n * @param value - The string value to set, or null to remove the attribute.\n *\n * @returns This component, for method chaining.\n *\n * @internal Consumers should use {@link getAria} to access typed ARIA setters.\n */\n applyAriaAttribute(name: string, value: string | null): this {\n if (value === null) {\n this.removeElementAttribute(name);\n } else {\n this.setElementAttribute(name, value);\n }\n\n return this;\n }\n\n /**\n * Returns the inline `pointer-events` value last passed to\n * {@link setPointerEvents}, or `null` if not set.\n *\n * @returns The pointer-events string, or null.\n */\n getPointerEvents(): string | null {\n return this._options.pointerEvents ?? this._defaultOptions.pointerEvents ?? null;\n }\n\n /**\n * Sets the CSS pointer-events property on the element.\n *\n * @param value - A CSS pointer-events value (e.g. \"none\", \"auto\").\n *\n * @returns This component, for method chaining.\n */\n setPointerEvents(value: string): this {\n this._options.pointerEvents = value;\n\n this.setElementStyle(\"pointerEvents\", value);\n\n return this;\n }\n\n /**\n * Removes the inline `pointer-events` property from the element.\n *\n * @returns This component, for method chaining.\n */\n clearPointerEvents(): this {\n if (this._options.pointerEvents === undefined) {\n return this;\n }\n\n this._options.pointerEvents = undefined;\n this.setElementStyle(\"pointerEvents\", null);\n\n return this;\n }\n\n /**\n * Returns the inline `writing-mode` value last passed to\n * {@link setWritingMode}, or `null` if not set.\n *\n * @returns The writing-mode string, or null.\n */\n getWritingMode(): string | null {\n return this._options.writingMode ?? this._defaultOptions.writingMode ?? null;\n }\n\n /**\n * Sets the CSS `writing-mode` property on the element. Unlike a\n * `transform: rotate`, `writing-mode` rotates the element's *layout box*,\n * so `getBoundingClientRect` reports the rotated width/height — used by the\n * vertical tab strip so measurement and hit-testing stay correct.\n *\n * @param value - A CSS writing-mode value (e.g. \"vertical-rl\", \"vertical-lr\").\n *\n * @returns This component, for method chaining.\n */\n setWritingMode(value: string): this {\n this._options.writingMode = value;\n\n this.setElementStyle(\"writingMode\", value);\n\n return this;\n }\n\n /**\n * Removes the inline `writing-mode` property from the element, restoring the\n * default horizontal text flow.\n *\n * @returns This component, for method chaining.\n */\n clearWritingMode(): this {\n if (this._options.writingMode === undefined) {\n return this;\n }\n\n this._options.writingMode = undefined;\n this.setElementStyle(\"writingMode\", null);\n\n return this;\n }\n\n /**\n * Returns the opacity value last passed to {@link setOpacity}, or `null` if\n * no opacity has been set.\n *\n * @returns The opacity number, or null.\n */\n getOpacity(): number | null {\n return this._opacity;\n }\n\n /**\n * Sets the CSS opacity property on the element.\n *\n * @param value - A number between `0` (fully transparent) and `1` (fully opaque). Use {@link clearOpacity} to remove the property.\n *\n * @returns This component, for method chaining.\n */\n setOpacity(value: number): this {\n this._opacity = value;\n\n this.setElementStyle(\"opacity\", String(value));\n\n return this;\n }\n\n /**\n * Removes the opacity property from the element's inline style, restoring\n * full opacity from the CSS rule or default.\n *\n * @returns This component, for method chaining.\n */\n clearOpacity(): this {\n this._opacity = null;\n this.setElementStyle(\"opacity\", null);\n\n return this;\n }\n\n /**\n * Returns the cached `will-change` value last passed to {@link setWillChange}.\n *\n * @returns The active hint string, or `null` if no hint is set.\n */\n getWillChange(): string | null {\n return this._willChange;\n }\n\n /**\n * Sets the CSS `will-change` hint on the element, pre-promoting it to its\n * own compositor layer so the first transform/scroll frame doesn't pay a\n * layer-creation cost. Pass `null` to clear the hint and release the layer.\n *\n * @param value - A CSS `will-change` value (e.g. `\"transform\"`) or `null` to clear.\n *\n * @returns This component, for method chaining.\n *\n * @remarks The hint costs GPU memory and is ignored by browsers past a\n * per-page threshold (~50–100 elements). Set it only over the active-motion\n * lifetime (drag, pool membership, scroll-target lifetime) and clear it\n * promptly when motion ends.\n */\n setWillChange(value: string | null): this {\n if (this._willChange === value) {\n return this;\n }\n\n this._willChange = value;\n\n this.setElementStyle(\"willChange\", value);\n\n return this;\n }\n\n /**\n * Returns the CSS `white-space` value last written by {@link setWhiteSpace},\n * or `null` if cleared.\n *\n * @returns The white-space string, or null.\n */\n getWhiteSpace(): string | null {\n return this._whiteSpace;\n }\n\n /**\n * Sets the CSS white-space property on the component's CSS rule.\n *\n * @param value - A CSS white-space value (e.g. \"nowrap\", \"normal\", \"pre\").\n *\n * @returns This component, for method chaining.\n *\n * @remarks Previously declared on [`Text`](/api/component/input/classes/Text);\n * promoted to `Component` because the property has no Text-specific\n * semantics. The `_whiteSpace` backing field that {@link applyStyle}\n * already consults on re-render lives here, so caching during the setter\n * call keeps the post-render state in lockstep with the cached value.\n */\n setWhiteSpace(value: string): this {\n this._whiteSpace = value;\n\n this.setReconciledCSSRules({ whiteSpace: value });\n\n return this;\n }\n\n /**\n * Removes the white-space CSS property from the component's CSS rule.\n *\n * @returns This component, for method chaining.\n */\n clearWhiteSpace(): this {\n if (this._whiteSpace === null) {\n return this;\n }\n\n this._whiteSpace = null;\n this.setElementCSSRule(\"whiteSpace\", null);\n\n return this;\n }\n\n /**\n * Returns the current CSS user-select value.\n *\n * @returns The CSS user-select string, or null if not set.\n */\n getUserSelect(): string | null {\n return \"userSelect\" in this._options ? (this._options.userSelect ?? null) : (this._defaultOptions.userSelect ?? null);\n }\n\n /**\n * Sets the CSS user-select style on the element.\n *\n * @param value - A CSS user-select value (e.g. \"none\", \"text\", \"auto\").\n *\n * @returns This component, for method chaining.\n */\n setUserSelect(value: string): this {\n if (this._options.userSelect === value) {\n return this;\n }\n this._options.userSelect = value;\n this.setReconciledCSSRules({ userSelect: value });\n\n return this;\n }\n\n /**\n * Removes the user-select CSS property from the element.\n *\n * @returns This component, for method chaining.\n */\n clearUserSelect(): this {\n // Set (not skip) the key so `getUserSelect` sees an explicit clear and\n // returns null, suppressing the class default — distinct from the\n // never-set case where the key is absent and the default applies.\n this._options.userSelect = undefined;\n this.setElementCSSRule(\"userSelect\", null);\n\n return this;\n }\n\n /**\n * Moves browser focus to this component's DOM element.\n *\n * @param preventScroll - When `true`, suppresses the browser's\n * scroll-the-focused-element-into-view behaviour. Set this when the host\n * manages its own scroll offset (e.g. the [`Tab`](/api/layout/classes/Tab)\n * strip owns its clip frame's native scroll explicitly, so a browser\n * focus-scroll of that `overflow:hidden` frame would fight it and silently\n * desync the strip's scroll bookkeeping).\n *\n * @returns This component, for method chaining.\n */\n focus(preventScroll: boolean = false): this {\n let element = this.getElement();\n if (!element) {\n //console.warn(\"Component #\" + this.id + \" is not yet in the DOM, unable to focus.\");\n return this;\n }\n\n DOM.sink.focus(element, { preventScroll });\n\n return this;\n }\n\n /**\n * Removes browser focus from this component's DOM element.\n *\n * @returns This component, for method chaining.\n */\n unfocus(): this {\n let element = this.getElement();\n if (!element) {\n //console.warn(\"Component #\" + this.id + \" is not yet in the DOM, unable to focus.\");\n return this;\n }\n\n DOM.sink.blur(element);\n\n return this;\n }\n\n /** True when the framework, class, or group rule already delivers `value` for `key`. */\n protected matchesClassStyle(key: string, value: string | null): boolean {\n if (this._styleGroupBag !== null && this._styleGroupBag[key] === value) {\n return true;\n }\n\n return this._inheritedStyleBag !== null && this._inheritedStyleBag[key] === value;\n }\n\n /**\n * Selector suffixes (e.g. `.pressed`, `.selected`) whose class-tier state\n * rule this component's resting chrome must stay isolated from — see\n * `reconcileRuleDeclaration` / `setReconciledCSSRules`. Empty by default: a\n * component with no mutually-exclusive toggle-state class needs no\n * isolation, and its resting chrome writes straight to `#id`, exactly as\n * before this mechanism existed.\n *\n * A subclass overrides this to add its own suffix, chaining onto\n * `super()`'s list rather than replacing it, so a grandchild class inherits\n * every ancestor's exclusion automatically. Expected to return a fixed,\n * construction-time-stable list per class — the same expectation\n * `getClassStyleDefaults()` already carries — because it is read from as\n * early as the `super()` construction cascade.\n */\n protected getRestingExclusionSuffixes(): readonly string[] {\n return [];\n }\n\n private get restingIsolationSuffix(): string {\n return this.getRestingExclusionSuffixes().map((suffix) => \":not(\" + suffix + \")\").join(\"\");\n }\n\n // Generalizes Button's original `_restingChromeIsolated` flag: an\n // instance-level opt-out for a class whose own defaults publish no\n // state-tier chrome to isolate from (e.g. a chromeless Button). `declare`\n // because a subclass may write it during the `super()` cascade (Button's\n // chromeless branch runs inside `applyChromeOptions`, itself dispatched from\n // `super()`); a plain initializer would run afterward and revert the write.\n private declare _chromeIsolationEnabled?: boolean;\n\n protected isChromeIsolationEnabled(): boolean {\n return this._chromeIsolationEnabled ?? true;\n }\n\n protected setChromeIsolationEnabled(enabled: boolean): void {\n this._chromeIsolationEnabled = enabled;\n }\n\n /** True when this instance currently isolates its resting chrome from at\n * least one registered state class. */\n protected isRestingChromeIsolated(): boolean {\n return this.isChromeIsolationEnabled() && this.restingIsolationSuffix !== \"\";\n }\n\n // Lazy resting-isolation rule. Never allocated unless isRestingChromeIsolated()\n // is true somewhere on a write path — see the guard in\n // reconcileRuleDeclaration / setReconciledCSSRules below, which never calls\n // this getter with an empty restingIsolationSuffix.\n protected declare _restingStyleRule?: StyleRule;\n protected get restingStyleRule(): StyleRule {\n return this._restingStyleRule ??= this.createStyleRule(this.restingIsolationSuffix);\n }\n\n /**\n * Inserts `restingStyleRule` when a write just queued a real declaration on\n * an already-rendered instance — `applyStyle` materialises deferred rules at\n * the end of a render pass; a runtime setter firing later has no such pass\n * behind it. A rule holding only `null` removals is left unmaterialised, as\n * `Component` does for every other deferred rule.\n */\n protected materialiseRestingRule(): void {\n if (this.getElement() && this.restingStyleRule.hasQueuedDeclarations()) {\n this.restingStyleRule.ensure();\n }\n }\n\n /**\n * Routes one `applyStyle` rule declaration to the rule that should carry\n * it: dropped when the framework or class rule already delivers the same\n * key/value, queued onto the per-component `#id` rule otherwise.\n *\n * @param key - The CSS property name (camelCase).\n * @param value - The value to write, or null to remove the property.\n *\n * @remarks Only skips a write issued from `applyStyle` itself — a runtime\n * setter calling `setElementCSSRule` never goes through this helper, so\n * it always reaches `#id` and wins on specificity regardless of what the\n * framework or class rule already holds. A hoisted property whose runtime\n * setter also needs this treatment routes through\n * {@link setReconciledCSSRules} instead, which still writes on a match —\n * as a removal — rather than skipping.\n */\n protected writeRuleDeclaration(key: string, value: string | null): void {\n if (this.matchesClassStyle(key, value)) {\n return;\n }\n\n this._styleRule.queue(key, value);\n }\n\n /**\n * `writeRuleDeclaration`'s clear-on-match sibling. A match queues a removal\n * rather than skipping, so a value the instance wrote earlier — during\n * construction, or through a runtime setter — cannot survive on `#id` and\n * outrank the class rule.\n */\n protected reconcileRuleDeclaration(key: string, value: string | null): void {\n if (this.isRestingChromeIsolated() && RESTING_ISOLATION_KEYS.has(key)) {\n this.restingStyleRule.set(key, this.matchesClassStyle(key, value) ? null : value);\n\n return;\n }\n\n this._styleRule.queue(key, this.matchesClassStyle(key, value) ? null : value);\n }\n\n /**\n * Runtime-setter form of `reconcileRuleDeclaration`. Routes through\n * `setElementCSSRules` so the whole bag commits in one flush and the\n * `autoCommitStyle` batching gate still applies. Inert before the first\n * render, when `_inheritedStyleBag` is still null.\n */\n protected setReconciledCSSRules(values: Style): this {\n const isolated = this.isRestingChromeIsolated();\n const resolved: Style = {};\n let wroteIsolated = false;\n\n for (const key of Object.keys(values)) {\n if (isolated && RESTING_ISOLATION_KEYS.has(key)) {\n wroteIsolated = true;\n this.restingStyleRule.set(key, this.matchesClassStyle(key, values[key]) ? null : values[key]);\n\n continue;\n }\n\n resolved[key] = this.matchesClassStyle(key, values[key]) ? null : values[key];\n }\n\n if (wroteIsolated) {\n this.materialiseRestingRule();\n }\n\n return Object.keys(resolved).length > 0 ? this.setElementCSSRules(resolved) : this;\n }\n\n /**\n * The class-comparison bag `ensureClassStyleRule` resolves for this class.\n * Base implementation is a bare reference to `_defaultOptions` — the same\n * value `applyStyle` has always passed. Override when a subclass needs to\n * contribute a comparison value that doesn't live in `_defaultOptions`\n * (e.g. `Text`, whose `fontSize`/`lineHeight` resolve through private\n * derived fields).\n */\n protected getClassStyleDefaults(): ClassStyleDefaults {\n return this._defaultOptions;\n }\n\n /**\n * Writes all current style properties to the given element and its associated CSS rule.\n *\n * @param element - The element handle to apply styles to.\n *\n * @returns This component, for method chaining.\n *\n * @remarks Clears all existing inline styles on the element before re-applying, ensuring a clean state.\n * Declarations that are uniform for this class — the same value every\n * instance would produce from its defaults — are served by a\n * framework-wide `:where(.ts-ui-component)` rule and, where this class's\n * defaults deviate from that, a shared `.ClassName` rule; only a value an\n * instance actually deviates on is queued into this component's own\n * `#id` rule. The `#id` rule is inserted only when a declaration was\n * queued during this pass; a component that contributes no deviation\n * gets no rule on the shared stylesheet until a later setter writes one.\n */\n applyStyle(element: Handle): this {\n DOM.sink.apply(element, { removeAttr: [\"style\"] });\n\n // Resolve the declarations this class inherits from the framework and\n // class rules before the phases run, so each phase can skip one it\n // already gets from a lower tier.\n this._inheritedStyleBag = ensureClassStyleRule(this.constructor, this.getClassStyleDefaults());\n\n const group = this.getStyleGroup();\n this._styleGroupBag = group\n ? ensureStyleGroupRule(this.constructor, group, resolveInstanceStyleDeclarations(this))\n : null;\n\n this.applyBoxAndVisibilityStyles();\n this.replayGeometryStyles();\n this.applySizeConstraintStyles();\n this.applyOverflowStyles();\n this.applyChromeStyles();\n this.applyMiscInlineStyles();\n this.applySubclassStyles();\n\n // Materialise last: every phase above queued into the dirty bag, so the\n // whole rule body reaches the stylesheet as one write — or none, if the\n // bag is empty.\n this.materialiseStyleRule();\n\n this.materialiseDeferredRules();\n\n return this;\n }\n\n /**\n * Writes the box-model, visibility, display, cursor, and colour styles — the\n * first `applyStyle` phase.\n */\n private applyBoxAndVisibilityStyles(): void {\n // Every option-backed read below goes through the field's getter (or an\n // inline `_options.X ?? _defaultOptions.X` for the carve-out sizes), so\n // class-level defaults reach the DOM even when no setter has fired —\n // the getter owns the fallback; there is no merged bag to drift from.\n if (this._boxSizing) {\n this.writeRuleDeclaration(\"boxSizing\", this._boxSizing);\n }\n\n this.writeRuleDeclaration(\"position\", this._position);\n\n const visible = this.isVisible();\n if (visible != null) {\n // `true` resolves to `inherit`, not `visible`, so an explicitly-shown\n // component still hides when an ancestor hides (e.g. a Tab panel that\n // is switched away). This mirrors the live `setVisible` setter, which\n // also writes `inherit` for `true`; writing `visible` here would pin\n // the element on screen and defeat ancestor-based hiding.\n this.reconcileRuleDeclaration(\"visibility\", visible ? \"inherit\" : \"hidden\");\n } else {\n this.reconcileRuleDeclaration(\"visibility\", \"inherit\");\n }\n\n const displayed = this.isDisplayed();\n if (displayed != null) {\n this.writeRuleDeclaration(\"display\", displayed ? \"block\" : \"none\");\n }\n\n const cursor = this.getCursor();\n if (cursor) {\n this.writeRuleDeclaration(\"cursor\", cursor);\n }\n\n const foregroundColor = this.getForegroundColor();\n if (foregroundColor) {\n this.reconcileRuleDeclaration(\"color\", foregroundColor);\n }\n\n const backgroundColor = this.getBackgroundColor();\n if (backgroundColor) {\n this.reconcileRuleDeclaration(\"backgroundColor\", backgroundColor);\n }\n\n const backgroundImage = this.getBackgroundImage();\n if (backgroundImage) {\n this.reconcileRuleDeclaration(\"backgroundImage\", backgroundImage);\n }\n }\n\n /**\n * Replays the cached width / top / left / height and translate transform that\n * the leading inline-style wipe cleared — the second `applyStyle` phase.\n */\n private replayGeometryStyles(): void {\n // NaN means \"never assigned by a setter\" — skip the DOM write for those.\n // Any finite value (including 0) MUST be written so the DOM matches the cached field.\n if (!Number.isNaN(this._width)) {\n this._inlineStyle.set(\"width\", Math.round(this._width) + \"px\");\n }\n\n if (!Number.isNaN(this._top)) {\n this._inlineStyle.set(\"top\", Math.round(this._top) + \"px\");\n }\n\n if (!Number.isNaN(this._left)) {\n this._inlineStyle.set(\"left\", Math.round(this._left) + \"px\");\n }\n\n if (!Number.isNaN(this._height)) {\n this._inlineStyle.set(\"height\", Math.round(this._height) + \"px\");\n }\n\n // Replay the cached translate so a `setTranslate`'d transform survives\n // the inline-style wipe above, the same way width/top/left/height are\n // replayed. Skipped at the (0,0) default so components that drive\n // `transform` through `setElementCSSRule` (rotation) are left untouched.\n if (this._translateX !== 0 || this._translateY !== 0) {\n this._inlineStyle.set(\"transform\", \"translate3d(\" + Math.round(this._translateX) + \"px,\" + Math.round(this._translateY) + \"px,0)\");\n }\n }\n\n /**\n * Writes the min/max CSS constraints and reflects `data-maxSize` — the third\n * `applyStyle` phase.\n */\n private applySizeConstraintStyles(): void {\n // Carve-out: the CSS min/max writes use the raw author *constraint*, not\n // the computed `getMinSize()`/`getMaxSize()` (which fold in the layout\n // manager and would push computed sizes into CSS, fighting the layout\n // engine). Read the option/default directly, never via the getter.\n const minSize = this.getMinSizeConstraint();\n if (minSize) {\n this.reconcileRuleDeclaration(\"minWidth\", minSize.width + \"px\");\n this.reconcileRuleDeclaration(\"minHeight\", minSize.height + \"px\");\n }\n\n const maxSize = this.getMaxSizeConstraint();\n if (maxSize) {\n this.reconcileRuleDeclaration(\"maxWidth\", isUnbounded(maxSize.width) ? \"none\" : maxSize.width + \"px\");\n this.reconcileRuleDeclaration(\"maxHeight\", isUnbounded(maxSize.height) ? \"none\" : maxSize.height + \"px\");\n this.setDataAttribute(\"maxSize\", formatSizeAttr(maxSize.width, maxSize.height));\n }\n }\n\n /**\n * Writes the overflow styles and refreshes the wheel-scroll controller — the\n * fourth `applyStyle` phase.\n */\n private applyOverflowStyles(): void {\n const overflowX = this.getOverflowX();\n if (overflowX !== null) {\n this.reconcileRuleDeclaration(\"overflowX\", overflowX);\n }\n const overflowY = this.getOverflowY();\n if (overflowY !== null) {\n this.reconcileRuleDeclaration(\"overflowY\", overflowY);\n }\n\n // A scrollable *default* overflow (e.g. Drawer's `\"auto\"`) no longer\n // dispatches `setOverflow` through `applyOptions`, so attach the eased\n // wheel-scroll controller here from the effective overflow. Idempotent:\n // `refreshWheelScrolling` no-ops when the scroller already matches.\n this.refreshWheelScrolling();\n }\n\n /**\n * Writes the border, outline, border-radius, and box-shadow chrome styles —\n * the fifth `applyStyle` phase.\n */\n private applyChromeStyles(): void {\n if (this._border) {\n const border = borderToStyle(this._border);\n for (const key of Object.keys(border)) {\n this.reconcileRuleDeclaration(key, border[key]);\n }\n } else {\n this.writeRuleDeclaration(\"border\", null);\n }\n\n const outline = this.getOutline();\n if (outline) {\n this.reconcileRuleDeclaration(\"outline\", outline);\n }\n\n const borderRadius = this.getBorderRadius();\n if (borderRadius) {\n this.reconcileRuleDeclaration(\"borderRadius\", borderRadius);\n }\n\n const shadow = this.getShadow();\n if (shadow) {\n this.reconcileRuleDeclaration(\"boxShadow\", shadow);\n }\n }\n\n /**\n * Writes the remaining inline and rule styles (white-space, pointer-events,\n * writing-mode, touch-action, z-index, will-change, transition, opacity,\n * user-select, padding, insets, margin) — the sixth `applyStyle` phase.\n */\n private applyMiscInlineStyles(): void {\n if (this._whiteSpace) {\n this.reconcileRuleDeclaration(\"whiteSpace\", this._whiteSpace);\n }\n\n const pointerEvents = this.getPointerEvents();\n if (pointerEvents) {\n this._inlineStyle.set(\"pointerEvents\", pointerEvents);\n }\n\n const writingMode = this.getWritingMode();\n if (writingMode) {\n this._inlineStyle.set(\"writingMode\", writingMode);\n }\n\n const touchAction = this.getTouchAction();\n if (touchAction) {\n this._inlineStyle.set(\"touchAction\", touchAction);\n }\n\n const zIndex = this.getZIndex();\n if (zIndex) {\n this._inlineStyle.set(\"zIndex\", String(zIndex));\n }\n\n // Replay the cached will-change hint for the same reason as the\n // transition below: `setWillChange` writes inline, so a hint set before\n // the element rendered — e.g. from `applyOptions` during the super()\n // cascade — is otherwise lost to the wipe.\n if (this._willChange !== null) {\n this._inlineStyle.set(\"willChange\", this._willChange);\n }\n\n // Replay the cached transition so setters that fired before init\n // (e.g. accordion section setup) survive the `removeAttribute(\"style\")`\n // wipe a few lines above. Inline rather than CSS-rule so callers can\n // freely overwrite per-instance (the height transition wouldn't make\n // sense at the class-rule level).\n if (this._transition !== null) {\n this._inlineStyle.set(\"transition\", this._transition);\n }\n\n if (this._opacity !== null) {\n this._inlineStyle.set(\"opacity\", String(this._opacity));\n }\n\n const userSelect = this.getUserSelect();\n if (userSelect) {\n this.reconcileRuleDeclaration(\"userSelect\", userSelect);\n }\n\n const padding = this.getPadding();\n if (padding) {\n this.writeRuleDeclaration(\"padding\", padding.render());\n }\n\n const insets = this.getInsets();\n if (insets) {\n this.setDataAttribute(\"insets\", insets.render());\n }\n\n this.writeRuleDeclaration(\"margin\", \"0px 0px 0px 0px\");\n }\n\n /**\n * Extension point for a subclass that needs to queue more `#id` rule\n * declarations — through `writeRuleDeclaration` / `reconcileRuleDeclaration`\n * / `setReconciledCSSRules`, so they still compare against the class tier —\n * before `applyStyle`'s one materialising flush runs. A no-op by default.\n *\n * A subclass overrides this, chaining onto `super()`'s call rather than\n * replacing it, so a grandchild class's own contribution runs too. Only\n * needed by a subclass whose extra declaration can itself resolve to a\n * class-tier-matching removal (see\n * plans/implemented/applystyle-flush-order-empty-rule-fix.md's Architecture\n * Decisions) — a subclass that only ever writes a real, always-present\n * value (`Legend`'s `marginLeft`, `Markdown`'s `maxWidth`) has no need of\n * this hook and can keep overriding `applyStyle` directly, calling\n * `super.applyStyle()` first.\n */\n protected applySubclassStyles(): void {\n // No-op by default.\n }\n\n /**\n * Materialises `rule` only when doing so is worth it: the rule already\n * exists — so any queued write, including a `null` removal, is a real\n * change to live state — or the dirty bag holds at least one real\n * declaration. Skips a rule that would otherwise insert empty, with every\n * currently-queued entry a no-op `null` removal of a property that was\n * never set.\n *\n * @param rule - The component-scoped or deferred `StyleRule` to\n * conditionally materialise.\n */\n private materialiseWhenNeeded(rule: StyleRule): void {\n if (rule.isMaterialized() || rule.hasQueuedDeclarations()) {\n rule.ensure();\n }\n }\n\n /**\n * Materialises this component's `#id` stylesheet rule and drains the queued\n * declarations into it — the final `applyStyle` phase before the deferred\n * state rules.\n *\n * @remarks Skipped entirely when the phases queued nothing worth a real\n * declaration: a component that contributes no declaration gets no rule\n * on the shared stylesheet, and none is needed until a later setter\n * writes one. `ensure()` flushes the bag on first materialisation; the\n * `flush()` after it covers the re-render case, where the rule already\n * exists and `ensure()` returns it without draining.\n */\n protected materialiseStyleRule(): void {\n this.materialiseWhenNeeded(this._styleRule);\n this._styleRule.flush();\n }\n\n /**\n * Materialises the deferred subclass state rules onto the live stylesheet —\n * the final `applyStyle` phase.\n */\n private materialiseDeferredRules(): void {\n // Materialise state-specific rules registered by subclasses (Button's\n // `.pressed` / `:hover:not(.pressed)`, ToggleButton's `.selected`). Each rule's\n // pending writes flush onto the live `CSSStyleRule` inside `ensure()`,\n // so the stylesheet picks up the entry on first render rather than on\n // first setter write during construction. A deferred rule allocated via\n // `createStyleRule()` but never given a real declaration (e.g. `Panel`'s\n // `::-webkit-scrollbar` rule when the native bar is never hidden) is\n // correctly skipped rather than inserted empty.\n for (const deferredRule of this._deferredStyleRules.values()) {\n this.materialiseWhenNeeded(deferredRule);\n }\n }\n\n /**\n * Re-applies all styles to the existing DOM element, syncing state after external changes.\n */\n sync() {\n let element = DOM.source.getElementById(this.getId());\n if (!element) {\n return;\n }\n\n this.applyStyle(element);\n }\n\n /**\n * Returns the parent component this component was added to, or null if it has no parent.\n *\n * @returns The parent {@link Component}, or null.\n */\n getParentComponent(): Component | null {\n return this._parent;\n }\n\n /**\n * Adds multiple child components in a single call, with optional per-component layout constraints.\n *\n * Each argument is either a {@link Component} (added with no constraints), a\n * {@link ComponentFactory} (added with no constraints), a\n * {@link ConstrainedComponent} pair (added with the supplied constraints), or an array of\n * any of those forms (each entry is processed in order). All forms can be freely mixed in\n * the same call.\n *\n * @param specs - The components to add. Each entry is a bare {@link Component}, a\n * {@link ComponentFactory}, a {@link ConstrainedComponent} pair, or an array of those.\n *\n * @returns This component, for method chaining.\n */\n addComponents(...specs: Array<Component | ComponentFactory | ConstrainedComponent\n | Array<Component | ComponentFactory | ConstrainedComponent>>): this {\n for (const spec of specs) {\n const items = Array.isArray(spec) ? spec : [spec];\n\n for (const item of items) {\n // A factory is a function, so it is neither a Component nor a\n // ConstrainedComponent pair — without the typeof arm it would\n // fall through and have `.component` read off a function.\n if (item instanceof Component || typeof item === \"function\") {\n this.addComponent(item);\n } else {\n this.addComponent(item.component, item.constraints);\n }\n }\n }\n\n return this;\n }\n\n /**\n * Wires a child into this container's size-change propagation: adopts it as\n * the child's parent and installs the two callback slots that relay a\n * child's preferred-size / constraint-size change up to this container (which\n * re-lays-out and relays onward to its own parent). The teardown counterpart\n * is `unwireChild`.\n *\n * @param component - The child being attached to this container.\n */\n private wireChild(component: Component): void {\n component._parent = this;\n component._onPreferredSizeChange = () => {\n this.scheduleLayout();\n\n this._onPreferredSizeChange?.();\n };\n component._onConstraintSizeChange = () => {\n this.scheduleLayout();\n\n this._onConstraintSizeChange?.();\n };\n }\n\n /**\n * Tears down a child wired by `wireChild`: releases its layout constraints,\n * nulls both size-change callback slots (so a detached child can no longer\n * re-enter this container's layout), clears its parent, and removes its\n * element. Shared by `removeComponent` and `removeAllComponents`.\n *\n * @param component - The child being detached from this container.\n * @returns The layout constraints that were registered for the child, or undefined.\n */\n private unwireChild(component: Component): LayoutConstraints | undefined {\n const constraints = this.delLayoutConstraints(component);\n\n component._parent = null;\n component._onPreferredSizeChange = null;\n component._onConstraintSizeChange = null;\n component.removeElement();\n\n return constraints ?? undefined;\n }\n\n /**\n * Adds a child component, appends its element, wires preferred-size change propagation, and triggers layout.\n *\n * The child may be a live {@link Component} or a {@link ComponentFactory} that has not been\n * built yet. A factory is offered to this container's layout manager first: a manager that\n * defers it owns when — and whether — it runs, which is how a\n * [`Tab`](/api/layout/classes/Tab) registers a tab whose content is built on first\n * activation. Every other manager declines, and the factory runs immediately.\n *\n * A factory returning a promise is only meaningful to a manager that defers it, because\n * that manager is the one showing a spinner for the wait. On the immediate path there is\n * nothing to host the wait, so a promise throws.\n *\n * @param component - The child component to add, or a factory producing it.\n * @param constraints - Optional. Layout constraints to pass to the layout manager.\n *\n * @throws Error if a factory returns a promise and no layout manager deferred it.\n */\n addComponent(component: Component | ComponentFactory, constraints?: LayoutConstraints): this {\n if (typeof component === \"function\") {\n const manager = this.getLayoutManager();\n\n // A manager that claims the factory owns when (and whether) it runs.\n if (manager && manager.addDeferredComponent(component, constraints)) {\n return this;\n }\n\n const built = component();\n\n if (built instanceof Promise) {\n throw new Error(\"Component.addComponent: an async factory needs a layout manager that defers it — \"\n + \"add it to a Tab-managed container and leave `lazy` at its default.\");\n }\n\n component = built;\n }\n\n return this.insertComponent(component, this._components.length, constraints);\n }\n\n /**\n * Inserts a child component at the given index, appends its element at the matching DOM position,\n * wires preferred-size change propagation, and triggers layout.\n *\n * @param component - The child component to insert.\n * @param index - Zero-based insertion index. Values outside `[0, children.length]` are clamped.\n * @param constraints - Optional. Layout constraints to pass to the layout manager.\n *\n * @remarks\n * Use this when child order matters — for example, placing a leading glyph before an existing\n * label without removing and re-appending the label. `addComponent(c, …)` is the append-at-end\n * shortcut for `insertComponent(c, children.length, …)`.\n */\n insertComponent(component: Component, index: number, constraints?: LayoutConstraints): this {\n if (component._parent === this) {\n return this;\n }\n\n if (component._parent !== null) {\n throw new Error(`Component ${component.getId()} already has a parent. Remove it first.`);\n }\n\n const clampedIndex = Util.clamp(index, 0, this._components.length);\n this._components.splice(clampedIndex, 0, component);\n\n this.setLayoutConstraints(component, constraints);\n\n this.wireChild(component);\n\n let element = this.getElement();\n if (!element) {\n return this;\n }\n\n let compElement = component.getElement(true);\n // Reference the following sibling's attach node, not its element: a\n // clip-framed sibling sits inside its frame, so `insertBefore` against\n // its bare element (no longer a direct child of this container) would\n // throw. `getAttachNode` resolves to the frame when one is active.\n const nextSibling = clampedIndex + 1 < this._components.length\n ? this._components[clampedIndex + 1].getAttachNode()\n : null;\n const host = this.getChildHost();\n\n if (host) {\n DOM.sink.insertBefore(host, compElement!, nextSibling ?? null);\n }\n\n this.scheduleLayout();\n // See addComponent: propagate the container's own preferred-size change up\n // so an ancestor that sizes to this container tracks the inserted child.\n this._onPreferredSizeChange?.();\n\n return this;\n }\n\n /**\n * Atomically moves a child from its current parent (if any) to this container, at an optional\n * index, in a single call.\n *\n * Detaches `child` from its present parent and attaches it here, expressed entirely through the\n * existing {@link removeComponent} / {@link insertComponent} mutators, so subclass overrides of\n * those methods are honoured and the `already has a parent` guard stays armed for the genuine\n * two-parents error. When `index` is omitted the child is appended (mirroring\n * {@link addComponent}); when supplied it is clamped to `[0, children.length]`.\n *\n * @param child - The component to move into this container.\n * @param index - Optional. Zero-based destination index. Omitted appends; values outside\n * `[0, children.length]` are clamped.\n * @param constraints - Optional. Layout constraints for the destination. When omitted, the\n * constraints held by the old parent are carried across.\n *\n * @returns This component, for method chaining.\n *\n * @remarks\n * Both the source and destination containers schedule a layout, because `removeComponent` and\n * `insertComponent` each call `scheduleLayout`; the two schedules collapse to a single\n * `requestAnimationFrame` flush. The child's DOM element is detached from the old parent and\n * re-attached under this container, so any in-flight CSS transition on the element or its\n * descendants is reset by the move. Constraints are carried from the old parent by default but\n * an explicit `constraints` argument always wins — carrying an old layout manager's constraints\n * into an incompatible new manager (e.g. a [`LayoutConstraints`](/api/layout/classes/LayoutConstraints)\n * shaped for a different region) is the caller's responsibility. Moving into a container whose\n * `addComponent` / `removeComponent` narrow the accepted child type is likewise the caller's\n * responsibility, as this base-class primitive accepts any {@link Component}.\n */\n moveComponent(child: Component, index?: number, constraints?: LayoutConstraints): this {\n const oldParent = child.getParentComponent();\n\n // True no-op: already here and no reorder requested.\n if (oldParent === this && index === undefined) {\n return this;\n }\n\n // Detach from the present parent, capturing its layout constraints so they can be carried\n // unless the caller overrides them. removeComponent clears child._parent to null, which\n // satisfies insertComponent's parent guard and disarms its same-parent early-return, so an\n // intra-parent reorder is honoured rather than silently dropped.\n const carried = oldParent ? oldParent.removeComponent(child) : undefined;\n\n // Computed after removeComponent has spliced child out, so the append index reflects the\n // post-detach length in the same-parent reorder case.\n const targetIndex = index ?? this._components.length;\n\n this.insertComponent(child, targetIndex, constraints ?? carried ?? undefined);\n\n return this;\n }\n\n /**\n * Removes a child component, detaches its element, and triggers layout.\n *\n * @param component - The Component instance to remove.\n *\n * @returns The layout constraints that were registered for the removed component, or undefined.\n *\n * @remarks Detach-only — does not call {@link dispose}. To discard every child at once\n * instead of re-parenting them, use {@link disposeAllComponents}.\n */\n removeComponent(component: Component): LayoutConstraints | undefined {\n let index = this._components.indexOf(component);\n\n if (index > -1) {\n this._components.splice(index, 1);\n }\n\n const constraints = this.unwireChild(component);\n\n this.scheduleLayout();\n // See addComponent: losing a child changes this container's own preferred\n // size, so notify the parent to relayout and re-measure.\n this._onPreferredSizeChange?.();\n\n return constraints;\n }\n\n /**\n * Removes all child components and their DOM elements without triggering layout.\n *\n * @returns This component, for method chaining.\n *\n * @remarks Detach-only, like {@link removeComponent} — none of the removed children are\n * disposed, so a re-parenting caller keeps them alive. To discard the children instead, use\n * {@link disposeAllComponents}.\n */\n removeAllComponents(): this {\n for (const component of this._components) {\n this.unwireChild(component);\n }\n\n this._components = [];\n\n return this;\n }\n\n /**\n * Disposes every current child, then removes them all.\n *\n * The discarding counterpart to {@link removeAllComponents}: that method\n * only detaches children (a re-parenting move, e.g. through\n * {@link moveComponent}, depends on the detached child staying alive), so a\n * caller that means to throw the children away instead has to loop\n * `.dispose()` over {@link getComponents} itself before calling it —\n * forgotten, that loop leaks each child's per-instance stylesheet rule and\n * any theme/listener subscriptions on every rebuild. Use this whenever a\n * rebuild's old children are not going to be reused.\n *\n * @returns This component, for method chaining.\n */\n disposeAllComponents(): this {\n for (const component of this._components) {\n component.dispose();\n }\n\n return this.removeAllComponents();\n }\n\n /**\n * Sorts the children array in place using the given comparator function.\n *\n * @param comparator - Optional. A comparator function that receives two Components and returns a number.\n *\n * @returns This component, for method chaining.\n */\n sortComponents(comparator: Comparator<Component, Component> | undefined): this {\n this._components.sort(comparator);\n\n return this;\n }\n\n /**\n * Returns the array of child components.\n *\n * @returns The live array of child Component instances.\n */\n getComponents() {\n return this._components;\n }\n\n /**\n * Returns the child components that participate in layout: `getComponents`\n * filtered to those whose `isDisplayed` is `true`. Layout managers that\n * size or place children iterate this rather than `getComponents()`, so a\n * `display: none` child reserves no space. The general `getComponents()`\n * accessor is unchanged and still returns *all* children for serialization,\n * teardown, event delegation, and DOM mounting.\n *\n * @returns The displayed child components, in order.\n */\n getLaidOutComponents(): Component[] {\n return this._components.filter(component => component.isDisplayed());\n }\n\n /**\n * Returns the layout constraints for a child component from the layout manager.\n *\n * @param component - The child component whose constraints to retrieve.\n *\n * @returns The LayoutConstraints for the component, or undefined if none are set.\n */\n getLayoutConstraints(component: Component) {\n const lm = this.getLayoutManager();\n if (!lm) {\n console.warn(\"Unable to get layout constraints, no layout manager specified.\");\n return;\n }\n\n return lm.getLayoutConstraints(component);\n }\n\n /**\n * Registers layout constraints for a child component with the layout manager.\n *\n * @param component - The child component to constrain.\n * @param constraints - Optional. The layout constraints to apply.\n */\n setLayoutConstraints(component: Component, constraints?: LayoutConstraints) {\n const lm = this.getLayoutManager();\n if (!lm) {\n console.warn(\"Unable to set layout constraints, no layout manager specified.\");\n return;\n }\n\n return lm.setLayoutConstraints(component, constraints);\n }\n\n /**\n * Removes and returns the layout constraints for a child component.\n *\n * @param component - The child component whose constraints to remove.\n *\n * @returns The removed LayoutConstraints, or null if no layout manager is set.\n */\n delLayoutConstraints(component: Component) {\n const lm = this.getLayoutManager();\n if (!lm) {\n return null;\n }\n\n return lm.delLayoutConstraints(component);\n }\n\n /**\n * Returns the layout manager currently attached to this component.\n *\n * @returns The current LayoutManager instance.\n */\n getLayoutManager(): LayoutManager {\n const layoutManager = (this._options.layoutManager as LayoutManager | undefined)\n ?? (this._defaultLayoutManager ??= new Absolute());\n\n // The class-level default manager is no longer dispatched through\n // `setLayoutManager`, so attach it lazily the first time it is\n // resolved. Layout consumers read the container back via\n // `getContainer()`; without this they would see `null`. The `!== this`\n // guard makes it fire exactly once and leaves the explicitly-set path\n // (which already attached in `setLayoutManager`) untouched. Mirror that\n // path's `data-layout` attribute so a default-layout component still\n // advertises its manager to DevTools.\n if (layoutManager && layoutManager.getContainer() !== this) {\n layoutManager.attach(this);\n this.setDataAttribute(\"layout\", layoutManager.getClassName().replace(/^_/, \"\"));\n }\n\n return layoutManager;\n }\n\n /**\n * Detaches the current layout manager, attaches the new one, and stores the class name as an attribute.\n *\n * @param layoutManager - The new LayoutManager to use for this component.\n */\n setLayoutManager(layoutManager: LayoutManager): this {\n const current = this._options.layoutManager;\n if (current) {\n current.detach();\n }\n\n this._options.layoutManager = layoutManager;\n\n if (layoutManager) {\n layoutManager.attach(this);\n }\n\n // `callable()`-wrapped classes report their underscored alias\n // (`_HBox`) through `constructor.name`; strip the leading underscore\n // so DevTools shows `data-layout=\"HBox\"` rather than `_HBox`.\n this.setDataAttribute(\"layout\", layoutManager.getClassName().replace(/^_/, \"\"));\n\n return this;\n }\n\n /**\n * Returns true if layout has been paused for this component.\n *\n * @returns True if layout passes are currently suppressed.\n */\n isLayoutPaused() {\n return this._layoutPaused;\n }\n\n /**\n * Suspends automatic layout passes until resumeLayout is called.\n */\n pauseLayout(): this {\n this._layoutPaused = true;\n\n return this;\n }\n\n /**\n * Resumes layout and immediately triggers a doLayout pass.\n *\n * @returns This component, for method chaining.\n *\n * @remarks The pass runs synchronously, so like `flushLayout()` it bypasses\n * the startup hold that keeps the first coalesced flush waiting for the web\n * font to activate — with the same exception for the virtualised row views,\n * whose rows stay unrendered until the hold ends. Resuming during startup\n * can therefore lay this component out against the fallback font; the\n * font-load re-measure corrects it once the real face arrives.\n */\n resumeLayout(): this {\n this._layoutPaused = false;\n this.doLayout();\n\n return this;\n }\n\n /**\n * Calls doLayout on each direct child component.\n *\n * @returns This component, for method chaining.\n */\n doChildrenComponentLayouts(): this {\n // Lay out only displayed children — a `display: none` subtree takes no\n // space, so recursing into it is wasted work and leaves stale committed\n // coordinates that `reserveContentFrame` would otherwise read.\n let components = this.getLaidOutComponents();\n\n for (let idx = 0; idx < components.length; idx += 1) {\n let component = components[idx];\n component.doLayout();\n }\n\n return this;\n }\n\n /**\n * Delegates layout to the layout manager unless layout is currently paused.\n *\n * @returns This component, for method chaining.\n *\n * @remarks Throws an Error if no layout manager has been set.\n *\n * The dirty flag is cleared only when this component has an element: a\n * layout manager that reads {@link getInnerSize} — `null` without one,\n * e.g. `Card`, `Fit`, `Border`, the box layouts — cannot actually place\n * its children on a pass run before this component is rendered, so\n * clearing the flag anyway would let {@link applyBounds} skip the real\n * pass once the element exists and the same rectangle is handed to it\n * again (the header-cell \"no element\" case the protected\n * `canSkipUnchangedLayout` gate's opt-ins guard against).\n */\n doLayout(): this {\n if (this.isLayoutPaused()) {\n return this;\n }\n\n const lm = this.getLayoutManager();\n if (!lm) {\n throw new Error(\"Unable to do layout, no layout manager specified.\");\n }\n\n if (this.getElement()) {\n this._layoutDirty = false;\n }\n\n lm.doLayout();\n this.runFirstLayoutCallbacks();\n\n return this;\n }\n\n /**\n * Runs a callback once, the first time this component completes a layout\n * while its element is connected to the document — a per-instance \"mounted\n * and sized\" signal.\n *\n * A component's content is built before its host attaches it (a dock tab's\n * panel, an accordion section's body), so on the tick that builds it the\n * element may not exist yet and its geometry is unknown. Polling\n * `requestAnimationFrame` until `getElement()` appears is the workaround this\n * replaces: the host schedules a layout when it mounts the component, and\n * this fires right after that first connected layout — the element exists and\n * has been sized, so focus, measurement, or seeding can act on it.\n *\n * If the component has already laid out connected when called, the callback\n * is deferred to the next layout flush (via {@link afterNextLayout}) rather\n * than run synchronously, so callers see one consistent asynchronous\n * contract. Unlike the static `afterNextLayout`, this waits for *this*\n * component specifically, so it is safe to register before the host mounts it.\n *\n * @param callback - The work to run once after the first connected layout.\n *\n * @returns This component, for method chaining.\n */\n onFirstLayout(callback: () => void): this {\n const element = this.getElement();\n\n if (element && DOM.source.isConnected(element)) {\n Component.afterNextLayout(callback);\n\n return this;\n }\n\n (this._firstLayoutCallbacks ??= []).push(callback);\n // Ensure a layout will occur to drive the drain even if nothing else\n // schedules one; if the component is still detached when it runs, the\n // drain is skipped and waits for the host's mount-time layout.\n this.scheduleLayout();\n\n return this;\n }\n\n /**\n * Drains the {@link onFirstLayout} queue once this component has laid out\n * while connected. A layout that runs on a still-detached component (laid out\n * in a subtree before its host attaches it) leaves the queue intact to fire\n * on the connected layout that follows.\n */\n private runFirstLayoutCallbacks(): void {\n if (!this._firstLayoutCallbacks) {\n return;\n }\n\n const element = this.getElement();\n\n if (!element || !DOM.source.isConnected(element)) {\n return;\n }\n\n const callbacks = this._firstLayoutCallbacks;\n this._firstLayoutCallbacks = null;\n\n for (const callback of callbacks) {\n callback();\n }\n }\n\n /**\n * Marks this component's layout as stale, so the next {@link applyBounds}\n * cannot skip it even when the rectangle it is handed is unchanged.\n *\n * @returns This component, for method chaining.\n *\n * @remarks The cheaper counterpart to {@link scheduleLayout} for setters\n * that cannot lay out immediately — during construction, or mid-cascade —\n * and only need to make sure a later pass is not withheld.\n */\n invalidateLayout(): this {\n this._layoutDirty = true;\n\n return this;\n }\n\n /**\n * Whether a layout pass is owed. True until the first {@link doLayout}\n * completes.\n *\n * @returns `true` when this component has never completed a layout pass,\n * or has been marked stale since its last one.\n */\n isLayoutDirty(): boolean {\n return this._layoutDirty ?? true;\n }\n\n /**\n * Queues a layout pass to run on the next animation frame. Multiple calls within\n * the same frame coalesce into a single doLayout() call; if an ancestor is also\n * scheduled, the ancestor's recursion subsumes this component and its scheduled\n * pass is skipped.\n *\n * @returns This component, for method chaining.\n *\n * @remarks Honors `pauseLayout()`. Callers that need a synchronous layout commit\n * (e.g. before reading getInnerSize) should call `flushLayout()` instead.\n */\n scheduleLayout(): this {\n this._layoutDirty = true;\n\n if (this.isLayoutPaused()) {\n return this;\n }\n\n pendingLayouts.add(this);\n ensureFlushScheduled();\n\n return this;\n }\n\n /**\n * Signals that this component's own preferred and minimum sizes changed for\n * a reason the framework cannot observe through {@link setPreferredSize} /\n * {@link setMinSize} — typically a layout manager whose intrinsic sizing\n * depends on internal state (e.g. an {@link layout!Accordion} opening or closing a\n * section changes the height it wants). Fires the same upward relay a\n * {@link setPreferredSize} call would (installed by the parent in\n * `wireChild`), so every ancestor — and in particular a scrolling host —\n * re-lays-out and recomputes its overflow.\n *\n * `scheduleLayout` alone is not enough here: it re-lays-out this component's\n * own subtree inside its *unchanged* bounds, but never tells the parent the\n * component now wants a different size, so an `autoScroll` ancestor's\n * scrollbar goes stale until the next resize forces a top-down pass. A no-op\n * when the component has no wired parent.\n *\n * @returns This component, for method chaining.\n */\n notifyIntrinsicSizeChanged(): this {\n this._onPreferredSizeChange?.();\n this._onConstraintSizeChange?.();\n\n return this;\n }\n\n /**\n * Runs a callback once, after the next batched layout flush completes.\n *\n * Layout is coalesced onto an animation frame (see {@link scheduleLayout}),\n * so geometry a consumer has just triggered is not yet final on the\n * synchronous tick that triggered it. Deferring work here runs it past that\n * flush, once every dirty component has laid out, so it observes the settled\n * tree. The canonical case is moving focus into a freshly laid-out element:\n * a bare `requestAnimationFrame` only races the flush, whereas this follows\n * it deterministically.\n *\n * The callback fires on the same frame as an already-pending flush, or on\n * the next frame when nothing is scheduled; either way after every\n * `doLayout`. A callback that itself calls `afterNextLayout` queues the new\n * work for the following frame, not re-entrantly within this drain.\n *\n * @param callback - The work to run once after the next layout flush.\n */\n static afterNextLayout(callback: () => void): void {\n afterLayoutCallbacks.push(callback);\n ensureFlushScheduled();\n }\n\n /**\n * Forces a synchronous layout pass on this component, removing it from the\n * scheduled-layout queue if it was pending. Use when a layout-derived value must\n * be read before the next animation frame.\n *\n * @returns This component, for method chaining.\n *\n * @remarks Lays out immediately, so it bypasses the startup hold that keeps\n * the first coalesced flush waiting for the web font to activate. A caller\n * that flushes during startup can therefore read geometry measured against\n * the fallback font. That is the deliberate trade for a synchronous read —\n * and it is corrected anyway, because the font-load re-measure re-flows\n * every subscribed component once the real face arrives. The virtualised\n * row views are the exception: `Tree` and the table body check the hold\n * inside their own render pass, so flushing one during startup lays out its\n * frame but leaves its rows unrendered until the hold ends, rather than\n * rendering them at fallback sizes.\n */\n flushLayout(): this {\n pendingLayouts.delete(this);\n this.doLayout();\n\n return this;\n }\n\n /**\n * Synchronously drains the coalesced effective-visibility queue, cancelling\n * any pending animation frame first. Mirrors `flushLayout()`'s escape hatch:\n * the offline `RecordingDOMSink.requestAnimationFrame` drops its callback,\n * so tests (and any caller needing an immediate reconcile) call this instead\n * of waiting on a real frame.\n */\n static flushEffectiveVisibility(): void {\n if (visibilityRafHandle !== null) {\n DOM.sink.cancelAnimationFrame(visibilityRafHandle);\n visibilityRafHandle = null;\n }\n flushPendingVisibility();\n }\n\n /**\n * Registers a `mousedown` event listener on this component. Named\n * accessor that lets cross-bucket consumers (e.g.\n * [`DragManager`](/api/overlay/variables/DragManager)) route through the\n * component instead of reaching for\n * `Event.addListener(component, \"mousedown\", ...)` directly — the\n * framework's \"components own their event surface\" rule\n * (`ARCHITECTURE.md` §Event handling).\n *\n * @param listener - The callback invoked with the originating MouseEvent.\n * Fires for every button — this public surface has no documented button\n * restriction, so it opts out of `Event.addListener`'s primary-only\n * default to preserve that.\n *\n * @returns This component, for method chaining.\n */\n addMouseDownListener(listener: Event.Listener): this {\n Event.addListener(this, \"mousedown\", { button: \"any\", handler: listener });\n\n return this;\n }\n\n /**\n * Removes a previously registered mousedown listener.\n *\n * @param listener - The exact callback reference passed to {@link addMouseDownListener}.\n *\n * @returns This component, for method chaining.\n */\n removeMouseDownListener(listener: Event.Listener): this {\n Event.removeListener(this, \"mousedown\", listener);\n\n return this;\n }\n\n /**\n * Registers a subtree `mousedown` listener — the handler fires\n * whenever a mousedown lands on this component **or any of its\n * descendants**. Used by\n * [`DragManager`](/api/overlay/variables/DragManager) so a press\n * anywhere on a complex source (e.g. a `Row` whose cells receive\n * the actual mousedown) starts the drag.\n *\n * @param listener - The callback invoked with the originating MouseEvent.\n * Fires for every button — this public surface has no documented button\n * restriction, so it opts out of `Event.addSubtreeListener`'s\n * primary-only default to preserve that.\n *\n * @returns This component, for method chaining.\n */\n addMouseDownSubtreeListener(listener: Event.Listener): this {\n Event.addSubtreeListener(this, \"mousedown\", { button: \"any\", handler: listener });\n\n return this;\n }\n\n /**\n * Removes a previously registered subtree mousedown listener.\n *\n * @param listener - The exact callback reference passed to\n * {@link addMouseDownSubtreeListener}.\n *\n * @returns This component, for method chaining.\n */\n removeMouseDownSubtreeListener(listener: Event.Listener): this {\n Event.removeSubtreeListener(this, \"mousedown\", listener);\n\n return this;\n }\n\n /**\n * Sets the element ID, attaches the style and attribute buffers, applies style, and appends child elements.\n *\n * @param element - Optional. The element to initialise. Falls back to getElement() if omitted.\n *\n * @returns This component, for method chaining.\n *\n * @remarks Throws an Error if no element is available (i.e. render has not been called).\n */\n protected init(element?: Handle): this {\n element = element || this.getElement();\n if (!element) {\n throw new Error(\"Component has not been rendered!\");\n }\n\n DOM.sink.setId(element, this.getId());\n\n // Bind the inline-style and attribute buffers so any writes queued\n // during detached construction flush into the live element, and\n // subsequent setters write through directly.\n this._inlineStyle.attach(element);\n this._elementAttributes.attach(element);\n\n const group = this.getStyleGroup();\n // Whitespace-normalised (see `styleGroupClassSuffix`) so this is\n // always a valid single `classList` token — a raw caller-supplied\n // token containing a space would otherwise throw here, since\n // CSS-escaping (used only for the class-tier selector) does not\n // remove whitespace.\n const groupClass = group ? [this.constructor.name + \"--\" + styleGroupClassSuffix(group)] : [];\n DOM.sink.apply(element, { addClass: [COMPONENT_CLASS, ...getStyleClassChain(this.constructor), ...groupClass] });\n\n this.applyStyle(element);\n\n let components = this.getComponents();\n for (let i in components) {\n let component = components[i];\n let compElement = component.getElement(true);\n\n DOM.sink.appendChild(element, compElement!);\n }\n\n if (this._pendingRematerialize) {\n this._pendingRematerialize = false;\n // Queue the scroll/focus restore for the first connected layout — a\n // detached element cannot hold scroll or focus. Pushed directly\n // (not via onFirstLayout, which calls getElement() — unset here\n // mid-render) and paired with a scheduled layout to guarantee the\n // drain.\n (this._firstLayoutCallbacks ??= []).push(() => this.restoreReleasedState(element));\n this.scheduleLayout();\n }\n\n return this;\n }\n\n /**\n * Re-binds the style and attribute buffers to the component's current\n * element, without re-running the rest of `init()` (no class list, no\n * `applyStyle`, no child re-append).\n *\n * @returns This component, for method chaining.\n *\n * @remarks For almost every component `getElement()` returns a cached\n * field set once at render, so the buffers stay bound to the right\n * handle for the component's lifetime. `Body` is the one component whose\n * `getElement()` always resolves the live document body afresh instead\n * of a cached field, so a caller that re-mounts it against a different\n * DOM (only relevant to a swappable seam, e.g. a test harness) calls\n * this first to keep the buffers pointed at the current element.\n */\n protected reattachElementBuffers(): this {\n const element = this.getElement();\n\n if (element) {\n this._inlineStyle.attach(element);\n this._elementAttributes.attach(element);\n }\n\n return this;\n }\n\n /**\n * Creates the root DOM element for this component.\n *\n * @remarks Override in subclasses that need a non-HTML namespace (e.g. SVG).\n * The returned element is treated as an `HTMLElement` by the rest of the\n * Component pipeline; non-HTML roots should use the API surface that is\n * common to all Element types (`id`, `classList`, `setAttribute`,\n * `appendChild`, `style`).\n *\n * @returns The newly created root element handle.\n */\n protected createRootElement(): Handle {\n return DOM.sink.createElement(this._tag);\n }\n\n /**\n * Creates the DOM element from the tag name and initializes it via init().\n *\n * @returns The newly created and initialised element handle.\n */\n protected render(): Handle {\n let element = this.createRootElement();\n\n this.trackHandle(element);\n this.init(element);\n\n return element;\n }\n}\n\nconst ComponentCallable = callable(Component);\ntype ComponentCallable<TOptions extends ComponentOptions = ComponentOptions> = Component<TOptions>;\n\n// Every real subclass (`class Foo extends Component`) resolves its\n// `Object.getPrototypeOf` link against this *callable*, public-facing\n// reference — the import consumers use — not the raw class above, so this\n// is the reference the hierarchy walk in `core/ClassStyleRules.ts` must\n// treat as its root. See ARCHITECTURE.md's \"Components are exported through\n// `callable()`\": the wrapper preserves the prototype chain, but `extends`\n// stores the exact reference on the right-hand side of the clause.\nregisterStyleChainRoot(ComponentCallable);\n\nexport {\n Component as _Component,\n ComponentCallable as Component\n};\n\n"],"x_google_ignoreList":[14,15],"mappings":"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"}
|