UNPKG

igniteui-webcomponents

Version:

Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.

192 lines 6.36 kB
import { findElementFromEventPath } from '../common/util.js'; import { createDefaultGhostElement, getDefaultLayer } from './default-ghost.js'; const additionalEvents = [ 'pointermove', 'lostpointercapture', 'contextmenu', ]; class ResizeController { get _element() { return this._activeRef ?? this._host; } get _resizeTarget() { return this._options.resizeTarget?.call(this._host) ?? this._host; } get _layer() { if (!this._isDeferred) { return this._host; } return this._options.layer?.() ?? this._host; } get _isDeferred() { return this._options.mode === 'deferred'; } get _stateParameters() { const { initial, current } = this._state; return { initial, current, deltaX: current.width - initial.width, deltaY: current.height - initial.height, ghost: this._ghost, trigger: this._activeRef, }; } constructor(host, options) { this._options = { enabled: true, layer: getDefaultLayer, }; this._id = -1; this._hasPointerCapture = false; this._activeRef = null; this._ghost = null; this._host = host; this._host.addController(this); this.set(options); } get enabled() { return Boolean(this._options.enabled); } set(options) { Object.assign(this._options, options); } dispose() { this._setResizeState(false); this._removeGhostElement(); this._activeRef = null; } hostConnected() { this._host.addEventListener('pointerdown', this); this._host.addEventListener('touchstart', this, { passive: false }); } hostDisconnected() { this._host.removeEventListener('pointerdown', this); this._host.removeEventListener('touchstart', this); this._setResizeCancelListener(false); this._removeGhostElement(); } handleEvent(event) { if (!this.enabled) { return; } switch (event.type) { case 'touchstart': case 'contextmenu': event.preventDefault(); break; case 'keydown': this._handleCancel(event); break; case 'pointerdown': this._handlePointerDown(event); break; case 'pointermove': this._handlePointerMove(event); break; case 'lostpointercapture': this._handlePointerEnd(event); break; } } _handlePointerDown(event) { if (event.button || this._shouldSkip(event)) { return; } this._setInitialState(event); this._createGhostElement(); const parameters = { event, state: this._stateParameters }; if (this._options.start?.call(this._host, parameters) === false) { this.dispose(); return; } this._setResizeState(); } _handlePointerMove(event) { if (!this._hasPointerCapture) { return; } this._updateState(event); const parameters = { event, state: this._stateParameters }; this._options.resize?.call(this._host, parameters); this._state.current = parameters.state.current; this._updatePosition(this._isDeferred ? this._ghost : this._resizeTarget); } _handlePointerEnd(event) { const parameters = { event, state: this._stateParameters }; this._options.end?.call(this._host, parameters); this._state.current = parameters.state.current; parameters.state.commit?.() ?? this._updatePosition(this._resizeTarget); this.dispose(); } _handleCancel(event) { const key = event.key.toLowerCase(); if (this._hasPointerCapture && key === 'escape') { this._options.cancel?.call(this._host, this._stateParameters); } } _shouldSkip(event) { this._setActiveRef(event); return !this._activeRef; } _setActiveRef(event) { const refs = this._options.ref?.map(({ value }) => value) ?? [this._host]; this._activeRef = findElementFromEventPath((e) => refs.includes(e), event) ?? null; } _setResizeState(enabled = true) { this._hasPointerCapture = enabled; enabled ? this._element.setPointerCapture(this._id) : this._element.releasePointerCapture(this._id); this._setResizeCancelListener(enabled); for (const type of additionalEvents) { enabled ? this._host.addEventListener(type, this) : this._host.removeEventListener(type, this); } } _setResizeCancelListener(enabled = true) { enabled ? globalThis.addEventListener('keydown', this) : globalThis.removeEventListener('keydown', this); } _setInitialState({ pointerId }) { const dimensions = this._resizeTarget.getBoundingClientRect(); this._id = pointerId; this._state = { initial: dimensions, current: structuredClone(dimensions), }; } _updateState({ clientX, clientY }) { this._state.current.width = clientX - this._state.initial.x; this._state.current.height = clientY - this._state.initial.y; } _updatePosition(element) { if (element) { Object.assign(element.style, { width: `${this._state.current.width}px`, height: `${this._state.current.height}px`, }); } } _createGhostElement() { if (!this._isDeferred) { return; } this._ghost = this._options.deferredFactory?.call(this._host) ?? createDefaultGhostElement(this._resizeTarget.getBoundingClientRect()); this._ghost.setAttribute('data-resize-ghost', ''); this._layer.append(this._ghost); } _removeGhostElement() { this._ghost?.remove(); this._ghost = null; } } export function addResizeController(host, options) { return new ResizeController(host, options); } //# sourceMappingURL=resize-controller.js.map