ranui
Version:
A framework-agnostic Web Components UI library built on native custom elements, with TypeScript types, light/dark theming, SSR and PWA support.
168 lines (167 loc) • 11 kB
JavaScript
import { T as u, _ as p, i as e, m as l, n as g } from "./factory-WDxu11V0.js";
import { t as m } from "./events-Cqz3ramM.js";
import "./builder-EH76YCFS.js";
import { a as h, i as f, n as v, o as _, t as w } from "./utils-U-9uH7EX.js";
import { a as y, n as x } from "./ssr-BzykYefm.js";
import { t as k } from "./disclosure-row-B6EePiK9.js";
import "./state-dot-DnPwHJNT.js";
import { diffLines as C } from "ranuts/utils";
var A = ":host{display:block;min-width:0;color:var(--ran-tool-card-color, var(--ran-color-text));font-size:var(--ran-tool-card-font-size, var(--ran-text-copy-2))}:host([hidden]){display:none}.ran-tool-card-body{display:flex;flex-direction:column;gap:var(--ran-tool-card-body-gap, var(--ran-space-2));padding:var(--ran-tool-card-body-padding, var(--ran-space-2) 0 var(--ran-space-2) var(--ran-space-6))}.ran-tool-card-io{display:flex;flex-direction:column;border:1px solid var(--ran-tool-card-io-border-color, var(--ran-color-border));border-radius:var(--ran-tool-card-io-radius, var(--ran-radius-md));background:var(--ran-tool-card-io-background, var(--ran-color-bg-muted));min-width:0}.ran-tool-card-io-section{display:grid;grid-template-columns:max-content 1fr;column-gap:var(--ran-tool-card-io-gutter-gap, var(--ran-space-3));align-items:baseline;padding:var(--ran-tool-card-io-padding, var(--ran-space-3));max-height:var(--ran-tool-card-io-max-height, 9.5rem);overflow:auto;overscroll-behavior:contain}.ran-tool-card-io-section+.ran-tool-card-io-section{border-top:1px solid var(--ran-tool-card-io-border-color, var(--ran-color-border))}.ran-tool-card-io-label{position:sticky;top:0;color:var(--ran-tool-card-io-label-color, var(--ran-color-text-disabled));font-size:var(--ran-tool-card-io-label-size, var(--ran-text-label-3));font-family:var(--ran-tool-card-output-font, var(--ran-font-mono));-webkit-user-select:none;user-select:none}.ran-tool-card-io-text{min-width:0;font-weight:var(--ran-tool-card-output-weight, var(--ran-text-mono-weight-regular));font-family:var(--ran-tool-card-output-font, var(--ran-font-mono));white-space:pre-wrap;overflow-wrap:anywhere}.ran-tool-card-io-text[data-error]{color:var(--ran-tool-card-io-error-color, var(--ran-color-danger))}.ran-tool-card-output{margin:0;max-height:var(--ran-tool-card-output-max-height, 18rem);overflow:auto;overscroll-behavior:contain;border-radius:var(--ran-tool-card-output-radius, var(--ran-radius-sm));background:var(--ran-tool-card-output-background, var(--ran-color-bg-muted));padding:var(--ran-tool-card-output-padding, var(--ran-space-2));font-weight:var(--ran-tool-card-output-weight, var(--ran-text-mono-weight-regular));font-family:var(--ran-tool-card-output-font, var(--ran-font-mono));white-space:pre}.ran-tool-card-output-wrap{white-space:pre-wrap;overflow-wrap:anywhere}.ran-tool-card-file+.ran-tool-card-file{margin-top:var(--ran-tool-card-file-gap, var(--ran-space-3))}.ran-tool-card-path{margin-bottom:var(--ran-tool-card-path-gap, var(--ran-space-1));color:var(--ran-tool-card-path-color, var(--ran-color-text-secondary));font-family:var(--ran-tool-card-output-font, var(--ran-font-mono))}.ran-tool-card-hunk{overflow-x:auto;border-radius:var(--ran-tool-card-output-radius, var(--ran-radius-sm));background:var(--ran-tool-card-output-background, var(--ran-color-bg-muted));font-family:var(--ran-tool-card-output-font, var(--ran-font-mono));white-space:pre}.ran-tool-card-hunk+.ran-tool-card-hunk{margin-top:var(--ran-tool-card-hunk-gap, var(--ran-space-2))}.ran-tool-card-line{display:flex;gap:var(--ran-tool-card-line-gap, var(--ran-space-2));padding:0 var(--ran-tool-card-line-padding, var(--ran-space-2))}.ran-tool-card-line[data-kind=added]{background:var(--ran-tool-card-added-background, var(--ran-green-200))}.ran-tool-card-line[data-kind=removed]{background:var(--ran-tool-card-removed-background, var(--ran-red-200))}.ran-tool-card-gutter{flex:none;min-width:var(--ran-tool-card-gutter-width, var(--ran-size-4));color:var(--ran-tool-card-gutter-color, var(--ran-color-text-disabled));text-align:right;-webkit-user-select:none;user-select:none}.ran-tool-card-locations{display:flex;flex-wrap:wrap;gap:var(--ran-tool-card-locations-gap, var(--ran-space-2));margin-top:var(--ran-tool-card-locations-margin, var(--ran-space-3))}.ran-tool-card-location{border:none;background:none;padding:0;color:var(--ran-tool-card-location-color, var(--ran-color-link));font:inherit;font-family:var(--ran-tool-card-output-font, var(--ran-font-mono));cursor:pointer}", S = /* @__PURE__ */ new Set([
"generic",
"terminal",
"diff"
]);
function E(r) {
const t = r?.card;
return typeof t == "string" && S.has(t) ? t : "generic";
}
function T(r) {
if (r === null) return "";
if (typeof r.summary == "string") return r.summary;
if (r.card === "terminal") return r.description ?? r.cwd ?? "";
if (r.card === "diff") return Array.isArray(r.diffs) ? r.diffs.map((o) => o.path).join(" · ") : "";
const t = r.card === "generic" ? r.input : void 0, a = typeof t == "object" && t !== null ? Object.values(t)[0] : void 0;
return typeof a == "string" ? a : "";
}
var D = {
running: "running",
success: "success",
error: "error"
}, L = class extends x {
_events = new m();
_shadowDom;
_row;
_dot;
_body;
_call = null;
_result = null;
static get observedAttributes() {
return [
"status",
"open",
"sheet"
];
}
constructor() {
super(), this._shadowDom = w(this, A);
const r = u(), t = u(), a = p("r-disclosure-row").attr("part", "row").children(p("r-state-dot").ref(r).attr("slot", "leading").build(), e().class("ran-tool-card-body").ref(t).attr("part", "body").build()).build();
this._shadowDom.appendChild(a), this._row = a, this._dot = h(r, "state dot"), this._body = h(t, "body");
}
get call() {
return this._call;
}
set call(r) {
this._call = r, this._render();
}
get result() {
return this._result;
}
set result(r) {
this._result = r, this._render();
}
get status() {
const r = v(this, "status", "running");
return r === "success" || r === "error" ? r : "running";
}
set status(r) {
f(this, "status", r);
}
get open() {
return this.hasAttribute("open");
}
set open(r) {
r ? this.setAttribute("open", "") : this.removeAttribute("open");
}
get sheet() {
return v(this, "sheet");
}
set sheet(r) {
f(this, "sheet", r);
}
connectedCallback() {
this.handlerExternalCss(), this._events.on(this._row, k, (r) => {
this.open = r.detail.open;
}), this._render();
}
disconnectedCallback() {
this._events.abort();
}
attributeChangedCallback(r, t, a) {
t !== a && (r === "sheet" ? this.handlerExternalCss() : this._render());
}
handlerExternalCss = () => {
_(this, this._shadowDom, "sheet", null, this.sheet);
};
_render() {
const r = this._call, t = this.status;
this._row.heading = r !== null && "title" in r ? r.title : "", this._row.summary = T(r), this._row.open = this.open, this._row.tone = t === "error" ? "error" : "", this._row.busy = t === "running", this._dot.state = D[t], this._body.replaceChildren();
const a = E(this._result ?? r);
a === "terminal" ? this._renderTerminal() : a === "diff" ? this._renderDiff() : this._renderGeneric();
const o = r !== null && "locations" in r ? r.locations : void 0;
Array.isArray(o) && o.length > 0 && this._body.appendChild(this._renderLocations(o)), this._row.expandable = this._body.childNodes.length > 0;
}
_ioCard(r, t, a) {
if (r === null && t === null) return null;
const o = e().class("ran-tool-card-io").attr("part", "io").build(), n = (i, s, b) => {
const d = e().class("ran-tool-card-io-section").build(), c = l().class("ran-tool-card-io-text").attr("part", "io-text").text(s).build();
return b && (c.dataset.error = ""), d.append(l().class("ran-tool-card-io-label").attr("aria-hidden", "true").text(i).build(), c), d;
};
return r !== null && o.appendChild(n("IN", r, !1)), t !== null && o.appendChild(n("OUT", t, a)), o;
}
_renderGeneric() {
const r = this._call, t = this._result, a = r !== null && r.card === "generic" && r.input !== void 0 ? Object.entries(r.input).map(([i, s]) => `${i}: ${s}`).join(`
`) : null, o = t !== null && t.card === "generic" && t.content !== void 0 ? t.content : null, n = this._ioCard(a, o === "" ? null : o, this.status === "error");
n !== null && this._body.appendChild(n);
}
_renderTerminal() {
const r = this._call, t = this._result, a = r !== null && r.card === "terminal" ? r.cwd === void 0 ? null : `cwd: ${r.cwd}` : null;
if (t === null || t.card !== "terminal") {
const n = this._ioCard(a, null, !1);
n !== null && this._body.appendChild(n);
return;
}
const o = this._ioCard(a, null, !1);
o !== null && this._body.appendChild(o), this._body.appendChild(this._pre(t.output, "preserve")), t.exitCode !== void 0 && t.exitCode !== 0 && this._body.appendChild(e().class("ran-tool-card-description").attr("part", "exit").text(`exit ${t.exitCode}`).build());
}
_renderDiff() {
const r = this._result ?? this._call, t = r !== null && r.card === "diff" ? r.diffs : void 0;
if (Array.isArray(t))
for (const a of t) this._body.appendChild(this._renderFile(a));
}
_renderFile(r) {
const t = e().class("ran-tool-card-file").attr("part", "file").build();
t.appendChild(e().class("ran-tool-card-path").attr("part", "path").text(r.path).build());
for (const a of C(r.oldText ?? "", r.newText)) t.appendChild(this._renderHunk(a));
return t;
}
_renderHunk(r) {
const t = e().class("ran-tool-card-hunk").attr("part", "hunk").build();
for (const a of r.lines) {
const o = e().class("ran-tool-card-line").attr("part", "line").build();
o.dataset.kind = a.kind, o.append(l().class("ran-tool-card-gutter").text(a.oldLine === null ? "" : String(a.oldLine)).build(), l().class("ran-tool-card-gutter").text(a.newLine === null ? "" : String(a.newLine)).build(), l().text(`${a.kind === "added" ? "+" : a.kind === "removed" ? "-" : " "}${a.text}`).build()), t.appendChild(o);
}
return t;
}
_renderLocations(r) {
const t = e().class("ran-tool-card-locations").attr("part", "locations").build();
for (const a of r) {
const o = a.line === void 0 ? a.path : `${a.path}:${a.line}`, n = g().class("ran-tool-card-location").attr("part", "location").attr("type", "button").text(o).build();
this._events.on(n, "click", () => {
this.dispatchEvent(new CustomEvent("locationclick", {
detail: { location: a },
bubbles: !0,
composed: !0
}));
}), t.appendChild(n);
}
return t;
}
_pre(r, t) {
const a = document.createElement("pre");
return a.className = t === "wrap" ? "ran-tool-card-output ran-tool-card-output-wrap" : "ran-tool-card-output", a.setAttribute("part", "output"), a.textContent = r, a;
}
};
y("r-tool-card", L);
export {
L as t
};