{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "icon-tile",
  "title": "Icon Tile",
  "author": "@fma-ui/ui",
  "description": "A square surface that gives icons a consistent footprint. `variant`: `outline` (bordered), `elevated` (raised chip), `soft` (tinted double container), `solid` (filled) or `frame` (double container matching `Card`); `soft` and `solid` follow `currentColor`, so a text color class retints them. `size` goes from `xs` to `xl`; `radius` is `default` (clamped to the tile) or `full` (circular). Renders a `<span>`; wrap it in a `Button` or `Link` to make it interactive.",
  "dependencies": [
    "class-variance-authority@^0.7.1",
    "cn@^0.4.0"
  ],
  "files": [
    {
      "path": "src/core/icon-tile/icon-tile.tsx",
      "content": "import { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"cn\";\nimport type * as React from \"react\";\n\n/**\n * The root owns four variables so every part of the tile stays in proportion\n * and is overridable from `className`:\n *\n *   --icon-tile-size       tile width/height\n *   --icon-tile-icon-size  glyph size applied to child svgs\n *   --icon-tile-radius     corner radius (also drives the nested inner card)\n *   --icon-tile-inset      gap between the outer ring and the inner card\n *\n * `frame` and `soft` paint their inner card with an `::after` pseudo element\n * instead of a wrapper node: `isolate` makes the root a stacking context, so\n * the negative z-index pseudo paints above the root background but below the\n * icon.\n *\n * `soft` and `solid` derive their fills from `currentColor` (default\n * `text-primary`), so a single text color class retints the whole tile.\n */\nconst iconTileVariants = cva(\n  [\n    \"relative inline-flex shrink-0 items-center justify-center align-middle\",\n    \"size-(--icon-tile-size) rounded-(--icon-tile-radius)\",\n    \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=size-])]:size-(--icon-tile-icon-size)\",\n  ],\n  {\n    variants: {\n      variant: {\n        /** Plain bordered surface. The quiet default for list rows and toolbars. */\n        outline: \"border border-border bg-background dark:bg-input/32\",\n        /** Raised muted fill with a background-colored ring. Reads as a physical chip. */\n        elevated:\n          \"border-2 border-background bg-muted text-accent-foreground shadow-[0_1px_3px_0_rgb(0_0_0/0.14)] dark:border\",\n        /** Tinted ring around a bordered inner card, all from `currentColor`. */\n        soft: [\n          \"isolate bg-current/10 p-(--icon-tile-inset) text-primary\",\n          \"after:absolute after:inset-(--icon-tile-inset) after:-z-10\",\n          \"after:rounded-[calc(var(--icon-tile-radius)-var(--icon-tile-inset))]\",\n          \"after:border after:border-current/20 after:bg-current/5\",\n        ],\n        /** Filled tone with a contrasting glyph. Retint with `bg-*` and a text color. */\n        solid: \"bg-primary text-primary-foreground\",\n        /** A muted ring around an inset card, matching `Card`. */\n        frame: [\n          \"isolate border border-border bg-muted/50 p-(--icon-tile-inset)\",\n          \"after:absolute after:inset-(--icon-tile-inset) after:-z-10\",\n          \"after:rounded-[calc(var(--icon-tile-radius)-var(--icon-tile-inset))]\",\n          \"after:border after:border-border after:bg-card after:shadow-xs\",\n        ],\n      },\n      size: {\n        xs: \"[--icon-tile-icon-size:--spacing(3.5)] [--icon-tile-inset:--spacing(0.5)] [--icon-tile-size:--spacing(6)]\",\n        sm: \"[--icon-tile-icon-size:--spacing(4)] [--icon-tile-inset:--spacing(0.5)] [--icon-tile-size:--spacing(8)]\",\n        default:\n          \"[--icon-tile-icon-size:--spacing(4.5)] [--icon-tile-inset:--spacing(0.75)] [--icon-tile-size:--spacing(10)]\",\n        lg: \"[--icon-tile-icon-size:--spacing(5.5)] [--icon-tile-inset:--spacing(0.75)] [--icon-tile-size:--spacing(12)]\",\n        xl: \"[--icon-tile-icon-size:--spacing(7)] [--icon-tile-inset:--spacing(1)] [--icon-tile-size:--spacing(14)]\",\n      },\n      radius: {\n        // Clamped to a third of the tile, so small tiles keep their corner\n        // ratio instead of turning into circles (which is what `full` is for).\n        default: \"[--icon-tile-radius:min(var(--radius-md),calc(var(--icon-tile-size)/3))]\",\n        full: \"[--icon-tile-radius:calc(infinity*1px)]\",\n      },\n    },\n    defaultVariants: {\n      variant: \"outline\",\n      size: \"default\",\n      radius: \"default\",\n    },\n  },\n);\n\ntype IconTileProps = React.ComponentProps<\"span\"> & VariantProps<typeof iconTileVariants>;\n\nfunction IconTile({\n  className,\n  variant = \"outline\",\n  size = \"default\",\n  radius = \"default\",\n  ...props\n}: IconTileProps) {\n  return (\n    <span\n      data-slot=\"icon-tile\"\n      data-variant={variant}\n      data-size={size}\n      className={cn(iconTileVariants({ variant, size, radius }), className)}\n      {...props}\n    />\n  );\n}\n\nexport type { IconTileProps };\nexport { IconTile, iconTileVariants };\n",
      "type": "registry:component",
      "target": "components/fma-ui/icon-tile.tsx"
    }
  ],
  "meta": {
    "status": "stable",
    "source": "third-party",
    "origin": "reui.io (https://reui.io/docs/components/base/icon-tile, MIT), via EMITTE",
    "tags": [
      "data-display",
      "icon",
      "surface"
    ]
  },
  "categories": [
    "data-display"
  ],
  "type": "registry:ui"
}