/// 组件库 v4:按 namethatui.com 组件分类学复刻扩展。
/// 覆盖 actions / inputs / selection / display / layout / navigation / feedback /
/// overlay 八大类,供 Agent 与组件面板消费。

///|
/// 追加扩展组件(独立函数便于 builtin_components 尾部调用)
pub fn extended_components(
  m : Map[String, ComponentDef],
) -> Map[String, ComponentDef] {
  // ---------------- feedback ----------------
  let av : Map[String, NodePatch] = Map::new()
  av.set("info", patch3("primary", "on_primary", 10.0))
  av.set("success", patch3("success", "on_primary", 10.0))
  av.set("error", patch3("error", "on_primary", 10.0))
  av.set("warning", patch3("warning", "on_primary", 10.0))
  m.set("alert", {
    id: "alert",
    kind: "rect",
    description: "警示条:页面级消息(info/success/error/warning),text 为消息文案。",
    variants: av,
    default_variant: "info",
    default_size: (320.0, 52.0),
    default_layout: None,
    category: "feedback",
  })

  let tv : Map[String, NodePatch] = Map::new()
  tv.set("default", patch3("text_primary", "text_on_primary", 8.0))
  m.set("toast", {
    id: "toast",
    kind: "rect",
    description: "轻提示:短暂浮出的操作反馈。",
    variants: tv,
    default_variant: "default",
    default_size: (240.0, 44.0),
    default_layout: None,
    category: "feedback",
  })

  let snv : Map[String, NodePatch] = Map::new()
  snv.set("default", patch3("surface", "text_primary", 8.0))
  m.set("snackbar", {
    id: "snackbar",
    kind: "rect",
    description: "底部通知条(可带动作)。",
    variants: snv,
    default_variant: "default",
    default_size: (300.0, 48.0),
    default_layout: None,
    category: "feedback",
  })

  let skv : Map[String, NodePatch] = Map::new()
  skv.set("text", patch2("surface_variant", 4.0))
  skv.set("circle", patch2("surface_variant", 999.0))
  skv.set("block", patch2("surface_variant", 8.0))
  m.set("skeleton", {
    id: "skeleton",
    kind: "rect",
    description: "加载占位骨屏(text/circle/block)。",
    variants: skv,
    default_variant: "block",
    default_size: (160.0, 16.0),
    default_layout: None,
    category: "feedback",
  })

  let spv : Map[String, NodePatch] = Map::new()
  spv.set("default", patch2("primary", 999.0))
  m.set("spinner", {
    id: "spinner",
    kind: "rect",
    description: "加载中指示环。",
    variants: spv,
    default_variant: "default",
    default_size: (24.0, 24.0),
    default_layout: None,
    category: "feedback",
  })

  let mtv : Map[String, NodePatch] = Map::new()
  mtv.set("default", patch2("surface_variant", 6.0))
  mtv.set("success", patch2("success", 6.0))
  m.set("meter", {
    id: "meter",
    kind: "rect",
    description: "度量条(用量/容量)。",
    variants: mtv,
    default_variant: "default",
    default_size: (140.0, 8.0),
    default_layout: None,
    category: "feedback",
  })

  // ---------------- overlay ----------------
  let dv : Map[String, NodePatch] = Map::new()
  dv.set("default", patch3("surface", "text_primary", 14.0))
  dv.set("modal", patch3("surface", "text_primary", 16.0))
  m.set("dialog", {
    id: "dialog",
    kind: "rect",
    description: "对话框容器(text 为标题)。",
    variants: dv,
    default_variant: "default",
    default_size: (360.0, 220.0),
    default_layout: None,
    category: "overlay",
  })

  let dwv : Map[String, NodePatch] = Map::new()
  dwv.set("left", patch3("surface", "text_primary", 0.0))
  dwv.set("right", patch3("surface", "text_primary", 0.0))
  m.set("drawer", {
    id: "drawer",
    kind: "rect",
    description: "抽屉面板(left/right 侧滑)。",
    variants: dwv,
    default_variant: "right",
    default_size: (300.0, 600.0),
    default_layout: None,
    category: "overlay",
  })

  let ppv : Map[String, NodePatch] = Map::new()
  ppv.set("default", patch3("surface", "text_primary", 10.0))
  m.set("popover", {
    id: "popover",
    kind: "rect",
    description: "气泡卡片(锚点浮层)。",
    variants: ppv,
    default_variant: "default",
    default_size: (220.0, 120.0),
    default_layout: None,
    category: "overlay",
  })

  let ttv : Map[String, NodePatch] = Map::new()
  ttv.set("dark", patch3("text_primary", "surface", 6.0))
  m.set("tooltip", {
    id: "tooltip",
    kind: "rect",
    description: "文字提示气泡。",
    variants: ttv,
    default_variant: "dark",
    default_size: (140.0, 30.0),
    default_layout: None,
    category: "overlay",
  })

  let dmv : Map[String, NodePatch] = Map::new()
  dmv.set("default", patch3("surface", "text_primary", 10.0))
  m.set("menu", {
    id: "menu",
    kind: "rect",
    description: "下拉菜单面板。",
    variants: dmv,
    default_variant: "default",
    default_size: (180.0, 160.0),
    default_layout: None,
    category: "overlay",
  })

  // ---------------- navigation ----------------
  let bcv : Map[String, NodePatch] = Map::new()
  bcv.set("default", patch3("surface", "text_secondary", 6.0))
  m.set("breadcrumb", {
    id: "breadcrumb",
    kind: "rect",
    description: "面包屑路径(text 为路径文案)。",
    variants: bcv,
    default_variant: "default",
    default_size: (220.0, 28.0),
    default_layout: None,
    category: "navigation",
  })

  let pgv2 : Map[String, NodePatch] = Map::new()
  pgv2.set("default", patch2("surface", 8.0))
  pgv2.set("active", patch2("primary", 8.0))
  m.set("pagination", {
    id: "pagination",
    kind: "rect",
    description: "分页控件。",
    variants: pgv2,
    default_variant: "default",
    default_size: (220.0, 32.0),
    default_layout: None,
    category: "navigation",
  })

  let stv : Map[String, NodePatch] = Map::new()
  stv.set("default", patch3("surface", "text_secondary", 999.0))
  stv.set("active", patch3("primary", "on_primary", 999.0))
  m.set("stepper", {
    id: "stepper",
    kind: "rect",
    description: "步骤指示节点。",
    variants: stv,
    default_variant: "default",
    default_size: (28.0, 28.0),
    default_layout: None,
    category: "navigation",
  })

  let nbv : Map[String, NodePatch] = Map::new()
  nbv.set("default", patch3("surface", "text_primary", 0.0))
  nbv.set("primary", patch3("primary", "on_primary", 0.0))
  m.set("navbar", {
    id: "navbar",
    kind: "rect",
    description: "网页顶部导航条。",
    variants: nbv,
    default_variant: "default",
    default_size: (1100.0, 60.0),
    default_layout: None,
    category: "navigation",
  })

  let bnv : Map[String, NodePatch] = Map::new()
  bnv.set("default", patch3("surface", "text_primary", 0.0))
  m.set("bottom_nav", {
    id: "bottom_nav",
    kind: "rect",
    description: "App 底部标签导航。",
    variants: bnv,
    default_variant: "default",
    default_size: (390.0, 56.0),
    default_layout: None,
    category: "navigation",
  })

  // ---------------- forms / inputs ----------------
  let tav : Map[String, NodePatch] = Map::new()
  tav.set("default", patch3("surface", "text_hint", 10.0))
  tav.set("filled", patch3("surface_variant", "text_hint", 10.0))
  m.set("textarea", {
    id: "textarea",
    kind: "rect",
    description: "多行文本输入域。",
    variants: tav,
    default_variant: "default",
    default_size: (280.0, 96.0),
    default_layout: None,
    category: "inputs",
  })

  let sev : Map[String, NodePatch] = Map::new()
  sev.set("default", patch3("surface", "text_hint", 10.0))
  m.set("select", {
    id: "select",
    kind: "rect",
    description: "下拉选择框(text 为当前值)。",
    variants: sev,
    default_variant: "default",
    default_size: (200.0, 40.0),
    default_layout: None,
    category: "inputs",
  })

  let cbv2 : Map[String, NodePatch] = Map::new()
  cbv2.set("default", patch3("surface", "text_hint", 10.0))
  m.set("combobox", {
    id: "combobox",
    kind: "rect",
    description: "可输入可选择的组合框。",
    variants: cbv2,
    default_variant: "default",
    default_size: (220.0, 40.0),
    default_layout: None,
    category: "inputs",
  })

  let dpv : Map[String, NodePatch] = Map::new()
  dpv.set("default", patch3("surface", "text_hint", 10.0))
  m.set("datepicker", {
    id: "datepicker",
    kind: "rect",
    description: "日期选择输入。",
    variants: dpv,
    default_variant: "default",
    default_size: (160.0, 40.0),
    default_layout: None,
    category: "inputs",
  })

  let fuv : Map[String, NodePatch] = Map::new()
  fuv.set("default", patch3("surface_variant", "text_hint", 12.0))
  fuv.set("dashed", patch3("surface", "text_hint", 12.0))
  m.set("file_upload", {
    id: "file_upload",
    kind: "rect",
    description: "文件上传区(text 为提示文案)。",
    variants: fuv,
    default_variant: "default",
    default_size: (280.0, 120.0),
    default_layout: None,
    category: "inputs",
  })

  // ---------------- display ----------------
  let rgv : Map[String, NodePatch] = Map::new()
  rgv.set("off", patch2("surface_variant", 4.0))
  rgv.set("on", patch2("warning", 4.0))
  m.set("rating", {
    id: "rating",
    kind: "rect",
    description: "评分星星(单个星位)。",
    variants: rgv,
    default_variant: "on",
    default_size: (22.0, 22.0),
    default_layout: None,
    category: "display",
  })

  let tgv : Map[String, NodePatch] = Map::new()
  tgv.set(
    "default",
    patch3("secondary_container", "on_secondary_container", 6.0),
  )
  tgv.set("outline", patch2("surface", 6.0))
  m.set("tag", {
    id: "tag",
    kind: "rect",
    description: "内容标签(同 chip 但用于内容分类)。",
    variants: tgv,
    default_variant: "default",
    default_size: (56.0, 24.0),
    default_layout: None,
    category: "display",
  })

  let stv2 : Map[String, NodePatch] = Map::new()
  stv2.set("default", patch3("surface", "text_primary", 12.0))
  m.set("stat", {
    id: "stat",
    kind: "rect",
    description: "统计数字块(text 为数值)。",
    variants: stv2,
    default_variant: "default",
    default_size: (140.0, 80.0),
    default_layout: None,
    category: "display",
  })

  let kbdv : Map[String, NodePatch] = Map::new()
  kbdv.set("default", patch3("surface_variant", "text_primary", 5.0))
  m.set("kbd", {
    id: "kbd",
    kind: "rect",
    description: "键盘按键样式(text 为键名)。",
    variants: kbdv,
    default_variant: "default",
    default_size: (26.0, 24.0),
    default_layout: None,
    category: "display",
  })

  let tbv2 : Map[String, NodePatch] = Map::new()
  tbv2.set("default", patch3("surface", "text_primary", 8.0))
  tbv2.set("striped", patch3("surface_variant", "text_primary", 8.0))
  m.set("table", {
    id: "table",
    kind: "rect",
    description: "数据表容器。",
    variants: tbv2,
    default_variant: "default",
    default_size: (480.0, 200.0),
    default_layout: None,
    category: "display",
  })

  // ---------------- layout ----------------
  let acv : Map[String, NodePatch] = Map::new()
  acv.set("default", patch3("surface", "text_primary", 10.0))
  acv.set("expanded", patch3("surface_variant", "text_primary", 10.0))
  m.set("accordion", {
    id: "accordion",
    kind: "rect",
    description: "折叠面板行(text 为标题)。",
    variants: acv,
    default_variant: "default",
    default_size: (320.0, 48.0),
    default_layout: None,
    category: "layout",
  })

  let cav : Map[String, NodePatch] = Map::new()
  cav.set("default", patch2("surface_variant", 12.0))
  cav.set("wide", patch2("surface_variant", 12.0))
  m.set("carousel", {
    id: "carousel",
    kind: "rect",
    description: "轮播容器。",
    variants: cav,
    default_variant: "default",
    default_size: (320.0, 180.0),
    default_layout: None,
    category: "layout",
  })

  let tlv : Map[String, NodePatch] = Map::new()
  tlv.set("default", patch2("primary", 999.0))
  m.set("timeline", {
    id: "timeline",
    kind: "rect",
    description: "时间线节点。",
    variants: tlv,
    default_variant: "default",
    default_size: (12.0, 12.0),
    default_layout: None,
    category: "layout",
  })

  let bgv : Map[String, NodePatch] = Map::new()
  bgv.set("default", patch2("surface_variant", 8.0))
  bgv.set("attached", patch2("surface_variant", 0.0))
  m.set("button_group", {
    id: "button_group",
    kind: "rect",
    description: "按钮组容器。",
    variants: bgv,
    default_variant: "default",
    default_size: (180.0, 36.0),
    default_layout: None,
    category: "actions",
  })

  let lkv : Map[String, NodePatch] = Map::new()
  lkv.set("default", patch2("primary", 0.0))
  m.set("link", {
    id: "link",
    kind: "text",
    description: "超链接文本(text 为链接文案)。",
    variants: lkv,
    default_variant: "default",
    default_size: (80.0, 20.0),
    default_layout: None,
    category: "actions",
  })

  m
}

