{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "article-card",
  "type": "registry:ui",
  "title": "Article Card",
  "description": "Prop-driven article preview with author, rating and action affordances.",
  "dependencies": [
    "@mantine/core@^9",
    "@tabler/icons-react@^3"
  ],
  "docs": "Adapted from Mantine UI ArticleCard at ffbf61c559f374a7ea28fcf00355e84dcbe9a908; demo data removed and replaced with typed props.",
  "registryDependencies": [
    "@house/mantine-ui-license"
  ],
  "files": [
    {
      "path": "registry/mantine-ui/article-card/article-card.tsx",
      "type": "registry:ui",
      "content": "/**\n * Adapted from Mantine UI's ArticleCard at\n * ffbf61c559f374a7ea28fcf00355e84dcbe9a908. MIT licensed; see\n * LICENSES/MANTINE-UI.txt after installation.\n */\n\nimport {\n  ActionIcon,\n  Avatar,\n  Badge,\n  type BoxProps,\n  Card,\n  type ElementProps,\n  type Factory,\n  factory,\n  Group,\n  Image,\n  type StylesApiProps,\n  Text,\n  useProps,\n  useStyles,\n} from \"@mantine/core\";\nimport { IconBookmarkFilled, IconHeartFilled, IconShare2 } from \"@tabler/icons-react\";\n\nimport classes from \"./article-card.module.css\";\n\nexport type ArticleCardStylesNames = \"root\" | \"image\" | \"rating\" | \"title\" | \"footer\" | \"action\";\n\nexport interface ArticleCardProps\n  extends BoxProps,\n    StylesApiProps<ArticleCardFactory>,\n    ElementProps<\"div\", \"title\"> {\n  image: string;\n  title: string;\n  description: string;\n  authorName: string;\n  authorAvatar?: string;\n  rating?: string;\n  href: string;\n  onLike?: () => void;\n  onBookmark?: () => void;\n  onShare?: () => void;\n}\n\nexport type ArticleCardFactory = Factory<{\n  props: ArticleCardProps;\n  ref: HTMLDivElement;\n  stylesNames: ArticleCardStylesNames;\n}>;\n\nexport const ArticleCard = factory<ArticleCardFactory>((_props) => {\n  const props = useProps(\"ArticleCard\", null, _props);\n  const {\n    classNames,\n    className,\n    style,\n    styles,\n    unstyled,\n    vars,\n    attributes,\n    ref,\n    image,\n    title,\n    description,\n    authorName,\n    authorAvatar,\n    rating,\n    href,\n    onLike,\n    onBookmark,\n    onShare,\n    ...others\n  } = props;\n  const getStyles = useStyles<ArticleCardFactory>({\n    name: \"ArticleCard\",\n    classes,\n    props,\n    className,\n    style,\n    classNames,\n    styles,\n    unstyled,\n    attributes,\n    vars,\n  });\n  const hasActions = Boolean(onLike || onBookmark || onShare);\n\n  return (\n    <Card ref={ref} withBorder radius=\"md\" unstyled={unstyled} {...getStyles(\"root\")} {...others}>\n      <Card.Section component=\"a\" href={href}>\n        <Image src={image} height={180} alt={title} {...getStyles(\"image\")} />\n      </Card.Section>\n\n      {rating && (\n        <Badge\n          {...getStyles(\"rating\")}\n          variant=\"gradient\"\n          gradient={{ from: \"indigo.8\", to: \"violet.8\", deg: 145 }}\n        >\n          {rating}\n        </Badge>\n      )}\n\n      <Text {...getStyles(\"title\")} component=\"a\" href={href}>\n        {title}\n      </Text>\n\n      <Text fz=\"sm\" lineClamp={4} opacity={0.9}>\n        {description}\n      </Text>\n\n      <Group justify=\"space-between\" {...getStyles(\"footer\")}>\n        <Group gap=\"xs\">\n          <Avatar src={authorAvatar} size={24} alt=\"\" />\n          <Text fz=\"sm\">{authorName}</Text>\n        </Group>\n\n        {hasActions && (\n          <Group gap={8}>\n            {onLike && (\n              <ActionIcon\n                variant=\"subtle\"\n                {...getStyles(\"action\")}\n                aria-label=\"Like\"\n                onClick={onLike}\n              >\n                <IconHeartFilled size={16} color=\"var(--mantine-color-red-6)\" />\n              </ActionIcon>\n            )}\n            {onBookmark && (\n              <ActionIcon\n                variant=\"subtle\"\n                {...getStyles(\"action\")}\n                aria-label=\"Bookmark\"\n                onClick={onBookmark}\n              >\n                <IconBookmarkFilled size={16} color=\"var(--mantine-color-yellow-7)\" />\n              </ActionIcon>\n            )}\n            {onShare && (\n              <ActionIcon\n                variant=\"subtle\"\n                {...getStyles(\"action\")}\n                aria-label=\"Share\"\n                onClick={onShare}\n              >\n                <IconShare2 size={16} color=\"var(--mantine-color-cyan-6)\" />\n              </ActionIcon>\n            )}\n          </Group>\n        )}\n      </Group>\n    </Card>\n  );\n});\n\nArticleCard.classes = classes;\nArticleCard.displayName = \"ArticleCard\";\n\nexport namespace ArticleCard {\n  export type Props = ArticleCardProps;\n  export type StylesNames = ArticleCardStylesNames;\n  export type Factory = ArticleCardFactory;\n}\n"
    },
    {
      "path": "registry/mantine-ui/article-card/article-card.module.css",
      "type": "registry:file",
      "target": "@ui/article-card.module.css",
      "content": "/*\n * Adapted from Mantine UI's ArticleCard at\n * ffbf61c559f374a7ea28fcf00355e84dcbe9a908. MIT licensed; see\n * LICENSES/MANTINE-UI.txt after installation.\n */\n.root {\n  position: relative;\n  overflow: visible;\n  background-color: var(--mantine-color-body);\n}\n\n.rating {\n  position: absolute;\n  top: var(--mantine-spacing-xs);\n  right: 12px;\n  pointer-events: none;\n}\n\n.title {\n  display: block;\n  margin-top: var(--mantine-spacing-md);\n  margin-bottom: 7px;\n  color: var(--mantine-color-bright);\n  font-family: var(--mantine-font-family);\n  font-weight: 500;\n}\n\n.image {\n  width: calc(100% + 2px);\n  margin-top: -1px;\n  margin-right: -1px;\n  margin-left: -1px;\n  border-top-left-radius: var(--mantine-radius-md);\n  border-top-right-radius: var(--mantine-radius-md);\n}\n\n.action {\n  background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-5));\n}\n\n.action:hover {\n  background-color: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-6));\n}\n\n.footer {\n  margin-top: var(--mantine-spacing-md);\n}\n"
    }
  ],
  "meta": {
    "mantine": {
      "requires": ">=9",
      "provider": "MantineProvider",
      "stylesApi": {
        "ArticleCard": [
          "root",
          "image",
          "rating",
          "title",
          "footer",
          "action"
        ]
      },
      "props": {
        "ArticleCard": [
          {
            "name": "image",
            "type": "string",
            "required": true,
            "description": "Cover image URL, rendered inside the linked card header."
          },
          {
            "name": "title",
            "type": "string",
            "required": true,
            "description": "Article title; also used as the image alt text and rendered as a link."
          },
          {
            "name": "description",
            "type": "string",
            "required": true,
            "description": "Summary text, clamped to four lines."
          },
          {
            "name": "authorName",
            "type": "string",
            "required": true,
            "description": "Byline shown in the card footer."
          },
          {
            "name": "authorAvatar",
            "type": "string",
            "description": "Avatar image URL for the byline; a placeholder avatar renders when omitted."
          },
          {
            "name": "rating",
            "type": "string",
            "description": "Text for the gradient badge over the image; no badge renders when omitted."
          },
          {
            "name": "href",
            "type": "string",
            "required": true,
            "description": "Destination for the image and title links."
          },
          {
            "name": "onLike",
            "type": "() => void",
            "description": "Renders the like action icon and handles its click."
          },
          {
            "name": "onBookmark",
            "type": "() => void",
            "description": "Renders the bookmark action icon and handles its click."
          },
          {
            "name": "onShare",
            "type": "() => void",
            "description": "Renders the share action icon and handles its click."
          },
          {
            "name": "...others",
            "type": "BoxProps & ElementProps<\"div\", \"title\">",
            "description": "All other props are forwarded to the root Card, after its own withBorder and radius=\"md\", so both can be overridden. Mantine Styles API props (classNames, styles, unstyled) are also accepted."
          }
        ]
      },
      "usage": {
        "path": "registry/mantine-ui/article-card/article-card.usage.tsx",
        "content": "import { ArticleCard } from \"@/components/ui/article-card\";\n\nexport function FeaturedArticle() {\n  return (\n    <ArticleCard\n      image=\"https://images.unsplash.com/photo-1778084356053-40103587d24f?auto=format&fit=crop&w=1080&q=80\"\n      title=\"How resilient teams design for change\"\n      description=\"A field guide to building systems that remain clear, useful, and adaptable as the work evolves.\"\n      authorName=\"Avery Stone\"\n      rating=\"4.9\"\n      href=\"/articles/resilient-teams\"\n      onLike={() => console.log(\"liked\")}\n      onBookmark={() => console.log(\"bookmarked\")}\n      onShare={() => console.log(\"shared\")}\n    />\n  );\n}\n"
      }
    }
  }
}
