{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "approval",
  "title": "Approval",
  "description": "A card asking to allow a tool call, with its arguments and answer buttons.",
  "dependencies": [
    "@stylexjs/stylex"
  ],
  "registryDependencies": [
    "https://constella.aayush.cv/r/base.json",
    "https://constella.aayush.cv/r/button.json",
    "https://constella.aayush.cv/r/card.json"
  ],
  "files": [
    {
      "path": "src/components/ai/approval.tsx",
      "content": "\"use client\";\n\nimport * as stylex from \"@stylexjs/stylex\";\nimport { createContext, use, useId } from \"react\";\nimport type { ComponentProps } from \"react\";\n\nimport { Button } from \"@/components/primitives/button\";\nimport type { ButtonProps } from \"@/components/primitives/button\";\nimport {\n  Card,\n  CardAction,\n  CardContent,\n  CardFooter,\n  CardHeader,\n  CardTitle,\n} from \"@/components/primitives/card\";\nimport type { Sx } from \"@/lib/constella/styles\";\nimport { colors, lineHeights, space } from \"@/lib/constella/tokens.stylex\";\n\ntype Styled<T> = Omit<T, \"className\" | \"style\"> & {\n  sx?: Sx;\n};\n\nconst TitleId = createContext<string | undefined>(undefined);\n\nconst styles = stylex.create({\n  title: {\n    alignItems: \"start\",\n    display: \"flex\",\n    gap: space.row,\n  },\n  // As tall as the title's line, so the icon centers on it.\n  media: {\n    alignItems: \"center\",\n    display: \"flex\",\n    flexShrink: 0,\n    height: lineHeights.textSm,\n  },\n  fields: {\n    alignItems: \"baseline\",\n    columnGap: space.lg,\n    display: \"grid\",\n    gridTemplateColumns: \"auto minmax(0, 1fr)\",\n    marginBlockEnd: 0,\n    marginBlockStart: 0,\n    rowGap: space.xs,\n  },\n  // The pair is one grid row, not a box of its own.\n  field: {\n    display: \"contents\",\n  },\n  label: {\n    color: colors.textSecondary,\n  },\n  value: {\n    marginInlineStart: 0,\n    overflowWrap: \"anywhere\",\n  },\n  footer: {\n    justifyContent: \"flex-end\",\n  },\n  // Apart from the action: a slip lands on the button that does nothing.\n  cancel: {\n    marginInlineEnd: \"auto\",\n  },\n});\n\n/** A card asking to allow a tool call, named by its title. */\nfunction Approval(\n  props: Omit<ComponentProps<typeof Card>, \"size\" | \"variant\">\n) {\n  const titleId = useId();\n  return (\n    <TitleId value={titleId}>\n      <Card\n        aria-labelledby={titleId}\n        // oxlint-disable-next-line jsx-a11y/prefer-tag-over-role -- Card renders a div; a fieldset would bring its own border and padding\n        role=\"group\"\n        size=\"sm\"\n        {...props}\n      />\n    </TitleId>\n  );\n}\n\nconst ApprovalHeader = CardHeader;\n\n/** What the tool will do (\"Send mail\"), after its media. */\nfunction ApprovalTitle({ sx, ...props }: ComponentProps<typeof CardTitle>) {\n  const titleId = use(TitleId);\n  return <CardTitle {...props} id={titleId} sx={[styles.title, sx]} />;\n}\n\n/** The tool's icon, bare, before the title. */\nfunction ApprovalMedia({ sx, ...props }: Styled<ComponentProps<\"span\">>) {\n  return (\n    <span\n      aria-hidden\n      data-slot=\"approval-media\"\n      {...props}\n      {...stylex.props(styles.media, sx)}\n    />\n  );\n}\n\nconst ApprovalAction = CardAction;\n\nconst ApprovalContent = CardContent;\n\n/** The call's arguments as label and value rows. */\nfunction ApprovalFields({ sx, ...props }: Styled<ComponentProps<\"dl\">>) {\n  return (\n    <dl\n      data-slot=\"approval-fields\"\n      {...props}\n      {...stylex.props(styles.fields, sx)}\n    />\n  );\n}\n\nfunction ApprovalField({ sx, ...props }: Styled<ComponentProps<\"div\">>) {\n  return (\n    <div\n      data-slot=\"approval-field\"\n      {...props}\n      {...stylex.props(styles.field, sx)}\n    />\n  );\n}\n\nfunction ApprovalFieldLabel({ sx, ...props }: Styled<ComponentProps<\"dt\">>) {\n  return (\n    <dt\n      data-slot=\"approval-field-label\"\n      {...props}\n      {...stylex.props(styles.label, sx)}\n    />\n  );\n}\n\nfunction ApprovalFieldValue({ sx, ...props }: Styled<ComponentProps<\"dd\">>) {\n  return (\n    <dd\n      data-slot=\"approval-field-value\"\n      {...props}\n      {...stylex.props(styles.value, sx)}\n    />\n  );\n}\n\n/** The card's answer buttons: `ApprovalCancel` at its start, the action at its end. */\nfunction ApprovalFooter({ sx, ...props }: ComponentProps<typeof CardFooter>) {\n  return <CardFooter {...props} sx={[styles.footer, sx]} />;\n}\n\n/** The outline Cancel button, alone at the footer's start. */\nfunction ApprovalCancel({\n  size = \"sm\",\n  sx,\n  variant = \"outline\",\n  ...props\n}: Omit<ButtonProps, \"render\">) {\n  return (\n    <Button\n      data-slot=\"approval-cancel\"\n      size={size}\n      sx={[styles.cancel, sx]}\n      variant={variant}\n      {...props}\n    />\n  );\n}\n\nexport {\n  Approval,\n  ApprovalAction,\n  ApprovalCancel,\n  ApprovalContent,\n  ApprovalField,\n  ApprovalFieldLabel,\n  ApprovalFieldValue,\n  ApprovalFields,\n  ApprovalFooter,\n  ApprovalHeader,\n  ApprovalMedia,\n  ApprovalTitle,\n};\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:ui"
}