namespace Htmx.ApiDemo.Templates.Components;
///
/// CSS-native DropdownMenu using <details>/<summary>.
/// Position: "left-0 top-full mt-1" (default) | "right-0 top-full mt-1" | etc.
/// Items: pre-built HTML — use BuildItem() helper for consistent styling.
///
public sealed class DropdownMenu : DropdownMenuBase
{
private const string ItemClasses =
"relative flex w-full cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm " +
"outline-none transition-colors hover:bg-accent hover:text-accent-foreground " +
"focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50";
private readonly byte[] _triggerClassesData;
private readonly byte[] _triggerData;
private readonly byte[] _positionData;
private readonly byte[] _itemsData;
public DropdownMenu(
IHtmxComponent trigger,
IEnumerable<(string Label, string Href, bool IsSeparator)> items,
string position = "left-0 top-full mt-1")
{
// Render trigger to bytes
var writer = new System.Buffers.ArrayBufferWriter();
trigger.Render(new HtmxRenderContext(writer));
_triggerData = writer.WrittenSpan.ToArray();
_triggerClassesData = []; // trigger already supplies its own classes
_positionData = position.ToUtf8Bytes();
var sb = new System.Text.StringBuilder();
foreach (var (label, href, isSeparator) in items)
{
if (isSeparator)
{
sb.Append("""""");
}
else if (string.IsNullOrEmpty(href))
{
sb.Append($"""""");
}
else
{
sb.Append($"""{label}""");
}
}
_itemsData = sb.ToString().ToUtf8Bytes();
}
protected override void RenderTriggerClasses(HtmxRenderContext ctx) => ctx.Writer.WriteUtf8(_triggerClassesData);
protected override void RenderTrigger(HtmxRenderContext ctx) => ctx.Writer.WriteUtf8(_triggerData);
protected override void RenderPosition(HtmxRenderContext ctx) => ctx.Writer.WriteUtf8(_positionData);
protected override void RenderItems(HtmxRenderContext ctx) => ctx.Writer.WriteUtf8(_itemsData);
}