@jimka/typescript-ui 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/{AbstractInput-sRNPzWel.js → AbstractInput-W2PLJV5_.js} +2 -2
- package/dist/lib/{AbstractInput-sRNPzWel.js.map → AbstractInput-W2PLJV5_.js.map} +1 -1
- package/dist/lib/{Anchor-CwRhdP2J.js → Anchor-iZhsvMlT.js} +2 -2
- package/dist/lib/{Anchor-CwRhdP2J.js.map → Anchor-iZhsvMlT.js.map} +1 -1
- package/dist/lib/AnimatedDropdown-D0RhVgv3.js +2 -0
- package/dist/lib/AnimatedDropdown-D0RhVgv3.js.map +1 -0
- package/dist/lib/Border-6GsTNV-2.js +2 -0
- package/dist/lib/Border-6GsTNV-2.js.map +1 -0
- package/dist/lib/Button-CnFAiQuV.js +2 -0
- package/dist/lib/Button-CnFAiQuV.js.map +1 -0
- package/dist/lib/{Card-QYo27r5b.js → Card-C20k2YHU.js} +2 -2
- package/dist/lib/{Card-QYo27r5b.js.map → Card-C20k2YHU.js.map} +1 -1
- package/dist/lib/Checkbox-CM1z8keM.js +2 -0
- package/dist/lib/Checkbox-CM1z8keM.js.map +1 -0
- package/dist/lib/{CheckboxMenuRow-CesLhSnp.js → CheckboxMenuRow-C1h4LPHR.js} +2 -2
- package/dist/lib/{CheckboxMenuRow-CesLhSnp.js.map → CheckboxMenuRow-C1h4LPHR.js.map} +1 -1
- package/dist/lib/{CodeEditor-N1FQodcF.js → CodeEditor-CTL2WjF8.js} +2 -2
- package/dist/lib/{CodeEditor-N1FQodcF.js.map → CodeEditor-CTL2WjF8.js.map} +1 -1
- package/dist/lib/ComboBox-PZ5YPL0X.js +2 -0
- package/dist/lib/ComboBox-PZ5YPL0X.js.map +1 -0
- package/dist/lib/Component-D99-15Zt.js +2 -0
- package/dist/lib/Component-D99-15Zt.js.map +1 -0
- package/dist/lib/Container-FWRjgF6T.js +2 -0
- package/dist/lib/{Container-abY5Ww3W.js.map → Container-FWRjgF6T.js.map} +1 -1
- package/dist/lib/DOM-Cjh7_7TF.js +2 -0
- package/dist/lib/DOM-Cjh7_7TF.js.map +1 -0
- package/dist/lib/Dialog-DN78RaVH.js +2 -0
- package/dist/lib/Dialog-DN78RaVH.js.map +1 -0
- package/dist/lib/{FieldDecorator-BlYMfZ9L.js → FieldDecorator-DyPX8CFh.js} +2 -2
- package/dist/lib/{FieldDecorator-BlYMfZ9L.js.map → FieldDecorator-DyPX8CFh.js.map} +1 -1
- package/dist/lib/{Fit-BhlB-HAo.js → Fit-CaPMj7Up.js} +2 -2
- package/dist/lib/{Fit-BhlB-HAo.js.map → Fit-CaPMj7Up.js.map} +1 -1
- package/dist/lib/{FloatingPanel-DkJXsZ2D.js → FloatingPanel-Dsy_vJxi.js} +2 -2
- package/dist/lib/{FloatingPanel-DkJXsZ2D.js.map → FloatingPanel-Dsy_vJxi.js.map} +1 -1
- package/dist/lib/Glyph-DiEpD3gy.js +2 -0
- package/dist/lib/Glyph-DiEpD3gy.js.map +1 -0
- package/dist/lib/{Grid-Daiz7F5d.js → Grid-ft_UUpj8.js} +2 -2
- package/dist/lib/{Grid-Daiz7F5d.js.map → Grid-ft_UUpj8.js.map} +1 -1
- package/dist/lib/{GridConstraints-C58LuTqM.js → GridConstraints-CvZ0Nzaw.js} +2 -2
- package/dist/lib/{GridConstraints-C58LuTqM.js.map → GridConstraints-CvZ0Nzaw.js.map} +1 -1
- package/dist/lib/{Header-Dql3Zxc6.js → Header-Osm3IjDw.js} +2 -2
- package/dist/lib/{Header-Dql3Zxc6.js.map → Header-Osm3IjDw.js.map} +1 -1
- package/dist/lib/{IconText-PUjhTLlp.js → IconText-BBaYJ2Fx.js} +2 -2
- package/dist/lib/{IconText-PUjhTLlp.js.map → IconText-BBaYJ2Fx.js.map} +1 -1
- package/dist/lib/{LayoutSerialization-CMxunLfV.js → LayoutSerialization-BC64__O7.js} +2 -2
- package/dist/lib/{LayoutSerialization-CMxunLfV.js.map → LayoutSerialization-BC64__O7.js.map} +1 -1
- package/dist/lib/List-CQbZK_pT.js +2 -0
- package/dist/lib/List-CQbZK_pT.js.map +1 -0
- package/dist/lib/{Menu-Q0bpXXze.js → Menu-CwHluLGT.js} +2 -2
- package/dist/lib/{Menu-Q0bpXXze.js.map → Menu-CwHluLGT.js.map} +1 -1
- package/dist/lib/{MenuButton-DCXi0tsP.js → MenuButton-BqCT-1yv.js} +2 -2
- package/dist/lib/{MenuButton-DCXi0tsP.js.map → MenuButton-BqCT-1yv.js.map} +1 -1
- package/dist/lib/{OverlayFade-3pof2AJH.js → OverlayFade-CuEXgimf.js} +2 -2
- package/dist/lib/{OverlayFade-3pof2AJH.js.map → OverlayFade-CuEXgimf.js.map} +1 -1
- package/dist/lib/{Panel-Cy1pdlWO.js → Panel-CtViePqY.js} +2 -2
- package/dist/lib/{Panel-Cy1pdlWO.js.map → Panel-CtViePqY.js.map} +1 -1
- package/dist/lib/{Position-BwtxouxK.js → Position-BIEU1Eze.js} +2 -2
- package/dist/lib/Position-BIEU1Eze.js.map +1 -0
- package/dist/lib/{ProgressSpinner-DK8xEQ9y.js → ProgressSpinner-BuBvC1FY.js} +2 -2
- package/dist/lib/{ProgressSpinner-DK8xEQ9y.js.map → ProgressSpinner-BuBvC1FY.js.map} +1 -1
- package/dist/lib/RadioButton-Df5J-H6m.js +2 -0
- package/dist/lib/RadioButton-Df5J-H6m.js.map +1 -0
- package/dist/lib/RadioMenuRow-Cfv0x6Qj.js +2 -0
- package/dist/lib/RadioMenuRow-Cfv0x6Qj.js.map +1 -0
- package/dist/lib/{RovingTabIndex-pHEv5oLD.js → RovingTabIndex--w28AnXc.js} +2 -2
- package/dist/lib/{RovingTabIndex-pHEv5oLD.js.map → RovingTabIndex--w28AnXc.js.map} +1 -1
- package/dist/lib/Scrollbar-DcnueNJd.js +2 -0
- package/dist/lib/Scrollbar-DcnueNJd.js.map +1 -0
- package/dist/lib/SelectableText-DZNxjKXR.js +2 -0
- package/dist/lib/SelectableText-DZNxjKXR.js.map +1 -0
- package/dist/lib/{Slider-CTbwR6HR.js → Slider-DNfd8Lxz.js} +2 -2
- package/dist/lib/{Slider-CTbwR6HR.js.map → Slider-DNfd8Lxz.js.map} +1 -1
- package/dist/lib/{Spacer-srdN2d2b.js → Spacer-BznfGbwG.js} +2 -2
- package/dist/lib/{Spacer-srdN2d2b.js.map → Spacer-BznfGbwG.js.map} +1 -1
- package/dist/lib/TabButton-CAACsMov.js +2 -0
- package/dist/lib/TabButton-CAACsMov.js.map +1 -0
- package/dist/lib/{TabCloseButton-CY7BGitY.js → TabCloseButton-CCiqsX3y.js} +2 -2
- package/dist/lib/{TabCloseButton-CY7BGitY.js.map → TabCloseButton-CCiqsX3y.js.map} +1 -1
- package/dist/lib/Text-O-FWa5Cy.js +2 -0
- package/dist/lib/Text-O-FWa5Cy.js.map +1 -0
- package/dist/lib/{Tooltip-CUOJOqQi.js → Tooltip-CyICVu15.js} +2 -2
- package/dist/lib/Tooltip-CyICVu15.js.map +1 -0
- package/dist/lib/{Tree-C64JNPWJ.js → Tree-CSEguhlk.js} +2 -2
- package/dist/lib/{Tree-C64JNPWJ.js.map → Tree-CSEguhlk.js.map} +1 -1
- package/dist/lib/{VBox-DfJPWXqc.js → VBox-DVe4UXwX.js} +2 -2
- package/dist/lib/{VBox-DfJPWXqc.js.map → VBox-DVe4UXwX.js.map} +1 -1
- package/dist/lib/{VirtualScroller-DTIn19o1.js → VirtualScroller-ggPTCQb0.js} +2 -2
- package/dist/lib/{VirtualScroller-DTIn19o1.js.map → VirtualScroller-ggPTCQb0.js.map} +1 -1
- package/dist/lib/component/button.es.js +1 -1
- package/dist/lib/component/chart.es.js +1 -1
- package/dist/lib/component/chart.es.js.map +1 -1
- package/dist/lib/component/container.es.js +1 -1
- package/dist/lib/component/diagram.es.js +1 -1
- package/dist/lib/component/display.es.js +1 -1
- package/dist/lib/component/display.es.js.map +1 -1
- package/dist/lib/component/editor.es.js +2 -2
- package/dist/lib/component/editor.es.js.map +1 -1
- package/dist/lib/component/input.es.js +1 -1
- package/dist/lib/component/input.es.js.map +1 -1
- package/dist/lib/component/list.es.js +1 -1
- package/dist/lib/component/menubar.es.js +1 -1
- package/dist/lib/component/table.es.js +6 -6
- package/dist/lib/component/table.es.js.map +1 -1
- package/dist/lib/component/tree.es.js +1 -1
- package/dist/lib/core.es.js +1 -1
- package/dist/lib/core.es.js.map +1 -1
- package/dist/lib/glyphs/solid/index.es.js +1 -1
- package/dist/lib/layout.es.js +1 -1
- package/dist/lib/overlay.es.js +1 -1
- package/dist/lib/overlay.es.js.map +1 -1
- package/dist/lib/primitive.es.js +1 -1
- package/dist/lib/router.es.js +1 -1
- package/dist/lib/{selectionsEqual-gMG7gCVI.js → selectionsEqual-C7MrKMQr.js} +2 -2
- package/dist/lib/{selectionsEqual-gMG7gCVI.js.map → selectionsEqual-C7MrKMQr.js.map} +1 -1
- package/dist/lib/types/component/button/Button.d.ts +9 -0
- package/dist/lib/types/component/button/TabButton.d.ts +5 -0
- package/dist/lib/types/component/button/ToggleButton.d.ts +3 -0
- package/dist/lib/types/component/chart/AbstractChart.d.ts +2 -0
- package/dist/lib/types/component/display/Markdown.d.ts +2 -1
- package/dist/lib/types/component/input/AbstractCalendarDropdown.d.ts +2 -0
- package/dist/lib/types/component/input/AbstractPickerField.d.ts +2 -0
- package/dist/lib/types/component/input/AutoCompleteDropdown.d.ts +2 -0
- package/dist/lib/types/component/input/ComboBox.d.ts +3 -1
- package/dist/lib/types/component/input/Link.d.ts +2 -0
- package/dist/lib/types/component/input/PasswordField.d.ts +2 -0
- package/dist/lib/types/component/input/PickerInput.d.ts +2 -0
- package/dist/lib/types/component/input/SelectableText.d.ts +11 -0
- package/dist/lib/types/component/input/SpinButton.d.ts +2 -0
- package/dist/lib/types/component/input/Text.d.ts +16 -2
- package/dist/lib/types/component/input/TextArea.d.ts +2 -0
- package/dist/lib/types/component/input/TextField.d.ts +2 -0
- package/dist/lib/types/component/input/TextInput.d.ts +2 -0
- package/dist/lib/types/component/input/TimePickerDropdown.d.ts +3 -1
- package/dist/lib/types/component/input/UsernameField.d.ts +2 -0
- package/dist/lib/types/component/input/index.d.ts +2 -0
- package/dist/lib/types/component/list/AbstractSelectableList.d.ts +4 -2
- package/dist/lib/types/component/table/Body.d.ts +40 -14
- package/dist/lib/types/component/table/Header.d.ts +1 -1
- package/dist/lib/types/component/table/Row.d.ts +20 -2
- package/dist/lib/types/component/table/Table.d.ts +2 -0
- package/dist/lib/types/component/table/TableExporter.d.ts +3 -0
- package/dist/lib/types/component/table/TablePanel.d.ts +1 -0
- package/dist/lib/types/component/table/TreeTablePanel.d.ts +1 -0
- package/dist/lib/types/component/table/cell/Cell.d.ts +7 -2
- package/dist/lib/types/component/table/cell/Default.d.ts +1 -1
- package/dist/lib/types/component/table/cell/Header.d.ts +3 -0
- package/dist/lib/types/component/table/cell/ResizeHandle.d.ts +1 -1
- package/dist/lib/types/component/table/cell/renderer/CellRenderer.d.ts +2 -2
- package/dist/lib/types/component/table/cell/renderer/String.d.ts +3 -1
- package/dist/lib/types/component/table/index.d.ts +1 -1
- package/dist/lib/types/core/AnimatedDropdown.d.ts +2 -0
- package/dist/lib/types/core/ClassStyleRules.d.ts +46 -3
- package/dist/lib/types/core/Component.d.ts +30 -2
- package/dist/lib/types/core/DOM.d.ts +5 -1
- package/dist/lib/types/core/LayerManager.d.ts +1 -0
- package/dist/lib/types/core/StyleTarget.d.ts +2 -0
- package/dist/lib/types/core/Theme.d.ts +1 -0
- package/dist/lib/types/core/Util.d.ts +4 -0
- package/dist/lib/types/core/index.d.ts +1 -1
- package/dist/lib/types/layout/Table.d.ts +2 -0
- package/dist/lib/types/overlay/AbstractWindow.d.ts +3 -0
- package/dist/lib/types/overlay/PopupPanel.d.ts +2 -0
- package/dist/lib/validation.es.js +1 -1
- package/package.json +1 -1
- package/dist/lib/AnimatedDropdown-H3Rh-YMZ.js +0 -2
- package/dist/lib/AnimatedDropdown-H3Rh-YMZ.js.map +0 -1
- package/dist/lib/Border-0DJFDiij.js +0 -2
- package/dist/lib/Border-0DJFDiij.js.map +0 -1
- package/dist/lib/Button-MpMIYBYJ.js +0 -2
- package/dist/lib/Button-MpMIYBYJ.js.map +0 -1
- package/dist/lib/Checkbox-D0JYK-wc.js +0 -2
- package/dist/lib/Checkbox-D0JYK-wc.js.map +0 -1
- package/dist/lib/ComboBox-Dx8Tk9yg.js +0 -2
- package/dist/lib/ComboBox-Dx8Tk9yg.js.map +0 -1
- package/dist/lib/Component-B0ShfPVi.js +0 -2
- package/dist/lib/Component-B0ShfPVi.js.map +0 -1
- package/dist/lib/Container-abY5Ww3W.js +0 -2
- package/dist/lib/DOM-C-Edb3tA.js +0 -2
- package/dist/lib/DOM-C-Edb3tA.js.map +0 -1
- package/dist/lib/Dialog-cbA9V17e.js +0 -2
- package/dist/lib/Dialog-cbA9V17e.js.map +0 -1
- package/dist/lib/Glyph-_VeBacS2.js +0 -2
- package/dist/lib/Glyph-_VeBacS2.js.map +0 -1
- package/dist/lib/List-nx8220Fi.js +0 -2
- package/dist/lib/List-nx8220Fi.js.map +0 -1
- package/dist/lib/Position-BwtxouxK.js.map +0 -1
- package/dist/lib/RadioButton-BEwpqg1k.js +0 -2
- package/dist/lib/RadioButton-BEwpqg1k.js.map +0 -1
- package/dist/lib/RadioMenuRow-DP5qPyFR.js +0 -2
- package/dist/lib/RadioMenuRow-DP5qPyFR.js.map +0 -1
- package/dist/lib/Scrollbar-t8fFrUVQ.js +0 -2
- package/dist/lib/Scrollbar-t8fFrUVQ.js.map +0 -1
- package/dist/lib/TabButton-DLoMQzky.js +0 -2
- package/dist/lib/TabButton-DLoMQzky.js.map +0 -1
- package/dist/lib/Text-CMKnK9uB.js +0 -2
- package/dist/lib/Text-CMKnK9uB.js.map +0 -1
- package/dist/lib/Tooltip-CUOJOqQi.js.map +0 -1
- package/dist/lib/types/component/table/CellGeometry.d.ts +0 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Checkbox-CM1z8keM.js","names":[],"sources":["../../src/typescript/lib/component/input/AbstractBooleanInput.ts","../../src/typescript/lib/component/input/Checkbox.ts"],"sourcesContent":["// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { AbstractInput, AbstractInputOptions } from \"~/component/input/AbstractInput.js\";\nimport { Component } from \"~/core/Component.js\";\nimport { Event } from \"~/core/Event.js\";\nimport { Text } from \"~/component/input/Text.js\";\nimport { Util } from \"~/core/Util.js\";\n\n/**\n * Construction-time options shared by the boolean-valued controls\n * ({@link Checkbox}, {@link RadioButton}, {@link Toggle}). Concrete subclasses\n * extend this with their own value / selected / indeterminate fields.\n *\n * @category Components\n */\nexport interface AbstractBooleanInputOptions extends AbstractInputOptions {\n label?: string | null;\n}\n\n/**\n * Abstract base for the three boolean-valued form controls — {@link Checkbox},\n * {@link RadioButton}, {@link Toggle}. Owns the mechanics they share verbatim:\n * the optional inline `_label` {@link Text} (mount / replace / remove), the\n * enabled / read-only ARIA + tabindex + interactive-surface cursor reflection,\n * the label-or-text baseline, and the keyboard-activation wiring routed through\n * the same enabled/read-only guard as pointer activation.\n *\n * Each subclass supplies only what differs: its inner graphic (the interactive\n * surface), the value mutation performed on activation, and — for {@link Toggle}\n * — the activation keys and a pill-centred baseline override. The value\n * semantics (`isSelected` /\n * `setSelected` / `getValue` / `setValue`, indeterminate handling, `ButtonGroup`\n * change firing, synthetic-click behaviour) stay in the subclasses.\n *\n * Not wrapped with `callable()` — abstract classes are never instantiated.\n *\n * @category Components\n */\nabstract class AbstractBooleanInput<\n TOptions extends AbstractBooleanInputOptions = AbstractBooleanInputOptions\n>\n extends AbstractInput<boolean, TOptions>\n{\n // Written by `applyLabel` from the subclass constructor body (after\n // super()), never by a cascade-dispatched setter, so a plain `= null`\n // initializer is safe.\n protected _label: Text | null = null;\n\n /**\n * Returns the label text, or `null` when none was set.\n *\n * @returns The label string, or `null`.\n */\n getLabel(): string | null {\n return this._options.label ?? null;\n }\n\n /**\n * Sets the inline label text. Pass `null` to remove the label entirely.\n *\n * @param text - The label text, or `null` to clear.\n *\n * @returns This component, for method chaining.\n */\n setLabel(text: string | null): this {\n this._options.label = text;\n this.applyLabel(text);\n\n return this;\n }\n\n /**\n * Returns the offset from the top of the control to its inline label's text\n * baseline, or — when there is no label — to the text baseline the graphic\n * would share with a label, so a label-less graphic still sits on a row's\n * baseline.\n *\n * @returns The baseline offset in pixels.\n *\n * @remarks A `null` baseline auto-centres the graphic within the row's\n * text-line height, which floats a small graphic to the row centre once a\n * tall sibling (e.g. a `TextArea`) inflates the row's descent. Returning the\n * text-line baseline keeps the graphic aligned exactly as a labelled\n * control's graphic would be. {@link Toggle} overrides this for its taller\n * pill.\n */\n getBaseline(): number | null {\n if (this._label === null) {\n return this.wrapInnerBaseline(Util.measureTextBaseline());\n }\n\n return this.wrapInnerBaseline(this._label.getBaseline());\n }\n\n /**\n * Mounts, replaces, or removes the inline label.\n *\n * @param text - The label text, or `null` to remove the label.\n */\n protected applyLabel(text: string | null): void {\n if (text === null) {\n if (this._label !== null) {\n super.removeComponent(this._label);\n this._label = null;\n }\n\n return;\n }\n\n if (this._label === null) {\n this._label = new Text(text);\n this._label.setPointerEvents(\"none\");\n super.addComponent(this._label);\n } else {\n this._label.setText(text);\n }\n }\n\n /**\n * Reflects the enabled flag in the ARIA tree, the tabindex, and the\n * interactive surface's cursor.\n *\n * @param value - The new enabled state.\n */\n protected applyEnabled(value: boolean): void {\n this.getAria().setDisabled(!value);\n this.getAria().setTabIndex(value ? 0 : -1);\n this.getInteractiveSurface().setCursor(value ? \"pointer\" : \"default\");\n }\n\n /**\n * Reflects the read-only flag in the ARIA tree.\n *\n * @param value - The new read-only state.\n */\n protected applyReadOnly(value: boolean): void {\n this.getAria().setReadOnly(value);\n }\n\n /**\n * Keydown handler: activates the control when the pressed key is one of\n * {@link activationKeys} and the control is enabled and not read-only.\n *\n * @param e - The keyboard event.\n */\n private handleActivationKey(e: KeyboardEvent): Event.ListenerResult {\n if (!this.activationKeys().includes(e.key)) {\n return;\n }\n\n if (this.isEnabled() && !this.isReadOnly()) {\n this.activate();\n }\n\n return { prevent: true };\n }\n\n /**\n * Wires the keyboard-activation listener on the focused root. Called from\n * each subclass constructor after its graphic is built.\n */\n protected installKeyboard(): void {\n Event.addListener(this, \"keydown\", this.handleActivationKey);\n }\n\n /**\n * Activates the control from a pointer click, subject to the same\n * enabled/read-only guard as the keyboard path. Wired by each subclass\n * onto its interactive surface (so the hit area is exactly the visible\n * graphic).\n */\n protected activateFromPointer(): void {\n if (this.isEnabled() && !this.isReadOnly()) {\n this.activate();\n }\n }\n\n /**\n * Keys that activate the control. Defaults to Space; {@link Toggle} widens\n * it to Space and Enter.\n *\n * @returns The activation key strings.\n */\n protected activationKeys(): string[] {\n return [\" \"];\n }\n\n /**\n * Subclass hook: perform the value mutation for an activation (click or\n * key). Called only after the enabled/read-only guard has passed.\n */\n protected abstract activate(): void;\n\n /**\n * Subclass hook: the inner graphic that owns the click + cursor surface\n * ({@link Checkbox}'s box, {@link RadioButton}'s ring, {@link Toggle}'s\n * track).\n *\n * @returns The interactive surface component.\n */\n protected abstract getInteractiveSurface(): Component;\n}\n\nexport { AbstractBooleanInput };\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Animation } from \"~/core/Animation.js\";\nimport { AbstractBooleanInput, AbstractBooleanInputOptions } from \"~/component/input/AbstractBooleanInput.js\";\nimport { Component, ComponentOptions } from \"~/core/Component.js\";\nimport { DOM, type Handle } from \"~/core/DOM.js\";\nimport { Event } from \"~/core/Event.js\";\nimport { Glyph, GlyphOptions } from \"~/component/display/Glyph.js\";\nimport { HBox } from \"~/layout/HBox.js\";\nimport { type StateStyleRule } from \"~/core/ClassStyleRules.js\";\nimport { borderToStyle } from \"~/primitive/Border.js\";\nimport { callable } from \"~/core/Callable.js\";\nimport { check } from \"~/glyphs/solid/check.js\";\n\n// Idempotent registration: the registry tolerates re-registration of the same\n// glyph definition, and this side-effect import lets Checkbox stand on its own\n// without an outside-the-class `Glyph.register` call.\nGlyph.register(check);\n\nconst _defaultCheckboxBoxOptions: Partial<ComponentOptions> = {\n preferredSize: { width: 16, height: 16 },\n minSize: { width: 16, height: 16 },\n maxSize: { width: 16, height: 16 },\n cursor: \"pointer\",\n backgroundColor: \"var(--ts-ui-checkbox-bg, var(--ts-ui-form-bg, rgb(255, 255, 255)))\",\n border: \"1px solid var(--ts-ui-form-border, rgb(160, 160, 160))\",\n borderRadius: \"var(--ts-ui-checkbox-radius, 3px)\",\n};\n\n/** `_box`'s checked-state declarations. Read by both `getSelectedClassDeclarations` and `applyState` — one source of truth, mirroring `ToggleButton`'s `TOGGLE_SELECTED_DECLARATIONS`. */\nconst CHECKBOX_SELECTED_DECLARATIONS: Readonly<Record<string, string>> = Object.freeze({\n backgroundColor: \"var(--ts-ui-checkbox-bg-selected, rgb(30, 100, 200))\",\n border: \"1px solid var(--ts-ui-checkbox-bg-selected, rgb(30, 100, 200))\",\n});\n\n/** `_box`'s indeterminate-state declarations. Same shape as `CHECKBOX_SELECTED_DECLARATIONS`. */\nconst CHECKBOX_INDETERMINATE_DECLARATIONS: Readonly<Record<string, string>> = Object.freeze({\n backgroundColor: \"var(--ts-ui-checkbox-bg-indeterminate, rgb(160, 160, 160))\",\n border: \"1px solid var(--ts-ui-checkbox-bg-indeterminate, rgb(160, 160, 160))\",\n});\n\n/**\n * The box graphic behind a {@link Checkbox} — the click + cursor surface.\n * Module-private: constructed only from `Checkbox`'s own constructor. Static\n * geometry, cursor, and border-radius are class defaults so every instance\n * shares one `.CheckboxBox` CSS rule instead of repeating them; the resting\n * backgroundColor/border are class defaults too, and the checked/indeterminate\n * background and border write through `createStateStyleRule`-backed state\n * rules — see `plans/implemented/checkbox-radio-delegate-state-style-defaults.md`.\n */\nclass CheckboxBox extends Component {\n private _selected: boolean = false;\n private _indeterminate: boolean = false;\n\n private declare _selectedStyleRule?: StateStyleRule;\n private get selectedStyleRule(): StateStyleRule {\n return this._selectedStyleRule ??= this.createStateStyleRule(\".selected\", () => this.getSelectedClassDeclarations());\n }\n\n private declare _indeterminateStyleRule?: StateStyleRule;\n private get indeterminateStyleRule(): StateStyleRule {\n return this._indeterminateStyleRule ??= this.createStateStyleRule(\".indeterminate\", () => this.getIndeterminateClassDeclarations());\n }\n\n constructor() {\n super(undefined, _defaultCheckboxBoxOptions);\n }\n\n protected getSelectedClassDeclarations(): Record<string, string | null> {\n return {\n backgroundColor: CHECKBOX_SELECTED_DECLARATIONS.backgroundColor,\n ...borderToStyle({ border: CHECKBOX_SELECTED_DECLARATIONS.border }),\n };\n }\n\n protected getIndeterminateClassDeclarations(): Record<string, string | null> {\n return {\n backgroundColor: CHECKBOX_INDETERMINATE_DECLARATIONS.backgroundColor,\n ...borderToStyle({ border: CHECKBOX_INDETERMINATE_DECLARATIONS.border }),\n };\n }\n\n /**\n * `_box`'s own resting chrome must stay isolated from both non-resting\n * states — see `plans/implemented/checkbox-radio-delegate-state-style-defaults.md`.\n */\n protected override getRestingExclusionSuffixes(): readonly string[] {\n return [\".selected\", \".indeterminate\"];\n }\n\n /**\n * Applies the checked/indeterminate visual state: toggles the CSS state\n * classes and, for a non-resting state, writes background + border\n * through the matching state-tier rule. The resting branch writes\n * nothing — `_box`'s base rule is never touched after construction (its\n * `backgroundColor`/`border` come from `_defaultCheckboxBoxOptions`\n * alone), so there is nothing to restore when a non-resting class is\n * removed; see this plan's Architecture Decisions.\n *\n * `selected` and `indeterminate` are not mutually exclusive as *passed\n * in* — `Checkbox.setIndeterminate` deliberately leaves `selected`\n * untouched, so a checkbox that is selected when it becomes indeterminate\n * reaches this method with both `true`. The `.selected` class is only\n * ever toggled on when `!indeterminate`, so the resting-isolation\n * selector's `:not(.selected):not(.indeterminate)` premise (the two CSS\n * classes themselves are mutually exclusive) holds regardless, and the\n * DOM matches the same indeterminate-wins priority the branch below\n * already applies to the style write.\n */\n applyState(selected: boolean, indeterminate: boolean): void {\n this._selected = selected;\n this._indeterminate = indeterminate;\n\n const element = this.getElement();\n if (element) {\n DOM.sink.apply(element, { toggleClass: { selected: selected && !indeterminate, indeterminate } });\n }\n\n if (indeterminate) {\n this.indeterminateStyleRule.setMany({\n backgroundColor: CHECKBOX_INDETERMINATE_DECLARATIONS.backgroundColor,\n ...borderToStyle({ border: CHECKBOX_INDETERMINATE_DECLARATIONS.border }),\n });\n } else if (selected) {\n this.selectedStyleRule.setMany({\n backgroundColor: CHECKBOX_SELECTED_DECLARATIONS.backgroundColor,\n ...borderToStyle({ border: CHECKBOX_SELECTED_DECLARATIONS.border }),\n });\n }\n }\n\n /** Re-applies the cached state classes at render, for a state set before mount. */\n protected render(): Handle {\n const element = super.render();\n DOM.sink.apply(element, { toggleClass: { selected: this._selected && !this._indeterminate, indeterminate: this._indeterminate } });\n return element;\n }\n}\n\n// The check glyph's fitted size inside the box (14×14 padding box, 1px\n// border): shared with Checkbox's own constructor below so the class\n// default and the imperative override can never drift apart.\nconst CHECKBOX_CHECK_SIZE = { width: 12, height: 12 };\n\nconst _defaultCheckboxCheckGlyphOptions: Partial<GlyphOptions> = {\n foregroundColor: \"var(--ts-ui-checkbox-check-color, rgb(255, 255, 255))\",\n minSize: CHECKBOX_CHECK_SIZE,\n maxSize: CHECKBOX_CHECK_SIZE,\n};\n\n/**\n * The check-mark glyph inside a {@link Checkbox}'s box. `foregroundColor`\n * and `minSize`/`maxSize` are class defaults, so every instance shares one\n * `.CheckboxCheckGlyph` CSS rule instead of repeating them. `Checkbox`'s own\n * constructor still calls `setPreferredSize`/`setMaxSize` imperatively (a\n * `Glyph`'s construction-time size pin cannot itself be deferred to a\n * defaults bag — see `Glyph.applyOptions`), but that call now resolves to\n * the same value this class already defaults, so `Component.applyStyle`'s\n * render-time reconciliation (`reconcileRuleDeclaration`, since\n * `plans/implemented/reconciled-write-path-widening.md`) turns it into a\n * removal instead of a redundant per-instance declaration. Opacity (which of\n * unchecked/checked/indeterminate is showing) stays a per-instance runtime\n * write in `Checkbox.applySelected` — it is not a class constant.\n */\nclass CheckboxCheckGlyph extends Glyph {\n constructor() {\n super(\"check\", undefined, _defaultCheckboxCheckGlyphOptions);\n }\n}\n\nconst _defaultCheckboxDashOptions: Partial<ComponentOptions> = {\n backgroundColor: \"var(--ts-ui-checkbox-check-color, rgb(255, 255, 255))\",\n preferredSize: { width: 8, height: 2 },\n maxSize: { width: 8, height: 2 },\n};\n\n/** The indeterminate-state bar inside a {@link Checkbox}'s box. */\nclass CheckboxDash extends Component {\n constructor() {\n super(undefined, _defaultCheckboxDashOptions);\n }\n}\n\n/**\n * Construction-time options for {@link Checkbox}.\n *\n * @category Components\n */\nexport interface CheckboxOptions extends AbstractBooleanInputOptions {\n selected?: boolean;\n value?: boolean;\n indeterminate?: boolean;\n /**\n * Construction-time listener bag — the declarative form of `on()`. Adds the\n * checkbox's `action` shorthand to the inherited `change` / `binding`.\n */\n listeners?: {\n action?: () => void;\n change?: (value: boolean) => void;\n binding?: () => void;\n };\n}\n\nconst _defaultCheckboxOptions: Partial<CheckboxOptions> = {\n outline: \"none\",\n};\n\n/**\n * A custom-drawn checkbox rendered as a focusable `<div>` with `role=\"checkbox\"`.\n *\n * The control owns a small `<div>` box that hosts a check {@link Glyph}; when\n * `indeterminate` is set, a horizontal bar replaces the check. The native\n * `<input type=\"checkbox\">` is intentionally not used so the visual is fully\n * themable through the shared `--ts-ui-form-*` and per-control checkbox tokens.\n *\n * @category Components\n */\nclass Checkbox<TOptions extends CheckboxOptions = CheckboxOptions>\n extends AbstractBooleanInput<TOptions>\n{\n private _box: CheckboxBox;\n private _check: Glyph;\n private _dash: Component;\n\n /**\n * Constructs a Checkbox.\n *\n * @param options - Optional construction-time options.\n * @param subclassDefaults - Per-subclass default bag layered over this\n * class's defaults; subclasses forward their `_defaultXxxOptions`\n * constant here.\n */\n constructor(options?: CheckboxOptions, subclassDefaults?: Partial<CheckboxOptions>);\n constructor(options?: TOptions, subclassDefaults?: Partial<TOptions>) {\n super(\n { ...(options ?? {}) } as TOptions,\n { ..._defaultCheckboxOptions, ...(subclassDefaults ?? {}) } as Partial<TOptions>,\n );\n\n this.setLayoutManager(new HBox());\n\n this._box = new CheckboxBox();\n // Min = preferred = max so the outer HBox shrink-on-overallocation\n // can't collapse the box graphic when the checkbox sits next to\n // flexible siblings.\n this._box.setSize({ width: 16, height: 16 });\n\n this._check = new CheckboxCheckGlyph();\n this._check.setPreferredSize(CHECKBOX_CHECK_SIZE);\n this._check.setMaxSize(CHECKBOX_CHECK_SIZE);\n // With box-sizing: border-box and the 1px box border, absolute children\n // are positioned relative to the 14×14 padding edge — so centering a\n // 12×12 glyph inside the 16×16 visible box means (14−12)/2 = 1, not 2.\n this._check.setX(1);\n this._check.setY(1);\n this._check.setOpacity(0);\n // Pass-through so clicks on the glyph still hit the box underneath.\n this._check.setPointerEvents(\"none\");\n\n this._dash = new CheckboxDash();\n this._dash.setSize({ width: 8, height: 2 });\n this._dash.setX(3);\n this._dash.setY(6);\n this._dash.setOpacity(0);\n this._dash.setPointerEvents(\"none\");\n\n if (!Animation.isReducedMotion()) {\n this._check.setTransition(\"opacity 120ms ease-out\");\n this._dash.setTransition(\"opacity 120ms ease-out\");\n this._box.setTransition(\"background-color 120ms ease-out, border-color 120ms ease-out\");\n }\n\n this._box.addComponent(this._check);\n this._box.addComponent(this._dash);\n super.addComponent(this._box);\n\n this.getAria().setRole(\"checkbox\");\n this.getAria().setTabIndex(0);\n this.getAria().setChecked(false);\n\n // The box owns the user-toggle click so the pointer/click + cursor\n // surface is exactly the visible 16 × 16 graphic — clicks on a label or\n // in any stretched empty area pass through to the root, which has no\n // listener of its own. This pointer line stays per-subclass (a closure\n // over the widget `this`) because a listener registered on the child\n // box would otherwise bind `this` to the box; only the keyboard path,\n // registered on the root, moves into the base.\n Event.addListener(this._box, \"click\", () => this.activateFromPointer());\n this.installKeyboard();\n\n if (this._options.value !== undefined && this._options.selected === undefined) {\n this._options.selected = this._options.value;\n }\n\n if (this._options.selected !== undefined) {\n this.applySelected(this._options.selected, this._options.indeterminate ?? false);\n }\n\n if (this._options.indeterminate !== undefined) {\n this.applySelected(this._options.selected ?? false, this._options.indeterminate);\n }\n\n if (this._options.label !== undefined) {\n this.applyLabel(this._options.label);\n }\n\n if (this._options.enabled !== undefined) {\n this.applyEnabled(this._options.enabled);\n }\n\n if (this._options.readOnly !== undefined) {\n this.applyReadOnly(this._options.readOnly);\n }\n }\n\n /**\n * Applies a {@link CheckboxOptions} bag. Inherited Component fields cascade\n * through `super.applyOptions`; checkbox-specific fields are stored pure on\n * `_options` so the constructor body can dispatch them after children are\n * built.\n *\n * @param options - The options bag carrying the values to apply.\n *\n * @returns This component, for method chaining.\n */\n protected applyOptions(options: TOptions): this {\n super.applyOptions(options);\n\n if (options.selected !== undefined) this._options.selected = options.selected;\n if (options.value !== undefined) this._options.value = options.value;\n if (options.indeterminate !== undefined) this._options.indeterminate = options.indeterminate;\n if (options.label !== undefined) this._options.label = options.label;\n if (options.enabled !== undefined) this._options.enabled = options.enabled;\n if (options.readOnly !== undefined) this._options.readOnly = options.readOnly;\n\n return this;\n }\n\n /**\n * Activates the checkbox from a click or key: a user activation from the\n * \"mixed\" state first clears the indeterminate flag and selects (WAI-ARIA);\n * otherwise it flips the selected state. `setSelected` handles the visual +\n * listener sync — calling it from a mixed state always lands at\n * `selected=true` because its guard treats indeterminate as a force-out.\n * The enabled/read-only guard is applied by the base before this runs.\n */\n protected activate(): void {\n if (this.isIndeterminate()) {\n this.setSelected(true);\n\n return;\n }\n\n this.setSelected(!this.isSelected());\n }\n\n /**\n * Returns the inner box graphic — the click + cursor surface.\n *\n * @returns The box component.\n */\n protected getInteractiveSurface(): Component {\n return this._box;\n }\n\n /**\n * Returns whether the checkbox is currently selected.\n *\n * @returns `true` when checked.\n */\n isSelected(): boolean {\n return this._options.selected ?? false;\n }\n\n /**\n * Sets the checked state. Notifies change and binding listeners on a real\n * transition; no-op when unchanged.\n *\n * @param value - `true` to check, `false` to uncheck.\n *\n * @returns This component, for method chaining.\n */\n setSelected(value: boolean): this {\n const next = !!value;\n if (next === this.isSelected() && !this.isIndeterminate()) {\n return this;\n }\n\n this._options.selected = next;\n this._options.indeterminate = false;\n this.applySelected(next, false);\n this.notifyChange(next);\n\n // Existing consumers wire \"click\"-based behaviour through `on(\"action\", fn)`,\n // so synthesize a \"click\" on the root so a programmatic state flip\n // continues to fire it. The user-toggle handler lives on `_box`, not\n // the root, so this synthetic event no longer races back into the\n // toggle path. Skip the synthetic click pre-mount — listeners haven't\n // attached yet and `fireEvent` would throw on the missing element.\n if (this.getElement()) {\n Event.fireEvent(this, \"click\");\n } else {\n console.warn(\"Checkbox '\" + this.getId() + \"' setSelected before mount; synthetic 'click' skipped.\");\n }\n\n return this;\n }\n\n /**\n * Returns the current value (alias for {@link isSelected}, satisfies\n * [`Bindable`](/api/core/interfaces/Bindable)).\n *\n * @returns `true` when checked.\n */\n getValue(): boolean {\n return this.isSelected();\n }\n\n /**\n * Sets the value (alias for {@link setSelected}, satisfies [`Bindable`](/api/core/interfaces/Bindable)).\n *\n * @param value - The new boolean state.\n *\n * @returns This component, for method chaining.\n */\n setValue(value: boolean): this {\n return this.setSelected(value);\n }\n\n /**\n * Returns whether the checkbox is in the mixed (`indeterminate`) state.\n *\n * @returns `true` when indeterminate.\n */\n isIndeterminate(): boolean {\n return this._options.indeterminate ?? false;\n }\n\n /**\n * Toggles the mixed (`indeterminate`) state. Setting `true` overrides the\n * visible check with a horizontal bar and announces `aria-checked=\"mixed\"`.\n *\n * @param value - `true` to enter the mixed state, `false` to leave it.\n *\n * @returns This component, for method chaining.\n */\n setIndeterminate(value: boolean): this {\n const next = !!value;\n if (next === this.isIndeterminate()) {\n return this;\n }\n\n this._options.indeterminate = next;\n this.applySelected(this.isSelected(), next);\n\n return this;\n }\n\n /**\n * Enables or disables the 120 ms check/fill CSS transition. Disabled\n * checkboxes still update their visual state instantly. Used by\n * `BooleanCell` to suppress the per-rebind transition flash when a\n * virtualized table re-binds many cells per scroll frame.\n *\n * @param value - `true` to keep the transition (default), `false` to remove it.\n */\n setAnimated(value: boolean): this {\n const t = value && !Animation.isReducedMotion();\n\n this._check.setTransition(t ? \"opacity 120ms ease-out\" : \"none\");\n this._dash .setTransition(t ? \"opacity 120ms ease-out\" : \"none\");\n this._box .setTransition(t ? \"background-color 120ms ease-out, border-color 120ms ease-out\" : \"none\");\n\n return this;\n }\n\n /**\n * Registers a listener for one of this checkbox's events. `\"action\"` is a\n * typed semantic shorthand over {@link Event.addListener} for the native\n * click (used e.g. by the [`BooleanEditor`](/api/component/table/cell/editor/classes/BooleanEditor)\n * cell editor); `\"change\"` and `\"binding\"` are the inherited\n * {@link AbstractInput} listener-bag events.\n *\n * @param event - The event name.\n * @param listener - Callback invoked when the event fires.\n *\n * @returns This component, for method chaining.\n */\n on(event: \"action\", listener: Event.Listener): this;\n on(event: \"change\", listener: (value: boolean) => void): this;\n on(event: \"binding\", listener: () => void): this;\n on(event: \"action\" | \"change\" | \"binding\", listener: Function): this {\n if (event === \"action\") {\n Event.addListener(this, \"click\", listener as Event.Listener);\n\n return this;\n }\n\n return super.on(event as \"change\", listener as (value: boolean) => void);\n }\n\n /**\n * Removes a previously registered listener. The exact callback\n * reference must match the one passed to {@link on}.\n *\n * @param event - The event the listener was registered for.\n * @param listener - The callback to remove.\n *\n * @returns This component, for method chaining.\n */\n off(event: \"action\" | \"change\" | \"binding\", listener: Function): this {\n if (event === \"action\") {\n Event.removeListener(this, \"click\", listener as Event.Listener);\n\n return this;\n }\n\n return super.off(event, listener);\n }\n\n /**\n * Updates the visual + ARIA state for a (selected, indeterminate) pair.\n */\n private applySelected(selected: boolean, indeterminate: boolean): void {\n if (indeterminate) {\n this.getAria().setChecked(\"mixed\");\n } else {\n this.getAria().setChecked(selected);\n }\n\n this._box.applyState(selected, indeterminate);\n\n this._check.setOpacity(selected && !indeterminate ? 1 : 0);\n this._dash.setOpacity(indeterminate ? 1 : 0);\n }\n\n}\n\nconst CheckboxCallable = callable(Checkbox);\ntype CheckboxCallable<TOptions extends CheckboxOptions = CheckboxOptions> = Checkbox<TOptions>;\nexport {\n Checkbox as _Checkbox,\n CheckboxCallable as Checkbox\n};\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./DOM-
|
|
2
|
-
//# sourceMappingURL=CheckboxMenuRow-
|
|
1
|
+
import{t as e}from"./DOM-Cjh7_7TF.js";import{t}from"./Position-BIEU1Eze.js";import{S as n,_ as r,h as i,t as a}from"./Component-D99-15Zt.js";import{a as o}from"./Tooltip-CyICVu15.js";import{t as s}from"./Text-O-FWa5Cy.js";import{t as c}from"./Checkbox-CM1z8keM.js";import{i as l,r as u}from"./Menu-CwHluLGT.js";var d=new WeakSet;function swallowUnconsumedWheel(e){if(r(e))return{prevent:!0}}function trapWheel(e){d.has(e)||(d.add(e),n.addSubtreeListener(e,`wheel`,{passive:!1,handler:swallowUnconsumedWheel}))}function untrapWheel(e){d.has(e)&&(d.delete(e),n.removeSubtreeListener(e,`wheel`,swallowUnconsumedWheel))}var f=o.Band.Window-1,DragFeedback=class extends a{_valid=!0;constructor(){super(),this.setPosition(t.ABSOLUTE),this.setZIndex(f),this.setPointerEvents(`none`),this.applyTintForValidity()}isValid(){return this._valid}setValid(e){this._valid!==e&&(this._valid=e,this.applyTintForValidity())}attachTo(t,n){let r=this.getElement(!0);if(n&&n!==t){this.setX(t.getX()),this.setY(t.getY()),this.setWidth(t.getWidth()),this.setHeight(t.getHeight());let i=n.getElement(!0);e.source.getParentElement(r)!==i&&e.sink.appendChild(i,r);return}this.setX(0),this.setY(0),this.setWidth(t.getWidth()),this.setHeight(t.getHeight());let i=t.getElement(!0);e.source.getParentElement(r)!==i&&e.sink.appendChild(i,r)}detach(){this.removeElement()}applyTintForValidity(){let e=this._valid?`valid`:`invalid`;this.setBackgroundColor(`var(--ts-ui-drag-feedback-${e}-bg)`),this.setBorder({border:`2px solid var(--ts-ui-drag-feedback-${e}-border)`})}},p=i(DragFeedback),m=10200,h=160,g=28,_=6,DragGhost=class extends a{_label=null;constructor(e,n,r){super(),this.setPosition(t.FIXED),this.setZIndex(m),this.setPointerEvents(`none`),this.setWidth(n??h),this.setHeight(r??g),this.setBackgroundColor(`var(--ts-ui-drag-ghost-bg)`),this.setBorder({border:`1px solid var(--ts-ui-drag-ghost-border)`}),this.setShadow(`var(--ts-ui-drag-ghost-shadow)`),this.setBorderRadius(`var(--ts-ui-border-radius, 4px)`),this.setOpacity(.85),e!==void 0&&(this._label=new s(e),this._label.setPointerEvents(`none`),this.addComponent(this._label))}moveTo(e,t){this.setX(e),this.setY(t)}show(){let t=this.getElement(!0);this.scheduleLayout(),e.sink.appendChild(e.source.getDocumentElement(),t)}hide(){this.removeElement()}doLayout(){super.doLayout();let e=this.getContentBounds();return this._label&&e&&(this._label.setX(e.x+_),this._label.setY(e.y+_),this._label.setWidth(e.width-12),this._label.setHeight(e.height-12)),this}},v=i(DragGhost),y=o.Band.Window-1,b=2,x=1,ReorderIndicator=class extends a{constructor(){super(),this.setPosition(t.ABSOLUTE),this.setZIndex(y),this.setPointerEvents(`none`),this.setHeight(b),this.setBackgroundColor(`var(--ts-ui-drag-reorder-color)`)}setInsertionY(e){this.setY(e-x)}attachTo(t){let n=t.getElement(!0),r=this.getElement(!0);this.setX(0),this.setWidth(t.getWidth()),e.source.getParentElement(r)!==n&&e.sink.appendChild(n,r)}detach(){this.removeElement()}},S=i(ReorderIndicator),C=new Map,w=1e3,T=12,E=12,D=new Map,O=new Map,k=null,A;(function(e){function makeDragSource(e,t){return D.set(e.getId(),{component:e,options:t}),e.addMouseDownSubtreeListener(onSourceMouseDown),tearDownDragSource.bind(null,e)}e.makeDragSource=makeDragSource;function makeDropTarget(e,t){return O.set(e.getId(),{component:e,options:t}),tearDownDropTarget.bind(null,e)}e.makeDropTarget=makeDropTarget;function isDragging(){return k!==null&&k.committed}e.isDragging=isDragging;function cancel(){k!==null&&endSession(!1,0,0)}e.cancel=cancel})(A||={});function resolveDragData(e){return typeof e.dragData==`function`?e.dragData():e.dragData}function tearDownDragSource(e){e.removeMouseDownSubtreeListener(onSourceMouseDown),D.delete(e.getId())}function tearDownDropTarget(e){O.delete(e.getId())}function onSourceMouseDown(t){if(k!==null||t.button!==0)return;let r=D.get(this.getId());if(!r)return;let i=r.component,a=r.options;k={source:i,sourceOptions:a,dragData:resolveDragData(a),startX:t.clientX,startY:t.clientY,committed:!1,ghost:null,feedback:null,indicator:null,currentTarget:null,previousBodyCursor:e.source.getInlineStyle(e.source.getBody(),`cursor`)},n.addViewportListener(i,`mousemove`,onMouseMove),n.addViewportListener(i,`mouseup`,onMouseUp),n.addViewportListener(i,`selectstart`,onSelectStart)}function commitSession(t){t.committed=!0;let n=t.sourceOptions.ghostFactory?t.sourceOptions.ghostFactory(t.source,t.dragData):new v;if(t.ghost=n,t.feedback=new p,t.indicator=new S,typeof n.show==`function`)n.show();else{let t=n.getElement(!0);e.sink.appendChild(e.source.getDocumentElement(),t)}t.sourceOptions.cursor&&e.sink.apply(e.source.getBody(),{style:{cursor:t.sourceOptions.cursor}})}function buildDetail(e,t,n){return{dragData:e.dragData,sourceId:e.source.getId(),clientX:t,clientY:n}}function pickDropTarget(t,n){let r=e.source.elementsFromPoint(t,n);for(let t of r){let n=O.get(e.source.getId(t));if(n)return n}return null}function leaveCurrentTarget(e,t){if(e.currentTarget===null)return;let n=O.get(e.currentTarget.getId());n&&n.options.onDragLeave&&n.options.onDragLeave(t),e.feedback&&e.feedback.detach(),e.indicator&&e.indicator.detach(),e.currentTarget=null}function enterNewTarget(e,t,n){let r=t.options.accepts(n);if(e.feedback&&!t.options.suppressValidityTint&&(e.feedback.setValid(r),e.feedback.attachTo(t.component,t.options.feedbackHost)),!r){e.currentTarget=t.component;return}let i=t.options.onDragOver?.(n);typeof i==`number`&&e.indicator?(e.indicator.attachTo(t.component),e.indicator.setInsertionY(i)):e.indicator&&e.indicator.detach(),e.currentTarget=t.component}function onSelectStart(){return{stop:!0,prevent:!0}}function onMouseMove(e){if(k===null)return;let t=k;if(!t.committed){let r=e.clientX-t.startX,i=e.clientY-t.startY;if(r*r+i*i<16)return{stop:!0,prevent:!0};let a=buildDetail(t,e.clientX,e.clientY);if(t.sourceOptions.onDragStart?.(a)===!1)return endSession(!1,e.clientX,e.clientY),{stop:!0,prevent:!0};commitSession(t),n.fireEvent(t.source,`dragstart`,{detail:a})}if(t.ghost){let n=t.ghost;typeof n.moveTo==`function`?n.moveTo(e.clientX+T,e.clientY+E):(t.ghost.setX(e.clientX+T),t.ghost.setY(e.clientY+E))}let r=buildDetail(t,e.clientX,e.clientY),i=pickDropTarget(e.clientX,e.clientY);if(i===null)return leaveCurrentTarget(t,r),{stop:!0,prevent:!0};if(t.currentTarget!==i.component)return leaveCurrentTarget(t,r),enterNewTarget(t,i,r),{stop:!0,prevent:!0};let a=i.options.accepts(r);if(t.feedback&&!i.options.suppressValidityTint&&t.feedback.setValid(a),!a)return t.indicator&&t.indicator.detach(),{stop:!0,prevent:!0};let o=i.options.onDragOver?.(r);return typeof o==`number`&&t.indicator?(t.indicator.attachTo(i.component),t.indicator.setInsertionY(o)):t.indicator&&t.indicator.detach(),{stop:!0,prevent:!0}}function onMouseUp(e){if(k===null)return;let t=k,r=buildDetail(t,e.clientX,e.clientY),i=!1;if(t.committed&&t.currentTarget!==null){let e=O.get(t.currentTarget.getId());e&&(e.options.accepts(r)&&e.options.onDrop?.(r)!==!1&&n.fireEvent(t.source,`drop`,{detail:r}),i=!0)}return endSession(i,e.clientX,e.clientY),!0}function endSession(t,r,i){if(k===null)return;let a=k;if(n.removeViewportListener(a.source,`mousemove`,onMouseMove),n.removeViewportListener(a.source,`mouseup`,onMouseUp),n.removeViewportListener(a.source,`selectstart`,onSelectStart),a.feedback&&a.feedback.dispose(),a.indicator&&a.indicator.dispose(),a.ghost){if(a.sourceOptions.ghostFactory){let e=a.ghost;typeof e.hide==`function`?e.hide():a.ghost.removeElement()}else a.ghost.dispose()}if(a.sourceOptions.cursor&&e.sink.apply(e.source.getBody(),{style:{cursor:a.previousBodyCursor}}),a.committed){let e=buildDetail(a,r,i);n.fireEvent(a.source,`dragend`,{detail:e}),a.sourceOptions.onDragEnd?.(e,t)}k=null}var j=.5,CheckboxMenuRow=class extends l{_checkbox;_iconStart=null;_checkZone=null;_onMouseOver;_onMouseOut;_onClick;constructor(e,t){super(e,t),this._checkbox=new c({label:e?.text??``,selected:e?.checked??!1,enabled:e?.enabled??!0}),this._checkbox.setPointerEvents(`none`),this.addComponent(this._checkbox),e?.enabled===!1&&(this.setPointerEvents(`none`),this.setOpacity(j)),this._onMouseOver=()=>{this.setFocused(!0)},this._onMouseOut=()=>{this.setFocused(!1)},this._onClick=()=>{this.activate()},n.addListener(this,`mouseover`,this._onMouseOver),n.addListener(this,`mouseout`,this._onMouseOut),n.addListener(this,`click`,this._onClick),this.applyListeners(e?.listeners)}isChecked(){return this._checkbox.isSelected()}setChecked(e){return this._checkbox.setSelected(e),this}isNavigable(){return!0}isEnabled(){return this._checkbox.isEnabled()}activate(){this.isEnabled()&&this.setChecked(!this.isChecked())}getContentWidth(){return Math.ceil(this._checkbox.getPreferredSize()?.width??0)+u.RIGHT_PAD}setColumns(e,t,n){this._checkZone=e,this._iconStart=t,this.scheduleLayout()}doLayout(){super.doLayout();let e=this.getContentBounds();if(!e)return this;let t=this._checkbox.getPreferredSize()??{width:0,height:0},n=this._checkZone??0,r=this._iconStart!==null&&this._iconStart-n===u.ICON_ZONE?n+4:this._iconStart??u.TEXT_INSET,i=Math.max(0,Math.floor((e.height-t.height)/2));return this._checkbox.setX(e.x+r),this._checkbox.setY(e.y+i),this._checkbox.setWidth(Math.max(0,e.width-r-u.RIGHT_PAD)),this._checkbox.setHeight(t.height),this}on(e,t){return n.addListener(this,`click`,t),this}off(e,t){return n.removeListener(this,`click`,t),this}},M=i(CheckboxMenuRow);export{S as a,trapWheel as c,C as i,untrapWheel as l,A as n,v as o,w as r,p as s,M as t};
|
|
2
|
+
//# sourceMappingURL=CheckboxMenuRow-C1h4LPHR.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckboxMenuRow-CesLhSnp.js","names":[],"sources":["../../src/typescript/lib/core/WheelTrap.ts","../../src/typescript/lib/overlay/DragFeedback.ts","../../src/typescript/lib/overlay/DragGhost.ts","../../src/typescript/lib/overlay/ReorderIndicator.ts","../../src/typescript/lib/overlay/DragManager.ts","../../src/typescript/lib/component/container/CheckboxMenuRow.ts"],"sourcesContent":["// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport type { Component } from \"~/core/Component.js\";\nimport { Event } from \"~/core/Event.js\";\nimport { consumeWheel } from \"~/core/SmoothScroller.js\";\n\n/**\n * Components that currently have the wheel trap installed. Used purely for\n * idempotency — the listener itself ({@link swallowUnconsumedWheel}) captures\n * nothing per component, so one shared reference serves every overlay. Keyed\n * weakly, mirroring how the layer registry keys per-layer state, so a closed\n * overlay's entry is collectable without an explicit purge.\n */\nconst _trapped = new WeakSet<Component>();\n\n/**\n * Subtree `wheel` handler shared by every trapped overlay: claims the event via\n * the framework's wheel once-marker and, when the claim succeeds (no inner\n * scroller took it first), `preventDefault()`s it so the native wheel never\n * reaches a scrollable ancestor behind the overlay.\n *\n * @param e - The wheel event reaching the overlay as the outermost ancestor.\n */\nfunction swallowUnconsumedWheel(e: WheelEvent): Event.ListenerResult {\n if (consumeWheel(e)) {\n return { prevent: true };\n }\n}\n\n/**\n * Registers a non-passive subtree `wheel` listener on `component` that\n * `preventDefault()`s any wheel the event reaches it unconsumed — trapping\n * wheels an inner scroller did not claim so they cannot fall through to content\n * behind a floating overlay. Idempotent per component.\n *\n * @param component - The overlay to install the trap on. Must already be mounted,\n * since the subtree listener resolves the component's element.\n *\n * @remarks Subtree events dispatch descendant-first, so any inner scroll\n * container under the pointer claims the wheel first and the overlay's handler,\n * firing last as the outermost ancestor, sees it already consumed and does\n * nothing — inner scroll proceeds untouched. The listener is `{ passive: false }`\n * to match the only other `wheel` registration (the inner scroll pipeline) and\n * because `preventDefault()` is a no-op on a passive listener.\n */\nexport function trapWheel(component: Component): void {\n if (_trapped.has(component)) {\n return;\n }\n\n _trapped.add(component);\n Event.addSubtreeListener(component, \"wheel\", { passive: false, handler: swallowUnconsumedWheel });\n}\n\n/**\n * Removes the trap installed by {@link trapWheel}. Safe to call when none was\n * installed.\n *\n * @param component - The overlay whose trap should be removed.\n */\nexport function untrapWheel(component: Component): void {\n if (!_trapped.has(component)) {\n return;\n }\n\n _trapped.delete(component);\n Event.removeSubtreeListener(component, \"wheel\", swallowUnconsumedWheel);\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport { Position } from \"~/primitive/Position.js\";\nimport { callable } from \"~/core/Callable.js\";\nimport { LayerManager } from \"~/core/LayerManager.js\";\nimport { DOM } from \"~/core/DOM.js\";\n\n/**\n * Z-order for the drop-target validity tint. The tint highlights a drop target,\n * which lives in ordinary app content — so it must sit **below** the lowest\n * {@link LayerManager} band (the {@link Window} band) or it paints over a\n * floating window, while still sitting above the target's own content (app\n * z-indexes top out near 3). The app tree establishes no isolating stacking\n * context, so a higher value escapes to the root context and beats windows —\n * which is exactly the bug `Band.Window - 1` avoids. Shared rationale with\n * {@link ReorderIndicator}; the drag ghost sits above both at the root.\n */\nconst Z_INDEX = LayerManager.Band.Window - 1;\n\n/**\n * A validity tint overlay drawn on top of the row currently being hovered\n * during an active drag. The colour swaps between the `valid` and\n * `invalid` theme tokens via {@link setValid}; the geometry is mirrored\n * onto a drop target via {@link attachTo}.\n *\n * Owned by [`DragManager`](/api/overlay/variables/DragManager) — application\n * code does not instantiate this directly.\n *\n * @category Core\n */\nclass DragFeedback extends Component {\n\n private _valid: boolean = true;\n\n /**\n * Constructs a drag-feedback overlay. The overlay is not attached\n * until {@link attachTo} is called.\n */\n constructor() {\n super();\n\n this.setPosition(Position.ABSOLUTE);\n this.setZIndex(Z_INDEX);\n this.setPointerEvents(\"none\");\n\n this.applyTintForValidity();\n }\n\n /**\n * Returns whether the overlay is currently showing the \"valid drop\"\n * tint.\n *\n * @returns `true` for the valid tint, `false` for the invalid tint.\n */\n isValid(): boolean {\n return this._valid;\n }\n\n /**\n * Switches the overlay between the `valid` and `invalid` theme\n * tokens. Idempotent — repeated calls with the same value are a\n * no-op.\n *\n * @param valid - `true` to show the valid tint, `false` for invalid.\n */\n setValid(valid: boolean): void {\n if (this._valid === valid) {\n return;\n }\n\n this._valid = valid;\n\n this.applyTintForValidity();\n }\n\n /**\n * Sizes this overlay to cover the drop target and appends it to the DOM.\n *\n * With no `host`, the tint is a child of the target, covering its body. When\n * a `host` is given, the tint instead lives in that (non-scrolling) layer,\n * sized to the target's box within it — so a target that scrolls its own\n * content (a Tab strip's clip frame) gets a tint over the *viewport* that\n * stays put instead of riding the scroll.\n *\n * @param target - The drop target whose box the tint should cover.\n * @param host - Optional non-scrolling layer to host the tint (see\n * {@link DropTargetOptions.feedbackHost}). Defaults to the target.\n */\n attachTo(target: Component, host?: Component): void {\n const myEl = this.getElement(true)!;\n\n if (host && host !== target) {\n // Overlay the target's box from within the host layer.\n this.setX(target.getX());\n this.setY(target.getY());\n this.setWidth(target.getWidth());\n this.setHeight(target.getHeight());\n\n const hostEl = host.getElement(true)!;\n if (DOM.source.getParentElement(myEl) !== hostEl) {\n DOM.sink.appendChild(hostEl, myEl);\n }\n\n return;\n }\n\n // Cover the target's own body as a child of it.\n this.setX(0);\n this.setY(0);\n this.setWidth(target.getWidth());\n this.setHeight(target.getHeight());\n\n const targetEl = target.getElement(true)!;\n if (DOM.source.getParentElement(myEl) !== targetEl) {\n DOM.sink.appendChild(targetEl, myEl);\n }\n }\n\n /**\n * Removes the overlay element from the DOM.\n */\n detach(): void {\n this.removeElement();\n }\n\n /**\n * Writes the background and border CSS variables that correspond to\n * the cached validity state. Called from the constructor and from\n * {@link setValid} on transitions.\n */\n private applyTintForValidity(): void {\n const suffix = this._valid ? \"valid\" : \"invalid\";\n\n this.setBackgroundColor(`var(--ts-ui-drag-feedback-${suffix}-bg)`);\n this.setBorder({ border: `2px solid var(--ts-ui-drag-feedback-${suffix}-border)` });\n }\n}\n\nconst DragFeedbackCallable = callable(DragFeedback);\ntype DragFeedbackCallable = DragFeedback;\nexport {\n DragFeedback as _DragFeedback,\n DragFeedbackCallable as DragFeedback,\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport { Position } from \"~/primitive/Position.js\";\nimport { Text } from \"~/component/input/Text.js\";\nimport { callable } from \"~/core/Callable.js\";\nimport { DOM } from \"~/core/DOM.js\";\n\n/**\n * Z-order ceiling for the drag ghost. The follow-the-cursor preview rides above\n * everything during a drag — appended at the document root, above the\n * LayerManager bands — so it is never occluded by a floating window or by the\n * per-target highlights ([`DragFeedback`](/api/overlay/classes/DragFeedback) /\n * [`ReorderIndicator`](/api/overlay/classes/ReorderIndicator)), which deliberately\n * sit *below* the window band instead.\n */\nconst Z_INDEX = 10200;\n\n/**\n * Default ghost width when the caller omits an explicit size. Picked to\n * comfortably surround a one-line label without measuring text.\n */\nconst DEFAULT_WIDTH = 160;\n\n/** Default ghost height — one row's worth of vertical room. */\nconst DEFAULT_HEIGHT = 28;\n\n/**\n * Inner padding around the optional ghost label so text doesn't crowd the\n * border at the framework's default font size.\n */\nconst LABEL_INSET = 6;\n\n/**\n * A floating drag preview that follows the pointer during an active drag\n * session, drawn above every other overlay. Created and owned by\n * [`DragManager`](/api/overlay/variables/DragManager); application code does\n * not instantiate this directly.\n *\n * The ghost is `Position.FIXED` (one of the documented overlay carve-outs\n * in `ARCHITECTURE.md` §Positioning) and renders with\n * `pointer-events: none` so the manager's\n * `document.elementsFromPoint` hit-test always returns the row underneath.\n *\n * @category Core\n */\nclass DragGhost extends Component {\n\n private _label: Text | null = null;\n\n /**\n * Constructs a drag ghost. The caller positions it via\n * {@link moveTo} and toggles visibility through {@link show} /\n * {@link hide}.\n *\n * @param label - Optional text drawn inside the ghost.\n * @param width - Optional width in pixels (defaults to 160).\n * @param height - Optional height in pixels (defaults to 28).\n */\n constructor(label?: string, width?: number, height?: number) {\n super();\n\n this.setPosition(Position.FIXED);\n this.setZIndex(Z_INDEX);\n this.setPointerEvents(\"none\");\n this.setWidth(width ?? DEFAULT_WIDTH);\n this.setHeight(height ?? DEFAULT_HEIGHT);\n\n this.setBackgroundColor(\"var(--ts-ui-drag-ghost-bg)\");\n this.setBorder({ border: \"1px solid var(--ts-ui-drag-ghost-border)\" });\n this.setShadow(\"var(--ts-ui-drag-ghost-shadow)\");\n this.setBorderRadius(\"var(--ts-ui-border-radius, 4px)\");\n this.setOpacity(Number(\"0.85\"));\n\n if (label !== undefined) {\n this._label = new Text(label);\n this._label.setPointerEvents(\"none\");\n this.addComponent(this._label);\n }\n }\n\n /**\n * Repositions the ghost so its top-left corner sits at\n * `(clientX, clientY)`. `DragManager` calls this on every `mousemove`\n * during an active drag.\n *\n * @param clientX - The viewport X (already offset from the cursor by the manager).\n * @param clientY - The viewport Y (already offset from the cursor by the manager).\n */\n moveTo(clientX: number, clientY: number): void {\n this.setX(clientX);\n this.setY(clientY);\n }\n\n /**\n * Appends the ghost to `<html>` and schedules a layout pass. Used by\n * `DragManager` when a drag commits past the movement threshold.\n */\n show(): void {\n const el = this.getElement(true)!;\n\n this.scheduleLayout();\n DOM.sink.appendChild(DOM.source.getDocumentElement(), el);\n }\n\n /**\n * Removes the ghost element from the DOM. Used by `DragManager` on\n * mouseup / cancel.\n */\n hide(): void {\n this.removeElement();\n }\n\n /**\n * Lays out the optional label inside the ghost's content box.\n *\n * @returns This component, for method chaining.\n */\n doLayout(): this {\n super.doLayout();\n\n const box = this.getContentBounds();\n\n if (this._label && box) {\n this._label.setX(box.x + LABEL_INSET);\n this._label.setY(box.y + LABEL_INSET);\n this._label.setWidth(box.width - LABEL_INSET * 2);\n this._label.setHeight(box.height - LABEL_INSET * 2);\n }\n\n return this;\n }\n}\n\nconst DragGhostCallable = callable(DragGhost);\ntype DragGhostCallable = DragGhost;\nexport {\n DragGhost as _DragGhost,\n DragGhostCallable as DragGhost,\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport { Position } from \"~/primitive/Position.js\";\nimport { callable } from \"~/core/Callable.js\";\nimport { LayerManager } from \"~/core/LayerManager.js\";\nimport { DOM } from \"~/core/DOM.js\";\n\n/**\n * Z-order shared with {@link DragFeedback}: just **below** the lowest\n * {@link LayerManager} band (the {@link Window} band) so this drop-target\n * insertion line — drawn over app content that establishes no isolating\n * stacking context — never paints over a floating window, while still sitting\n * above the target's own content. The drag ghost sits above both at the root.\n */\nconst Z_INDEX = LayerManager.Band.Window - 1;\n\n/** Height of the insertion-line bar in pixels. */\nconst BAR_HEIGHT = 2;\n\n/**\n * Half the bar height — subtracted in {@link ReorderIndicator.setInsertionY}\n * so the 2 px bar is centred on the insertion line.\n */\nconst BAR_HALF = 1;\n\n/**\n * A 2 px horizontal bar drawn between rows to mark the insertion line\n * during an active drag-reorder gesture.\n *\n * Reserved for future sibling-reorder work — drop-on-directory does not\n * use this overlay. The class ships now so the public API surface and\n * theme tokens stabilise alongside\n * [`DragGhost`](/api/overlay/classes/DragGhost) and\n * [`DragFeedback`](/api/overlay/classes/DragFeedback); the row-DnD wiring\n * in [`TreeTable`](/api/component/table/classes/TreeTable) only attaches\n * the feedback tint.\n *\n * @category Core\n */\nclass ReorderIndicator extends Component {\n\n /**\n * Constructs a reorder indicator. The bar is not attached until\n * {@link attachTo} is called.\n */\n constructor() {\n super();\n\n this.setPosition(Position.ABSOLUTE);\n this.setZIndex(Z_INDEX);\n this.setPointerEvents(\"none\");\n this.setHeight(BAR_HEIGHT);\n\n this.setBackgroundColor(\"var(--ts-ui-drag-reorder-color)\");\n }\n\n /**\n * Centres the bar on the given y-coordinate within the attached\n * target. The `- BAR_HALF` shift accounts for the 2 px bar height.\n *\n * @param y - Insertion-line y, measured from the target's top edge.\n */\n setInsertionY(y: number): void {\n this.setY(y - BAR_HALF);\n }\n\n /**\n * Mirrors the target's width onto the bar and appends the bar\n * element to the target.\n *\n * @param target - The drop target whose top-left coordinate space\n * the bar is positioned within.\n */\n attachTo(target: Component): void {\n const targetEl = target.getElement(true)!;\n const myEl = this.getElement(true)!;\n\n this.setX(0);\n this.setWidth(target.getWidth());\n\n if (DOM.source.getParentElement(myEl) === targetEl) {\n return;\n }\n\n DOM.sink.appendChild(targetEl, myEl);\n }\n\n /**\n * Removes the bar element from the DOM.\n */\n detach(): void {\n this.removeElement();\n }\n}\n\nconst ReorderIndicatorCallable = callable(ReorderIndicator);\ntype ReorderIndicatorCallable = ReorderIndicator;\nexport {\n ReorderIndicator as _ReorderIndicator,\n ReorderIndicatorCallable as ReorderIndicator,\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport { DragFeedback } from \"~/overlay/DragFeedback.js\";\nimport { DragGhost } from \"~/overlay/DragGhost.js\";\nimport { Event } from \"~/core/Event.js\";\nimport { ReorderIndicator } from \"~/overlay/ReorderIndicator.js\";\nimport { DOM } from \"~/core/DOM.js\";\n\n/**\n * Arbitrary, caller-defined payload attached to a drag source — the\n * shape is consumer-domain and the manager never inspects fields.\n *\n * @category Core\n */\nexport type DragData = Record<string, unknown>;\n\n/**\n * Payload delivered to every named drag-source / drop-target callback\n * and to every fired DOM event. Field names are stable across\n * `dragstart`, `dragover`, `dragleave`, `drop`, `dragend`.\n *\n * @category Core\n */\nexport interface DragEventDetail {\n /** The source's resolved drag data — read from the source options at session start. */\n dragData : DragData;\n /** The source component's id (`getId()`), useful for cycle / self-drop checks. */\n sourceId : string;\n /** Viewport-relative pointer X at the moment the event was raised. */\n clientX : number;\n /** Viewport-relative pointer Y at the moment the event was raised. */\n clientY : number;\n}\n\n/**\n * Drag-data payload attached to every tab-header drag — the cross-container\n * contract shared by the within-strip reorder path, tab tear-off / re-dock, the\n * Ctrl-drag window re-dock, and the downstream edge-split / dock-manager work.\n * A drop target reads it off {@link DragEventDetail}'s `dragData`. Because\n * {@link DragData} is a plain record it cannot carry a live component reference,\n * so `componentId` keys into the module-level `tabDragRegistry` to resolve the\n * dragged content.\n *\n * @category Core\n */\nexport interface TabDragData {\n /** Discriminator a drop target tests in its `accepts` predicate. */\n tabDrag: true;\n /** The source strip's stable id — distinguishes reorder-within from dock-from-elsewhere. */\n sourceTabId: string;\n /** The dragged content component's id — the key into `tabDragRegistry`. */\n componentId: string;\n /** The tab label — used for the drag ghost and the tear-off window title. */\n label: string;\n}\n\n/**\n * Resolves a {@link TabDragData} `componentId` back to the live content\n * component being dragged. Written when a header drag starts and cleared when it\n * ends, so a drop target — the same strip, another strip, or a torn-off\n * {@link DragData}-carrying window — can move the real component rather than\n * only learning its id. Shared by-import across `Tab` and `Window`; one\n * instance, so a source-side write is visible to the destination-side read.\n */\nexport const tabDragRegistry: Map<string, Component> = new Map<string, Component>();\n\n/**\n * Dwell, in milliseconds, before a tab held over a drop target spring-loads a\n * raise of that target's host window — surfacing a backgrounded float so the user\n * can aim the drop. Shared by the two dock drop surfaces so a region body\n * ([`DockRegion`](/api/layout/classes/DockRegion)) and a tab bar\n * ([`TabBar`](/api/component/container/classes/TabBar)) raise on the same cadence.\n *\n * Long enough that brushing a drag across a background window in transit does not\n * raise it, short enough that a deliberate hover surfaces the target. Set above a\n * `MenuItem` submenu's 150ms hover delay because raising a whole window is a\n * heavier, more disruptive action than opening a submenu, so it should demand a\n * clearly deliberate pause.\n */\nexport const SPRING_RAISE_DELAY_MS = 1000;\n\n/**\n * Construction-time options accepted by {@link DragManager.makeDragSource}.\n *\n * @category Core\n */\nexport interface DragSourceOptions {\n /** Static or factory-produced payload attached to the session. */\n dragData : DragData | (() => DragData);\n /**\n * Optional veto callback fired the moment the threshold is crossed.\n * Return `false` to abort the drag before any overlay is shown.\n */\n onDragStart? : (detail: DragEventDetail) => boolean | void;\n /**\n * Optional ghost factory. The returned component is used in place of\n * the manager's default ghost (which carries no label and matches the\n * source's size). The component must be detached when returned.\n */\n ghostFactory?: (source: Component, data: DragData) => Component;\n /** CSS cursor applied to `<body>` while the drag is active. */\n cursor? : string;\n /**\n * Fired once the gesture ends, after any `onDrop`. `dropped` is `true` when\n * the release was handled by a registered drop target — whether the target\n * accepted the drop or refused it — and `false` only on a release over empty\n * space. Lets a source distinguish a release that landed on a target from a\n * fall-through to empty space (e.g. tab tear-off), the signal the `\"dragend\"`\n * DOM event alone cannot carry.\n */\n onDragEnd? : (detail: DragEventDetail, dropped: boolean) => void;\n}\n\n/**\n * Construction-time options accepted by {@link DragManager.makeDropTarget}.\n *\n * @category Core\n */\nexport interface DropTargetOptions {\n /**\n * Validity predicate. Returns `true` when the dragged source may\n * drop on this target; the visual feedback tint mirrors the result.\n */\n accepts : (detail: DragEventDetail) => boolean;\n /**\n * Optional hover callback. Return a number to position the\n * [`ReorderIndicator`](/api/overlay/classes/ReorderIndicator) at the\n * given y inside the target; return `null` / `undefined` for no\n * reorder line.\n */\n onDragOver? : (detail: DragEventDetail) => number | null | void;\n /** Optional leave callback (cursor exits target's box). */\n onDragLeave? : (detail: DragEventDetail) => void;\n /** Optional drop callback — return `false` to suppress the `drop` event. */\n onDrop? : (detail: DragEventDetail) => boolean | void;\n /**\n * Suppresses the whole-target validity tint\n * ([`DragFeedback`](/api/overlay/classes/DragFeedback)) for this target. Pass it\n * when the target paints its own positional validity feedback (e.g. a\n * [`DockRegion`](/api/layout/classes/DockRegion) colours the drop *zone*\n * blue/red in `onDragOver`) so the two don't stack into a tinted frame *and*\n * a tinted zone. `accepts` still governs whether `onDragOver`/`onDrop` fire.\n */\n suppressValidityTint?: boolean;\n /**\n * Optional non-scrolling layer to host the validity tint, sized to the\n * target's box within it. Pass it when the target scrolls its own content\n * (e.g. a Tab strip's clip frame) so the tint overlays the *viewport* and\n * stays put instead of riding the scroll. Defaults to the target itself.\n */\n feedbackHost?: Component;\n}\n\ninterface DragSourceRecord {\n component: Component;\n options: DragSourceOptions;\n}\n\ninterface DropTargetRecord {\n component: Component;\n options: DropTargetOptions;\n}\n\ninterface DragSession {\n source: Component;\n sourceOptions: DragSourceOptions;\n dragData: DragData;\n startX: number;\n startY: number;\n committed: boolean;\n ghost: Component | null;\n feedback: DragFeedback | null;\n indicator: ReorderIndicator | null;\n currentTarget: Component | null;\n previousBodyCursor: string;\n}\n\n/**\n * Distance the cursor must travel between `mousedown` and `mousemove`\n * before the press-and-drag commits to a drag. The 4 px slop matches\n * the standard HIG threshold on Windows and macOS — anything shorter\n * fires a drag on plain clicks; anything longer feels unresponsive.\n */\nconst DRAG_THRESHOLD = 4;\n\n/**\n * Diagonal offsets applied to the ghost's top-left corner so the cursor\n * stays clear of the preview. Matches Finder / VS Code placement.\n */\nconst GHOST_OFFSET_X = 12;\nconst GHOST_OFFSET_Y = 12;\n\nconst dragSources = new Map<string, DragSourceRecord>();\nconst dropTargets = new Map<string, DropTargetRecord>();\nlet activeSession: DragSession | null = null;\n\n/**\n * Process-wide drag-and-drop coordinator. Maintains the global source /\n * target registry, owns the single active drag session, and\n * positions the three overlay components\n * ([`DragGhost`](/api/overlay/classes/DragGhost),\n * [`DragFeedback`](/api/overlay/classes/DragFeedback),\n * [`ReorderIndicator`](/api/overlay/classes/ReorderIndicator)) above the\n * page during a drag.\n *\n * Consumers register through the two factory functions and receive a\n * teardown closure to unwire when the source / target component goes\n * away. The manager itself fires no events directly — every callback\n * lives on the option bag the caller passed to the factory.\n *\n * @example\n * ```typescript\n * const tearDownSrc = DragManager.makeDragSource(row, {\n * dragData: () => ({ recordId: row.getRecord()?.get('id') }),\n * });\n * const tearDownTgt = DragManager.makeDropTarget(folder, {\n * accepts: (d) => d.dragData.recordId !== folder.getRecord()?.get('id'),\n * onDrop: (d) => moveRecord(d.dragData.recordId, folder),\n * });\n * ```\n *\n * @category Core\n */\nexport namespace DragManager {\n\n /**\n * Registers a component as a drag source. The component's mousedown\n * event begins a pending drag session that commits once the cursor\n * travels past the 4 px movement threshold.\n *\n * @param component - The source component.\n * @param options - Drag source configuration.\n *\n * @returns A teardown function that removes the source registration\n * and the mousedown listener.\n */\n export function makeDragSource(component: Component, options: DragSourceOptions): () => void {\n dragSources.set(component.getId(), { component, options });\n component.addMouseDownSubtreeListener(onSourceMouseDown);\n\n return tearDownDragSource.bind(null, component);\n }\n\n /**\n * Registers a component as a drop target. The component is queried\n * for `accepts` during every `mousemove` while a drag is active and\n * receives the configured callbacks at the appropriate phases.\n *\n * @param component - The drop target.\n * @param options - Drop target configuration.\n *\n * @returns A teardown function that removes the target registration.\n */\n export function makeDropTarget(component: Component, options: DropTargetOptions): () => void {\n dropTargets.set(component.getId(), { component, options });\n\n return tearDownDropTarget.bind(null, component);\n }\n\n /**\n * Returns whether a drag is currently in progress (committed past\n * the 4 px movement threshold).\n *\n * @returns `true` while the ghost is visible; `false` otherwise.\n */\n export function isDragging(): boolean {\n return activeSession !== null && activeSession.committed;\n }\n\n /**\n * Aborts an in-flight drag. Mirrors a `mouseup` outside any drop\n * target — no drop callback fires; the session tears down.\n */\n export function cancel(): void {\n if (activeSession === null) {\n return;\n }\n\n endSession(false, 0, 0);\n }\n}\n\n/**\n * Resolves the source's drag-data payload — accepts either a literal or\n * a factory function on every drag start so callers can carry per-row\n * state without re-registering the source.\n */\nfunction resolveDragData(options: DragSourceOptions): DragData {\n return typeof options.dragData === \"function\" ? options.dragData() : options.dragData;\n}\n\n/**\n * Removes the per-component mousedown listener and drops the source\n * record. Bound to `(component)` by `makeDragSource` so the returned\n * teardown closure stays a stable named-function reference.\n */\nfunction tearDownDragSource(component: Component): void {\n component.removeMouseDownSubtreeListener(onSourceMouseDown);\n dragSources.delete(component.getId());\n}\n\n/**\n * Drops the target record. Bound to `(component)` by\n * `makeDropTarget` so the returned teardown closure stays a stable\n * named-function reference.\n */\nfunction tearDownDropTarget(component: Component): void {\n dropTargets.delete(component.getId());\n}\n\n/**\n * Records the pending press and arms the viewport-level move / up\n * listeners. Nothing visual happens until the cursor crosses the\n * threshold.\n *\n * Registered as a subtree mousedown listener on every drag source, so\n * a press on any descendant of the source bubbles up the subtree\n * walker and the framework's Event router applies `component` as\n * `this` for the matching source — the lookup that identifies which\n * source was pressed.\n */\nfunction onSourceMouseDown(this: Component, e: MouseEvent): void {\n if (activeSession !== null) {\n return;\n }\n\n if (e.button !== 0) {\n return;\n }\n\n const record = dragSources.get(this.getId());\n\n if (!record) {\n return;\n }\n\n const source = record.component;\n const options = record.options;\n\n activeSession = {\n source,\n sourceOptions: options,\n dragData: resolveDragData(options),\n startX: e.clientX,\n startY: e.clientY,\n committed: false,\n ghost: null,\n feedback: null,\n indicator: null,\n currentTarget: null,\n previousBodyCursor: DOM.source.getInlineStyle(DOM.source.getBody(), \"cursor\"),\n };\n\n // Viewport listeners route through Event.baseViewportListener, which stops\n // mouseup propagation at window capture phase whenever any viewport\n // listener for the type exists. A raw document-level mouseup binding would\n // race SpinButton-class registrants that already pre-empt mouseup at\n // capture and never fire.\n Event.addViewportListener(source, \"mousemove\", onMouseMove);\n Event.addViewportListener(source, \"mouseup\", onMouseUp);\n Event.addViewportListener(source, \"selectstart\", onSelectStart);\n}\n\n/**\n * Builds the session's three overlay components and writes the page-\n * wide cursor. Called once on the first mousemove that crosses the\n * threshold.\n */\nfunction commitSession(session: DragSession): void {\n session.committed = true;\n\n const ghost = session.sourceOptions.ghostFactory\n ? session.sourceOptions.ghostFactory(session.source, session.dragData)\n : new DragGhost();\n\n session.ghost = ghost;\n session.feedback = new DragFeedback();\n session.indicator = new ReorderIndicator();\n\n if (typeof (ghost as unknown as { show?: () => void }).show === \"function\") {\n (ghost as unknown as { show: () => void }).show();\n } else {\n const el = ghost.getElement(true)!;\n\n DOM.sink.appendChild(DOM.source.getDocumentElement(), el);\n }\n\n if (session.sourceOptions.cursor) {\n DOM.sink.apply(DOM.source.getBody(), { style: { cursor: session.sourceOptions.cursor } });\n }\n}\n\n/**\n * Builds the immutable detail payload threaded through every\n * source / target callback for the current pointer position.\n */\nfunction buildDetail(session: DragSession, clientX: number, clientY: number): DragEventDetail {\n return {\n dragData: session.dragData,\n sourceId: session.source.getId(),\n clientX,\n clientY,\n };\n}\n\n/**\n * Hit-tests under the ghost (which is pointer-events-none) and returns\n * the registered drop target whose element is the first match in the\n * z-stack, or `null` when no registered target sits under the cursor.\n */\nfunction pickDropTarget(clientX: number, clientY: number): DropTargetRecord | null {\n const stack = DOM.source.elementsFromPoint(clientX, clientY);\n\n for (const el of stack) {\n const record = dropTargets.get(DOM.source.getId(el));\n\n if (record) {\n return record;\n }\n }\n\n return null;\n}\n\n/**\n * Detaches the validity tint from the previous target and fires its\n * `onDragLeave`. No-op when there is no previous target.\n */\nfunction leaveCurrentTarget(session: DragSession, detail: DragEventDetail): void {\n if (session.currentTarget === null) {\n return;\n }\n\n const prev = dropTargets.get(session.currentTarget.getId());\n\n if (prev && prev.options.onDragLeave) {\n prev.options.onDragLeave(detail);\n }\n\n if (session.feedback) {\n session.feedback.detach();\n }\n\n if (session.indicator) {\n session.indicator.detach();\n }\n\n session.currentTarget = null;\n}\n\n/**\n * Attaches the validity tint to the new target, calls `onDragOver`\n * once, and positions the reorder indicator if the callback returned a\n * y value.\n */\nfunction enterNewTarget(session: DragSession, target: DropTargetRecord, detail: DragEventDetail): void {\n const accepted = target.options.accepts(detail);\n\n if (session.feedback && !target.options.suppressValidityTint) {\n session.feedback.setValid(accepted);\n session.feedback.attachTo(target.component, target.options.feedbackHost);\n }\n\n if (!accepted) {\n session.currentTarget = target.component;\n\n return;\n }\n\n const hint = target.options.onDragOver?.(detail);\n\n if (typeof hint === \"number\" && session.indicator) {\n session.indicator.attachTo(target.component);\n session.indicator.setInsertionY(hint);\n } else if (session.indicator) {\n session.indicator.detach();\n }\n\n session.currentTarget = target.component;\n}\n\n/**\n * Suppresses the browser's own text-selection gesture for the duration of a\n * drag session, which would otherwise run alongside it now that table cell\n * text is selectable — the drag is mouse-driven (mousedown/mousemove), not\n * HTML5 drag-and-drop, so nothing else stops a selection from painting in\n * parallel. `preventDefault()` on `mousemove` does not by itself stop the\n * browser from extending a selection (verified live: the selection still\n * grew with every `mousemove` observably prevented), so the suppression has\n * to target `selectstart` itself. Registered and torn down alongside the\n * mousemove/mouseup viewport listeners, so it is live only while a session\n * exists — including the brief press-to-release window of a plain click\n * that never crosses the drag threshold, where losing the (invisible)\n * collapsed-caret placement a real `selectstart` would otherwise produce\n * has no observable effect on a non-editable table cell.\n *\n * @returns Always suppresses the event while installed.\n */\nfunction onSelectStart(): Event.ListenerResult {\n return { stop: true, prevent: true };\n}\n\n/**\n * Drives the active session forward each frame: commits past the\n * threshold, moves the ghost, hands target changes to the\n * enter / leave helpers, and re-runs `onDragOver` while the cursor stays\n * inside the same target.\n *\n * @returns `true` while a drag session is live, consuming the move so nothing else\n * tracks the pointer; nothing when there is no session, so the move keeps propagating.\n */\nfunction onMouseMove(e: MouseEvent): Event.ListenerResult {\n if (activeSession === null) {\n return;\n }\n\n const session = activeSession;\n\n if (!session.committed) {\n const dx = e.clientX - session.startX;\n const dy = e.clientY - session.startY;\n\n if (dx * dx + dy * dy < DRAG_THRESHOLD * DRAG_THRESHOLD) {\n return { stop: true, prevent: true };\n }\n\n const startDetail = buildDetail(session, e.clientX, e.clientY);\n\n if (session.sourceOptions.onDragStart?.(startDetail) === false) {\n endSession(false, e.clientX, e.clientY);\n\n return { stop: true, prevent: true };\n }\n\n commitSession(session);\n Event.fireEvent(session.source, \"dragstart\", { detail: startDetail });\n }\n\n if (session.ghost) {\n const dragGhost = session.ghost as unknown as { moveTo?: (x: number, y: number) => void };\n\n if (typeof dragGhost.moveTo === \"function\") {\n dragGhost.moveTo(e.clientX + GHOST_OFFSET_X, e.clientY + GHOST_OFFSET_Y);\n } else {\n session.ghost.setX(e.clientX + GHOST_OFFSET_X);\n session.ghost.setY(e.clientY + GHOST_OFFSET_Y);\n }\n }\n\n const detail = buildDetail(session, e.clientX, e.clientY);\n const target = pickDropTarget(e.clientX, e.clientY);\n\n if (target === null) {\n leaveCurrentTarget(session, detail);\n\n return { stop: true, prevent: true };\n }\n\n if (session.currentTarget !== target.component) {\n leaveCurrentTarget(session, detail);\n enterNewTarget(session, target, detail);\n\n return { stop: true, prevent: true };\n }\n\n // Same target as last frame — re-check accepts so the feedback\n // tint stays accurate (the validity of a drop can change as the\n // cursor moves within the same target, e.g. crossing into a\n // descendant region the source isn't allowed to land on). Skip\n // onDragOver / reorder indicator entirely while the drop is\n // rejected.\n const accepted = target.options.accepts(detail);\n\n if (session.feedback && !target.options.suppressValidityTint) {\n session.feedback.setValid(accepted);\n }\n\n if (!accepted) {\n if (session.indicator) {\n session.indicator.detach();\n }\n\n return { stop: true, prevent: true };\n }\n\n const hint = target.options.onDragOver?.(detail);\n\n if (typeof hint === \"number\" && session.indicator) {\n session.indicator.attachTo(target.component);\n session.indicator.setInsertionY(hint);\n } else if (session.indicator) {\n session.indicator.detach();\n }\n\n return { stop: true, prevent: true };\n}\n\n/**\n * Commits the drop (if any) and tears down the session.\n *\n * @returns `true` when a drag session was live, consuming the release that ends it;\n * nothing when there is no session, so the release keeps propagating.\n */\nfunction onMouseUp(e: MouseEvent): Event.ListenerResult {\n if (activeSession === null) {\n return;\n }\n\n const session = activeSession;\n const detail = buildDetail(session, e.clientX, e.clientY);\n let dropped = false;\n\n if (session.committed && session.currentTarget !== null) {\n const target = dropTargets.get(session.currentTarget.getId());\n\n if (target) {\n // Released over a registered drop target. Dispatch the drop only\n // when the target accepts; either way the release was *handled* by a\n // target rather than falling through to empty space, so report\n // `dropped` so the source skips its empty-space fallback — e.g. a Tab\n // header snaps back instead of tearing off into a window when the\n // target refused it (a rejected self-dock is a no-op, not a detach).\n if (target.options.accepts(detail)) {\n const onDropResult = target.options.onDrop?.(detail);\n\n if (onDropResult !== false) {\n Event.fireEvent(session.source, \"drop\", { detail });\n }\n }\n\n dropped = true;\n }\n }\n\n endSession(dropped, e.clientX, e.clientY);\n\n return true;\n}\n\n/**\n * Removes overlays, unwires viewport listeners, restores the body\n * cursor, and fires `dragend` when the session committed.\n */\nfunction endSession(dropped: boolean, clientX: number, clientY: number): void {\n if (activeSession === null) {\n return;\n }\n\n const session = activeSession;\n\n Event.removeViewportListener(session.source, \"mousemove\", onMouseMove);\n Event.removeViewportListener(session.source, \"mouseup\", onMouseUp);\n Event.removeViewportListener(session.source, \"selectstart\", onSelectStart);\n\n // The drag chrome is built fresh for every committed gesture in\n // `commitSession` and held only on the session record — none of it is\n // registered through `addComponent`, so `Component.destructor()`'s child\n // recursion can never reach it. Disposing, rather than only detaching,\n // is what reclaims each one's per-instance stylesheet rule before the\n // session reference is dropped; detaching alone grew the shared sheet by\n // one rule per drag, without bound.\n if (session.feedback) {\n session.feedback.dispose();\n }\n\n if (session.indicator) {\n session.indicator.dispose();\n }\n\n if (session.ghost) {\n if (session.sourceOptions.ghostFactory) {\n // A ghost from the caller's factory belongs to the caller, which\n // may hand back the same component on every gesture — so it is\n // detached, never disposed.\n const dragGhost = session.ghost as unknown as { hide?: () => void };\n\n if (typeof dragGhost.hide === \"function\") {\n dragGhost.hide();\n } else {\n session.ghost.removeElement();\n }\n } else {\n session.ghost.dispose();\n }\n }\n\n if (session.sourceOptions.cursor) {\n DOM.sink.apply(DOM.source.getBody(), { style: { cursor: session.previousBodyCursor } });\n }\n\n if (session.committed) {\n const detail = buildDetail(session, clientX, clientY);\n\n Event.fireEvent(session.source, \"dragend\", { detail });\n session.sourceOptions.onDragEnd?.(detail, dropped);\n }\n\n activeSession = null;\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { ComponentOptions } from \"~/core/Component.js\";\nimport { Event } from \"~/core/Event.js\";\nimport { Checkbox } from \"~/component/input/Checkbox.js\";\nimport { MenuItem } from \"~/component/container/MenuItem.js\";\nimport { MenuRow } from \"~/component/container/MenuRow.js\";\nimport { callable } from \"~/core/Callable.js\";\n\n/** Events exposed by {@link CheckboxMenuRow}. */\nexport type CheckboxMenuRowEvent = \"action\";\n\n// Dim applied to a disabled row, matching the framework's other composite\n// disabled controls (Button.setEnabled, NumberSpinner.applyEnabled).\nconst DISABLED_OPACITY = 0.5;\n\n/**\n * Construction-time options for {@link CheckboxMenuRow}.\n *\n * @category Components\n */\nexport interface CheckboxMenuRowOptions extends ComponentOptions {\n /** Row label, rendered beside the checkbox graphic. */\n text?: string;\n /** Initial checked state. Defaults to `false`. */\n checked?: boolean;\n /** Defaults to `true`. Disabled rows are dimmed and non-interactive. */\n enabled?: boolean;\n /**\n * Construction-time listener bag; `action` fires after each toggle.\n */\n listeners?: { action?: () => void };\n}\n\n/**\n * A [`Menu`](/api/overlay/classes/Menu) row hosting a real\n * [`Checkbox`](/api/component/input/classes/Checkbox), for a multi-select menu.\n *\n * Built via `{ row: () => new CheckboxMenuRow({ text, checked }) }` on a\n * `MenuItemConfig`. Toggles on a click anywhere in the row or on Enter (via\n * {@link activate}) and leaves the menu open — unlike a plain `MenuItem`,\n * activating it never closes the panel. `isNavigable()` reports `true`, so\n * the menu's roving arrow-key highlight lands on it like any other row.\n *\n * @category Components\n */\nclass CheckboxMenuRow extends MenuRow<CheckboxMenuRowOptions> {\n\n private _checkbox: Checkbox;\n // The title offset the owning Menu pushed in, or null when this row is\n // standalone — in which case doLayout falls back to MenuItem.TEXT_INSET.\n private _iconStart: number | null = null;\n // The check-column width the owning Menu pushed in, alongside _iconStart —\n // needed to tell whether _iconStart was widened for a sibling's icon (see\n // doLayout's `iconColumnReserved`).\n private _checkZone: number | null = null;\n\n private readonly _onMouseOver: () => void;\n private readonly _onMouseOut: () => void;\n private readonly _onClick: () => void;\n\n /**\n * Constructs a CheckboxMenuRow.\n *\n * @param options - Optional construction-time options.\n * @param subclassDefaults - Per-subclass default bag layered over this\n * class's defaults; subclasses forward their `_defaultXxxOptions`\n * constant here.\n */\n constructor(options?: CheckboxMenuRowOptions, subclassDefaults?: Partial<CheckboxMenuRowOptions>) {\n super(options, subclassDefaults);\n\n // `text` / `checked` are read from the raw constructor argument, not\n // `this._options`: neither field has a matching setter for\n // `applyOptions` to dispatch through (there is no live `setText`, and\n // `setChecked` below writes straight to `_checkbox`, which cannot\n // exist yet during the `super()` cascade), so `this._options` is\n // never populated for them — `_checkbox` itself is the state cache\n // for `checked` from this point on.\n this._checkbox = new Checkbox({\n label: options?.text ?? \"\",\n selected: options?.checked ?? false,\n enabled: options?.enabled ?? true,\n });\n // Pointer-inert child so a click anywhere in the row hits the row\n // element and toggles — the same arrangement MenuItem uses for its\n // five labels and SelectableListRow uses for its renderer. The row's\n // own `click` listener is exact-target, so the Checkbox's internal\n // synthetic click (fired from setSelected on its own element) cannot\n // re-enter it.\n this._checkbox.setPointerEvents(\"none\");\n this.addComponent(this._checkbox);\n\n if (options?.enabled === false) {\n // Pointer-inert, not merely guarded: a consumer's `on(\"action\", …)`\n // handler is a second click listener on this row, which no guard\n // inside `activate()` can suppress. Keeping the click off the row\n // is what makes a disabled row truly non-interactive.\n this.setPointerEvents(\"none\");\n this.setOpacity(DISABLED_OPACITY);\n }\n\n this._onMouseOver = () => {\n this.setFocused(true);\n };\n\n this._onMouseOut = () => {\n this.setFocused(false);\n };\n\n this._onClick = () => {\n this.activate();\n };\n\n Event.addListener(this, \"mouseover\", this._onMouseOver);\n Event.addListener(this, \"mouseout\", this._onMouseOut);\n Event.addListener(this, \"click\", this._onClick);\n\n this.applyListeners(options?.listeners);\n }\n\n /**\n * Returns the row's current checked state.\n *\n * @returns Whether the checkbox is currently checked.\n */\n isChecked(): boolean {\n return this._checkbox.isSelected();\n }\n\n /**\n * Sets the checked state.\n *\n * @param value - `true` to check, `false` to uncheck.\n * @returns This row, for method chaining.\n */\n setChecked(value: boolean): this {\n this._checkbox.setSelected(value);\n\n return this;\n }\n\n /**\n * Returns `true` — a `CheckboxMenuRow` behaves like a menu item, so the\n * menu's roving highlight lands on it and Enter activates it.\n *\n * @returns `true`.\n */\n isNavigable(): boolean {\n return true;\n }\n\n /**\n * Overrides {@link MenuRow.isEnabled}, reading the inner `Checkbox`'s\n * own enabled state — the cache for this row's `enabled` option, just as\n * it already is for `checked`.\n *\n * @returns Whether this row is interactive.\n */\n isEnabled(): boolean {\n return this._checkbox.isEnabled();\n }\n\n /**\n * Flips the checkbox. Called by a click on the row or by\n * `Menu.activateFocused()` on Enter. A no-op when the row is disabled.\n */\n activate(): void {\n if (!this.isEnabled()) {\n return;\n }\n\n this.setChecked(!this.isChecked());\n }\n\n /**\n * Returns the row's own content width — the checkbox's natural width\n * plus right padding, excluding any left inset of its own (`Menu` adds\n * the shared `iconStart` uniformly; see {@link MenuRow.getContentWidth}).\n * Read by `Menu.layOutColumns` **before** {@link setColumns} runs, so\n * this must never depend on the injected `iconStart` value itself.\n *\n * @returns The row's preferred content width in pixels.\n */\n getContentWidth(): number {\n const width = Math.ceil(this._checkbox.getPreferredSize()?.width ?? 0);\n\n return width + MenuItem.RIGHT_PAD;\n }\n\n /**\n * Stores the menu-computed left offset so the checkbox lines up with the\n * `MenuItem`s around it. `titleColumn` is unused — this row has no shared\n * title column of its own.\n *\n * @param checkZone - Width reserved for the menu's leading checkmark column.\n * @param iconStart - The left offset (in pixels) to align the checkbox to.\n * @param _titleColumn - Unused.\n */\n setColumns(checkZone: number, iconStart: number, _titleColumn: number): void {\n this._checkZone = checkZone;\n this._iconStart = iconStart;\n this.scheduleLayout();\n }\n\n /**\n * Positions the checkbox within the row's content box, vertically\n * centred, at the injected `iconStart` (or `MenuItem.TEXT_INSET` when\n * this row was never given one).\n *\n * When a sibling row reserves an icon column, `iconStart` is pushed out\n * to align with icon rows' *title text* — past their icon — which would\n * otherwise indent this row's checkbox behind an icon-sized gap of empty\n * space. Aligning with the icon's own position instead (`checkZone + 4`,\n * matching {@link MenuItem}'s icon inset) keeps the checkbox flush with\n * where a sibling's icon renders, since the checkbox plays the same\n * visual role. With no icon column, `iconStart` already collapses to\n * `checkZone + MenuItem.TEXT_INSET`, so this leaves a plain\n * checkbox-only menu's layout unchanged.\n *\n * @returns This row, for method chaining.\n */\n doLayout(): this {\n super.doLayout();\n\n const box = this.getContentBounds();\n\n if (!box) {\n return this;\n }\n\n const size = this._checkbox.getPreferredSize() ?? { width: 0, height: 0 };\n const checkZone = this._checkZone ?? 0;\n const iconColumnReserved = this._iconStart !== null && this._iconStart - checkZone === MenuItem.ICON_ZONE;\n const left = iconColumnReserved ? checkZone + 4 : (this._iconStart ?? MenuItem.TEXT_INSET);\n const top = Math.max(0, Math.floor((box.height - size.height) / 2));\n\n this._checkbox.setX(box.x + left);\n this._checkbox.setY(box.y + top);\n this._checkbox.setWidth(Math.max(0, box.width - left - MenuItem.RIGHT_PAD));\n this._checkbox.setHeight(size.height);\n\n return this;\n }\n\n /**\n * Registers a listener for this row's `\"action\"` event — fired after\n * each toggle (click or {@link activate}). A typed semantic shorthand\n * over {@link Event.addListener} (the underlying DOM event is `\"click\"`).\n *\n * @param event - The event name. Only `\"action\"` is accepted.\n * @param listener - The callback to invoke after each toggle.\n * @returns This row, for method chaining.\n */\n on(event: \"action\", listener: () => void): this;\n on(_event: \"action\", listener: () => void): this {\n Event.addListener(this, \"click\", listener);\n\n return this;\n }\n\n /**\n * Removes a previously registered `\"action\"` listener.\n *\n * @param event - The event the listener was registered for.\n * @param listener - The callback to remove.\n * @returns This row, for method chaining.\n */\n off(event: \"action\", listener: () => void): this;\n off(_event: \"action\", listener: () => void): this {\n Event.removeListener(this, \"click\", listener);\n\n return this;\n }\n}\n\nconst CheckboxMenuRowCallable = callable(CheckboxMenuRow);\ntype CheckboxMenuRowCallable = CheckboxMenuRow;\nexport {\n CheckboxMenuRow as _CheckboxMenuRow,\n CheckboxMenuRowCallable as CheckboxMenuRow\n};\n"],"mappings":"uTAaA,IAAM,EAAW,IAAI,QAUrB,SAAS,uBAAuB,EAAqC,CACjE,GAAI,EAAa,CAAC,EACd,MAAO,CAAE,QAAS,EAAK,CAE/B,CAkBA,SAAgB,UAAU,EAA4B,CAC9C,EAAS,IAAI,CAAS,IAI1B,EAAS,IAAI,CAAS,EACtB,EAAM,mBAAmB,EAAW,QAAS,CAAE,QAAS,GAAO,QAAS,sBAAuB,CAAC,EACpG,CAQA,SAAgB,YAAY,EAA4B,CAC/C,EAAS,IAAI,CAAS,IAI3B,EAAS,OAAO,CAAS,EACzB,EAAM,sBAAsB,EAAW,QAAS,sBAAsB,EAC1E,CCjDA,IAAM,EAAU,EAAa,KAAK,OAAS,EAarC,aAAN,cAA2B,CAAU,CAEjC,OAA0B,GAM1B,aAAc,CACV,MAAM,EAEN,KAAK,YAAY,EAAS,QAAQ,EAClC,KAAK,UAAU,CAAO,EACtB,KAAK,iBAAiB,MAAM,EAE5B,KAAK,qBAAqB,CAC9B,CAQA,SAAmB,CACf,OAAO,KAAK,MAChB,CASA,SAAS,EAAsB,CACvB,KAAK,SAAW,IAIpB,KAAK,OAAS,EAEd,KAAK,qBAAqB,EAC9B,CAeA,SAAS,EAAmB,EAAwB,CAChD,IAAM,EAAO,KAAK,WAAW,EAAI,EAEjC,GAAI,GAAQ,IAAS,EAAQ,CAEzB,KAAK,KAAK,EAAO,KAAK,CAAC,EACvB,KAAK,KAAK,EAAO,KAAK,CAAC,EACvB,KAAK,SAAS,EAAO,SAAS,CAAC,EAC/B,KAAK,UAAU,EAAO,UAAU,CAAC,EAEjC,IAAM,EAAS,EAAK,WAAW,EAAI,EAC/B,EAAI,OAAO,iBAAiB,CAAI,IAAM,GACtC,EAAI,KAAK,YAAY,EAAQ,CAAI,EAGrC,MACJ,CAGA,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,CAAC,EACX,KAAK,SAAS,EAAO,SAAS,CAAC,EAC/B,KAAK,UAAU,EAAO,UAAU,CAAC,EAEjC,IAAM,EAAW,EAAO,WAAW,EAAI,EACnC,EAAI,OAAO,iBAAiB,CAAI,IAAM,GACtC,EAAI,KAAK,YAAY,EAAU,CAAI,CAE3C,CAKA,QAAe,CACX,KAAK,cAAc,CACvB,CAOA,sBAAqC,CACjC,IAAM,EAAS,KAAK,OAAS,QAAU,UAEvC,KAAK,mBAAmB,6BAA6B,EAAO,KAAK,EACjE,KAAK,UAAU,CAAE,OAAQ,uCAAuC,EAAO,SAAU,CAAC,CACtF,CACJ,EAEM,EAAuB,EAAS,YAAY,EC3H5C,EAAU,MAMV,EAAgB,IAGhB,EAAiB,GAMjB,EAAc,EAed,UAAN,cAAwB,CAAU,CAE9B,OAA8B,KAW9B,YAAY,EAAgB,EAAgB,EAAiB,CACzD,MAAM,EAEN,KAAK,YAAY,EAAS,KAAK,EAC/B,KAAK,UAAU,CAAO,EACtB,KAAK,iBAAiB,MAAM,EAC5B,KAAK,SAAS,GAAS,CAAa,EACpC,KAAK,UAAU,GAAU,CAAc,EAEvC,KAAK,mBAAmB,4BAA4B,EACpD,KAAK,UAAU,CAAE,OAAQ,0CAA2C,CAAC,EACrE,KAAK,UAAU,gCAAgC,EAC/C,KAAK,gBAAgB,iCAAiC,EACtD,KAAK,WAAW,GAAc,EAE1B,IAAU,IAAA,KACV,KAAK,OAAS,IAAI,EAAK,CAAK,EAC5B,KAAK,OAAO,iBAAiB,MAAM,EACnC,KAAK,aAAa,KAAK,MAAM,EAErC,CAUA,OAAO,EAAiB,EAAuB,CAC3C,KAAK,KAAK,CAAO,EACjB,KAAK,KAAK,CAAO,CACrB,CAMA,MAAa,CACT,IAAM,EAAK,KAAK,WAAW,EAAI,EAE/B,KAAK,eAAe,EACpB,EAAI,KAAK,YAAY,EAAI,OAAO,mBAAmB,EAAG,CAAE,CAC5D,CAMA,MAAa,CACT,KAAK,cAAc,CACvB,CAOA,UAAiB,CACb,MAAM,SAAS,EAEf,IAAM,EAAM,KAAK,iBAAiB,EASlC,OAPI,KAAK,QAAU,IACf,KAAK,OAAO,KAAK,EAAI,EAAI,CAAW,EACpC,KAAK,OAAO,KAAK,EAAI,EAAI,CAAW,EACpC,KAAK,OAAO,SAAS,EAAI,MAAQ,EAAe,EAChD,KAAK,OAAO,UAAU,EAAI,OAAS,EAAe,GAG/C,IACX,CACJ,EAEM,EAAoB,EAAS,SAAS,ECvHtC,EAAU,EAAa,KAAK,OAAS,EAGrC,EAAa,EAMb,EAAW,EAgBX,iBAAN,cAA+B,CAAU,CAMrC,aAAc,CACV,MAAM,EAEN,KAAK,YAAY,EAAS,QAAQ,EAClC,KAAK,UAAU,CAAO,EACtB,KAAK,iBAAiB,MAAM,EAC5B,KAAK,UAAU,CAAU,EAEzB,KAAK,mBAAmB,iCAAiC,CAC7D,CAQA,cAAc,EAAiB,CAC3B,KAAK,KAAK,EAAI,CAAQ,CAC1B,CASA,SAAS,EAAyB,CAC9B,IAAM,EAAW,EAAO,WAAW,EAAI,EACjC,EAAW,KAAK,WAAW,EAAI,EAErC,KAAK,KAAK,CAAC,EACX,KAAK,SAAS,EAAO,SAAS,CAAC,EAE3B,EAAI,OAAO,iBAAiB,CAAI,IAAM,GAI1C,EAAI,KAAK,YAAY,EAAU,CAAI,CACvC,CAKA,QAAe,CACX,KAAK,cAAc,CACvB,CACJ,EAEM,EAA2B,EAAS,gBAAgB,EC/B7C,EAA0C,IAAI,IAe9C,EAAwB,IA8G/B,EAAiB,GACjB,EAAiB,GAEjB,EAAc,IAAI,IAClB,EAAc,IAAI,IACpB,EAAoC,KA6BvB,GAAV,SAAA,EAAA,CAaI,SAAS,eAAe,EAAsB,EAAwC,CAIzF,OAHA,EAAY,IAAI,EAAU,MAAM,EAAG,CAAE,YAAW,SAAQ,CAAC,EACzD,EAAU,4BAA4B,iBAAiB,EAEhD,mBAAmB,KAAK,KAAM,CAAS,CAClD,iCAYO,SAAS,eAAe,EAAsB,EAAwC,CAGzF,OAFA,EAAY,IAAI,EAAU,MAAM,EAAG,CAAE,YAAW,SAAQ,CAAC,EAElD,mBAAmB,KAAK,KAAM,CAAS,CAClD,iCAQO,SAAS,YAAsB,CAClC,OAAO,IAAkB,MAAQ,EAAc,SACnD,yBAMO,SAAS,QAAe,CACvB,IAAkB,MAItB,WAAW,GAAO,EAAG,CAAC,CAC1B,gBACH,EAAA,CAAA,AAAA,IAAA,CAAA,CAAD,EAOA,SAAS,gBAAgB,EAAsC,CAC3D,OAAO,OAAO,EAAQ,UAAa,WAAa,EAAQ,SAAS,EAAI,EAAQ,QACjF,CAOA,SAAS,mBAAmB,EAA4B,CACpD,EAAU,+BAA+B,iBAAiB,EAC1D,EAAY,OAAO,EAAU,MAAM,CAAC,CACxC,CAOA,SAAS,mBAAmB,EAA4B,CACpD,EAAY,OAAO,EAAU,MAAM,CAAC,CACxC,CAaA,SAAS,kBAAmC,EAAqB,CAK7D,GAJI,IAAkB,MAIlB,EAAE,SAAW,EACb,OAGJ,IAAM,EAAS,EAAY,IAAI,KAAK,MAAM,CAAC,EAE3C,GAAI,CAAC,EACD,OAGJ,IAAM,EAAU,EAAO,UACjB,EAAU,EAAO,QAEvB,EAAgB,CACZ,SACA,cAAe,EACf,SAAe,gBAAgB,CAAO,EACtC,OAAe,EAAE,QACjB,OAAe,EAAE,QACjB,UAAe,GACf,MAAe,KACf,SAAe,KACf,UAAe,KACf,cAAe,KACf,mBAAoB,EAAI,OAAO,eAAe,EAAI,OAAO,QAAQ,EAAG,QAAQ,CAChF,EAOA,EAAM,oBAAoB,EAAQ,YAAe,WAAW,EAC5D,EAAM,oBAAoB,EAAQ,UAAe,SAAS,EAC1D,EAAM,oBAAoB,EAAQ,cAAe,aAAa,CAClE,CAOA,SAAS,cAAc,EAA4B,CAC/C,EAAQ,UAAY,GAEpB,IAAM,EAAQ,EAAQ,cAAc,aAC9B,EAAQ,cAAc,aAAa,EAAQ,OAAQ,EAAQ,QAAQ,EACnE,IAAI,EAMV,GAJA,EAAQ,MAAY,EACpB,EAAQ,SAAY,IAAI,EACxB,EAAQ,UAAY,IAAI,EAEpB,OAAQ,EAA2C,MAAS,WAC5D,EAA2C,KAAK,MAC7C,CACH,IAAM,EAAK,EAAM,WAAW,EAAI,EAEhC,EAAI,KAAK,YAAY,EAAI,OAAO,mBAAmB,EAAG,CAAE,CAC5D,CAEI,EAAQ,cAAc,QACtB,EAAI,KAAK,MAAM,EAAI,OAAO,QAAQ,EAAG,CAAE,MAAO,CAAE,OAAQ,EAAQ,cAAc,MAAO,CAAE,CAAC,CAEhG,CAMA,SAAS,YAAY,EAAsB,EAAiB,EAAkC,CAC1F,MAAO,CACH,SAAU,EAAQ,SAClB,SAAU,EAAQ,OAAO,MAAM,EAC/B,UACA,SACJ,CACJ,CAOA,SAAS,eAAe,EAAiB,EAA0C,CAC/E,IAAM,EAAQ,EAAI,OAAO,kBAAkB,EAAS,CAAO,EAE3D,IAAK,IAAM,KAAM,EAAO,CACpB,IAAM,EAAS,EAAY,IAAI,EAAI,OAAO,MAAM,CAAE,CAAC,EAEnD,GAAI,EACA,OAAO,CAEf,CAEA,OAAO,IACX,CAMA,SAAS,mBAAmB,EAAsB,EAA+B,CAC7E,GAAI,EAAQ,gBAAkB,KAC1B,OAGJ,IAAM,EAAO,EAAY,IAAI,EAAQ,cAAc,MAAM,CAAC,EAEtD,GAAQ,EAAK,QAAQ,aACrB,EAAK,QAAQ,YAAY,CAAM,EAG/B,EAAQ,UACR,EAAQ,SAAS,OAAO,EAGxB,EAAQ,WACR,EAAQ,UAAU,OAAO,EAG7B,EAAQ,cAAgB,IAC5B,CAOA,SAAS,eAAe,EAAsB,EAA0B,EAA+B,CACnG,IAAM,EAAW,EAAO,QAAQ,QAAQ,CAAM,EAO9C,GALI,EAAQ,UAAY,CAAC,EAAO,QAAQ,uBACpC,EAAQ,SAAS,SAAS,CAAQ,EAClC,EAAQ,SAAS,SAAS,EAAO,UAAW,EAAO,QAAQ,YAAY,GAGvE,CAAC,EAAU,CACX,EAAQ,cAAgB,EAAO,UAE/B,MACJ,CAEA,IAAM,EAAO,EAAO,QAAQ,aAAa,CAAM,EAE3C,OAAO,GAAS,UAAY,EAAQ,WACpC,EAAQ,UAAU,SAAS,EAAO,SAAS,EAC3C,EAAQ,UAAU,cAAc,CAAI,GAC7B,EAAQ,WACf,EAAQ,UAAU,OAAO,EAG7B,EAAQ,cAAgB,EAAO,SACnC,CAmBA,SAAS,eAAsC,CAC3C,MAAO,CAAE,KAAM,GAAM,QAAS,EAAK,CACvC,CAWA,SAAS,YAAY,EAAqC,CACtD,GAAI,IAAkB,KAClB,OAGJ,IAAM,EAAU,EAEhB,GAAI,CAAC,EAAQ,UAAW,CACpB,IAAM,EAAK,EAAE,QAAU,EAAQ,OACzB,EAAK,EAAE,QAAU,EAAQ,OAE/B,GAAI,EAAK,EAAK,EAAK,EAAK,GACpB,MAAO,CAAE,KAAM,GAAM,QAAS,EAAK,EAGvC,IAAM,EAAc,YAAY,EAAS,EAAE,QAAS,EAAE,OAAO,EAE7D,GAAI,EAAQ,cAAc,cAAc,CAAW,IAAM,GAGrD,OAFA,WAAW,GAAO,EAAE,QAAS,EAAE,OAAO,EAE/B,CAAE,KAAM,GAAM,QAAS,EAAK,EAGvC,cAAc,CAAO,EACrB,EAAM,UAAU,EAAQ,OAAQ,YAAa,CAAE,OAAQ,CAAY,CAAC,CACxE,CAEA,GAAI,EAAQ,MAAO,CACf,IAAM,EAAY,EAAQ,MAEtB,OAAO,EAAU,QAAW,WAC5B,EAAU,OAAO,EAAE,QAAU,EAAgB,EAAE,QAAU,CAAc,GAEvE,EAAQ,MAAM,KAAK,EAAE,QAAU,CAAc,EAC7C,EAAQ,MAAM,KAAK,EAAE,QAAU,CAAc,EAErD,CAEA,IAAM,EAAS,YAAY,EAAS,EAAE,QAAS,EAAE,OAAO,EAClD,EAAS,eAAe,EAAE,QAAS,EAAE,OAAO,EAElD,GAAI,IAAW,KAGX,OAFA,mBAAmB,EAAS,CAAM,EAE3B,CAAE,KAAM,GAAM,QAAS,EAAK,EAGvC,GAAI,EAAQ,gBAAkB,EAAO,UAIjC,OAHA,mBAAmB,EAAS,CAAM,EAClC,eAAe,EAAS,EAAQ,CAAM,EAE/B,CAAE,KAAM,GAAM,QAAS,EAAK,EASvC,IAAM,EAAW,EAAO,QAAQ,QAAQ,CAAM,EAM9C,GAJI,EAAQ,UAAY,CAAC,EAAO,QAAQ,sBACpC,EAAQ,SAAS,SAAS,CAAQ,EAGlC,CAAC,EAKD,OAJI,EAAQ,WACR,EAAQ,UAAU,OAAO,EAGtB,CAAE,KAAM,GAAM,QAAS,EAAK,EAGvC,IAAM,EAAO,EAAO,QAAQ,aAAa,CAAM,EAS/C,OAPI,OAAO,GAAS,UAAY,EAAQ,WACpC,EAAQ,UAAU,SAAS,EAAO,SAAS,EAC3C,EAAQ,UAAU,cAAc,CAAI,GAC7B,EAAQ,WACf,EAAQ,UAAU,OAAO,EAGtB,CAAE,KAAM,GAAM,QAAS,EAAK,CACvC,CAQA,SAAS,UAAU,EAAqC,CACpD,GAAI,IAAkB,KAClB,OAGJ,IAAM,EAAU,EACV,EAAU,YAAY,EAAS,EAAE,QAAS,EAAE,OAAO,EACrD,EAAY,GAEhB,GAAI,EAAQ,WAAa,EAAQ,gBAAkB,KAAM,CACrD,IAAM,EAAS,EAAY,IAAI,EAAQ,cAAc,MAAM,CAAC,EAExD,IAOI,EAAO,QAAQ,QAAQ,CAAM,GACR,EAAO,QAAQ,SAAS,CAAM,IAE9B,IACjB,EAAM,UAAU,EAAQ,OAAQ,OAAQ,CAAE,QAAO,CAAC,EAI1D,EAAU,GAElB,CAIA,OAFA,WAAW,EAAS,EAAE,QAAS,EAAE,OAAO,EAEjC,EACX,CAMA,SAAS,WAAW,EAAkB,EAAiB,EAAuB,CAC1E,GAAI,IAAkB,KAClB,OAGJ,IAAM,EAAU,EAqBhB,GAnBA,EAAM,uBAAuB,EAAQ,OAAQ,YAAe,WAAW,EACvE,EAAM,uBAAuB,EAAQ,OAAQ,UAAe,SAAS,EACrE,EAAM,uBAAuB,EAAQ,OAAQ,cAAe,aAAa,EASrE,EAAQ,UACR,EAAQ,SAAS,QAAQ,EAGzB,EAAQ,WACR,EAAQ,UAAU,QAAQ,EAG1B,EAAQ,MAAO,CACf,GAAI,EAAQ,cAAc,aAAc,CAIpC,IAAM,EAAY,EAAQ,MAEtB,OAAO,EAAU,MAAS,WAC1B,EAAU,KAAK,EAEf,EAAQ,MAAM,cAAc,CAEpC,MACI,EAAQ,MAAM,QAAQ,CAE9B,CAMA,GAJI,EAAQ,cAAc,QACtB,EAAI,KAAK,MAAM,EAAI,OAAO,QAAQ,EAAG,CAAE,MAAO,CAAE,OAAQ,EAAQ,kBAAmB,CAAE,CAAC,EAGtF,EAAQ,UAAW,CACnB,IAAM,EAAS,YAAY,EAAS,EAAS,CAAO,EAEpD,EAAM,UAAU,EAAQ,OAAQ,UAAW,CAAE,QAAO,CAAC,EACrD,EAAQ,cAAc,YAAY,EAAQ,CAAO,CACrD,CAEA,EAAgB,IACpB,CC7qBA,IAAM,EAAmB,GAgCnB,gBAAN,cAA8B,CAAgC,CAE1D,UAGA,WAAoC,KAIpC,WAAoC,KAEpC,aACA,YACA,SAUA,YAAY,EAAkC,EAAoD,CAC9F,MAAM,EAAS,CAAgB,EAS/B,KAAK,UAAY,IAAI,EAAS,CAC1B,MAAU,GAAS,MAAQ,GAC3B,SAAU,GAAS,SAAW,GAC9B,QAAU,GAAS,SAAW,EAClC,CAAC,EAOD,KAAK,UAAU,iBAAiB,MAAM,EACtC,KAAK,aAAa,KAAK,SAAS,EAE5B,GAAS,UAAY,KAKrB,KAAK,iBAAiB,MAAM,EAC5B,KAAK,WAAW,CAAgB,GAGpC,KAAK,iBAAqB,CACtB,KAAK,WAAW,EAAI,CACxB,EAEA,KAAK,gBAAoB,CACrB,KAAK,WAAW,EAAK,CACzB,EAEA,KAAK,aAAiB,CAClB,KAAK,SAAS,CAClB,EAEA,EAAM,YAAY,KAAM,YAAa,KAAK,YAAY,EACtD,EAAM,YAAY,KAAM,WAAY,KAAK,WAAW,EACpD,EAAM,YAAY,KAAM,QAAS,KAAK,QAAQ,EAE9C,KAAK,eAAe,GAAS,SAAS,CAC1C,CAOA,WAAqB,CACjB,OAAO,KAAK,UAAU,WAAW,CACrC,CAQA,WAAW,EAAsB,CAG7B,OAFA,KAAK,UAAU,YAAY,CAAK,EAEzB,IACX,CAQA,aAAuB,CACnB,MAAO,EACX,CASA,WAAqB,CACjB,OAAO,KAAK,UAAU,UAAU,CACpC,CAMA,UAAiB,CACR,KAAK,UAAU,GAIpB,KAAK,WAAW,CAAC,KAAK,UAAU,CAAC,CACrC,CAWA,iBAA0B,CAGtB,OAFc,KAAK,KAAK,KAAK,UAAU,iBAAiB,CAAC,EAAE,OAAS,CAE7D,EAAQ,EAAS,SAC5B,CAWA,WAAW,EAAmB,EAAmB,EAA4B,CACzE,KAAK,WAAa,EAClB,KAAK,WAAa,EAClB,KAAK,eAAe,CACxB,CAmBA,UAAiB,CACb,MAAM,SAAS,EAEf,IAAM,EAAM,KAAK,iBAAiB,EAElC,GAAI,CAAC,EACD,OAAO,KAGX,IAAM,EAAO,KAAK,UAAU,iBAAiB,GAAK,CAAE,MAAO,EAAG,OAAQ,CAAE,EAClE,EAAsB,KAAK,YAAc,EAEzC,EADsB,KAAK,aAAe,MAAQ,KAAK,WAAa,IAAc,EAAS,UAC/D,EAAY,EAAK,KAAK,YAAc,EAAS,WACzE,EAAO,KAAK,IAAI,EAAG,KAAK,OAAO,EAAI,OAAS,EAAK,QAAU,CAAC,CAAC,EAOnE,OALA,KAAK,UAAU,KAAK,EAAI,EAAI,CAAI,EAChC,KAAK,UAAU,KAAK,EAAI,EAAI,CAAG,EAC/B,KAAK,UAAU,SAAS,KAAK,IAAI,EAAG,EAAI,MAAQ,EAAO,EAAS,SAAS,CAAC,EAC1E,KAAK,UAAU,UAAU,EAAK,MAAM,EAE7B,IACX,CAYA,GAAG,EAAkB,EAA4B,CAG7C,OAFA,EAAM,YAAY,KAAM,QAAS,CAAQ,EAElC,IACX,CAUA,IAAI,EAAkB,EAA4B,CAG9C,OAFA,EAAM,eAAe,KAAM,QAAS,CAAQ,EAErC,IACX,CACJ,EAEM,EAA0B,EAAS,eAAe"}
|
|
1
|
+
{"version":3,"file":"CheckboxMenuRow-C1h4LPHR.js","names":[],"sources":["../../src/typescript/lib/core/WheelTrap.ts","../../src/typescript/lib/overlay/DragFeedback.ts","../../src/typescript/lib/overlay/DragGhost.ts","../../src/typescript/lib/overlay/ReorderIndicator.ts","../../src/typescript/lib/overlay/DragManager.ts","../../src/typescript/lib/component/container/CheckboxMenuRow.ts"],"sourcesContent":["// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport type { Component } from \"~/core/Component.js\";\nimport { Event } from \"~/core/Event.js\";\nimport { consumeWheel } from \"~/core/SmoothScroller.js\";\n\n/**\n * Components that currently have the wheel trap installed. Used purely for\n * idempotency — the listener itself ({@link swallowUnconsumedWheel}) captures\n * nothing per component, so one shared reference serves every overlay. Keyed\n * weakly, mirroring how the layer registry keys per-layer state, so a closed\n * overlay's entry is collectable without an explicit purge.\n */\nconst _trapped = new WeakSet<Component>();\n\n/**\n * Subtree `wheel` handler shared by every trapped overlay: claims the event via\n * the framework's wheel once-marker and, when the claim succeeds (no inner\n * scroller took it first), `preventDefault()`s it so the native wheel never\n * reaches a scrollable ancestor behind the overlay.\n *\n * @param e - The wheel event reaching the overlay as the outermost ancestor.\n */\nfunction swallowUnconsumedWheel(e: WheelEvent): Event.ListenerResult {\n if (consumeWheel(e)) {\n return { prevent: true };\n }\n}\n\n/**\n * Registers a non-passive subtree `wheel` listener on `component` that\n * `preventDefault()`s any wheel the event reaches it unconsumed — trapping\n * wheels an inner scroller did not claim so they cannot fall through to content\n * behind a floating overlay. Idempotent per component.\n *\n * @param component - The overlay to install the trap on. Must already be mounted,\n * since the subtree listener resolves the component's element.\n *\n * @remarks Subtree events dispatch descendant-first, so any inner scroll\n * container under the pointer claims the wheel first and the overlay's handler,\n * firing last as the outermost ancestor, sees it already consumed and does\n * nothing — inner scroll proceeds untouched. The listener is `{ passive: false }`\n * to match the only other `wheel` registration (the inner scroll pipeline) and\n * because `preventDefault()` is a no-op on a passive listener.\n */\nexport function trapWheel(component: Component): void {\n if (_trapped.has(component)) {\n return;\n }\n\n _trapped.add(component);\n Event.addSubtreeListener(component, \"wheel\", { passive: false, handler: swallowUnconsumedWheel });\n}\n\n/**\n * Removes the trap installed by {@link trapWheel}. Safe to call when none was\n * installed.\n *\n * @param component - The overlay whose trap should be removed.\n */\nexport function untrapWheel(component: Component): void {\n if (!_trapped.has(component)) {\n return;\n }\n\n _trapped.delete(component);\n Event.removeSubtreeListener(component, \"wheel\", swallowUnconsumedWheel);\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport { Position } from \"~/primitive/Position.js\";\nimport { callable } from \"~/core/Callable.js\";\nimport { LayerManager } from \"~/core/LayerManager.js\";\nimport { DOM } from \"~/core/DOM.js\";\n\n/**\n * Z-order for the drop-target validity tint. The tint highlights a drop target,\n * which lives in ordinary app content — so it must sit **below** the lowest\n * {@link LayerManager} band (the {@link Window} band) or it paints over a\n * floating window, while still sitting above the target's own content (app\n * z-indexes top out near 3). The app tree establishes no isolating stacking\n * context, so a higher value escapes to the root context and beats windows —\n * which is exactly the bug `Band.Window - 1` avoids. Shared rationale with\n * {@link ReorderIndicator}; the drag ghost sits above both at the root.\n */\nconst Z_INDEX = LayerManager.Band.Window - 1;\n\n/**\n * A validity tint overlay drawn on top of the row currently being hovered\n * during an active drag. The colour swaps between the `valid` and\n * `invalid` theme tokens via {@link setValid}; the geometry is mirrored\n * onto a drop target via {@link attachTo}.\n *\n * Owned by [`DragManager`](/api/overlay/variables/DragManager) — application\n * code does not instantiate this directly.\n *\n * @category Core\n */\nclass DragFeedback extends Component {\n\n private _valid: boolean = true;\n\n /**\n * Constructs a drag-feedback overlay. The overlay is not attached\n * until {@link attachTo} is called.\n */\n constructor() {\n super();\n\n this.setPosition(Position.ABSOLUTE);\n this.setZIndex(Z_INDEX);\n this.setPointerEvents(\"none\");\n\n this.applyTintForValidity();\n }\n\n /**\n * Returns whether the overlay is currently showing the \"valid drop\"\n * tint.\n *\n * @returns `true` for the valid tint, `false` for the invalid tint.\n */\n isValid(): boolean {\n return this._valid;\n }\n\n /**\n * Switches the overlay between the `valid` and `invalid` theme\n * tokens. Idempotent — repeated calls with the same value are a\n * no-op.\n *\n * @param valid - `true` to show the valid tint, `false` for invalid.\n */\n setValid(valid: boolean): void {\n if (this._valid === valid) {\n return;\n }\n\n this._valid = valid;\n\n this.applyTintForValidity();\n }\n\n /**\n * Sizes this overlay to cover the drop target and appends it to the DOM.\n *\n * With no `host`, the tint is a child of the target, covering its body. When\n * a `host` is given, the tint instead lives in that (non-scrolling) layer,\n * sized to the target's box within it — so a target that scrolls its own\n * content (a Tab strip's clip frame) gets a tint over the *viewport* that\n * stays put instead of riding the scroll.\n *\n * @param target - The drop target whose box the tint should cover.\n * @param host - Optional non-scrolling layer to host the tint (see\n * {@link DropTargetOptions.feedbackHost}). Defaults to the target.\n */\n attachTo(target: Component, host?: Component): void {\n const myEl = this.getElement(true)!;\n\n if (host && host !== target) {\n // Overlay the target's box from within the host layer.\n this.setX(target.getX());\n this.setY(target.getY());\n this.setWidth(target.getWidth());\n this.setHeight(target.getHeight());\n\n const hostEl = host.getElement(true)!;\n if (DOM.source.getParentElement(myEl) !== hostEl) {\n DOM.sink.appendChild(hostEl, myEl);\n }\n\n return;\n }\n\n // Cover the target's own body as a child of it.\n this.setX(0);\n this.setY(0);\n this.setWidth(target.getWidth());\n this.setHeight(target.getHeight());\n\n const targetEl = target.getElement(true)!;\n if (DOM.source.getParentElement(myEl) !== targetEl) {\n DOM.sink.appendChild(targetEl, myEl);\n }\n }\n\n /**\n * Removes the overlay element from the DOM.\n */\n detach(): void {\n this.removeElement();\n }\n\n /**\n * Writes the background and border CSS variables that correspond to\n * the cached validity state. Called from the constructor and from\n * {@link setValid} on transitions.\n */\n private applyTintForValidity(): void {\n const suffix = this._valid ? \"valid\" : \"invalid\";\n\n this.setBackgroundColor(`var(--ts-ui-drag-feedback-${suffix}-bg)`);\n this.setBorder({ border: `2px solid var(--ts-ui-drag-feedback-${suffix}-border)` });\n }\n}\n\nconst DragFeedbackCallable = callable(DragFeedback);\ntype DragFeedbackCallable = DragFeedback;\nexport {\n DragFeedback as _DragFeedback,\n DragFeedbackCallable as DragFeedback,\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport { Position } from \"~/primitive/Position.js\";\nimport { Text } from \"~/component/input/Text.js\";\nimport { callable } from \"~/core/Callable.js\";\nimport { DOM } from \"~/core/DOM.js\";\n\n/**\n * Z-order ceiling for the drag ghost. The follow-the-cursor preview rides above\n * everything during a drag — appended at the document root, above the\n * LayerManager bands — so it is never occluded by a floating window or by the\n * per-target highlights ([`DragFeedback`](/api/overlay/classes/DragFeedback) /\n * [`ReorderIndicator`](/api/overlay/classes/ReorderIndicator)), which deliberately\n * sit *below* the window band instead.\n */\nconst Z_INDEX = 10200;\n\n/**\n * Default ghost width when the caller omits an explicit size. Picked to\n * comfortably surround a one-line label without measuring text.\n */\nconst DEFAULT_WIDTH = 160;\n\n/** Default ghost height — one row's worth of vertical room. */\nconst DEFAULT_HEIGHT = 28;\n\n/**\n * Inner padding around the optional ghost label so text doesn't crowd the\n * border at the framework's default font size.\n */\nconst LABEL_INSET = 6;\n\n/**\n * A floating drag preview that follows the pointer during an active drag\n * session, drawn above every other overlay. Created and owned by\n * [`DragManager`](/api/overlay/variables/DragManager); application code does\n * not instantiate this directly.\n *\n * The ghost is `Position.FIXED` (one of the documented overlay carve-outs\n * in `ARCHITECTURE.md` §Positioning) and renders with\n * `pointer-events: none` so the manager's\n * `document.elementsFromPoint` hit-test always returns the row underneath.\n *\n * @category Core\n */\nclass DragGhost extends Component {\n\n private _label: Text | null = null;\n\n /**\n * Constructs a drag ghost. The caller positions it via\n * {@link moveTo} and toggles visibility through {@link show} /\n * {@link hide}.\n *\n * @param label - Optional text drawn inside the ghost.\n * @param width - Optional width in pixels (defaults to 160).\n * @param height - Optional height in pixels (defaults to 28).\n */\n constructor(label?: string, width?: number, height?: number) {\n super();\n\n this.setPosition(Position.FIXED);\n this.setZIndex(Z_INDEX);\n this.setPointerEvents(\"none\");\n this.setWidth(width ?? DEFAULT_WIDTH);\n this.setHeight(height ?? DEFAULT_HEIGHT);\n\n this.setBackgroundColor(\"var(--ts-ui-drag-ghost-bg)\");\n this.setBorder({ border: \"1px solid var(--ts-ui-drag-ghost-border)\" });\n this.setShadow(\"var(--ts-ui-drag-ghost-shadow)\");\n this.setBorderRadius(\"var(--ts-ui-border-radius, 4px)\");\n this.setOpacity(Number(\"0.85\"));\n\n if (label !== undefined) {\n this._label = new Text(label);\n this._label.setPointerEvents(\"none\");\n this.addComponent(this._label);\n }\n }\n\n /**\n * Repositions the ghost so its top-left corner sits at\n * `(clientX, clientY)`. `DragManager` calls this on every `mousemove`\n * during an active drag.\n *\n * @param clientX - The viewport X (already offset from the cursor by the manager).\n * @param clientY - The viewport Y (already offset from the cursor by the manager).\n */\n moveTo(clientX: number, clientY: number): void {\n this.setX(clientX);\n this.setY(clientY);\n }\n\n /**\n * Appends the ghost to `<html>` and schedules a layout pass. Used by\n * `DragManager` when a drag commits past the movement threshold.\n */\n show(): void {\n const el = this.getElement(true)!;\n\n this.scheduleLayout();\n DOM.sink.appendChild(DOM.source.getDocumentElement(), el);\n }\n\n /**\n * Removes the ghost element from the DOM. Used by `DragManager` on\n * mouseup / cancel.\n */\n hide(): void {\n this.removeElement();\n }\n\n /**\n * Lays out the optional label inside the ghost's content box.\n *\n * @returns This component, for method chaining.\n */\n doLayout(): this {\n super.doLayout();\n\n const box = this.getContentBounds();\n\n if (this._label && box) {\n this._label.setX(box.x + LABEL_INSET);\n this._label.setY(box.y + LABEL_INSET);\n this._label.setWidth(box.width - LABEL_INSET * 2);\n this._label.setHeight(box.height - LABEL_INSET * 2);\n }\n\n return this;\n }\n}\n\nconst DragGhostCallable = callable(DragGhost);\ntype DragGhostCallable = DragGhost;\nexport {\n DragGhost as _DragGhost,\n DragGhostCallable as DragGhost,\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport { Position } from \"~/primitive/Position.js\";\nimport { callable } from \"~/core/Callable.js\";\nimport { LayerManager } from \"~/core/LayerManager.js\";\nimport { DOM } from \"~/core/DOM.js\";\n\n/**\n * Z-order shared with {@link DragFeedback}: just **below** the lowest\n * {@link LayerManager} band (the {@link Window} band) so this drop-target\n * insertion line — drawn over app content that establishes no isolating\n * stacking context — never paints over a floating window, while still sitting\n * above the target's own content. The drag ghost sits above both at the root.\n */\nconst Z_INDEX = LayerManager.Band.Window - 1;\n\n/** Height of the insertion-line bar in pixels. */\nconst BAR_HEIGHT = 2;\n\n/**\n * Half the bar height — subtracted in {@link ReorderIndicator.setInsertionY}\n * so the 2 px bar is centred on the insertion line.\n */\nconst BAR_HALF = 1;\n\n/**\n * A 2 px horizontal bar drawn between rows to mark the insertion line\n * during an active drag-reorder gesture.\n *\n * Reserved for future sibling-reorder work — drop-on-directory does not\n * use this overlay. The class ships now so the public API surface and\n * theme tokens stabilise alongside\n * [`DragGhost`](/api/overlay/classes/DragGhost) and\n * [`DragFeedback`](/api/overlay/classes/DragFeedback); the row-DnD wiring\n * in [`TreeTable`](/api/component/table/classes/TreeTable) only attaches\n * the feedback tint.\n *\n * @category Core\n */\nclass ReorderIndicator extends Component {\n\n /**\n * Constructs a reorder indicator. The bar is not attached until\n * {@link attachTo} is called.\n */\n constructor() {\n super();\n\n this.setPosition(Position.ABSOLUTE);\n this.setZIndex(Z_INDEX);\n this.setPointerEvents(\"none\");\n this.setHeight(BAR_HEIGHT);\n\n this.setBackgroundColor(\"var(--ts-ui-drag-reorder-color)\");\n }\n\n /**\n * Centres the bar on the given y-coordinate within the attached\n * target. The `- BAR_HALF` shift accounts for the 2 px bar height.\n *\n * @param y - Insertion-line y, measured from the target's top edge.\n */\n setInsertionY(y: number): void {\n this.setY(y - BAR_HALF);\n }\n\n /**\n * Mirrors the target's width onto the bar and appends the bar\n * element to the target.\n *\n * @param target - The drop target whose top-left coordinate space\n * the bar is positioned within.\n */\n attachTo(target: Component): void {\n const targetEl = target.getElement(true)!;\n const myEl = this.getElement(true)!;\n\n this.setX(0);\n this.setWidth(target.getWidth());\n\n if (DOM.source.getParentElement(myEl) === targetEl) {\n return;\n }\n\n DOM.sink.appendChild(targetEl, myEl);\n }\n\n /**\n * Removes the bar element from the DOM.\n */\n detach(): void {\n this.removeElement();\n }\n}\n\nconst ReorderIndicatorCallable = callable(ReorderIndicator);\ntype ReorderIndicatorCallable = ReorderIndicator;\nexport {\n ReorderIndicator as _ReorderIndicator,\n ReorderIndicatorCallable as ReorderIndicator,\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport { DragFeedback } from \"~/overlay/DragFeedback.js\";\nimport { DragGhost } from \"~/overlay/DragGhost.js\";\nimport { Event } from \"~/core/Event.js\";\nimport { ReorderIndicator } from \"~/overlay/ReorderIndicator.js\";\nimport { DOM } from \"~/core/DOM.js\";\n\n/**\n * Arbitrary, caller-defined payload attached to a drag source — the\n * shape is consumer-domain and the manager never inspects fields.\n *\n * @category Core\n */\nexport type DragData = Record<string, unknown>;\n\n/**\n * Payload delivered to every named drag-source / drop-target callback\n * and to every fired DOM event. Field names are stable across\n * `dragstart`, `dragover`, `dragleave`, `drop`, `dragend`.\n *\n * @category Core\n */\nexport interface DragEventDetail {\n /** The source's resolved drag data — read from the source options at session start. */\n dragData : DragData;\n /** The source component's id (`getId()`), useful for cycle / self-drop checks. */\n sourceId : string;\n /** Viewport-relative pointer X at the moment the event was raised. */\n clientX : number;\n /** Viewport-relative pointer Y at the moment the event was raised. */\n clientY : number;\n}\n\n/**\n * Drag-data payload attached to every tab-header drag — the cross-container\n * contract shared by the within-strip reorder path, tab tear-off / re-dock, the\n * Ctrl-drag window re-dock, and the downstream edge-split / dock-manager work.\n * A drop target reads it off {@link DragEventDetail}'s `dragData`. Because\n * {@link DragData} is a plain record it cannot carry a live component reference,\n * so `componentId` keys into the module-level `tabDragRegistry` to resolve the\n * dragged content.\n *\n * @category Core\n */\nexport interface TabDragData {\n /** Discriminator a drop target tests in its `accepts` predicate. */\n tabDrag: true;\n /** The source strip's stable id — distinguishes reorder-within from dock-from-elsewhere. */\n sourceTabId: string;\n /** The dragged content component's id — the key into `tabDragRegistry`. */\n componentId: string;\n /** The tab label — used for the drag ghost and the tear-off window title. */\n label: string;\n}\n\n/**\n * Resolves a {@link TabDragData} `componentId` back to the live content\n * component being dragged. Written when a header drag starts and cleared when it\n * ends, so a drop target — the same strip, another strip, or a torn-off\n * {@link DragData}-carrying window — can move the real component rather than\n * only learning its id. Shared by-import across `Tab` and `Window`; one\n * instance, so a source-side write is visible to the destination-side read.\n */\nexport const tabDragRegistry: Map<string, Component> = new Map<string, Component>();\n\n/**\n * Dwell, in milliseconds, before a tab held over a drop target spring-loads a\n * raise of that target's host window — surfacing a backgrounded float so the user\n * can aim the drop. Shared by the two dock drop surfaces so a region body\n * ([`DockRegion`](/api/layout/classes/DockRegion)) and a tab bar\n * ([`TabBar`](/api/component/container/classes/TabBar)) raise on the same cadence.\n *\n * Long enough that brushing a drag across a background window in transit does not\n * raise it, short enough that a deliberate hover surfaces the target. Set above a\n * `MenuItem` submenu's 150ms hover delay because raising a whole window is a\n * heavier, more disruptive action than opening a submenu, so it should demand a\n * clearly deliberate pause.\n */\nexport const SPRING_RAISE_DELAY_MS = 1000;\n\n/**\n * Construction-time options accepted by {@link DragManager.makeDragSource}.\n *\n * @category Core\n */\nexport interface DragSourceOptions {\n /** Static or factory-produced payload attached to the session. */\n dragData : DragData | (() => DragData);\n /**\n * Optional veto callback fired the moment the threshold is crossed.\n * Return `false` to abort the drag before any overlay is shown.\n */\n onDragStart? : (detail: DragEventDetail) => boolean | void;\n /**\n * Optional ghost factory. The returned component is used in place of\n * the manager's default ghost (which carries no label and matches the\n * source's size). The component must be detached when returned.\n */\n ghostFactory?: (source: Component, data: DragData) => Component;\n /** CSS cursor applied to `<body>` while the drag is active. */\n cursor? : string;\n /**\n * Fired once the gesture ends, after any `onDrop`. `dropped` is `true` when\n * the release was handled by a registered drop target — whether the target\n * accepted the drop or refused it — and `false` only on a release over empty\n * space. Lets a source distinguish a release that landed on a target from a\n * fall-through to empty space (e.g. tab tear-off), the signal the `\"dragend\"`\n * DOM event alone cannot carry.\n */\n onDragEnd? : (detail: DragEventDetail, dropped: boolean) => void;\n}\n\n/**\n * Construction-time options accepted by {@link DragManager.makeDropTarget}.\n *\n * @category Core\n */\nexport interface DropTargetOptions {\n /**\n * Validity predicate. Returns `true` when the dragged source may\n * drop on this target; the visual feedback tint mirrors the result.\n */\n accepts : (detail: DragEventDetail) => boolean;\n /**\n * Optional hover callback. Return a number to position the\n * [`ReorderIndicator`](/api/overlay/classes/ReorderIndicator) at the\n * given y inside the target; return `null` / `undefined` for no\n * reorder line.\n */\n onDragOver? : (detail: DragEventDetail) => number | null | void;\n /** Optional leave callback (cursor exits target's box). */\n onDragLeave? : (detail: DragEventDetail) => void;\n /** Optional drop callback — return `false` to suppress the `drop` event. */\n onDrop? : (detail: DragEventDetail) => boolean | void;\n /**\n * Suppresses the whole-target validity tint\n * ([`DragFeedback`](/api/overlay/classes/DragFeedback)) for this target. Pass it\n * when the target paints its own positional validity feedback (e.g. a\n * [`DockRegion`](/api/layout/classes/DockRegion) colours the drop *zone*\n * blue/red in `onDragOver`) so the two don't stack into a tinted frame *and*\n * a tinted zone. `accepts` still governs whether `onDragOver`/`onDrop` fire.\n */\n suppressValidityTint?: boolean;\n /**\n * Optional non-scrolling layer to host the validity tint, sized to the\n * target's box within it. Pass it when the target scrolls its own content\n * (e.g. a Tab strip's clip frame) so the tint overlays the *viewport* and\n * stays put instead of riding the scroll. Defaults to the target itself.\n */\n feedbackHost?: Component;\n}\n\ninterface DragSourceRecord {\n component: Component;\n options: DragSourceOptions;\n}\n\ninterface DropTargetRecord {\n component: Component;\n options: DropTargetOptions;\n}\n\ninterface DragSession {\n source: Component;\n sourceOptions: DragSourceOptions;\n dragData: DragData;\n startX: number;\n startY: number;\n committed: boolean;\n ghost: Component | null;\n feedback: DragFeedback | null;\n indicator: ReorderIndicator | null;\n currentTarget: Component | null;\n previousBodyCursor: string;\n}\n\n/**\n * Distance the cursor must travel between `mousedown` and `mousemove`\n * before the press-and-drag commits to a drag. The 4 px slop matches\n * the standard HIG threshold on Windows and macOS — anything shorter\n * fires a drag on plain clicks; anything longer feels unresponsive.\n */\nconst DRAG_THRESHOLD = 4;\n\n/**\n * Diagonal offsets applied to the ghost's top-left corner so the cursor\n * stays clear of the preview. Matches Finder / VS Code placement.\n */\nconst GHOST_OFFSET_X = 12;\nconst GHOST_OFFSET_Y = 12;\n\nconst dragSources = new Map<string, DragSourceRecord>();\nconst dropTargets = new Map<string, DropTargetRecord>();\nlet activeSession: DragSession | null = null;\n\n/**\n * Process-wide drag-and-drop coordinator. Maintains the global source /\n * target registry, owns the single active drag session, and\n * positions the three overlay components\n * ([`DragGhost`](/api/overlay/classes/DragGhost),\n * [`DragFeedback`](/api/overlay/classes/DragFeedback),\n * [`ReorderIndicator`](/api/overlay/classes/ReorderIndicator)) above the\n * page during a drag.\n *\n * Consumers register through the two factory functions and receive a\n * teardown closure to unwire when the source / target component goes\n * away. The manager itself fires no events directly — every callback\n * lives on the option bag the caller passed to the factory.\n *\n * @example\n * ```typescript\n * const tearDownSrc = DragManager.makeDragSource(row, {\n * dragData: () => ({ recordId: row.getRecord()?.get('id') }),\n * });\n * const tearDownTgt = DragManager.makeDropTarget(folder, {\n * accepts: (d) => d.dragData.recordId !== folder.getRecord()?.get('id'),\n * onDrop: (d) => moveRecord(d.dragData.recordId, folder),\n * });\n * ```\n *\n * @category Core\n */\nexport namespace DragManager {\n\n /**\n * Registers a component as a drag source. The component's mousedown\n * event begins a pending drag session that commits once the cursor\n * travels past the 4 px movement threshold.\n *\n * @param component - The source component.\n * @param options - Drag source configuration.\n *\n * @returns A teardown function that removes the source registration\n * and the mousedown listener.\n */\n export function makeDragSource(component: Component, options: DragSourceOptions): () => void {\n dragSources.set(component.getId(), { component, options });\n component.addMouseDownSubtreeListener(onSourceMouseDown);\n\n return tearDownDragSource.bind(null, component);\n }\n\n /**\n * Registers a component as a drop target. The component is queried\n * for `accepts` during every `mousemove` while a drag is active and\n * receives the configured callbacks at the appropriate phases.\n *\n * @param component - The drop target.\n * @param options - Drop target configuration.\n *\n * @returns A teardown function that removes the target registration.\n */\n export function makeDropTarget(component: Component, options: DropTargetOptions): () => void {\n dropTargets.set(component.getId(), { component, options });\n\n return tearDownDropTarget.bind(null, component);\n }\n\n /**\n * Returns whether a drag is currently in progress (committed past\n * the 4 px movement threshold).\n *\n * @returns `true` while the ghost is visible; `false` otherwise.\n */\n export function isDragging(): boolean {\n return activeSession !== null && activeSession.committed;\n }\n\n /**\n * Aborts an in-flight drag. Mirrors a `mouseup` outside any drop\n * target — no drop callback fires; the session tears down.\n */\n export function cancel(): void {\n if (activeSession === null) {\n return;\n }\n\n endSession(false, 0, 0);\n }\n}\n\n/**\n * Resolves the source's drag-data payload — accepts either a literal or\n * a factory function on every drag start so callers can carry per-row\n * state without re-registering the source.\n */\nfunction resolveDragData(options: DragSourceOptions): DragData {\n return typeof options.dragData === \"function\" ? options.dragData() : options.dragData;\n}\n\n/**\n * Removes the per-component mousedown listener and drops the source\n * record. Bound to `(component)` by `makeDragSource` so the returned\n * teardown closure stays a stable named-function reference.\n */\nfunction tearDownDragSource(component: Component): void {\n component.removeMouseDownSubtreeListener(onSourceMouseDown);\n dragSources.delete(component.getId());\n}\n\n/**\n * Drops the target record. Bound to `(component)` by\n * `makeDropTarget` so the returned teardown closure stays a stable\n * named-function reference.\n */\nfunction tearDownDropTarget(component: Component): void {\n dropTargets.delete(component.getId());\n}\n\n/**\n * Records the pending press and arms the viewport-level move / up\n * listeners. Nothing visual happens until the cursor crosses the\n * threshold.\n *\n * Registered as a subtree mousedown listener on every drag source, so\n * a press on any descendant of the source bubbles up the subtree\n * walker and the framework's Event router applies `component` as\n * `this` for the matching source — the lookup that identifies which\n * source was pressed.\n */\nfunction onSourceMouseDown(this: Component, e: MouseEvent): void {\n if (activeSession !== null) {\n return;\n }\n\n if (e.button !== 0) {\n return;\n }\n\n const record = dragSources.get(this.getId());\n\n if (!record) {\n return;\n }\n\n const source = record.component;\n const options = record.options;\n\n activeSession = {\n source,\n sourceOptions: options,\n dragData: resolveDragData(options),\n startX: e.clientX,\n startY: e.clientY,\n committed: false,\n ghost: null,\n feedback: null,\n indicator: null,\n currentTarget: null,\n previousBodyCursor: DOM.source.getInlineStyle(DOM.source.getBody(), \"cursor\"),\n };\n\n // Viewport listeners route through Event.baseViewportListener, which stops\n // mouseup propagation at window capture phase whenever any viewport\n // listener for the type exists. A raw document-level mouseup binding would\n // race SpinButton-class registrants that already pre-empt mouseup at\n // capture and never fire.\n Event.addViewportListener(source, \"mousemove\", onMouseMove);\n Event.addViewportListener(source, \"mouseup\", onMouseUp);\n Event.addViewportListener(source, \"selectstart\", onSelectStart);\n}\n\n/**\n * Builds the session's three overlay components and writes the page-\n * wide cursor. Called once on the first mousemove that crosses the\n * threshold.\n */\nfunction commitSession(session: DragSession): void {\n session.committed = true;\n\n const ghost = session.sourceOptions.ghostFactory\n ? session.sourceOptions.ghostFactory(session.source, session.dragData)\n : new DragGhost();\n\n session.ghost = ghost;\n session.feedback = new DragFeedback();\n session.indicator = new ReorderIndicator();\n\n if (typeof (ghost as unknown as { show?: () => void }).show === \"function\") {\n (ghost as unknown as { show: () => void }).show();\n } else {\n const el = ghost.getElement(true)!;\n\n DOM.sink.appendChild(DOM.source.getDocumentElement(), el);\n }\n\n if (session.sourceOptions.cursor) {\n DOM.sink.apply(DOM.source.getBody(), { style: { cursor: session.sourceOptions.cursor } });\n }\n}\n\n/**\n * Builds the immutable detail payload threaded through every\n * source / target callback for the current pointer position.\n */\nfunction buildDetail(session: DragSession, clientX: number, clientY: number): DragEventDetail {\n return {\n dragData: session.dragData,\n sourceId: session.source.getId(),\n clientX,\n clientY,\n };\n}\n\n/**\n * Hit-tests under the ghost (which is pointer-events-none) and returns\n * the registered drop target whose element is the first match in the\n * z-stack, or `null` when no registered target sits under the cursor.\n */\nfunction pickDropTarget(clientX: number, clientY: number): DropTargetRecord | null {\n const stack = DOM.source.elementsFromPoint(clientX, clientY);\n\n for (const el of stack) {\n const record = dropTargets.get(DOM.source.getId(el));\n\n if (record) {\n return record;\n }\n }\n\n return null;\n}\n\n/**\n * Detaches the validity tint from the previous target and fires its\n * `onDragLeave`. No-op when there is no previous target.\n */\nfunction leaveCurrentTarget(session: DragSession, detail: DragEventDetail): void {\n if (session.currentTarget === null) {\n return;\n }\n\n const prev = dropTargets.get(session.currentTarget.getId());\n\n if (prev && prev.options.onDragLeave) {\n prev.options.onDragLeave(detail);\n }\n\n if (session.feedback) {\n session.feedback.detach();\n }\n\n if (session.indicator) {\n session.indicator.detach();\n }\n\n session.currentTarget = null;\n}\n\n/**\n * Attaches the validity tint to the new target, calls `onDragOver`\n * once, and positions the reorder indicator if the callback returned a\n * y value.\n */\nfunction enterNewTarget(session: DragSession, target: DropTargetRecord, detail: DragEventDetail): void {\n const accepted = target.options.accepts(detail);\n\n if (session.feedback && !target.options.suppressValidityTint) {\n session.feedback.setValid(accepted);\n session.feedback.attachTo(target.component, target.options.feedbackHost);\n }\n\n if (!accepted) {\n session.currentTarget = target.component;\n\n return;\n }\n\n const hint = target.options.onDragOver?.(detail);\n\n if (typeof hint === \"number\" && session.indicator) {\n session.indicator.attachTo(target.component);\n session.indicator.setInsertionY(hint);\n } else if (session.indicator) {\n session.indicator.detach();\n }\n\n session.currentTarget = target.component;\n}\n\n/**\n * Suppresses the browser's own text-selection gesture for the duration of a\n * drag session, which would otherwise run alongside it now that table cell\n * text is selectable — the drag is mouse-driven (mousedown/mousemove), not\n * HTML5 drag-and-drop, so nothing else stops a selection from painting in\n * parallel. `preventDefault()` on `mousemove` does not by itself stop the\n * browser from extending a selection (verified live: the selection still\n * grew with every `mousemove` observably prevented), so the suppression has\n * to target `selectstart` itself. Registered and torn down alongside the\n * mousemove/mouseup viewport listeners, so it is live only while a session\n * exists — including the brief press-to-release window of a plain click\n * that never crosses the drag threshold, where losing the (invisible)\n * collapsed-caret placement a real `selectstart` would otherwise produce\n * has no observable effect on a non-editable table cell.\n *\n * @returns Always suppresses the event while installed.\n */\nfunction onSelectStart(): Event.ListenerResult {\n return { stop: true, prevent: true };\n}\n\n/**\n * Drives the active session forward each frame: commits past the\n * threshold, moves the ghost, hands target changes to the\n * enter / leave helpers, and re-runs `onDragOver` while the cursor stays\n * inside the same target.\n *\n * @returns `true` while a drag session is live, consuming the move so nothing else\n * tracks the pointer; nothing when there is no session, so the move keeps propagating.\n */\nfunction onMouseMove(e: MouseEvent): Event.ListenerResult {\n if (activeSession === null) {\n return;\n }\n\n const session = activeSession;\n\n if (!session.committed) {\n const dx = e.clientX - session.startX;\n const dy = e.clientY - session.startY;\n\n if (dx * dx + dy * dy < DRAG_THRESHOLD * DRAG_THRESHOLD) {\n return { stop: true, prevent: true };\n }\n\n const startDetail = buildDetail(session, e.clientX, e.clientY);\n\n if (session.sourceOptions.onDragStart?.(startDetail) === false) {\n endSession(false, e.clientX, e.clientY);\n\n return { stop: true, prevent: true };\n }\n\n commitSession(session);\n Event.fireEvent(session.source, \"dragstart\", { detail: startDetail });\n }\n\n if (session.ghost) {\n const dragGhost = session.ghost as unknown as { moveTo?: (x: number, y: number) => void };\n\n if (typeof dragGhost.moveTo === \"function\") {\n dragGhost.moveTo(e.clientX + GHOST_OFFSET_X, e.clientY + GHOST_OFFSET_Y);\n } else {\n session.ghost.setX(e.clientX + GHOST_OFFSET_X);\n session.ghost.setY(e.clientY + GHOST_OFFSET_Y);\n }\n }\n\n const detail = buildDetail(session, e.clientX, e.clientY);\n const target = pickDropTarget(e.clientX, e.clientY);\n\n if (target === null) {\n leaveCurrentTarget(session, detail);\n\n return { stop: true, prevent: true };\n }\n\n if (session.currentTarget !== target.component) {\n leaveCurrentTarget(session, detail);\n enterNewTarget(session, target, detail);\n\n return { stop: true, prevent: true };\n }\n\n // Same target as last frame — re-check accepts so the feedback\n // tint stays accurate (the validity of a drop can change as the\n // cursor moves within the same target, e.g. crossing into a\n // descendant region the source isn't allowed to land on). Skip\n // onDragOver / reorder indicator entirely while the drop is\n // rejected.\n const accepted = target.options.accepts(detail);\n\n if (session.feedback && !target.options.suppressValidityTint) {\n session.feedback.setValid(accepted);\n }\n\n if (!accepted) {\n if (session.indicator) {\n session.indicator.detach();\n }\n\n return { stop: true, prevent: true };\n }\n\n const hint = target.options.onDragOver?.(detail);\n\n if (typeof hint === \"number\" && session.indicator) {\n session.indicator.attachTo(target.component);\n session.indicator.setInsertionY(hint);\n } else if (session.indicator) {\n session.indicator.detach();\n }\n\n return { stop: true, prevent: true };\n}\n\n/**\n * Commits the drop (if any) and tears down the session.\n *\n * @returns `true` when a drag session was live, consuming the release that ends it;\n * nothing when there is no session, so the release keeps propagating.\n */\nfunction onMouseUp(e: MouseEvent): Event.ListenerResult {\n if (activeSession === null) {\n return;\n }\n\n const session = activeSession;\n const detail = buildDetail(session, e.clientX, e.clientY);\n let dropped = false;\n\n if (session.committed && session.currentTarget !== null) {\n const target = dropTargets.get(session.currentTarget.getId());\n\n if (target) {\n // Released over a registered drop target. Dispatch the drop only\n // when the target accepts; either way the release was *handled* by a\n // target rather than falling through to empty space, so report\n // `dropped` so the source skips its empty-space fallback — e.g. a Tab\n // header snaps back instead of tearing off into a window when the\n // target refused it (a rejected self-dock is a no-op, not a detach).\n if (target.options.accepts(detail)) {\n const onDropResult = target.options.onDrop?.(detail);\n\n if (onDropResult !== false) {\n Event.fireEvent(session.source, \"drop\", { detail });\n }\n }\n\n dropped = true;\n }\n }\n\n endSession(dropped, e.clientX, e.clientY);\n\n return true;\n}\n\n/**\n * Removes overlays, unwires viewport listeners, restores the body\n * cursor, and fires `dragend` when the session committed.\n */\nfunction endSession(dropped: boolean, clientX: number, clientY: number): void {\n if (activeSession === null) {\n return;\n }\n\n const session = activeSession;\n\n Event.removeViewportListener(session.source, \"mousemove\", onMouseMove);\n Event.removeViewportListener(session.source, \"mouseup\", onMouseUp);\n Event.removeViewportListener(session.source, \"selectstart\", onSelectStart);\n\n // The drag chrome is built fresh for every committed gesture in\n // `commitSession` and held only on the session record — none of it is\n // registered through `addComponent`, so `Component.destructor()`'s child\n // recursion can never reach it. Disposing, rather than only detaching,\n // is what reclaims each one's per-instance stylesheet rule before the\n // session reference is dropped; detaching alone grew the shared sheet by\n // one rule per drag, without bound.\n if (session.feedback) {\n session.feedback.dispose();\n }\n\n if (session.indicator) {\n session.indicator.dispose();\n }\n\n if (session.ghost) {\n if (session.sourceOptions.ghostFactory) {\n // A ghost from the caller's factory belongs to the caller, which\n // may hand back the same component on every gesture — so it is\n // detached, never disposed.\n const dragGhost = session.ghost as unknown as { hide?: () => void };\n\n if (typeof dragGhost.hide === \"function\") {\n dragGhost.hide();\n } else {\n session.ghost.removeElement();\n }\n } else {\n session.ghost.dispose();\n }\n }\n\n if (session.sourceOptions.cursor) {\n DOM.sink.apply(DOM.source.getBody(), { style: { cursor: session.previousBodyCursor } });\n }\n\n if (session.committed) {\n const detail = buildDetail(session, clientX, clientY);\n\n Event.fireEvent(session.source, \"dragend\", { detail });\n session.sourceOptions.onDragEnd?.(detail, dropped);\n }\n\n activeSession = null;\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { ComponentOptions } from \"~/core/Component.js\";\nimport { Event } from \"~/core/Event.js\";\nimport { Checkbox } from \"~/component/input/Checkbox.js\";\nimport { MenuItem } from \"~/component/container/MenuItem.js\";\nimport { MenuRow } from \"~/component/container/MenuRow.js\";\nimport { callable } from \"~/core/Callable.js\";\n\n/** Events exposed by {@link CheckboxMenuRow}. */\nexport type CheckboxMenuRowEvent = \"action\";\n\n// Dim applied to a disabled row, matching the framework's other composite\n// disabled controls (Button.setEnabled, NumberSpinner.applyEnabled).\nconst DISABLED_OPACITY = 0.5;\n\n/**\n * Construction-time options for {@link CheckboxMenuRow}.\n *\n * @category Components\n */\nexport interface CheckboxMenuRowOptions extends ComponentOptions {\n /** Row label, rendered beside the checkbox graphic. */\n text?: string;\n /** Initial checked state. Defaults to `false`. */\n checked?: boolean;\n /** Defaults to `true`. Disabled rows are dimmed and non-interactive. */\n enabled?: boolean;\n /**\n * Construction-time listener bag; `action` fires after each toggle.\n */\n listeners?: { action?: () => void };\n}\n\n/**\n * A [`Menu`](/api/overlay/classes/Menu) row hosting a real\n * [`Checkbox`](/api/component/input/classes/Checkbox), for a multi-select menu.\n *\n * Built via `{ row: () => new CheckboxMenuRow({ text, checked }) }` on a\n * `MenuItemConfig`. Toggles on a click anywhere in the row or on Enter (via\n * {@link activate}) and leaves the menu open — unlike a plain `MenuItem`,\n * activating it never closes the panel. `isNavigable()` reports `true`, so\n * the menu's roving arrow-key highlight lands on it like any other row.\n *\n * @category Components\n */\nclass CheckboxMenuRow extends MenuRow<CheckboxMenuRowOptions> {\n\n private _checkbox: Checkbox;\n // The title offset the owning Menu pushed in, or null when this row is\n // standalone — in which case doLayout falls back to MenuItem.TEXT_INSET.\n private _iconStart: number | null = null;\n // The check-column width the owning Menu pushed in, alongside _iconStart —\n // needed to tell whether _iconStart was widened for a sibling's icon (see\n // doLayout's `iconColumnReserved`).\n private _checkZone: number | null = null;\n\n private readonly _onMouseOver: () => void;\n private readonly _onMouseOut: () => void;\n private readonly _onClick: () => void;\n\n /**\n * Constructs a CheckboxMenuRow.\n *\n * @param options - Optional construction-time options.\n * @param subclassDefaults - Per-subclass default bag layered over this\n * class's defaults; subclasses forward their `_defaultXxxOptions`\n * constant here.\n */\n constructor(options?: CheckboxMenuRowOptions, subclassDefaults?: Partial<CheckboxMenuRowOptions>) {\n super(options, subclassDefaults);\n\n // `text` / `checked` are read from the raw constructor argument, not\n // `this._options`: neither field has a matching setter for\n // `applyOptions` to dispatch through (there is no live `setText`, and\n // `setChecked` below writes straight to `_checkbox`, which cannot\n // exist yet during the `super()` cascade), so `this._options` is\n // never populated for them — `_checkbox` itself is the state cache\n // for `checked` from this point on.\n this._checkbox = new Checkbox({\n label: options?.text ?? \"\",\n selected: options?.checked ?? false,\n enabled: options?.enabled ?? true,\n });\n // Pointer-inert child so a click anywhere in the row hits the row\n // element and toggles — the same arrangement MenuItem uses for its\n // five labels and SelectableListRow uses for its renderer. The row's\n // own `click` listener is exact-target, so the Checkbox's internal\n // synthetic click (fired from setSelected on its own element) cannot\n // re-enter it.\n this._checkbox.setPointerEvents(\"none\");\n this.addComponent(this._checkbox);\n\n if (options?.enabled === false) {\n // Pointer-inert, not merely guarded: a consumer's `on(\"action\", …)`\n // handler is a second click listener on this row, which no guard\n // inside `activate()` can suppress. Keeping the click off the row\n // is what makes a disabled row truly non-interactive.\n this.setPointerEvents(\"none\");\n this.setOpacity(DISABLED_OPACITY);\n }\n\n this._onMouseOver = () => {\n this.setFocused(true);\n };\n\n this._onMouseOut = () => {\n this.setFocused(false);\n };\n\n this._onClick = () => {\n this.activate();\n };\n\n Event.addListener(this, \"mouseover\", this._onMouseOver);\n Event.addListener(this, \"mouseout\", this._onMouseOut);\n Event.addListener(this, \"click\", this._onClick);\n\n this.applyListeners(options?.listeners);\n }\n\n /**\n * Returns the row's current checked state.\n *\n * @returns Whether the checkbox is currently checked.\n */\n isChecked(): boolean {\n return this._checkbox.isSelected();\n }\n\n /**\n * Sets the checked state.\n *\n * @param value - `true` to check, `false` to uncheck.\n * @returns This row, for method chaining.\n */\n setChecked(value: boolean): this {\n this._checkbox.setSelected(value);\n\n return this;\n }\n\n /**\n * Returns `true` — a `CheckboxMenuRow` behaves like a menu item, so the\n * menu's roving highlight lands on it and Enter activates it.\n *\n * @returns `true`.\n */\n isNavigable(): boolean {\n return true;\n }\n\n /**\n * Overrides {@link MenuRow.isEnabled}, reading the inner `Checkbox`'s\n * own enabled state — the cache for this row's `enabled` option, just as\n * it already is for `checked`.\n *\n * @returns Whether this row is interactive.\n */\n isEnabled(): boolean {\n return this._checkbox.isEnabled();\n }\n\n /**\n * Flips the checkbox. Called by a click on the row or by\n * `Menu.activateFocused()` on Enter. A no-op when the row is disabled.\n */\n activate(): void {\n if (!this.isEnabled()) {\n return;\n }\n\n this.setChecked(!this.isChecked());\n }\n\n /**\n * Returns the row's own content width — the checkbox's natural width\n * plus right padding, excluding any left inset of its own (`Menu` adds\n * the shared `iconStart` uniformly; see {@link MenuRow.getContentWidth}).\n * Read by `Menu.layOutColumns` **before** {@link setColumns} runs, so\n * this must never depend on the injected `iconStart` value itself.\n *\n * @returns The row's preferred content width in pixels.\n */\n getContentWidth(): number {\n const width = Math.ceil(this._checkbox.getPreferredSize()?.width ?? 0);\n\n return width + MenuItem.RIGHT_PAD;\n }\n\n /**\n * Stores the menu-computed left offset so the checkbox lines up with the\n * `MenuItem`s around it. `titleColumn` is unused — this row has no shared\n * title column of its own.\n *\n * @param checkZone - Width reserved for the menu's leading checkmark column.\n * @param iconStart - The left offset (in pixels) to align the checkbox to.\n * @param _titleColumn - Unused.\n */\n setColumns(checkZone: number, iconStart: number, _titleColumn: number): void {\n this._checkZone = checkZone;\n this._iconStart = iconStart;\n this.scheduleLayout();\n }\n\n /**\n * Positions the checkbox within the row's content box, vertically\n * centred, at the injected `iconStart` (or `MenuItem.TEXT_INSET` when\n * this row was never given one).\n *\n * When a sibling row reserves an icon column, `iconStart` is pushed out\n * to align with icon rows' *title text* — past their icon — which would\n * otherwise indent this row's checkbox behind an icon-sized gap of empty\n * space. Aligning with the icon's own position instead (`checkZone + 4`,\n * matching {@link MenuItem}'s icon inset) keeps the checkbox flush with\n * where a sibling's icon renders, since the checkbox plays the same\n * visual role. With no icon column, `iconStart` already collapses to\n * `checkZone + MenuItem.TEXT_INSET`, so this leaves a plain\n * checkbox-only menu's layout unchanged.\n *\n * @returns This row, for method chaining.\n */\n doLayout(): this {\n super.doLayout();\n\n const box = this.getContentBounds();\n\n if (!box) {\n return this;\n }\n\n const size = this._checkbox.getPreferredSize() ?? { width: 0, height: 0 };\n const checkZone = this._checkZone ?? 0;\n const iconColumnReserved = this._iconStart !== null && this._iconStart - checkZone === MenuItem.ICON_ZONE;\n const left = iconColumnReserved ? checkZone + 4 : (this._iconStart ?? MenuItem.TEXT_INSET);\n const top = Math.max(0, Math.floor((box.height - size.height) / 2));\n\n this._checkbox.setX(box.x + left);\n this._checkbox.setY(box.y + top);\n this._checkbox.setWidth(Math.max(0, box.width - left - MenuItem.RIGHT_PAD));\n this._checkbox.setHeight(size.height);\n\n return this;\n }\n\n /**\n * Registers a listener for this row's `\"action\"` event — fired after\n * each toggle (click or {@link activate}). A typed semantic shorthand\n * over {@link Event.addListener} (the underlying DOM event is `\"click\"`).\n *\n * @param event - The event name. Only `\"action\"` is accepted.\n * @param listener - The callback to invoke after each toggle.\n * @returns This row, for method chaining.\n */\n on(event: \"action\", listener: () => void): this;\n on(_event: \"action\", listener: () => void): this {\n Event.addListener(this, \"click\", listener);\n\n return this;\n }\n\n /**\n * Removes a previously registered `\"action\"` listener.\n *\n * @param event - The event the listener was registered for.\n * @param listener - The callback to remove.\n * @returns This row, for method chaining.\n */\n off(event: \"action\", listener: () => void): this;\n off(_event: \"action\", listener: () => void): this {\n Event.removeListener(this, \"click\", listener);\n\n return this;\n }\n}\n\nconst CheckboxMenuRowCallable = callable(CheckboxMenuRow);\ntype CheckboxMenuRowCallable = CheckboxMenuRow;\nexport {\n CheckboxMenuRow as _CheckboxMenuRow,\n CheckboxMenuRowCallable as CheckboxMenuRow\n};\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime-O8uOSEUP.js";import{t}from"./DOM-
|
|
2
|
-
//# sourceMappingURL=CodeEditor-
|
|
1
|
+
import{t as e}from"./rolldown-runtime-O8uOSEUP.js";import{t}from"./DOM-Cjh7_7TF.js";import{h as n,r,t as i,v as a}from"./Component-D99-15Zt.js";import{t as o}from"./ListenerBag-WPdKuuds.js";import{t as s}from"./LanguageRegistry-CcVnbKuh.js";import{EditorView as c,drawSelection as l,highlightActiveLine as u,highlightActiveLineGutter as d,keymap as f,lineNumbers as p}from"@codemirror/view";import{Compartment as m,EditorState as h}from"@codemirror/state";import{defaultKeymap as g,history as _,historyKeymap as v,indentWithTab as y}from"@codemirror/commands";import{HighlightStyle as b,bracketMatching as x,indentOnInput as S,indentRange as C,syntaxHighlighting as w}from"@codemirror/language";import{tags as T}from"@lezer/highlight";var E=`#2563eb`,D=`#16a34a`,O=`#6b7280`,k=`#d97706`,A=`#7c3aed`,j=`#0891b2`,M=`#be185d`;function codeEditorTheme(e){return[c.theme({"&":{height:`100%`,color:`var(--ts-ui-text-color, #1a1a1a)`,backgroundColor:`var(--ts-ui-input-bg, #ffffff)`},".cm-content":{fontFamily:`var(--ts-ui-font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace)`,caretColor:`var(--ts-ui-indicator-focus, #2563eb)`,cursor:`text`},".cm-gutters":{color:`var(--ts-ui-text-color, #1a1a1a)`,backgroundColor:`var(--ts-ui-input-bg, #ffffff)`,borderRight:`1px solid var(--ts-ui-border-color, rgba(127, 127, 127, 0.4))`},"&.cm-focused .cm-cursor":{borderLeftColor:`var(--ts-ui-indicator-focus, #2563eb)`},"&.cm-focused .cm-selectionBackground, .cm-selectionBackground":{backgroundColor:`var(--ts-ui-indicator-selection, rgba(37, 99, 235, 0.25))`},".cm-activeLine, .cm-activeLineGutter":{backgroundColor:`rgba(127, 127, 127, 0.08)`}},{dark:e}),w(b.define([{tag:T.keyword,color:E},{tag:[T.string,T.special(T.string)],color:D},{tag:T.comment,color:O,fontStyle:`italic`},{tag:[T.number,T.bool,T.null],color:k},{tag:[T.definition(T.variableName),T.function(T.variableName)],color:A},{tag:T.typeName,color:j},{tag:[T.propertyName,T.attributeName],color:M},{tag:T.tagName,color:E},{tag:[T.heading,T.heading1,T.heading2,T.heading3,T.heading4,T.heading5,T.heading6],color:E,fontWeight:`bold`},{tag:T.strong,fontWeight:`bold`},{tag:T.emphasis,fontStyle:`italic`},{tag:T.monospace,color:D},{tag:[T.link,T.url],color:E,textDecoration:`underline`},{tag:[T.quote,T.contentSeparator],color:O},{tag:T.processingInstruction,color:O}]))]}var N=e({CodeEditor:()=>V,_CodeEditor:()=>CodeEditor}),P={overflow:`auto`},F=`.cm-scroller`,I=`.cm-content`,L=1,R=300,z=.16,B=`var(--ts-ui-validation-error-border, #dc2626)`;function buildReadOnlyExtension(e){return h.readOnly.of(e)}var CodeEditor=class extends i{_view=null;_flashOverlay=null;_flashAnimation=null;_langCompartment=new m;_readOnlyCompartment=new m;_themeCompartment=new m;_listeners=new o;_unsubscribeTheme;_scrollElement=null;_contentElement=null;_lastSyncedShape=null;_lastHbarReserve=0;constructor(e,t,n){super(t,{...P,...n??{}}),e!==void 0&&this._options.value===void 0&&(this._options.value=e),this._unsubscribeTheme=r.onThemeChange(()=>this.onThemeChange()),this.applyListeners(t?.listeners),this.onFirstLayout(()=>this.mount())}applyOptions(e){return super.applyOptions(e),e.value!==void 0&&(this._options.value=e.value),e.language!==void 0&&(this._options.language=e.language),e.readOnly!==void 0&&(this._options.readOnly=e.readOnly),e.autoHeightMaxRows!==void 0&&(this._options.autoHeightMaxRows=e.autoHeightMaxRows),this}getValue(){return this._view?this._view.state.doc.toString():this._options.value??``}setValue(e){return this._options.value=e,this._view&&this._view.dispatch({changes:{from:0,to:this._view.state.doc.length,insert:e}}),this}getLanguage(){return this._options.language??null}setLanguage(e){if(this._options.language=e??void 0,!this._view)return this;if(!e)return this._view.dispatch({effects:this._langCompartment.reconfigure([])}),this;let t=s(e);return t&&t.loadExtension().then(t=>{this._view&&this.getLanguage()===e&&this._view.dispatch({effects:this._langCompartment.reconfigure(t)})}),this}getReadOnly(){return this._options.readOnly??!1}setReadOnly(e){return this._options.readOnly=e,this._view&&this._view.dispatch({effects:this._readOnlyCompartment.reconfigure(buildReadOnlyExtension(e))}),this}getAutoHeightMaxRows(){return this._options.autoHeightMaxRows??null}focus(e=!1){return this._view?(this._view.focus(),this):super.focus(e)}moveCursorToEnd(){if(this._view){let e=this._view.state.doc.length;this._view.dispatch({selection:{anchor:e},scrollIntoView:!0})}return this}async format(){let e=this.getLanguage(),t=e?s(e):void 0;if(!t?.loadFormatter){this.reindentFallback();return}let n=await(await t.loadFormatter())(this.getValue(),this._view?this._view.state.selection.main.head:0);this._options.value=n.formatted,this._view&&this._view.dispatch({changes:{from:0,to:this._view.state.doc.length,insert:n.formatted},selection:{anchor:Math.min(n.cursorOffset,n.formatted.length)}})}reindentFallback(){this._view&&this._view.dispatch({changes:C(this._view.state,0,this._view.state.doc.length)})}on(e,t){return this._listeners.add(e,t),this}off(e,t){return this._listeners.remove(e,t),this}emit(e,t){this._listeners.fire(e,...t?[t]:[])}destructor(){this._flashAnimation?.cancel(),this._flashAnimation=null,this._unsubscribeTheme(),this._scrollElement=null,this._contentElement=null,this._view?.destroy(),this._view=null,super.destructor()}getScrollElement(){return this._scrollElement??super.getScrollElement()}mount(){if(this._view)return;let e=this.getElement();if(!e)return;let n=r.getTheme().colorScheme===`dark`,i=[_(),f.of([...g,...v,y]),l(),p(),u(),d(),S(),x(),this._readOnlyCompartment.of(buildReadOnlyExtension(this.getReadOnly())),this._themeCompartment.of(codeEditorTheme(n)),this._langCompartment.of([]),c.updateListener.of(e=>{e.docChanged&&(this._options.value=e.state.doc.toString(),this.emit(`change`,{value:this._options.value})),(e.heightChanged||e.geometryChanged)&&this.syncAutoHeight(e.selectionSet&&!e.docChanged)}),c.domEventHandlers({beforeinput:()=>this.onEditIntent(),paste:()=>this.onEditIntent(),drop:()=>this.onEditIntent()})],a=h.create({doc:this._options.value??``,extensions:i});this._view=t.sink.mountView(e,e=>new c({parent:e,state:a})),this._view&&(this.mountFlashOverlay(e),this._scrollElement=t.source.querySelector(e,F),this._scrollElement&&(this._contentElement=t.source.querySelector(this._scrollElement,I)),this._scrollElement&&this.getAutoHeightMaxRows()!==null&&t.sink.apply(this._scrollElement,{style:{paddingBottom:`1px`,scrollbarGutter:`stable`}}));let o=this.getLanguage();o&&this.setLanguage(o),this.syncAutoHeight()}syncAutoHeight(e=!1){let n=this.getAutoHeightMaxRows();if(!this._view||n===null||!this._scrollElement)return;let r=t.source.getScrollMetrics(this._scrollElement),i=this._view.documentPadding.top+this._view.documentPadding.bottom,a=(r.scrollHeight-i)/this._view.state.doc.lines*n+i,o=Math.min(r.scrollHeight,a);if(e&&o>this.getHeight())return;let s=[this._view.state.doc.lines,this._view.state.doc.length,r.clientWidth],c=this._lastSyncedShape===null||s.some((e,t)=>e!==this._lastSyncedShape[t]);this._lastSyncedShape=s;let l=this.getHeight(),u=r.clientHeight;if(c){if(this.setHeight(o),u=t.source.getScrollMetrics(this._scrollElement).clientHeight,r.scrollHeight<=a&&this._contentElement){let e=t.source.getElementRect(this._contentElement).height,n=t.source.getElementRect(this._scrollElement).height-L;o+=Math.max(0,e-n)}}else{let e=l-this._lastHbarReserve;o<e&&e-o>=1&&(o=e)}let d=t.source.getOffsetSize(this._scrollElement);this._lastHbarReserve=Math.max(0,d.offsetHeight-u);let f=o+this._lastHbarReserve;f!==l&&(f>l&&!c||f<l&&!c&&l-f<1||(this.setHeight(f),this.emit(`heightchange`,{height:f})))}mountFlashOverlay(e){let n=this.trackHandle(t.sink.createElement(`div`));t.sink.apply(n,{style:{position:`absolute`,inset:`0`,pointerEvents:`none`,zIndex:`300`,backgroundColor:B,opacity:`0`}}),t.sink.appendChild(e,n),this._flashOverlay=n}onThemeChange(){if(!this._view)return;let e=r.getTheme().colorScheme===`dark`;this._view.dispatch({effects:this._themeCompartment.reconfigure(codeEditorTheme(e))})}onEditIntent(){return this.getReadOnly()&&this.signalReadOnlyEdit(),!1}signalReadOnlyEdit(){this.emit(`readonlyedit`),this.flashReadOnly()}flashReadOnly(){this._flashOverlay&&(this._flashAnimation?.cancel(),this._flashAnimation=a.play(this._flashOverlay,{from:{opacity:String(z)},to:{opacity:`0`},durationMs:R,properties:[`opacity`]}))}},V=n(CodeEditor);export{N as n,V as t};
|
|
2
|
+
//# sourceMappingURL=CodeEditor-CTL2WjF8.js.map
|