UNPKG

ranui

Version:

A framework-agnostic Web Components UI library built on native custom elements, with TypeScript types, light/dark theming, SSR and PWA support.

176 lines (175 loc) 8.31 kB
import { T as h, i as a, n as f, p } from "./factory-WDxu11V0.js"; import { t as _ } from "./events-Cqz3ramM.js"; import "./builder-EH76YCFS.js"; import { a as u, i as l, n as d, o as b, t as m } from "./utils-U-9uH7EX.js"; import { a as w, n as g } from "./ssr-BzykYefm.js"; import { createBottomFollower as y } from "ranuts/utils"; import { createConversationEngine as x } from "ranuts/conversation"; var E = ":host{display:flex;flex-direction:column;min-height:0;color:var(--ran-conversation-color, var(--ran-color-text));font-size:var(--ran-conversation-font-size, var(--ran-text-copy-2))}:host([hidden]){display:none}.ran-conversation{display:flex;flex:1;flex-direction:column;min-height:0;overflow-y:auto;overscroll-behavior:contain;background:var(--ran-conversation-background, var(--ran-color-bg));overflow-anchor:none}.ran-conversation-list{display:flex;flex-direction:column;box-sizing:border-box;gap:var(--ran-conversation-gap, var(--ran-space-4));margin:0 auto;padding:var(--ran-conversation-padding, var(--ran-space-4));width:100%;max-width:var(--ran-conversation-measure, 46rem)}.ran-conversation-row{display:block;min-width:0;content-visibility:auto;contain-intrinsic-size:auto 8rem}.ran-conversation-older{display:flex;box-sizing:border-box;justify-content:center;margin:0 auto;padding:var(--ran-conversation-padding, var(--ran-space-4)) var(--ran-conversation-padding, var(--ran-space-4)) 0;width:100%;max-width:var(--ran-conversation-measure, 46rem)}.ran-conversation-older[hidden]{display:none}.ran-conversation-older button{border:1px solid var(--ran-conversation-older-border-color, var(--ran-color-border));border-radius:var(--ran-conversation-older-radius, var(--ran-radius-full));background:none;padding:var(--ran-conversation-older-padding, var(--ran-space-1) var(--ran-space-3));color:var(--ran-conversation-older-color, var(--ran-color-text-secondary));font:inherit;font-size:var(--ran-conversation-older-font-size, var(--ran-text-label-3));cursor:pointer}.ran-conversation-older button:hover:not(:disabled){border-color:var(--ran-conversation-older-hover-border-color, var(--ran-color-border-hover));color:var(--ran-conversation-older-hover-color, var(--ran-color-text))}.ran-conversation-older button:disabled{cursor:default;opacity:.6}.ran-conversation-older button:focus-visible{outline:2px solid var(--ran-conversation-focus-color, var(--ran-color-primary));outline-offset:2px}.ran-conversation-footer{flex:none;background:var(--ran-conversation-footer-background, var(--ran-color-bg))}.ran-conversation-empty{padding:var(--ran-conversation-empty-padding, var(--ran-space-8));color:var(--ran-conversation-empty-color, var(--ran-color-text-secondary));text-align:center}", k = "olderrequest", C = class extends g { _events = new _(); _shadowDom; _scroll; _list; _older; _olderButton; _footer; _views = []; _engine = null; _unsubscribe = null; _follower = null; _rows = /* @__PURE__ */ new Map(); _emptyRow = null; static get observedAttributes() { return [ "follow", "empty", "older", "loading-older", "sheet" ]; } constructor() { super(), this._shadowDom = m(this, E); const e = h(), t = h(), n = h(); this._scroll = a().class("ran-conversation").attr("part", "conversation").children(a().class("ran-conversation-older").ref(t).attr("part", "older").children(f().ref(n).attr("type", "button").build()).build(), a().class("ran-conversation-list").ref(e).attr("part", "list").build()).build(), this._shadowDom.appendChild(this._scroll), this._footer = a().class("ran-conversation-footer").attr("part", "footer").children(p().attr("name", "footer").build()).build(), this._shadowDom.appendChild(this._footer), this._list = u(e, "list"), this._older = u(t, "older"), this._olderButton = u(n, "older button"), this._older.hidden = !0; } get older() { return d(this, "older"); } set older(e) { l(this, "older", e); } get loadingOlder() { return this.hasAttribute("loading-older"); } set loadingOlder(e) { e ? this.setAttribute("loading-older", "") : this.removeAttribute("loading-older"); } get follow() { return d(this, "follow", "true") !== "false"; } set follow(e) { l(this, "follow", e ? "true" : "false"); } get empty() { return d(this, "empty"); } set empty(e) { l(this, "empty", e); } get sheet() { return d(this, "sheet"); } set sheet(e) { l(this, "sheet", e); } get pinned() { return this._follower?.pinned ?? !0; } register(e) { if (this._engine !== null) throw new Error(`r-conversation: register("${e.kind}") after the first push — register every view first`); this._views.push(e); } push(e) { this._ensureEngine().push(e); } truncate(e) { return this._engine?.truncate(e) ?? 0; } batch(e) { this._ensureEngine().batch(e); } reset() { this._engine?.reset(); } scrollToBottom() { this._follower?.toBottom(); } captureAnchor(e) { const t = e === void 0 ? this._list.firstElementChild : this._rows.get(e); return !(t instanceof HTMLElement) || this._follower === null ? !1 : (this._follower.captureAnchor(t), !0); } restoreAnchor() { return this._follower?.restoreAnchor() ?? !1; } connectedCallback() { this.handlerExternalCss(), this._syncEmpty(), this._syncOlder(), this._events.on(this._olderButton, "click", this._requestOlder), this._follower = y({ scrollport: this._scroll, observe: [this._list, this._footer], onPinnedChange: (e) => { this.dispatchEvent(new CustomEvent("pinnedchange", { detail: { pinned: e }, bubbles: !0, composed: !0 })); } }), this.follow || this._follower.releaseAnchor(); } disconnectedCallback() { this._events.abort(), this._unsubscribe?.(), this._unsubscribe = null, this._follower?.destroy(), this._follower = null, this._engine?.destroy(), this._engine = null; } attributeChangedCallback(e, t, n) { t !== n && (e === "sheet" && this.handlerExternalCss(), e === "empty" && this._syncEmpty(), (e === "older" || e === "loading-older") && this._syncOlder()); } handlerExternalCss = () => { b(this, this._shadowDom, "sheet", null, this.sheet); }; _ensureEngine() { if (this._engine !== null) return this._engine; const e = x({ definitions: this._views }); return this._unsubscribe = e.subscribe((t, n) => { this._renderNodes(t, n); }), this._engine = e, e; } _viewFor(e) { return this._views.find((t) => t.kind === e); } _renderNodes(e, t) { const n = /* @__PURE__ */ new Set(); for (const r of e) { const o = this._viewFor(r.kind); if (o?.mount === void 0) continue; n.add(r.key); let i = this._rows.get(r.key), v = !1; if (i === void 0) { const s = o.mount(r); if (s === null) continue; s.classList.add("ran-conversation-row"), s.setAttribute("part", "row"), s.dataset.kind = r.kind, s.dataset.key = r.key, this._rows.set(r.key, s), i = s, v = !0; } (v || t === void 0 || t.has(r.key)) && o.patch?.(i, r); } for (const [r, o] of this._rows) n.has(r) || (o.remove(), this._rows.delete(r)); let c = null; for (const r of e) { const o = this._rows.get(r.key); if (o === void 0) continue; const i = c === null ? this._list.firstChild : c.nextSibling; i !== o && this._list.insertBefore(o, i), c = o; } this._syncEmpty(), this.follow && this._follower?.follow(); } _requestOlder = () => { this.loadingOlder || (this.captureAnchor(), this.dispatchEvent(new CustomEvent(k, { bubbles: !0, composed: !0 }))); }; _syncOlder() { const e = this.older; this._older.hidden = e === "", this._olderButton.textContent = e, this._olderButton.disabled = this.loadingOlder; } _syncEmpty() { const e = this.empty; if (!(this._rows.size === 0 && e !== "")) { this._emptyRow?.remove(), this._emptyRow = null; return; } this._emptyRow ??= a().class("ran-conversation-empty").attr("part", "empty").build(), this._emptyRow.textContent = e, this._emptyRow.parentNode === null && this._list.appendChild(this._emptyRow); } }; w("r-conversation", C); export { k as n, C as t };