{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "token-input",
  "title": "Token Input",
  "description": "Tokens pop into the field as you add them, and the remove buttons press in.",
  "dependencies": [
    "@ui-sdk/core@0.1.0-beta.2",
    "@ui-sdk/react@0.1.0-beta.2"
  ],
  "registryDependencies": [
    "@keyframery/motion"
  ],
  "files": [
    {
      "path": "registry/components/keyframery/primitives/token-input.tsx",
      "content": "\"use client\"\n\n/* Animated drop-in for `@ui-sdk/react/token-input`: same parts, same props. Swap the import and keep your code.\n   This file adds motion only. Colours, radii, shadows and spacing stay yours.\n\n   - Token: pops in when added (scale 0.4 to 1 on `ease-pop`, with a short blur).\n   - Token remove: Press. */\n\nimport {\n  TokenInputToken as TokenInputTokenPart,\n  TokenInputTokenRemove as TokenInputTokenRemovePart,\n} from \"@ui-sdk/react/token-input\"\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport * from \"@ui-sdk/react/token-input\"\n\nfunction TokenInputToken({ className, ...props }: React.ComponentProps<typeof TokenInputTokenPart>) {\n  return (\n    <TokenInputTokenPart\n      className={cn(\n        \"inline-block origin-center motion-reduce:transition-none! transition-[scale,opacity,filter] duration-[calc(420ms*var(--kf-speed,1))] ease-pop\",\n        \"starting:scale-[0.4] starting:opacity-0 starting:blur-[3px]\",\n        \"motion-reduce:transition-none!\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction TokenInputTokenRemove({ className, ...props }: React.ComponentProps<typeof TokenInputTokenRemovePart>) {\n  return (\n    <TokenInputTokenRemovePart\n      className={cn(\n        \"transition-[scale,color,background-color] duration-[calc(200ms*var(--kf-speed,1))] ease-pop active:scale-[0.8] motion-reduce:transition-none!\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { TokenInputToken, TokenInputTokenRemove }\n",
      "type": "registry:component",
      "target": "components/keyframery/primitives/token-input.tsx"
    },
    {
      "path": "registry/components/keyframery/token-input.tsx",
      "content": "\"use client\"\n\n/* Styled token input: the animated primitive plus the Keyframery look. */\n\nimport {\n  TokenInput as TokenInputRoot,\n  TokenInputEditor as TokenInputEditorPart,\n  TokenInputToken as TokenInputTokenPart,\n  TokenInputTokenRemove as TokenInputTokenRemovePart,\n  createTokenInputController,\n  defaultCodec,\n  fromText,\n  toLabel,\n  toText,\n  type Token,\n} from \"@/components/keyframery/primitives/token-input\"\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction XIcon() {\n  return (\n    <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n      <path d=\"m4.5 4.5 7 7m0-7-7 7\" />\n    </svg>\n  )\n}\n\n/* Without a renderToken of its own, each token is a small key with its label and an x. */\nfunction defaultRenderToken(token: Token) {\n  return (\n    <TokenInputToken>\n      {token.label}\n      <TokenInputTokenRemove />\n    </TokenInputToken>\n  )\n}\n\n/* Renders no element of its own. */\nfunction TokenInput({\n  renderToken = defaultRenderToken,\n  ...props\n}: React.ComponentProps<typeof TokenInputRoot>) {\n  return <TokenInputRoot renderToken={renderToken} {...props} />\n}\n\n/* The field: text and tokens wrap inside one box that grows with them. */\nfunction TokenInputEditor({\n  className,\n  ...props\n}: React.ComponentProps<typeof TokenInputEditorPart>) {\n  return (\n    <TokenInputEditorPart\n      className={cn(\n        \"relative min-h-9 w-full min-w-0 cursor-text rounded-[10px] bg-background px-2 py-[5px] text-[13px] leading-[26px] break-words whitespace-pre-wrap text-foreground outline-none\",\n        \"[--field-line:rgb(0_0_0/0.09)] dark:[--field-line:rgb(255_255_255/0.1)]\",\n        \"shadow-[0_0_0_1px_var(--field-line),0_1px_2px_rgb(0_0_0/0.05)] dark:shadow-[0_0_0_1px_var(--field-line)]\",\n        \"transition-[box-shadow] duration-[calc(150ms*var(--kf-speed,1))] ease-house motion-reduce:transition-none!\",\n        \"hover:[--field-line:rgb(0_0_0/0.16)] dark:hover:[--field-line:rgb(255_255_255/0.18)]\",\n        \"focus-visible:ring-[3px] focus-visible:ring-ring/25 focus-visible:[--field-line:var(--ring)] dark:focus-visible:[--field-line:var(--ring)]\",\n        \"aria-invalid:ring-destructive/25 aria-invalid:[--field-line:var(--destructive)] dark:aria-invalid:[--field-line:var(--destructive)]\",\n        \"data-empty:before:pointer-events-none data-empty:before:absolute data-empty:before:text-muted-foreground data-empty:before:content-[attr(aria-placeholder)]\",\n        \"data-readonly:bg-muted/50\",\n        \"data-disabled:cursor-not-allowed data-disabled:bg-muted data-disabled:text-muted-foreground data-disabled:[--field-line:rgb(0_0_0/0.06)] dark:data-disabled:[--field-line:rgb(255_255_255/0.06)]\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* A token is a small key; the primitive pops it in when it is added. */\nfunction TokenInputToken({\n  className,\n  ...props\n}: React.ComponentProps<typeof TokenInputTokenPart>) {\n  return (\n    <TokenInputTokenPart\n      className={cn(\n        \"mx-[2px] inline-flex h-[22px] max-w-full items-center gap-1 rounded-[7px] bg-background pr-0.5 pl-2 align-middle text-[12px] leading-none font-medium whitespace-nowrap text-foreground select-none\",\n        \"shadow-[0_0_0_1px_rgb(0_0_0/0.06),0_1px_1px_rgb(0_0_0/0.05),0_3px_6px_-2px_rgb(0_0_0/0.1)]\",\n        \"dark:bg-accent dark:shadow-[0_0_0_1px_rgb(255_255_255/0.07),inset_0_1px_0_rgb(255_255_255/0.08),0_2px_6px_-1px_rgb(0_0_0/0.6)]\",\n        \"[&>svg]:size-3.5 [&>svg]:shrink-0 [&>svg]:text-muted-foreground\",\n        /* Selected for removal or in the selection. */\n        \"data-selected:bg-primary data-selected:text-primary-foreground data-selected:[&>svg]:text-primary-foreground/70\",\n        \"data-selected:shadow-[inset_0_1px_0_rgb(255_255_255/0.14),0_1px_2px_rgb(0_0_0/0.25)]\",\n        /* Loading. */\n        \"data-pending:opacity-60\",\n        /* Needs the user, like an address that doesn't look right. */\n        \"data-unresolved:bg-destructive/10 data-unresolved:text-destructive data-unresolved:shadow-[0_0_0_1px_color-mix(in_oklab,var(--destructive)_35%,transparent)] dark:data-unresolved:bg-destructive/15\",\n        \"data-disabled:opacity-60\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction TokenInputTokenRemove({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof TokenInputTokenRemovePart>) {\n  return (\n    <TokenInputTokenRemovePart\n      className={cn(\n        \"grid size-[18px] cursor-pointer place-items-center rounded-[5px] text-muted-foreground\",\n        \"hover:bg-foreground/[0.08] hover:text-foreground\",\n        \"in-data-selected:text-primary-foreground/70 in-data-selected:hover:bg-primary-foreground/15 in-data-selected:hover:text-primary-foreground\",\n        \"data-disabled:pointer-events-none data-disabled:opacity-40 data-readonly:hidden\",\n        \"[&_svg]:size-3\",\n        className,\n      )}\n      {...props}\n    >\n      {children ?? <XIcon />}\n    </TokenInputTokenRemovePart>\n  )\n}\n\nexport {\n  createTokenInputController,\n  defaultCodec,\n  fromText,\n  toLabel,\n  TokenInput,\n  TokenInputEditor,\n  TokenInputToken,\n  TokenInputTokenRemove,\n  toText,\n}\n",
      "type": "registry:component",
      "target": "components/keyframery/token-input.tsx"
    }
  ],
  "type": "registry:component"
}