@progress/kendo-react-layout
Version:
React Layout components enable you to create a perceptive and intuitive layout of web projects. KendoReact Layout package
238 lines (237 loc) • 10.9 kB
JavaScript
/**
* @license
*-------------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the package root for more information
*-------------------------------------------------------------------------------------------
*/
import * as d from "react";
import a from "prop-types";
import { getScrollbarWidth as f, canUseDOM as y, classNames as m, Draggable as x } from "@progress/kendo-react-common";
import { ResizeHandlers as E } from "./ResizeHandlers.mjs";
const g = 200, p = class p extends d.Component {
constructor() {
super(...arguments), this.state = {
rtl: !1,
visibleHint: !1
}, this.oldSize = {}, this.draggable = null, this.dragging = !1, this.resizing = !1, this.element = null, this.hintElement = null, this.ignoreDrag = !1, this.pressOffset = { x: 0, y: 0 }, this.pressXY = { x: 0, y: 0 }, this.currentTranslate = { x: 0, y: 0 }, this.preventDataOps = void 0, this.handleResize = (t, e) => {
if (e.end) {
this.handleRelease();
return;
}
if (!this.element || !this.hintElement)
return;
const n = t.clientX, l = t.clientY;
this.resizing = !0;
const r = (e.direction !== "ns" ? n - this.pressXY.x : 0) * (this.state.rtl ? -1 : 1), s = e.direction !== "ew" ? l - this.pressXY.y : 0;
if (this.dragElement && (this.state.rtl ? this.dragElement.style.marginLeft = -r + "px" : this.dragElement.style.marginRight = -r + "px", this.dragElement.style.height = `calc(100% + ${s}px)`), this.hintElement.classList.add("k-layout-item-hint-resize"), this.preventDataOps)
return;
let i = 0, o = 0;
const h = this.element.getBoundingClientRect();
r > h.width / this.props.defaultPosition.colSpan / 3 && (i = 1), r < -h.width / this.props.defaultPosition.colSpan / 1.25 && (i = -1), s > h.height / this.props.defaultPosition.rowSpan / 3 && (o = 1), s < -h.height / this.props.defaultPosition.rowSpan / 1.25 && (o = -1), (i !== 0 || o !== 0) && this.props.update(this.props.index, 0, 0, o, i);
}, this.handlePress = (t) => {
if (!this.dragElement)
return;
if (this.pressXY = {
x: t.event.clientX,
y: t.event.clientY
}, this.ignoreDrag = !1, this.props.ignoreDrag && this.props.ignoreDrag(t.event.originalEvent)) {
this.ignoreDrag = !0;
return;
}
this.element && (this.element.style.zIndex = "10", this.setState({ visibleHint: !0 })), this.dragElement.classList.remove("k-cursor-move"), this.dragElement.classList.add("k-cursor-grabbing");
const e = this.dragElement.getBoundingClientRect();
this.pressOffset = {
x: t.event.clientX - e.x,
y: t.event.clientY - e.y
}, this.props.onPress();
}, this.handleDrag = (t) => {
var i;
if (this.ignoreDrag)
return;
const e = this.dragElement;
if (t.event.originalEvent.defaultPrevented || !e)
return;
this.dragging = !0, t.event.originalEvent.preventDefault();
const n = e.getBoundingClientRect();
if (this.currentTranslate = {
x: t.event.clientX - n.x - this.pressOffset.x + this.currentTranslate.x,
y: t.event.clientY - n.y - this.pressOffset.y + this.currentTranslate.y
}, e.style.transform = `translate(${this.currentTranslate.x}px, ${this.currentTranslate.y}px)`, e.style.transition = "transform 0s", this.preventDataOps)
return;
let l = 0, r = 0;
this.currentTranslate.y > 0.7 * n.height / this.props.defaultPosition.rowSpan && (r = 1), this.currentTranslate.y < 0.7 * -n.height / this.props.defaultPosition.rowSpan && (r = -1), this.currentTranslate.x > 0.7 * n.width / this.props.defaultPosition.colSpan && (l = 1), this.currentTranslate.x < 0.7 * -n.width / this.props.defaultPosition.colSpan && (l = -1), this.props.update(this.props.index, r, this.state.rtl ? -l : l, 0, 0);
const s = (i = this.element) == null ? void 0 : i.closest(".k-tilelayout");
if (s && this.hintElement) {
const o = s.getBoundingClientRect(), h = f() || 50;
t.event.clientX < o.left - h || t.event.clientX > o.right - h || t.event.clientY < o.top || t.event.clientY > o.bottom ? this.hintElement.style.display = "none" : this.hintElement.style.display = "block";
}
}, this.handleRelease = () => {
this.dragging = this.resizing = !1, this.currentTranslate = { x: 0, y: 0 }, this.element && this.hintElement && (this.element.style.zIndex = "1", this.hintElement.classList.remove("k-layout-item-hint-resize"), this.setState({ visibleHint: !1 }));
const t = this.dragElement;
t && (t.style.transform = "translate(0px, 0px)", t.style.transition = `transform ${g}ms cubic-bezier(0.2, 0, 0, 1) 0s`, t.style.marginRight = "0px", t.style.marginLeft = "0px", t.style.height = "100%", t.classList.remove("k-cursor-grabbing"), t.classList.add("k-cursor-move")), this.props.onRelease();
}, this.handleMouseDown = () => {
this.setInitialHintPosition();
}, this.handleMouseUp = () => {
setTimeout(() => {
this.setInitialHintPosition();
}, 100);
}, this.calcNewHintPosition = () => {
if (!this.dragElement || !this.hintElement)
return;
const t = this.dragElement.getBoundingClientRect(), e = t.top + this.currentTranslate.y, n = t.left + this.currentTranslate.x;
this.hintElement.style.top = `${e}px`, this.hintElement.style.left = `${n}px`, this.hintElement.style.display = "block";
};
}
get reorderable() {
return this.props.reorderable !== void 0 ? this.props.reorderable : p.defaultProps.reorderable;
}
get dragElement() {
return this.draggable ? this.draggable.element : void 0;
}
componentDidMount() {
this.element && (getComputedStyle(this.element).direction === "rtl" && this.setState({
rtl: !0
}), this.hintElement && (this.hintElement.style.height = this.element.offsetHeight + "px", this.hintElement.style.width = this.element.offsetWidth + "px"));
}
render() {
y && clearTimeout && typeof clearTimeout == "function" && (clearTimeout(this.preventDataOps), this.preventDataOps = window.setTimeout(() => {
this.preventDataOps = void 0;
}, 200));
const t = this.props.defaultPosition, e = this.props.resizable !== void 0 ? this.props.resizable : p.defaultProps.resizable, n = {
gridColumnStart: t.col,
gridColumnEnd: `span ${t.colSpan}`,
gridRowStart: t.row,
gridRowEnd: `span ${t.rowSpan}`,
outline: "none",
order: t.order,
display: "block",
...this.props.hintStyle
}, l = {
gridColumnStart: t.col,
gridColumnEnd: `span ${t.colSpan}`,
gridRowStart: t.row,
gridRowEnd: `span ${t.rowSpan}`,
order: t.order
}, r = /* @__PURE__ */ d.createElement(
"div",
{
ref: (s) => {
this.draggable = s ? { element: s } : null;
},
role: "listitem",
tabIndex: 0,
"aria-labelledby": typeof this.props.header == "string" ? this.props.header : `tile-${this.props.index}`,
"aria-keyshortcuts": "Enter",
className: m(
"k-tilelayout-item k-card",
{ "k-cursor-move": this.reorderable },
this.props.className
),
style: { height: "100%", ...l, ...this.props.style },
onMouseDown: this.handleMouseDown,
onMouseUp: this.handleMouseUp
},
this.props.children,
/* @__PURE__ */ d.createElement(
E,
{
onPress: this.handlePress,
onResize: this.handleResize,
resizable: e,
rtl: this.state.rtl
}
)
);
return /* @__PURE__ */ d.createElement(d.Fragment, null, this.state.visibleHint && /* @__PURE__ */ d.createElement(
"div",
{
ref: (s) => {
this.hintElement = s;
},
style: { position: "fixed", ...n },
className: m("k-layout-item-hint", this.props.hintClassName)
}
), /* @__PURE__ */ d.createElement(
x,
{
ref: (s) => {
this.draggable = s, this.element = s ? s.element : null;
},
onDrag: this.props.reorderable ? this.handleDrag : void 0,
onRelease: this.props.reorderable ? this.handleRelease : void 0,
onPress: this.props.reorderable ? this.handlePress : void 0
},
r
));
}
/**
* @hidden
*/
getSnapshotBeforeUpdate(t) {
return this.oldSize = {}, this.dragElement && (this.oldSize = this.dragElement.getBoundingClientRect()), null;
}
/**
* @hidden
*/
setInitialHintPosition() {
if (this.element && this.hintElement) {
const t = this.element.getBoundingClientRect();
this.hintElement.style.top = t.top + "px", this.hintElement.style.left = t.left + "px", this.hintElement.style.height = this.element.offsetHeight + "px", this.hintElement.style.width = this.element.offsetWidth + "px";
}
}
/**
* @hidden
*/
componentDidUpdate(t) {
const e = this.dragElement;
if (!e)
return;
const n = e.getBoundingClientRect(), l = this.oldSize;
if (this.resizing) {
const i = n.width - l.width;
if (this.state.rtl) {
const c = parseFloat(e.style.marginLeft || "0");
e.style.marginLeft = c - i + "px";
} else {
const c = parseFloat(e.style.marginRight || "0");
e.style.marginRight = c + i + "px";
}
this.pressXY.x += this.state.rtl ? -i : i;
const o = n.height - l.height, h = parseFloat(e.style.height.substring(12));
e.style.height = `calc(100% + ${h + o}px)`, this.pressXY.y += o;
}
const r = l.left - n.left, s = l.top - n.top;
if (!(r === 0 && s === 0)) {
if (this.dragging) {
(t.defaultPosition.order !== this.props.defaultPosition.order || t.defaultPosition.col !== this.props.defaultPosition.col) && (this.currentTranslate.x = 0, this.currentTranslate.y = 0, e.style.transform = "", this.calcNewHintPosition());
return;
}
Math.abs(s) < 15 && Math.abs(r) < 15 || requestAnimationFrame(() => {
const i = this.element;
i && (i.style.transform = `translate(${r}px, ${s}px)`, i.style.transition = "transform 0s", requestAnimationFrame(() => {
i.style.transform = "", i.style.transition = `transform ${g}ms cubic-bezier(0.2, 0, 0, 1) 0s`;
}));
});
}
}
};
p.propTypes = {
defaultPosition: a.object.isRequired,
style: a.object,
className: a.string,
hintStyle: a.object,
hintClassName: a.string,
header: a.any,
body: a.any,
item: a.any,
resizable: a.oneOf(["horizontal", "vertical", !0, !1]),
reorderable: a.bool
}, p.displayName = "KendoTileLayoutItem", p.defaultProps = {
resizable: !0,
reorderable: !0
};
let u = p;
export {
u as InternalTile
};