import { Component, ComponentChildren, ContextType, createContext, } from "preact"; import round from "lodash/round"; type CtxProps = { min: number; max: number; striped: boolean; animated: boolean; precision: number; }; const PCtx = createContext(null); type BarProps = { value: number; striped?: boolean; animated?: boolean; class?: string; label?: string; set_label?: ( per: number, value: number, max: number, min: number, ) => string; precision?: number; }; class ProgressBar extends Component { static contextType = PCtx; declare context: ContextType; render() { let cls = "progress-bar"; const striped = this.props.striped === undefined ? this.context?.striped : this.props.striped; const animated = this.props.animated === undefined ? this.context?.animated : this.props.animated; const precision = (this.props.precision === undefined ? this.context?.precision : this.props.precision) || 2; if (striped || animated) cls += " progress-bar-striped"; if (animated) cls += " progress-bar-animated"; if (this.props.class) cls += " " + this.props.class; const max = this.context?.max || 100; const min = this.context?.min || 0; const v = this.props.value; const per = (v - min) / (max - min) * 100; const style = `width: ${per}%;`; let label = this.props.label; if (this.props.set_label) { label = this.props.set_label(round(per, precision), v, max, min); } return (
{label}
); } } type Props = { /**@default {0} */ min?: number; /**@default {100} */ max?: number; /**@default {false} */ striped?: boolean; /**@default {false} */ animated?: boolean; children: ComponentChildren; /**@default {2} */ precision?: number; }; export default class Progress extends Component { static readonly Bar = ProgressBar; render() { return (
{this.props.children}
); } }