{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "icon-tile",
  "title": "Icon Tile",
  "description": "A square tile that gives icons a consistent surface, in outline, elevated, soft, solid and framed styles.",
  "dependencies": [
    "@radix-ui/react-slot",
    "class-variance-authority"
  ],
  "files": [
    {
      "path": "registry/tealmac/icon-tile.tsx",
      "content": "/**\n * Icon Tile - adapted for tealmac UI from ReUI \"icon-tile\"\n * (https://github.com/keenthemes/reui), MIT License, Copyright (c) 2025\n * Keenthemes Inc. The full licence text is in THIRD_PARTY_NOTICES.md.\n * Changes: tealmac UI import paths and theme tokens, one self-contained file,\n * lucide icons, a single style, and neutral demo content.\n */\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\n// Title: Icon Tile\n// Description: Square container that gives icons a consistent surface\n\n/**\n * CSS variable architecture:\n *\n * The root owns four variables so every part of the tile stays in proportion\n * and stays overridable from a single `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 * The `frame` and `soft` variants paint their inner card with an `::after`\n * pseudo element instead of a wrapper node. `isolate` makes the root a stacking\n * context, so the negative z-index pseudo paints above the root background but\n * below the in-flow icon - no extra DOM, and `asChild` composition keeps working.\n *\n * Tone: `soft` and `solid` derive every fill and border from `currentColor`, so\n * a single text color class (e.g. `text-success`) retints the whole tile. They\n * default to `text-primary`; override it to recolor without touching internals.\n */\nconst iconTileVariants = cva(\n  [\n    \"relative inline-flex shrink-0 items-center justify-center align-middle\",\n    \"size-(--icon-tile-size) rounded-[var(--icon-tile-radius,min(var(--radius-md),calc(var(--icon-tile-size)/3)))]\",\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        /**\n         * Tinted double container: an opacity-filled outer ring with no border\n         * around a bordered inner card, all derived from `currentColor`. The\n         * quiet, colorful sibling of `frame`. Retint with a text color class.\n         */\n        soft: [\n          \"isolate p-(--icon-tile-inset) text-primary bg-current/10\",\n          \"after:absolute after:-z-10 after:inset-(--icon-tile-inset)\",\n          \"after:rounded-[calc(var(--icon-tile-radius,min(var(--radius-md),calc(var(--icon-tile-size)/3)))-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-*` + a text color. */\n        solid: \"bg-primary text-primary-foreground\",\n        /** Double container - a muted ring around an inset card, matching Frame. */\n        frame: [\n          \"isolate border border-border bg-muted/50 p-(--icon-tile-inset)\",\n          \"after:absolute after:-z-10 after:inset-(--icon-tile-inset)\",\n          \"after:rounded-[calc(var(--icon-tile-radius,min(var(--radius-md),calc(var(--icon-tile-size)/3)))-var(--icon-tile-inset))]\",\n          \"after:border after:border-border after:bg-card after:shadow-xs\",\n        ],\n      },\n      size: {\n        xs: \"[--icon-tile-size:--spacing(6)] [--icon-tile-icon-size:--spacing(3.5)] [--icon-tile-inset:--spacing(0.5)]\",\n        sm: \"[--icon-tile-size:--spacing(8)] [--icon-tile-icon-size:--spacing(4)] [--icon-tile-inset:--spacing(0.5)]\",\n        default:\n          \"[--icon-tile-size:--spacing(10)] [--icon-tile-icon-size:--spacing(4.5)] [--icon-tile-inset:--spacing(0.75)]\",\n        lg: \"[--icon-tile-size:--spacing(12)] [--icon-tile-icon-size:--spacing(5.5)] [--icon-tile-inset:--spacing(0.75)]\",\n        xl: \"[--icon-tile-size:--spacing(14)] [--icon-tile-icon-size:--spacing(7)] [--icon-tile-inset:--spacing(1)]\",\n      },\n      /**\n       * `default`: active style radius. `full`: circular.\n       * No bare rung beside the ladder: the registry transform writes the\n       * installed style's rung bare, and a second bare rung would leave class\n       * order to pick the winner. The no-style fallback lives in the var()\n       * that reads the radius instead.\n       *\n       * Each style token is clamped to a fraction of the tile. A flat radius\n       * is a circle once it reaches half the box, so the soft styles used to\n       * render `xs` (24px) and `sm` (32px) as plain circles and swallow the\n       * `full` variant's meaning. Clamping keeps one corner ratio at every\n       * size instead, so a tile still reads as the same shape when it scales.\n       * Luma and Rhea take the gentler quarter ratio; Maia stays at a third.\n       */\n      radius: {\n        default:\n          \"[--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\ninterface IconTileProps\n  extends React.ComponentProps<\"span\">, VariantProps<typeof iconTileVariants> {\n  asChild?: boolean\n}\n\nfunction IconTile({\n  className,\n  variant = \"outline\",\n  size = \"default\",\n  radius = \"default\",\n  asChild = false,\n  ...props\n}: IconTileProps) {\n  const Comp = asChild ? Slot : \"span\"\n\n  return (\n    <Comp\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 { IconTile, iconTileVariants, type IconTileProps }\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}