// ---------------- v5:namethatui.com 对标补全(13 组件) ----------------

///|
/// 追加 v5 批次:bento_grid / chat_bubble / command_palette /
/// hover_card / lightbox / marquee / masonry / multi_select / resize_handle /
/// scrim / status_dot / steps / toggle_group
/// (数量漂移由 agent_test 的 catalog 断言锚定,注释不承载权威计数)
pub fn extended_components_v5(
  m : Map[String, ComponentDef],
) -> Map[String, ComponentDef] {
  // ---------------- selection ----------------
  let mg : Map[String, NodePatch] = Map::new()
  mg.set("multi", patch3("primary_container", "text_primary", 8.0))
  mg.set("single", patch3("surface_variant", "text_primary", 8.0))
  m.set("multi_select", {
    id: "multi_select",
    kind: "rect",
    description: "多选控件:勾选多个值的下拉面板,text 为占位文案。",
    variants: mg,
    default_variant: "multi",
    default_size: (200.0, 44.0),
    default_layout: None,
    category: "inputs",
  })

  let tg : Map[String, NodePatch] = Map::new()
  tg.set("single", patch3("surface_variant", "text_primary", 8.0))
  tg.set("segmented", patch3("primary", "on_primary", 8.0))
  m.set("toggle_group", {
    id: "toggle_group",
    kind: "rect",
    description: "切换组/分段控件:一组互斥按钮,text 为当前段文案。",
    variants: tg,
    default_variant: "single",
    default_size: (180.0, 36.0),
    default_layout: None,
    category: "selection",
  })

  let st : Map[String, NodePatch] = Map::new()
  st.set("active", patch3("primary", "on_primary", 999.0))
  st.set("inactive", patch3("surface_variant", "text_secondary", 999.0))
  m.set("steps", {
    id: "steps",
    kind: "rect",
    description: "步骤条:向导/流程进度(当前步高亮),text 为当前步名。",
    variants: st,
    default_variant: "active",
    default_size: (240.0, 32.0),
    default_layout: None,
    category: "navigation",
  })

  // ---------------- status / indicator ----------------
  let sd : Map[String, NodePatch] = Map::new()
  sd.set("online", patch3("success", "on_primary", 999.0))
  sd.set("away", patch3("warning", "on_primary", 999.0))
  sd.set("offline", patch3("outline", "on_primary", 999.0))
  m.set("status_dot", {
    id: "status_dot",
    kind: "rect",
    description: "状态点/在线指示器:小圆点标示在线状态,text 可省略。",
    variants: sd,
    default_variant: "online",
    default_size: (16.0, 16.0),
    default_layout: None,
    category: "display",
  })

  // ---------------- overlay ----------------
  let sc : Map[String, NodePatch] = Map::new()
  sc.set("default", patch2("text_primary", 0.0))
  m.set("scrim", {
    id: "scrim",
    kind: "rect",
    description: "遮罩层/背景覆盖:半透明压暗层,text 为空。opacity 建议调低。",
    variants: sc,
    default_variant: "default",
    default_size: (390.0, 844.0),
    default_layout: None,
    category: "overlay",
  })

  let hc : Map[String, NodePatch] = Map::new()
  hc.set("default", patch3("surface", "text_primary", 12.0))
  m.set("hover_card", {
    id: "hover_card",
    kind: "rect",
    description: "悬停卡片:hover 展示的预览卡(头像+简介),text 为简介。",
    variants: hc,
    default_variant: "default",
    default_size: (240.0, 120.0),
    default_layout: None,
    category: "overlay",
  })

  let lb : Map[String, NodePatch] = Map::new()
  lb.set("default", patch2("text_primary", 0.0))
  m.set("lightbox", {
    id: "lightbox",
    kind: "image",
    description: "灯箱:点击放大的全屏图片查看层,text 为图片 src。",
    variants: lb,
    default_variant: "default",
    default_size: (390.0, 500.0),
    default_layout: None,
    category: "overlay",
  })

  let cp : Map[String, NodePatch] = Map::new()
  cp.set("default", patch3("surface", "text_primary", 12.0))
  m.set("command_palette", {
    id: "command_palette",
    kind: "rect",
    description: "命令面板:⌘K 式快捷命令搜索列表,text 为搜索占位。",
    variants: cp,
    default_variant: "default",
    default_size: (320.0, 240.0),
    default_layout: None,
    category: "overlay",
  })

  // ---------------- content / layout ----------------
  let cb : Map[String, NodePatch] = Map::new()
  cb.set("mine", patch3("primary", "on_primary", 16.0))
  cb.set("theirs", patch3("surface_variant", "text_primary", 16.0))
  m.set("chat_bubble", {
    id: "chat_bubble",
    kind: "rect",
    description: "聊天气泡:对话消息(mine=右侧主视角,theirs=左侧对方),text 为消息。",
    variants: cb,
    default_variant: "mine",
    default_size: (220.0, 48.0),
    default_layout: None,
    category: "display",
  })

  let mq : Map[String, NodePatch] = Map::new()
  mq.set("default", patch3("surface_variant", "text_primary", 0.0))
  m.set("marquee", {
    id: "marquee",
    kind: "rect",
    description: "跑马灯:横向循环滚动的文字条,text 为滚动文案。",
    variants: mq,
    default_variant: "default",
    default_size: (340.0, 40.0),
    default_layout: None,
    category: "display",
  })

  let ms : Map[String, NodePatch] = Map::new()
  ms.set("default", patch3("surface_variant", "text_primary", 12.0))
  ms.set("dense", patch3("surface_variant", "text_primary", 8.0))
  m.set("masonry", {
    id: "masonry",
    kind: "frame",
    description: "瀑布流布局容器:不等高多列卡片流。",
    variants: ms,
    default_variant: "default",
    default_size: (340.0, 400.0),
    default_layout: None,
    category: "layout",
  })

  let bg : Map[String, NodePatch] = Map::new()
  bg.set("default", patch3("surface_variant", "text_primary", 16.0))
  bg.set("compact", patch3("surface_variant", "text_primary", 8.0))
  m.set("bento_grid", {
    id: "bento_grid",
    kind: "frame",
    description: "便当盒网格:大小混排的模块化网格布局。",
    variants: bg,
    default_variant: "default",
    default_size: (340.0, 320.0),
    default_layout: None,
    category: "layout",
  })

  let rh : Map[String, NodePatch] = Map::new()
  rh.set("vertical", patch3("outline", "on_primary", 2.0))
  rh.set("horizontal", patch3("outline", "on_primary", 2.0))
  m.set("resize_handle", {
    id: "resize_handle",
    kind: "rect",
    description: "调整大小手柄:面板分割处的拖拽把手(vertical/horizontal)。",
    variants: rh,
    default_variant: "vertical",
    default_size: (8.0, 64.0),
    default_layout: None,
    category: "layout",
  })

  m
}