Files
mixtape/zero.Backoffice.UI/app/directives/v-resizeable.ts
T
2021-12-06 16:18:58 +01:00

138 lines
3.0 KiB
TypeScript

// object (new) that handles resizing of an element
const Resizable = function (element, params)
{
const prefix = 'zero.ui-resizable.';
const cacheKey = prefix + (params.save || 'none');
const resizingClass = 'ui-resizing';
let isVertical = ['Y', 'y'].indexOf(params.axis) > -1;
this.element = element;
this.params = params;
this.handle = this.element.querySelector(this.params.handle || '.handle');
if (!this.handle)
{
throw 'Set the [handle] parameter to a valid CSS selector within the attached element';
}
// binds events to the handle so the resizing works
this.listen = () =>
{
this.handle.addEventListener('mousedown', this.start);
this.handle.addEventListener('dblclick', this.reset);
};
// detaches the resizable
this.detach = () =>
{
this.handle.removeEventListener('mousedown', this.start);
this.handle.removeEventListener('dblclick', this.reset);
document.removeEventListener('mousemove', this.resize);
document.removeEventListener('mouseup', this.stop);
};
// start resizing of an element
this.start = (e) =>
{
this.coordinates = {
X: e.pageX,
Y: e.pageY,
offsetX: 0,
offsetY: 0
};
document.body.classList.add(resizingClass);
document.addEventListener('mousemove', this.resize);
document.addEventListener('mouseup', this.stop);
};
// resize the element
this.resize = (e) =>
{
let deltaX = e.pageX - this.coordinates.X;
let deltaY = e.pageY - this.coordinates.Y;
let delta = isVertical ? deltaY : deltaX;
let newValue = this.value + delta;
if (params.min && params.min > newValue)
{
newValue = params.min;
}
else if (params.max && params.max < newValue)
{
newValue = params.max;
}
this.update(newValue);
};
// stop resizing and unbind listeners
this.stop = (e) =>
{
document.body.classList.remove(resizingClass);
document.removeEventListener('mousemove', this.resize);
document.removeEventListener('mouseup', this.stop);
this.value = getCurrentValue();
localStorage.setItem(cacheKey, this.value);
};
// updates dimension of the target element
this.update = value =>
{
if (value > 0)
{
this.element.style[isVertical ? 'height' : 'width'] = value + 'px';
}
};
// resets to the original value
this.reset = () =>
{
localStorage.removeItem(cacheKey);
this.element.style[isVertical ? 'height' : 'width'] = '';
this.value = getCurrentValue();
};
// get current size value from element
let getCurrentValue = () =>
{
return this.element[isVertical ? 'clientHeight' : 'clientWidth'];
};
this.value = getCurrentValue();
// use cached value on load
if (params.save)
{
const newValue = +localStorage.getItem(cacheKey);
if (newValue > 0)
{
this.update(+localStorage.getItem(cacheKey));
this.value = newValue;
}
}
};
/**
* resize an element
*/
export default {
bind(el, binding)
{
let resizable = new Resizable(el, binding.value);
resizable.listen();
}
};