${this.PRESETS.map((p) => {
const pct = this.sanitizePercent(p);
const active = (this.selectedPercent ?? percentNow) === pct;
const label = pct === 100 ? this.i18n.max() : `${pct}%`;
return html`
`;
})}
`;
}
private renderSlider(percentNow: number) {
const basis = this.getTotalNumber();
const cap = this.getCapacityLeft();
const hardMax = cap === null ? basis : Math.min(basis, cap);
const dead = !this.isSenderAlive() || !this.isTargetAlive();
// Where to draw the cap marker (as % of Available)
const capPercent =
cap === null
? null
: Math.max(
0,
Math.min(
100,
Math.round((Math.min(cap, basis) / (basis || 1)) * 100),
),
);
const fill = this.getFillColor();
const disabled = basis <= 0 || dead;
const sliderOuterMb = capPercent !== null ? "mb-8" : "mb-2";
return html`
{
if (dead) return;
const raw = Number((e.target as HTMLInputElement).value);
const pctRaw = basis ? Math.round((raw / basis) * 100) : 0;
this.selectedPercent = this.sanitizePercent(pctRaw);
const clamped = Math.min(raw, hardMax);
this.sendAmount = this.clampSend(clamped);
}}
class="w-full appearance-none bg-transparent range-x focus:outline-hidden"
aria-label=${this.i18n.ariaSlider()}
aria-valuemin="0"
aria-valuemax=${hardMax}
aria-valuetext=${this.i18n.sliderTooltip(
percentNow,
this.format(this.sendAmount),
)}
style="--percent:${percentNow}%; --fill:${fill}; --track: rgba(255,255,255,.28); --thumb-ring: rgb(24 24 27);"
/>
${percentNow}% • ${this.format(this.sendAmount)}
${capPercent !== null
? html`
`
: html``}
`;
}
private renderCapacityNote(allowed: number) {
const capped = allowed !== this.sendAmount;
if (!capped) return html``;
return html`
${this.i18n.targetDeadTitle()}
${this.i18n.targetDeadNote()}
`;
}
private renderSliderStyles() {
return html`
`;
}
render() {
if (!this.open) return html``;
const percent = this.percentOfBasis(this.sendAmount);
const allowed = this.limitAmount(this.sendAmount);
return html`