export let widget_context_menu_item = (b, i, w, item_h, radius, label_fill, hover_fill, items, targets, close_str, disabled_items, item_blocks, has_blocks) => {
let item = has_blocks ? item_blocks[i] : b
let label = has_blocks ? attr_or(item, "label", "Item") : trim(items[i])
let target = has_blocks ? attr_or(item, "target", "") : (len(targets) > i ? trim(targets[i]) : "")
let disabled = has_blocks ? attr_or(item, "disabled", "false") == "true" : contains(disabled_items, label)
let closes = has_blocks ? attr_or(item, "close_targets", close_str) : close_str
let close_ids = closes != "" ? split(",", closes) : []
let close_events = map(close_ids, (menu_id) => {
trigger = "hover",
target = trim(menu_id),
state = "shown",
mode = "remove"
})
let open_event = target != "" ? [{ trigger = "hover", target = target, state = "shown", mode = "add" }] : []
let events = disabled ? [] : concat(concat([{ trigger = "hover", state = "hovered", mode = "while" }], close_events), open_event)
let arrow = target != "" ? [
{ kind = "text", x = w - 18, y = 0, width = 10, height = item_h,
content = ">", font_size = 12, fill = label_fill, pointer_events = "none" }
] : []
{
kind = "group",
id = "item_" + label,
x = 0,
y = i * item_h,
width = w,
height = item_h,
class = disabled ? "wdoc-menu-item wdoc-menu-item-disabled" : "wdoc-menu-item",
pointer_events = disabled ? "none" : "all",
cursor = disabled ? "default" : "pointer",
events = events,
children = concat([
{ kind = "rect", x = 4, y = 2, width = w - 8, height = item_h - 4,
rx = radius, fill = hover_fill, class = "wdoc-menu-item-bg" },
{ kind = "text", x = 12, y = 0, width = w - 24, height = item_h,
content = label, font_size = 12, anchor = "start",
fill = label_fill, pointer_events = "none" }
], arrow)
}
}
export let widget_context_menu = (b) => {
let w = attr_or(b, "width", 170)
let items_str = attr_or(b, "items", "Open,Rename,Delete")
let target_str = attr_or(b, "menu_targets", "")
let targets = target_str != "" ? split(",", target_str) : []
let close_str = attr_or(b, "close_targets", target_str)
let disabled_str = attr_or(b, "disabled_items", "")
let disabled_items = disabled_str != "" ? split(",", disabled_str) : []
let item_blocks = children(b, "wdoc::draw::menu_item")
let has_blocks = len(item_blocks) > 0
let items = split(",", items_str)
let n = has_blocks ? len(item_blocks) : len(items)
let item_h = attr_or(b, "item_height", 28)
let h = attr_or(b, "height", n * item_h)
let bg_fill = attr_or(b, "background_fill", attr_or(b, "surface_fill", "var(--color-bg)"))
let border_stroke = attr_or(b, "border_stroke", "var(--color-nav-border)")
let label_fill = attr_or(b, "label_fill", "currentColor")
let hover_fill = attr_or(b, "hover_fill", "var(--color-nav-active)")
let separator_stroke = attr_or(b, "separator_stroke", border_stroke)
let radius = attr_or(b, "radius", 6)
let border_width = attr_or(b, "border_width", 1)
let dismiss_on_leave = attr_or(b, "dismiss_on_leave", "true") == "true"
let leave_close_str = attr_or(b, "leave_close_targets", to_string(b.id))
let leave_close_ids = leave_close_str != "" ? split(",", leave_close_str) : []
let leave_events = dismiss_on_leave ? map(leave_close_ids, (menu_id) => {
trigger = "mouse_leave",
target = trim(menu_id),
state = "shown",
mode = "remove"
}) : []
let separators = map(range(1, n), (i) => {
kind = "line",
x1 = 8,
y1 = i * item_h,
x2 = w - 8,
y2 = i * item_h,
stroke = separator_stroke,
stroke_width = 1,
opacity = 0.55
})
let item_rows = map(range(0, n), (i) => wdoc::widget_context_menu_item(b, i, w, item_h, radius, label_fill, hover_fill, items, targets, close_str, disabled_items, item_blocks, has_blocks))
[
{
kind = "group",
id = "surface",
x = 0,
y = 0,
width = w,
height = h,
events = leave_events,
children = concat(concat([
{ kind = "rect", x = 0, y = 0, width = w, height = h, rx = radius,
fill = bg_fill, stroke = border_stroke, stroke_width = border_width }
], item_rows), separators)
}
]
}