{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "figure",
  "type": "registry:ui",
  "title": "Figure",
  "description": "Self-contained, referenced content — an image, diagram, code block, or quotation — wrapped in a native <figure> whose <figcaption> supplies its accessible name. Distinct from a Card's generic surface: a figure stands apart from the main flow and can be moved without breaking it, and its caption is semantically tied to the content. Built on native <figure> + <figcaption>, zero JavaScript.",
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/ui/figure.tsx",
      "type": "registry:ui",
      "target": "components/ui/figure.tsx",
      "content": "/** @jsxImportSource hono/jsx */\nimport type { Child, PropsWithChildren } from \"hono/jsx\"\nimport { cn, type ClassValue } from \"@/registry/lib/cn\"\n\n// Figure — shadcn-htmx, htmx v4 + Tailwind v4.\n//\n// Self-contained captioned content — an image, diagram, code block, or\n// quotation — wrapped in a native <figure> whose <figcaption> supplies the\n// figure's accessible name. Unlike <Card> (a generic styled surface),\n// <Figure> is *referential*: it stands apart from the main flow and can be\n// moved elsewhere without breaking it, and the caption is semantically tied\n// to the content. No interactivity, no JavaScript.\n//\n// Built on (native elements; we add nothing the platform doesn't ship):\n//   - <figure> — represents self-contained content, optionally captioned;\n//     the figure, its caption, and its contents are one unit. Implicit ARIA\n//     role \"figure\".\n//       repos/mdn/files/en-us/web/html/reference/elements/figure/index.md\n//   - <figcaption> — caption/legend for the parent <figure>; provides the\n//     <figure> its accessible name. Must be the figure's first or last child\n//     (the first <figcaption> found is presented as the caption).\n//       repos/mdn/files/en-us/web/html/reference/elements/figcaption/index.md\n//\n// Anatomy mirrors shadcn's Card family (read for intent only, not copied —\n// different element, different semantics):\n//   repos/shadcn-ui/apps/v4/registry/new-york-v4/ui/card.tsx\n//\n// Theme tokens only: border / bg-card / text-card-foreground for the surface,\n// text-muted-foreground for the caption, bg-muted for plain content slots.\n\n// Where the caption sits relative to the content. Both are valid per the\n// spec (first OR last child); we render the <figcaption> in the chosen DOM\n// position so the accessible name is correct either way.\nexport type FigureCaptionSide = \"top\" | \"bottom\"\n\ntype FigureProps = PropsWithChildren<{\n  class?: ClassValue\n  id?: string\n  // Caption position. \"bottom\" (default) reads as a credit/label under the\n  // content; \"top\" reads as a legend introducing it (common for code blocks\n  // and quotations). See the MDN figure examples.\n  captionSide?: FigureCaptionSide\n  // Forward hx-*, data-*, aria-* and standard global attributes onto the\n  // <figure> root.\n  [key: string]: unknown\n}>\n\n// Surface: a bordered card-like box. We keep it visually distinct from the\n// document body but lighter than a full Card (no shadow) so it reads as\n// \"referenced content\", not a UI panel. Caption position is purely a matter\n// of DOM order (figcaption first vs last) — both are spec-valid — so it needs\n// no extra class; the column flow handles either. `data-caption-side` records\n// the author's intent for styling hooks / tests.\nconst root =\n  \"flex flex-col gap-3 overflow-hidden rounded-lg border bg-card p-3 text-card-foreground\"\n\nexport function Figure(props: FigureProps) {\n  const {\n    class: className,\n    id,\n    captionSide = \"bottom\",\n    children,\n    ...rest\n  } = props\n\n  return (\n    <figure\n      id={id}\n      data-slot=\"figure\"\n      data-caption-side={captionSide}\n      class={cn(root, className)}\n      {...rest}\n    >\n      {children}\n    </figure>\n  )\n}\n\n// The content slot — image, code block, quote, diagram. Optional thin wrapper\n// that gives non-replaced content (code, quotes) a muted backdrop and rounds\n// it to match the surface. For a bare <img> you can skip this and put the\n// image directly in <Figure>.\nexport function FigureContent(\n  props: PropsWithChildren<{ class?: ClassValue }>,\n) {\n  return (\n    <div\n      data-slot=\"figure-content\"\n      class={cn(\n        \"overflow-hidden rounded-md bg-muted text-sm text-foreground\",\n        props.class,\n      )}\n    >\n      {props.children}\n    </div>\n  )\n}\n\n// The caption — renders a native <figcaption>, which gives the parent\n// <figure> its accessible name. Keep it concise; it is the figure's label,\n// not its body. Use <FigureCredit> inside for a secondary line (source,\n// author) styled lighter.\nexport function FigureCaption(\n  props: PropsWithChildren<{ class?: ClassValue; id?: string }>,\n) {\n  return (\n    <figcaption\n      id={props.id}\n      data-slot=\"figure-caption\"\n      class={cn(\n        \"px-1 text-sm leading-snug text-muted-foreground\",\n        props.class,\n      )}\n    >\n      {props.children}\n    </figcaption>\n  )\n}\n\n// Optional secondary line inside a caption (attribution / source / date),\n// rendered a touch smaller. Purely presentational; stays inside <figcaption>\n// so it remains part of the accessible name.\nexport function FigureCredit(\n  props: PropsWithChildren<{ class?: ClassValue }>,\n) {\n  return (\n    <span\n      data-slot=\"figure-credit\"\n      class={cn(\"mt-1 block text-xs text-muted-foreground/80\", props.class)}\n    >\n      {props.children}\n    </span>\n  )\n}\n\nexport type { FigureProps }\nexport type FigureChild = Child\n"
    },
    {
      "path": "registry/jinja2/figure.html",
      "type": "registry:file",
      "target": "templates/components/figure.html",
      "content": "{# Figure macros — shadcn-htmx, htmx v4 + Tailwind v4.\n   Mirrors registry/ui/figure.tsx.\n\n   Self-contained captioned content (image, diagram, code, quote) in a native\n   <figure>; the <figcaption> supplies the figure's accessible name. Zero JS.\n     MDN figure:     repos/mdn/files/en-us/web/html/reference/elements/figure/index.md\n     MDN figcaption: repos/mdn/files/en-us/web/html/reference/elements/figcaption/index.md\n\n   The <figcaption> must be the figure's first or last child; choose\n   caption_side accordingly and put the figure_caption(...) call in that DOM\n   position yourself (this mirrors how the .tsx renders children in order).\n\n   Usage:\n     {% from \"components/figure.html\" import figure, figure_content,\n        figure_caption, figure_credit %}\n\n     {% call figure(caption_side=\"bottom\") %}\n       <img src=\"/elephant.jpg\" alt=\"An elephant at sunset\" class=\"w-full rounded-md\">\n       {% call figure_caption() %}An elephant at sunset{% endcall %}\n     {% endcall %} #}\n\n{% macro figure(caption_side=\"bottom\", id=none, extra_class=\"\", **attrs) -%}\n<figure\n  {%- if id %} id=\"{{ id }}\"{% endif %}\n  data-slot=\"figure\"\n  data-caption-side=\"{{ caption_side }}\"\n  class=\"flex flex-col gap-3 overflow-hidden rounded-lg border bg-card p-3 text-card-foreground {{ extra_class }}\"\n  {%- for k, v in attrs.items() %} {{ k|replace('_','-') }}=\"{{ v }}\"{% endfor %}>{{ caller() }}</figure>\n{%- endmacro %}\n\n{% macro figure_content(extra_class=\"\") -%}\n<div data-slot=\"figure-content\" class=\"overflow-hidden rounded-md bg-muted text-sm text-foreground {{ extra_class }}\">{{ caller() }}</div>\n{%- endmacro %}\n\n{% macro figure_caption(id=none, extra_class=\"\") -%}\n<figcaption {% if id %}id=\"{{ id }}\" {% endif %}data-slot=\"figure-caption\" class=\"px-1 text-sm leading-snug text-muted-foreground {{ extra_class }}\">{{ caller() }}</figcaption>\n{%- endmacro %}\n\n{% macro figure_credit(extra_class=\"\") -%}\n<span data-slot=\"figure-credit\" class=\"mt-1 block text-xs text-muted-foreground/80 {{ extra_class }}\">{{ caller() }}</span>\n{%- endmacro %}\n"
    },
    {
      "path": "registry/go-templates/figure.tmpl",
      "type": "registry:file",
      "target": "components/figure.tmpl",
      "content": "{{/*\n  Figure template — shadcn-htmx, htmx v4 + Tailwind v4.\n  Mirrors registry/ui/figure.tsx.\n\n  Self-contained captioned content (image, diagram, code, quote) in a native\n  <figure>; the <figcaption> supplies the figure's accessible name. Zero JS.\n    MDN figure:     repos/mdn/files/en-us/web/html/reference/elements/figure/index.md\n    MDN figcaption: repos/mdn/files/en-us/web/html/reference/elements/figcaption/index.md\n\n  The <figcaption> must be the figure's first or last child. The \"figure\"\n  template renders Caption first when CaptionSide == \"top\", otherwise last,\n  matching the .tsx DOM order. Compose the inner content/caption yourself via\n  the helper templates if you need finer control.\n\n      type FigureArgs struct {\n          CaptionSide string        // \"bottom\" (default) | \"top\"\n          ID          string\n          Class       string\n          Caption     template.HTML // <figcaption> inner HTML\n          Body        template.HTML // content (img / code block / quote …)\n      }\n*/}}\n\n{{define \"figure-caption\"}}\n{{- $id := .ID -}}\n<figcaption {{if $id}}id=\"{{$id}}\" {{end}}data-slot=\"figure-caption\" class=\"px-1 text-sm leading-snug text-muted-foreground {{.Class}}\">{{htmlSafe .Body}}</figcaption>\n{{end}}\n\n{{define \"figure-content\"}}\n<div data-slot=\"figure-content\" class=\"overflow-hidden rounded-md bg-muted text-sm text-foreground {{.Class}}\">{{htmlSafe .Body}}</div>\n{{end}}\n\n{{define \"figure-credit\"}}\n<span data-slot=\"figure-credit\" class=\"mt-1 block text-xs text-muted-foreground/80 {{.Class}}\">{{htmlSafe .Body}}</span>\n{{end}}\n\n{{define \"figure\"}}\n{{- $side := or .CaptionSide \"bottom\" -}}\n<figure {{if .ID}}id=\"{{.ID}}\" {{end}}data-slot=\"figure\" data-caption-side=\"{{$side}}\" class=\"flex flex-col gap-3 overflow-hidden rounded-lg border bg-card p-3 text-card-foreground {{.Class}}\">\n{{- if eq $side \"top\" -}}\n{{- if .Caption}}<figcaption data-slot=\"figure-caption\" class=\"px-1 text-sm leading-snug text-muted-foreground\">{{htmlSafe .Caption}}</figcaption>{{end -}}\n{{- htmlSafe .Body -}}\n{{- else -}}\n{{- htmlSafe .Body -}}\n{{- if .Caption}}<figcaption data-slot=\"figure-caption\" class=\"px-1 text-sm leading-snug text-muted-foreground\">{{htmlSafe .Caption}}</figcaption>{{end -}}\n{{- end -}}\n</figure>\n{{end}}\n"
    },
    {
      "path": "registry/phoenix/figure.ex",
      "type": "registry:file",
      "target": "lib/my_app_web/components/figure.ex",
      "content": "defmodule ShadcnHtmx.Components.Figure do\n  @moduledoc \"\"\"\n  Figure — shadcn-htmx, htmx v4 + Tailwind v4 for Phoenix.\n\n  Mirrors registry/ui/figure.tsx. Self-contained captioned content (image,\n  diagram, code block, quotation) in a native `<figure>`; the `<figcaption>`\n  supplies the figure's accessible name. No JavaScript.\n\n    MDN figure:     repos/mdn/files/en-us/web/html/reference/elements/figure/index.md\n    MDN figcaption: repos/mdn/files/en-us/web/html/reference/elements/figcaption/index.md\n\n  The `<figcaption>` must be the figure's first or last child. Pass\n  `caption_side=\"top\"` to render the caption above the content (legend),\n  otherwise it renders below (credit/label).\n\n  ## Examples\n\n      <.figure>\n        <img src=\"/elephant.jpg\" alt=\"An elephant at sunset\" class=\"w-full rounded-md\" />\n        <.figure_caption>An elephant at sunset</.figure_caption>\n      </.figure>\n\n      <.figure caption_side=\"top\">\n        <.figure_caption>\n          Get browser details <.figure_credit>via navigator</.figure_credit>\n        </.figure_caption>\n        <.figure_content>\n          <pre class=\"overflow-x-auto p-4\"><code>navigator.userAgent</code></pre>\n        </.figure_content>\n      </.figure>\n  \"\"\"\n\n  use Phoenix.Component\n\n  attr :caption_side, :string, default: \"bottom\", values: ~w(top bottom)\n  attr :class, :string, default: nil\n  attr :rest, :global\n  slot :inner_block, required: true\n\n  def figure(assigns) do\n    ~H\"\"\"\n    <figure\n      data-slot=\"figure\"\n      data-caption-side={@caption_side}\n      class={[\n        \"flex flex-col gap-3 overflow-hidden rounded-lg border bg-card p-3 text-card-foreground\",\n        @class\n      ]}\n      {@rest}\n    >\n      {render_slot(@inner_block)}\n    </figure>\n    \"\"\"\n  end\n\n  attr :class, :string, default: nil\n  slot :inner_block, required: true\n\n  def figure_content(assigns) do\n    ~H\"\"\"\n    <div\n      data-slot=\"figure-content\"\n      class={[\"overflow-hidden rounded-md bg-muted text-sm text-foreground\", @class]}\n    >\n      {render_slot(@inner_block)}\n    </div>\n    \"\"\"\n  end\n\n  attr :id, :string, default: nil\n  attr :class, :string, default: nil\n  slot :inner_block, required: true\n\n  def figure_caption(assigns) do\n    ~H\"\"\"\n    <figcaption\n      id={@id}\n      data-slot=\"figure-caption\"\n      class={[\"px-1 text-sm leading-snug text-muted-foreground\", @class]}\n    >\n      {render_slot(@inner_block)}\n    </figcaption>\n    \"\"\"\n  end\n\n  attr :class, :string, default: nil\n  slot :inner_block, required: true\n\n  def figure_credit(assigns) do\n    ~H\"\"\"\n    <span\n      data-slot=\"figure-credit\"\n      class={[\"mt-1 block text-xs text-muted-foreground/80\", @class]}\n    >\n      {render_slot(@inner_block)}\n    </span>\n    \"\"\"\n  end\nend\n"
    },
    {
      "path": "registry/html/figure.html",
      "type": "registry:file",
      "target": "snippets/figure.html",
      "content": "<!--\n  shadcn-htmx — raw HTML figure snippets.\n  Mirrors registry/ui/figure.tsx.\n\n  Self-contained captioned content (image, diagram, code, quote) in a native\n  <figure>; the <figcaption> gives the <figure> its accessible name. The\n  caption must be the figure's first or last child. Zero JavaScript —\n  Tailwind theme tokens only.\n\n    MDN figure:     repos/mdn/files/en-us/web/html/reference/elements/figure/index.md\n    MDN figcaption: repos/mdn/files/en-us/web/html/reference/elements/figcaption/index.md\n\n  ROOT:\n    flex flex-col gap-3 overflow-hidden rounded-lg border bg-card p-3 text-card-foreground\n  data-caption-side=\"top\" | \"bottom\" records where the figcaption sits.\n-->\n\n<!-- Image with a caption below (the common case) -->\n<figure data-slot=\"figure\" data-caption-side=\"bottom\"\n        class=\"flex flex-col gap-3 overflow-hidden rounded-lg border bg-card p-3 text-card-foreground\">\n  <img src=\"/elephant.jpg\" alt=\"An elephant at sunset\"\n       class=\"w-full rounded-md\">\n  <figcaption data-slot=\"figure-caption\"\n              class=\"px-1 text-sm leading-snug text-muted-foreground\">\n    An elephant at sunset\n    <span data-slot=\"figure-credit\" class=\"mt-1 block text-xs text-muted-foreground/80\">\n      Photo: J. Doe / CC BY 4.0\n    </span>\n  </figcaption>\n</figure>\n\n<!-- Code block with a legend on top -->\n<figure data-slot=\"figure\" data-caption-side=\"top\"\n        class=\"flex flex-col gap-3 overflow-hidden rounded-lg border bg-card p-3 text-card-foreground\">\n  <figcaption data-slot=\"figure-caption\"\n              class=\"px-1 text-sm leading-snug text-muted-foreground\">\n    Get browser details using <code>navigator</code>.\n  </figcaption>\n  <div data-slot=\"figure-content\"\n       class=\"overflow-hidden rounded-md bg-muted text-sm text-foreground\">\n    <pre class=\"overflow-x-auto p-4\"><code>console.log(navigator.userAgent);</code></pre>\n  </div>\n</figure>\n\n<!-- Quotation: blockquote content, attribution in the caption -->\n<figure data-slot=\"figure\" data-caption-side=\"bottom\"\n        class=\"flex flex-col gap-3 overflow-hidden rounded-lg border bg-card p-3 text-card-foreground\">\n  <div data-slot=\"figure-content\"\n       class=\"overflow-hidden rounded-md bg-muted text-sm text-foreground\">\n    <blockquote class=\"border-l-2 border-border px-4 py-3 italic\">\n      If debugging is the process of removing software bugs, then programming\n      must be the process of putting them in.\n    </blockquote>\n  </div>\n  <figcaption data-slot=\"figure-caption\"\n              class=\"px-1 text-sm leading-snug text-muted-foreground\">\n    — Edsger W. Dijkstra\n  </figcaption>\n</figure>\n"
    }
  ]
}
