ranui
Version:
A framework-agnostic Web Components UI library built on native custom elements, with TypeScript types, light/dark theming, SSR and PWA support.
140 lines (139 loc) • 7.15 kB
JavaScript
import { _ as c, i as h, m, n as l } from "./factory-WDxu11V0.js";
import { t as d } from "./events-Cqz3ramM.js";
import "./builder-EH76YCFS.js";
import { i, n as o, o as u, t as p } from "./utils-U-9uH7EX.js";
import { a as v, n as b } from "./ssr-BzykYefm.js";
import { formatBytes as f } from "ranuts/utils";
var _ = ":host{display:block}:host([hidden]){display:none}:host(:not([count])) .ran-attachments{display:none}.ran-attachments{display:flex;flex-wrap:wrap;gap:var(--ran-attachments-gap, var(--ran-space-2));padding:var(--ran-attachments-padding, var(--ran-space-2) 0)}.ran-attachment{display:flex;position:relative;align-items:center;gap:var(--ran-attachment-gap, var(--ran-space-2));border:1px solid var(--ran-attachment-border-color, var(--ran-color-border));border-radius:var(--ran-attachment-border-radius, var(--ran-radius-md));background:var(--ran-attachment-background, var(--ran-color-bg-subtle));padding:var(--ran-attachment-padding, var(--ran-space-1) var(--ran-space-2));max-width:var(--ran-attachment-max-width, 220px)}.ran-attachment-thumb{flex:none;border-radius:var(--ran-attachment-thumb-radius, var(--ran-radius-sm));width:var(--ran-attachment-thumb-size, var(--ran-size-6));height:var(--ran-attachment-thumb-size, var(--ran-size-6));object-fit:cover}.ran-attachment-icon{flex:none;color:var(--ran-attachment-icon-color, var(--ran-color-text-secondary))}.ran-attachment-meta{display:flex;flex-direction:column;min-width:0}.ran-attachment-name{overflow:hidden;color:var(--ran-attachment-name-color, var(--ran-color-text));font-size:var(--ran-attachment-name-font-size, var(--ran-text-label-3));white-space:nowrap;text-overflow:ellipsis}.ran-attachment-size{color:var(--ran-attachment-size-color, var(--ran-color-text-secondary));font-size:var(--ran-attachment-size-font-size, var(--ran-text-label-3))}.ran-attachment-remove{display:flex;flex:none;align-items:center;justify-content:center;border:none;border-radius:var(--ran-attachment-remove-radius, var(--ran-radius-full));background:none;padding:0;width:var(--ran-attachment-remove-size, var(--ran-size-3));height:var(--ran-attachment-remove-size, var(--ran-size-3));color:var(--ran-attachment-remove-color, var(--ran-color-text-secondary));cursor:pointer}.ran-attachment-remove:hover{background:var(--ran-attachment-remove-hover-background, var(--ran-color-bg-hover));color:var(--ran-attachment-remove-hover-color, var(--ran-color-text))}.ran-attachment-remove:focus-visible{outline:2px solid var(--ran-attachment-focus-color, var(--ran-color-primary));outline-offset:1px}", g = 10485760, x = 0, w = class extends b {
_events = new d();
_shadowDom;
_list;
_attachments = [];
static get observedAttributes() {
return ["sheet"];
}
constructor() {
super(), this._shadowDom = p(this, _), this._list = h().class("ran-attachments").attr("part", "list").attr("role", "list").build(), this._shadowDom.appendChild(this._list);
}
get attachments() {
return this._attachments;
}
get files() {
return this._attachments.map((t) => t.file);
}
get accept() {
return o(this, "accept");
}
set accept(t) {
i(this, "accept", t);
}
get maxSize() {
const t = Number(o(this, "max-size"));
return Number.isFinite(t) && t > 0 ? t : g;
}
set maxSize(t) {
i(this, "max-size", String(t));
}
get maxCount() {
const t = Number(o(this, "max-count"));
return Number.isFinite(t) && t > 0 ? t : Number.POSITIVE_INFINITY;
}
set maxCount(t) {
i(this, "max-count", String(t));
}
get sheet() {
return o(this, "sheet");
}
set sheet(t) {
i(this, "sheet", t);
}
add(t) {
const e = [];
for (const a of t) {
const r = this._reject(a);
if (r !== null) {
this._emit("attachmentrejected", {
file: a,
reason: r
});
continue;
}
const n = {
id: `attachment-${x += 1}`,
file: a,
name: a.name,
size: a.size,
type: a.type,
previewUrl: a.type.startsWith("image/") ? URL.createObjectURL(a) : null
};
this._attachments.push(n), e.push(n);
}
return e.length > 0 && this._render(), e;
}
detach(t) {
const e = this._attachments.findIndex((r) => r.id === t);
if (e === -1) return !1;
const [a] = this._attachments.splice(e, 1);
return this._release(a), this._render(), !0;
}
clear() {
if (this._attachments.length !== 0) {
for (const t of this._attachments) this._release(t);
this._attachments = [], this._render();
}
}
connectedCallback() {
this.handlerExternalCss(), this._render();
}
disconnectedCallback() {
this._events.abort();
for (const t of this._attachments) this._release(t);
}
attributeChangedCallback(t, e, a) {
e !== a && t === "sheet" && this.handlerExternalCss();
}
handlerExternalCss = () => {
u(this, this._shadowDom, "sheet", null, this.sheet);
};
_release(t) {
t.previewUrl !== null && URL.revokeObjectURL(t.previewUrl);
}
_emit(t, e) {
this.dispatchEvent(new CustomEvent(t, {
detail: e,
bubbles: !0,
composed: !0
}));
}
_reject(t) {
return this._attachments.length >= this.maxCount ? "too-many" : t.size > this.maxSize ? "too-large" : this._accepts(t) ? this._attachments.some((e) => e.name === t.name && e.size === t.size && e.file.lastModified === t.lastModified) ? "duplicate" : null : "type-not-accepted";
}
_accepts(t) {
const e = this.accept.trim();
if (e === "") return !0;
const a = t.name.toLowerCase(), r = t.type.toLowerCase();
return e.split(",").some((n) => {
const s = n.trim().toLowerCase();
return s === "" ? !1 : s.startsWith(".") ? a.endsWith(s) : s.endsWith("/*") ? r.startsWith(s.slice(0, -1)) : r === s;
});
}
_render() {
this._events.abort(), this._list.replaceChildren();
for (const t of this._attachments) {
const e = h().class("ran-attachment").attr("part", "attachment").attr("role", "listitem").build();
if (e.dataset.id = t.id, t.previewUrl !== null) {
const n = c("img").class("ran-attachment-thumb").attr("part", "thumb").build();
n.src = t.previewUrl, n.alt = t.name, e.appendChild(n);
} else e.appendChild(c("r-icon").class("ran-attachment-icon").attr("part", "icon").attr("name", "book").build());
const a = h().class("ran-attachment-meta").build();
a.appendChild(m().class("ran-attachment-name").attr("part", "name").text(t.name).build()), a.appendChild(m().class("ran-attachment-size").attr("part", "size").text(f(t.size)).build()), e.appendChild(a);
const r = l().class("ran-attachment-remove").attr("part", "remove").attr("type", "button").attr("aria-label", `Remove ${t.name}`).children(c("r-icon").attr("name", "close").build()).build();
this._events.on(r, "click", () => this.detach(t.id)), e.appendChild(r), this._list.appendChild(e);
}
i(this, "count", this._attachments.length === 0 ? null : String(this._attachments.length), { removeEmpty: !0 }), this._emit("attachmentschange", { attachments: this.attachments });
}
};
v("r-attachments", w);
export {
w as t
};