@shoelace-style/shoelace
Version:
A forward-thinking library of web components.
153 lines (148 loc) • 4.27 kB
JavaScript
import {
image_comparer_styles_default
} from "./chunk.RCGFCKTU.js";
import {
drag
} from "./chunk.ESELY2US.js";
import {
clamp
} from "./chunk.HF7GESMZ.js";
import {
LocalizeController
} from "./chunk.WLV3FVBR.js";
import {
SlIcon
} from "./chunk.E6QAPUBK.js";
import {
watch
} from "./chunk.CCJUT23E.js";
import {
component_styles_default
} from "./chunk.TUVJKY7S.js";
import {
ShoelaceElement
} from "./chunk.UYAO2JRR.js";
import {
__decorateClass
} from "./chunk.B3BW2AY6.js";
// src/components/image-comparer/image-comparer.component.ts
import { classMap } from "lit/directives/class-map.js";
import { html } from "lit";
import { property, query } from "lit/decorators.js";
import { styleMap } from "lit/directives/style-map.js";
var SlImageComparer = class extends ShoelaceElement {
constructor() {
super(...arguments);
this.localize = new LocalizeController(this);
this.position = 50;
}
handleDrag(event) {
const { width } = this.base.getBoundingClientRect();
const isRtl = this.localize.dir() === "rtl";
event.preventDefault();
drag(this.base, {
onMove: (x) => {
this.position = parseFloat(clamp(x / width * 100, 0, 100).toFixed(2));
if (isRtl)
this.position = 100 - this.position;
},
initialEvent: event
});
}
handleKeyDown(event) {
const isLtr = this.localize.dir() === "ltr";
const isRtl = this.localize.dir() === "rtl";
if (["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) {
const incr = event.shiftKey ? 10 : 1;
let newPosition = this.position;
event.preventDefault();
if (isLtr && event.key === "ArrowLeft" || isRtl && event.key === "ArrowRight") {
newPosition -= incr;
}
if (isLtr && event.key === "ArrowRight" || isRtl && event.key === "ArrowLeft") {
newPosition += incr;
}
if (event.key === "Home") {
newPosition = 0;
}
if (event.key === "End") {
newPosition = 100;
}
newPosition = clamp(newPosition, 0, 100);
this.position = newPosition;
}
}
handlePositionChange() {
this.emit("sl-change");
}
render() {
const isRtl = this.localize.dir() === "rtl";
return html`
<div
part="base"
id="image-comparer"
class=${classMap({
"image-comparer": true,
"image-comparer--rtl": isRtl
})}
@keydown=${this.handleKeyDown}
>
<div class="image-comparer__image">
<div part="before" class="image-comparer__before">
<slot name="before"></slot>
</div>
<div
part="after"
class="image-comparer__after"
style=${styleMap({
clipPath: isRtl ? `inset(0 0 0 ${100 - this.position}%)` : `inset(0 ${100 - this.position}% 0 0)`
})}
>
<slot name="after"></slot>
</div>
</div>
<div
part="divider"
class="image-comparer__divider"
style=${styleMap({
left: isRtl ? `${100 - this.position}%` : `${this.position}%`
})}
@mousedown=${this.handleDrag}
@touchstart=${this.handleDrag}
>
<div
part="handle"
class="image-comparer__handle"
role="scrollbar"
aria-valuenow=${this.position}
aria-valuemin="0"
aria-valuemax="100"
aria-controls="image-comparer"
tabindex="0"
>
<slot name="handle">
<sl-icon library="system" name="grip-vertical"></sl-icon>
</slot>
</div>
</div>
</div>
`;
}
};
SlImageComparer.styles = [component_styles_default, image_comparer_styles_default];
SlImageComparer.scopedElement = { "sl-icon": SlIcon };
__decorateClass([
query(".image-comparer")
], SlImageComparer.prototype, "base", 2);
__decorateClass([
query(".image-comparer__handle")
], SlImageComparer.prototype, "handle", 2);
__decorateClass([
property({ type: Number, reflect: true })
], SlImageComparer.prototype, "position", 2);
__decorateClass([
watch("position", { waitUntilFirstUpdate: true })
], SlImageComparer.prototype, "handlePositionChange", 1);
export {
SlImageComparer
};