import { a as e, r as t } from "./sanitize-uWpY18N9.js";
import { n } from "./utils-CSEWuKHo.js";
import { n as r, r as i } from "./sorting-ClExT3HS.js";
import { r as a, t as o } from "./a11y-ZYZ3T617.js";
import { i as s, t as c } from "./keyboard-BH4fCxA0.js";
//#region src/components/data-table/renderers.ts
function l(e) {
	if (e === 0) return "0 B";
	let t = [
		"B",
		"KB",
		"MB",
		"GB",
		"TB"
	], n = 1024, r = Math.floor(Math.log(e) / Math.log(n)), i = Math.min(r, t.length - 1), a = t[i];
	return a === void 0 ? `${String(e)} B` : `${(e / n ** i).toFixed(2)} ${a}`;
}
function u(e) {
	let t = Date.now() - e.getTime(), n = Math.floor(t / 1e3), r = Math.floor(n / 60), i = Math.floor(r / 60), a = Math.floor(i / 24);
	return n < 60 ? `${String(n)}s ago` : r < 60 ? `${String(r)}m ago` : i < 24 ? `${String(i)}h ago` : `${String(a)}d ago`;
}
function d(e) {
	return e == null ? "" : typeof e == "string" ? e : typeof e == "number" || typeof e == "boolean" ? String(e) : JSON.stringify(e);
}
function f(e, n, r) {
	let i = d(e);
	switch (n) {
		case "text": return t(i);
		case "badge": {
			let e = t(i), n = r?.badgeMap, a = "default";
			if (typeof n == "object" && n) {
				let e = n[i];
				e !== void 0 && (a = e);
			}
			return `<span class="cmm-badge cmm-badge--${t(a)}">${e}</span>`;
		}
		case "link": {
			let e = t(i);
			return /^https?:\/\//.test(i) ? `<a href="${e}" class="cmm-link" target="_blank" rel="noopener noreferrer">${e}</a>` : e;
		}
		case "code": return `<code class="cmm-code">${t(i)}</code>`;
		case "bytes": {
			let n = typeof e == "number" ? e : parseFloat(i);
			return t(Number.isNaN(n) ? i : l(n));
		}
		case "datetime": {
			let n = e instanceof Date ? e : new Date(i);
			if (Number.isNaN(n.getTime())) return t(i);
			let a = r?.format;
			return t(a === "iso" ? n.toISOString() : a === "locale" ? n.toLocaleString() : u(n));
		}
		case "number": {
			let n = typeof e == "number" ? e : parseFloat(i);
			return t(Number.isNaN(n) ? i : n.toLocaleString());
		}
		default: return t(i);
	}
}
//#endregion
//#region src/components/data-table/export.ts
function p(e) {
	let t = e == null ? "" : typeof e == "string" || typeof e == "number" || typeof e == "boolean" ? String(e) : JSON.stringify(e);
	return t.includes(",") || t.includes("\"") || t.includes("\n") || t.includes("\r") ? `"${t.replace(/"/g, "\"\"")}"` : t;
}
function m(e, t) {
	let n = [e.map((e) => p(e.label)).join(",")];
	for (let r of t) {
		let t = [];
		for (let n = 0; n < e.length; n++) {
			let e = r[n];
			t.push(p(e));
		}
		n.push(t.join(","));
	}
	return n.join("\n");
}
function h(e, t) {
	let n = [];
	for (let r of t) {
		let t = {};
		for (let n = 0; n < e.length; n++) {
			let i = e[n];
			i !== void 0 && (t[i.key] = r[n] ?? null);
		}
		n.push(t);
	}
	return JSON.stringify(n, null, 2);
}
async function g(e) {
	await navigator.clipboard.writeText(e);
}
//#endregion
//#region src/components/data-table/index.ts
function _(e) {
	if (typeof e == "string") {
		let t = document.querySelector(e);
		if (!t) throw Error(`DataTable container not found: ${e}`);
		return t;
	}
	return e;
}
var v = class {
	container;
	columns;
	config;
	rows = [];
	sortState = null;
	currentPage = 0;
	wrapperEl = null;
	tableEl = null;
	liveRegion = null;
	tableId;
	captionId;
	focusedRow = 0;
	focusedCol = 0;
	selectedKeys = /* @__PURE__ */ new Set();
	selectAllEl = null;
	constructor(e) {
		if (this.container = _(e.container), this.columns = e.columns, this.config = e, this.tableId = n("cmm-data-table"), this.captionId = n("cmm-data-table-caption"), e.data !== void 0 && (this.rows = e.data), e.selectable === !0 && e.selectedRows !== void 0) for (let t of e.selectedRows) t >= 0 && t < this.rows.length && this.selectedKeys.add(t);
		this.liveRegion = a("polite"), this.render();
	}
	setData(e) {
		this.rows = e, this.currentPage = 0, this.focusedRow = 0, this.focusedCol = 0, this.selectedKeys.clear(), this.render(), this.announceUpdate(`Table updated with ${String(e.length)} rows`);
	}
	appendRows(e) {
		this.rows = [...this.rows, ...e], this.render(), this.announceUpdate(`Added ${String(e.length)} rows, total ${String(this.rows.length)} rows`);
	}
	setLoading(e) {
		if (!this.wrapperEl) return;
		let t = this.wrapperEl.querySelector(".cmm-data-table__loading");
		if (e) {
			if (!t) {
				let e = document.createElement("div");
				e.className = "cmm-data-table__loading", e.setAttribute("role", "status"), e.setAttribute("aria-live", "polite");
				let t = document.createElement("span");
				t.textContent = "Loading...", e.appendChild(t), this.wrapperEl.appendChild(e), this.announceUpdate("Loading data");
			}
		} else t && (t.remove(), this.announceUpdate("Data loaded"));
	}
	clear() {
		this.rows = [], this.currentPage = 0, this.focusedRow = 0, this.focusedCol = 0, this.selectedKeys.clear(), this.render(), this.announceUpdate("Table cleared");
	}
	getRowCount() {
		return this.rows.length;
	}
	isSelectable() {
		return this.config.selectable === !0;
	}
	getSelectedIndices() {
		return [...this.selectedKeys].sort((e, t) => e - t);
	}
	getSelectedRows() {
		return this.rows.filter((e, t) => this.selectedKeys.has(t));
	}
	setSelectedRows(e) {
		this.selectedKeys.clear();
		for (let t of e) t >= 0 && t < this.rows.length && this.selectedKeys.add(t);
		this.render(), this.emitSelectionChange();
	}
	clearSelection() {
		this.selectedKeys.size !== 0 && (this.selectedKeys.clear(), this.render(), this.emitSelectionChange());
	}
	emitSelectionChange() {
		this.config.onSelectionChange?.(this.getSelectedIndices(), this.getSelectedRows());
	}
	updateSelectAllState() {
		if (this.selectAllEl === null) return;
		let e = this.rows.length, t = this.selectedKeys.size;
		this.selectAllEl.checked = e > 0 && t === e, this.selectAllEl.indeterminate = t > 0 && t < e;
	}
	buildCheckbox(e) {
		let t = document.createElement("input");
		return t.type = "checkbox", t.className = "cmm-data-table__checkbox", t.setAttribute("aria-label", e), t;
	}
	toggleAll(e) {
		if (this.selectedKeys.clear(), e) for (let e = 0; e < this.rows.length; e++) this.selectedKeys.add(e);
		let t = this.tableEl?.querySelector("tbody");
		if (t) for (let n of Array.from(t.querySelectorAll("tr.cmm-data-table__row"))) {
			let t = n.querySelector(".cmm-data-table__cell--checkbox .cmm-data-table__checkbox");
			t && (t.checked = e), e ? (n.classList.add("cmm-data-table__row--selected"), n.dataset.state = "selected") : (n.classList.remove("cmm-data-table__row--selected"), delete n.dataset.state);
		}
		this.updateSelectAllState(), this.emitSelectionChange();
	}
	toggleRow(e, t, n) {
		t ? (this.selectedKeys.add(e), n.classList.add("cmm-data-table__row--selected"), n.dataset.state = "selected") : (this.selectedKeys.delete(e), n.classList.remove("cmm-data-table__row--selected"), delete n.dataset.state), this.updateSelectAllState(), this.emitSelectionChange();
	}
	destroy() {
		this.container.replaceChildren(), this.wrapperEl = null, this.tableEl = null, this.liveRegion?.destroy(), this.liveRegion = null;
	}
	announceUpdate(e) {
		this.liveRegion?.announce(e);
	}
	getPageRows() {
		let e = this.config.pagination;
		if (e === void 0) return this.rows;
		let t = this.currentPage * e.pageSize, n = t + e.pageSize;
		return this.rows.slice(t, n);
	}
	getTotalPages() {
		let e = this.config.pagination;
		return e === void 0 ? 1 : Math.max(1, Math.ceil(this.rows.length / e.pageSize));
	}
	handleSort(e) {
		let t = this.columns.find((t) => t.key === e);
		if (t?.sortable !== !0) return;
		let n = r(this.sortState?.key ?? null, this.sortState?.direction ?? null, e);
		this.sortState = n;
		let i = n?.direction ?? null;
		if (i === null) this.announceUpdate(`${t.label} sort cleared`);
		else {
			let e = i === "asc" ? "ascending" : "descending";
			this.announceUpdate(`Sorted by ${t.label} ${e}`);
		}
		this.config.onSort !== void 0 && this.config.onSort(e, i), this.currentPage = 0, this.render();
	}
	getSortedRows() {
		if (this.sortState === null) return [...this.rows];
		let { key: e, direction: t } = this.sortState, n = this.columns.findIndex((t) => t.key === e);
		return n < 0 || t === null ? [...this.rows] : i(this.rows, t, (e) => e[n]);
	}
	buildSortIcon(e) {
		let t = this.sortState?.key === e ? "cmm-data-table__sort-icon--active" : "";
		return this.sortState?.key === e ? this.sortState.direction === "asc" ? `<span class="cmm-data-table__sort-icon ${t}" aria-hidden="true">&#8593;</span>` : `<span class="cmm-data-table__sort-icon ${t}" aria-hidden="true">&#8595;</span>` : `<span class="cmm-data-table__sort-icon ${t}" aria-hidden="true">&#8597;</span>`;
	}
	getSortLabel(e) {
		return this.sortState?.key === e ? this.sortState.direction === "asc" ? "ascending" : "descending" : "none";
	}
	handleKeyDown(e) {
		let t = e.target;
		if (this.tableEl?.contains(t) !== !0) return;
		let n = this.tableEl.querySelector("tbody");
		if (!n) return;
		let r = Array.from(n.querySelectorAll("tr")), i = this.getPageRows();
		if (i.length === 0) return;
		let a = s(e, {
			columns: this.columns.length,
			rows: i.length,
			currentCol: this.focusedCol,
			currentRow: this.focusedRow,
			wrap: !1
		});
		if (a.handled && (e.preventDefault(), this.focusedRow = a.row, this.focusedCol = a.col, this.focusCell(r)), e.key === c.ENTER || e.key === c.SPACE) {
			let t = this.config.pagination, n = (t === void 0 ? 0 : this.currentPage * t.pageSize) + this.focusedRow, r = this.rows[n];
			r !== void 0 && this.config.onRowClick !== void 0 && (e.preventDefault(), this.config.onRowClick(r, n));
		}
	}
	focusCell(e) {
		let t = e[this.focusedRow];
		if (t === void 0) return;
		let n = Array.from(t.querySelectorAll("td"))[this.focusedCol + +!!this.isSelectable()];
		if (n !== void 0) {
			n.focus();
			let e = n.textContent;
			o(`${this.columns[this.focusedCol]?.label ?? ""}: ${e}`, "polite");
		}
	}
	render() {
		this.container.replaceChildren();
		let n = document.createElement("div");
		n.className = "cmm-data-table", n.setAttribute("data-slot", "data-table"), this.wrapperEl = n;
		let r = this.config.pagination, i = this.isSelectable(), a = +!!i, o = new Map(this.rows.map((e, t) => [e, t]));
		r !== void 0 && (r.position === "top" || r.position === "both") && n.appendChild(this.buildPagination("top")), this.config.exportFormats !== void 0 && this.config.exportFormats.length > 0 && n.appendChild(this.buildExportBar());
		let s = this.getSortedRows(), l = this.rows;
		this.rows = s;
		let u = this.getPageRows();
		this.rows = l;
		let d = document.createElement("table");
		d.className = "cmm-data-table__table", d.id = this.tableId, d.setAttribute("role", "grid"), d.setAttribute("aria-labelledby", this.captionId), d.setAttribute("aria-rowcount", String(this.rows.length)), d.setAttribute("aria-colcount", String(this.columns.length + a)), this.tableEl = d;
		let p = document.createElement("caption");
		p.id = this.captionId, p.className = "cmm-sr-only", p.textContent = this.config.emptyMessage === void 0 ? `Data table with ${String(this.rows.length)} rows and ${String(this.columns.length)} columns. Use arrow keys to navigate.` : `Data table. ${String(this.rows.length)} rows, ${String(this.columns.length)} columns. Use arrow keys to navigate.`, d.appendChild(p);
		let m = document.createElement("thead");
		m.className = "cmm-data-table__head";
		let h = document.createElement("tr");
		if (h.setAttribute("role", "row"), i) {
			let e = document.createElement("th");
			e.className = "cmm-data-table__header cmm-data-table__header--checkbox", e.setAttribute("role", "columnheader"), e.setAttribute("scope", "col"), e.setAttribute("aria-colindex", "1");
			let t = this.buildCheckbox("Select all rows");
			this.selectAllEl = t, t.addEventListener("change", () => {
				this.toggleAll(t.checked);
			}), e.appendChild(t), h.appendChild(e);
		} else this.selectAllEl = null;
		for (let n = 0; n < this.columns.length; n++) {
			let r = this.columns[n];
			if (r === void 0) continue;
			let i = document.createElement("th");
			i.className = "cmm-data-table__header", i.setAttribute("role", "columnheader"), i.setAttribute("scope", "col"), i.setAttribute("aria-colindex", String(n + 1 + a)), r.width !== void 0 && (i.style.width = r.width), r.className !== void 0 && i.classList.add(r.className), r.sortable === !0 ? (i.classList.add("cmm-data-table__header--sortable"), i.setAttribute("aria-sort", this.getSortLabel(r.key)), i.setAttribute("tabindex", "0"), e(i, `${t(r.label)} ${this.buildSortIcon(r.key)}`), i.addEventListener("click", () => {
				this.handleSort(r.key);
			}), i.addEventListener("keydown", (e) => {
				(e.key === c.ENTER || e.key === c.SPACE) && (e.preventDefault(), this.handleSort(r.key));
			})) : i.textContent = r.label, this.sortState !== null && this.sortState.key === r.key && i.classList.add("cmm-data-table__cell--sorted"), h.appendChild(i);
		}
		m.appendChild(h), d.appendChild(m), this.updateSelectAllState();
		let g = document.createElement("tbody");
		if (g.className = "cmm-data-table__body", u.length === 0) {
			let e = document.createElement("tr");
			e.setAttribute("role", "row");
			let t = document.createElement("td");
			t.className = "cmm-data-table__empty", t.colSpan = this.columns.length + a, t.setAttribute("role", "gridcell"), t.textContent = this.config.emptyMessage ?? "No data available", e.appendChild(t), g.appendChild(e);
		} else {
			let t = r === void 0 ? 0 : this.currentPage * r.pageSize;
			for (let n = 0; n < u.length; n++) {
				let r = u[n];
				if (r === void 0) continue;
				let s = document.createElement("tr");
				s.className = "cmm-data-table__row", s.setAttribute("role", "row"), s.setAttribute("aria-rowindex", String(t + n + 1));
				let c = t + n;
				if (this.config.onRowClick !== void 0 && (s.classList.add("cmm-data-table__row--clickable"), s.style.cursor = "pointer", s.addEventListener("click", () => {
					this.config.onRowClick?.(r, c);
				})), this.config.onRowContext !== void 0 && s.addEventListener("contextmenu", (e) => {
					this.config.onRowContext?.(r, c, e);
				}), i) {
					let e = o.get(r) ?? c;
					this.selectedKeys.has(e) && (s.classList.add("cmm-data-table__row--selected"), s.dataset.state = "selected");
					let t = document.createElement("td");
					t.className = "cmm-data-table__cell cmm-data-table__cell--checkbox", t.setAttribute("role", "gridcell"), t.setAttribute("aria-colindex", "1");
					let n = this.buildCheckbox(`Select row ${String(c + 1)}`);
					n.checked = this.selectedKeys.has(e), n.addEventListener("click", (e) => {
						e.stopPropagation();
					}), n.addEventListener("change", () => {
						this.toggleRow(e, n.checked, s);
					}), t.appendChild(n), s.appendChild(t);
				}
				for (let t = 0; t < this.columns.length; t++) {
					let i = this.columns[t];
					if (i === void 0) continue;
					let o = document.createElement("td");
					o.className = "cmm-data-table__cell", o.setAttribute("role", "gridcell"), o.setAttribute("aria-colindex", String(t + 1 + a)), o.setAttribute("tabindex", n === this.focusedRow && t === this.focusedCol ? "0" : "-1"), i.className !== void 0 && o.classList.add(i.className), this.sortState !== null && this.sortState.key === i.key && o.classList.add("cmm-data-table__cell--sorted");
					let c = r[t], l = i.renderer ?? "text", u = {};
					i.badgeMap !== void 0 && (u.badgeMap = i.badgeMap), i.format !== void 0 && (u.format = i.format), e(o, f(c, l, u)), s.appendChild(o);
				}
				g.appendChild(s);
			}
		}
		d.appendChild(g), d.addEventListener("keydown", (e) => {
			this.handleKeyDown(e);
		}), n.appendChild(d), r !== void 0 && (r.position === void 0 || r.position === "bottom" || r.position === "both") && n.appendChild(this.buildPagination("bottom")), this.container.appendChild(n);
	}
	buildPagination(e) {
		let t = document.createElement("nav");
		t.className = "cmm-data-table__pagination", t.setAttribute("role", "navigation"), t.setAttribute("aria-label", `Table pagination ${e}`);
		let n = this.getTotalPages(), r = document.createElement("span");
		r.className = "cmm-data-table__pagination-info", r.setAttribute("aria-live", "polite"), r.textContent = `Page ${String(this.currentPage + 1)} of ${String(n)}`, t.appendChild(r);
		let i = document.createElement("button");
		i.className = "cmm-data-table__pagination-btn", i.type = "button", i.textContent = "Previous", i.disabled = this.currentPage === 0, i.setAttribute("aria-label", "Go to previous page"), this.currentPage === 0 && i.setAttribute("aria-disabled", "true"), i.addEventListener("click", () => {
			this.currentPage > 0 && (this.currentPage--, this.focusedRow = 0, this.focusedCol = 0, this.render(), this.announceUpdate(`Page ${String(this.currentPage + 1)} of ${String(n)}`));
		}), t.appendChild(i);
		let a = document.createElement("button");
		return a.className = "cmm-data-table__pagination-btn", a.type = "button", a.textContent = "Next", a.disabled = this.currentPage >= n - 1, a.setAttribute("aria-label", "Go to next page"), this.currentPage >= n - 1 && a.setAttribute("aria-disabled", "true"), a.addEventListener("click", () => {
			this.currentPage < n - 1 && (this.currentPage++, this.focusedRow = 0, this.focusedCol = 0, this.render(), this.announceUpdate(`Page ${String(this.currentPage + 1)} of ${String(n)}`));
		}), t.appendChild(a), t;
	}
	buildExportBar() {
		let e = document.createElement("div");
		e.className = "cmm-data-table__export", e.setAttribute("role", "toolbar"), e.setAttribute("aria-label", "Export options");
		let t = this.config.exportFormats ?? [];
		for (let n of t) {
			let t = document.createElement("button");
			switch (t.className = "cmm-data-table__export-btn", t.type = "button", n) {
				case "csv":
					t.textContent = "Export CSV", t.setAttribute("aria-label", "Export data as CSV file"), t.addEventListener("click", () => {
						let e = m(this.columns, this.rows), t = new Blob([e], { type: "text/csv" }), n = URL.createObjectURL(t), r = document.createElement("a");
						r.href = n, r.download = "export.csv", r.click(), URL.revokeObjectURL(n), this.announceUpdate("CSV file downloaded");
					});
					break;
				case "json":
					t.textContent = "Export JSON", t.setAttribute("aria-label", "Export data as JSON file"), t.addEventListener("click", () => {
						let e = h(this.columns, this.rows), t = new Blob([e], { type: "application/json" }), n = URL.createObjectURL(t), r = document.createElement("a");
						r.href = n, r.download = "export.json", r.click(), URL.revokeObjectURL(n), this.announceUpdate("JSON file downloaded");
					});
					break;
				case "clipboard":
					t.textContent = "Copy to Clipboard", t.setAttribute("aria-label", "Copy data to clipboard"), t.addEventListener("click", () => {
						g(m(this.columns, this.rows)).then(() => {
							this.announceUpdate("Data copied to clipboard");
						});
					});
					break;
			}
			e.appendChild(t);
		}
		return e;
	}
};
//#endregion
export { v as t };

//# sourceMappingURL=data-table-DcgJjvnu.js.map