@21st-sdk/react 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { Chat } from "@ai-sdk/react"
2
2
  import { DefaultChatTransport, type UIMessage } from "ai"
3
- import type { CreateAnChatOptions } from "./types"
3
+ import type { CreateAgentChatOptions } from "./types"
4
4
 
5
5
  const DEFAULT_API_URL = "https://relay.an.dev"
6
6
 
@@ -29,8 +29,8 @@ function createTokenFetcher(tokenUrl: string, agent: string) {
29
29
  }
30
30
  }
31
31
 
32
- /** Create an AI SDK Chat instance pointed at the AN Relay API */
33
- export function createAnChat(options: CreateAnChatOptions): Chat<UIMessage> {
32
+ /** Create an AI SDK Chat instance pointed at the relay API */
33
+ export function createAgentChat(options: CreateAgentChatOptions): Chat<UIMessage> {
34
34
  const {
35
35
  agent,
36
36
  tokenUrl,
@@ -44,7 +44,7 @@ export function createAnChat(options: CreateAnChatOptions): Chat<UIMessage> {
44
44
 
45
45
  const getToken = getTokenFn || (tokenUrl ? createTokenFetcher(tokenUrl, agent) : null)
46
46
  if (!getToken) {
47
- throw new Error("createAnChat: provide either tokenUrl or getToken")
47
+ throw new Error("createAgentChat: provide either tokenUrl or getToken")
48
48
  }
49
49
 
50
50
  return new Chat({
@@ -64,3 +64,6 @@ export function createAnChat(options: CreateAnChatOptions): Chat<UIMessage> {
64
64
  onError,
65
65
  })
66
66
  }
67
+
68
+ // Legacy factory alias kept for compatibility.
69
+ export const createAnChat = createAgentChat
package/src/index.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  // Main drop-in component
2
- export { AnAgentChat } from "./an-agent-chat"
2
+ export { AgentChat, AnAgentChat } from "./an-agent-chat"
3
3
 
4
4
  // Chat factory
5
- export { createAnChat } from "./create-an-chat"
5
+ export { createAgentChat, createAnChat } from "./create-an-chat"
6
6
 
7
7
  // Theme
8
8
  export { applyTheme } from "./theme"
@@ -71,11 +71,17 @@ export { FileExtIcon } from "./icons/file-ext-icon"
71
71
  export { PaperclipIcon } from "./icons/shared-icons"
72
72
 
73
73
  // Models
74
- export { AN_CLAUDE_MODELS, AN_DEFAULT_MODEL_ID } from "./models"
75
- export type { AnClaudeModelId } from "./models"
74
+ export { CLAUDE_MODELS, DEFAULT_MODEL_ID, AN_CLAUDE_MODELS, AN_DEFAULT_MODEL_ID } from "./models"
75
+ export type { ClaudeModelId, AnClaudeModelId } from "./models"
76
76
 
77
77
  // Types
78
78
  export type {
79
+ ChatTheme,
80
+ ChatClassNames,
81
+ ChatSlots,
82
+ ModelOption,
83
+ CreateAgentChatOptions,
84
+ AgentChatProps,
79
85
  AnTheme,
80
86
  AnClassNames,
81
87
  AnSlots,
@@ -84,7 +90,7 @@ export type {
84
90
  AnAgentChatProps,
85
91
  CustomToolRendererProps,
86
92
  } from "./types"
87
- export type { AnThemeConfig } from "./theme-config"
93
+ export type { ChatThemeConfig, AnThemeConfig } from "./theme-config"
88
94
  export type { TimelineStep, StepState } from "./types/timeline"
89
95
  export type { ToolSize } from "./types/tool-styles"
90
96
  export type { SourceType } from "./icons/source-icons"
package/src/models.ts CHANGED
@@ -1,14 +1,19 @@
1
- import type { AnModelOption } from "./types"
1
+ import type { ModelOption } from "./types"
2
2
 
3
- /** Claude model IDs supported by the AN relay */
4
- export type AnClaudeModelId = "opus" | "sonnet" | "haiku"
3
+ /** Claude model IDs supported by the relay */
4
+ export type ClaudeModelId = "opus" | "sonnet" | "haiku"
5
5
 
6
- /** Pre-defined Claude models available through AN */
7
- export const AN_CLAUDE_MODELS: AnModelOption[] = [
6
+ /** Pre-defined Claude models available through the relay */
7
+ export const CLAUDE_MODELS: ModelOption[] = [
8
8
  { id: "sonnet", name: "Sonnet", version: "4.6" },
9
9
  { id: "opus", name: "Opus", version: "4.6" },
10
10
  { id: "haiku", name: "Haiku", version: "4.5" },
11
11
  ]
12
12
 
13
13
  /** Default model ID */
14
- export const AN_DEFAULT_MODEL_ID: AnClaudeModelId = "sonnet"
14
+ export const DEFAULT_MODEL_ID: ClaudeModelId = "sonnet"
15
+
16
+ // Legacy model aliases kept for compatibility.
17
+ export type AnClaudeModelId = ClaudeModelId
18
+ export const AN_CLAUDE_MODELS = CLAUDE_MODELS
19
+ export const AN_DEFAULT_MODEL_ID = DEFAULT_MODEL_ID
@@ -1,7 +1,7 @@
1
1
  import React, { createContext, useContext } from "react"
2
- import type { AnTheme } from "./types"
2
+ import type { ChatTheme } from "./types"
3
3
 
4
- export interface AnThemeConfig {
4
+ export interface ChatThemeConfig {
5
5
  messageStyle: "bubble-right" | "full-width"
6
6
  messageDensity: "relaxed" | "compact" | "dense"
7
7
  inputStyle: "rounded" | "flat" | "bordered"
@@ -31,7 +31,10 @@ export interface AnThemeConfig {
31
31
  attachmentPreviewStyle: "thumbnail" | "chip" | "hidden"
32
32
  }
33
33
 
34
- export const DEFAULT_THEME_CONFIG: AnThemeConfig = {
34
+ // Legacy type alias kept for compatibility.
35
+ export type AnThemeConfig = ChatThemeConfig
36
+
37
+ export const DEFAULT_THEME_CONFIG: ChatThemeConfig = {
35
38
  messageStyle: "bubble-right",
36
39
  messageDensity: "relaxed",
37
40
  inputStyle: "bordered",
@@ -95,7 +98,7 @@ function readEnum<T extends string>(
95
98
  return fallback
96
99
  }
97
100
 
98
- export function extractThemeConfig(theme?: AnTheme): AnThemeConfig {
101
+ export function extractThemeConfig(theme?: ChatTheme): ChatThemeConfig {
99
102
  if (!theme?.theme) return DEFAULT_THEME_CONFIG
100
103
  const t = theme.theme
101
104
 
@@ -130,8 +133,8 @@ export function extractThemeConfig(theme?: AnTheme): AnThemeConfig {
130
133
  }
131
134
  }
132
135
 
133
- export const ThemeConfigContext = createContext<AnThemeConfig>(DEFAULT_THEME_CONFIG)
136
+ export const ThemeConfigContext = createContext<ChatThemeConfig>(DEFAULT_THEME_CONFIG)
134
137
 
135
- export function useThemeConfig(): AnThemeConfig {
138
+ export function useThemeConfig(): ChatThemeConfig {
136
139
  return useContext(ThemeConfigContext)
137
140
  }
package/src/theme.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { AnTheme } from "./types"
1
+ import type { ChatTheme } from "./types"
2
2
  import { contrastText } from "./utils/contrast"
3
3
 
4
4
  export type ResolvedColorMode = "light" | "dark"
@@ -16,7 +16,7 @@ export function resolveColorMode(
16
16
  /** Apply theme CSS variables from playground JSON to a DOM element */
17
17
  export function applyTheme(
18
18
  element: HTMLElement,
19
- theme: AnTheme,
19
+ theme: ChatTheme,
20
20
  colorMode: "light" | "dark" | "auto" = "auto",
21
21
  ) {
22
22
  // Apply shared vars
@@ -1,9 +1,9 @@
1
1
  import type { TimelineStep, StepState } from "../types/timeline"
2
2
  import type { ToolSize } from "../types/tool-styles"
3
- import type { AnThemeConfig } from "../theme-config"
3
+ import type { ChatThemeConfig } from "../theme-config"
4
4
  import React from "react"
5
5
 
6
- export function resolveToolSize(config: AnThemeConfig): ToolSize {
6
+ export function resolveToolSize(config: ChatThemeConfig): ToolSize {
7
7
  return config.toolCallStyle === "compact" ? "compact" : "normal"
8
8
  }
9
9
 
@@ -16,7 +16,7 @@ function routeToolCall(
16
16
  step: Extract<TimelineStep, { type: "tool-call" }>,
17
17
  state: StepState,
18
18
  onComplete: () => void,
19
- config: AnThemeConfig,
19
+ config: ChatThemeConfig,
20
20
  actionIndex: number,
21
21
  ): React.ReactNode {
22
22
  // Lazy imports to prevent circular dependency issues
package/src/types.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  import type React from "react"
2
2
  import type { UIMessage, ChatStatus } from "ai"
3
3
 
4
- /** Theme JSON generated by the AN playground */
5
- export interface AnTheme {
4
+ /** Theme JSON generated by the playground */
5
+ export interface ChatTheme {
6
6
  theme: Record<string, string>
7
7
  light: Record<string, string>
8
8
  dark: Record<string, string>
9
9
  }
10
10
 
11
11
  /** Per-element CSS class overrides */
12
- export interface AnClassNames {
12
+ export interface ChatClassNames {
13
13
  root: string
14
14
  messageList: string
15
15
  userMessage: string
@@ -28,7 +28,7 @@ export interface AnClassNames {
28
28
  }
29
29
 
30
30
  /** Component slot overrides */
31
- export interface AnSlots {
31
+ export interface ChatSlots {
32
32
  InputBar: React.ComponentType<any>
33
33
  UserMessage: React.ComponentType<any>
34
34
  AssistantMessage: React.ComponentType<any>
@@ -36,8 +36,8 @@ export interface AnSlots {
36
36
  MessageActions: React.ComponentType<any>
37
37
  }
38
38
 
39
- /** Props for createAnChat() */
40
- export interface CreateAnChatOptions {
39
+ /** Props for createAgentChat() */
40
+ export interface CreateAgentChatOptions {
41
41
  agent: string
42
42
  /** Provide either tokenUrl (simple) or getToken (full control) */
43
43
  tokenUrl?: string
@@ -54,10 +54,10 @@ export interface CreateAnChatOptions {
54
54
  *
55
55
  * @example
56
56
  * // Per-user sandbox
57
- * createAnChat({ agent: "my-agent", tokenUrl: "/api/an/token", sandboxId: `user-${userId}` })
57
+ * createAgentChat({ agent: "my-agent", tokenUrl: "/api/an/token", sandboxId: `user-${userId}` })
58
58
  *
59
59
  * // Continue existing sandbox
60
- * createAnChat({ agent: "my-agent", tokenUrl: "/api/an/token", sandboxId: sandbox.id })
60
+ * createAgentChat({ agent: "my-agent", tokenUrl: "/api/an/token", sandboxId: sandbox.id })
61
61
  */
62
62
  sandboxId?: string
63
63
  /**
@@ -78,25 +78,25 @@ export interface CustomToolRendererProps {
78
78
  }
79
79
 
80
80
  /** A model option for the model selector */
81
- export interface AnModelOption {
81
+ export interface ModelOption {
82
82
  id: string
83
83
  name: string
84
84
  version?: string
85
85
  }
86
86
 
87
- /** Props for the <AnAgentChat> drop-in component */
88
- export interface AnAgentChatProps {
87
+ /** Props for the <AgentChat> drop-in component */
88
+ export interface AgentChatProps {
89
89
  messages: UIMessage[]
90
90
  onSend: (message: { role: "user"; content: string }) => void
91
91
  status: ChatStatus
92
92
  onStop: () => void
93
93
  error?: Error
94
94
 
95
- theme?: AnTheme
95
+ theme?: ChatTheme
96
96
  colorMode?: "light" | "dark" | "auto"
97
97
 
98
- classNames?: Partial<AnClassNames>
99
- slots?: Partial<AnSlots>
98
+ classNames?: Partial<ChatClassNames>
99
+ slots?: Partial<ChatSlots>
100
100
  toolRenderers?: Record<string, React.ComponentType<CustomToolRendererProps>>
101
101
 
102
102
  /** Show window chrome header (traffic lights + agent indicator) */
@@ -104,7 +104,7 @@ export interface AnAgentChatProps {
104
104
 
105
105
  /** Model selector configuration */
106
106
  modelSelector?: {
107
- models: AnModelOption[]
107
+ models: ModelOption[]
108
108
  activeModelId?: string
109
109
  onModelChange?: (id: string) => void
110
110
  display?: "popover" | "badge"
@@ -133,3 +133,11 @@ export interface AnAgentChatProps {
133
133
  className?: string
134
134
  style?: React.CSSProperties
135
135
  }
136
+
137
+ // Legacy type aliases kept for compatibility.
138
+ export type AnTheme = ChatTheme
139
+ export type AnClassNames = ChatClassNames
140
+ export type AnSlots = ChatSlots
141
+ export type CreateAnChatOptions = CreateAgentChatOptions
142
+ export type AnModelOption = ModelOption
143
+ export type AnAgentChatProps = AgentChatProps
@@ -0,0 +1,161 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ /*
6
+ * AN Agent Chat - CSS Custom Properties
7
+ * These are the default values. Consumers override via <AnAgentChat theme={...} />
8
+ * which calls applyTheme() to set these vars on the root element.
9
+ */
10
+ :root, .an-root {
11
+ /* Typography */
12
+ --an-font-family: system-ui, sans-serif;
13
+ --an-text-size: 14px;
14
+ --an-text-size-sm: 13px;
15
+ --an-text-size-xs: 11px;
16
+ --an-line-height: 1.6;
17
+ --an-font-weight: 400;
18
+ --an-font-weight-medium: 500;
19
+ --an-font-weight-semibold: 600;
20
+
21
+ /* Geometry — all radii derive from --an-border-radius */
22
+ --an-border-radius: 16px;
23
+ --an-message-border-radius: var(--an-border-radius);
24
+ --an-input-border-radius: var(--an-border-radius);
25
+ --an-tool-border-radius: var(--an-border-radius);
26
+ --an-code-border-radius: var(--an-border-radius);
27
+
28
+ /* Layout — --an-message-gap is intentionally unset; density config provides the default */
29
+ --an-user-message-padding: 10px 14px;
30
+ --an-input-padding: 12px 16px;
31
+
32
+ /* Sizes */
33
+ --an-send-button-size: 32px;
34
+ --an-stop-button-size: 32px;
35
+ --an-send-button-border-radius: 9999px;
36
+
37
+ /* Colors - Light mode defaults */
38
+ --an-background: #ffffff;
39
+ --an-background-secondary: #f5f5f5;
40
+ --an-background-tertiary: #fafafa;
41
+ --an-foreground: #1a1a1a;
42
+ --an-foreground-muted: #737373;
43
+ --an-foreground-subtle: #a3a3a3;
44
+ --an-border-color: #e5e5e5;
45
+ --an-border-color-light: #f0f0f0;
46
+ --an-primary-color: #3b82f6;
47
+
48
+ /* User Messages */
49
+ --an-user-message-bg: #f5f5f5;
50
+ --an-user-message-text: #1a1a1a;
51
+
52
+ /* Input */
53
+ --an-input-background: #ffffff;
54
+ --an-input-border-color: #e5e5e5;
55
+ --an-input-color: #1a1a1a;
56
+ --an-input-placeholder-color: #a3a3a3;
57
+
58
+ /* Send/Stop Buttons */
59
+ --an-send-button-bg: #3b82f6;
60
+ --an-send-button-color: #ffffff;
61
+ --an-stop-button-bg: #1a1a1a;
62
+ --an-stop-button-color: #ffffff;
63
+
64
+ /* Tools */
65
+ --an-tool-background: #fafafa;
66
+ --an-tool-border-color: #e5e5e5;
67
+ --an-tool-color: #1a1a1a;
68
+ --an-tool-color-muted: #737373;
69
+
70
+ /* Code */
71
+ --an-code-background: #1e1e1e;
72
+ --an-code-color: #d4d4d4;
73
+ --an-code-font-family: ui-monospace, monospace;
74
+ --an-code-font-size: 13px;
75
+
76
+ /* Diff colors */
77
+ --an-diff-added-bg: rgba(34, 197, 94, 0.1);
78
+ --an-diff-added-border: rgba(34, 197, 94, 0.5);
79
+ --an-diff-added-text: #15803d;
80
+ --an-diff-removed-bg: rgba(239, 68, 68, 0.1);
81
+ --an-diff-removed-border: rgba(239, 68, 68, 0.5);
82
+ --an-diff-removed-text: #dc2626;
83
+ }
84
+
85
+ /* Dark mode defaults */
86
+ .dark, .an-root.dark, .dark .an-root {
87
+ --an-background: #0a0a0a;
88
+ --an-background-secondary: #1a1a1a;
89
+ --an-background-tertiary: #141414;
90
+ --an-foreground: #fafafa;
91
+ --an-foreground-muted: #a3a3a3;
92
+ --an-foreground-subtle: #71717a;
93
+ --an-border-color: #2a2a2a;
94
+ --an-border-color-light: #1f1f1f;
95
+ --an-primary-color: #60a5fa;
96
+
97
+ --an-user-message-bg: #1a1a1a;
98
+ --an-user-message-text: #fafafa;
99
+
100
+ --an-input-background: #0a0a0a;
101
+ --an-input-border-color: #2a2a2a;
102
+ --an-input-color: #fafafa;
103
+ --an-input-placeholder-color: #71717a;
104
+
105
+ --an-send-button-bg: #60a5fa;
106
+ --an-send-button-color: #ffffff;
107
+ --an-stop-button-bg: #fafafa;
108
+ --an-stop-button-color: #0a0a0a;
109
+
110
+ --an-tool-background: #141414;
111
+ --an-tool-border-color: #2a2a2a;
112
+ --an-tool-color: #fafafa;
113
+ --an-tool-color-muted: #a3a3a3;
114
+
115
+ --an-code-background: #0a0a0a;
116
+ --an-code-color: #d4d4d4;
117
+
118
+ --an-diff-added-bg: rgba(34, 197, 94, 0.15);
119
+ --an-diff-added-border: rgba(34, 197, 94, 0.4);
120
+ --an-diff-added-text: #4ade80;
121
+ --an-diff-removed-bg: rgba(239, 68, 68, 0.15);
122
+ --an-diff-removed-border: rgba(239, 68, 68, 0.4);
123
+ --an-diff-removed-text: #f87171;
124
+ }
125
+
126
+ /* TextShimmer animation */
127
+ @keyframes an-shimmer {
128
+ from { background-position: 100% center; }
129
+ to { background-position: 0% center; }
130
+ }
131
+
132
+ .an-text-shimmer {
133
+ display: inline-block;
134
+ background-size: 250% 100%;
135
+ background-clip: text;
136
+ -webkit-background-clip: text;
137
+ color: transparent;
138
+ background-image:
139
+ linear-gradient(90deg, transparent calc(50% - var(--an-shimmer-spread, 100px)), var(--an-foreground-muted, #737373), transparent calc(50% + var(--an-shimmer-spread, 100px))),
140
+ linear-gradient(var(--an-foreground-subtle, #a3a3a3), var(--an-foreground-subtle, #a3a3a3));
141
+ background-repeat: no-repeat, padding-box;
142
+ }
143
+
144
+ .an-text-shimmer--active {
145
+ animation: an-shimmer var(--an-shimmer-duration, 2s) linear infinite;
146
+ }
147
+
148
+ /* Scrollbar hide utility */
149
+ .scrollbar-hide {
150
+ -ms-overflow-style: none;
151
+ scrollbar-width: none;
152
+ }
153
+ .scrollbar-hide::-webkit-scrollbar {
154
+ display: none;
155
+ }
156
+
157
+ /* Spinner animation */
158
+ @keyframes an-spinner-rotate {
159
+ from { transform: rotate(0deg); }
160
+ to { transform: rotate(360deg); }
161
+ }