{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "grid-toolbar",
  "title": "网格工具栏",
  "description": "一行格子组成的工具栏，格子之间虚线分隔、窄容器自动换行；方条输入、分段选择、方条下拉放进来会自动去掉外框铺满整格。",
  "dependencies": [
    "class-variance-authority"
  ],
  "files": [
    {
      "path": "src/registry/ui/grid-toolbar/grid-toolbar.tsx",
      "content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\n/**\n * 行高写进 `--grid-toolbar-height`，格子与格内控件都读它；\n * 对应按钮 `icon` / `icon-lg` 档（32 / 36px），触屏加高一档（40 / 44px）。\n */\nconst gridToolbarVariants = cva(\n  \"@container/grid-toolbar w-full overflow-hidden bg-background\",\n  {\n    variants: {\n      size: {\n        sm: \"[--grid-toolbar-height:2rem] pointer-coarse:[--grid-toolbar-height:2.5rem]\",\n        default:\n          \"[--grid-toolbar-height:2.25rem] pointer-coarse:[--grid-toolbar-height:2.75rem]\",\n      },\n    },\n    defaultVariants: { size: \"default\" },\n  },\n)\n\ntype GridToolbarProps = React.ComponentProps<\"div\"> &\n  VariantProps<typeof gridToolbarVariants> & {\n    /**\n     * 外框：单独使用时整条带边框；放进表格等已有边线的容器时设为 false，由容器画线\n     * @default true\n     */\n    bordered?: boolean\n  }\n\n/**\n * 网格工具栏：一行格子，格子之间用虚线分隔，窄容器里自动换行，换行后横线照样接上。\n * 方条输入（bar-field）、分段选择（segmented-control）、方条下拉（bar-select）放进来时\n * 会自动去掉自己的外框、圆角和底色，铺满整格。\n */\nfunction GridToolbar({\n  className,\n  size,\n  bordered = true,\n  children,\n  ...props\n}: GridToolbarProps) {\n  return (\n    <div\n      data-slot=\"grid-toolbar\"\n      data-bordered={bordered ? \"\" : undefined}\n      className={cn(\n        gridToolbarVariants({ size }),\n        bordered && \"border border-edge\",\n        className,\n      )}\n      {...props}\n    >\n      {/*\n        每一格都画左线和上线，内层整体往左上挪 1px，由外层 overflow-hidden 裁掉最左一列和最上一行的线。\n        这样无论怎样换行，格子之间都只有一条线，外圈的线交给外框（或容器）。\n      */}\n      <div\n        data-slot=\"grid-toolbar-content\"\n        className=\"-ms-px -mt-px flex flex-wrap\"\n      >\n        {children}\n      </div>\n    </div>\n  )\n}\n\ntype GridToolbarItemProps = React.ComponentProps<\"div\"> & {\n  /**\n   * 占满剩余宽度（如搜索框）\n   * @default false\n   */\n  grow?: boolean\n  /**\n   * 这一格左侧的分隔线：同一组内用虚线；`solid` 表示从这一格开始是新的一组\n   * @default \"dashed\"\n   */\n  separator?: \"dashed\" | \"solid\"\n  /**\n   * 容器窄于 40rem 时独占一行（如搜索框）；后面的格子自动换到下一行，\n   * 带 `grow` 的格子在下一行平分宽度。宽容器里不受影响\n   * @default false\n   */\n  fullOnNarrow?: boolean\n}\n\n/**\n * 工具栏里的一格：高度跟随工具栏，里面的控件铺满整格。\n * 直接放进来的官方 `Button` 也会自动变成方形的格子（铺满高度、无圆角、焦点环在格内），不用再手写类名。\n */\nfunction GridToolbarItem({\n  className,\n  grow = false,\n  separator = \"dashed\",\n  fullOnNarrow = false,\n  ...props\n}: GridToolbarItemProps) {\n  return (\n    <div\n      data-slot=\"grid-toolbar-item\"\n      data-separator={separator}\n      className={cn(\n        \"flex h-(--grid-toolbar-height) min-w-0 items-stretch border-s border-t border-edge *:min-w-0\",\n        // 上线（换行后的横线）始终是虚线；左线按分组取虚线或实线\n        \"[border-top-style:dashed]\",\n        separator === \"solid\"\n          ? \"[border-inline-start-style:solid]\"\n          : \"[border-inline-start-style:dashed]\",\n        grow ? \"flex-1\" : \"shrink-0\",\n        // 按钮格：和方条控件一样去掉圆角、铺满整格；grow 的格子里按钮拉伸占满\n        \"*:data-[slot=button]:h-full *:data-[slot=button]:rounded-none *:data-[slot=button]:focus-visible:ring-inset\",\n        grow && \"*:data-[slot=button]:flex-1\",\n        // 窄容器独占一行：basis 取整行，后面的格子装不下就换行\n        fullOnNarrow && \"@max-[40rem]/grid-toolbar:basis-full\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { GridToolbar, GridToolbarItem, gridToolbarVariants }\nexport type { GridToolbarProps, GridToolbarItemProps }\n",
      "type": "registry:ui",
      "target": "@ui/grid-toolbar/grid-toolbar.tsx"
    }
  ],
  "cssVars": {
    "theme": {
      "color-edge": "var(--edge)"
    },
    "light": {
      "edge": "color-mix(in oklch, var(--foreground) 12%, transparent)"
    },
    "dark": {
      "edge": "color-mix(in oklch, var(--foreground) 18%, transparent)"
    }
  },
  "type": "registry:ui"
}
