melt
Version:
The next generation of Melt UI. Built for Svelte 5.
58 lines (57 loc) • 1.82 kB
JavaScript
import { Synced } from "../Synced.svelte";
import { styleAttr } from "../utils/attribute";
import { extract } from "../utils/extract";
import { createDataIds } from "../utils/identifiers";
const dataIds = createDataIds("progress", ["root", "progress"]);
export class Progress {
// Props
#props;
max = $derived(extract(this.#props.max, 100));
// States
#value;
constructor(props = {}) {
this.#props = props;
this.#value = new Synced({
value: props.value,
onChange: props.onValueChange,
defaultValue: 0,
});
}
get value() {
return this.#value.current;
}
set value(value) {
this.#value.current = value;
}
/**
* Spread attributes for the Progress root element.
*/
get root() {
return {
[dataIds.root]: "",
value: this.#value.current,
max: this.max,
role: "progressbar",
"aria-valuemin": 0,
"aria-valuemax": this.max,
"aria-valuenow": this.#value.current,
"data-value": this.#value.current,
"data-state": this.#value.current === this.max ? "complete" : "loading",
"data-max": this.max,
};
}
/**
* Spread attributes for the Progress percentage element.
* Provides a --progress CSS variable that can be used to style the progress:
* `transform: translateX(calc(var(--progress) * -1));`
*/
get progress() {
return {
[dataIds.progress]: "",
style: styleAttr({
"--progress": `${100 - (100 * (this.#value.current ?? 0)) / (this.max ?? 1)}%`,
"--neg-progress": `-${100 - (100 * (this.#value.current ?? 0)) / (this.max ?? 1)}%`,
}),
};
}
}