{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "delete-row",
  "type": "registry:ui",
  "title": "Delete Row",
  "description": "A row/item delete affordance that confirms, sends DELETE, then fades out in place. One inherited declaration on the list host (hx-confirm:inherited / hx-target:inherited / hx-swap:inherited) covers every row, so each Delete button only needs hx-delete — no per-row wiring and no client-side list state. The server replies 200 with an empty body and the row simply disappears after a CSS opacity fade. Zero custom JS.",
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/ui/delete-row.tsx",
      "type": "registry:ui",
      "target": "components/ui/delete-row.tsx",
      "content": "/** @jsxImportSource hono/jsx */\nimport type { PropsWithChildren } from \"hono/jsx\"\nimport { cn, type ClassValue } from \"@/registry/lib/cn\"\nimport { buttonClasses, type ButtonVariant, type ButtonSize } from \"@/registry/ui/button\"\n\n// Delete Row — shadcn-htmx, htmx v4 + Tailwind v4.\n//\n// A row/item delete affordance that confirms, sends DELETE, then fades out\n// in place. One inherited declaration on the list host covers every row —\n// no per-row wiring, no client-side list state. The server answers the\n// DELETE with a 200 and an empty body, so the row is swapped with nothing\n// and simply disappears.\n//\n// Built on:\n//   repos/htmx/www/src/content/patterns/03-records/02-delete-in-place.md\n//     The canonical pattern: the <tbody> hoists hx-confirm / hx-target /\n//     hx-swap with the :inherited modifier; each Delete button only needs\n//     hx-delete. During the swap delay htmx adds the htmx-swapping class to\n//     the target row, which we use to drive a CSS opacity fade.\n//   repos/htmx/www/src/content/docs/03-features/08-attribute-inheritance.md:10,29-32\n//     htmx v4 inheritance is explicit — hoist an attribute to an ancestor\n//     with the `:inherited` modifier (e.g. hx-confirm:inherited).\n//   repos/htmx/www/src/content/reference/01-attributes/05-hx-delete.md:25-29\n//     Respond to DELETE with a 200 + empty body to remove the element (a\n//     204 performs no swap).\n//   repos/htmx/www/src/content/reference/01-attributes/08-hx-target.md\n//     hx-target=\"closest tr\" targets the row containing the button.\n//   repos/htmx/www/src/content/reference/01-attributes/07-hx-swap.md:211\n//     hx-swap=\"outerHTML swap:Nms\" delays the removal by N ms, giving the\n//     fade transition time to play before the node is detached.\n//   repos/htmx/www/src/content/reference/01-attributes/22-hx-confirm.md\n//     hx-confirm prompts with window.confirm before issuing the request.\n//   repos/htmx/src/htmx.js:1304,1394\n//     htmx adds `htmx-swapping` to the target before the swap delay and\n//     removes it after the swap — the hook our fade keys off.\n//\n// Native semantics:\n//   - The list host is a real <tbody> (default) so the rows live in a valid\n//     table model and AT users get row/column navigation for free.\n//     repos/mdn/files/en-us/web/html/reference/elements/tbody/index.md\n//   - The delete affordance is a real <button>, so Enter / Space activation\n//     and focus come from the platform; no role/tabindex needed.\n//     repos/aria-practices/content/patterns/button/button-pattern.html\n//\n// Style analogues: registry/ui/table.tsx (the row/cell model + transition\n// idiom on <tr>), registry/ui/button.tsx (the affordance classes + the\n// `[&.htmx-request]:…` arbitrary-variant idiom this fade mirrors).\n\n// ── List host ─────────────────────────────────────────────────────────────\n// The inheritance host. It hoists the shared delete behaviour onto every\n// descendant Delete button via htmx's `:inherited` modifier, so a single\n// declaration covers the whole list. Defaults to <tbody>; pass `as=\"ul\"`\n// (etc.) for non-table lists, and set the matching `target` (e.g. \"closest\n// li\").\n\ntype ListTag = \"tbody\" | \"ul\" | \"ol\" | \"div\"\n\ntype DeleteRowListProps = PropsWithChildren<{\n  // Confirmation question shown by the browser before each DELETE fires.\n  // Pass null to skip confirmation entirely.\n  confirm?: string | null\n  // Selector for the element each Delete request removes. Default \"closest\n  // tr\" — change to match `as` (e.g. \"closest li\" for a <ul>).\n  target?: string\n  // Fade duration in ms. Must match the row's CSS transition; both default\n  // to 300ms. This is the htmx swap delay (hx-swap=\"… swap:Nms\").\n  swapMs?: number\n  // Element the host renders as. Default \"tbody\".\n  as?: ListTag\n  class?: ClassValue\n}> &\n  Record<string, any>\n\nexport function DeleteRowList(props: DeleteRowListProps) {\n  const {\n    children,\n    confirm = \"Are you sure you want to delete this?\",\n    target = \"closest tr\",\n    swapMs = 300,\n    as = \"tbody\",\n    class: className,\n    ...rest\n  } = props\n  const Tag: any = as\n\n  return (\n    <Tag\n      data-slot=\"delete-row\"\n      // htmx v4 explicit inheritance: every descendant Delete button picks\n      // up these three attributes, so the per-row markup only needs\n      // hx-delete. One declaration, every row.\n      hx-confirm:inherited={confirm === null ? undefined : confirm}\n      hx-target:inherited={target}\n      hx-swap:inherited={`outerHTML swap:${swapMs}ms`}\n      class={cn(className)}\n      {...rest}\n    >\n      {children}\n    </Tag>\n  )\n}\n\n// ── Row ─────────────────────────────────────────────────────────────────\n// One deletable row. Carries the opacity transition so that when htmx adds\n// `htmx-swapping` during the swap delay, the row fades out before it's\n// detached. Defaults to <tr>; pass `as` to match the list host.\n\ntype RowTag = \"tr\" | \"li\" | \"div\"\n\ntype DeleteRowItemProps = PropsWithChildren<{\n  // Duration of the fade in ms; must equal the host's swapMs. Default 300.\n  swapMs?: number\n  as?: RowTag\n  class?: ClassValue\n}> &\n  Record<string, any>\n\nexport function DeleteRowItem(props: DeleteRowItemProps) {\n  const { children, swapMs = 300, as = \"tr\", class: className, ...rest } = props\n  const Tag: any = as\n\n  return (\n    <Tag\n      data-slot=\"delete-row-item\"\n      // The fade: opacity transitions over the swap delay, and htmx's\n      // `htmx-swapping` class (added to this row for the swap:Nms window)\n      // drives it to 0 before the node is removed. Same arbitrary-variant\n      // idiom as button.tsx's [&.htmx-request]:… hook.\n      style={`transition-duration:${swapMs}ms`}\n      class={cn(\n        \"transition-opacity ease-out [&.htmx-swapping]:opacity-0\",\n        className,\n      )}\n      {...rest}\n    >\n      {children}\n    </Tag>\n  )\n}\n\n// ── Delete affordance ─────────────────────────────────────────────────────\n// The per-row button. It only carries hx-delete — confirm / target / swap\n// are inherited from DeleteRowList. Styled as a ghost button by default so\n// it sits quietly in a cell; pass variant=\"destructive\" for a louder one.\n\ntype DeleteRowProps = PropsWithChildren<{\n  // DELETE endpoint for this row's resource. Respond 200 + empty body.\n  href: string\n  // Button label. Default \"Delete\". Use `ariaLabel` when the visible label\n  // is an icon only.\n  variant?: ButtonVariant\n  size?: ButtonSize\n  ariaLabel?: string\n  ariaLabelledby?: string\n  ariaDescribedby?: string\n  disabled?: boolean\n  class?: ClassValue\n}> &\n  Record<string, any>\n\nexport function DeleteRow(props: DeleteRowProps) {\n  const {\n    children,\n    href,\n    variant = \"ghost\",\n    size = \"sm\",\n    ariaLabel,\n    ariaLabelledby,\n    ariaDescribedby,\n    disabled,\n    class: className,\n    ...rest\n  } = props\n\n  return (\n    <button\n      type=\"button\"\n      data-slot=\"delete-row-trigger\"\n      hx-delete={href}\n      disabled={disabled}\n      aria-label={ariaLabel}\n      aria-labelledby={ariaLabelledby}\n      aria-describedby={ariaDescribedby}\n      class={buttonClasses({\n        variant,\n        size,\n        class: cn(\"text-muted-foreground hover:text-destructive\", className),\n      })}\n      {...rest}\n    >\n      {children ?? \"Delete\"}\n    </button>\n  )\n}\n"
    },
    {
      "path": "registry/jinja2/delete-row.html",
      "type": "registry:file",
      "target": "templates/components/delete-row.html",
      "content": "{# Delete Row macros — shadcn-htmx, htmx v4 + Tailwind v4.\n   Mirrors registry/ui/delete-row.tsx for Python/Flask/FastAPI/Django/Jinja2.\n\n   A row/item delete affordance that confirms, sends DELETE, then fades out\n   in place. One inherited declaration on the list host covers every row —\n   no per-row wiring, no client-side list state. The server answers the\n   DELETE with a 200 and an empty body, so the row is swapped with nothing\n   and simply disappears.\n   See repos/htmx/www/src/content/patterns/03-records/02-delete-in-place.md.\n\n   htmx v4 inheritance is explicit (the `:inherited` modifier), so the host\n   hoists hx-confirm / hx-target / hx-swap to every descendant Delete button:\n   see repos/htmx/www/src/content/docs/03-features/08-attribute-inheritance.md.\n\n   Usage:\n       {% from \"components/delete-row.html\" import delete_row_list, delete_row_item, delete_row %}\n\n       <table class=\"w-full caption-bottom text-sm\">\n         <tbody is not used directly — wrap rows in delete_row_list #}\n         {% call delete_row_list() %}\n           {% call delete_row_item() %}\n             <td>Joe Smith</td>\n             <td class=\"text-right\">{{ delete_row(href=\"/contacts/1\") }}</td>\n           {% endcall %}\n         {% endcall %}\n       </table>\n#}\n\n{# List host — hoists the shared delete behaviour onto every Delete button. #}\n{% macro delete_row_list(confirm=\"Are you sure you want to delete this?\", target=\"closest tr\", swap_ms=300, as=\"tbody\", extra_class=\"\", caller=none) %}\n<{{ as }} data-slot=\"delete-row\"\n   {%- if confirm is not none %} hx-confirm:inherited=\"{{ confirm }}\"{% endif %}\n   hx-target:inherited=\"{{ target }}\" hx-swap:inherited=\"outerHTML swap:{{ swap_ms }}ms\"\n   class=\"{{ extra_class }}\">\n  {%- if caller %}{{ caller() }}{% endif %}\n</{{ as }}>\n{% endmacro %}\n\n{# Row — carries the opacity fade keyed off htmx's `htmx-swapping` class. #}\n{% macro delete_row_item(swap_ms=300, as=\"tr\", extra_class=\"\", caller=none) %}\n<{{ as }} data-slot=\"delete-row-item\" style=\"transition-duration:{{ swap_ms }}ms\"\n   class=\"transition-opacity ease-out [&.htmx-swapping]:opacity-0 {{ extra_class }}\">\n  {%- if caller %}{{ caller() }}{% endif %}\n</{{ as }}>\n{% endmacro %}\n\n{# Delete affordance — only carries hx-delete; the rest is inherited. #}\n{% macro delete_row(href, label=\"Delete\", aria_label=none, disabled=false, extra_class=\"\", attrs={}) %}\n{%- set _btn = \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&.htmx-request]:pointer-events-none [&.htmx-request]:opacity-70 hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5 text-muted-foreground hover:text-destructive\" -%}\n<button type=\"button\" data-slot=\"delete-row-trigger\" hx-delete=\"{{ href }}\"\n        {%- if aria_label %} aria-label=\"{{ aria_label }}\"{% endif %}\n        {%- if disabled %} disabled{% endif %}\n        {%- for k, v in attrs.items() %} {{ k|replace('_','-') }}=\"{{ v }}\"{% endfor %}\n        class=\"{{ _btn }} {{ extra_class }}\">{{ label }}</button>\n{% endmacro %}\n"
    },
    {
      "path": "registry/go-templates/delete-row.tmpl",
      "type": "registry:file",
      "target": "components/delete-row.tmpl",
      "content": "{{/*\n  Delete Row templates — shadcn-htmx, htmx v4 + Tailwind v4.\n  Mirrors registry/ui/delete-row.tsx for Go projects using html/template.\n\n  A row/item delete affordance that confirms, sends DELETE, then fades out\n  in place. One inherited declaration on the list host covers every row —\n  no per-row wiring, no client-side list state. The server answers the\n  DELETE with a 200 and an empty body, so the row is swapped with nothing\n  and simply disappears.\n  See repos/htmx/www/src/content/patterns/03-records/02-delete-in-place.md.\n\n  htmx v4 inheritance is explicit (the `:inherited` modifier), so the host\n  hoists hx-confirm / hx-target / hx-swap to every descendant Delete button:\n  see repos/htmx/www/src/content/docs/03-features/08-attribute-inheritance.md.\n\n  Three templates:\n    - \"delete_row_list\" — the inheritance host (default <tbody>).\n    - \"delete_row_item\" — one deletable row (default <tr>) with the fade.\n    - \"delete_row\"      — the Delete button; only carries hx-delete.\n\n  Args:\n\n      type DeleteRowListArgs struct {\n          Confirm string       // \"\" disables the confirm prompt\n          Target  string       // default \"closest tr\"\n          SwapMs  int          // default 300\n          As      string       // default \"tbody\"\n          Body    template.HTML\n      }\n      type DeleteRowItemArgs struct {\n          SwapMs int           // default 300\n          As     string        // default \"tr\"\n          Body   template.HTML\n      }\n      type DeleteRowArgs struct {\n          Href      string     // DELETE endpoint; respond 200 + empty body\n          Label     string     // default \"Delete\"\n          AriaLabel string\n          Disabled  bool\n      }\n\n  Pass these via a (dict ...) helper and (htmlSafe ...) for the body, e.g.\n\n      {{template \"delete_row_list\" (dict \"Body\" (htmlSafe $rows))}}\n*/}}\n\n{{define \"delete_row_list\"}}\n{{- $confirm := or .Confirm \"Are you sure you want to delete this?\" -}}\n{{- $target := or .Target \"closest tr\" -}}\n{{- $swapMs := or .SwapMs 300 -}}\n{{- $as := or .As \"tbody\" -}}\n<{{$as}} data-slot=\"delete-row\"\n   {{- if .NoConfirm}}{{else}} hx-confirm:inherited=\"{{$confirm}}\"{{end}}\n   hx-target:inherited=\"{{$target}}\" hx-swap:inherited=\"outerHTML swap:{{$swapMs}}ms\">\n  {{- .Body}}\n</{{$as}}>\n{{end}}\n\n{{define \"delete_row_item\"}}\n{{- $swapMs := or .SwapMs 300 -}}\n{{- $as := or .As \"tr\" -}}\n<{{$as}} data-slot=\"delete-row-item\" style=\"transition-duration:{{$swapMs}}ms\"\n   class=\"transition-opacity ease-out [&.htmx-swapping]:opacity-0\">\n  {{- .Body}}\n</{{$as}}>\n{{end}}\n\n{{define \"delete_row\"}}\n{{- $btn := \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&.htmx-request]:pointer-events-none [&.htmx-request]:opacity-70 hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5 text-muted-foreground hover:text-destructive\" -}}\n{{- $label := or .Label \"Delete\" -}}\n<button type=\"button\" data-slot=\"delete-row-trigger\" hx-delete=\"{{.Href}}\"\n        {{- if .AriaLabel}} aria-label=\"{{.AriaLabel}}\"{{end}}\n        {{- if .Disabled}} disabled{{end}}\n        class=\"{{$btn}}\">{{$label}}</button>\n{{end}}\n"
    },
    {
      "path": "registry/phoenix/delete_row.ex",
      "type": "registry:file",
      "target": "lib/my_app_web/components/delete_row.ex",
      "content": "defmodule ShadcnHtmx.Components.DeleteRow do\n  @moduledoc \"\"\"\n  Delete Row — shadcn-htmx, htmx v4 + Tailwind v4 for Phoenix.\n\n  Mirrors registry/ui/delete-row.tsx. A row/item delete affordance that\n  confirms, sends DELETE, then fades out in place. One inherited declaration\n  on the list host covers every row — no per-row wiring, no client-side list\n  state. The server answers the DELETE with a 200 and an empty body, so the\n  row is swapped with nothing and simply disappears.\n  See repos/htmx/www/src/content/patterns/03-records/02-delete-in-place.md.\n\n  htmx v4 inheritance is explicit (the `:inherited` modifier), so the host\n  hoists hx-confirm / hx-target / hx-swap to every descendant Delete button:\n  see repos/htmx/www/src/content/docs/03-features/08-attribute-inheritance.md.\n\n  Three function components:\n    - `delete_row_list/1` — the inheritance host (default <tbody>).\n    - `delete_row_item/1` — one deletable row (default <tr>) with the fade.\n    - `delete_row/1`      — the Delete button; only carries hx-delete.\n\n  ## Examples\n\n      <table class=\"w-full caption-bottom text-sm\">\n        <.delete_row_list>\n          <.delete_row_item>\n            <td>Joe Smith</td>\n            <td class=\"text-right\"><.delete_row href={~p\"/contacts/1\"} /></td>\n          </.delete_row_item>\n        </.delete_row_list>\n      </table>\n  \"\"\"\n\n  use Phoenix.Component\n\n  @btn \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none \" <>\n         \"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 \" <>\n         \"disabled:pointer-events-none disabled:opacity-50 \" <>\n         \"aria-disabled:pointer-events-none aria-disabled:opacity-50 \" <>\n         \"aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 \" <>\n         \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 \" <>\n         \"[&.htmx-request]:pointer-events-none [&.htmx-request]:opacity-70 \" <>\n         \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 \" <>\n         \"h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5 \" <>\n         \"text-muted-foreground hover:text-destructive\"\n\n  attr :confirm, :string,\n    default: \"Are you sure you want to delete this?\",\n    doc: \"Confirm prompt; pass nil to skip confirmation.\"\n\n  attr :target, :string, default: \"closest tr\"\n  attr :swap_ms, :integer, default: 300\n  attr :as, :string, default: \"tbody\"\n  attr :class, :string, default: nil\n  attr :rest, :global\n  slot :inner_block, required: true\n\n  def delete_row_list(assigns) do\n    ~H\"\"\"\n    <.dynamic_tag\n      tag_name={@as}\n      data-slot=\"delete-row\"\n      hx-confirm:inherited={@confirm}\n      hx-target:inherited={@target}\n      hx-swap:inherited={\"outerHTML swap:#{@swap_ms}ms\"}\n      class={@class}\n      {@rest}\n    >\n      {render_slot(@inner_block)}\n    </.dynamic_tag>\n    \"\"\"\n  end\n\n  attr :swap_ms, :integer, default: 300\n  attr :as, :string, default: \"tr\"\n  attr :class, :string, default: nil\n  attr :rest, :global\n  slot :inner_block, required: true\n\n  def delete_row_item(assigns) do\n    ~H\"\"\"\n    <.dynamic_tag\n      tag_name={@as}\n      data-slot=\"delete-row-item\"\n      style={\"transition-duration:#{@swap_ms}ms\"}\n      class={[\"transition-opacity ease-out [&.htmx-swapping]:opacity-0\", @class]}\n      {@rest}\n    >\n      {render_slot(@inner_block)}\n    </.dynamic_tag>\n    \"\"\"\n  end\n\n  attr :href, :string, required: true\n  attr :label, :string, default: \"Delete\"\n  attr :aria_label, :string, default: nil\n  attr :disabled, :boolean, default: false\n  attr :class, :string, default: nil\n  attr :rest, :global, include: ~w(hx-target hx-swap hx-confirm hx-trigger hx-indicator)\n\n  def delete_row(assigns) do\n    assigns = assign(assigns, :btn, @btn)\n\n    ~H\"\"\"\n    <button\n      type=\"button\"\n      data-slot=\"delete-row-trigger\"\n      hx-delete={@href}\n      aria-label={@aria_label}\n      disabled={@disabled}\n      class={[@btn, @class]}\n      {@rest}\n    >\n      {@label}\n    </button>\n    \"\"\"\n  end\nend\n"
    },
    {
      "path": "registry/html/delete-row.html",
      "type": "registry:file",
      "target": "snippets/delete-row.html",
      "content": "<!--\n  shadcn-htmx — raw HTML Delete Row snippet.\n\n  Mirrors registry/ui/delete-row.tsx. Drop onto any page that loads htmx v4\n  + Tailwind CSS v4 and the shadcn theme variables (muted-foreground,\n  destructive, accent, border, ring). Relies only on theme tokens.\n\n  A row/item delete affordance that confirms, sends DELETE, then fades out\n  in place. One inherited declaration on the <tbody> covers every row — no\n  per-row wiring, no client-side list state.\n  See repos/htmx/www/src/content/patterns/03-records/02-delete-in-place.md.\n\n  How it works (all native + htmx, zero custom JS):\n    - The <tbody> hoists three attributes to every descendant Delete button\n      using htmx v4's explicit `:inherited` modifier:\n        hx-confirm:inherited  → window.confirm before each request\n        hx-target:inherited   → \"closest tr\" targets the row to remove\n        hx-swap:inherited     → \"outerHTML swap:300ms\" delays removal 300ms\n    - Each Delete button only carries hx-delete=\"/…\". On click it confirms,\n      sends DELETE, and during the 300ms swap delay htmx adds the\n      `htmx-swapping` class to the row — which drives the CSS opacity fade.\n    - The server responds 200 with an EMPTY body, so the row is replaced\n      with nothing and disappears. (A 204 would skip the swap entirely.)\n-->\n\n<table class=\"w-full caption-bottom text-sm\">\n  <thead class=\"[&_tr]:border-b\">\n    <tr>\n      <th scope=\"col\" class=\"h-10 px-2 text-left align-middle font-medium text-muted-foreground\">Name</th>\n      <th scope=\"col\" class=\"h-10 px-2 text-left align-middle font-medium text-muted-foreground\">Email</th>\n      <th scope=\"col\" class=\"h-10 px-2 text-left align-middle font-medium text-muted-foreground\"><span class=\"sr-only\">Actions</span></th>\n    </tr>\n  </thead>\n\n  <!-- List host: one inherited declaration, every row. -->\n  <tbody data-slot=\"delete-row\"\n         hx-confirm:inherited=\"Are you sure you want to delete this?\"\n         hx-target:inherited=\"closest tr\"\n         hx-swap:inherited=\"outerHTML swap:300ms\"\n         class=\"[&_tr:last-child]:border-0\">\n\n    <!-- Row: fades out via opacity while htmx-swapping is on it. -->\n    <tr data-slot=\"delete-row-item\" style=\"transition-duration:300ms\"\n        class=\"border-b transition-opacity ease-out [&.htmx-swapping]:opacity-0 hover:bg-muted/50\">\n      <td class=\"p-2 align-middle\">Joe Smith</td>\n      <td class=\"p-2 align-middle text-muted-foreground\">joe@smith.org</td>\n      <td class=\"p-2 align-middle text-right\">\n        <button type=\"button\" data-slot=\"delete-row-trigger\" hx-delete=\"/contacts/1\"\n                class=\"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&.htmx-request]:pointer-events-none [&.htmx-request]:opacity-70 hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5 text-muted-foreground hover:text-destructive\">Delete</button>\n      </td>\n    </tr>\n\n    <tr data-slot=\"delete-row-item\" style=\"transition-duration:300ms\"\n        class=\"border-b transition-opacity ease-out [&.htmx-swapping]:opacity-0 hover:bg-muted/50\">\n      <td class=\"p-2 align-middle\">Angie MacDowell</td>\n      <td class=\"p-2 align-middle text-muted-foreground\">angie@macdowell.org</td>\n      <td class=\"p-2 align-middle text-right\">\n        <button type=\"button\" data-slot=\"delete-row-trigger\" hx-delete=\"/contacts/2\"\n                class=\"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&.htmx-request]:pointer-events-none [&.htmx-request]:opacity-70 hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5 text-muted-foreground hover:text-destructive\">Delete</button>\n      </td>\n    </tr>\n  </tbody>\n</table>\n"
    }
  ]
}
