{"_id":"@ainative/aikit-react","_rev":"3-b457d54c672fc3e19ed5f2e18817c129","name":"@ainative/aikit-react","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@ainative/aikit-react","version":"0.1.0","keywords":["react","ai","streaming","markdown","components"],"author":{"name":"AINative"},"license":"MIT","_id":"@ainative/aikit-react@0.1.0","maintainers":[{"name":"ainative-studio","email":"toby@rely.ventures"}],"homepage":"https://ainative.studio/ai-kit","bugs":{"url":"https://github.com/AINative-Studio/ai-kit/issues"},"dist":{"shasum":"547dcf4a9146d3815821eec45ed7484c75223171","tarball":"https://registry.npmjs.org/@ainative/aikit-react/-/aikit-react-0.1.0.tgz","fileCount":27,"integrity":"sha512-VZduQvVJuw989x/+K879GHPEkE2VkSZ01C+JFQ8k/yUvyCzRHZSSl/1VeTjxdvW9JPh3Mj9neNit2Kng8IFVxg==","signatures":[{"sig":"MEYCIQCYYRm5bCZjPjLqSbIDUYXW6kqgpnWyt+lqBx+E+2sI7wIhAITo5ootXowAbiAGyCmKkaWIYzea1JJkF7GxEmiv2OI6","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":178335},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.esm.js","gitHead":"aeb438a1de158c08236f70513886068a808483f6","scripts":{"lint":"eslint src --ext .ts,.tsx","test":"jest","build":"rollup -c","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"ainative-studio","email":"toby@rely.ventures"},"repository":{"url":"git+https://github.com/AINative-Studio/ai-kit.git","type":"git","directory":"packages/react"},"_npmVersion":"10.9.4","description":"React components for AI-powered streaming interfaces","directories":{},"_nodeVersion":"22.21.0","dependencies":{"remark-gfm":"^4.0.0","react-markdown":"^9.0.1","react-syntax-highlighter":"^15.5.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","react":"^18.2.0","eslint":"^8.56.0","rollup":"^4.9.1","react-dom":"^18.2.0","typescript":"^5.3.3","@types/jest":"^29.5.11","@types/react":"^18.2.45","@types/react-dom":"^18.2.18","eslint-plugin-react":"^7.33.2","@testing-library/react":"^14.1.2","jest-environment-jsdom":"^29.7.0","@testing-library/jest-dom":"^6.1.5","@typescript-eslint/parser":"^6.15.0","eslint-plugin-react-hooks":"^4.6.0","rollup-plugin-typescript2":"^0.36.0","@testing-library/user-event":"^14.5.1","@types/react-syntax-highlighter":"^15.5.11","@typescript-eslint/eslint-plugin":"^6.15.0"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/aikit-react_0.1.0_1765569245307_0.7252730870740056","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@ainative/aikit-react","version":"0.2.0","keywords":["react","ai","streaming","markdown","components"],"author":{"name":"AINative"},"license":"MIT","_id":"@ainative/aikit-react@0.2.0","maintainers":[{"name":"ainative-studio","email":"toby@rely.ventures"}],"homepage":"https://ainative.studio/ai-kit","bugs":{"url":"https://github.com/AINative-Studio/ai-kit/issues"},"dist":{"shasum":"8760a4ebeb97b12384db487ed829c47c76a5d00f","tarball":"https://registry.npmjs.org/@ainative/aikit-react/-/aikit-react-0.2.0.tgz","fileCount":27,"integrity":"sha512-GuZq/JWjiFnNgK+570XOTY4bOeRC1HiHjnAQMzHaQzJcP8ec05KcWbGYzGGFGdXOcNnKuQSjB0lr8/bWHQ1Wkw==","signatures":[{"sig":"MEUCIQCgeLoqiM1vc92VNM8IrDqKAKULhQUTKDthYqKqBBuwDgIgKspxe38HNdlEPo5Q3yqrIS9Ur8503S5d7wrbK420KHk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":178335},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.esm.js","gitHead":"3a886abb850118fe80590af91d22d98cd6c47a4e","scripts":{"lint":"eslint src --ext .ts,.tsx","test":"jest","build":"rollup -c","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"ainative-studio","email":"toby@rely.ventures"},"repository":{"url":"git+https://github.com/AINative-Studio/ai-kit.git","type":"git","directory":"packages/react"},"_npmVersion":"10.9.4","description":"React components for AI-powered streaming interfaces","directories":{},"_nodeVersion":"22.21.0","dependencies":{"remark-gfm":"^4.0.0","react-markdown":"^9.0.1","react-syntax-highlighter":"^16.1.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","react":"^18.2.0","eslint":"^8.56.0","rollup":"^4.9.1","react-dom":"^18.2.0","typescript":"^5.3.3","@types/jest":"^29.5.11","@types/react":"^18.2.45","@types/react-dom":"^18.2.18","eslint-plugin-react":"^7.33.2","@testing-library/react":"^14.1.2","jest-environment-jsdom":"^29.7.0","@testing-library/jest-dom":"^6.1.5","@typescript-eslint/parser":"^6.15.0","eslint-plugin-react-hooks":"^4.6.0","rollup-plugin-typescript2":"^0.36.0","@testing-library/user-event":"^14.5.1","@types/react-syntax-highlighter":"^15.5.11","@typescript-eslint/eslint-plugin":"^6.15.0"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/aikit-react_0.2.0_1779041318678_0.875546590861763","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@ainative/aikit-react","version":"0.3.0","description":"React components for AI-powered streaming interfaces","main":"dist/index.js","module":"dist/index.esm.js","types":"dist/index.d.ts","scripts":{"build":"rollup -c","test":"jest","test:watch":"jest --watch","test:coverage":"jest --coverage","lint":"eslint src --ext .ts,.tsx","typecheck":"tsc --noEmit"},"keywords":["react","ai","streaming","markdown","components"],"author":{"name":"AINative"},"license":"MIT","homepage":"https://ainative.studio/ai-kit","repository":{"type":"git","url":"git+https://github.com/AINative-Studio/ai-kit.git","directory":"packages/react"},"bugs":{"url":"https://github.com/AINative-Studio/ai-kit/issues"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0"},"dependencies":{"react-markdown":"^9.0.1","react-syntax-highlighter":"^16.1.0","remark-gfm":"^4.0.0"},"devDependencies":{"@testing-library/jest-dom":"^6.1.5","@testing-library/react":"^14.1.2","@testing-library/user-event":"^14.5.1","@types/jest":"^29.5.11","@types/react":"^18.2.45","@types/react-dom":"^18.2.18","@types/react-syntax-highlighter":"^15.5.11","@typescript-eslint/eslint-plugin":"^6.15.0","@typescript-eslint/parser":"^6.15.0","eslint":"^8.56.0","eslint-plugin-react":"^7.33.2","eslint-plugin-react-hooks":"^4.6.0","jest":"^29.7.0","jest-environment-jsdom":"^29.7.0","react":"^18.2.0","react-dom":"^18.2.0","rollup":"^4.9.1","rollup-plugin-typescript2":"^0.36.0","typescript":"^5.3.3"},"_id":"@ainative/aikit-react@0.3.0","gitHead":"00e69898b568831654464de9f83a9c505650ca64","_nodeVersion":"22.21.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-sSvDMcm6g7ax0fKG/1Nu25jo1YfhVywuRferzQ/Rr08Wv/PUGCCPubWAt0IwTPM+Pu6r4ciCQQRwp/nddAauXQ==","shasum":"691620ca16ae989bfa5fb5d1d5767e66a0ca7de2","tarball":"https://registry.npmjs.org/@ainative/aikit-react/-/aikit-react-0.3.0.tgz","fileCount":30,"unpackedSize":234292,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD/vf8tE0IX8G+deu2ihvIIBD732MRwc9xocoXLMpYFkgIgYs9LCipVFKYwMlT1hqFtTR2Os5OGY3H9qPFWDjgLMXs="}]},"_npmUser":{"name":"ainative-studio","email":"toby@rely.ventures"},"directories":{},"maintainers":[{"name":"ainative-studio","email":"toby@rely.ventures"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/aikit-react_0.3.0_1779061503779_0.5584889487526847"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-12T19:54:05.244Z","modified":"2026-05-17T23:45:04.111Z","0.1.0":"2025-12-12T19:54:05.456Z","0.2.0":"2026-05-17T18:08:38.824Z","0.3.0":"2026-05-17T23:45:03.976Z"},"bugs":{"url":"https://github.com/AINative-Studio/ai-kit/issues"},"author":{"name":"AINative"},"license":"MIT","homepage":"https://ainative.studio/ai-kit","keywords":["react","ai","streaming","markdown","components"],"repository":{"type":"git","url":"git+https://github.com/AINative-Studio/ai-kit.git","directory":"packages/react"},"description":"React components for AI-powered streaming interfaces","maintainers":[{"name":"ainative-studio","email":"toby@rely.ventures"}],"readme":"# @aikit/react\n\nReact components for building AI-powered streaming interfaces with smooth animations and markdown support.\n\n## Features\n\n- **Streaming Message Component**: Display AI messages with real-time streaming support\n- **Token-by-Token Animations**: Smooth typewriter and fade-in effects for new tokens\n- **Markdown Rendering**: Full markdown support with GFM (GitHub Flavored Markdown)\n- **Syntax Highlighting**: Beautiful code blocks with multiple themes\n- **Accessible**: WCAG 2.1 AA compliant with proper ARIA attributes\n- **Responsive**: Mobile-first design that works on all screen sizes\n- **TypeScript**: Fully typed with comprehensive TypeScript definitions\n- **Customizable**: Extensive props for styling and behavior customization\n\n## Installation\n\n```bash\nnpm install @aikit/react\n```\n\nOr with yarn:\n\n```bash\nyarn add @aikit/react\n```\n\n## Peer Dependencies\n\nThis package requires React 18+ as a peer dependency:\n\n```bash\nnpm install react react-dom\n```\n\n## Quick Start\n\n```tsx\nimport { StreamingMessage } from '@aikit/react';\n\nfunction ChatInterface() {\n  const [message, setMessage] = useState('');\n\n  return (\n    <StreamingMessage\n      role=\"assistant\"\n      content={message}\n      streamingState=\"streaming\"\n      enableMarkdown={true}\n      animationType=\"typewriter\"\n    />\n  );\n}\n```\n\n## Components\n\n### StreamingMessage\n\nThe main component for displaying AI messages with streaming support.\n\n#### Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `role` | `'user' \\| 'assistant' \\| 'system'` | **Required** | Message sender role |\n| `content` | `string` | **Required** | Message content (can be partial during streaming) |\n| `streamingState` | `'idle' \\| 'streaming' \\| 'complete' \\| 'error'` | `'idle'` | Current streaming state |\n| `animationType` | `'none' \\| 'fade' \\| 'typewriter' \\| 'smooth'` | `'smooth'` | Animation type for new tokens |\n| `animationSpeed` | `number` | `30` | Animation speed in ms per character |\n| `enableMarkdown` | `boolean` | `true` | Enable markdown rendering |\n| `codeTheme` | `'dark' \\| 'light' \\| 'vs-dark' \\| 'github' \\| 'monokai' \\| 'nord' \\| 'dracula'` | `'dark'` | Code syntax highlighting theme |\n| `showStreamingIndicator` | `boolean` | `true` | Show streaming indicator |\n| `className` | `string` | `''` | Custom CSS class |\n| `style` | `CSSProperties` | - | Custom inline styles |\n| `avatar` | `string \\| ReactNode` | - | Avatar URL or custom element |\n| `displayName` | `string` | - | Display name for message sender |\n| `showTimestamp` | `boolean` | `false` | Show message timestamp |\n| `metadata` | `MessageMetadata` | - | Additional message metadata |\n| `onStreamingComplete` | `() => void` | - | Callback when streaming completes |\n| `onContentUpdate` | `(content: string) => void` | - | Callback on content updates |\n| `onError` | `(error: Error) => void` | - | Error handler |\n| `enableCodeCopy` | `boolean` | `true` | Enable copy button for code blocks |\n| `roleColors` | `object` | - | Custom colors for each role |\n| `testId` | `string` | `'streaming-message'` | Test ID for testing |\n\n#### Examples\n\n**Basic Usage**\n\n```tsx\n<StreamingMessage\n  role=\"assistant\"\n  content=\"Hello! How can I help you today?\"\n  streamingState=\"complete\"\n/>\n```\n\n**With Streaming Animation**\n\n```tsx\n<StreamingMessage\n  role=\"assistant\"\n  content={streamingContent}\n  streamingState=\"streaming\"\n  animationType=\"typewriter\"\n  animationSpeed={20}\n  showStreamingIndicator={true}\n/>\n```\n\n**With Markdown and Code Highlighting**\n\n```tsx\n<StreamingMessage\n  role=\"assistant\"\n  content={`\n# Code Example\n\nHere's a JavaScript function:\n\n\\`\\`\\`javascript\nfunction greet(name) {\n  return \\`Hello, \\${name}!\\`;\n}\n\\`\\`\\`\n  `}\n  enableMarkdown={true}\n  codeTheme=\"dracula\"\n  enableCodeCopy={true}\n/>\n```\n\n**With Avatar and Metadata**\n\n```tsx\n<StreamingMessage\n  role=\"assistant\"\n  content=\"Processing your request...\"\n  avatar=\"https://example.com/bot-avatar.png\"\n  displayName=\"AI Assistant\"\n  showTimestamp={true}\n  metadata={{\n    timestamp: new Date(),\n    model: 'gpt-4',\n    tokensUsed: 150\n  }}\n/>\n```\n\n**With Custom Styling**\n\n```tsx\n<StreamingMessage\n  role=\"user\"\n  content=\"What's the weather like?\"\n  className=\"custom-message\"\n  style={{ maxWidth: '600px' }}\n  roleColors={{\n    user: '#2196F3',\n    assistant: '#4CAF50',\n    system: '#FF9800'\n  }}\n/>\n```\n\n**With Callbacks**\n\n```tsx\n<StreamingMessage\n  role=\"assistant\"\n  content={content}\n  streamingState={streamingState}\n  onStreamingComplete={() => {\n    console.log('Streaming completed!');\n    saveMessage();\n  }}\n  onContentUpdate={(newContent) => {\n    console.log('Content updated:', newContent);\n  }}\n  onError={(error) => {\n    console.error('Streaming error:', error);\n    handleError(error);\n  }}\n/>\n```\n\n### StreamingIndicator\n\nAnimated indicator for showing streaming progress.\n\n#### Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `variant` | `'dots' \\| 'pulse' \\| 'wave'` | `'dots'` | Indicator style variant |\n| `className` | `string` | `''` | Custom CSS class |\n| `style` | `CSSProperties` | - | Custom inline styles |\n| `testId` | `string` | `'streaming-indicator'` | Test ID for testing |\n\n#### Examples\n\n```tsx\nimport { StreamingIndicator } from '@aikit/react';\n\n// Dots variant (default)\n<StreamingIndicator variant=\"dots\" />\n\n// Pulse variant\n<StreamingIndicator variant=\"pulse\" />\n\n// Wave variant\n<StreamingIndicator variant=\"wave\" />\n\n// With custom styling\n<StreamingIndicator\n  variant=\"dots\"\n  style={{ color: '#3b82f6' }}\n/>\n```\n\n### CodeBlock\n\nSyntax-highlighted code block with copy functionality.\n\n#### Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `language` | `string` | **Required** | Programming language |\n| `children` | `string` | **Required** | Code content |\n| `theme` | `CodeTheme` | `'dark'` | Syntax highlighting theme |\n| `enableCopy` | `boolean` | `true` | Enable copy button |\n| `className` | `string` | `''` | Custom CSS class |\n| `showLineNumbers` | `boolean` | `true` | Show line numbers |\n\n#### Examples\n\n```tsx\nimport { CodeBlock } from '@aikit/react';\n\n// JavaScript code\n<CodeBlock language=\"javascript\">\n  {`function hello() {\n    return \"world\";\n  }`}\n</CodeBlock>\n\n// Python with custom theme\n<CodeBlock language=\"python\" theme=\"monokai\">\n  {`def greet(name):\n    return f\"Hello, {name}!\"`}\n</CodeBlock>\n\n// Without copy button\n<CodeBlock language=\"typescript\" enableCopy={false}>\n  {`const x: number = 42;`}\n</CodeBlock>\n```\n\n## Advanced Usage\n\n### Building a Chat Interface\n\n```tsx\nimport { useState, useEffect } from 'react';\nimport { StreamingMessage } from '@aikit/react';\n\ninterface ChatMessage {\n  id: string;\n  role: 'user' | 'assistant';\n  content: string;\n  streaming?: boolean;\n}\n\nfunction ChatInterface() {\n  const [messages, setMessages] = useState<ChatMessage[]>([]);\n  const [streamingContent, setStreamingContent] = useState('');\n\n  const handleSendMessage = async (text: string) => {\n    // Add user message\n    const userMessage: ChatMessage = {\n      id: Date.now().toString(),\n      role: 'user',\n      content: text,\n    };\n    setMessages(prev => [...prev, userMessage]);\n\n    // Start streaming assistant response\n    const assistantMessage: ChatMessage = {\n      id: (Date.now() + 1).toString(),\n      role: 'assistant',\n      content: '',\n      streaming: true,\n    };\n    setMessages(prev => [...prev, assistantMessage]);\n\n    // Simulate streaming\n    const fullResponse = await fetchAIResponse(text);\n    for (let i = 0; i < fullResponse.length; i++) {\n      setStreamingContent(fullResponse.slice(0, i + 1));\n      await new Promise(resolve => setTimeout(resolve, 20));\n    }\n\n    // Complete streaming\n    setMessages(prev =>\n      prev.map(msg =>\n        msg.id === assistantMessage.id\n          ? { ...msg, content: fullResponse, streaming: false }\n          : msg\n      )\n    );\n  };\n\n  return (\n    <div className=\"chat-container\">\n      {messages.map(message => (\n        <StreamingMessage\n          key={message.id}\n          role={message.role}\n          content={message.streaming ? streamingContent : message.content}\n          streamingState={message.streaming ? 'streaming' : 'complete'}\n          enableMarkdown={true}\n          animationType=\"typewriter\"\n          showTimestamp={true}\n          metadata={{\n            timestamp: new Date(),\n          }}\n        />\n      ))}\n    </div>\n  );\n}\n```\n\n### Custom Animation Timing\n\n```tsx\n<StreamingMessage\n  role=\"assistant\"\n  content={content}\n  streamingState=\"streaming\"\n  animationType=\"typewriter\"\n  animationSpeed={15} // Faster animation (15ms per character)\n/>\n```\n\n### Handling Different Message Types\n\n```tsx\nfunction MessageRenderer({ message }) {\n  const getAnimationType = (role) => {\n    switch (role) {\n      case 'user':\n        return 'none'; // No animation for user messages\n      case 'assistant':\n        return 'typewriter'; // Typewriter for AI responses\n      case 'system':\n        return 'fade'; // Fade for system messages\n      default:\n        return 'smooth';\n    }\n  };\n\n  return (\n    <StreamingMessage\n      role={message.role}\n      content={message.content}\n      streamingState={message.streamingState}\n      animationType={getAnimationType(message.role)}\n      roleColors={{\n        user: '#3b82f6',\n        assistant: '#10b981',\n        system: '#f59e0b',\n      }}\n    />\n  );\n}\n```\n\n## TypeScript Support\n\nAll components are fully typed with TypeScript. Import types as needed:\n\n```tsx\nimport type {\n  StreamingMessageProps,\n  MessageRole,\n  StreamingState,\n  AnimationType,\n  CodeTheme,\n  MessageMetadata,\n} from '@aikit/react';\n```\n\n## Accessibility\n\nAll components follow WCAG 2.1 AA guidelines:\n\n- Proper ARIA attributes for screen readers\n- Keyboard navigation support\n- Sufficient color contrast ratios\n- Descriptive labels for interactive elements\n- Status indicators for streaming states\n\n## Browser Support\n\n- Chrome/Edge: Last 2 versions\n- Firefox: Last 2 versions\n- Safari: Last 2 versions\n- Mobile browsers: iOS Safari 12+, Chrome Android\n\n## Testing\n\nComponents are tested with React Testing Library:\n\n```bash\nnpm test\nnpm run test:coverage\n```\n\nCoverage threshold: 80%+ for all metrics.\n\n## Contributing\n\nContributions are welcome! Please read our contributing guidelines before submitting PRs.\n\n## License\n\nMIT\n\n## Support\n\nFor issues and questions, please visit our GitHub repository or contact support.\n","readmeFilename":"README.md"}