230 lines
6.7 KiB
JavaScript
230 lines
6.7 KiB
JavaScript
|
import {
|
||
|
split_panel_styles_default
|
||
|
} from "./chunk.IDFVJOTW.js";
|
||
|
import {
|
||
|
drag
|
||
|
} from "./chunk.ESELY2US.js";
|
||
|
import {
|
||
|
clamp
|
||
|
} from "./chunk.HF7GESMZ.js";
|
||
|
import {
|
||
|
LocalizeController
|
||
|
} from "./chunk.NH3SRVOC.js";
|
||
|
import {
|
||
|
o
|
||
|
} from "./chunk.2URMUHDY.js";
|
||
|
import {
|
||
|
watch
|
||
|
} from "./chunk.FA5RT4K4.js";
|
||
|
import {
|
||
|
ShoelaceElement,
|
||
|
e,
|
||
|
n
|
||
|
} from "./chunk.SEXBCYCU.js";
|
||
|
import {
|
||
|
x
|
||
|
} from "./chunk.CXZZ2LVK.js";
|
||
|
import {
|
||
|
__decorateClass
|
||
|
} from "./chunk.KIILAQWQ.js";
|
||
|
|
||
|
// src/components/split-panel/split-panel.component.ts
|
||
|
var SlSplitPanel = class extends ShoelaceElement {
|
||
|
constructor() {
|
||
|
super(...arguments);
|
||
|
this.localize = new LocalizeController(this);
|
||
|
this.position = 50;
|
||
|
this.vertical = false;
|
||
|
this.disabled = false;
|
||
|
this.snapThreshold = 12;
|
||
|
}
|
||
|
connectedCallback() {
|
||
|
super.connectedCallback();
|
||
|
this.resizeObserver = new ResizeObserver((entries) => this.handleResize(entries));
|
||
|
this.updateComplete.then(() => this.resizeObserver.observe(this));
|
||
|
this.detectSize();
|
||
|
this.cachedPositionInPixels = this.percentageToPixels(this.position);
|
||
|
}
|
||
|
disconnectedCallback() {
|
||
|
super.disconnectedCallback();
|
||
|
this.resizeObserver.unobserve(this);
|
||
|
}
|
||
|
detectSize() {
|
||
|
const { width, height } = this.getBoundingClientRect();
|
||
|
this.size = this.vertical ? height : width;
|
||
|
}
|
||
|
percentageToPixels(value) {
|
||
|
return this.size * (value / 100);
|
||
|
}
|
||
|
pixelsToPercentage(value) {
|
||
|
return value / this.size * 100;
|
||
|
}
|
||
|
handleDrag(event) {
|
||
|
const isRtl = this.localize.dir() === "rtl";
|
||
|
if (this.disabled) {
|
||
|
return;
|
||
|
}
|
||
|
if (event.cancelable) {
|
||
|
event.preventDefault();
|
||
|
}
|
||
|
drag(this, {
|
||
|
onMove: (x2, y) => {
|
||
|
let newPositionInPixels = this.vertical ? y : x2;
|
||
|
if (this.primary === "end") {
|
||
|
newPositionInPixels = this.size - newPositionInPixels;
|
||
|
}
|
||
|
if (this.snap) {
|
||
|
const snaps = this.snap.split(" ");
|
||
|
snaps.forEach((value) => {
|
||
|
let snapPoint;
|
||
|
if (value.endsWith("%")) {
|
||
|
snapPoint = this.size * (parseFloat(value) / 100);
|
||
|
} else {
|
||
|
snapPoint = parseFloat(value);
|
||
|
}
|
||
|
if (isRtl && !this.vertical) {
|
||
|
snapPoint = this.size - snapPoint;
|
||
|
}
|
||
|
if (newPositionInPixels >= snapPoint - this.snapThreshold && newPositionInPixels <= snapPoint + this.snapThreshold) {
|
||
|
newPositionInPixels = snapPoint;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
this.position = clamp(this.pixelsToPercentage(newPositionInPixels), 0, 100);
|
||
|
},
|
||
|
initialEvent: event
|
||
|
});
|
||
|
}
|
||
|
handleKeyDown(event) {
|
||
|
if (this.disabled) {
|
||
|
return;
|
||
|
}
|
||
|
if (["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End"].includes(event.key)) {
|
||
|
let newPosition = this.position;
|
||
|
const incr = (event.shiftKey ? 10 : 1) * (this.primary === "end" ? -1 : 1);
|
||
|
event.preventDefault();
|
||
|
if (event.key === "ArrowLeft" && !this.vertical || event.key === "ArrowUp" && this.vertical) {
|
||
|
newPosition -= incr;
|
||
|
}
|
||
|
if (event.key === "ArrowRight" && !this.vertical || event.key === "ArrowDown" && this.vertical) {
|
||
|
newPosition += incr;
|
||
|
}
|
||
|
if (event.key === "Home") {
|
||
|
newPosition = this.primary === "end" ? 100 : 0;
|
||
|
}
|
||
|
if (event.key === "End") {
|
||
|
newPosition = this.primary === "end" ? 0 : 100;
|
||
|
}
|
||
|
this.position = clamp(newPosition, 0, 100);
|
||
|
}
|
||
|
}
|
||
|
handleResize(entries) {
|
||
|
const { width, height } = entries[0].contentRect;
|
||
|
this.size = this.vertical ? height : width;
|
||
|
if (this.primary) {
|
||
|
this.position = this.pixelsToPercentage(this.cachedPositionInPixels);
|
||
|
}
|
||
|
}
|
||
|
handlePositionChange() {
|
||
|
this.cachedPositionInPixels = this.percentageToPixels(this.position);
|
||
|
this.positionInPixels = this.percentageToPixels(this.position);
|
||
|
this.emit("sl-reposition");
|
||
|
}
|
||
|
handlePositionInPixelsChange() {
|
||
|
this.position = this.pixelsToPercentage(this.positionInPixels);
|
||
|
}
|
||
|
handleVerticalChange() {
|
||
|
this.detectSize();
|
||
|
}
|
||
|
render() {
|
||
|
const gridTemplate = this.vertical ? "gridTemplateRows" : "gridTemplateColumns";
|
||
|
const gridTemplateAlt = this.vertical ? "gridTemplateColumns" : "gridTemplateRows";
|
||
|
const isRtl = this.localize.dir() === "rtl";
|
||
|
const primary = `
|
||
|
clamp(
|
||
|
0%,
|
||
|
clamp(
|
||
|
var(--min),
|
||
|
${this.position}% - var(--divider-width) / 2,
|
||
|
var(--max)
|
||
|
),
|
||
|
calc(100% - var(--divider-width))
|
||
|
)
|
||
|
`;
|
||
|
const secondary = "auto";
|
||
|
if (this.primary === "end") {
|
||
|
if (isRtl && !this.vertical) {
|
||
|
this.style[gridTemplate] = `${primary} var(--divider-width) ${secondary}`;
|
||
|
} else {
|
||
|
this.style[gridTemplate] = `${secondary} var(--divider-width) ${primary}`;
|
||
|
}
|
||
|
} else {
|
||
|
if (isRtl && !this.vertical) {
|
||
|
this.style[gridTemplate] = `${secondary} var(--divider-width) ${primary}`;
|
||
|
} else {
|
||
|
this.style[gridTemplate] = `${primary} var(--divider-width) ${secondary}`;
|
||
|
}
|
||
|
}
|
||
|
this.style[gridTemplateAlt] = "";
|
||
|
return x`
|
||
|
<slot name="start" part="panel start" class="start"></slot>
|
||
|
|
||
|
<div
|
||
|
part="divider"
|
||
|
class="divider"
|
||
|
tabindex=${o(this.disabled ? void 0 : "0")}
|
||
|
role="separator"
|
||
|
aria-valuenow=${this.position}
|
||
|
aria-valuemin="0"
|
||
|
aria-valuemax="100"
|
||
|
aria-label=${this.localize.term("resize")}
|
||
|
@keydown=${this.handleKeyDown}
|
||
|
@mousedown=${this.handleDrag}
|
||
|
@touchstart=${this.handleDrag}
|
||
|
>
|
||
|
<slot name="divider"></slot>
|
||
|
</div>
|
||
|
|
||
|
<slot name="end" part="panel end" class="end"></slot>
|
||
|
`;
|
||
|
}
|
||
|
};
|
||
|
SlSplitPanel.styles = split_panel_styles_default;
|
||
|
__decorateClass([
|
||
|
e(".divider")
|
||
|
], SlSplitPanel.prototype, "divider", 2);
|
||
|
__decorateClass([
|
||
|
n({ type: Number, reflect: true })
|
||
|
], SlSplitPanel.prototype, "position", 2);
|
||
|
__decorateClass([
|
||
|
n({ attribute: "position-in-pixels", type: Number })
|
||
|
], SlSplitPanel.prototype, "positionInPixels", 2);
|
||
|
__decorateClass([
|
||
|
n({ type: Boolean, reflect: true })
|
||
|
], SlSplitPanel.prototype, "vertical", 2);
|
||
|
__decorateClass([
|
||
|
n({ type: Boolean, reflect: true })
|
||
|
], SlSplitPanel.prototype, "disabled", 2);
|
||
|
__decorateClass([
|
||
|
n()
|
||
|
], SlSplitPanel.prototype, "primary", 2);
|
||
|
__decorateClass([
|
||
|
n()
|
||
|
], SlSplitPanel.prototype, "snap", 2);
|
||
|
__decorateClass([
|
||
|
n({ type: Number, attribute: "snap-threshold" })
|
||
|
], SlSplitPanel.prototype, "snapThreshold", 2);
|
||
|
__decorateClass([
|
||
|
watch("position")
|
||
|
], SlSplitPanel.prototype, "handlePositionChange", 1);
|
||
|
__decorateClass([
|
||
|
watch("positionInPixels")
|
||
|
], SlSplitPanel.prototype, "handlePositionInPixelsChange", 1);
|
||
|
__decorateClass([
|
||
|
watch("vertical")
|
||
|
], SlSplitPanel.prototype, "handleVerticalChange", 1);
|
||
|
|
||
|
export {
|
||
|
SlSplitPanel
|
||
|
};
|