import { html } from "lit";
import type { WebwriterWebsiteBuilder } from "../../webwriter-website-builder";
import { ComponentRegistry } from "../../components/registry";
import { SHOELACE_ICON_NAMES } from "../data/shoelaceIcons";
import { componentSyntaxHint, tileGlyph } from "../palette-helpers";
import { msg } from "@lit/localize";
// ─── Icon Dialog ──────────────────────────────────────────────────────────────
export function renderIconDialog(host: WebwriterWebsiteBuilder) {
const q = host.iconQuery.trim().toLowerCase();
const items = q
? SHOELACE_ICON_NAMES.filter((n) => n.toLowerCase().includes(q))
: SHOELACE_ICON_NAMES;
return html`
{
const input = e.currentTarget as any;
host.iconQuery = String(input.value ?? "");
host.iconScrollTop = 0;
host.iconScroller?.scrollTo({ top: 0 });
host.requestUpdate();
}}
@sl-clear=${() => (host.iconQuery = "")}
>
{
host.iconDraftColor = String(
e?.target?.value ?? e?.detail?.value ?? (e?.currentTarget as any)?.value ?? "",
);
host.requestUpdate();
}}
>
${renderIconVirtualGrid(host, items)}
`;
}
function renderIconVirtualGrid(host: WebwriterWebsiteBuilder, items: string[]) {
const ICON_ROW_H = 60;
const ICON_OVERSCAN = 3;
const width = host.iconScroller?.clientWidth ?? 760;
const minCol = 56;
const cols = Math.max(1, Math.floor((width - 24) / (minCol + 6)));
const totalRows = Math.ceil(items.length / cols);
const spacerH = totalRows * ICON_ROW_H;
let startRow = Math.floor(host.iconScrollTop / ICON_ROW_H) - ICON_OVERSCAN;
startRow = Math.max(0, Math.min(startRow, totalRows - 1));
const endRow = Math.min(
totalRows,
Math.ceil((host.iconScrollTop + host.iconViewportH) / ICON_ROW_H) + ICON_OVERSCAN,
);
const startIndex = startRow * cols;
const endIndex = Math.min(items.length, endRow * cols);
const slice = items.slice(startIndex, endIndex);
const offsetY = startRow * ICON_ROW_H;
return html`
${slice.map((name) => {
const selected = name === host.iconDraftName;
return html`
`;
})}
`;
}
// ─── All Components Dialog ────────────────────────────────────────────────────
export function renderAllComponentsDialog(host: WebwriterWebsiteBuilder) {
const q = host.allComponentsQuery.trim().toLowerCase();
const allTypes = Object.keys(ComponentRegistry);
const types = (
q
? allTypes.filter((t) => {
const label = (ComponentRegistry[t]?.label() ?? t).toLowerCase();
return t.toLowerCase().includes(q) || label.includes(q);
})
: allTypes
).sort((a, b) => {
const la = (ComponentRegistry[a]?.label() ?? a).toLowerCase();
const lb = (ComponentRegistry[b]?.label() ?? b).toLowerCase();
return la.localeCompare(lb);
});
return html`
{
const dlg = e.target as HTMLElement;
queueMicrotask(() => {
(dlg.querySelector("#ww-all-components-search") as any)?.focus?.();
});
}}
@sl-after-hide=${() => {
host.allComponentsDialogOpen = false;
}}
>
{
host.allComponentsQuery = String(
e?.currentTarget?.value ?? e?.target?.value ?? e?.detail?.value ?? "",
);
host.requestUpdate();
}}
@sl-clear=${() => (host.allComponentsQuery = "")}
style="flex:1;"
>
${types.length} ${types.length === 1 ? msg("item") : msg("items")}
${types.map((type) => {
const comp = ComponentRegistry[type];
const label = comp?.label?.() ?? type;
const syntax = componentSyntaxHint(type);
return html`
${tileGlyph(type)}
${label}
{
host.quickAdd(type);
host.requestUpdate();
}}
>${msg("Insert")}
${msg("Drag tiles from the palette, or insert here at default position.")}
${msg("Syntax (preview)")}
${syntax}
`;
})}
(host.renderRoot.querySelector("#ww-all-components-dialog") as any)?.hide?.()}
>${msg("Close")}
`;
}