@rcarls/rc-splitter 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -61
- package/dist/custom-elements.json +255 -27
- package/dist/{rc-splitter-BZgnDbmR.js → rc-splitter-CJTLxYi3.js} +265 -130
- package/dist/rc-splitter-CJTLxYi3.js.map +1 -0
- package/dist/rc-splitter-define.js +1 -1
- package/dist/rc-splitter.js +1 -1
- package/dist/types/packages/rc-splitter/src/rc-splitter.d.ts +68 -13
- package/package.json +1 -1
- package/dist/rc-splitter-BZgnDbmR.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rc-splitter-CJTLxYi3.js","sources":["../src/rc-splitter.styles.ts","../src/rc-splitter.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const splitterStyles = css`\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n }\n\n :host {\n --rc-splitter-separator-size: 6px;\n\n position: relative;\n display: flex;\n flex-direction: row;\n align-items: stretch;\n }\n\n :host([orientation='vertical']) {\n flex-direction: column;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n /* because :has(:focus-visible) doesn't work across slot boundary */\n :host([data-interaction-mode='keyboard']):focus-within {\n outline: auto;\n }\n\n ::slotted(*) {\n width: 100%;\n height: 100%;\n }\n\n #separator {\n grid-column: separator;\n flex: 0 0 var(--rc-splitter-separator-size, 6px);\n display: flex;\n flex-direction: column;\n justify-content: center;\n background-color: var(\n --rc-splitter-separator-color,\n color-mix(in srgb, ButtonBorder 35%, Canvas 65%)\n );\n border-left: var(\n --rc-splitter-separator-border-inline-start,\n var(--rc-splitter-keyline, 1px solid ButtonBorder)\n );\n border-right: var(\n --rc-splitter-separator-border-inline-end,\n var(--rc-splitter-keyline, 1px solid ButtonBorder)\n );\n /* z-index: 1 as a flex item stacks separator above pane siblings so the\n ::after touch-target circle (which extends past the strip) is hittable */\n z-index: 1;\n /* Required for collapse-button absolute positioning */\n position: relative;\n\n :host([orientation='vertical']) & {\n flex-direction: row;\n border-left: unset;\n border-right: unset;\n border-top: var(\n --rc-splitter-separator-border-block-start,\n var(--rc-splitter-keyline, 1px solid ButtonBorder)\n );\n border-bottom: var(\n --rc-splitter-separator-border-block-end,\n var(--rc-splitter-keyline, 1px solid ButtonBorder)\n );\n }\n }\n\n #collapse-button {\n /* Positioned at the start of the separator strip, centered on the cross\n axis. The button intentionally protrudes into the primary pane so it\n is visible and hittable at a reasonable size even on narrow strips. */\n position: absolute;\n top: var(--rc-splitter-collapse-button-offset, 8px);\n left: 50%;\n transform: translateX(-50%);\n width: var(--rc-splitter-collapse-button-size, 20px);\n height: var(--rc-splitter-collapse-button-size, 20px);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n border: 1px solid var(--rc-splitter-collapse-button-border, ButtonBorder);\n border-radius: 50%;\n background: var(--rc-splitter-collapse-button-bg, Canvas);\n color: var(--rc-splitter-collapse-button-color, ButtonText);\n cursor: pointer;\n line-height: 1;\n\n &:hover {\n background: var(--rc-splitter-collapse-button-hover-bg, ButtonFace);\n }\n\n &:focus-visible {\n outline: 2px solid Highlight;\n outline-offset: 2px;\n }\n\n :host([orientation='vertical']) & {\n top: 50%;\n left: var(--rc-splitter-collapse-button-offset, 8px);\n transform: translateY(-50%);\n }\n }\n\n #separator-handle {\n touch-action: none;\n width: 100%;\n height: var(--rc-splitter-separator-handle-size, 100%);\n cursor: col-resize;\n display: flex;\n align-items: center;\n justify-content: center;\n /* Required so ::after is positioned relative to this element */\n position: relative;\n\n /* ── Visual drag indicator ─────────────────────────────────────────────\n Default: 3-dot vertical grip (horizontal splitter / vertical bar).\n Themes override via --rc-splitter-handle-pattern (background-image) and\n --rc-splitter-handle-fill (background-color). */\n &::before {\n content: '';\n display: block;\n width: var(--rc-splitter-handle-thickness, 4px);\n height: 100%;\n background-color: var(--rc-splitter-handle-fill, transparent);\n background-image: var(\n --rc-splitter-handle-pattern,\n radial-gradient(\n circle 1px at 50% calc(50% - 5px),\n var(--rc-splitter-handle-color, ButtonBorder) 100%,\n transparent 100%\n ),\n radial-gradient(\n circle 1px at 50% 50%,\n var(--rc-splitter-handle-color, ButtonBorder) 100%,\n transparent 100%\n ),\n radial-gradient(\n circle 1px at 50% calc(50% + 5px),\n var(--rc-splitter-handle-color, ButtonBorder) 100%,\n transparent 100%\n )\n );\n border-radius: var(--rc-splitter-handle-border-radius, 0);\n pointer-events: none;\n transition: background-color var(--rc-splitter-handle-transition, 0ms);\n }\n\n /* Hover highlight stays on the visual indicator only, never the full strip */\n &:hover::before {\n background-color: var(--rc-splitter-handle-hover-fill, transparent);\n }\n\n /* ── Touch target circle ───────────────────────────────────────────────\n 24 px diameter transparent circle, centered on the handle. Invisible\n and non-interactive for mouse/keyboard. On coarse-pointer (touch)\n devices the circle becomes hittable, giving a WCAG-compliant touch\n target without widening the visual separator. */\n &::after {\n content: '';\n position: absolute;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n pointer-events: none;\n }\n\n :host([orientation='vertical']) & {\n width: var(--rc-splitter-separator-handle-size, 100%);\n height: 100%;\n cursor: row-resize;\n\n /* Horizontal 3-dot grip (vertical splitter / horizontal bar) */\n &::before {\n width: 100%;\n height: var(--rc-splitter-handle-thickness, 4px);\n background-image: var(\n --rc-splitter-handle-pattern,\n radial-gradient(\n circle 1px at calc(50% - 5px) 50%,\n var(--rc-splitter-handle-color, ButtonBorder) 100%,\n transparent 100%\n ),\n radial-gradient(\n circle 1px at 50% 50%,\n var(--rc-splitter-handle-color, ButtonBorder) 100%,\n transparent 100%\n ),\n radial-gradient(\n circle 1px at calc(50% + 5px) 50%,\n var(--rc-splitter-handle-color, ButtonBorder) 100%,\n transparent 100%\n )\n );\n }\n }\n\n :host([fixed]) & {\n pointer-events: none;\n }\n }\n\n /* Activate the touch target circle only on coarse-pointer (touch) devices */\n @media (any-pointer: coarse) {\n #separator-handle::after {\n pointer-events: auto;\n }\n }\n\n #primary,\n #secondary {\n overflow: hidden;\n }\n\n #primary {\n grid-column: primary;\n flex: 0 0 auto;\n }\n\n #secondary {\n grid-column: secondary;\n flex: 1;\n }\n`;\n\nexport default splitterStyles;\n","import { LitElement, html, nothing } from 'lit';\nimport { property, state, query, queryAssignedElements } from 'lit/decorators.js';\n\nimport {\n DragGestureController,\n findNearestSnapIndex,\n findNextSnapIndex,\n keyInteraction,\n keyNavigation,\n type DragGestureDetail,\n type KeyboardNavigationAction,\n} from '@rcarls/rc-common';\n\nimport splitterStyles from './rc-splitter.styles';\n\ntype SplitterOrientation = 'horizontal' | 'vertical';\n\ntype SplitterMode = 'length' | 'percent' | 'fixed';\n\nconst MIN_SWIPE_DISTANCE = 24;\nconst DEFAULT_SNAP_DURATION_MS = 200;\nconst SNAP_EASING = 'cubic-bezier(0.4, 0, 0.2, 1)';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-splitter': RCSplitter;\n }\n}\n\n/**\n * Resizable pane splitter with pointer, keyboard, anchored settling, and\n * collapse/restore controls, following the WAI-ARIA Window Splitter pattern.\n *\n * Set `orientation=\"vertical\"` for a vertical splitter\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-splitter rc-splitter docs}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/ WAI-ARIA Window Splitter pattern}\n *\n * @slot - Primary pane contents\n * @slot secondary - Secondary pane contents (optional)\n *\n * @fires rc-splitter-change - Fired when the separator position changes; `detail: { value, valueText }`\n *\n * @attr label - Accessible label applied to the primary pane and referenced by the separator\n * handle's `aria-labelledby`.\n * @attr orientation - Layout direction: `horizontal` (left/right panes) or `vertical` (top/bottom panes).\n * @attr mode - Value units and pane sizing behavior: `length`, `percent`, or `fixed`.\n * @attr step - Keyboard resize step size, in the current mode's units.\n * @attr min - Minimum primary pane size, in the current mode's units.\n * @attr max - Maximum primary pane size, in the current mode's units. Defaults to the full\n * container size.\n * @attr value - Current primary pane size. Host writes update silently.\n * @attr default-value - Initial uncontrolled primary pane size.\n * @attr fixed - Disables pointer and keyboard resizing without changing pane size.\n * @attr collapsible - Renders a collapse/expand toggle button on the separator.\n * @attr snap-points - Ascending whitespace-separated anchors, in the current mode's units.\n * @attr swipe-velocity - Minimum release velocity, in px/s, that qualifies as a swipe.\n *\n * @cssprop [--rc-splitter-separator-size=6px] - Thickness of the separator bar\n * @cssprop [--rc-splitter-separator-handle-size=100%] - Length of the drag handle area within the separator (also the length of the visible indicator)\n * @cssprop [--rc-splitter-separator-color=color-mix(in srgb, ButtonBorder 35%, Canvas 65%)] - Separator background color\n * @cssprop [--rc-splitter-keyline=1px solid ButtonBorder] - Shared separator keyline border\n * @cssprop [--rc-splitter-handle-color=ButtonBorder] - Color of the dot grip indicators (default visual)\n * @cssprop [--rc-splitter-handle-thickness=4px] - Cross-axis size of the visual indicator (dot column width or pill/line thickness)\n * @cssprop [--rc-splitter-handle-border-radius=0] - Border-radius of the visual indicator; set to a large value (e.g. 999px) for a pill shape\n * @cssprop [--rc-splitter-handle-pattern=<3-dot radial-gradient>] - background-image for the visual indicator; set to `none` to use a solid fill via --rc-splitter-handle-fill instead\n * @cssprop [--rc-splitter-handle-fill=transparent] - background-color of the visual indicator; effective when --rc-splitter-handle-pattern is none (e.g. for a solid pill)\n * @cssprop [--rc-splitter-handle-hover-fill=transparent] - background-color of the visual indicator on hover; scoped to the indicator element only, not the full separator strip\n * @cssprop [--rc-splitter-handle-transition=0ms] - CSS transition duration/easing for the visual indicator's background-color changes\n * @cssprop [--rc-splitter-snap-duration=200ms] - Duration of anchored settling after pointer release or `snapTo()`\n * @cssprop [--rc-splitter-collapse-button-size=20px] - Diameter of the collapse/expand toggle button\n * @cssprop [--rc-splitter-collapse-button-offset=8px] - Distance from the start edge of the separator to the collapse button center\n * @cssprop [--rc-splitter-collapse-button-bg=Canvas] - Collapse button background color\n * @cssprop [--rc-splitter-collapse-button-hover-bg=ButtonFace] - Collapse button background color on hover\n * @cssprop [--rc-splitter-collapse-button-border=ButtonBorder] - Collapse button border color\n * @cssprop [--rc-splitter-collapse-button-color=ButtonText] - Collapse button icon color\n * @cssprop [--rc-splitter-separator-border-inline-start=1px solid ButtonBorder] - Inline-start border\n * @cssprop [--rc-splitter-separator-border-inline-end=1px solid ButtonBorder] - Inline-end border\n * @cssprop [--rc-splitter-separator-border-block-start=1px solid ButtonBorder] - Block-start border (vertical orientation)\n * @cssprop [--rc-splitter-separator-border-block-end=1px solid ButtonBorder] - Block-end border (vertical orientation)\n * @csspart primary - Primary pane container\n * @csspart secondary - Secondary pane container\n * @csspart separator - The separator bar\n * @csspart separator-handle - The focusable drag handle\n * @csspart collapse-button - The collapse/expand toggle button (only rendered when `collapsible` is set)\n */\nexport class RCSplitter extends LitElement {\n static styles = [splitterStyles];\n\n /** Accessible label for this splitter. Default label is 'Splitter'. */\n @property({ type: String })\n label = 'Splitter';\n\n /** Splitter orientation, for keyboard navigation and initial sizing. */\n @property({ type: String, reflect: true })\n orientation: SplitterOrientation = 'horizontal';\n\n /**\n * Determines value units and pane sizing behavior.\n *\n * - `length` uses px for the primary pane size.\n * - `percent` uses percentage points.\n * - `fixed` uses px for a clampable fixed primary pane while the secondary pane flexes.\n */\n @property({ type: String, reflect: true })\n mode: SplitterMode = 'length';\n\n /** The step size for resizing, in either pixels or percentage points depending on `mode`. */\n @property({ type: Number })\n step: number = 1;\n\n /** Minimum size of the primary pane in current mode units. Defaults to 0. */\n @property({ type: Number })\n min: number = 0;\n\n /** Maximum size of the primary pane in current mode units. Defaults to the full container size. */\n @property({ type: Number })\n max: number | undefined = undefined;\n\n private _defaultValue: number | undefined;\n private _hostValue: number | undefined;\n private _valueInitialized = false;\n\n /** The current splitter value. Host writes update silently. */\n @property({ type: Number })\n set value(val: number) {\n const oldValue = this._hostValue;\n\n this._hostValue = val;\n\n if (this._initialMax) {\n this._setValue(val, false);\n }\n\n this.requestUpdate('value', oldValue);\n }\n\n /** The current splitter value, corresponding to the separator position, in either pixels or percentage points depending on `mode`. */\n get value() {\n return this._value;\n }\n\n /** Initial uncontrolled splitter value. */\n @property({ type: Number, attribute: 'default-value' })\n set defaultValue(val: number | undefined) {\n const oldValue = this._defaultValue;\n\n this._defaultValue = val;\n\n if (!this._initialMax && this._hostValue === undefined && val !== undefined) {\n this._setValue(val, false);\n }\n\n this.requestUpdate('defaultValue', oldValue);\n }\n\n /** Initial uncontrolled splitter value. */\n get defaultValue() {\n return this._defaultValue;\n }\n\n protected get _effectiveMin(): number {\n return Math.max(this._minValue, this.min);\n }\n\n protected get _effectiveMax(): number {\n return Math.min(this._maxValue, this.max ?? this._maxValue);\n }\n\n /** True once initialized and the primary pane is at its effective minimum. */\n protected get _isCollapsed(): boolean {\n return this._initialMax > 0 && this.value <= this._effectiveMin;\n }\n\n protected _toggleCollapse(): void {\n this._setUserValue(this._isCollapsed ? this._lastValue : this._effectiveMin);\n }\n\n protected _onCollapseButtonClick(): void {\n this._toggleCollapse();\n }\n\n protected _onCollapseKeydown(e: KeyboardEvent): void {\n if (!this.collapsible || this.fixed) {\n return;\n }\n\n if (!e.ctrlKey && !e.metaKey) {\n return;\n }\n\n const isRelevantKey =\n this.orientation === 'horizontal'\n ? e.key === 'ArrowLeft' || e.key === 'ArrowRight'\n : e.key === 'ArrowUp' || e.key === 'ArrowDown';\n\n if (isRelevantKey) {\n e.preventDefault();\n e.stopImmediatePropagation();\n this._toggleCollapse();\n }\n }\n\n protected get _collapseButtonIcon() {\n const isHorizontal = this.orientation === 'horizontal';\n // Chevron points LEFT/UP to collapse (separator moves toward primary),\n // RIGHT/DOWN to expand (separator moves away from primary).\n const d = isHorizontal\n ? this._isCollapsed\n ? 'M 3 1 L 7 5 L 3 9'\n : 'M 7 1 L 3 5 L 7 9'\n : this._isCollapsed\n ? 'M 1 3 L 5 7 L 9 3'\n : 'M 1 7 L 5 3 L 9 7';\n\n return html`<svg\n aria-hidden=\"true\"\n viewBox=\"0 0 10 10\"\n width=\"10\"\n height=\"10\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=${d} />\n </svg>`;\n }\n\n protected _setValue(val: number, dispatch: boolean): void {\n const oldValue = this._value;\n\n this._value = Math.min(\n Math.max(Math.round(val / this.step) * this.step, this._effectiveMin),\n this._effectiveMax,\n );\n\n if (dispatch && this._value !== oldValue) {\n this.dispatchEvent(\n new CustomEvent('rc-splitter-change', {\n bubbles: true,\n composed: true,\n detail: { value: this._value, valueText: this.valueText },\n }),\n );\n }\n }\n\n protected _setUserValue(val: number): void {\n this._valueInitialized = true;\n this._hostValue = undefined;\n\n // Capture the last position above the effective minimum before a user-driven\n // change so toggle-collapse can restore it. Internal resize callbacks use\n // _setValue directly and must not overwrite this.\n if (this._value > this._effectiveMin) {\n this._lastValue = this._value;\n }\n\n this._setValue(val, true);\n }\n\n @state()\n private _value: number = 0;\n\n /** Disables pointer and keyboard resizing without changing pane size. */\n @property({ type: Boolean })\n fixed: boolean = false;\n\n /** Renders a collapse/expand toggle button on the separator. */\n @property({ type: Boolean })\n collapsible: boolean = false;\n\n /**\n * Ascending whitespace-separated snap points in the current mode's units.\n * An empty value keeps pointer resizing continuous.\n */\n @property({ type: String, attribute: 'snap-points' })\n snapPoints = '';\n\n /** Minimum release velocity, in px/s, that qualifies as a swipe. */\n @property({ type: Number, attribute: 'swipe-velocity' })\n swipeVelocity = 500;\n\n /** A human-readable string representation of the value. */\n get valueText() {\n return `${this.value}${this.mode === 'percent' ? '%' : 'px'}`;\n }\n\n @state()\n protected _minValue: number = 0;\n\n @state()\n protected _maxValue: number = 0;\n\n /** Last valid value, for collapse functionality. */\n @state()\n protected _lastValue: number = 0;\n\n @query('#primary', true)\n protected _$primary!: HTMLDivElement;\n\n @query('#separator-handle')\n protected _$separatorHandle!: HTMLDivElement;\n\n @queryAssignedElements()\n protected _$primaryElements!: Array<HTMLElement>;\n\n @queryAssignedElements({ slot: 'secondary' })\n protected _$secondaryElements!: Array<HTMLElement>;\n\n protected _initialMax: number = 0;\n\n protected _gestureStartValue = 0;\n protected _gestureRestoreValue = 0;\n protected _activeSnapAnimation: Animation | null = null;\n protected readonly _reducedMotion =\n typeof window !== 'undefined' ? window.matchMedia('(prefers-reduced-motion: reduce)') : null;\n\n protected readonly _gesture = new DragGestureController(this, {\n target: () => this._$separatorHandle,\n axis: this.orientation === 'horizontal' ? 'x' : 'y',\n focusOnStart: true,\n onStart: (detail) => this._onGestureStart(detail),\n onMove: (detail) => this._onGestureMove(detail),\n onEnd: (detail) => this._onGestureEnd(detail),\n onCancel: () => this._onGestureCancel(),\n });\n\n protected _resizeObserver = new ResizeObserver(() => this._onResize());\n\n protected _onKeyboardResize(action: KeyboardNavigationAction) {\n if (this.fixed) {\n return;\n }\n\n switch (action) {\n case 'next':\n this._setUserValue(this.value + this.step);\n break;\n case 'prev':\n this._setUserValue(this.value - this.step);\n break;\n case 'next-large':\n this._setUserValue(this.value + this.step * 10);\n break;\n case 'prev-large':\n this._setUserValue(this.value - this.step * 10);\n break;\n case 'start':\n this._setUserValue(this._effectiveMin);\n break;\n case 'end':\n this._setUserValue(this._effectiveMax);\n break;\n case 'toggle':\n this._setUserValue(\n this.value === this._effectiveMin ? this._lastValue : this._effectiveMin,\n );\n break;\n }\n }\n\n protected _onPointerResize(e: Pick<PointerEvent, 'clientX' | 'clientY'>) {\n if (this.fixed) {\n return;\n }\n\n const clientRect = this.getBoundingClientRect();\n\n if (this.orientation === 'vertical') {\n this._setUserValue(((e.clientY - clientRect.top) / clientRect.height) * this._maxValue);\n } else {\n this._setUserValue(((e.clientX - clientRect.left) / clientRect.width) * this._maxValue);\n }\n }\n\n /**\n * Settles at a declared snap point by zero-based index.\n *\n * Finite fractional indices are truncated and clamped. Calls without valid\n * snap points or with a non-finite index have no effect.\n *\n * @param index - zero-based index into `snapPoints`\n * @param behavior - whether to animate the movement\n */\n snapTo(index: number, behavior: 'animated' | 'instant' = 'animated'): void {\n const points = this._resolvedSnapPoints();\n\n if (!Number.isFinite(index) || points.length === 0) {\n return;\n }\n\n const clampedIndex = Math.max(0, Math.min(Math.trunc(index), points.length - 1));\n\n void this._settleToValue(points[clampedIndex], behavior);\n }\n\n protected _onGestureStart(_detail: DragGestureDetail): void {\n this._activeSnapAnimation?.cancel();\n this._activeSnapAnimation = null;\n this._gestureStartValue = this.value;\n this._gestureRestoreValue = this._lastValue;\n }\n\n protected _onGestureMove(detail: DragGestureDetail): void {\n this._onPointerResize({ clientX: detail.x, clientY: detail.y });\n }\n\n protected _onGestureEnd(detail: DragGestureDetail): void {\n const delta = this.orientation === 'horizontal' ? detail.deltaX : detail.deltaY;\n const velocity = this.orientation === 'horizontal' ? detail.velocityX : detail.velocityY;\n const decisive =\n Math.abs(delta) >= MIN_SWIPE_DISTANCE && Math.abs(velocity) >= this.swipeVelocity;\n\n if (decisive && this.collapsible) {\n if (velocity < 0) {\n const restoreValue =\n this._gestureRestoreValue > this._effectiveMin\n ? this._gestureRestoreValue\n : this._gestureStartValue;\n\n void this._settleToValue(this._effectiveMin, 'animated');\n this._lastValue = restoreValue;\n\n return;\n }\n\n if (this._gestureStartValue <= this._effectiveMin) {\n void this._settleToValue(\n Math.max(this._gestureRestoreValue, this._effectiveMin),\n 'animated',\n );\n\n return;\n }\n }\n\n const points = this._resolvedSnapPoints();\n\n if (points.length === 0) {\n return;\n }\n\n const index = decisive\n ? findNextSnapIndex(points, this._gestureStartValue, velocity > 0 ? 1 : -1)\n : findNearestSnapIndex(points, this.value);\n\n if (index >= 0) {\n void this._settleToValue(points[index], 'animated');\n }\n }\n\n protected _onGestureCancel(): void {\n this._activeSnapAnimation?.cancel();\n this._activeSnapAnimation = null;\n }\n\n protected _resolvedSnapPoints(): number[] {\n if (!this.snapPoints.trim()) {\n return [];\n }\n\n return this.snapPoints\n .trim()\n .split(/\\s+/)\n .map(Number)\n .filter(Number.isFinite)\n .map((point) => Math.min(Math.max(point, this._effectiveMin), this._effectiveMax))\n .filter((point, index, points) => index === 0 || point !== points[index - 1]);\n }\n\n protected async _settleToValue(value: number, behavior: 'animated' | 'instant'): Promise<void> {\n const $primary = this._$primary;\n const fromSize =\n this.orientation === 'horizontal'\n ? $primary.getBoundingClientRect().width\n : $primary.getBoundingClientRect().height;\n\n this._activeSnapAnimation?.cancel();\n this._activeSnapAnimation = null;\n this._setUserValue(value);\n await this.updateComplete;\n\n if (behavior === 'instant' || this._reducedMotion?.matches) {\n return;\n }\n\n const toSize =\n this.orientation === 'horizontal'\n ? $primary.getBoundingClientRect().width\n : $primary.getBoundingClientRect().height;\n\n if (fromSize === toSize) {\n return;\n }\n\n const property = this.orientation === 'horizontal' ? 'width' : 'height';\n const animation = $primary.animate(\n [{ [property]: `${fromSize}px` }, { [property]: `${toSize}px` }],\n {\n duration: this._snapDuration(),\n easing: SNAP_EASING,\n },\n );\n\n this._activeSnapAnimation = animation;\n\n try {\n await animation.finished;\n } catch {\n // A newer gesture or snap call owns the final visual state.\n } finally {\n if (this._activeSnapAnimation === animation) {\n this._activeSnapAnimation = null;\n }\n }\n }\n\n protected _snapDuration(): number {\n const raw = getComputedStyle(this).getPropertyValue('--rc-splitter-snap-duration').trim();\n const parsed = Number.parseFloat(raw);\n\n return Number.isFinite(parsed) ? parsed : DEFAULT_SNAP_DURATION_MS;\n }\n\n protected _onPrimaryChange(_e: Event) {\n queueMicrotask(() => {\n if (this._$primaryElements.length < 2) {\n return;\n }\n\n this._$primaryElements.slice(1).forEach(($el) => $el.setAttribute('slot', 'secondary'));\n });\n }\n\n protected _onSecondaryChange(_e: Event) {\n queueMicrotask(() => {\n if (!this._$secondaryElements.length || this._$primaryElements.length) {\n return;\n }\n\n this._$secondaryElements.at(0)?.removeAttribute('slot');\n });\n }\n\n protected _measureHostSize(axis: 'inline' | 'block'): number {\n const clientRect = this.getBoundingClientRect();\n const measuredSize = axis === 'inline' ? clientRect.width : clientRect.height;\n\n if (measuredSize > 0) {\n return Math.ceil(measuredSize);\n }\n\n const computedStyle = getComputedStyle(this);\n const fallbackSize = axis === 'inline' ? computedStyle.width : computedStyle.height;\n const parsedFallbackSize = Number.parseFloat(fallbackSize);\n\n return Number.isFinite(parsedFallbackSize) ? Math.ceil(parsedFallbackSize) : 0;\n }\n\n protected _onResize() {\n const $el = this._$primaryElements.at(0);\n const prevStyle = this._$primary.style.getPropertyValue('display');\n\n // Request animation frame to prevent layout paint jank.\n globalThis.requestAnimationFrame(() => {\n // Temporarily display the first light DOM element as a direct child for measurement.\n this._$primary.style.setProperty('display', 'contents');\n\n const clientRect = $el?.getBoundingClientRect() ?? this.getBoundingClientRect();\n\n if (this.mode !== 'percent') {\n const measured =\n this.orientation === 'horizontal'\n ? // For horizontal splitters, just take the host width...\n this._measureHostSize('inline')\n : // ...otherwise try to use the first lightDOM element's auto height, and cache it\n this._initialMax || Math.ceil(clientRect.height) || this._measureHostSize('block');\n\n // After initialization, ignore spurious zero measurements (e.g. during\n // Chromium's layout recalculation triggered by a secondary ResizeObserver\n // callback). A temporarily-zero result would clamp _value to 0 incorrectly.\n if (measured > 0 || !this._initialMax) {\n this._maxValue = measured;\n }\n } else {\n // Percentage max is always just 100%\n this._maxValue = 100.0;\n }\n\n if (!this._initialMax) {\n this._initialMax = this._maxValue;\n\n this._setValue(\n this._valueInitialized\n ? this._value\n : (this._hostValue ?? this.defaultValue ?? this._maxValue / 2),\n false,\n );\n } else if (this._hostValue !== undefined) {\n this._setValue(this._hostValue, false);\n } else {\n this._setValue(this.value, false);\n }\n\n // Restore previous display mode\n prevStyle\n ? this._$primary.style.setProperty('display', prevStyle)\n : this._$primary.style.removeProperty('display');\n });\n }\n\n connectedCallback() {\n super.connectedCallback();\n this._resizeObserver.observe(this);\n }\n\n disconnectedCallback(): void {\n this._resizeObserver.disconnect();\n this._activeSnapAnimation?.cancel();\n this._activeSnapAnimation = null;\n super.disconnectedCallback();\n }\n\n firstUpdated() {\n this._onResize();\n }\n\n protected updated(): void {\n this._gesture.setOptions({\n axis: this.orientation === 'horizontal' ? 'x' : 'y',\n target: () => this._$separatorHandle,\n });\n }\n\n render() {\n return html`\n <div\n id=\"primary\"\n part=\"primary\"\n aria-label=${this.label}\n style=${this.orientation === 'horizontal'\n ? `width: ${this.valueText}`\n : `height: ${this.valueText}`}\n ?hidden=${this.value === this._minValue}\n >\n <slot @slotchange=${this._onPrimaryChange}></slot>\n </div>\n\n <div id=\"separator\" part=\"separator\">\n ${this.collapsible && this._$secondaryElements.length && !this.fixed\n ? html`<button\n id=\"collapse-button\"\n part=\"collapse-button\"\n aria-label=${this._isCollapsed ? `Expand ${this.label}` : `Collapse ${this.label}`}\n aria-expanded=${String(!this._isCollapsed)}\n aria-controls=\"primary\"\n @click=${this._onCollapseButtonClick}\n >\n ${this._collapseButtonIcon}\n </button>`\n : nothing}\n <div\n id=\"separator-handle\"\n role=\"separator\"\n tabindex=\"0\"\n part=\"separator-handle\"\n aria-labelledby=\"primary\"\n aria-controls=\"primary\"\n aria-orientation=${this.orientation === 'horizontal' ? 'vertical' : 'horizontal'}\n aria-valuenow=${this.value}\n aria-valuetext=${this.valueText}\n aria-valuemin=${this._effectiveMin}\n aria-valuemax=${this._effectiveMax}\n @keydown=${this._onCollapseKeydown}\n ${keyNavigation(this._onKeyboardResize)}\n ${keyInteraction()}\n ?hidden=${!this._$secondaryElements.length}\n ></div>\n </div>\n\n <aside\n id=\"secondary\"\n part=\"secondary\"\n ?hidden=${!this._$secondaryElements.length || this.value === this._maxValue}\n >\n <slot name=\"secondary\" @slotchange=${this._onSecondaryChange}></slot>\n </aside>\n `;\n }\n}\n\nexport default RCSplitter;\n"],"names":["splitterStyles","css","MIN_SWIPE_DISTANCE","DEFAULT_SNAP_DURATION_MS","SNAP_EASING","_RCSplitter","LitElement","DragGestureController","detail","val","oldValue","e","d","html","dispatch","action","clientRect","index","behavior","points","clampedIndex","_detail","delta","velocity","decisive","restoreValue","findNextSnapIndex","findNearestSnapIndex","point","value","$primary","fromSize","toSize","property","animation","raw","parsed","_e","$el","axis","measuredSize","computedStyle","fallbackSize","parsedFallbackSize","prevStyle","measured","nothing","keyNavigation","keyInteraction","RCSplitter","__decorateClass","state","query","queryAssignedElements"],"mappings":";;;AAEO,MAAMA,IAAiBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACiB9B,MAAMC,I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"}
|
package/dist/rc-splitter.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
|
-
import { KeyboardNavigationAction } from '@rcarls/rc-common';
|
|
3
|
-
type SplitterOrientation =
|
|
4
|
-
type SplitterMode =
|
|
2
|
+
import { DragGestureController, DragGestureDetail, KeyboardNavigationAction } from '@rcarls/rc-common';
|
|
3
|
+
type SplitterOrientation = 'horizontal' | 'vertical';
|
|
4
|
+
type SplitterMode = 'length' | 'percent' | 'fixed';
|
|
5
5
|
declare global {
|
|
6
6
|
interface HTMLElementTagNameMap {
|
|
7
|
-
|
|
7
|
+
'rc-splitter': RCSplitter;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
* Resizable pane splitter with pointer, keyboard,
|
|
12
|
-
* the WAI-ARIA Window Splitter pattern.
|
|
11
|
+
* Resizable pane splitter with pointer, keyboard, anchored settling, and
|
|
12
|
+
* collapse/restore controls, following the WAI-ARIA Window Splitter pattern.
|
|
13
13
|
*
|
|
14
14
|
* Set `orientation="vertical"` for a vertical splitter
|
|
15
15
|
*
|
|
@@ -19,6 +19,23 @@ declare global {
|
|
|
19
19
|
* @slot - Primary pane contents
|
|
20
20
|
* @slot secondary - Secondary pane contents (optional)
|
|
21
21
|
*
|
|
22
|
+
* @fires rc-splitter-change - Fired when the separator position changes; `detail: { value, valueText }`
|
|
23
|
+
*
|
|
24
|
+
* @attr label - Accessible label applied to the primary pane and referenced by the separator
|
|
25
|
+
* handle's `aria-labelledby`.
|
|
26
|
+
* @attr orientation - Layout direction: `horizontal` (left/right panes) or `vertical` (top/bottom panes).
|
|
27
|
+
* @attr mode - Value units and pane sizing behavior: `length`, `percent`, or `fixed`.
|
|
28
|
+
* @attr step - Keyboard resize step size, in the current mode's units.
|
|
29
|
+
* @attr min - Minimum primary pane size, in the current mode's units.
|
|
30
|
+
* @attr max - Maximum primary pane size, in the current mode's units. Defaults to the full
|
|
31
|
+
* container size.
|
|
32
|
+
* @attr value - Current primary pane size. Host writes update silently.
|
|
33
|
+
* @attr default-value - Initial uncontrolled primary pane size.
|
|
34
|
+
* @attr fixed - Disables pointer and keyboard resizing without changing pane size.
|
|
35
|
+
* @attr collapsible - Renders a collapse/expand toggle button on the separator.
|
|
36
|
+
* @attr snap-points - Ascending whitespace-separated anchors, in the current mode's units.
|
|
37
|
+
* @attr swipe-velocity - Minimum release velocity, in px/s, that qualifies as a swipe.
|
|
38
|
+
*
|
|
22
39
|
* @cssprop [--rc-splitter-separator-size=6px] - Thickness of the separator bar
|
|
23
40
|
* @cssprop [--rc-splitter-separator-handle-size=100%] - Length of the drag handle area within the separator (also the length of the visible indicator)
|
|
24
41
|
* @cssprop [--rc-splitter-separator-color=color-mix(in srgb, ButtonBorder 35%, Canvas 65%)] - Separator background color
|
|
@@ -30,6 +47,7 @@ declare global {
|
|
|
30
47
|
* @cssprop [--rc-splitter-handle-fill=transparent] - background-color of the visual indicator; effective when --rc-splitter-handle-pattern is none (e.g. for a solid pill)
|
|
31
48
|
* @cssprop [--rc-splitter-handle-hover-fill=transparent] - background-color of the visual indicator on hover; scoped to the indicator element only, not the full separator strip
|
|
32
49
|
* @cssprop [--rc-splitter-handle-transition=0ms] - CSS transition duration/easing for the visual indicator's background-color changes
|
|
50
|
+
* @cssprop [--rc-splitter-snap-duration=200ms] - Duration of anchored settling after pointer release or `snapTo()`
|
|
33
51
|
* @cssprop [--rc-splitter-collapse-button-size=20px] - Diameter of the collapse/expand toggle button
|
|
34
52
|
* @cssprop [--rc-splitter-collapse-button-offset=8px] - Distance from the start edge of the separator to the collapse button center
|
|
35
53
|
* @cssprop [--rc-splitter-collapse-button-bg=Canvas] - Collapse button background color
|
|
@@ -52,7 +70,13 @@ export declare class RCSplitter extends LitElement {
|
|
|
52
70
|
label: string;
|
|
53
71
|
/** Splitter orientation, for keyboard navigation and initial sizing. */
|
|
54
72
|
orientation: SplitterOrientation;
|
|
55
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* Determines value units and pane sizing behavior.
|
|
75
|
+
*
|
|
76
|
+
* - `length` uses px for the primary pane size.
|
|
77
|
+
* - `percent` uses percentage points.
|
|
78
|
+
* - `fixed` uses px for a clampable fixed primary pane while the secondary pane flexes.
|
|
79
|
+
*/
|
|
56
80
|
mode: SplitterMode;
|
|
57
81
|
/** The step size for resizing, in either pixels or percentage points depending on `mode`. */
|
|
58
82
|
step: number;
|
|
@@ -78,14 +102,21 @@ export declare class RCSplitter extends LitElement {
|
|
|
78
102
|
protected _toggleCollapse(): void;
|
|
79
103
|
protected _onCollapseButtonClick(): void;
|
|
80
104
|
protected _onCollapseKeydown(e: KeyboardEvent): void;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
105
|
+
protected get _collapseButtonIcon(): import('lit').TemplateResult<1>;
|
|
106
|
+
protected _setValue(val: number, dispatch: boolean): void;
|
|
107
|
+
protected _setUserValue(val: number): void;
|
|
84
108
|
private _value;
|
|
85
|
-
/**
|
|
109
|
+
/** Disables pointer and keyboard resizing without changing pane size. */
|
|
86
110
|
fixed: boolean;
|
|
87
111
|
/** Renders a collapse/expand toggle button on the separator. */
|
|
88
112
|
collapsible: boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Ascending whitespace-separated snap points in the current mode's units.
|
|
115
|
+
* An empty value keeps pointer resizing continuous.
|
|
116
|
+
*/
|
|
117
|
+
snapPoints: string;
|
|
118
|
+
/** Minimum release velocity, in px/s, that qualifies as a swipe. */
|
|
119
|
+
swipeVelocity: number;
|
|
89
120
|
/** A human-readable string representation of the value. */
|
|
90
121
|
get valueText(): string;
|
|
91
122
|
protected _minValue: number;
|
|
@@ -93,19 +124,43 @@ export declare class RCSplitter extends LitElement {
|
|
|
93
124
|
/** Last valid value, for collapse functionality. */
|
|
94
125
|
protected _lastValue: number;
|
|
95
126
|
protected _$primary: HTMLDivElement;
|
|
127
|
+
protected _$separatorHandle: HTMLDivElement;
|
|
96
128
|
protected _$primaryElements: Array<HTMLElement>;
|
|
97
129
|
protected _$secondaryElements: Array<HTMLElement>;
|
|
98
130
|
protected _initialMax: number;
|
|
131
|
+
protected _gestureStartValue: number;
|
|
132
|
+
protected _gestureRestoreValue: number;
|
|
133
|
+
protected _activeSnapAnimation: Animation | null;
|
|
134
|
+
protected readonly _reducedMotion: MediaQueryList | null;
|
|
135
|
+
protected readonly _gesture: DragGestureController;
|
|
99
136
|
protected _resizeObserver: ResizeObserver;
|
|
100
137
|
protected _onKeyboardResize(action: KeyboardNavigationAction): void;
|
|
101
|
-
protected _onPointerResize(e:
|
|
138
|
+
protected _onPointerResize(e: Pick<PointerEvent, 'clientX' | 'clientY'>): void;
|
|
139
|
+
/**
|
|
140
|
+
* Settles at a declared snap point by zero-based index.
|
|
141
|
+
*
|
|
142
|
+
* Finite fractional indices are truncated and clamped. Calls without valid
|
|
143
|
+
* snap points or with a non-finite index have no effect.
|
|
144
|
+
*
|
|
145
|
+
* @param index - zero-based index into `snapPoints`
|
|
146
|
+
* @param behavior - whether to animate the movement
|
|
147
|
+
*/
|
|
148
|
+
snapTo(index: number, behavior?: 'animated' | 'instant'): void;
|
|
149
|
+
protected _onGestureStart(_detail: DragGestureDetail): void;
|
|
150
|
+
protected _onGestureMove(detail: DragGestureDetail): void;
|
|
151
|
+
protected _onGestureEnd(detail: DragGestureDetail): void;
|
|
152
|
+
protected _onGestureCancel(): void;
|
|
153
|
+
protected _resolvedSnapPoints(): number[];
|
|
154
|
+
protected _settleToValue(value: number, behavior: 'animated' | 'instant'): Promise<void>;
|
|
155
|
+
protected _snapDuration(): number;
|
|
102
156
|
protected _onPrimaryChange(_e: Event): void;
|
|
103
157
|
protected _onSecondaryChange(_e: Event): void;
|
|
104
|
-
|
|
158
|
+
protected _measureHostSize(axis: 'inline' | 'block'): number;
|
|
105
159
|
protected _onResize(): void;
|
|
106
160
|
connectedCallback(): void;
|
|
107
161
|
disconnectedCallback(): void;
|
|
108
162
|
firstUpdated(): void;
|
|
163
|
+
protected updated(): void;
|
|
109
164
|
render(): import('lit').TemplateResult<1>;
|
|
110
165
|
}
|
|
111
166
|
export default RCSplitter;
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rc-splitter-BZgnDbmR.js","sources":["../src/rc-splitter.styles.ts","../src/rc-splitter.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const splitterStyles = css`\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n }\n\n :host {\n --rc-splitter-separator-size: 6px;\n\n position: relative;\n display: flex;\n flex-direction: row;\n align-items: stretch;\n }\n\n :host([orientation='vertical']) {\n flex-direction: column;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n /* because :has(:focus-visible) doesn't work across slot boundary */\n :host([data-interaction-mode='keyboard']):focus-within {\n outline: auto;\n }\n\n ::slotted(*) {\n width: 100%;\n height: 100%;\n }\n\n #separator {\n grid-column: separator;\n flex: 0 0 var(--rc-splitter-separator-size, 6px);\n display: flex;\n flex-direction: column;\n justify-content: center;\n background-color: var(--rc-splitter-separator-color, color-mix(in srgb, ButtonBorder 35%, Canvas 65%));\n border-left: var(--rc-splitter-separator-border-inline-start, var(--rc-splitter-keyline, 1px solid ButtonBorder));\n border-right: var(--rc-splitter-separator-border-inline-end, var(--rc-splitter-keyline, 1px solid ButtonBorder));\n /* z-index: 1 as a flex item stacks separator above pane siblings so the\n ::after touch-target circle (which extends past the strip) is hittable */\n z-index: 1;\n /* Required for collapse-button absolute positioning */\n position: relative;\n\n :host([orientation='vertical']) & {\n flex-direction: row;\n border-left: unset;\n border-right: unset;\n border-top: var(--rc-splitter-separator-border-block-start, var(--rc-splitter-keyline, 1px solid ButtonBorder));\n border-bottom: var(--rc-splitter-separator-border-block-end, var(--rc-splitter-keyline, 1px solid ButtonBorder));\n }\n }\n\n #collapse-button {\n /* Positioned at the start of the separator strip, centered on the cross\n axis. The button intentionally protrudes into the primary pane so it\n is visible and hittable at a reasonable size even on narrow strips. */\n position: absolute;\n top: var(--rc-splitter-collapse-button-offset, 8px);\n left: 50%;\n transform: translateX(-50%);\n width: var(--rc-splitter-collapse-button-size, 20px);\n height: var(--rc-splitter-collapse-button-size, 20px);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n border: 1px solid var(--rc-splitter-collapse-button-border, ButtonBorder);\n border-radius: 50%;\n background: var(--rc-splitter-collapse-button-bg, Canvas);\n color: var(--rc-splitter-collapse-button-color, ButtonText);\n cursor: pointer;\n line-height: 1;\n\n &:hover {\n background: var(--rc-splitter-collapse-button-hover-bg, ButtonFace);\n }\n\n &:focus-visible {\n outline: 2px solid Highlight;\n outline-offset: 2px;\n }\n\n :host([orientation='vertical']) & {\n top: 50%;\n left: var(--rc-splitter-collapse-button-offset, 8px);\n transform: translateY(-50%);\n }\n }\n\n #separator-handle {\n width: 100%;\n height: var(--rc-splitter-separator-handle-size, 100%);\n cursor: col-resize;\n display: flex;\n align-items: center;\n justify-content: center;\n /* Required so ::after is positioned relative to this element */\n position: relative;\n\n /* ── Visual drag indicator ─────────────────────────────────────────────\n Default: 3-dot vertical grip (horizontal splitter / vertical bar).\n Themes override via --rc-splitter-handle-pattern (background-image) and\n --rc-splitter-handle-fill (background-color). */\n &::before {\n content: '';\n display: block;\n width: var(--rc-splitter-handle-thickness, 4px);\n height: 100%;\n background-color: var(--rc-splitter-handle-fill, transparent);\n background-image: var(\n --rc-splitter-handle-pattern,\n radial-gradient(circle 1px at 50% calc(50% - 5px), var(--rc-splitter-handle-color, ButtonBorder) 100%, transparent 100%),\n radial-gradient(circle 1px at 50% 50%, var(--rc-splitter-handle-color, ButtonBorder) 100%, transparent 100%),\n radial-gradient(circle 1px at 50% calc(50% + 5px), var(--rc-splitter-handle-color, ButtonBorder) 100%, transparent 100%)\n );\n border-radius: var(--rc-splitter-handle-border-radius, 0);\n pointer-events: none;\n transition: background-color var(--rc-splitter-handle-transition, 0ms);\n }\n\n /* Hover highlight stays on the visual indicator only, never the full strip */\n &:hover::before {\n background-color: var(--rc-splitter-handle-hover-fill, transparent);\n }\n\n /* ── Touch target circle ───────────────────────────────────────────────\n 24 px diameter transparent circle, centered on the handle. Invisible\n and non-interactive for mouse/keyboard. On coarse-pointer (touch)\n devices the circle becomes hittable, giving a WCAG-compliant touch\n target without widening the visual separator. */\n &::after {\n content: '';\n position: absolute;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n pointer-events: none;\n }\n\n :host([orientation='vertical']) & {\n width: var(--rc-splitter-separator-handle-size, 100%);\n height: 100%;\n cursor: row-resize;\n\n /* Horizontal 3-dot grip (vertical splitter / horizontal bar) */\n &::before {\n width: 100%;\n height: var(--rc-splitter-handle-thickness, 4px);\n background-image: var(\n --rc-splitter-handle-pattern,\n radial-gradient(circle 1px at calc(50% - 5px) 50%, var(--rc-splitter-handle-color, ButtonBorder) 100%, transparent 100%),\n radial-gradient(circle 1px at 50% 50%, var(--rc-splitter-handle-color, ButtonBorder) 100%, transparent 100%),\n radial-gradient(circle 1px at calc(50% + 5px) 50%, var(--rc-splitter-handle-color, ButtonBorder) 100%, transparent 100%)\n );\n }\n }\n\n :host([fixed]) & {\n pointer-events: none;\n }\n }\n\n /* Activate the touch target circle only on coarse-pointer (touch) devices */\n @media (any-pointer: coarse) {\n #separator-handle::after {\n pointer-events: auto;\n }\n }\n\n #primary,\n #secondary {\n overflow: hidden;\n }\n\n #primary {\n grid-column: primary;\n flex: 0 0 auto;\n }\n\n #secondary {\n grid-column: secondary;\n flex: 1;\n }\n`;\n\nexport default splitterStyles;\n","import { LitElement, html, nothing } from \"lit\";\nimport {\n property,\n state,\n query,\n queryAssignedElements,\n} from \"lit/decorators.js\";\n\nimport {\n keyInteraction,\n keyNavigation,\n type KeyboardNavigationAction,\n mouseMove,\n} from \"@rcarls/rc-common\";\n\nimport splitterStyles from \"./rc-splitter.styles\";\n\ntype SplitterOrientation = \"horizontal\" | \"vertical\";\n\ntype SplitterMode = \"length\" | \"percent\";\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"rc-splitter\": RCSplitter;\n }\n}\n\n/**\n * Resizable pane splitter with pointer, keyboard, and collapse/restore controls, following\n * the WAI-ARIA Window Splitter pattern.\n *\n * Set `orientation=\"vertical\"` for a vertical splitter\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-splitter rc-splitter docs}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/ WAI-ARIA Window Splitter pattern}\n *\n * @slot - Primary pane contents\n * @slot secondary - Secondary pane contents (optional)\n *\n * @cssprop [--rc-splitter-separator-size=6px] - Thickness of the separator bar\n * @cssprop [--rc-splitter-separator-handle-size=100%] - Length of the drag handle area within the separator (also the length of the visible indicator)\n * @cssprop [--rc-splitter-separator-color=color-mix(in srgb, ButtonBorder 35%, Canvas 65%)] - Separator background color\n * @cssprop [--rc-splitter-keyline=1px solid ButtonBorder] - Shared separator keyline border\n * @cssprop [--rc-splitter-handle-color=ButtonBorder] - Color of the dot grip indicators (default visual)\n * @cssprop [--rc-splitter-handle-thickness=4px] - Cross-axis size of the visual indicator (dot column width or pill/line thickness)\n * @cssprop [--rc-splitter-handle-border-radius=0] - Border-radius of the visual indicator; set to a large value (e.g. 999px) for a pill shape\n * @cssprop [--rc-splitter-handle-pattern=<3-dot radial-gradient>] - background-image for the visual indicator; set to `none` to use a solid fill via --rc-splitter-handle-fill instead\n * @cssprop [--rc-splitter-handle-fill=transparent] - background-color of the visual indicator; effective when --rc-splitter-handle-pattern is none (e.g. for a solid pill)\n * @cssprop [--rc-splitter-handle-hover-fill=transparent] - background-color of the visual indicator on hover; scoped to the indicator element only, not the full separator strip\n * @cssprop [--rc-splitter-handle-transition=0ms] - CSS transition duration/easing for the visual indicator's background-color changes\n * @cssprop [--rc-splitter-collapse-button-size=20px] - Diameter of the collapse/expand toggle button\n * @cssprop [--rc-splitter-collapse-button-offset=8px] - Distance from the start edge of the separator to the collapse button center\n * @cssprop [--rc-splitter-collapse-button-bg=Canvas] - Collapse button background color\n * @cssprop [--rc-splitter-collapse-button-hover-bg=ButtonFace] - Collapse button background color on hover\n * @cssprop [--rc-splitter-collapse-button-border=ButtonBorder] - Collapse button border color\n * @cssprop [--rc-splitter-collapse-button-color=ButtonText] - Collapse button icon color\n * @cssprop [--rc-splitter-separator-border-inline-start=1px solid ButtonBorder] - Inline-start border\n * @cssprop [--rc-splitter-separator-border-inline-end=1px solid ButtonBorder] - Inline-end border\n * @cssprop [--rc-splitter-separator-border-block-start=1px solid ButtonBorder] - Block-start border (vertical orientation)\n * @cssprop [--rc-splitter-separator-border-block-end=1px solid ButtonBorder] - Block-end border (vertical orientation)\n * @csspart primary - Primary pane container\n * @csspart secondary - Secondary pane container\n * @csspart separator - The separator bar\n * @csspart separator-handle - The focusable drag handle\n * @csspart collapse-button - The collapse/expand toggle button (only rendered when `collapsible` is set)\n */\nexport class RCSplitter extends LitElement {\n static styles = [splitterStyles];\n\n /** Accessible label for this splitter. Default label is 'Splitter'. */\n @property({ type: String })\n label = \"Splitter\";\n\n /** Splitter orientation, for keyboard navigation and initial sizing. */\n @property({ type: String, reflect: true })\n orientation: SplitterOrientation = \"horizontal\";\n\n /** Determines length units for min, max and step attributes, one of either `length` (default) or `percent` */\n @property({ type: String })\n mode: SplitterMode = \"length\";\n\n /** The step size for resizing, in either pixels or percentage points depending on `mode`. */\n @property({ type: Number })\n step: number = 1;\n\n /** Minimum size of the primary pane in current mode units. Defaults to 0. */\n @property({ type: Number })\n min: number = 0;\n\n /** Maximum size of the primary pane in current mode units. Defaults to the full container size. */\n @property({ type: Number })\n max: number | undefined = undefined;\n\n private _defaultValue: number | undefined;\n private _hostValue: number | undefined;\n private _valueInitialized = false;\n\n /** The current splitter value. Host writes update silently. */\n @property({ type: Number })\n set value(val: number) {\n const oldValue = this._hostValue;\n\n this._hostValue = val;\n\n if (this._initialMax) {\n this._setValue(val, false);\n }\n\n this.requestUpdate(\"value\", oldValue);\n }\n\n /** The current splitter value, corresponding to the separator position, in either pixels or percentage points depending on `mode`. */\n get value() {\n return this._value;\n }\n\n /** Initial uncontrolled splitter value. */\n @property({ type: Number, attribute: \"default-value\" })\n set defaultValue(val: number | undefined) {\n const oldValue = this._defaultValue;\n\n this._defaultValue = val;\n\n if (!this._initialMax && this._hostValue === undefined && val !== undefined) {\n this._setValue(val, false);\n }\n\n this.requestUpdate(\"defaultValue\", oldValue);\n }\n\n /** Initial uncontrolled splitter value. */\n get defaultValue() {\n return this._defaultValue;\n }\n\n protected get _effectiveMin(): number {\n return Math.max(this._minValue, this.min);\n }\n\n protected get _effectiveMax(): number {\n return Math.min(this._maxValue, this.max ?? this._maxValue);\n }\n\n /** True once initialized and the primary pane is at its effective minimum. */\n protected get _isCollapsed(): boolean {\n return this._initialMax > 0 && this.value <= this._effectiveMin;\n }\n\n protected _toggleCollapse(): void {\n this._setUserValue(\n this._isCollapsed ? this._lastValue : this._effectiveMin,\n );\n }\n\n protected _onCollapseButtonClick(): void {\n this._toggleCollapse();\n }\n\n protected _onCollapseKeydown(e: KeyboardEvent): void {\n if (!this.collapsible || this.fixed) return;\n if (!e.ctrlKey && !e.metaKey) return;\n\n const isRelevantKey =\n this.orientation === \"horizontal\"\n ? e.key === \"ArrowLeft\" || e.key === \"ArrowRight\"\n : e.key === \"ArrowUp\" || e.key === \"ArrowDown\";\n\n if (isRelevantKey) {\n e.preventDefault();\n e.stopImmediatePropagation();\n this._toggleCollapse();\n }\n }\n\n private get _collapseButtonIcon() {\n const isHorizontal = this.orientation === \"horizontal\";\n // Chevron points LEFT/UP to collapse (separator moves toward primary),\n // RIGHT/DOWN to expand (separator moves away from primary).\n const d = isHorizontal\n ? this._isCollapsed\n ? \"M 3 1 L 7 5 L 3 9\"\n : \"M 7 1 L 3 5 L 7 9\"\n : this._isCollapsed\n ? \"M 1 3 L 5 7 L 9 3\"\n : \"M 1 7 L 5 3 L 9 7\";\n\n return html`<svg\n aria-hidden=\"true\"\n viewBox=\"0 0 10 10\"\n width=\"10\"\n height=\"10\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=${d} />\n </svg>`;\n }\n\n private _setValue(val: number, dispatch: boolean): void {\n const oldValue = this._value;\n\n this._value = Math.min(\n Math.max(Math.round(val / this.step) * this.step, this._effectiveMin),\n this._effectiveMax,\n );\n\n if (dispatch && this._value !== oldValue) {\n this.dispatchEvent(\n new CustomEvent(\"rc-splitter-change\", {\n bubbles: true,\n composed: true,\n detail: { value: this._value, valueText: this.valueText },\n }),\n );\n }\n }\n\n private _setUserValue(val: number): void {\n this._valueInitialized = true;\n this._hostValue = undefined;\n // Capture the last position above the effective minimum before a user-driven\n // change so toggle-collapse can restore it. Internal resize callbacks use\n // _setValue directly and must not overwrite this.\n if (this._value > this._effectiveMin) {\n this._lastValue = this._value;\n }\n this._setValue(val, true);\n }\n\n @state()\n private _value: number = 0;\n\n /** Toggles resizing ability */\n @property({ type: Boolean })\n fixed: boolean = false;\n\n /** Renders a collapse/expand toggle button on the separator. */\n @property({ type: Boolean })\n collapsible: boolean = false;\n\n /** A human-readable string representation of the value. */\n get valueText() {\n return `${this.value}${this.mode === \"length\" ? \"px\" : \"%\"}`;\n }\n\n @state()\n protected _minValue: number = 0;\n\n @state()\n protected _maxValue: number = 0;\n\n /** Last valid value, for collapse functionality. */\n @state()\n protected _lastValue: number = 0;\n\n @query(\"#primary\", true)\n protected _$primary!: HTMLDivElement;\n\n @queryAssignedElements()\n protected _$primaryElements!: Array<HTMLElement>;\n\n @queryAssignedElements({ slot: \"secondary\" })\n protected _$secondaryElements!: Array<HTMLElement>;\n\n protected _initialMax: number = 0;\n\n protected _resizeObserver = new ResizeObserver(() => this._onResize());\n\n protected _onKeyboardResize(action: KeyboardNavigationAction) {\n if (this.fixed) {\n return;\n }\n\n switch (action) {\n case \"next\":\n this._setUserValue(this.value + this.step);\n break;\n case \"prev\":\n this._setUserValue(this.value - this.step);\n break;\n case \"next-large\":\n this._setUserValue(this.value + this.step * 10);\n break;\n case \"prev-large\":\n this._setUserValue(this.value - this.step * 10);\n break;\n case \"start\":\n this._setUserValue(this._effectiveMin);\n break;\n case \"end\":\n this._setUserValue(this._effectiveMax);\n break;\n case \"toggle\":\n this._setUserValue(\n this.value === this._effectiveMin ? this._lastValue : this._effectiveMin,\n );\n break;\n }\n }\n\n protected _onPointerResize(e: MouseEvent) {\n if (this.fixed) {\n return;\n }\n\n const clientRect = this.getBoundingClientRect();\n\n if (this.orientation === \"vertical\") {\n this._setUserValue(\n ((e.clientY - clientRect.top) / clientRect.height) * this._maxValue,\n );\n } else {\n this._setUserValue(\n ((e.clientX - clientRect.left) / clientRect.width) * this._maxValue,\n );\n }\n }\n\n protected _onPrimaryChange(_e: Event) {\n queueMicrotask(() => {\n if (this._$primaryElements.length < 2) return;\n\n this._$primaryElements\n .slice(1)\n .forEach((el) => el.setAttribute(\"slot\", \"secondary\"));\n });\n }\n\n protected _onSecondaryChange(_e: Event) {\n queueMicrotask(() => {\n if (!this._$secondaryElements.length || this._$primaryElements.length) {\n return;\n }\n\n this._$secondaryElements.at(0)?.removeAttribute(\"slot\");\n });\n }\n\n private _measureHostSize(axis: \"inline\" | \"block\"): number {\n const clientRect = this.getBoundingClientRect();\n const measuredSize = axis === \"inline\" ? clientRect.width : clientRect.height;\n\n if (measuredSize > 0) {\n return Math.ceil(measuredSize);\n }\n\n const computedStyle = getComputedStyle(this);\n const fallbackSize =\n axis === \"inline\" ? computedStyle.width : computedStyle.height;\n const parsedFallbackSize = Number.parseFloat(fallbackSize);\n\n return Number.isFinite(parsedFallbackSize)\n ? Math.ceil(parsedFallbackSize)\n : 0;\n }\n\n protected _onResize() {\n const el = this._$primaryElements.at(0);\n const prevStyle = this._$primary.style.getPropertyValue(\"display\");\n\n // Request animation frame to prevent layout paint jank.\n globalThis.requestAnimationFrame(() => {\n // Temporarily display the first light DOM element as a direct child for measurement.\n this._$primary.style.setProperty(\"display\", \"contents\");\n\n const clientRect =\n el?.getBoundingClientRect() ?? this.getBoundingClientRect();\n\n if (this.mode === \"length\") {\n const measured =\n this.orientation === \"horizontal\"\n ? // For horizontal splitters, just take the host width...\n this._measureHostSize(\"inline\")\n : // ...otherwise try to use the first lightDOM element's auto height, and cache it\n this._initialMax ||\n Math.ceil(clientRect.height) ||\n this._measureHostSize(\"block\");\n\n // After initialization, ignore spurious zero measurements (e.g. during\n // Chromium's layout recalculation triggered by a secondary ResizeObserver\n // callback). A temporarily-zero result would clamp _value to 0 incorrectly.\n if (measured > 0 || !this._initialMax) {\n this._maxValue = measured;\n }\n } else {\n // Percentage max is always just 100%\n this._maxValue = 100.0;\n }\n\n if (!this._initialMax) {\n this._initialMax = this._maxValue;\n this._setValue(\n this._valueInitialized\n ? this._value\n : (this._hostValue ?? this.defaultValue ?? this._maxValue / 2),\n false,\n );\n } else if (this._hostValue !== undefined) {\n this._setValue(this._hostValue, false);\n } else {\n this._setValue(this.value, false);\n }\n\n // Restore previous display mode\n prevStyle\n ? this._$primary.style.setProperty(\"display\", prevStyle)\n : this._$primary.style.removeProperty(\"display\");\n });\n }\n\n connectedCallback() {\n super.connectedCallback();\n this._resizeObserver.observe(this);\n }\n\n disconnectedCallback(): void {\n this._resizeObserver.disconnect();\n super.disconnectedCallback();\n }\n\n firstUpdated() {\n this._onResize();\n }\n\n render() {\n return html`\n <div\n id=\"primary\"\n part=\"primary\"\n aria-label=${this.label}\n style=${this.orientation === \"horizontal\"\n ? `width: ${this.valueText}`\n : `height: ${this.valueText}`}\n ?hidden=${this.value === this._minValue}\n >\n <slot @slotchange=${this._onPrimaryChange}></slot>\n </div>\n\n <div id=\"separator\" part=\"separator\">\n ${this.collapsible && this._$secondaryElements.length && !this.fixed\n ? html`<button\n id=\"collapse-button\"\n part=\"collapse-button\"\n aria-label=${this._isCollapsed\n ? `Expand ${this.label}`\n : `Collapse ${this.label}`}\n aria-expanded=${String(!this._isCollapsed)}\n aria-controls=\"primary\"\n @click=${this._onCollapseButtonClick}\n >${this._collapseButtonIcon}</button>`\n : nothing}\n <div\n id=\"separator-handle\"\n role=\"separator\"\n tabindex=\"0\"\n part=\"separator-handle\"\n aria-labelledby=\"primary\"\n aria-controls=\"primary\"\n aria-orientation=${this.orientation === 'horizontal' ? 'vertical' : 'horizontal'}\n aria-valuenow=${this.value}\n aria-valuetext=${this.valueText}\n aria-valuemin=${this._effectiveMin}\n aria-valuemax=${this._effectiveMax}\n @keydown=${this._onCollapseKeydown}\n ${keyNavigation(this._onKeyboardResize)}\n ${keyInteraction()}\n ${mouseMove(this._onPointerResize)}\n ?hidden=${!this._$secondaryElements.length}\n ></div>\n </div>\n\n <aside\n id=\"secondary\"\n part=\"secondary\"\n ?hidden=${!this._$secondaryElements.length ||\n this.value === this._maxValue}\n >\n <slot name=\"secondary\" @slotchange=${this._onSecondaryChange}></slot>\n </aside>\n `;\n }\n}\n\nexport default RCSplitter;\n"],"names":["splitterStyles","css","_RCSplitter","LitElement","val","oldValue","d","html","dispatch","action","clientRect","_e","el","axis","measuredSize","computedStyle","fallbackSize","parsedFallbackSize","prevStyle","measured","nothing","keyNavigation","keyInteraction","mouseMove","RCSplitter","__decorateClass","property","state","query","queryAssignedElements"],"mappings":"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"}
|