@ixfx/components 0.8.8 → 0.8.9
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/bundle/index.d.ts +232 -42
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +1102 -37
- package/bundle/index.js.map +1 -1
- package/dist/crumbs.d.ts +1 -1
- package/dist/{data-grid-BKa9i86q.d.ts → data-grid-C588pTgt.d.ts} +3 -3
- package/dist/{data-grid-BKa9i86q.d.ts.map → data-grid-C588pTgt.d.ts.map} +1 -1
- package/dist/data-grid.d.ts +2 -2
- package/dist/data-grid.js +1 -1
- package/dist/{detail-list-CHTomlbR.d.ts → detail-list-IKl76Wnp.d.ts} +4 -4
- package/dist/{detail-list-CHTomlbR.d.ts.map → detail-list-IKl76Wnp.d.ts.map} +1 -1
- package/dist/detail-list.d.ts +3 -3
- package/dist/detail-list.js +1 -1
- package/dist/{grid-list-CsZcXxMC.d.ts → grid-list-BUlUnisU.d.ts} +7 -55
- package/dist/grid-list-BUlUnisU.d.ts.map +1 -0
- package/dist/{grid-list-C8oMxLl-.js → grid-list-D18FNJRH.js} +2 -2
- package/dist/{grid-list-C8oMxLl-.js.map → grid-list-D18FNJRH.js.map} +1 -1
- package/dist/grid-list.d.ts +2 -2
- package/dist/grid-list.js +1 -1
- package/dist/incr-search.d.ts +1 -1
- package/dist/{index-Dgrx-DIA.d.ts → index--qnhBWZJ.d.ts} +2 -2
- package/dist/{index-Dgrx-DIA.d.ts.map → index--qnhBWZJ.d.ts.map} +1 -1
- package/dist/index.d.ts +30 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -9
- package/dist/index.js.map +1 -1
- package/dist/{labelled-slider-input-BCH9968c.js → labelled-slider-input-aEYDvW2S.js} +2 -2
- package/dist/{labelled-slider-input-BCH9968c.js.map → labelled-slider-input-aEYDvW2S.js.map} +1 -1
- package/dist/labelled-slider-input.js +1 -1
- package/dist/list-native-drag-controller-CFyrkKUj.d.ts +61 -0
- package/dist/list-native-drag-controller-CFyrkKUj.d.ts.map +1 -0
- package/dist/{list-native-drag-controller-DrY3qeJM.js → list-native-drag-controller-DxD6Yjci.js} +14 -2
- package/dist/list-native-drag-controller-DxD6Yjci.js.map +1 -0
- package/dist/miller.d.ts +2 -2
- package/dist/plots.js +1 -1
- package/dist/slider-input-BxURAAmD.d.ts.map +1 -1
- package/dist/{slider-input-WR8_RwHg.js → slider-input-Cb5uSV42.js} +78 -11
- package/dist/slider-input-Cb5uSV42.js.map +1 -0
- package/dist/slider-input.js +1 -1
- package/dist/{tree-DSMn566I.js → tree-a14n9y7i.js} +1006 -19
- package/dist/tree-a14n9y7i.js.map +1 -0
- package/dist/{tree-component-nPP5Y-WS.d.ts → tree-component-BW2iCFq9.d.ts} +107 -3
- package/dist/tree-component-BW2iCFq9.d.ts.map +1 -0
- package/dist/tree.d.ts +102 -4
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +2 -2
- package/dist/{vertical-list-A6oWfivZ.d.ts → vertical-list-CHrXmmQ3.d.ts} +3 -3
- package/dist/{vertical-list-A6oWfivZ.d.ts.map → vertical-list-CHrXmmQ3.d.ts.map} +1 -1
- package/dist/vertical-list.d.ts +2 -2
- package/dist/vertical-list.js +1 -1
- package/dist/{xy-axis-CrrVdDFe.js → xy-axis-COKw338Q.js} +2 -2
- package/dist/xy-axis-COKw338Q.js.map +1 -0
- package/dist/xy-axis-DQqd2yXJ.d.ts.map +1 -1
- package/docs-user/index.json +2 -2
- package/docs-user/tree.md +75 -0
- package/package.json +1 -1
- package/dist/grid-list-CsZcXxMC.d.ts.map +0 -1
- package/dist/list-drag-types-kpaXz2pZ.d.ts +0 -42
- package/dist/list-drag-types-kpaXz2pZ.d.ts.map +0 -1
- package/dist/list-native-drag-controller-DrY3qeJM.js.map +0 -1
- package/dist/slider-input-WR8_RwHg.js.map +0 -1
- package/dist/tree-DSMn566I.js.map +0 -1
- package/dist/tree-component-nPP5Y-WS.d.ts.map +0 -1
- package/dist/xy-axis-CrrVdDFe.js.map +0 -1
|
@@ -5,7 +5,7 @@ import { t as LabelledInputBase } from "./labelled-input-base-hoKGwyKT.js";
|
|
|
5
5
|
import { EditableLabel } from "./editable-label.js";
|
|
6
6
|
import { t as resolveAxisStep } from "./keyboard-B5xD7Fz-.js";
|
|
7
7
|
import { t as WheelNudgeMixin } from "./wheel-nudge-D5rmht3v.js";
|
|
8
|
-
import "./slider-input-
|
|
8
|
+
import "./slider-input-Cb5uSV42.js";
|
|
9
9
|
import { css, html } from "lit";
|
|
10
10
|
import { property } from "lit/decorators.js";
|
|
11
11
|
//#region src/editable-label/editable-number.ts
|
|
@@ -805,4 +805,4 @@ LabelledSliderInput = __decorate([safeCustomElement(`ixfx-labelled-slider-input`
|
|
|
805
805
|
//#endregion
|
|
806
806
|
export { EditableNumber as n, LabelledSliderInput as t };
|
|
807
807
|
|
|
808
|
-
//# sourceMappingURL=labelled-slider-input-
|
|
808
|
+
//# sourceMappingURL=labelled-slider-input-aEYDvW2S.js.map
|
package/dist/{labelled-slider-input-BCH9968c.js.map → labelled-slider-input-aEYDvW2S.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"labelled-slider-input-BCH9968c.js","names":["#lastInputValue","#dragStartY","#dragStartValue","#dragCurrentValue","#dragging","#hasDragged","customElement","customElement"],"sources":["../src/editable-label/editable-number.ts","../src/labelled-slider-input/labelled-slider-input.ts"],"sourcesContent":["/**\n * <ixfx-editable-number> — inline editable number label with Ableton-style drag.\n *\n * Extends <ixfx-editable-label> with:\n * • Pointer drag to adjust value — drag up to increase, down to decrease,\n * without entering full text-edit mode.\n * • Click gives focus; pressing any key while focused enters text-edit mode.\n * • Optional min/max clamping and step snapping.\n * • Optional fill-bar visualization behind the label text.\n *\n * Attributes:\n * min Minimum value (no clamping if unset)\n * max Maximum value (no clamping if unset)\n * step Snap increment, also informs decimal-place display (unset = no snapping)\n * stops Number of quantised keyboard stops (unset = no snapping). Wins over `step` when > 1.\n * drag-sensitivity Steps changed per pixel of drag (default: 1); multiply by step to get units/px\n * precision Decimal places applied when rounding drag-produced values (default: 0 = integers).\n * Has no effect when step is set (step implies its own precision).\n * Typed values are never precision-rounded — the user can always enter finer values.\n * fill-style 'linear' (default) or 'circular' — shape of the fill visualization\n * linear-style 'range' (default), 'bipolar', or 'unipolar' — how value maps to fill (linear mode only)\n * circular-style 'grow' (default), 'offset', or 'dot' — how value maps to fill (circular mode only)\n * no-drag Boolean — disables drag interaction; text editing still works\n * lighttouch Boolean — wheel adjusts the value on hover instead of requiring focus.\n * Wheel is suppressed while the user is typing (`_editing === true`).\n *\n * CSS variables:\n * --fill-color Fill bar color (default: var(--accent))\n * --fill-opacity Fill bar opacity as 0..1 (default: 0.25)\n * --value Current normalized value (0..1)\n *\n * All CSS variables from <ixfx-editable-label> are also inherited.\n *\n * Events:\n * change — CustomEvent<{ value: string }>, bubbles + composed\n * Fired on text-edit commit AND on drag-end (if value changed).\n */\nimport type { CSSResult } from 'lit';\nimport type { WheelDirection } from '../mixins/wheel-nudge.js';\nimport type { EditableLabelChangeDetail } from './editable-label.js';\nimport { css, html } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { resolveAxisStep } from '../keyboard.js';\nimport { WheelNudgeMixin } from '../mixins/wheel-nudge.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { EditableLabel } from './editable-label.js';\n\nconst DRAG_THRESHOLD_PX = 3;\n\n@customElement(`ixfx-editable-number`)\nexport class EditableNumber extends WheelNudgeMixin(EditableLabel) {\n @property({ type: Number }) min?: number;\n @property({ type: Number }) max?: number;\n @property({ type: Number }) step?: number;\n /** Quantised stops for keyboard nudging. Overrides `step` when > 1. */\n @property({ type: Number }) stops?: number;\n @property({ type: Number, attribute: `drag-sensitivity` }) dragSensitivity = 1;\n @property({ attribute: `fill-style` }) fillStyle?: `linear` | `circular`;\n @property({ attribute: `linear-style` }) linearStyle?: `range` | `bipolar` | `unipolar`;\n @property({ attribute: `circular-style` }) circularStyle?: `grow` | `offset` | `dot`;\n @property({ type: Boolean, attribute: `no-drag` }) noDrag = false;\n @property({ type: Number }) precision = 0;\n\n // ── Drag state (not reactive — managed imperatively to avoid Lit cycles) ──\n #dragStartY = 0;\n #dragStartValue = 0;\n #dragging = false;\n #hasDragged = false;\n #dragCurrentValue = 0;\n #lastInputValue = ``;\n #firstUpdateComplete = false;\n\n constructor() {\n super();\n // Override parent defaults for a number input context\n this.mode = `editor`;\n this.entryMode = `number`;\n this.value = `0`;\n }\n\n // ── Render ───────────────────────────────────────────────────────────────────\n\n override render() {\n return html`\n ${this.fillStyle ? html`<div class=\"track\"></div>` : ``}\n ${this.fillStyle ? html`<div class=\"value\"><div class=\"bar\"></div></div>` : ``}\n <div\n class=\"number\"\n part=\"content\"\n tabindex=\"${this.disabled ? -1 : 0}\"\n contenteditable=\"${this._editing ? `plaintext-only` : `false`}\"\n data-placeholder=\"${this.placeholder}\"\n @click=${this._handleClick}\n @focus=${this._handleFocus}\n @blur=${this._handleBlur}\n @keydown=${this._handleKeydown}\n @beforeinput=${this._handleBeforeInput}\n @input=${this._stopNativeInput}\n ></div>\n `;\n }\n\n private _stopNativeInput = (e: Event): void => {\n e.stopPropagation();\n };\n\n // ── Lifecycle ─────────────────────────────────────────────────────────────\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener(`pointerdown`, this._onPointerDown);\n this.addEventListener(`pointermove`, this._onPointerMove);\n this.addEventListener(`pointerup`, this._onPointerUp);\n this.addEventListener(`keydown`, this._onKeyDown);\n this.addEventListener(`click`, this._interceptClick, { capture: true });\n this.addEventListener(`mouseenter`, this._handleMouseEnter);\n this.addEventListener(`mouseleave`, this._handleMouseLeave);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener(`pointerdown`, this._onPointerDown);\n this.removeEventListener(`pointermove`, this._onPointerMove);\n this.removeEventListener(`pointerup`, this._onPointerUp);\n this.removeEventListener(`keydown`, this._onKeyDown);\n this.removeEventListener(`click`, this._interceptClick);\n this.removeEventListener(`mouseenter`, this._handleMouseEnter);\n this.removeEventListener(`mouseleave`, this._handleMouseLeave);\n }\n\n private _handleMouseEnter = (): void => {\n if (this.displayTextLogic !== `transient` || this._editing)\n return;\n this._hovering = true;\n this._clearTransientTimer();\n this._transientTimer = window.setTimeout(() => {\n this._transientShowingValue = true;\n this._requestDisplayUpdate();\n }, this.appearDelay);\n };\n\n private _handleMouseLeave = (): void => {\n if (this.displayTextLogic !== `transient` || this._editing)\n return;\n this._hovering = false;\n this._clearTransientTimer();\n if (this._transientShowingValue) {\n this._transientTimer = window.setTimeout(() => {\n if (!this._hovering) {\n this._transientShowingValue = false;\n this._requestDisplayUpdate();\n }\n }, this.disappearDelay);\n }\n };\n\n // ── Override parent interaction — focus only, edit via keypress ───────────\n\n /** Click just focuses; edit mode is entered by pressing a key while focused. */\n protected _handleClick = (): void => {\n if (this.disabled)\n return;\n this.renderRoot?.querySelector<HTMLElement>(`.number`)?.focus();\n };\n\n /** Suppress auto-edit-on-focus from editor mode; keydown handles it instead. */\n protected override _handleFocus = (): void => { /* intentional no-op */ };\n\n /** Override to use .number instead of .content for text display */\n protected get _contentEl(): HTMLElement | undefined {\n const el = this.renderRoot?.querySelector<HTMLElement>(`.number`);\n return el ?? undefined;\n }\n\n override firstUpdated(changedProperties: Map<string, unknown>): void {\n super.firstUpdated(changedProperties);\n // For 'show' mode, start by showing displayText at rest\n if (this.displayTextLogic === `show`) {\n this._showModeWaitingToHide = true;\n }\n this._updateValueCss(this._normalizedValue());\n this._requestDisplayUpdate();\n }\n\n protected _onUserInteraction(): void {\n if (this.displayTextLogic === `show` && !this._editing) {\n this._clearTransientTimer();\n this._showModeWaitingToHide = false;\n this._requestDisplayUpdate();\n this._transientTimer = window.setTimeout(() => {\n this._showModeWaitingToHide = true;\n this._requestDisplayUpdate();\n }, this.disappearDelay);\n return;\n }\n if (this.displayTextLogic === `transient` && !this._editing) {\n this._clearTransientTimer();\n this._transientShowingValue = true;\n this._requestDisplayUpdate();\n this._transientTimer = window.setTimeout(() => {\n if (!this._hovering) {\n this._transientShowingValue = false;\n this._requestDisplayUpdate();\n }\n }, this.disappearDelay);\n return;\n }\n super._onUserInteraction();\n }\n\n private _onValueChange(): void {\n if (this.displayTextLogic !== `show` || this._editing)\n return;\n\n this._clearTransientTimer();\n this._showModeWaitingToHide = false;\n this._requestDisplayUpdate();\n this._transientTimer = window.setTimeout(() => {\n this._showModeWaitingToHide = true;\n this._requestDisplayUpdate();\n }, this.disappearDelay);\n }\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n // Note: We do NOT call _onValueChange here for 'show' mode.\n // The parent class handles display updates via _requestDisplayUpdate\n // in firstUpdated. Additional value changes are handled via\n // drag/keyboard events that call _onValueChange directly.\n if (!this._editing) {\n this._updateValueCss(this._normalizedValue());\n }\n }\n\n private _updateValueCss(normalized: number): void {\n this.style.setProperty(`--value`, String(normalized));\n\n let valueStart = 0;\n let valueEnd = normalized;\n\n if (this.linearStyle === `bipolar`) {\n if (normalized <= 0.5) {\n valueStart = normalized;\n valueEnd = 0.5;\n } else {\n valueStart = 0.5;\n valueEnd = normalized;\n }\n } else if (this.linearStyle === `unipolar`) {\n valueStart = 0.5 - normalized * 0.5;\n valueEnd = 0.5 + normalized * 0.5;\n }\n\n this.style.setProperty(`--value-start`, String(valueStart));\n this.style.setProperty(`--value-end`, String(valueEnd));\n\n // For circular offset mode, compute pixel offset from center\n // and set component dimensions for radius calculation\n if (this.fillStyle === `circular` && this.circularStyle === `offset`) {\n const h = this.offsetHeight;\n const w = this.offsetWidth;\n const r = h / 2 - 2; // radius with margin to prevent clipping at top/bottom\n // Circle edges must stay 2px inside component edges:\n // - at value=0: circle left edge at 2px\n // - at value=1: circle right edge at w-2px\n const leftEdge = 2;\n const rightEdge = w - 2;\n const valueCenterPx = leftEdge + r + normalized * (rightEdge - leftEdge - 2 * r);\n this.style.setProperty(`--radius`, `${r}px`);\n this.style.setProperty(`--value-center-px`, `${valueCenterPx}px`);\n this.style.setProperty(`--component-width-px`, `${w}px`);\n this.style.setProperty(`--component-height-px`, `${h}px`);\n }\n }\n\n protected override _getDisplayText(): string {\n // In override mode, always show displayText (even when dragging or editing)\n if (this._shouldUseDisplayText()) {\n return this.displayText ?? ``;\n }\n // For transient mode, show the drag value while dragging\n if (this.#dragging) {\n const formatted = this.step !== undefined\n ? this._formatNumber(this.#dragCurrentValue)\n : this.#dragCurrentValue.toFixed(this.precision);\n return this.formatter ? this.formatter(formatted) : formatted;\n }\n // Normal case: when a custom formatter is set, pass raw value so formatter\n // can apply its own precision logic (e.g. \"0.5\" → \"50%\" without precision loss)\n if (this.formatter) {\n const raw = Number.parseFloat(this.value);\n return this.formatter(Number.isNaN(raw) ? this.value : String(raw));\n }\n return this._formatDisplay();\n }\n\n // ── Clamp before parent commits (overrides parent's private _tryCommit) ──\n\n protected override _tryCommit(): void {\n const el = this.renderRoot?.querySelector<HTMLElement>(`.number`);\n if (el) {\n const n = Number.parseFloat(el.textContent?.trim() ?? ``);\n if (!Number.isNaN(n)) {\n el.textContent = this._formatNumber(this._clamp(this._snap(n)));\n }\n }\n super._tryCommit();\n }\n\n // ── Override parent's input handling — fire 'input' events on each keypress ──\n\n protected override _handleBeforeInput = (e: InputEvent): void => {\n if (e.inputType !== `insertText` || !e.data) {\n return;\n }\n\n if (!this._isAllowedInput(e.data)) {\n e.preventDefault();\n return;\n }\n\n const contentEl = this._contentEl;\n if (!contentEl) {\n return;\n }\n\n const currentContent = contentEl.textContent ?? ``;\n const insertPosition = (contentEl as HTMLInputElement).selectionStart ?? currentContent.length;\n const newValue = currentContent.slice(0, insertPosition) + e.data + currentContent.slice(insertPosition);\n\n if (newValue !== this.#lastInputValue) {\n this.#lastInputValue = newValue;\n this.dispatchEvent(new CustomEvent(`input`, {\n detail: { value: newValue },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n protected override _handleKeydown = (e: KeyboardEvent): void => {\n if (!this._editing) {\n return;\n }\n\n if (e.key === `Enter`) {\n e.preventDefault();\n this._tryCommit();\n if (this.mode === `editor`)\n this._contentEl?.blur();\n } else if (e.key === `Escape`) {\n e.preventDefault();\n this.dispatchEvent(new CustomEvent(`cancelled`, {\n detail: { value: this._prevValue },\n bubbles: true,\n composed: true,\n }));\n this._cancelEdit();\n this.dispatchEvent(new CustomEvent(`change`, {\n detail: { value: this._prevValue },\n bubbles: true,\n composed: true,\n }));\n if (this.mode === `editor`)\n this._contentEl?.blur();\n }\n };\n\n // ── Drag event handlers ───────────────────────────────────────────────────\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if (this._editing || this.disabled)\n return;\n\n if (this._handleArrowKey(e)) {\n return;\n }\n\n // Printable characters while focused → enter edit mode.\n // Enter is intentionally excluded: the parent handles Enter for commit,\n // and including it here would re-enter edit mode immediately after commit.\n if (e.key.length === 1) {\n this._onUserInteraction();\n this._beginEdit();\n }\n };\n\n private _handleArrowKey(e: KeyboardEvent): boolean {\n const range = (this.max ?? 100) - (this.min ?? 0);\n if (range === 0)\n return false;\n\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, e.shiftKey);\n\n let delta = 0;\n let handled = false;\n\n switch (e.key) {\n case `ArrowUp`:\n case `ArrowRight`:\n delta = effectiveStep;\n handled = true;\n break;\n case `ArrowDown`:\n case `ArrowLeft`:\n delta = -effectiveStep;\n handled = true;\n break;\n case `Home`:\n delta = -(this._parseValue() - (this.min ?? 0));\n handled = true;\n break;\n case `End`:\n delta = (this.max ?? 0) - this._parseValue();\n handled = true;\n break;\n }\n\n if (handled) {\n e.preventDefault();\n this._applyDelta(delta);\n return true;\n }\n\n return false;\n }\n\n /**\n * Apply a signed delta to the current value, clamp/snap/format, and fire\n * `input`/`change`. Shared between arrow-key handler and the wheel handler.\n */\n private _applyDelta(delta: number): void {\n const prev = this.value;\n const current = this._parseValue();\n const newValue = this._clamp(this._snap(current + delta));\n\n const newValueStr = this.step !== undefined\n ? this._formatNumber(newValue)\n : newValue.toFixed(this.precision);\n\n this.value = newValueStr;\n\n this._requestDisplayUpdate();\n this._updateValueCss(this._normalizedValue(newValue));\n\n if (newValueStr !== prev) {\n this.dispatchEvent(new CustomEvent(`input`, {\n detail: { value: newValueStr },\n bubbles: true,\n composed: true,\n }));\n }\n\n requestAnimationFrame(() => {\n if (this.value !== prev) {\n this.dispatchEvent(new CustomEvent<EditableLabelChangeDetail>(`change`, {\n detail: { value: this.value },\n bubbles: true,\n composed: true,\n }));\n }\n });\n }\n\n // Wheel handler — installed by WheelNudgeMixin on the host. Skipped during\n // text edit so wheel-scrolling the value doesn't fight with the user's typing.\n override _shouldHandleWheel(): boolean {\n if (this._editing)\n return false;\n return super._shouldHandleWheel();\n }\n\n override _applyWheelDelta(direction: WheelDirection, event: WheelEvent): void {\n const range = (this.max ?? 100) - (this.min ?? 0);\n if (range === 0)\n return;\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);\n this._applyDelta(direction * effectiveStep);\n }\n\n private _onPointerDown = (e: PointerEvent): void => {\n if (e.button !== 0)\n return; // left button only\n if (this._editing)\n return; // let contenteditable handle it\n if (this.disabled || this.noDrag)\n return;\n e.preventDefault(); // suppress browser text-select / native drag\n this.renderRoot?.querySelector<HTMLElement>(`.number`)?.focus(); // restore focus manually\n\n this.#dragStartY = e.clientY;\n this.#dragStartValue = this._parseValue();\n this.#dragCurrentValue = this.#dragStartValue;\n this.#dragging = false;\n this.#hasDragged = false;\n this.setPointerCapture(e.pointerId);\n };\n\n private _onPointerMove = (e: PointerEvent): void => {\n if (!(e.buttons & 1))\n return; // left button must be held\n if (this._editing)\n return;\n if (this.disabled || this.noDrag)\n return;\n\n const deltaY = this.#dragStartY - e.clientY; // up = positive\n if (!this.#dragging && Math.abs(deltaY) < DRAG_THRESHOLD_PX)\n return;\n\n this.#dragging = true;\n this.#hasDragged = true;\n this.toggleAttribute(`dragging`, true);\n this._onUserInteraction();\n\n const raw = this.#dragStartValue + deltaY * this.dragSensitivity * (this.step || 1);\n const snapped = this._clamp(this._snap(raw));\n // When step is set, snapping already gives the right precision.\n // When step is unset, round to `precision` decimal places.\n this.#dragCurrentValue = this.step !== undefined\n ? snapped\n : Number.parseFloat(snapped.toFixed(this.precision));\n\n const dragValueStr = this.step !== undefined\n ? this._formatNumber(this.#dragCurrentValue)\n : this.#dragCurrentValue.toFixed(this.precision);\n\n if (dragValueStr !== this.#lastInputValue) {\n this.#lastInputValue = dragValueStr;\n this.dispatchEvent(new CustomEvent(`input`, {\n detail: { value: dragValueStr },\n bubbles: true,\n composed: true,\n }));\n }\n\n // Update display using parent's displayTextLogic handling\n this._requestDisplayUpdate();\n this._updateValueCss(this._normalizedValue(this.#dragCurrentValue));\n };\n\n private _onPointerUp = (e: PointerEvent): void => {\n if (this.hasPointerCapture(e.pointerId))\n this.releasePointerCapture(e.pointerId);\n if (!this.#dragging)\n return;\n if (this.disabled || this.noDrag)\n return;\n\n this.#dragging = false;\n this.toggleAttribute(`dragging`, false);\n // Format with step-based or precision-based dp so trailing zeros are preserved\n // in the stored string (e.g. \"5.0\" when precision=1, not \"5\").\n const finalStr = this.step !== undefined\n ? this._formatNumber(this.#dragCurrentValue)\n : this.#dragCurrentValue.toFixed(this.precision);\n const prev = this.value;\n this.value = finalStr;\n if (finalStr !== prev) {\n this.dispatchEvent(new CustomEvent<EditableLabelChangeDetail>(`change`, {\n detail: { value: finalStr },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n private _interceptClick = (e: MouseEvent): void => {\n if (this.#hasDragged) {\n e.stopImmediatePropagation();\n this.#hasDragged = false;\n }\n };\n\n // ── Number helpers ────────────────────────────────────────────────────────\n\n private _parseValue(): number {\n return Number.parseFloat(this.value) || 0;\n }\n\n /**\n * Formats the stored value for display, inferring decimal places from the value\n * string itself. This preserves typed precision (e.g. \"0.1234\" stays \"0.1234\")\n * and also respects trailing zeros written by drag storage (e.g. \"5.0\" stays \"5.0\").\n */\n private _formatDisplay(): string {\n const n = Number.parseFloat(this.value);\n if (Number.isNaN(n))\n return this.value;\n if (this.precision !== undefined) {\n return n.toFixed(this.precision);\n }\n const dot = this.value.indexOf(`.`);\n const dp = dot >= 0 ? this.value.length - dot - 1 : 0;\n return n.toFixed(dp);\n }\n\n private _clamp(n: number): number {\n if (this.min !== undefined)\n n = Math.max(this.min, n);\n if (this.max !== undefined)\n n = Math.min(this.max, n);\n return n;\n }\n\n private _snap(n: number): number {\n if (this.stops && this.stops > 1) {\n const min = this.min ?? 0;\n const range = (this.max ?? 100) - min;\n const stopStep = range / this.stops;\n return Math.round((n - min) / stopStep) * stopStep + min;\n }\n if (!this.step)\n return n;\n return Math.round(n / this.step) * this.step;\n }\n\n private _inferDecimals(n?: number): number {\n if (this.step !== undefined) {\n const s = String(this.step);\n const dot = s.indexOf(`.`);\n return dot >= 0 ? s.length - dot - 1 : 0;\n }\n // No step set: infer from the value being formatted so floats are preserved\n const s = String(n ?? this._parseValue());\n const dot = s.indexOf(`.`);\n return dot >= 0 ? s.length - dot - 1 : 0;\n }\n\n private _formatNumber(n: number): string {\n return n.toFixed(this._inferDecimals(n));\n }\n\n /** Returns a 0..1 fraction for the given value within [min, max]. */\n private _normalizedValue(n = this._parseValue()): number {\n if (this.min === undefined || this.max === undefined)\n return 0;\n if (this.max === this.min)\n return 0;\n return Math.max(0, Math.min(1, (n - this.min) / (this.max - this.min)));\n }\n\n // ── Styles ───────────────────────────────────────────────────────────────\n\n static override styles: CSSResult[] = [\n themeFallbacks,\n prominenceStyles,\n ...EditableLabel.styles,\n css`\n :host {\n font-size: var(--text-s,11px);\n --value: 0;\n --value-start: 0;\n --value-end: 0;\n --_fill-color-alpha: color-mix(\n in oklch,\n var(--fill-color, var(--accent, oklch(60% 0.15 140))) calc(var(--fill-opacity, 0.25) * 100%),\n transparent\n );\n }\n\n /* ── Layout (when fill-style is enabled) ── */\n :host([fill-style]) {\n display: grid;\n position: relative;\n grid-template-columns: 1fr;\n grid-template-rows: 1fr;\n min-height: 1.5em;\n min-width: 5em;\n }\n\n :host([fill-style]) .track,\n :host([fill-style]) .value {\n grid-area: 1 / 1;\n position: absolute;\n inset: 0;\n }\n\n /* Track background styling */\n :host([fill-style]) .track {\n z-index: 0;\n background: var(--surface-4, oklch(22% 0.02 240));\n border: var(--border, 1px solid oklch(25% 0.02 240));\n }\n\n :host([fill-style]) .value {\n z-index: 1;\n }\n\n :host([fill-style=\"linear\"]) .track {\n border-radius: var(--radius-s, 3px);\n }\n\n :host([fill-style=\"circular\"]) .track {\n border-radius: 50%;\n overflow: hidden;\n }\n\n /* Linear: all linear-styles use .bar positioned via --value-start and --value-end */\n :host([fill-style=\"linear\"]) .value {\n overflow: hidden;\n }\n\n :host([fill-style=\"linear\"]) .bar {\n position: absolute;\n top: 0;\n bottom: 0;\n left: calc(var(--value-start, 0) * 100%);\n width: calc((var(--value-end, 0) - var(--value-start, 0)) * 100%);\n background: var(--fill-image, var(--_fill-color-alpha));\n }\n\n /* Circular grow: filled circle growing from center */\n :host([fill-style=\"circular\"][circular-style=\"grow\"]) .value,\n :host([fill-style=\"circular\"]:not([circular-style])) .value {\n background: var(--fill-image, var(--_fill-color-alpha));\n clip-path: circle(calc(var(--value) * 50%) at 50% 50%);\n }\n\n /* Circular offset: value circle slides left/right from center.\n Track circle is centered, filling the height.\n Value circle is same size, offset by --value-offset-px.\n At value=0.5: value circle centered on track (invisible when overlaid)\n At value=0: value circle at far left\n At value=1: value circle at far right\n */\n :host([fill-style=\"circular\"][circular-style=\"offset\"]) {\n min-width: 80px;\n min-height: 26px;\n overflow: hidden;\n }\n\n :host([fill-style=\"circular\"][circular-style=\"offset\"]) .track {\n position: absolute;\n top: 50%;\n border-radius: 50%;\n background: var(--surface-4, oklch(22% 0.02 240));\n border: var(--border, 1px solid oklch(25% 0.02 240));\n width: calc(var(--radius, 11px) * 2);\n height: calc(var(--radius, 11px) * 2);\n left: 50%;\n transform: translate(-50%, -50%);\n }\n\n :host([fill-style=\"circular\"][circular-style=\"offset\"]) .value {\n position: absolute;\n top: 50%;\n background: var(--fill-image, var(--_fill-color-alpha));\n border-radius: 50%;\n width: calc(var(--radius, 11px) * 2);\n height: calc(var(--radius, 11px) * 2);\n transform: translate(calc(var(--value-center-px, 13px) - var(--radius, 11px)), -50%);\n }\n\n :host([fill-style=\"circular\"][circular-style=\"offset\"]) .number {\n border-radius: 0;\n }\n\n /* Circular dot: full circle */\n :host([fill-style=\"circular\"][circular-style=\"dot\"]) .value {\n background: var(--fill-image, var(--_fill-color-alpha));\n }\n\n /* ── Number (top layer - text display) ── */\n :host([fill-style]) .number {\n position: absolute;\n inset: 0;\n z-index: 2;\n display: flex;\n align-items: center;\n justify-content: center;\n font-family: inherit;\n font-size: inherit;\n color: inherit;\n padding: var(--space-xs, 3px) var(--space-s, 4px);\n }\n\n :host([fill-style=\"circular\"]) .number {\n border-radius: 50%;\n }\n\n /* Drag cursor + no text selection while not in text-edit mode */\n :host(:not([disabled]):not([no-drag])) .number:not([contenteditable=\"plaintext-only\"]) {\n cursor: ns-resize;\n user-select: none;\n -webkit-user-select: none;\n touch-action: none;\n }\n\n /* Focus outline */\n :host .number {\n outline: none;\n }\n\n :host .number:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n\n /* ── Circular host sizing ── */\n :host([fill-style=\"circular\"][circular-style=\"grow\"]),\n :host([fill-style=\"circular\"]:not([circular-style])) {\n aspect-ratio: 1;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-editable-number': EditableNumber;\n }\n}\n","/**\n * <ixfx-labelled-slider-input> — labelled slider input combining ixfx-editable-number and ixfx-slider-input.\n *\n * Layout is driven by container queries on the component's own height:\n * - height >= 80px → vertical (label above slider) — the default with height: 100px\n * - height < 80px → horizontal (label beside slider)\n *\n * Mini mode: hides ixfx-editable-number, shows only the slider.\n * Triggered when width < --mini-width-threshold (default 120px)\n * OR height < --mini-height-threshold (default 45px).\n * Force on/off with CSS variable: --mini: 1 (always mini) | 0 (never mini).\n *\n * Override layout entirely with --flow: row | column (bypasses the container query;\n * --flow: column stacks at any --height, so a tight --height hugs label + slider\n * with no dead space above/below).\n * Override height with --height (e.g. --height: 100% to fill a constrained container).\n * Override the editable-number width (horizontal layout only) with --label-width (e.g. 4em).\n * Override the slider's band thickness in the stacked layout with --slider-thickness (default: 2.5em);\n * extra component height beyond label + slider is split evenly above and below the group.\n *\n * CSS variables (passes through to child components):\n *\n * From ixfx-editable-number:\n * --label-font-size (default: var(--text-m))\n * --label-font-family (default: var(--font-family))\n * --label-color (default: var(--surface-2-text))\n * --label-muted-color (default: var(--surface-muted-text))\n * --label-padding (default: var(--space-xs) var(--space-s))\n * --label-radius (default: var(--radius-s))\n * --label-align (default: center)\n *\n * From ixfx-slider-input:\n * --lane-track-color, --lane-value-color, --lane-color, --lane-<key>-color\n * --lane-dasharray, --lane-dashoffset, --lane-linecap (round | butt)\n * --marker-color, --marker-thickness, --marker-length, --marker-offset\n * --marker-border-width, --marker-border-color, --marker-a-color, etc.\n * --track-color, --track-width, --track-margin\n * --midpoint-color, --midpoint-thickness, --midpoint-length\n *\n * Properties:\n * label Label text content\n * min / max / value / step Range bounds and current value\n * stops Quantise to N discrete positions (default: undefined)\n * drag-sensitivity Steps per pixel of drag (default: 1)\n * precision Decimal places (default: 0)\n * orientation 'horizontal' | 'vertical' (slider orientation)\n * single-style 'range' | 'bipolar' | 'unipolar' (single mode only)\n * marker-style 'needle' | 'dot' | 'triangle' | 'none'\n * disabled Boolean — disables all interaction\n * swipeable Boolean — swipe-to-draw gesture (no pointer capture,\n * for step-sequencer layouts; mirrors ixfx-slider-input)\n * switch-height Height threshold for vertical↔horizontal switch (default: 80)\n * mini-width-threshold Width (in pixels) below which mini mode activates (default: 120)\n * mini-height-threshold Height (in pixels) below which mini mode activates (default: 45)\n * display-text-logic 'hidden' | 'show' | 'override' | 'transient'\n * formatter Function (value: string) => string — formats value for display\n * lighttouch Boolean — passed through to the inner slider and editable-number so wheel\n * adjusts the value on hover instead of requiring focus on either\n *\n * Events:\n * change — CustomEvent<{ value: string }>, bubbles + composed\n * Fired when value changes via slider or editable-number commit\n * input — CustomEvent<{ value: number }>, bubbles + composed\n * Fired on every slider move\n */\nimport type { CSSResultGroup } from 'lit';\nimport type { SliderMarkerStyle, SliderSingleStyle } from '../slider-input/types.js';\nimport { css, html } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { LabelledInputBase } from '../mixins/labelled-input-base.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../editable-label/editable-number.js';\nimport '../slider-input/slider-input.js';\n\n@customElement(`ixfx-labelled-slider-input`)\nexport class LabelledSliderInput extends LabelledInputBase {\n readonly inputSelector = `ixfx-slider-input`;\n\n @property({ type: String }) orientation: `horizontal` | `vertical` = `horizontal`;\n @property({ type: String, attribute: `single-style` }) singleStyle: SliderSingleStyle = `range`;\n @property({ type: String, attribute: `marker-style` }) markerStyle: SliderMarkerStyle = `needle`;\n @property({ type: Number }) stops: number | undefined = undefined;\n @property({ type: Boolean, reflect: true }) disabled = false;\n @property({ type: Boolean, reflect: true }) swipeable = false;\n /** Pass-through: enables wheel-on-hover for the inner slider and editable-number. */\n @property({ type: Boolean }) lighttouch = false;\n\n @property({ type: Number, attribute: `switch-height` }) switchHeight = 80;\n\n protected override _renderEditableNumber() {\n // Override base implementation to pass lighttouch through to the inner\n // editable-number. Mirrors the props forwarded in LabelledInputBase.\n if (this._isMini) {\n // Mini mode: no editable-number rendered at all (matches base behaviour).\n return html``;\n }\n return html`\n <ixfx-editable-number\n class=\"number\"\n mode=\"label\"\n no-drag\n ?lighttouch=${this.lighttouch}\n .value=${String(this.value)}\n .min=${this.min}\n .max=${this.max}\n .step=${this.step}\n .dragSensitivity=${this.dragSensitivity}\n .precision=${this.precision}\n .displayText=${this.label}\n .displayTextLogic=${this._isDragging ? `hidden` : this.displayTextLogic}\n .formatter=${this._formatter}\n @change=${this._handleNumberChange}\n ></ixfx-editable-number>\n `;\n }\n\n protected override _syncValue(v: number): void {\n super._syncValue(v);\n // Base applyValue() sets `.value`, but ixfx-slider-input holds its value\n // in `.valueA` — sync it directly so programmatic changes propagate.\n const input = this.renderRoot?.querySelector(this.inputSelector) as unknown as { valueA?: number } | null;\n if (input && typeof input.valueA === `number` && input.valueA !== v) {\n input.valueA = v;\n }\n }\n\n override render() {\n // No tooltip on the inner slider: the editable-number already shows the\n // value, so a slider tooltip would be redundant.\n return html`\n <div class=\"wrap ${this._isMini ? `mini` : ``}\">\n ${this._renderEditableNumber()}\n <ixfx-slider-input\n class=\"slider\"\n ?lighttouch=${this.lighttouch}\n ?disabled=${this.disabled}\n ?swipeable=${this.swipeable}\n .valueA=${this.value}\n .min=${this.min}\n .max=${this.max}\n .step=${this.step}\n .stops=${this.stops}\n .orientation=${this.orientation}\n .singleStyle=${this.singleStyle}\n .markerStyle=${this.markerStyle}\n @input=${this._handleSliderInput}\n @change=${this._handleInputChange}\n ></ixfx-slider-input>\n </div>\n `;\n }\n\n static styles: CSSResultGroup = css`\n :host {\n display: block;\n container-type: size;\n min-height: var(--min-height, 20px);\n min-width: var(--min-width, 50px);\n width: var(--width, auto);\n height: var(--height, 100px);\n }\n\n /* One focus ring for the whole control: the inner slider's own ring is\n suppressed (see ixfx-slider-input below) and re-drawn here so it wraps\n the label + slider group instead of just the track. */\n :host(:focus-within) {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n\n .wrap {\n display: flex;\n width: 100%;\n height: 100%;\n align-items: center;\n }\n\n ixfx-editable-number {\n flex-shrink: 0;\n }\n\n ixfx-slider-input {\n flex: 1;\n min-width: 0;\n /* Suppress the slider's own focus ring; the wrapper draws one around\n the whole control via :host(:focus-within) above. */\n --slider-input-svg-focus-outline: none;\n --slider-input-svg-focus-outline-offset: 0;\n }\n\n /* Default (compact): horizontal — label beside slider */\n .wrap {\n flex-direction: var(--flow, row);\n justify-content: flex-start;\n align-items: center;\n }\n\n ixfx-editable-number {\n --label-align: left;\n width: var(--label-width, 5ch);\n --label-min-width: var(--label-width, 5ch);\n /* Block fill/background variables from reaching editable-number */\n --fill-color: initial;\n --fill-opacity: initial;\n --fill-image: initial;\n }\n\n /* Vertically-stacked layout: applied when the container is tall enough\n to fit label + slider, OR when the author forces it with --flow:\n column (a style query, so an explicit --flow: column brings the\n label/slider companion rules too — not just the flex direction — and\n therefore works at any --height, not only >= 80px). */\n @container (height >= 80px) or style(--flow: column) {\n .wrap {\n flex-direction: var(--flow, column);\n /* Centre the label+slider group so any height the component is\n given beyond what the two need is split evenly above and below,\n rather than dumped into a stretched slider. */\n justify-content: center;\n align-items: center;\n }\n\n ixfx-editable-number {\n --label-align: center;\n /* Stretch (not width: 100%): in the normal stacked column this is\n visually identical (full-width centered label), but a hardcoded\n 100% width would also apply when --flow forces a row at this\n height — eating the whole row and squeezing the slider to zero. */\n align-self: stretch;\n width: auto;\n }\n\n ixfx-slider-input {\n width: 100%;\n /* Don't stretch to fill the column. The slider paints its bar\n thickness as a fraction of the height it's handed, so a fat\n lane-track-width in a tall slot leaves most of that slot as\n dead space. Cap it to a sensible band (override with\n --slider-thickness) and let the centred group absorb the rest. */\n flex: 0 1 auto;\n height: var(--slider-thickness, 2.5em);\n max-height: 100%;\n }\n }\n\n /* Mini mode: slider fills the full component */\n .wrap.mini {\n gap: 0;\n }\n\n .wrap.mini ixfx-slider-input {\n width: 100%;\n height: 100%;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-labelled-slider-input': LabelledSliderInput;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"labelled-slider-input-aEYDvW2S.js","names":["#lastInputValue","#dragStartY","#dragStartValue","#dragCurrentValue","#dragging","#hasDragged","customElement","customElement"],"sources":["../src/editable-label/editable-number.ts","../src/labelled-slider-input/labelled-slider-input.ts"],"sourcesContent":["/**\n * <ixfx-editable-number> — inline editable number label with Ableton-style drag.\n *\n * Extends <ixfx-editable-label> with:\n * • Pointer drag to adjust value — drag up to increase, down to decrease,\n * without entering full text-edit mode.\n * • Click gives focus; pressing any key while focused enters text-edit mode.\n * • Optional min/max clamping and step snapping.\n * • Optional fill-bar visualization behind the label text.\n *\n * Attributes:\n * min Minimum value (no clamping if unset)\n * max Maximum value (no clamping if unset)\n * step Snap increment, also informs decimal-place display (unset = no snapping)\n * stops Number of quantised keyboard stops (unset = no snapping). Wins over `step` when > 1.\n * drag-sensitivity Steps changed per pixel of drag (default: 1); multiply by step to get units/px\n * precision Decimal places applied when rounding drag-produced values (default: 0 = integers).\n * Has no effect when step is set (step implies its own precision).\n * Typed values are never precision-rounded — the user can always enter finer values.\n * fill-style 'linear' (default) or 'circular' — shape of the fill visualization\n * linear-style 'range' (default), 'bipolar', or 'unipolar' — how value maps to fill (linear mode only)\n * circular-style 'grow' (default), 'offset', or 'dot' — how value maps to fill (circular mode only)\n * no-drag Boolean — disables drag interaction; text editing still works\n * lighttouch Boolean — wheel adjusts the value on hover instead of requiring focus.\n * Wheel is suppressed while the user is typing (`_editing === true`).\n *\n * CSS variables:\n * --fill-color Fill bar color (default: var(--accent))\n * --fill-opacity Fill bar opacity as 0..1 (default: 0.25)\n * --value Current normalized value (0..1)\n *\n * All CSS variables from <ixfx-editable-label> are also inherited.\n *\n * Events:\n * change — CustomEvent<{ value: string }>, bubbles + composed\n * Fired on text-edit commit AND on drag-end (if value changed).\n */\nimport type { CSSResult } from 'lit';\nimport type { WheelDirection } from '../mixins/wheel-nudge.js';\nimport type { EditableLabelChangeDetail } from './editable-label.js';\nimport { css, html } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { resolveAxisStep } from '../keyboard.js';\nimport { WheelNudgeMixin } from '../mixins/wheel-nudge.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { EditableLabel } from './editable-label.js';\n\nconst DRAG_THRESHOLD_PX = 3;\n\n@customElement(`ixfx-editable-number`)\nexport class EditableNumber extends WheelNudgeMixin(EditableLabel) {\n @property({ type: Number }) min?: number;\n @property({ type: Number }) max?: number;\n @property({ type: Number }) step?: number;\n /** Quantised stops for keyboard nudging. Overrides `step` when > 1. */\n @property({ type: Number }) stops?: number;\n @property({ type: Number, attribute: `drag-sensitivity` }) dragSensitivity = 1;\n @property({ attribute: `fill-style` }) fillStyle?: `linear` | `circular`;\n @property({ attribute: `linear-style` }) linearStyle?: `range` | `bipolar` | `unipolar`;\n @property({ attribute: `circular-style` }) circularStyle?: `grow` | `offset` | `dot`;\n @property({ type: Boolean, attribute: `no-drag` }) noDrag = false;\n @property({ type: Number }) precision = 0;\n\n // ── Drag state (not reactive — managed imperatively to avoid Lit cycles) ──\n #dragStartY = 0;\n #dragStartValue = 0;\n #dragging = false;\n #hasDragged = false;\n #dragCurrentValue = 0;\n #lastInputValue = ``;\n #firstUpdateComplete = false;\n\n constructor() {\n super();\n // Override parent defaults for a number input context\n this.mode = `editor`;\n this.entryMode = `number`;\n this.value = `0`;\n }\n\n // ── Render ───────────────────────────────────────────────────────────────────\n\n override render() {\n return html`\n ${this.fillStyle ? html`<div class=\"track\"></div>` : ``}\n ${this.fillStyle ? html`<div class=\"value\"><div class=\"bar\"></div></div>` : ``}\n <div\n class=\"number\"\n part=\"content\"\n tabindex=\"${this.disabled ? -1 : 0}\"\n contenteditable=\"${this._editing ? `plaintext-only` : `false`}\"\n data-placeholder=\"${this.placeholder}\"\n @click=${this._handleClick}\n @focus=${this._handleFocus}\n @blur=${this._handleBlur}\n @keydown=${this._handleKeydown}\n @beforeinput=${this._handleBeforeInput}\n @input=${this._stopNativeInput}\n ></div>\n `;\n }\n\n private _stopNativeInput = (e: Event): void => {\n e.stopPropagation();\n };\n\n // ── Lifecycle ─────────────────────────────────────────────────────────────\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener(`pointerdown`, this._onPointerDown);\n this.addEventListener(`pointermove`, this._onPointerMove);\n this.addEventListener(`pointerup`, this._onPointerUp);\n this.addEventListener(`keydown`, this._onKeyDown);\n this.addEventListener(`click`, this._interceptClick, { capture: true });\n this.addEventListener(`mouseenter`, this._handleMouseEnter);\n this.addEventListener(`mouseleave`, this._handleMouseLeave);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener(`pointerdown`, this._onPointerDown);\n this.removeEventListener(`pointermove`, this._onPointerMove);\n this.removeEventListener(`pointerup`, this._onPointerUp);\n this.removeEventListener(`keydown`, this._onKeyDown);\n this.removeEventListener(`click`, this._interceptClick);\n this.removeEventListener(`mouseenter`, this._handleMouseEnter);\n this.removeEventListener(`mouseleave`, this._handleMouseLeave);\n }\n\n private _handleMouseEnter = (): void => {\n if (this.displayTextLogic !== `transient` || this._editing)\n return;\n this._hovering = true;\n this._clearTransientTimer();\n this._transientTimer = window.setTimeout(() => {\n this._transientShowingValue = true;\n this._requestDisplayUpdate();\n }, this.appearDelay);\n };\n\n private _handleMouseLeave = (): void => {\n if (this.displayTextLogic !== `transient` || this._editing)\n return;\n this._hovering = false;\n this._clearTransientTimer();\n if (this._transientShowingValue) {\n this._transientTimer = window.setTimeout(() => {\n if (!this._hovering) {\n this._transientShowingValue = false;\n this._requestDisplayUpdate();\n }\n }, this.disappearDelay);\n }\n };\n\n // ── Override parent interaction — focus only, edit via keypress ───────────\n\n /** Click just focuses; edit mode is entered by pressing a key while focused. */\n protected _handleClick = (): void => {\n if (this.disabled)\n return;\n this.renderRoot?.querySelector<HTMLElement>(`.number`)?.focus();\n };\n\n /** Suppress auto-edit-on-focus from editor mode; keydown handles it instead. */\n protected override _handleFocus = (): void => { /* intentional no-op */ };\n\n /** Override to use .number instead of .content for text display */\n protected get _contentEl(): HTMLElement | undefined {\n const el = this.renderRoot?.querySelector<HTMLElement>(`.number`);\n return el ?? undefined;\n }\n\n override firstUpdated(changedProperties: Map<string, unknown>): void {\n super.firstUpdated(changedProperties);\n // For 'show' mode, start by showing displayText at rest\n if (this.displayTextLogic === `show`) {\n this._showModeWaitingToHide = true;\n }\n this._updateValueCss(this._normalizedValue());\n this._requestDisplayUpdate();\n }\n\n protected _onUserInteraction(): void {\n if (this.displayTextLogic === `show` && !this._editing) {\n this._clearTransientTimer();\n this._showModeWaitingToHide = false;\n this._requestDisplayUpdate();\n this._transientTimer = window.setTimeout(() => {\n this._showModeWaitingToHide = true;\n this._requestDisplayUpdate();\n }, this.disappearDelay);\n return;\n }\n if (this.displayTextLogic === `transient` && !this._editing) {\n this._clearTransientTimer();\n this._transientShowingValue = true;\n this._requestDisplayUpdate();\n this._transientTimer = window.setTimeout(() => {\n if (!this._hovering) {\n this._transientShowingValue = false;\n this._requestDisplayUpdate();\n }\n }, this.disappearDelay);\n return;\n }\n super._onUserInteraction();\n }\n\n private _onValueChange(): void {\n if (this.displayTextLogic !== `show` || this._editing)\n return;\n\n this._clearTransientTimer();\n this._showModeWaitingToHide = false;\n this._requestDisplayUpdate();\n this._transientTimer = window.setTimeout(() => {\n this._showModeWaitingToHide = true;\n this._requestDisplayUpdate();\n }, this.disappearDelay);\n }\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n // Note: We do NOT call _onValueChange here for 'show' mode.\n // The parent class handles display updates via _requestDisplayUpdate\n // in firstUpdated. Additional value changes are handled via\n // drag/keyboard events that call _onValueChange directly.\n if (!this._editing) {\n this._updateValueCss(this._normalizedValue());\n }\n }\n\n private _updateValueCss(normalized: number): void {\n this.style.setProperty(`--value`, String(normalized));\n\n let valueStart = 0;\n let valueEnd = normalized;\n\n if (this.linearStyle === `bipolar`) {\n if (normalized <= 0.5) {\n valueStart = normalized;\n valueEnd = 0.5;\n } else {\n valueStart = 0.5;\n valueEnd = normalized;\n }\n } else if (this.linearStyle === `unipolar`) {\n valueStart = 0.5 - normalized * 0.5;\n valueEnd = 0.5 + normalized * 0.5;\n }\n\n this.style.setProperty(`--value-start`, String(valueStart));\n this.style.setProperty(`--value-end`, String(valueEnd));\n\n // For circular offset mode, compute pixel offset from center\n // and set component dimensions for radius calculation\n if (this.fillStyle === `circular` && this.circularStyle === `offset`) {\n const h = this.offsetHeight;\n const w = this.offsetWidth;\n const r = h / 2 - 2; // radius with margin to prevent clipping at top/bottom\n // Circle edges must stay 2px inside component edges:\n // - at value=0: circle left edge at 2px\n // - at value=1: circle right edge at w-2px\n const leftEdge = 2;\n const rightEdge = w - 2;\n const valueCenterPx = leftEdge + r + normalized * (rightEdge - leftEdge - 2 * r);\n this.style.setProperty(`--radius`, `${r}px`);\n this.style.setProperty(`--value-center-px`, `${valueCenterPx}px`);\n this.style.setProperty(`--component-width-px`, `${w}px`);\n this.style.setProperty(`--component-height-px`, `${h}px`);\n }\n }\n\n protected override _getDisplayText(): string {\n // In override mode, always show displayText (even when dragging or editing)\n if (this._shouldUseDisplayText()) {\n return this.displayText ?? ``;\n }\n // For transient mode, show the drag value while dragging\n if (this.#dragging) {\n const formatted = this.step !== undefined\n ? this._formatNumber(this.#dragCurrentValue)\n : this.#dragCurrentValue.toFixed(this.precision);\n return this.formatter ? this.formatter(formatted) : formatted;\n }\n // Normal case: when a custom formatter is set, pass raw value so formatter\n // can apply its own precision logic (e.g. \"0.5\" → \"50%\" without precision loss)\n if (this.formatter) {\n const raw = Number.parseFloat(this.value);\n return this.formatter(Number.isNaN(raw) ? this.value : String(raw));\n }\n return this._formatDisplay();\n }\n\n // ── Clamp before parent commits (overrides parent's private _tryCommit) ──\n\n protected override _tryCommit(): void {\n const el = this.renderRoot?.querySelector<HTMLElement>(`.number`);\n if (el) {\n const n = Number.parseFloat(el.textContent?.trim() ?? ``);\n if (!Number.isNaN(n)) {\n el.textContent = this._formatNumber(this._clamp(this._snap(n)));\n }\n }\n super._tryCommit();\n }\n\n // ── Override parent's input handling — fire 'input' events on each keypress ──\n\n protected override _handleBeforeInput = (e: InputEvent): void => {\n if (e.inputType !== `insertText` || !e.data) {\n return;\n }\n\n if (!this._isAllowedInput(e.data)) {\n e.preventDefault();\n return;\n }\n\n const contentEl = this._contentEl;\n if (!contentEl) {\n return;\n }\n\n const currentContent = contentEl.textContent ?? ``;\n const insertPosition = (contentEl as HTMLInputElement).selectionStart ?? currentContent.length;\n const newValue = currentContent.slice(0, insertPosition) + e.data + currentContent.slice(insertPosition);\n\n if (newValue !== this.#lastInputValue) {\n this.#lastInputValue = newValue;\n this.dispatchEvent(new CustomEvent(`input`, {\n detail: { value: newValue },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n protected override _handleKeydown = (e: KeyboardEvent): void => {\n if (!this._editing) {\n return;\n }\n\n if (e.key === `Enter`) {\n e.preventDefault();\n this._tryCommit();\n if (this.mode === `editor`)\n this._contentEl?.blur();\n } else if (e.key === `Escape`) {\n e.preventDefault();\n this.dispatchEvent(new CustomEvent(`cancelled`, {\n detail: { value: this._prevValue },\n bubbles: true,\n composed: true,\n }));\n this._cancelEdit();\n this.dispatchEvent(new CustomEvent(`change`, {\n detail: { value: this._prevValue },\n bubbles: true,\n composed: true,\n }));\n if (this.mode === `editor`)\n this._contentEl?.blur();\n }\n };\n\n // ── Drag event handlers ───────────────────────────────────────────────────\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if (this._editing || this.disabled)\n return;\n\n if (this._handleArrowKey(e)) {\n return;\n }\n\n // Printable characters while focused → enter edit mode.\n // Enter is intentionally excluded: the parent handles Enter for commit,\n // and including it here would re-enter edit mode immediately after commit.\n if (e.key.length === 1) {\n this._onUserInteraction();\n this._beginEdit();\n }\n };\n\n private _handleArrowKey(e: KeyboardEvent): boolean {\n const range = (this.max ?? 100) - (this.min ?? 0);\n if (range === 0)\n return false;\n\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, e.shiftKey);\n\n let delta = 0;\n let handled = false;\n\n switch (e.key) {\n case `ArrowUp`:\n case `ArrowRight`:\n delta = effectiveStep;\n handled = true;\n break;\n case `ArrowDown`:\n case `ArrowLeft`:\n delta = -effectiveStep;\n handled = true;\n break;\n case `Home`:\n delta = -(this._parseValue() - (this.min ?? 0));\n handled = true;\n break;\n case `End`:\n delta = (this.max ?? 0) - this._parseValue();\n handled = true;\n break;\n }\n\n if (handled) {\n e.preventDefault();\n this._applyDelta(delta);\n return true;\n }\n\n return false;\n }\n\n /**\n * Apply a signed delta to the current value, clamp/snap/format, and fire\n * `input`/`change`. Shared between arrow-key handler and the wheel handler.\n */\n private _applyDelta(delta: number): void {\n const prev = this.value;\n const current = this._parseValue();\n const newValue = this._clamp(this._snap(current + delta));\n\n const newValueStr = this.step !== undefined\n ? this._formatNumber(newValue)\n : newValue.toFixed(this.precision);\n\n this.value = newValueStr;\n\n this._requestDisplayUpdate();\n this._updateValueCss(this._normalizedValue(newValue));\n\n if (newValueStr !== prev) {\n this.dispatchEvent(new CustomEvent(`input`, {\n detail: { value: newValueStr },\n bubbles: true,\n composed: true,\n }));\n }\n\n requestAnimationFrame(() => {\n if (this.value !== prev) {\n this.dispatchEvent(new CustomEvent<EditableLabelChangeDetail>(`change`, {\n detail: { value: this.value },\n bubbles: true,\n composed: true,\n }));\n }\n });\n }\n\n // Wheel handler — installed by WheelNudgeMixin on the host. Skipped during\n // text edit so wheel-scrolling the value doesn't fight with the user's typing.\n override _shouldHandleWheel(): boolean {\n if (this._editing)\n return false;\n return super._shouldHandleWheel();\n }\n\n override _applyWheelDelta(direction: WheelDirection, event: WheelEvent): void {\n const range = (this.max ?? 100) - (this.min ?? 0);\n if (range === 0)\n return;\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);\n this._applyDelta(direction * effectiveStep);\n }\n\n private _onPointerDown = (e: PointerEvent): void => {\n if (e.button !== 0)\n return; // left button only\n if (this._editing)\n return; // let contenteditable handle it\n if (this.disabled || this.noDrag)\n return;\n e.preventDefault(); // suppress browser text-select / native drag\n this.renderRoot?.querySelector<HTMLElement>(`.number`)?.focus(); // restore focus manually\n\n this.#dragStartY = e.clientY;\n this.#dragStartValue = this._parseValue();\n this.#dragCurrentValue = this.#dragStartValue;\n this.#dragging = false;\n this.#hasDragged = false;\n this.setPointerCapture(e.pointerId);\n };\n\n private _onPointerMove = (e: PointerEvent): void => {\n if (!(e.buttons & 1))\n return; // left button must be held\n if (this._editing)\n return;\n if (this.disabled || this.noDrag)\n return;\n\n const deltaY = this.#dragStartY - e.clientY; // up = positive\n if (!this.#dragging && Math.abs(deltaY) < DRAG_THRESHOLD_PX)\n return;\n\n this.#dragging = true;\n this.#hasDragged = true;\n this.toggleAttribute(`dragging`, true);\n this._onUserInteraction();\n\n const raw = this.#dragStartValue + deltaY * this.dragSensitivity * (this.step || 1);\n const snapped = this._clamp(this._snap(raw));\n // When step is set, snapping already gives the right precision.\n // When step is unset, round to `precision` decimal places.\n this.#dragCurrentValue = this.step !== undefined\n ? snapped\n : Number.parseFloat(snapped.toFixed(this.precision));\n\n const dragValueStr = this.step !== undefined\n ? this._formatNumber(this.#dragCurrentValue)\n : this.#dragCurrentValue.toFixed(this.precision);\n\n if (dragValueStr !== this.#lastInputValue) {\n this.#lastInputValue = dragValueStr;\n this.dispatchEvent(new CustomEvent(`input`, {\n detail: { value: dragValueStr },\n bubbles: true,\n composed: true,\n }));\n }\n\n // Update display using parent's displayTextLogic handling\n this._requestDisplayUpdate();\n this._updateValueCss(this._normalizedValue(this.#dragCurrentValue));\n };\n\n private _onPointerUp = (e: PointerEvent): void => {\n if (this.hasPointerCapture(e.pointerId))\n this.releasePointerCapture(e.pointerId);\n if (!this.#dragging)\n return;\n if (this.disabled || this.noDrag)\n return;\n\n this.#dragging = false;\n this.toggleAttribute(`dragging`, false);\n // Format with step-based or precision-based dp so trailing zeros are preserved\n // in the stored string (e.g. \"5.0\" when precision=1, not \"5\").\n const finalStr = this.step !== undefined\n ? this._formatNumber(this.#dragCurrentValue)\n : this.#dragCurrentValue.toFixed(this.precision);\n const prev = this.value;\n this.value = finalStr;\n if (finalStr !== prev) {\n this.dispatchEvent(new CustomEvent<EditableLabelChangeDetail>(`change`, {\n detail: { value: finalStr },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n private _interceptClick = (e: MouseEvent): void => {\n if (this.#hasDragged) {\n e.stopImmediatePropagation();\n this.#hasDragged = false;\n }\n };\n\n // ── Number helpers ────────────────────────────────────────────────────────\n\n private _parseValue(): number {\n return Number.parseFloat(this.value) || 0;\n }\n\n /**\n * Formats the stored value for display, inferring decimal places from the value\n * string itself. This preserves typed precision (e.g. \"0.1234\" stays \"0.1234\")\n * and also respects trailing zeros written by drag storage (e.g. \"5.0\" stays \"5.0\").\n */\n private _formatDisplay(): string {\n const n = Number.parseFloat(this.value);\n if (Number.isNaN(n))\n return this.value;\n if (this.precision !== undefined) {\n return n.toFixed(this.precision);\n }\n const dot = this.value.indexOf(`.`);\n const dp = dot >= 0 ? this.value.length - dot - 1 : 0;\n return n.toFixed(dp);\n }\n\n private _clamp(n: number): number {\n if (this.min !== undefined)\n n = Math.max(this.min, n);\n if (this.max !== undefined)\n n = Math.min(this.max, n);\n return n;\n }\n\n private _snap(n: number): number {\n if (this.stops && this.stops > 1) {\n const min = this.min ?? 0;\n const range = (this.max ?? 100) - min;\n const stopStep = range / this.stops;\n return Math.round((n - min) / stopStep) * stopStep + min;\n }\n if (!this.step)\n return n;\n return Math.round(n / this.step) * this.step;\n }\n\n private _inferDecimals(n?: number): number {\n if (this.step !== undefined) {\n const s = String(this.step);\n const dot = s.indexOf(`.`);\n return dot >= 0 ? s.length - dot - 1 : 0;\n }\n // No step set: infer from the value being formatted so floats are preserved\n const s = String(n ?? this._parseValue());\n const dot = s.indexOf(`.`);\n return dot >= 0 ? s.length - dot - 1 : 0;\n }\n\n private _formatNumber(n: number): string {\n return n.toFixed(this._inferDecimals(n));\n }\n\n /** Returns a 0..1 fraction for the given value within [min, max]. */\n private _normalizedValue(n = this._parseValue()): number {\n if (this.min === undefined || this.max === undefined)\n return 0;\n if (this.max === this.min)\n return 0;\n return Math.max(0, Math.min(1, (n - this.min) / (this.max - this.min)));\n }\n\n // ── Styles ───────────────────────────────────────────────────────────────\n\n static override styles: CSSResult[] = [\n themeFallbacks,\n prominenceStyles,\n ...EditableLabel.styles,\n css`\n :host {\n font-size: var(--text-s,11px);\n --value: 0;\n --value-start: 0;\n --value-end: 0;\n --_fill-color-alpha: color-mix(\n in oklch,\n var(--fill-color, var(--accent, oklch(60% 0.15 140))) calc(var(--fill-opacity, 0.25) * 100%),\n transparent\n );\n }\n\n /* ── Layout (when fill-style is enabled) ── */\n :host([fill-style]) {\n display: grid;\n position: relative;\n grid-template-columns: 1fr;\n grid-template-rows: 1fr;\n min-height: 1.5em;\n min-width: 5em;\n }\n\n :host([fill-style]) .track,\n :host([fill-style]) .value {\n grid-area: 1 / 1;\n position: absolute;\n inset: 0;\n }\n\n /* Track background styling */\n :host([fill-style]) .track {\n z-index: 0;\n background: var(--surface-4, oklch(22% 0.02 240));\n border: var(--border, 1px solid oklch(25% 0.02 240));\n }\n\n :host([fill-style]) .value {\n z-index: 1;\n }\n\n :host([fill-style=\"linear\"]) .track {\n border-radius: var(--radius-s, 3px);\n }\n\n :host([fill-style=\"circular\"]) .track {\n border-radius: 50%;\n overflow: hidden;\n }\n\n /* Linear: all linear-styles use .bar positioned via --value-start and --value-end */\n :host([fill-style=\"linear\"]) .value {\n overflow: hidden;\n }\n\n :host([fill-style=\"linear\"]) .bar {\n position: absolute;\n top: 0;\n bottom: 0;\n left: calc(var(--value-start, 0) * 100%);\n width: calc((var(--value-end, 0) - var(--value-start, 0)) * 100%);\n background: var(--fill-image, var(--_fill-color-alpha));\n }\n\n /* Circular grow: filled circle growing from center */\n :host([fill-style=\"circular\"][circular-style=\"grow\"]) .value,\n :host([fill-style=\"circular\"]:not([circular-style])) .value {\n background: var(--fill-image, var(--_fill-color-alpha));\n clip-path: circle(calc(var(--value) * 50%) at 50% 50%);\n }\n\n /* Circular offset: value circle slides left/right from center.\n Track circle is centered, filling the height.\n Value circle is same size, offset by --value-offset-px.\n At value=0.5: value circle centered on track (invisible when overlaid)\n At value=0: value circle at far left\n At value=1: value circle at far right\n */\n :host([fill-style=\"circular\"][circular-style=\"offset\"]) {\n min-width: 80px;\n min-height: 26px;\n overflow: hidden;\n }\n\n :host([fill-style=\"circular\"][circular-style=\"offset\"]) .track {\n position: absolute;\n top: 50%;\n border-radius: 50%;\n background: var(--surface-4, oklch(22% 0.02 240));\n border: var(--border, 1px solid oklch(25% 0.02 240));\n width: calc(var(--radius, 11px) * 2);\n height: calc(var(--radius, 11px) * 2);\n left: 50%;\n transform: translate(-50%, -50%);\n }\n\n :host([fill-style=\"circular\"][circular-style=\"offset\"]) .value {\n position: absolute;\n top: 50%;\n background: var(--fill-image, var(--_fill-color-alpha));\n border-radius: 50%;\n width: calc(var(--radius, 11px) * 2);\n height: calc(var(--radius, 11px) * 2);\n transform: translate(calc(var(--value-center-px, 13px) - var(--radius, 11px)), -50%);\n }\n\n :host([fill-style=\"circular\"][circular-style=\"offset\"]) .number {\n border-radius: 0;\n }\n\n /* Circular dot: full circle */\n :host([fill-style=\"circular\"][circular-style=\"dot\"]) .value {\n background: var(--fill-image, var(--_fill-color-alpha));\n }\n\n /* ── Number (top layer - text display) ── */\n :host([fill-style]) .number {\n position: absolute;\n inset: 0;\n z-index: 2;\n display: flex;\n align-items: center;\n justify-content: center;\n font-family: inherit;\n font-size: inherit;\n color: inherit;\n padding: var(--space-xs, 3px) var(--space-s, 4px);\n }\n\n :host([fill-style=\"circular\"]) .number {\n border-radius: 50%;\n }\n\n /* Drag cursor + no text selection while not in text-edit mode */\n :host(:not([disabled]):not([no-drag])) .number:not([contenteditable=\"plaintext-only\"]) {\n cursor: ns-resize;\n user-select: none;\n -webkit-user-select: none;\n touch-action: none;\n }\n\n /* Focus outline */\n :host .number {\n outline: none;\n }\n\n :host .number:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n\n /* ── Circular host sizing ── */\n :host([fill-style=\"circular\"][circular-style=\"grow\"]),\n :host([fill-style=\"circular\"]:not([circular-style])) {\n aspect-ratio: 1;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-editable-number': EditableNumber;\n }\n}\n","/**\n * <ixfx-labelled-slider-input> — labelled slider input combining ixfx-editable-number and ixfx-slider-input.\n *\n * Layout is driven by container queries on the component's own height:\n * - height >= 80px → vertical (label above slider) — the default with height: 100px\n * - height < 80px → horizontal (label beside slider)\n *\n * Mini mode: hides ixfx-editable-number, shows only the slider.\n * Triggered when width < --mini-width-threshold (default 120px)\n * OR height < --mini-height-threshold (default 45px).\n * Force on/off with CSS variable: --mini: 1 (always mini) | 0 (never mini).\n *\n * Override layout entirely with --flow: row | column (bypasses the container query;\n * --flow: column stacks at any --height, so a tight --height hugs label + slider\n * with no dead space above/below).\n * Override height with --height (e.g. --height: 100% to fill a constrained container).\n * Override the editable-number width (horizontal layout only) with --label-width (e.g. 4em).\n * Override the slider's band thickness in the stacked layout with --slider-thickness (default: 2.5em);\n * extra component height beyond label + slider is split evenly above and below the group.\n *\n * CSS variables (passes through to child components):\n *\n * From ixfx-editable-number:\n * --label-font-size (default: var(--text-m))\n * --label-font-family (default: var(--font-family))\n * --label-color (default: var(--surface-2-text))\n * --label-muted-color (default: var(--surface-muted-text))\n * --label-padding (default: var(--space-xs) var(--space-s))\n * --label-radius (default: var(--radius-s))\n * --label-align (default: center)\n *\n * From ixfx-slider-input:\n * --lane-track-color, --lane-value-color, --lane-color, --lane-<key>-color\n * --lane-dasharray, --lane-dashoffset, --lane-linecap (round | butt)\n * --marker-color, --marker-thickness, --marker-length, --marker-offset\n * --marker-border-width, --marker-border-color, --marker-a-color, etc.\n * --track-color, --track-width, --track-margin\n * --midpoint-color, --midpoint-thickness, --midpoint-length\n *\n * Properties:\n * label Label text content\n * min / max / value / step Range bounds and current value\n * stops Quantise to N discrete positions (default: undefined)\n * drag-sensitivity Steps per pixel of drag (default: 1)\n * precision Decimal places (default: 0)\n * orientation 'horizontal' | 'vertical' (slider orientation)\n * single-style 'range' | 'bipolar' | 'unipolar' (single mode only)\n * marker-style 'needle' | 'dot' | 'triangle' | 'none'\n * disabled Boolean — disables all interaction\n * swipeable Boolean — swipe-to-draw gesture (no pointer capture,\n * for step-sequencer layouts; mirrors ixfx-slider-input)\n * switch-height Height threshold for vertical↔horizontal switch (default: 80)\n * mini-width-threshold Width (in pixels) below which mini mode activates (default: 120)\n * mini-height-threshold Height (in pixels) below which mini mode activates (default: 45)\n * display-text-logic 'hidden' | 'show' | 'override' | 'transient'\n * formatter Function (value: string) => string — formats value for display\n * lighttouch Boolean — passed through to the inner slider and editable-number so wheel\n * adjusts the value on hover instead of requiring focus on either\n *\n * Events:\n * change — CustomEvent<{ value: string }>, bubbles + composed\n * Fired when value changes via slider or editable-number commit\n * input — CustomEvent<{ value: number }>, bubbles + composed\n * Fired on every slider move\n */\nimport type { CSSResultGroup } from 'lit';\nimport type { SliderMarkerStyle, SliderSingleStyle } from '../slider-input/types.js';\nimport { css, html } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { LabelledInputBase } from '../mixins/labelled-input-base.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../editable-label/editable-number.js';\nimport '../slider-input/slider-input.js';\n\n@customElement(`ixfx-labelled-slider-input`)\nexport class LabelledSliderInput extends LabelledInputBase {\n readonly inputSelector = `ixfx-slider-input`;\n\n @property({ type: String }) orientation: `horizontal` | `vertical` = `horizontal`;\n @property({ type: String, attribute: `single-style` }) singleStyle: SliderSingleStyle = `range`;\n @property({ type: String, attribute: `marker-style` }) markerStyle: SliderMarkerStyle = `needle`;\n @property({ type: Number }) stops: number | undefined = undefined;\n @property({ type: Boolean, reflect: true }) disabled = false;\n @property({ type: Boolean, reflect: true }) swipeable = false;\n /** Pass-through: enables wheel-on-hover for the inner slider and editable-number. */\n @property({ type: Boolean }) lighttouch = false;\n\n @property({ type: Number, attribute: `switch-height` }) switchHeight = 80;\n\n protected override _renderEditableNumber() {\n // Override base implementation to pass lighttouch through to the inner\n // editable-number. Mirrors the props forwarded in LabelledInputBase.\n if (this._isMini) {\n // Mini mode: no editable-number rendered at all (matches base behaviour).\n return html``;\n }\n return html`\n <ixfx-editable-number\n class=\"number\"\n mode=\"label\"\n no-drag\n ?lighttouch=${this.lighttouch}\n .value=${String(this.value)}\n .min=${this.min}\n .max=${this.max}\n .step=${this.step}\n .dragSensitivity=${this.dragSensitivity}\n .precision=${this.precision}\n .displayText=${this.label}\n .displayTextLogic=${this._isDragging ? `hidden` : this.displayTextLogic}\n .formatter=${this._formatter}\n @change=${this._handleNumberChange}\n ></ixfx-editable-number>\n `;\n }\n\n protected override _syncValue(v: number): void {\n super._syncValue(v);\n // Base applyValue() sets `.value`, but ixfx-slider-input holds its value\n // in `.valueA` — sync it directly so programmatic changes propagate.\n const input = this.renderRoot?.querySelector(this.inputSelector) as unknown as { valueA?: number } | null;\n if (input && typeof input.valueA === `number` && input.valueA !== v) {\n input.valueA = v;\n }\n }\n\n override render() {\n // No tooltip on the inner slider: the editable-number already shows the\n // value, so a slider tooltip would be redundant.\n return html`\n <div class=\"wrap ${this._isMini ? `mini` : ``}\">\n ${this._renderEditableNumber()}\n <ixfx-slider-input\n class=\"slider\"\n ?lighttouch=${this.lighttouch}\n ?disabled=${this.disabled}\n ?swipeable=${this.swipeable}\n .valueA=${this.value}\n .min=${this.min}\n .max=${this.max}\n .step=${this.step}\n .stops=${this.stops}\n .orientation=${this.orientation}\n .singleStyle=${this.singleStyle}\n .markerStyle=${this.markerStyle}\n @input=${this._handleSliderInput}\n @change=${this._handleInputChange}\n ></ixfx-slider-input>\n </div>\n `;\n }\n\n static styles: CSSResultGroup = css`\n :host {\n display: block;\n container-type: size;\n min-height: var(--min-height, 20px);\n min-width: var(--min-width, 50px);\n width: var(--width, auto);\n height: var(--height, 100px);\n }\n\n /* One focus ring for the whole control: the inner slider's own ring is\n suppressed (see ixfx-slider-input below) and re-drawn here so it wraps\n the label + slider group instead of just the track. */\n :host(:focus-within) {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n\n .wrap {\n display: flex;\n width: 100%;\n height: 100%;\n align-items: center;\n }\n\n ixfx-editable-number {\n flex-shrink: 0;\n }\n\n ixfx-slider-input {\n flex: 1;\n min-width: 0;\n /* Suppress the slider's own focus ring; the wrapper draws one around\n the whole control via :host(:focus-within) above. */\n --slider-input-svg-focus-outline: none;\n --slider-input-svg-focus-outline-offset: 0;\n }\n\n /* Default (compact): horizontal — label beside slider */\n .wrap {\n flex-direction: var(--flow, row);\n justify-content: flex-start;\n align-items: center;\n }\n\n ixfx-editable-number {\n --label-align: left;\n width: var(--label-width, 5ch);\n --label-min-width: var(--label-width, 5ch);\n /* Block fill/background variables from reaching editable-number */\n --fill-color: initial;\n --fill-opacity: initial;\n --fill-image: initial;\n }\n\n /* Vertically-stacked layout: applied when the container is tall enough\n to fit label + slider, OR when the author forces it with --flow:\n column (a style query, so an explicit --flow: column brings the\n label/slider companion rules too — not just the flex direction — and\n therefore works at any --height, not only >= 80px). */\n @container (height >= 80px) or style(--flow: column) {\n .wrap {\n flex-direction: var(--flow, column);\n /* Centre the label+slider group so any height the component is\n given beyond what the two need is split evenly above and below,\n rather than dumped into a stretched slider. */\n justify-content: center;\n align-items: center;\n }\n\n ixfx-editable-number {\n --label-align: center;\n /* Stretch (not width: 100%): in the normal stacked column this is\n visually identical (full-width centered label), but a hardcoded\n 100% width would also apply when --flow forces a row at this\n height — eating the whole row and squeezing the slider to zero. */\n align-self: stretch;\n width: auto;\n }\n\n ixfx-slider-input {\n width: 100%;\n /* Don't stretch to fill the column. The slider paints its bar\n thickness as a fraction of the height it's handed, so a fat\n lane-track-width in a tall slot leaves most of that slot as\n dead space. Cap it to a sensible band (override with\n --slider-thickness) and let the centred group absorb the rest. */\n flex: 0 1 auto;\n height: var(--slider-thickness, 2.5em);\n max-height: 100%;\n }\n }\n\n /* Mini mode: slider fills the full component */\n .wrap.mini {\n gap: 0;\n }\n\n .wrap.mini ixfx-slider-input {\n width: 100%;\n height: 100%;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-labelled-slider-input': LabelledSliderInput;\n }\n}\n"],"mappings":";;;;;;;;;;;AAiDA,MAAM,oBAAoB;AAGnB,IAAM,iBAAN,MAAM,uBAAuB,gBAAgB,aAAa,CAAC,CAAC;CAcjE;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,cAAc;EACZ,MAAM;EAjBqE,KAAA,kBAAA;EAIjB,KAAA,SAAA;EACpB,KAAA,YAAA;EAG1B,KAAA,cAAA;EACI,KAAA,kBAAA;EACN,KAAA,YAAA;EACE,KAAA,cAAA;EACM,KAAA,oBAAA;EACF,KAAA,kBAAA;EACK,KAAA,uBAAA;EAgCK,KAAA,oBAAA,MAAmB;GAC7C,EAAE,gBAAgB;EACpB;EA0BwC,KAAA,0BAAA;GACtC,IAAI,KAAK,qBAAqB,eAAe,KAAK,UAChD;GACF,KAAK,YAAY;GACjB,KAAK,qBAAqB;GAC1B,KAAK,kBAAkB,OAAO,iBAAiB;IAC7C,KAAK,yBAAyB;IAC9B,KAAK,sBAAsB;GAC7B,GAAG,KAAK,WAAW;EACrB;EAEwC,KAAA,0BAAA;GACtC,IAAI,KAAK,qBAAqB,eAAe,KAAK,UAChD;GACF,KAAK,YAAY;GACjB,KAAK,qBAAqB;GAC1B,IAAI,KAAK,wBACP,KAAK,kBAAkB,OAAO,iBAAiB;IAC7C,IAAI,CAAC,KAAK,WAAW;KACnB,KAAK,yBAAyB;KAC9B,KAAK,sBAAsB;IAC7B;GACF,GAAG,KAAK,cAAc;EAE1B;EAKqC,KAAA,qBAAA;GACnC,IAAI,KAAK,UACP;GACF,KAAK,YAAY,cAA2B,SAAS,CAAC,EAAE,MAAM;EAChE;EAG8C,KAAA,qBAAA,CAA0B;EAiJ/B,KAAA,sBAAA,MAAwB;GAC/D,IAAI,EAAE,cAAc,gBAAgB,CAAC,EAAE,MACrC;GAGF,IAAI,CAAC,KAAK,gBAAgB,EAAE,IAAI,GAAG;IACjC,EAAE,eAAe;IACjB;GACF;GAEA,MAAM,YAAY,KAAK;GACvB,IAAI,CAAC,WACH;GAGF,MAAM,iBAAiB,UAAU,eAAe;GAChD,MAAM,iBAAkB,UAA+B,kBAAkB,eAAe;GACxF,MAAM,WAAW,eAAe,MAAM,GAAG,cAAc,IAAI,EAAE,OAAO,eAAe,MAAM,cAAc;GAEvG,IAAI,aAAa,KAAKA,iBAAiB;IACrC,KAAKA,kBAAkB;IACvB,KAAK,cAAc,IAAI,YAAY,SAAS;KAC1C,QAAQ,EAAE,OAAO,SAAS;KAC1B,SAAS;KACT,UAAU;IACZ,CAAC,CAAC;GACJ;EACF;EAEqC,KAAA,kBAAA,MAA2B;GAC9D,IAAI,CAAC,KAAK,UACR;GAGF,IAAI,EAAE,QAAQ,SAAS;IACrB,EAAE,eAAe;IACjB,KAAK,WAAW;IAChB,IAAI,KAAK,SAAS,UAChB,KAAK,YAAY,KAAK;GAC1B,OAAO,IAAI,EAAE,QAAQ,UAAU;IAC7B,EAAE,eAAe;IACjB,KAAK,cAAc,IAAI,YAAY,aAAa;KAC9C,QAAQ,EAAE,OAAO,KAAK,WAAW;KACjC,SAAS;KACT,UAAU;IACZ,CAAC,CAAC;IACF,KAAK,YAAY;IACjB,KAAK,cAAc,IAAI,YAAY,UAAU;KAC3C,QAAQ,EAAE,OAAO,KAAK,WAAW;KACjC,SAAS;KACT,UAAU;IACZ,CAAC,CAAC;IACF,IAAI,KAAK,SAAS,UAChB,KAAK,YAAY,KAAK;GAC1B;EACF;EAIsB,KAAA,cAAA,MAA2B;GAC/C,IAAI,KAAK,YAAY,KAAK,UACxB;GAEF,IAAI,KAAK,gBAAgB,CAAC,GACxB;GAMF,IAAI,EAAE,IAAI,WAAW,GAAG;IACtB,KAAK,mBAAmB;IACxB,KAAK,WAAW;GAClB;EACF;EA+F0B,KAAA,kBAAA,MAA0B;GAClD,IAAI,EAAE,WAAW,GACf;GACF,IAAI,KAAK,UACP;GACF,IAAI,KAAK,YAAY,KAAK,QACxB;GACF,EAAE,eAAe;GACjB,KAAK,YAAY,cAA2B,SAAS,CAAC,EAAE,MAAM;GAE9D,KAAKC,cAAc,EAAE;GACrB,KAAKC,kBAAkB,KAAK,YAAY;GACxC,KAAKC,oBAAoB,KAAKD;GAC9B,KAAKE,YAAY;GACjB,KAAKC,cAAc;GACnB,KAAK,kBAAkB,EAAE,SAAS;EACpC;EAE0B,KAAA,kBAAA,MAA0B;GAClD,IAAI,EAAE,EAAE,UAAU,IAChB;GACF,IAAI,KAAK,UACP;GACF,IAAI,KAAK,YAAY,KAAK,QACxB;GAEF,MAAM,SAAS,KAAKJ,cAAc,EAAE;GACpC,IAAI,CAAC,KAAKG,aAAa,KAAK,IAAI,MAAM,IAAI,mBACxC;GAEF,KAAKA,YAAY;GACjB,KAAKC,cAAc;GACnB,KAAK,gBAAgB,YAAY,IAAI;GACrC,KAAK,mBAAmB;GAExB,MAAM,MAAM,KAAKH,kBAAkB,SAAS,KAAK,mBAAmB,KAAK,QAAQ;GACjF,MAAM,UAAU,KAAK,OAAO,KAAK,MAAM,GAAG,CAAC;GAG3C,KAAKC,oBAAoB,KAAK,SAAS,KAAA,IACnC,UACA,OAAO,WAAW,QAAQ,QAAQ,KAAK,SAAS,CAAC;GAErD,MAAM,eAAe,KAAK,SAAS,KAAA,IAC/B,KAAK,cAAc,KAAKA,iBAAiB,IACzC,KAAKA,kBAAkB,QAAQ,KAAK,SAAS;GAEjD,IAAI,iBAAiB,KAAKH,iBAAiB;IACzC,KAAKA,kBAAkB;IACvB,KAAK,cAAc,IAAI,YAAY,SAAS;KAC1C,QAAQ,EAAE,OAAO,aAAa;KAC9B,SAAS;KACT,UAAU;IACZ,CAAC,CAAC;GACJ;GAGA,KAAK,sBAAsB;GAC3B,KAAK,gBAAgB,KAAK,iBAAiB,KAAKG,iBAAiB,CAAC;EACpE;EAEwB,KAAA,gBAAA,MAA0B;GAChD,IAAI,KAAK,kBAAkB,EAAE,SAAS,GACpC,KAAK,sBAAsB,EAAE,SAAS;GACxC,IAAI,CAAC,KAAKC,WACR;GACF,IAAI,KAAK,YAAY,KAAK,QACxB;GAEF,KAAKA,YAAY;GACjB,KAAK,gBAAgB,YAAY,KAAK;GAGtC,MAAM,WAAW,KAAK,SAAS,KAAA,IAC3B,KAAK,cAAc,KAAKD,iBAAiB,IACzC,KAAKA,kBAAkB,QAAQ,KAAK,SAAS;GACjD,MAAM,OAAO,KAAK;GAClB,KAAK,QAAQ;GACb,IAAI,aAAa,MACf,KAAK,cAAc,IAAI,YAAuC,UAAU;IACtE,QAAQ,EAAE,OAAO,SAAS;IAC1B,SAAS;IACT,UAAU;GACZ,CAAC,CAAC;EAEN;EAE2B,KAAA,mBAAA,MAAwB;GACjD,IAAI,KAAKE,aAAa;IACpB,EAAE,yBAAyB;IAC3B,KAAKA,cAAc;GACrB;EACF;EAjfE,KAAK,OAAO;EACZ,KAAK,YAAY;EACjB,KAAK,QAAQ;CACf;CAIA,SAAkB;EAChB,OAAO,IAAI;QACP,KAAK,YAAY,IAAI,8BAA8B,GAAG;QACtD,KAAK,YAAY,IAAI,qDAAqD,GAAG;;;;oBAIjE,KAAK,WAAW,KAAK,EAAE;2BAChB,KAAK,WAAW,mBAAmB,QAAQ;4BAC1C,KAAK,YAAY;iBAC5B,KAAK,aAAa;iBAClB,KAAK,aAAa;gBACnB,KAAK,YAAY;mBACd,KAAK,eAAe;uBAChB,KAAK,mBAAmB;iBAC9B,KAAK,iBAAiB;;;CAGrC;CAQA,oBAAmC;EACjC,MAAM,kBAAkB;EACxB,KAAK,iBAAiB,eAAe,KAAK,cAAc;EACxD,KAAK,iBAAiB,eAAe,KAAK,cAAc;EACxD,KAAK,iBAAiB,aAAa,KAAK,YAAY;EACpD,KAAK,iBAAiB,WAAW,KAAK,UAAU;EAChD,KAAK,iBAAiB,SAAS,KAAK,iBAAiB,EAAE,SAAS,KAAK,CAAC;EACtE,KAAK,iBAAiB,cAAc,KAAK,iBAAiB;EAC1D,KAAK,iBAAiB,cAAc,KAAK,iBAAiB;CAC5D;CAEA,uBAAsC;EACpC,MAAM,qBAAqB;EAC3B,KAAK,oBAAoB,eAAe,KAAK,cAAc;EAC3D,KAAK,oBAAoB,eAAe,KAAK,cAAc;EAC3D,KAAK,oBAAoB,aAAa,KAAK,YAAY;EACvD,KAAK,oBAAoB,WAAW,KAAK,UAAU;EACnD,KAAK,oBAAoB,SAAS,KAAK,eAAe;EACtD,KAAK,oBAAoB,cAAc,KAAK,iBAAiB;EAC7D,KAAK,oBAAoB,cAAc,KAAK,iBAAiB;CAC/D;;CAyCA,IAAc,aAAsC;EAElD,OADW,KAAK,YAAY,cAA2B,SAAS,KACnD,KAAA;CACf;CAEA,aAAsB,mBAA+C;EACnE,MAAM,aAAa,iBAAiB;EAEpC,IAAI,KAAK,qBAAqB,QAC5B,KAAK,yBAAyB;EAEhC,KAAK,gBAAgB,KAAK,iBAAiB,CAAC;EAC5C,KAAK,sBAAsB;CAC7B;CAEA,qBAAqC;EACnC,IAAI,KAAK,qBAAqB,UAAU,CAAC,KAAK,UAAU;GACtD,KAAK,qBAAqB;GAC1B,KAAK,yBAAyB;GAC9B,KAAK,sBAAsB;GAC3B,KAAK,kBAAkB,OAAO,iBAAiB;IAC7C,KAAK,yBAAyB;IAC9B,KAAK,sBAAsB;GAC7B,GAAG,KAAK,cAAc;GACtB;EACF;EACA,IAAI,KAAK,qBAAqB,eAAe,CAAC,KAAK,UAAU;GAC3D,KAAK,qBAAqB;GAC1B,KAAK,yBAAyB;GAC9B,KAAK,sBAAsB;GAC3B,KAAK,kBAAkB,OAAO,iBAAiB;IAC7C,IAAI,CAAC,KAAK,WAAW;KACnB,KAAK,yBAAyB;KAC9B,KAAK,sBAAsB;IAC7B;GACF,GAAG,KAAK,cAAc;GACtB;EACF;EACA,MAAM,mBAAmB;CAC3B;CAEA,iBAA+B;EAC7B,IAAI,KAAK,qBAAqB,UAAU,KAAK,UAC3C;EAEF,KAAK,qBAAqB;EAC1B,KAAK,yBAAyB;EAC9B,KAAK,sBAAsB;EAC3B,KAAK,kBAAkB,OAAO,iBAAiB;GAC7C,KAAK,yBAAyB;GAC9B,KAAK,sBAAsB;EAC7B,GAAG,KAAK,cAAc;CACxB;CAEA,QAAiB,mBAA+C;EAC9D,MAAM,QAAQ,iBAAiB;EAK/B,IAAI,CAAC,KAAK,UACR,KAAK,gBAAgB,KAAK,iBAAiB,CAAC;CAEhD;CAEA,gBAAwB,YAA0B;EAChD,KAAK,MAAM,YAAY,WAAW,OAAO,UAAU,CAAC;EAEpD,IAAI,aAAa;EACjB,IAAI,WAAW;EAEf,IAAI,KAAK,gBAAgB,WAAW;GAClC,IAAI,cAAc,IAAK;IACrB,aAAa;IACb,WAAW;GACb,OAAO;IACL,aAAa;IACb,WAAW;GACb;EACF,OAAO,IAAI,KAAK,gBAAgB,YAAY;GAC1C,aAAa,KAAM,aAAa;GAChC,WAAW,KAAM,aAAa;EAChC;EAEA,KAAK,MAAM,YAAY,iBAAiB,OAAO,UAAU,CAAC;EAC1D,KAAK,MAAM,YAAY,eAAe,OAAO,QAAQ,CAAC;EAItD,IAAI,KAAK,cAAc,cAAc,KAAK,kBAAkB,UAAU;GACpE,MAAM,IAAI,KAAK;GACf,MAAM,IAAI,KAAK;GACf,MAAM,IAAI,IAAI,IAAI;GAIlB,MAAM,WAAW;GACjB,MAAM,YAAY,IAAI;GACtB,MAAM,gBAAgB,WAAW,IAAI,cAAc,YAAY,WAAW,IAAI;GAC9E,KAAK,MAAM,YAAY,YAAY,GAAG,EAAE,GAAG;GAC3C,KAAK,MAAM,YAAY,qBAAqB,GAAG,cAAc,GAAG;GAChE,KAAK,MAAM,YAAY,wBAAwB,GAAG,EAAE,GAAG;GACvD,KAAK,MAAM,YAAY,yBAAyB,GAAG,EAAE,GAAG;EAC1D;CACF;CAEA,kBAA6C;EAE3C,IAAI,KAAK,sBAAsB,GAC7B,OAAO,KAAK,eAAe;EAG7B,IAAI,KAAKD,WAAW;GAClB,MAAM,YAAY,KAAK,SAAS,KAAA,IAC5B,KAAK,cAAc,KAAKD,iBAAiB,IACzC,KAAKA,kBAAkB,QAAQ,KAAK,SAAS;GACjD,OAAO,KAAK,YAAY,KAAK,UAAU,SAAS,IAAI;EACtD;EAGA,IAAI,KAAK,WAAW;GAClB,MAAM,MAAM,OAAO,WAAW,KAAK,KAAK;GACxC,OAAO,KAAK,UAAU,OAAO,MAAM,GAAG,IAAI,KAAK,QAAQ,OAAO,GAAG,CAAC;EACpE;EACA,OAAO,KAAK,eAAe;CAC7B;CAIA,aAAsC;EACpC,MAAM,KAAK,KAAK,YAAY,cAA2B,SAAS;EAChE,IAAI,IAAI;GACN,MAAM,IAAI,OAAO,WAAW,GAAG,aAAa,KAAK,KAAK,EAAE;GACxD,IAAI,CAAC,OAAO,MAAM,CAAC,GACjB,GAAG,cAAc,KAAK,cAAc,KAAK,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC;EAElE;EACA,MAAM,WAAW;CACnB;CAgFA,gBAAwB,GAA2B;EACjD,MAAM,SAAS,KAAK,OAAO,QAAQ,KAAK,OAAO;EAC/C,IAAI,UAAU,GACZ,OAAO;EAET,MAAM,gBAAgB,gBAAgB,OAAO,KAAK,OAAO,KAAK,MAAM,EAAE,QAAQ;EAE9E,IAAI,QAAQ;EACZ,IAAI,UAAU;EAEd,QAAQ,EAAE,KAAV;GACE,KAAK;GACL,KAAK;IACH,QAAQ;IACR,UAAU;IACV;GACF,KAAK;GACL,KAAK;IACH,QAAQ,CAAC;IACT,UAAU;IACV;GACF,KAAK;IACH,QAAQ,EAAE,KAAK,YAAY,KAAK,KAAK,OAAO;IAC5C,UAAU;IACV;GACF,KAAK;IACH,SAAS,KAAK,OAAO,KAAK,KAAK,YAAY;IAC3C,UAAU;EAEd;EAEA,IAAI,SAAS;GACX,EAAE,eAAe;GACjB,KAAK,YAAY,KAAK;GACtB,OAAO;EACT;EAEA,OAAO;CACT;;;;;CAMA,YAAoB,OAAqB;EACvC,MAAM,OAAO,KAAK;EAClB,MAAM,UAAU,KAAK,YAAY;EACjC,MAAM,WAAW,KAAK,OAAO,KAAK,MAAM,UAAU,KAAK,CAAC;EAExD,MAAM,cAAc,KAAK,SAAS,KAAA,IAC9B,KAAK,cAAc,QAAQ,IAC3B,SAAS,QAAQ,KAAK,SAAS;EAEnC,KAAK,QAAQ;EAEb,KAAK,sBAAsB;EAC3B,KAAK,gBAAgB,KAAK,iBAAiB,QAAQ,CAAC;EAEpD,IAAI,gBAAgB,MAClB,KAAK,cAAc,IAAI,YAAY,SAAS;GAC1C,QAAQ,EAAE,OAAO,YAAY;GAC7B,SAAS;GACT,UAAU;EACZ,CAAC,CAAC;EAGJ,4BAA4B;GAC1B,IAAI,KAAK,UAAU,MACjB,KAAK,cAAc,IAAI,YAAuC,UAAU;IACtE,QAAQ,EAAE,OAAO,KAAK,MAAM;IAC5B,SAAS;IACT,UAAU;GACZ,CAAC,CAAC;EAEN,CAAC;CACH;CAIA,qBAAuC;EACrC,IAAI,KAAK,UACP,OAAO;EACT,OAAO,MAAM,mBAAmB;CAClC;CAEA,iBAA0B,WAA2B,OAAyB;EAC5E,MAAM,SAAS,KAAK,OAAO,QAAQ,KAAK,OAAO;EAC/C,IAAI,UAAU,GACZ;EACF,MAAM,gBAAgB,gBAAgB,OAAO,KAAK,OAAO,KAAK,MAAM,MAAM,QAAQ;EAClF,KAAK,YAAY,YAAY,aAAa;CAC5C;CAkGA,cAA8B;EAC5B,OAAO,OAAO,WAAW,KAAK,KAAK,KAAK;CAC1C;;;;;;CAOA,iBAAiC;EAC/B,MAAM,IAAI,OAAO,WAAW,KAAK,KAAK;EACtC,IAAI,OAAO,MAAM,CAAC,GAChB,OAAO,KAAK;EACd,IAAI,KAAK,cAAc,KAAA,GACrB,OAAO,EAAE,QAAQ,KAAK,SAAS;EAEjC,MAAM,MAAM,KAAK,MAAM,QAAQ,GAAG;EAClC,MAAM,KAAK,OAAO,IAAI,KAAK,MAAM,SAAS,MAAM,IAAI;EACpD,OAAO,EAAE,QAAQ,EAAE;CACrB;CAEA,OAAe,GAAmB;EAChC,IAAI,KAAK,QAAQ,KAAA,GACf,IAAI,KAAK,IAAI,KAAK,KAAK,CAAC;EAC1B,IAAI,KAAK,QAAQ,KAAA,GACf,IAAI,KAAK,IAAI,KAAK,KAAK,CAAC;EAC1B,OAAO;CACT;CAEA,MAAc,GAAmB;EAC/B,IAAI,KAAK,SAAS,KAAK,QAAQ,GAAG;GAChC,MAAM,MAAM,KAAK,OAAO;GAExB,MAAM,aADS,KAAK,OAAO,OAAO,OACT,KAAK;GAC9B,OAAO,KAAK,OAAO,IAAI,OAAO,QAAQ,IAAI,WAAW;EACvD;EACA,IAAI,CAAC,KAAK,MACR,OAAO;EACT,OAAO,KAAK,MAAM,IAAI,KAAK,IAAI,IAAI,KAAK;CAC1C;CAEA,eAAuB,GAAoB;EACzC,IAAI,KAAK,SAAS,KAAA,GAAW;GAC3B,MAAM,IAAI,OAAO,KAAK,IAAI;GAC1B,MAAM,MAAM,EAAE,QAAQ,GAAG;GACzB,OAAO,OAAO,IAAI,EAAE,SAAS,MAAM,IAAI;EACzC;EAEA,MAAM,IAAI,OAAO,KAAK,KAAK,YAAY,CAAC;EACxC,MAAM,MAAM,EAAE,QAAQ,GAAG;EACzB,OAAO,OAAO,IAAI,EAAE,SAAS,MAAM,IAAI;CACzC;CAEA,cAAsB,GAAmB;EACvC,OAAO,EAAE,QAAQ,KAAK,eAAe,CAAC,CAAC;CACzC;;CAGA,iBAAyB,IAAI,KAAK,YAAY,GAAW;EACvD,IAAI,KAAK,QAAQ,KAAA,KAAa,KAAK,QAAQ,KAAA,GACzC,OAAO;EACT,IAAI,KAAK,QAAQ,KAAK,KACpB,OAAO;EACT,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,IAAI,KAAK,QAAQ,KAAK,MAAM,KAAK,IAAI,CAAC;CACxE;;EAIsC,KAAA,SAAA;GACpC;GACA;GACA,GAAG,cAAc;GACjB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6JL;;AACF;AAnvBG,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,eAAA,WAAA,OAAA,KAAA,CAAA;AACzB,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,eAAA,WAAA,OAAA,KAAA,CAAA;AACzB,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,eAAA,WAAA,QAAA,KAAA,CAAA;AAEzB,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,eAAA,WAAA,SAAA,KAAA,CAAA;AACzB,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,WAAW;AAAmB,CAAC,CAAA,GAAA,eAAA,WAAA,mBAAA,KAAA,CAAA;AACxD,WAAA,CAAA,SAAS,EAAE,WAAW,aAAa,CAAC,CAAA,GAAA,eAAA,WAAA,aAAA,KAAA,CAAA;AACpC,WAAA,CAAA,SAAS,EAAE,WAAW,eAAe,CAAC,CAAA,GAAA,eAAA,WAAA,eAAA,KAAA,CAAA;AACtC,WAAA,CAAA,SAAS,EAAE,WAAW,iBAAiB,CAAC,CAAA,GAAA,eAAA,WAAA,iBAAA,KAAA,CAAA;AACxC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,WAAW;AAAU,CAAC,CAAA,GAAA,eAAA,WAAA,UAAA,KAAA,CAAA;AAChD,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,eAAA,WAAA,aAAA,KAAA,CAAA;AAZ3BG,iBAAAA,WAAAA,CAAAA,kBAAc,sBAAsB,CAAA,GAAA,cAAA;;;ACwB9B,IAAM,sBAAN,MAAM,4BAA4B,kBAAkB;;;EAChC,KAAA,gBAAA;EAE4C,KAAA,cAAA;EACmB,KAAA,cAAA;EACA,KAAA,cAAA;EAChC,KAAA,QAAA,KAAA;EACD,KAAA,WAAA;EACC,KAAA,YAAA;EAEd,KAAA,aAAA;EAE6B,KAAA,eAAA;;CAEvE,wBAA2C;EAGzC,IAAI,KAAK,SAEP,OAAO,IAAI;EAEb,OAAO,IAAI;;;;;sBAKO,KAAK,WAAW;iBACrB,OAAO,KAAK,KAAK,EAAE;eACrB,KAAK,IAAI;eACT,KAAK,IAAI;gBACR,KAAK,KAAK;2BACC,KAAK,gBAAgB;qBAC3B,KAAK,UAAU;uBACb,KAAK,MAAM;4BACN,KAAK,cAAc,WAAW,KAAK,iBAAiB;qBAC3D,KAAK,WAAW;kBACnB,KAAK,oBAAoB;;;CAGzC;CAEA,WAA8B,GAAiB;EAC7C,MAAM,WAAW,CAAC;EAGlB,MAAM,QAAQ,KAAK,YAAY,cAAc,KAAK,aAAa;EAC/D,IAAI,SAAS,OAAO,MAAM,WAAW,YAAY,MAAM,WAAW,GAChE,MAAM,SAAS;CAEnB;CAEA,SAAkB;EAGhB,OAAO,IAAI;yBACU,KAAK,UAAU,SAAS,GAAG;UAC1C,KAAK,sBAAsB,EAAE;;;wBAGf,KAAK,WAAW;sBAClB,KAAK,SAAS;uBACb,KAAK,UAAU;oBAClB,KAAK,MAAM;iBACd,KAAK,IAAI;iBACT,KAAK,IAAI;kBACR,KAAK,KAAK;mBACT,KAAK,MAAM;yBACL,KAAK,YAAY;yBACjB,KAAK,YAAY;yBACjB,KAAK,YAAY;mBACvB,KAAK,mBAAmB;oBACvB,KAAK,mBAAmB;;;;CAI1C;;EAEgC,KAAA,SAAA,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuGrC;AAjLG,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,oBAAA,WAAA,eAAA,KAAA,CAAA;AACzB,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,WAAW;AAAe,CAAC,CAAA,GAAA,oBAAA,WAAA,eAAA,KAAA,CAAA;AACpD,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,WAAW;AAAe,CAAC,CAAA,GAAA,oBAAA,WAAA,eAAA,KAAA,CAAA;AACpD,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,oBAAA,WAAA,SAAA,KAAA,CAAA;AACzB,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,oBAAA,WAAA,YAAA,KAAA,CAAA;AACzC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,oBAAA,WAAA,aAAA,KAAA,CAAA;AAEzC,WAAA,CAAA,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,oBAAA,WAAA,cAAA,KAAA,CAAA;AAE1B,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,WAAW;AAAgB,CAAC,CAAA,GAAA,oBAAA,WAAA,gBAAA,KAAA,CAAA;AAbvDC,sBAAAA,WAAAA,CAAAA,kBAAc,4BAA4B,CAAA,GAAA,mBAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as LabelledSliderInput } from "./labelled-slider-input-
|
|
1
|
+
import { t as LabelledSliderInput } from "./labelled-slider-input-aEYDvW2S.js";
|
|
2
2
|
export { LabelledSliderInput };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { F as ListDragSource, I as ListNativeDragStartDetail, N as ListDragPreviewContext, P as ListDragPreviewRenderer, j as ListDragEntry } from "./tree-component-BW2iCFq9.js";
|
|
2
|
+
import { ReactiveController, ReactiveControllerHost } from "lit";
|
|
3
|
+
//#region src/interaction/list-native-drag-controller.d.ts
|
|
4
|
+
type ListNativeDragControllerConfig<T> = {
|
|
5
|
+
readonly source: ListDragSource;
|
|
6
|
+
/** `itemsDraggable && selection usable` */
|
|
7
|
+
isEnabled: () => boolean;
|
|
8
|
+
/** Event target → item key, or `undefined` when the drag did not start on an item. */
|
|
9
|
+
resolveEventToKey: (target: EventTarget | null) => string | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Apply the origin rule (origin ∉ selection ⇒ replace with origin); return
|
|
12
|
+
* display-ordered `{ origin, selected }` for both modes, or `undefined` when
|
|
13
|
+
* the origin is not selectable.
|
|
14
|
+
*/
|
|
15
|
+
prepareSelection: (originKey: string) => {
|
|
16
|
+
origin: ListDragEntry<T>;
|
|
17
|
+
selected: Array<ListDragEntry<T>>;
|
|
18
|
+
} | undefined;
|
|
19
|
+
getMetrics: () => ListDragPreviewContext<T>[`metrics`];
|
|
20
|
+
getRenderer: () => ListDragPreviewRenderer<T> | undefined;
|
|
21
|
+
/** Fire the cancelable `list-native-drag-start`; return `!defaultPrevented`. */
|
|
22
|
+
dispatch: (detail: ListNativeDragStartDetail<T>) => boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Optional: write custom payloads onto the drag's `DataTransfer` (e.g. a
|
|
25
|
+
* MIME type for same-app drops). Called once, after a non-cancelled dispatch,
|
|
26
|
+
* inside the synchronous `dragstart` turn.
|
|
27
|
+
*/
|
|
28
|
+
writeDataTransfer?: (dataTransfer: DataTransfer, detail: ListNativeDragStartDetail<T>) => void;
|
|
29
|
+
/** Host toggles `data-native-dragging` / `aria-label`, re-renders. */
|
|
30
|
+
onActiveChange: (active: boolean, originKey?: string) => void;
|
|
31
|
+
/** Host clears state + starts its post-drag click-suppress timer. */
|
|
32
|
+
onEnd: () => void;
|
|
33
|
+
/** Optional: sync `draggable` on light-DOM / slotted children while enabled. */
|
|
34
|
+
syncLightDomDraggable?: () => void;
|
|
35
|
+
};
|
|
36
|
+
type DragHost = ReactiveControllerHost & HTMLElement;
|
|
37
|
+
/**
|
|
38
|
+
* Shared native item/row drag-out for list components.
|
|
39
|
+
*
|
|
40
|
+
* Owns capture-phase `dragstart` / `dragend` listeners on the host and its
|
|
41
|
+
* render root, a `MutationObserver` that keeps light-DOM / slotted item `draggable`
|
|
42
|
+
* attributes in sync, and a single post-dispatch disposal on
|
|
43
|
+
* `requestAnimationFrame`. All DOM / selection knowledge lives in the host
|
|
44
|
+
* config callbacks.
|
|
45
|
+
*/
|
|
46
|
+
declare class ListNativeDragController<T> implements ReactiveController {
|
|
47
|
+
#private;
|
|
48
|
+
constructor(host: DragHost, config: ListNativeDragControllerConfig<T>);
|
|
49
|
+
get isDragging(): boolean;
|
|
50
|
+
/** `"true"` when enabled, else `"false"` — for shadow-row template bindings. */
|
|
51
|
+
get draggableAttr(): string;
|
|
52
|
+
/** Re-run the light-DOM `draggable` sync (e.g. after `itemsDraggable` flips). */
|
|
53
|
+
refreshDraggable(): void;
|
|
54
|
+
hostConnected(): void;
|
|
55
|
+
/** `renderRoot` does not exist yet at `hostConnected` for a shadow-DOM host — rebind once it does. */
|
|
56
|
+
hostUpdated(): void;
|
|
57
|
+
hostDisconnected(): void;
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { ListNativeDragControllerConfig as n, ListNativeDragController as t };
|
|
61
|
+
//# sourceMappingURL=list-native-drag-controller-CFyrkKUj.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-native-drag-controller-CFyrkKUj.d.ts","names":[],"sources":["../src/interaction/list-native-drag-controller.ts"],"mappings":";;;KAWY,+BAA+B;WAChC,QAAQ;;EAEjB;;EAEA,oBAAoB,QAAQ;;;;;;EAM5B,mBAAmB;IAAwB,QAAQ,cAAc;IAAI,UAAU,MAAM,cAAc;;EACnG,kBAAkB,uBAAuB;EACzC,mBAAmB,wBAAwB;;EAE3C,WAAW,QAAQ,0BAA0B;;;;;;EAM7C,qBAAqB,cAAc,cAAc,QAAQ,0BAA0B;;EAEnF,iBAAiB,iBAAiB;;EAElC;;EAEA;;KAGG,WAAW,yBAAyB;;;;;;;;;;cAW5B,yBAAyB,cAAc;;EAUtC,YAAA,MAAM,UAAU,QAAQ,+BAA+B;MAM/D;;MAKA;;EASJ;EAQA;;EAYA;EAIA"}
|
package/dist/{list-native-drag-controller-DrY3qeJM.js → list-native-drag-controller-DxD6Yjci.js}
RENAMED
|
@@ -406,6 +406,10 @@ var ListNativeDragController = class {
|
|
|
406
406
|
} catch {}
|
|
407
407
|
this.refreshDraggable();
|
|
408
408
|
}
|
|
409
|
+
/** `renderRoot` does not exist yet at `hostConnected` for a shadow-DOM host — rebind once it does. */
|
|
410
|
+
hostUpdated() {
|
|
411
|
+
this.#bind();
|
|
412
|
+
}
|
|
409
413
|
hostDisconnected() {
|
|
410
414
|
this.#unbind();
|
|
411
415
|
try {
|
|
@@ -443,7 +447,6 @@ var ListNativeDragController = class {
|
|
|
443
447
|
#onDragStart = (event) => {
|
|
444
448
|
if (!(event instanceof DragEvent)) return;
|
|
445
449
|
if (this.#seenDragStarts.has(event)) return;
|
|
446
|
-
this.#seenDragStarts.add(event);
|
|
447
450
|
let enabled = false;
|
|
448
451
|
try {
|
|
449
452
|
enabled = this.#config.isEnabled();
|
|
@@ -457,6 +460,7 @@ var ListNativeDragController = class {
|
|
|
457
460
|
} catch {
|
|
458
461
|
return;
|
|
459
462
|
}
|
|
463
|
+
if (originKey) this.#seenDragStarts.add(event);
|
|
460
464
|
if (!originKey) return;
|
|
461
465
|
let prepared;
|
|
462
466
|
try {
|
|
@@ -515,6 +519,14 @@ var ListNativeDragController = class {
|
|
|
515
519
|
notCancelled = true;
|
|
516
520
|
}
|
|
517
521
|
if (notCancelled) {
|
|
522
|
+
if (event.dataTransfer) {
|
|
523
|
+
try {
|
|
524
|
+
if (event.dataTransfer.effectAllowed === `none` || event.dataTransfer.effectAllowed === `uninitialized`) event.dataTransfer.effectAllowed = `copyMove`;
|
|
525
|
+
} catch {}
|
|
526
|
+
try {
|
|
527
|
+
this.#config.writeDataTransfer?.(event.dataTransfer, detail);
|
|
528
|
+
} catch {}
|
|
529
|
+
}
|
|
518
530
|
const hotspot = preview.hotspot ?? {
|
|
519
531
|
x: 16,
|
|
520
532
|
y: 16
|
|
@@ -552,4 +564,4 @@ var ListNativeDragController = class {
|
|
|
552
564
|
//#endregion
|
|
553
565
|
export { captionForEntry as n, createDefaultListDragPreview as r, ListNativeDragController as t };
|
|
554
566
|
|
|
555
|
-
//# sourceMappingURL=list-native-drag-controller-
|
|
567
|
+
//# sourceMappingURL=list-native-drag-controller-DxD6Yjci.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-native-drag-controller-DxD6Yjci.js","names":["#host","#config","#dragging","#bind","#observer","#unbind","#renderRoot","#boundRoot","#onDragStart","#onDragEnd","#boundHost","#seenDragStarts"],"sources":["../src/interaction/list-drag-preview-default.ts","../src/interaction/list-native-drag-controller.ts"],"sourcesContent":["import type { ListDragEntry, ListDragPreview, ListDragPreviewContext } from './list-drag-types.js';\n\nconst CARD_DEFAULT = 72;\nconst CARD_MIN = 48;\nconst CARD_MAX = 96;\nconst LIST_WIDTH = 220;\nconst LIST_MAX_ROWS = 5;\nconst MAX_CANVAS_DIM = 1024;\n\nfunction cssVar(style: CSSStyleDeclaration, name: string, fallback: string): string {\n try {\n const value = style.getPropertyValue(name)?.trim();\n return value || fallback;\n } catch {\n return fallback;\n }\n}\n\nfunction fontOf(style: CSSStyleDeclaration): string {\n try {\n const font = style.font?.trim();\n if (font)\n return font;\n } catch {\n // Ignore.\n }\n return `12px system-ui, sans-serif`;\n}\n\n/** Caption for a drag entry — element labels win, then string items, then common object fields, then the key. */\nexport function captionForEntry(entry: ListDragEntry<unknown>): string {\n const el = entry.element ?? (entry.item instanceof Element ? entry.item : undefined);\n if (el) {\n const labelled = el.getAttribute(`data-label`)\n ?? el.querySelector(`[data-grid-list-caption]`)?.textContent?.trim()\n ?? el.getAttribute(`data-search-label`)\n ?? el.querySelector(`.cell`)?.textContent?.trim();\n if (labelled)\n return labelled.slice(0, 80);\n const text = el.textContent?.trim();\n if (text)\n return text.slice(0, 80);\n }\n const item = entry.item;\n if (typeof item === `string` && item.length > 0)\n return item.slice(0, 80);\n if (item !== null && typeof item === `object` && !(item instanceof Element)) {\n const record = item as Record<string, unknown>;\n for (const field of [`label`, `name`, `title`, `text`]) {\n const value = record[field];\n if (typeof value === `string` && value.length > 0)\n return value.slice(0, 80);\n }\n }\n return entry.key;\n}\n\nfunction glyphFor(caption: string): string {\n const first = caption.trim().at(0);\n return first ? first.toLocaleUpperCase() : `?`;\n}\n\n/** A decoded `<img>` ready for `drawImage`, if the entry's element has one. */\nfunction decodedImage(entry: ListDragEntry<unknown>): HTMLImageElement | undefined {\n const scope = entry.element ?? (entry.item instanceof Element ? entry.item : undefined);\n if (!scope || typeof scope.querySelector !== `function`)\n return undefined;\n // The entry element itself may be an <img> (e.g. slotted image content).\n if (scope instanceof HTMLImageElement) {\n if (scope.complete && scope.naturalWidth > 0)\n return scope;\n return undefined;\n }\n try {\n const img = scope.querySelector(`img`);\n if (img instanceof HTMLImageElement && img.complete && img.naturalWidth > 0)\n return img;\n } catch {\n // Ignore.\n }\n return undefined;\n}\n\nfunction cardSize(metrics: ListDragPreviewContext<unknown>[`metrics`]): number {\n if (metrics.itemSize !== undefined && Number.isFinite(metrics.itemSize))\n return Math.max(CARD_MIN, Math.min(CARD_MAX, Math.round(metrics.itemSize)));\n return CARD_DEFAULT;\n}\n\nfunction rowHeight(metrics: ListDragPreviewContext<unknown>[`metrics`]): number {\n const raw = metrics.rowHeight;\n if (raw !== undefined && Number.isFinite(raw))\n return Math.max(24, Math.min(36, Math.round(raw)));\n return 28;\n}\n\nfunction thumbCell(doc: Document, caption: string, img: HTMLImageElement | undefined, size: number): HTMLElement {\n const well = doc.createElement(`div`);\n well.setAttribute(`data-thumb`, ``);\n well.style.cssText = `width:${size}px;height:${size}px;border-radius:4px;overflow:hidden;`\n + `background:var(--surface-5, rgba(128,128,128,0.25));flex-shrink:0;display:flex;`\n + `align-items:center;justify-content:center;font-size:${Math.round(size * 0.4)}px;font-weight:600;`;\n if (img) {\n try {\n const clone = img.cloneNode(true) as HTMLImageElement;\n clone.style.cssText = `width:100%;height:100%;object-fit:cover;`;\n clone.removeAttribute(`id`);\n well.appendChild(clone);\n } catch {\n well.textContent = glyphFor(caption);\n }\n } else {\n well.textContent = glyphFor(caption);\n }\n return well;\n}\n\nfunction buildCardsElement(ctx: ListDragPreviewContext<unknown>, captions: string[], images: Array<HTMLImageElement | undefined>): HTMLElement {\n const doc = document;\n const size = cardSize(ctx.metrics);\n const gap = 6;\n const pad = 8;\n const root = doc.createElement(`div`);\n root.setAttribute(`data-preview`, `cards`);\n root.setAttribute(`part`, `drag-preview`);\n root.style.cssText = `position:fixed;top:-9999px;left:-9999px;display:flex;flex-direction:row;gap:${gap}px;`\n + `padding:${pad}px;background:var(--surface-4, #333);color:var(--surface-4-text, #fff);`\n + `border:1px solid var(--border-subtle, #555);border-radius:var(--radius-m, 8px);`\n + `box-shadow:0 4px 16px rgba(0,0,0,0.3);font-family:system-ui,sans-serif;font-size:11px;`\n + `max-width:320px;z-index:999999;pointer-events:none;`;\n const n = ctx.selected.length;\n for (let i = 0; i < n; i++) {\n const card = doc.createElement(`div`);\n card.setAttribute(`data-card`, ``);\n card.style.cssText = `display:flex;flex-direction:column;gap:4px;align-items:center;width:${size}px;`;\n card.appendChild(thumbCell(doc, captions[i], images[i], Math.round(size * 0.72)));\n const label = doc.createElement(`span`);\n label.setAttribute(`data-caption`, ``);\n label.style.cssText = `max-width:${size}px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;opacity:0.9;`;\n label.textContent = captions[i];\n card.appendChild(label);\n root.appendChild(card);\n }\n return root;\n}\n\nfunction buildListElement(\n ctx: ListDragPreviewContext<unknown>,\n captions: string[],\n images: Array<HTMLImageElement | undefined>,\n): HTMLElement {\n const doc = document;\n const rh = rowHeight(ctx.metrics);\n const thumb = Math.round(rh * 0.78);\n const root = doc.createElement(`div`);\n root.setAttribute(`data-preview`, `list`);\n root.setAttribute(`part`, `drag-preview`);\n root.style.cssText = `position:fixed;top:-9999px;left:-9999px;display:flex;flex-direction:column;gap:4px;`\n + `padding:8px;background:var(--surface-4, #333);color:var(--surface-4-text, #fff);`\n + `border:1px solid var(--border-subtle, #555);border-radius:var(--radius-m, 8px);`\n + `box-shadow:0 4px 16px rgba(0,0,0,0.3);font-family:system-ui,sans-serif;font-size:12px;`\n + `width:${LIST_WIDTH}px;max-width:${LIST_WIDTH}px;z-index:999999;pointer-events:none;`;\n const header = doc.createElement(`div`);\n header.setAttribute(`data-header`, ``);\n header.style.cssText = `font-weight:600;padding-bottom:4px;border-bottom:1px solid var(--border-subtle, #555);margin-bottom:4px;`;\n header.textContent = `${ctx.selected.length} items`;\n root.appendChild(header);\n for (let i = 0; i < Math.min(LIST_MAX_ROWS, captions.length); i++) {\n const row = doc.createElement(`div`);\n row.setAttribute(`data-row`, ``);\n row.style.cssText = `display:flex;align-items:center;gap:6px;height:${rh}px;overflow:hidden;`;\n row.appendChild(thumbCell(doc, captions[i], images[i], thumb));\n const label = doc.createElement(`span`);\n label.setAttribute(`data-caption`, ``);\n label.style.cssText = `flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;`;\n label.textContent = captions[i];\n row.appendChild(label);\n root.appendChild(row);\n }\n if (captions.length > LIST_MAX_ROWS) {\n const more = doc.createElement(`div`);\n more.setAttribute(`data-more`, ``);\n more.style.cssText = `opacity:0.6;text-align:center;`;\n more.textContent = `+${captions.length - LIST_MAX_ROWS} more`;\n root.appendChild(more);\n }\n return root;\n}\n\ntype Palette = {\n bg: string;\n fg: string;\n subtle: string;\n accent: string;\n radius: number;\n font: string;\n};\n\nfunction paletteOf(style: CSSStyleDeclaration): Palette {\n const bg = cssVar(style, `--surface-4`, `#333333`);\n const fg = cssVar(style, `--surface-4-text`, `#ffffff`);\n const subtle = cssVar(style, `--border-subtle`, `#555555`);\n const accent = cssVar(style, `--accent`, `#4da3ff`);\n const radiusRaw = cssVar(style, `--radius-m`, `8`);\n const radius = Number.parseFloat(radiusRaw) || 8;\n return { bg, fg, subtle, accent, radius, font: fontOf(style) };\n}\n\nfunction fitCanvas(canvas: HTMLCanvasElement, cssW: number, cssH: number): { scale: number; dpr: number } {\n const dpr = Math.max(1, Math.min(3, (typeof devicePixelRatio === `number` && devicePixelRatio > 0) ? devicePixelRatio : 1));\n let scale = dpr;\n // Bound the backing store so huge selections cannot allocate unbounded canvases.\n const maxScaleW = MAX_CANVAS_DIM / Math.max(1, cssW);\n const maxScaleH = MAX_CANVAS_DIM / Math.max(1, cssH);\n scale = Math.min(scale, maxScaleW, maxScaleH);\n canvas.width = Math.max(1, Math.round(cssW * scale));\n canvas.height = Math.max(1, Math.round(cssH * scale));\n canvas.style.width = `${cssW}px`;\n canvas.style.height = `${cssH}px`;\n return { scale, dpr: scale };\n}\n\nfunction roundRectPath(context: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number): void {\n const radius = Math.max(0, Math.min(r, w / 2, h / 2));\n if (typeof context.roundRect === `function`) {\n context.beginPath();\n context.roundRect(x, y, w, h, radius);\n return;\n }\n context.beginPath();\n context.moveTo(x + radius, y);\n context.arcTo(x + w, y, x + w, y + h, radius);\n context.arcTo(x + w, y + h, x, y + h, radius);\n context.arcTo(x, y + h, x, y, radius);\n context.arcTo(x, y, x + w, y, radius);\n context.closePath();\n}\n\nfunction paintCards(\n context: CanvasRenderingContext2D,\n scale: number,\n palette: Palette,\n captions: string[],\n images: Array<HTMLImageElement | undefined>,\n size: number,\n cssW: number,\n cssH: number,\n): void {\n context.save();\n context.scale(scale, scale);\n roundRectPath(context, 0, 0, cssW, cssH, palette.radius);\n context.fillStyle = palette.bg;\n context.fill();\n context.strokeStyle = palette.subtle;\n context.lineWidth = 1;\n context.stroke();\n context.clip();\n\n const gap = 6;\n const pad = 8;\n const wellSize = Math.round(size * 0.72);\n context.font = palette.font;\n context.textBaseline = `middle`;\n for (let i = 0; i < captions.length; i++) {\n const x = pad + i * (size + gap);\n const wellX = x + (size - wellSize) / 2;\n const wellY = pad;\n roundRectPath(context, wellX, wellY, wellSize, wellSize, 4);\n context.fillStyle = palette.subtle;\n context.globalAlpha = 0.35;\n context.fill();\n context.globalAlpha = 1;\n const img = images[i];\n if (img) {\n try {\n context.save();\n context.clip();\n context.drawImage(img, wellX, wellY, wellSize, wellSize);\n context.restore();\n } catch {\n // Placeholder below already painted.\n }\n } else {\n context.fillStyle = palette.fg;\n context.globalAlpha = 0.9;\n context.font = `600 ${Math.round(wellSize * 0.4)}px system-ui, sans-serif`;\n context.textAlign = `center`;\n context.fillText(glyphFor(captions[i]), wellX + wellSize / 2, wellY + wellSize / 2 + 1);\n context.globalAlpha = 1;\n context.textAlign = `left`;\n context.font = palette.font;\n }\n context.fillStyle = palette.fg;\n context.globalAlpha = 0.9;\n context.font = palette.font;\n const label = captions[i].length > 12 ? `${captions[i].slice(0, 11)}…` : captions[i];\n const textWidth = context.measureText(label).width;\n context.fillText(label, x + (size - Math.min(size, textWidth)) / 2, wellY + wellSize + 10, size);\n context.globalAlpha = 1;\n }\n context.restore();\n}\n\nfunction paintList(\n context: CanvasRenderingContext2D,\n scale: number,\n palette: Palette,\n captions: string[],\n images: Array<HTMLImageElement | undefined>,\n rh: number,\n cssW: number,\n cssH: number,\n): void {\n context.save();\n context.scale(scale, scale);\n roundRectPath(context, 0, 0, cssW, cssH, palette.radius);\n context.fillStyle = palette.bg;\n context.fill();\n context.strokeStyle = palette.subtle;\n context.lineWidth = 1;\n context.stroke();\n context.clip();\n\n const pad = 8;\n context.fillStyle = palette.fg;\n context.font = `600 ${palette.font}`;\n context.textBaseline = `middle`;\n context.fillText(`${captions.length} items`, pad, pad + 8, cssW - pad * 2);\n context.strokeStyle = palette.subtle;\n context.beginPath();\n context.moveTo(pad, pad + 20);\n context.lineTo(cssW - pad, pad + 20);\n context.stroke();\n\n const thumb = Math.round(rh * 0.78);\n const rows = Math.min(LIST_MAX_ROWS, captions.length);\n context.font = palette.font;\n for (let i = 0; i < rows; i++) {\n const y = pad + 24 + i * rh;\n roundRectPath(context, pad, y + (rh - thumb) / 2, thumb, thumb, 4);\n context.fillStyle = palette.subtle;\n context.globalAlpha = 0.35;\n context.fill();\n context.globalAlpha = 1;\n const img = images[i];\n if (img) {\n try {\n context.save();\n context.clip();\n context.drawImage(img, pad, y + (rh - thumb) / 2, thumb, thumb);\n context.restore();\n } catch {\n // Placeholder already painted.\n }\n } else {\n context.fillStyle = palette.fg;\n context.font = `600 ${Math.round(thumb * 0.45)}px system-ui, sans-serif`;\n context.textAlign = `center`;\n context.fillText(glyphFor(captions[i]), pad + thumb / 2, y + rh / 2 + 1);\n context.textAlign = `left`;\n context.font = palette.font;\n }\n context.fillStyle = palette.fg;\n context.globalAlpha = 0.92;\n const maxText = cssW - pad * 2 - thumb - 6;\n context.fillText(captions[i], pad + thumb + 6, y + rh / 2 + 1, Math.max(8, maxText));\n context.globalAlpha = 1;\n }\n if (captions.length > LIST_MAX_ROWS) {\n context.fillStyle = palette.fg;\n context.globalAlpha = 0.6;\n context.textAlign = `center`;\n context.fillText(`+${captions.length - LIST_MAX_ROWS} more`, cssW / 2, cssH - pad - 6, cssW - pad * 2);\n context.textAlign = `left`;\n context.globalAlpha = 1;\n }\n context.restore();\n}\n\n/**\n * Uniform built-in HTML+canvas drag preview for all four list components.\n *\n * - ≤5 selected → a row of small cards (thumbnail well + caption).\n * - >5 selected → a compact list (`N items` header, up to 5 rows, `+N more`).\n *\n * Always returns an offscreen `element` for `DataTransfer.setDragImage()` and,\n * when a 2D context is available, a DPR-aware painted `canvas` for native\n * hosts. Colours track the active theme via `ctx.hostStyle` CSS variables.\n */\nexport function createDefaultListDragPreview<T>(ctx: ListDragPreviewContext<T>): ListDragPreview {\n const entries = ctx.selected as ReadonlyArray<ListDragEntry<unknown>>;\n const captions = entries.map(entry => captionForEntry(entry));\n const images = entries.map(entry => decodedImage(entry));\n const isCards = entries.length <= 5;\n\n let element: HTMLElement;\n let cssW: number;\n let cssH: number;\n if (isCards) {\n const size = cardSize(ctx.metrics);\n const gap = 6;\n const pad = 8;\n cssW = entries.length * size + Math.max(0, entries.length - 1) * gap + pad * 2;\n cssH = Math.round(size * 0.72) + 22 + pad * 2;\n element = buildCardsElement(ctx, captions, images);\n } else {\n const rh = rowHeight(ctx.metrics);\n const pad = 8;\n const rows = Math.min(LIST_MAX_ROWS, entries.length);\n const more = entries.length > LIST_MAX_ROWS ? 18 : 0;\n cssW = LIST_WIDTH + 16;\n cssH = pad * 2 + 24 + rows * rh + more;\n element = buildListElement(ctx, captions, images);\n }\n\n let canvas: HTMLCanvasElement | undefined;\n try {\n const candidate = document.createElement(`canvas`);\n const paint = candidate.getContext(`2d`);\n if (paint) {\n const { scale } = fitCanvas(candidate, cssW, cssH);\n const palette = paletteOf(ctx.hostStyle);\n if (isCards) {\n paintCards(paint, scale, palette, captions, images, cardSize(ctx.metrics), cssW, cssH);\n } else {\n paintList(paint, scale, palette, captions, images, rowHeight(ctx.metrics), cssW, cssH);\n }\n canvas = candidate;\n }\n } catch {\n canvas = undefined;\n }\n\n return {\n element,\n hotspot: { x: 16, y: 16 },\n ...(canvas ? { canvas } : {}),\n dispose: () => {},\n };\n}\n","import type { ReactiveController, ReactiveControllerHost } from 'lit';\nimport type {\n ListDragEntry,\n ListDragPreview,\n ListDragPreviewContext,\n ListDragPreviewRenderer,\n ListDragSource,\n ListNativeDragStartDetail,\n} from './list-drag-types.js';\nimport { createDefaultListDragPreview } from './list-drag-preview-default.js';\n\nexport type ListNativeDragControllerConfig<T> = {\n readonly source: ListDragSource;\n /** `itemsDraggable && selection usable` */\n isEnabled: () => boolean;\n /** Event target → item key, or `undefined` when the drag did not start on an item. */\n resolveEventToKey: (target: EventTarget | null) => string | undefined;\n /**\n * Apply the origin rule (origin ∉ selection ⇒ replace with origin); return\n * display-ordered `{ origin, selected }` for both modes, or `undefined` when\n * the origin is not selectable.\n */\n prepareSelection: (originKey: string) => { origin: ListDragEntry<T>; selected: Array<ListDragEntry<T>> } | undefined;\n getMetrics: () => ListDragPreviewContext<T>[`metrics`];\n getRenderer: () => ListDragPreviewRenderer<T> | undefined;\n /** Fire the cancelable `list-native-drag-start`; return `!defaultPrevented`. */\n dispatch: (detail: ListNativeDragStartDetail<T>) => boolean;\n /**\n * Optional: write custom payloads onto the drag's `DataTransfer` (e.g. a\n * MIME type for same-app drops). Called once, after a non-cancelled dispatch,\n * inside the synchronous `dragstart` turn.\n */\n writeDataTransfer?: (dataTransfer: DataTransfer, detail: ListNativeDragStartDetail<T>) => void;\n /** Host toggles `data-native-dragging` / `aria-label`, re-renders. */\n onActiveChange: (active: boolean, originKey?: string) => void;\n /** Host clears state + starts its post-drag click-suppress timer. */\n onEnd: () => void;\n /** Optional: sync `draggable` on light-DOM / slotted children while enabled. */\n syncLightDomDraggable?: () => void;\n};\n\ntype DragHost = ReactiveControllerHost & HTMLElement;\n\n/**\n * Shared native item/row drag-out for list components.\n *\n * Owns capture-phase `dragstart` / `dragend` listeners on the host and its\n * render root, a `MutationObserver` that keeps light-DOM / slotted item `draggable`\n * attributes in sync, and a single post-dispatch disposal on\n * `requestAnimationFrame`. All DOM / selection knowledge lives in the host\n * config callbacks.\n */\nexport class ListNativeDragController<T> implements ReactiveController {\n readonly #host: DragHost;\n readonly #config: ListNativeDragControllerConfig<T>;\n\n #dragging = false;\n #boundRoot: EventTarget | undefined;\n #boundHost = false;\n #seenDragStarts = new WeakSet<Event>();\n #observer: MutationObserver | undefined;\n\n constructor(host: DragHost, config: ListNativeDragControllerConfig<T>) {\n this.#host = host;\n this.#config = config;\n host.addController(this);\n }\n\n get isDragging(): boolean {\n return this.#dragging;\n }\n\n /** `\"true\"` when enabled, else `\"false\"` — for shadow-row template bindings. */\n get draggableAttr(): string {\n try {\n return this.#config.isEnabled() ? `true` : `false`;\n } catch {\n return `false`;\n }\n }\n\n /** Re-run the light-DOM `draggable` sync (e.g. after `itemsDraggable` flips). */\n refreshDraggable(): void {\n try {\n this.#config.syncLightDomDraggable?.();\n } catch {\n // Host sync must never break the controller.\n }\n }\n\n hostConnected(): void {\n this.#bind();\n this.#observer ??= new MutationObserver(() => this.refreshDraggable());\n try {\n this.#observer.observe(this.#host, { childList: true, subtree: true });\n } catch {\n // happy-dom-safe: observing must never throw.\n }\n this.refreshDraggable();\n }\n\n /** `renderRoot` does not exist yet at `hostConnected` for a shadow-DOM host — rebind once it does. */\n hostUpdated(): void {\n this.#bind();\n }\n\n hostDisconnected(): void {\n this.#unbind();\n try {\n this.#observer?.disconnect();\n } catch {\n // Ignore.\n }\n this.#dragging = false;\n }\n\n #renderRoot(): EventTarget {\n const maybe = this.#host as unknown as { renderRoot?: EventTarget };\n return maybe.renderRoot ?? this.#host;\n }\n\n #bind(): void {\n // Capture on both the host (light-DOM / slotted items, and everything in\n // happy-dom where slot distribution is not reflected in the event path)\n // and the render root (shadow cells). A shadow-originated drag reaches\n // both — `#seenDragStarts` dedups the second call.\n const root = this.#renderRoot();\n if (root !== this.#boundRoot) {\n this.#unbind();\n this.#boundRoot = root;\n root.addEventListener(`dragstart`, this.#onDragStart as EventListener, { capture: true });\n root.addEventListener(`dragend`, this.#onDragEnd as EventListener, { capture: true });\n }\n if (!this.#boundHost) {\n this.#boundHost = true;\n this.#host.addEventListener(`dragstart`, this.#onDragStart as EventListener, { capture: true });\n this.#host.addEventListener(`dragend`, this.#onDragEnd as EventListener, { capture: true });\n }\n }\n\n #unbind(): void {\n this.#boundRoot?.removeEventListener(`dragstart`, this.#onDragStart as EventListener, { capture: true });\n this.#boundRoot?.removeEventListener(`dragend`, this.#onDragEnd as EventListener, { capture: true });\n this.#boundRoot = undefined;\n if (this.#boundHost) {\n this.#boundHost = false;\n this.#host.removeEventListener(`dragstart`, this.#onDragStart as EventListener, { capture: true });\n this.#host.removeEventListener(`dragend`, this.#onDragEnd as EventListener, { capture: true });\n }\n }\n\n #onDragStart = (event: Event): void => {\n if (!(event instanceof DragEvent))\n return;\n if (this.#seenDragStarts.has(event))\n return;\n let enabled = false;\n try {\n enabled = this.#config.isEnabled();\n } catch {\n return;\n }\n if (!enabled)\n return;\n let originKey: string | undefined;\n try {\n originKey = this.#config.resolveEventToKey(event.target);\n } catch {\n return;\n }\n // Do NOT mark the event seen until we have a key. This handler is bound to\n // both the host and the render root; on a shadow-DOM host the host-level\n // invocation sees a retargeted `event.target` and resolves no key — it must\n // not poison the dedup for the render-root invocation that will succeed.\n if (originKey)\n this.#seenDragStarts.add(event);\n if (!originKey)\n return;\n let prepared: { origin: ListDragEntry<T>; selected: Array<ListDragEntry<T>> } | undefined;\n try {\n prepared = this.#config.prepareSelection(originKey);\n } catch {\n return;\n }\n if (!prepared || prepared.selected.length === 0)\n return;\n const { origin, selected } = prepared;\n\n let hostStyle: CSSStyleDeclaration;\n try {\n hostStyle = getComputedStyle(this.#host);\n } catch {\n hostStyle = document.createElement(`div`).style as unknown as CSSStyleDeclaration;\n }\n let metrics: ListDragPreviewContext<T>[`metrics`] = {};\n try {\n metrics = this.#config.getMetrics() ?? {};\n } catch {\n metrics = {};\n }\n const context: ListDragPreviewContext<T> = {\n source: this.#config.source,\n origin,\n selected,\n metrics,\n hostStyle,\n };\n let renderer: ListDragPreviewRenderer<T> | undefined;\n try {\n renderer = this.#config.getRenderer();\n } catch {\n renderer = undefined;\n }\n let preview: ListDragPreview;\n try {\n preview = renderer ? renderer(context) : createDefaultListDragPreview(context);\n } catch {\n preview = createDefaultListDragPreview(context);\n }\n try {\n document.body.appendChild(preview.element);\n } catch {\n // happy-dom-safe.\n }\n\n const detail: ListNativeDragStartDetail<T> = {\n key: origin.key,\n index: origin.index,\n item: origin.item,\n selectedKeys: selected.map(entry => entry.key),\n selected,\n preview,\n };\n let notCancelled = true;\n try {\n notCancelled = this.#config.dispatch(detail);\n } catch {\n notCancelled = true;\n }\n\n if (notCancelled) {\n if (event.dataTransfer) {\n try {\n // Let drop targets show a \"move\" / \"copy\" cursor.\n if (event.dataTransfer.effectAllowed === `none` || event.dataTransfer.effectAllowed === `uninitialized`)\n event.dataTransfer.effectAllowed = `copyMove`;\n } catch {\n // read-only in some contexts — non-fatal.\n }\n try {\n this.#config.writeDataTransfer?.(event.dataTransfer, detail);\n } catch {\n // A misbehaving payload writer must not abort the drag.\n }\n }\n const hotspot = preview.hotspot ?? { x: 16, y: 16 };\n try {\n event.dataTransfer?.setDragImage(preview.element, hotspot.x, hotspot.y);\n } catch {\n // Stubbed dataTransfer in tests may throw — non-fatal.\n }\n } else {\n try {\n event.preventDefault();\n } catch {\n // Ignore.\n }\n }\n\n this.#dragging = true;\n try {\n this.#config.onActiveChange(true, origin.key);\n } catch {\n // Ignore.\n }\n requestAnimationFrame(() => {\n try {\n preview.element.remove();\n } catch {\n // Ignore.\n }\n try {\n preview.dispose?.();\n } catch {\n // Ignore.\n }\n });\n };\n\n #onDragEnd = (): void => {\n if (!this.#dragging)\n return;\n this.#dragging = false;\n try {\n this.#config.onActiveChange(false);\n } catch {\n // Ignore.\n }\n try {\n this.#config.onEnd();\n } catch {\n // Ignore.\n }\n };\n}\n"],"mappings":"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"}
|
package/dist/miller.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { D as TreeTickleDetail, E as TreeSelectEvent, O as TreeTickleEvent, T as TreeSelectDetail, a as TreeComponent, b as TreeItemClickDetail, i as TreeCollapseEvent, k as TreeDataModel, n as TreeActivateEvent, o as TreeComponentEventMap, r as TreeCollapseDetail, t as TreeActivateDetail, v as TreeExpandDetail, w as TreeSearchHost, x as TreeItemClickEvent, y as TreeExpandEvent } from "./tree-component-BW2iCFq9.js";
|
|
1
2
|
import { a as TreeItem, n as TreeExclusivity, o as TreeNode, r as TreeFilterPredicate, s as TreeSelectionFilter, t as LoadChildrenCallback } from "./types-Bc23SI94.js";
|
|
2
|
-
import {
|
|
3
|
-
import { S as ListSearchController } from "./index-Dgrx-DIA.js";
|
|
3
|
+
import { S as ListSearchController } from "./index--qnhBWZJ.js";
|
|
4
4
|
import { n as TickledController } from "./tickled-controller-C1ZsHpyg.js";
|
|
5
5
|
import { LitElement, PropertyValues, TemplateResult, nothing } from "lit";
|
|
6
6
|
import { CommandRegistry } from "@clinth/ui-commands";
|
package/dist/plots.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { c as computeColour, i as PlotMultiAxis, l as parseColourScaleAttr, n as PlotSingleAxis, o as PlotDataSeries, r as PlotHistogram, s as applyAgeModification, t as PlotXyAxis, u as readBaseColour } from "./xy-axis-
|
|
1
|
+
import { c as computeColour, i as PlotMultiAxis, l as parseColourScaleAttr, n as PlotSingleAxis, o as PlotDataSeries, r as PlotHistogram, s as applyAgeModification, t as PlotXyAxis, u as readBaseColour } from "./xy-axis-COKw338Q.js";
|
|
2
2
|
export { PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, applyAgeModification, computeColour, parseColourScaleAttr, readBaseColour };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slider-input-BxURAAmD.d.ts","names":[],"sources":["../src/slider-input/types.ts","../src/slider-input/slider-input.ts"],"mappings":";;;;;;KAIY;KACA;KACA;KACA;KACA;KACA;;;;;;;KAOA;KACA;KACA;;;;;;;UAQK;EACf;EACA,MAAM;;;;;EAKN;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;KAOU;;;;;;;;UASK;WACN;WACA;;WAEA;;WAEA;WACA;WACA;;WAEA;WACA;;WAEA,UAAU;;UAGJ;WACN;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,UAAU;;KAGT,wBAAwB,YAAY;KACpC,yBAAyB,YAAY;UAEhC;EACf,OAAO;EACP,QAAQ;;;;;
|
|
1
|
+
{"version":3,"file":"slider-input-BxURAAmD.d.ts","names":[],"sources":["../src/slider-input/types.ts","../src/slider-input/slider-input.ts"],"mappings":";;;;;;KAIY;KACA;KACA;KACA;KACA;KACA;;;;;;;KAOA;KACA;KACA;;;;;;;UAQK;EACf;EACA,MAAM;;;;;EAKN;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;KAOU;;;;;;;;UASK;WACN;WACA;;WAEA;;WAEA;WACA;WACA;;WAEA;WACA;;WAEA,UAAU;;UAGJ;WACN;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,UAAU;;KAGT,wBAAwB,YAAY;KACpC,yBAAyB,YAAY;UAEhC;EACf,OAAO;EACP,QAAQ;;;;;cCiFG,2BAA2B;;EAGtC;EAGA;;;;;;EAQA;EAGA;EAGA;EAGA;EAGA;EAGA,WAAW;EAGX,aAAa;EAGb,aAAa;EAGb,aAAa;;;;;;EAQb,cAAc;EAGd,WAAW;EAGX,WAAW;;;;;;;EASX,cAAc;EAGd;EAGA;;;;;;;;;;;;;EAeA;;EAyFS;EAiFT,QACE,aACA;IACE;IACA;IACA;IACA,OAAO;IACP;IACA;;EAgBJ,aAAa,aAAa;EAQ1B,aAAa,aAAa,kBAAkB;EAW5C,WAAW;EAKX,YAAY,oBAAoB;EAIhC,QAAQ,cAAc;EAunCb,iBAAiB,WAAW,gBAAgB,OAAO;YAoXzC,WAAW,SAAS;EAsE9B;YA2JU,QAAQ,SAAS;EAkB3B;SAiBO,sBAAM;;QAqJhB;YACI;IACR,qBAAqB;;;UAKR;EACf,oBAAoB,gBAAgB,4BAClC,MAAM,GACN,WAAW,MAAM,oBAAoB,OAAO,2BAA2B,aACvE,oBAAoB,sCAEpB,cACA,UAAU,oCACV,oBAAoB"}
|