Your IP : 18.117.72.244


Current Path : /var/www/www-root/data/www/www.monolith-realty.ru/bitrix/js/ui/bottomsheet/src/
Upload File :
Current File : /var/www/www-root/data/www/www.monolith-realty.ru/bitrix/js/ui/bottomsheet/src/bottomsheet.js

import { Type, Tag, Dom, Loc } from 'main.core';
import TouchDragListener from './touchdraglistener';

import 'ui.design-tokens';
import './style.css';

export default class BottomSheet
{
	constructor({
		content,
		help,
		className,
		padding
	})
	{
		this.content = Type.isDomNode(content) ? content : null;
		this.className = Type.isString(className) ? className : '';
		this.padding = Type.isString(padding) || Type.isNumber(padding) ? padding : null;

		this.help = null;
		switch (true)
		{
			case Type.isString(help):
				this.help = help;
				break;
			case Type.isFunction(help):
				this.help = help;
				break;
		}

		this.layout = {
			wrapper: null,
			container: null,
			content: null,
			overlay: null,
			close: null,
			help: null
		};

		this.halfOfHeight = 0;
		this.currentHeight = null;

		this.sheetListener = new TouchDragListener({
			element: this.#getPanel(),
			touchStartCallback: ({element, active, initialY, currentY, yOffset}) => {
				element.style.setProperty('--translateY', 'translateY(0)');
				element.style.setProperty('transition', 'unset');
			},
			touchEndCallback: ({element, active, initialY, currentY, yOffset}) => {
				element.style.setProperty(
					'transition',
					'transform .3s'
				);
				element.style.setProperty(
					'--translateY',
					'translateY(' + currentY + 'px)'
				);

				if (parseInt(currentY) > this.halfOfHeight)
				{
					this.close();
				}
			},
			touchMoveCallback: ({element, active, initialY, currentY, yOffset}) => {
				
				if (currentY <= 0)
				{
					return;
				}

				if (currentY <= -40)
				{
					currentY = -41 + currentY / 10;
				}

				element.style.setProperty(
					'--translateY',
					'translateY(' + currentY + 'px)'
				);
			}
		});

		if (this.content)
		{
			this.setContent(this.content);
		}
	}

	#getOverlay()
	{
		if (!this.layout.overlay)
		{
			this.layout.overlay = Tag.render`
				<div class="ui-bottomsheet__overlay"></div>
			`;

			this.layout.overlay.addEventListener('click', this.close.bind(this));
		}

		return this.layout.overlay;
	}

	#getHelp()
	{
		if (!this.layout.help)
		{
			if (Type.isString(this.help))
			{
				this.layout.help = Tag.render`
					<a href="${this.help}" class="ui-bottomsheet__panel-control--item --cursor-pointer">
						<span class="ui-bottomsheet__panel-control--item-text">${Loc.getMessage('UI_BOTTOMSHEET_HELP')}</span>
					</a>
				`;
			}

			if (Type.isFunction(this.help))
			{
				this.layout.help = Tag.render`
					<div class="ui-bottomsheet__panel-control--item --cursor-pointer">
						<div class="ui-bottomsheet__panel-control--item-text">${Loc.getMessage('UI_BOTTOMSHEET_HELP')}</div>
					</div>
				`;

				this.layout.help.addEventListener('click', ()=> {
					this.help();
				});
			}
		}

		return this.layout.help;
	}

	#getClose()
	{
		if (!this.layout.close)
		{
			this.layout.close = Tag.render`
				<div class="ui-bottomsheet__panel-control--item --cursor-pointer --close">
					<div class="ui-bottomsheet__panel-control--item-text">${Loc.getMessage('UI_BOTTOMSHEET_CLOSE')}</div>
				</div>
			`;

			this.layout.close.addEventListener('click', this.close.bind(this));
		}

		return this.layout.close;
	}

	#getPanel()
	{
		if (!this.layout.container)
		{
			const panelWrapper = Tag.render`
				<div class="ui-bottomsheet__panel-wrapper">
					${this.#getContent()}
				</div>
			`;

			if (this.padding || this.padding === 0)
			{
				let padding;

				switch(true)
				{
					case Type.isString(this.padding):
						padding = this.padding;
						break;

					case Type.isNumber(this.padding):
						padding = this.padding + 'px';
						break;
				}

				panelWrapper.style.setProperty(
					'padding',
					padding
				);
			}

			this.layout.container = Tag.render`
				<div class="ui-bottomsheet__panel">
					<div class="ui-bottomsheet__panel-control">
						${this.help ? this.#getHelp() : ''}
						<div class="ui-bottomsheet__panel-handler"></div>
						${this.#getClose()}
					</div>
					${panelWrapper}
				</div>
			`;
		}

		return this.layout.container;
	}

	#getContent()
	{
		if (!this.layout.content)
		{
			this.layout.content = Tag.render`
				<div class="ui-bottomsheet__panel-content"></div>
			`;
		}

		return this.layout.content;
	}

	#getWrapper()
	{
		if (!this.layout.wrapper)
		{
			this.layout.wrapper = Tag.render`
				<div class="ui-bottomsheet ${this.className}"></div>
			`;
		}

		return this.layout.wrapper;
	}
	
	setContent(content: HTMLElement)
	{
		if (Type.isDomNode(content))
		{
			Dom.clean(this.#getContent());
			this.#getContent().appendChild(content);
		}

		if (Type.isString(content))
		{
			Dom.clean(this.#getContent());
			this.#getContent().innerText = content;
		}
	}

	adjustPosition()
	{

	}

	adjustSize()
	{
		if (this.currentHeight !== this.#getPanel().offsetHeight)
		{
			let currentHeight = this.currentHeight;
			let newHeight = this.#getPanel().offsetHeight;
			this.#getPanel().style.setProperty(
				'height',
				currentHeight + 'px'
			);

			setTimeout(()=> {
				currentHeight = this.#getPanel().offsetHeight;
				this.#getPanel().style.setProperty(
					'height',
					newHeight + 'px'
				);

				const adjustHeight = ()=> {
					this.#getPanel().style.removeProperty(
						'height',
						newHeight + 'px'
					);
					this.#getPanel().removeEventListener('transitionend', adjustHeight)
				};

				this.#getPanel().addEventListener('transitionend', adjustHeight);

				this.currentHeight = newHeight;
				this.halfOfHeight = this.currentHeight / 2;
			});
		}
	}

	close()
	{
		if (this.#getWrapper().parentNode)
		{
			this.#getPanel().classList.remove('--show');
			this.#getOverlay().classList.remove('--show');

			const animationProgress = () => {
				this.#getWrapper().classList.remove('--show');
				this.#getPanel().removeEventListener('transitionend', animationProgress);
			}

			this.#getPanel().addEventListener('transitionend', animationProgress)
		}
	}

	show()
	{
		if (!this.#getWrapper().parentNode)
		{
			this.#getWrapper().appendChild(this.#getOverlay());
			this.#getWrapper().appendChild(this.#getPanel());
			document.body.appendChild(this.#getWrapper());
		}

		this.#getWrapper().classList.add('--show');

		setTimeout(()=> {
			this.currentHeight = this.#getPanel().offsetHeight;
			this.halfOfHeight = this.currentHeight / 2;
			this.#getPanel().classList.add('--show');
			this.#getOverlay().classList.add('--show');
		});
	}
}