UNPKG

@primer/react

Version:

An implementation of GitHub's Primer Design System using React

463 lines (458 loc) • 19 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var duration = require('./duration.js'); var __classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var _RelativeTimeElement_instances, _RelativeTimeElement_customTitle, _RelativeTimeElement_updating, _RelativeTimeElement_lang_get, _RelativeTimeElement_renderRoot, _RelativeTimeElement_getFormattedTitle, _RelativeTimeElement_resolveFormat, _RelativeTimeElement_getDurationFormat, _RelativeTimeElement_getRelativeFormat, _RelativeTimeElement_getDateTimeFormat, _RelativeTimeElement_onRelativeTimeUpdated; const HTMLElement = globalThis.HTMLElement || null; const emptyDuration = new duration.Duration(); const microEmptyDuration = new duration.Duration(0, 0, 0, 0, 0, 1); class RelativeTimeUpdatedEvent extends Event { constructor(oldText, newText, oldTitle, newTitle) { super('relative-time-updated', { bubbles: true, composed: true }); this.oldText = oldText; this.newText = newText; this.oldTitle = oldTitle; this.newTitle = newTitle; } } function getUnitFactor(el) { if (!el.date) return Infinity; if (el.format === 'duration' || el.format === 'elapsed') { const precision = el.precision; if (precision === 'second') { return 1000; } else if (precision === 'minute') { return 60 * 1000; } } const ms = Math.abs(Date.now() - el.date.getTime()); if (ms < 60 * 1000) return 1000; if (ms < 60 * 60 * 1000) return 60 * 1000; return 60 * 60 * 1000; } const dateObserver = new (class { constructor() { this.elements = new Set(); this.time = Infinity; this.timer = -1; } observe(element) { if (this.elements.has(element)) return; this.elements.add(element); const date = element.date; if (date && date.getTime()) { const ms = getUnitFactor(element); const time = Date.now() + ms; if (time < this.time) { clearTimeout(this.timer); this.timer = setTimeout(() => this.update(), ms); this.time = time; } } } unobserve(element) { if (!this.elements.has(element)) return; this.elements.delete(element); } update() { clearTimeout(this.timer); if (!this.elements.size) return; let nearestDistance = Infinity; for (const timeEl of this.elements) { nearestDistance = Math.min(nearestDistance, getUnitFactor(timeEl)); timeEl.update(); } this.time = Math.min(60 * 60 * 1000, nearestDistance); this.timer = setTimeout(() => this.update(), this.time); this.time += Date.now(); } })(); class RelativeTimeElement extends HTMLElement { constructor() { super(...arguments); _RelativeTimeElement_instances.add(this); _RelativeTimeElement_customTitle.set(this, false); _RelativeTimeElement_updating.set(this, false); _RelativeTimeElement_renderRoot.set(this, this.shadowRoot ? this.shadowRoot : this.attachShadow ? this.attachShadow({ mode: 'open' }) : this); _RelativeTimeElement_onRelativeTimeUpdated.set(this, null); } static define(tag = 'relative-time', registry = customElements) { registry.define(tag, this); return this; } static get observedAttributes() { return [ 'second', 'minute', 'hour', 'weekday', 'day', 'month', 'year', 'time-zone-name', 'prefix', 'threshold', 'tense', 'precision', 'format', 'format-style', 'no-title', 'datetime', 'lang', 'title', ]; } get onRelativeTimeUpdated() { return __classPrivateFieldGet(this, _RelativeTimeElement_onRelativeTimeUpdated, "f"); } set onRelativeTimeUpdated(listener) { if (__classPrivateFieldGet(this, _RelativeTimeElement_onRelativeTimeUpdated, "f")) { this.removeEventListener('relative-time-updated', __classPrivateFieldGet(this, _RelativeTimeElement_onRelativeTimeUpdated, "f")); } __classPrivateFieldSet(this, _RelativeTimeElement_onRelativeTimeUpdated, typeof listener === 'object' || typeof listener === 'function' ? listener : null, "f"); if (typeof listener === 'function') { this.addEventListener('relative-time-updated', listener); } } get second() { const second = this.getAttribute('second'); if (second === 'numeric' || second === '2-digit') return second; } set second(value) { this.setAttribute('second', value || ''); } get minute() { const minute = this.getAttribute('minute'); if (minute === 'numeric' || minute === '2-digit') return minute; } set minute(value) { this.setAttribute('minute', value || ''); } get hour() { const hour = this.getAttribute('hour'); if (hour === 'numeric' || hour === '2-digit') return hour; } set hour(value) { this.setAttribute('hour', value || ''); } get weekday() { const weekday = this.getAttribute('weekday'); if (weekday === 'long' || weekday === 'short' || weekday === 'narrow') { return weekday; } if (this.format === 'datetime' && weekday !== '') return this.formatStyle; } set weekday(value) { this.setAttribute('weekday', value || ''); } get day() { var _a; const day = (_a = this.getAttribute('day')) !== null && _a !== void 0 ? _a : 'numeric'; if (day === 'numeric' || day === '2-digit') return day; } set day(value) { this.setAttribute('day', value || ''); } get month() { const format = this.format; let month = this.getAttribute('month'); if (month === '') return; month !== null && month !== void 0 ? month : (month = format === 'datetime' ? this.formatStyle : 'short'); if (month === 'numeric' || month === '2-digit' || month === 'short' || month === 'long' || month === 'narrow') { return month; } } set month(value) { this.setAttribute('month', value || ''); } get year() { var _a; const year = this.getAttribute('year'); if (year === 'numeric' || year === '2-digit') return year; if (!this.hasAttribute('year') && new Date().getUTCFullYear() !== ((_a = this.date) === null || _a === void 0 ? void 0 : _a.getUTCFullYear())) { return 'numeric'; } } set year(value) { this.setAttribute('year', value || ''); } get timeZoneName() { const name = this.getAttribute('time-zone-name'); if (name === 'long' || name === 'short' || name === 'shortOffset' || name === 'longOffset' || name === 'shortGeneric' || name === 'longGeneric') { return name; } } set timeZoneName(value) { this.setAttribute('time-zone-name', value || ''); } get prefix() { var _a; return (_a = this.getAttribute('prefix')) !== null && _a !== void 0 ? _a : (this.format === 'datetime' ? '' : 'on'); } set prefix(value) { this.setAttribute('prefix', value); } get threshold() { const threshold = this.getAttribute('threshold'); return threshold && duration.isDuration(threshold) ? threshold : 'P30D'; } set threshold(value) { this.setAttribute('threshold', value); } get tense() { const tense = this.getAttribute('tense'); if (tense === 'past') return 'past'; if (tense === 'future') return 'future'; return 'auto'; } set tense(value) { this.setAttribute('tense', value); } get precision() { const precision = this.getAttribute('precision'); if (duration.unitNames.includes(precision)) return precision; if (this.format === 'micro') return 'minute'; return 'second'; } set precision(value) { this.setAttribute('precision', value); } get format() { const format = this.getAttribute('format'); if (format === 'datetime') return 'datetime'; if (format === 'relative') return 'relative'; if (format === 'duration') return 'duration'; if (format === 'micro') return 'micro'; if (format === 'elapsed') return 'elapsed'; return 'auto'; } set format(value) { this.setAttribute('format', value); } get formatStyle() { const formatStyle = this.getAttribute('format-style'); if (formatStyle === 'long') return 'long'; if (formatStyle === 'short') return 'short'; if (formatStyle === 'narrow') return 'narrow'; const format = this.format; if (format === 'elapsed' || format === 'micro') return 'narrow'; if (format === 'datetime') return 'short'; return 'long'; } set formatStyle(value) { this.setAttribute('format-style', value); } get noTitle() { return this.hasAttribute('no-title'); } set noTitle(value) { this.toggleAttribute('no-title', value); } get datetime() { return this.getAttribute('datetime') || ''; } set datetime(value) { this.setAttribute('datetime', value); } get date() { const parsed = Date.parse(this.datetime); return Number.isNaN(parsed) ? null : new Date(parsed); } set date(value) { this.datetime = (value === null || value === void 0 ? void 0 : value.toISOString()) || ''; } connectedCallback() { this.update(); } disconnectedCallback() { dateObserver.unobserve(this); } attributeChangedCallback(attrName, oldValue, newValue) { if (oldValue === newValue) return; if (attrName === 'title') { __classPrivateFieldSet(this, _RelativeTimeElement_customTitle, newValue !== null && (this.date && __classPrivateFieldGet(this, _RelativeTimeElement_instances, "m", _RelativeTimeElement_getFormattedTitle).call(this, this.date)) !== newValue, "f"); } if (!__classPrivateFieldGet(this, _RelativeTimeElement_updating, "f") && !(attrName === 'title' && __classPrivateFieldGet(this, _RelativeTimeElement_customTitle, "f"))) { __classPrivateFieldSet(this, _RelativeTimeElement_updating, (async () => { await Promise.resolve(); this.update(); __classPrivateFieldSet(this, _RelativeTimeElement_updating, false, "f"); })(), "f"); } } update() { const oldText = __classPrivateFieldGet(this, _RelativeTimeElement_renderRoot, "f").textContent || this.textContent || ''; const oldTitle = this.getAttribute('title') || ''; let newTitle = oldTitle; const date = this.date; if (typeof Intl === 'undefined' || !Intl.DateTimeFormat || !date) { __classPrivateFieldGet(this, _RelativeTimeElement_renderRoot, "f").textContent = oldText; return; } const now = Date.now(); if (!__classPrivateFieldGet(this, _RelativeTimeElement_customTitle, "f")) { newTitle = __classPrivateFieldGet(this, _RelativeTimeElement_instances, "m", _RelativeTimeElement_getFormattedTitle).call(this, date) || ''; if (newTitle && !this.noTitle) this.setAttribute('title', newTitle); } const duration$1 = duration.elapsedTime(date, this.precision, now); const format = __classPrivateFieldGet(this, _RelativeTimeElement_instances, "m", _RelativeTimeElement_resolveFormat).call(this, duration$1); let newText = oldText; if (format === 'duration') { newText = __classPrivateFieldGet(this, _RelativeTimeElement_instances, "m", _RelativeTimeElement_getDurationFormat).call(this, duration$1); } else if (format === 'relative') { newText = __classPrivateFieldGet(this, _RelativeTimeElement_instances, "m", _RelativeTimeElement_getRelativeFormat).call(this, duration$1); } else { newText = __classPrivateFieldGet(this, _RelativeTimeElement_instances, "m", _RelativeTimeElement_getDateTimeFormat).call(this, date); } if (newText) { __classPrivateFieldGet(this, _RelativeTimeElement_renderRoot, "f").textContent = newText; } else if (this.shadowRoot === __classPrivateFieldGet(this, _RelativeTimeElement_renderRoot, "f") && this.textContent) { __classPrivateFieldGet(this, _RelativeTimeElement_renderRoot, "f").textContent = this.textContent; } if (newText !== oldText || newTitle !== oldTitle) { this.dispatchEvent(new RelativeTimeUpdatedEvent(oldText, newText, oldTitle, newTitle)); } if (format === 'relative' || format === 'duration') { dateObserver.observe(this); } else { dateObserver.unobserve(this); } } } _RelativeTimeElement_customTitle = new WeakMap(), _RelativeTimeElement_updating = new WeakMap(), _RelativeTimeElement_renderRoot = new WeakMap(), _RelativeTimeElement_onRelativeTimeUpdated = new WeakMap(), _RelativeTimeElement_instances = new WeakSet(), _RelativeTimeElement_lang_get = function _RelativeTimeElement_lang_get() { var _a; const lang = ((_a = this.closest('[lang]')) === null || _a === void 0 ? void 0 : _a.getAttribute('lang')) || this.ownerDocument.documentElement.getAttribute('lang'); try { return new Intl.Locale(lang !== null && lang !== void 0 ? lang : '').toString(); } catch (_b) { return 'default'; } }, _RelativeTimeElement_getFormattedTitle = function _RelativeTimeElement_getFormattedTitle(date) { return new Intl.DateTimeFormat(__classPrivateFieldGet(this, _RelativeTimeElement_instances, "a", _RelativeTimeElement_lang_get), { day: 'numeric', month: 'short', year: 'numeric', hour: 'numeric', minute: '2-digit', timeZoneName: 'short', }).format(date); }, _RelativeTimeElement_resolveFormat = function _RelativeTimeElement_resolveFormat(duration$1) { const format = this.format; if (format === 'datetime') return 'datetime'; if (format === 'duration') return 'duration'; if (format === 'elapsed') return 'duration'; if (format === 'micro') return 'duration'; if ((format === 'auto' || format === 'relative') && typeof Intl !== 'undefined' && Intl.RelativeTimeFormat) { const tense = this.tense; if (tense === 'past' || tense === 'future') return 'relative'; if (duration.Duration.compare(duration$1, this.threshold) === 1) return 'relative'; } return 'datetime'; }, _RelativeTimeElement_getDurationFormat = function _RelativeTimeElement_getDurationFormat(duration$1) { const locale = __classPrivateFieldGet(this, _RelativeTimeElement_instances, "a", _RelativeTimeElement_lang_get); const format = this.format; const style = this.formatStyle; const tense = this.tense; let empty = emptyDuration; if (format === 'micro') { duration$1 = duration.roundToSingleUnit(duration$1); empty = microEmptyDuration; if ((this.tense === 'past' && duration$1.sign !== -1) || (this.tense === 'future' && duration$1.sign !== 1)) { duration$1 = microEmptyDuration; } } else if ((tense === 'past' && duration$1.sign !== -1) || (tense === 'future' && duration$1.sign !== 1)) { duration$1 = empty; } const display = `${this.precision}sDisplay`; if (duration$1.blank) { return empty.toLocaleString(locale, { style, [display]: 'always' }); } return duration$1.abs().toLocaleString(locale, { style }); }, _RelativeTimeElement_getRelativeFormat = function _RelativeTimeElement_getRelativeFormat(duration$1) { const relativeFormat = new Intl.RelativeTimeFormat(__classPrivateFieldGet(this, _RelativeTimeElement_instances, "a", _RelativeTimeElement_lang_get), { numeric: 'auto', style: this.formatStyle, }); const tense = this.tense; if (tense === 'future' && duration$1.sign !== 1) duration$1 = emptyDuration; if (tense === 'past' && duration$1.sign !== -1) duration$1 = emptyDuration; const [int, unit] = duration.getRelativeTimeUnit(duration$1); if (unit === 'second' && int < 10) { return relativeFormat.format(0, this.precision === 'millisecond' ? 'second' : this.precision); } return relativeFormat.format(int, unit); }, _RelativeTimeElement_getDateTimeFormat = function _RelativeTimeElement_getDateTimeFormat(date) { const formatter = new Intl.DateTimeFormat(__classPrivateFieldGet(this, _RelativeTimeElement_instances, "a", _RelativeTimeElement_lang_get), { second: this.second, minute: this.minute, hour: this.hour, weekday: this.weekday, day: this.day, month: this.month, year: this.year, timeZoneName: this.timeZoneName, }); return `${this.prefix} ${formatter.format(date)}`.trim(); }; exports.RelativeTimeElement = RelativeTimeElement; exports.RelativeTimeUpdatedEvent = RelativeTimeUpdatedEvent; exports.default = RelativeTimeElement;