adwaveui
Version:
Interactive Web Components inspired by the Gtk Adwaita theme.
160 lines (158 loc) • 6.03 kB
JavaScript
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
// src/components/slider/slider.tsx
import { jsx as _jsx, jsxs as _jsxs } from "@ncpa0cpl/vanilla-jsx/jsx-runtime";
import "../../base-elements.mjs";
import { sig } from "@ncpa0cpl/vanilla-jsx/signals";
import { Slider } from "adwavecss";
import { customElement } from "wc_toolkit";
import { CustomKeyboardEvent, CustomPointerEvent } from "../../utils/events.mjs";
import { isLmb } from "../../utils/is-lmb.mjs";
import { changeWithStep, clamp, toPrecision } from "../../utils/math.mjs";
import { stopEvent } from "../../utils/prevent-default.mjs";
var preventDefault = /* @__PURE__ */ __name((e) => {
e.preventDefault();
return false;
}, "preventDefault");
var AdwSliderChangeEvent = class extends Event {
static {
__name(this, "AdwSliderChangeEvent");
}
constructor(type, value) {
super("change", {
bubbles: true
});
this.value = value;
}
};
var { CustomElement } = customElement("adw-slider").attributes({
value: "number",
defaultValue: "number",
min: "number",
max: "number",
/*
* Determines by how much the value will be incremented or
* decremented when the user interacts with the slider.
*
* @default 1
*/
step: "number",
/**
* The number of decimal places to round the value to.
*
* @default 4
*/
precision: "number",
disabled: "boolean",
name: "string",
form: "string"
}).events({
"pointerdown": CustomPointerEvent,
"change": AdwSliderChangeEvent,
"keydown": CustomKeyboardEvent
}).context(({ value, min, max }) => {
const positions = sig.derive(value.signal, min.signal, max.signal, (value2 = 0, min2 = 0, max2 = 100) => {
const percent = (value2 - min2) / (max2 - min2) * 100;
return {
progressRight: `${100 - percent}%`,
thumbLeft: `calc(${percent}% - 0.3em)`
};
});
return {
isPressed: sig(false),
positions
};
}).methods((wc) => {
const { attribute: { min, max, value, disabled, precision, step }, context } = wc;
value.onChange((v) => {
v = v ?? 0;
const maxV = max.get() ?? 100;
const minV = min.get() ?? 0;
if (v > maxV) {
value.set(maxV);
} else if (v < minV) {
value.set(minV);
}
});
const handlePointerEventUp = /* @__PURE__ */ __name((event) => {
event.stopPropagation();
context.isPressed.dispatch(false);
}, "handlePointerEventUp");
const handlePointerEventMove = /* @__PURE__ */ __name((event) => {
event.stopPropagation();
if (disabled.get())
return;
if (context.isPressed.get()) {
const minV = min.get() ?? 0;
const maxV = max.get() ?? 100;
const { left, width } = wc.thisElement.getBoundingClientRect();
const percent = (event.clientX - left) / width;
const tmpValue = changeWithStep(value.get() ?? 0, toPrecision(minV + percent * (maxV - minV), precision.get() ?? 4), step.get() ?? 1);
methods.setValue(tmpValue);
}
}, "handlePointerEventMove");
const setValue = /* @__PURE__ */ __name((v) => {
value.set(v);
wc.emitEvent("change", value.get() ?? 0);
}, "setValue");
const methods = {
setValue(newValue) {
newValue = clamp(newValue, min.get() ?? 0, max.get() ?? 100);
if (newValue === value.get())
return;
setValue(newValue);
},
focus() {
wc.thisElement.querySelector(`.${Slider.slider}`)?.focus();
},
_handlePointerDown(event) {
event.stopPropagation();
wc.emitEvent("pointerdown", {}, event).onCommit(() => {
if (isLmb(event)) {
context.isPressed.dispatch(true);
handlePointerEventMove(event);
}
});
},
_handleKeyDown(event) {
if (disabled.get())
return;
switch (event.key) {
case "ArrowLeft":
event.stopPropagation();
wc.emitEvent("keydown", {}, event).onCommit(() => {
this.setValue((value.get() ?? 0) - (step.get() ?? 1));
});
break;
case "ArrowRight":
event.stopPropagation();
wc.emitEvent("keydown", {}, event).onCommit(() => {
this.setValue((value.get() ?? 0) + (step.get() ?? 1));
});
break;
}
},
_handlePointerEventUp: handlePointerEventUp,
_handlePointerEventMove: handlePointerEventMove
};
return methods;
}).connected((wc) => {
const { method, attribute: { disabled, min, max, value, form, step, name, defaultValue } } = wc;
if (value.get() == null && defaultValue.get() != null) {
method.setValue(defaultValue.get());
}
wc.listenWindow("pointerup", method._handlePointerEventUp);
wc.listenWindow("pointermove", method._handlePointerEventMove);
wc.attach(_jsxs("div", { draggable: false, class: {
[Slider.slider]: true,
[Slider.disabled]: disabled.signal
}, onpointerdown: method._handlePointerDown, onpointermove: preventDefault, ondrag: preventDefault, onkeydown: method._handleKeyDown, tabIndex: 0, role: "slider", "aria-valuemin": min.signal, "aria-valuemax": max.signal, "aria-valuenow": value.signal, "aria-disabled": disabled, children: [_jsx("div", { draggable: false, class: Slider.track, onpointermove: preventDefault, ondrag: preventDefault }), _jsx("div", { draggable: false, class: Slider.progress, onpointermove: preventDefault, ondrag: preventDefault, style: {
right: wc.context.positions.derive((p) => p.progressRight)
} }), _jsx("div", { draggable: false, class: Slider.thumb, onpointermove: preventDefault, ondrag: preventDefault, style: {
left: wc.context.positions.derive((p) => p.thumbLeft)
} }), _jsx("input", { type: "range", class: "_adw_hidden", disabled: disabled.signal, name: name.signal, "attribute:form": form.signal, min: min.signal.derive(String), max: max.signal.derive(String), step: step.signal.derive(String), value: value.signal, onchange: stopEvent, "aria-hidden": "true" })] }));
}).register();
var AdwSlider = CustomElement;
export {
AdwSlider
};