UNPKG

@stimulus-library/controllers

Version:

A library of useful controllers for Stimulus

85 lines (84 loc) 2.49 kB
import { formatDuration } from "date-fns/formatDuration"; import { intervalToDuration } from "date-fns/intervalToDuration"; import { toDate } from "date-fns/toDate"; import { BaseController } from "@stimulus-library/utilities"; import { useInterval } from "@stimulus-library/mixins"; export class DurationController extends BaseController { get _format() { const keys = [ "years", "months", "weeks", "days", "hours", ]; if (this._minutes) { keys.push("minutes"); } if (this._seconds) { keys.push("seconds"); } return keys; } get _output() { let { years, months, weeks, days, hours, minutes, seconds } = this._duration; years || (years = 0); months || (months = 0); weeks || (weeks = 0); days || (days = 0); hours || (hours = 0); minutes || (minutes = 0); seconds || (seconds = 0); const largeDenominators = [years, months, weeks, days, hours]; if (!this._minutes && !this._seconds && largeDenominators.every((x) => x === 0)) { minutes = minutes + seconds / 60.0; return `${(minutes / 60).toFixed(1)} hours`; } return formatDuration(this._duration, { format: this._format, delimiter: ", " }); } get _seconds() { return this.hasSecondsValue ? this.secondsValue : true; } get _minutes() { return this.hasMinutesValue ? this.minutesValue : true; } get _timestamp() { if (this.hasTimestampValue) { return toDate(this.timestampValue * 1000); } else { throw new Error("Expected `timestampValue` to be present"); } } get _duration() { return intervalToDuration({ start: new Date(), end: this._timestamp }); } get _tickInterval() { if (this._seconds) { return 1000; } else if (this._minutes) { return 15000; } else { return 120000; } } connect() { this._clearInterval = useInterval(this, this._update, this._tickInterval); this._update(); } _update() { try { this.el.innerHTML = this._output; } catch { this._clearInterval(); } } } DurationController.values = { timestamp: Number, minutes: Boolean, seconds: Boolean, };