@gram-ai/elements 1.20.2 → 1.21.2

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.
Files changed (74) hide show
  1. package/bin/cli.js +14 -12
  2. package/dist/components/Chat/stories/ConnectionConfiguration.stories.d.ts +2 -2
  3. package/dist/components/Chat/stories/ToolApproval.stories.d.ts +2 -0
  4. package/dist/components/ui/dialog.d.ts +1 -1
  5. package/dist/components/ui/tooltip.d.ts +3 -1
  6. package/dist/constants/tailwind.d.ts +1 -0
  7. package/dist/contexts/portal-container-context.d.ts +2 -0
  8. package/dist/contexts/portal-container.d.ts +7 -0
  9. package/dist/elements.cjs +1 -160
  10. package/dist/elements.cjs.map +1 -1
  11. package/dist/elements.css +1 -1
  12. package/dist/elements.js +11 -47215
  13. package/dist/elements.js.map +1 -1
  14. package/dist/hooks/usePortalContainer.d.ts +8 -0
  15. package/dist/hooks/useSession.d.ts +1 -2
  16. package/dist/index-BVvrv2G3.cjs +169 -0
  17. package/dist/index-BVvrv2G3.cjs.map +1 -0
  18. package/dist/index-OU3wjArm.js +54670 -0
  19. package/dist/index-OU3wjArm.js.map +1 -0
  20. package/dist/index.d.ts +3 -1
  21. package/dist/lib/auth.d.ts +2 -2
  22. package/dist/lib/errorTracking.config.d.ts +16 -0
  23. package/dist/lib/errorTracking.d.ts +24 -0
  24. package/dist/lib/tools.d.ts +3 -2
  25. package/dist/profiler-DPH9zydw.cjs +2 -0
  26. package/dist/profiler-DPH9zydw.cjs.map +1 -0
  27. package/dist/profiler-D_HNXmyv.js +278 -0
  28. package/dist/profiler-D_HNXmyv.js.map +1 -0
  29. package/dist/startRecording-B97e4Mlu.cjs +3 -0
  30. package/dist/startRecording-B97e4Mlu.cjs.map +1 -0
  31. package/dist/startRecording-DOMzQAAr.js +1212 -0
  32. package/dist/startRecording-DOMzQAAr.js.map +1 -0
  33. package/dist/types/index.d.ts +45 -15
  34. package/package.json +16 -2
  35. package/src/components/Chat/index.tsx +31 -3
  36. package/src/components/Chat/stories/Composer.stories.tsx +0 -7
  37. package/src/components/Chat/stories/ConnectionConfiguration.stories.tsx +7 -14
  38. package/src/components/Chat/stories/CustomComponents.stories.tsx +0 -7
  39. package/src/components/Chat/stories/Density.stories.tsx +0 -7
  40. package/src/components/Chat/stories/ErrorBoundary.stories.tsx +4 -23
  41. package/src/components/Chat/stories/FrontendTools.stories.tsx +0 -7
  42. package/src/components/Chat/stories/Model.stories.tsx +0 -7
  43. package/src/components/Chat/stories/Plugins.stories.tsx +0 -7
  44. package/src/components/Chat/stories/Radius.stories.tsx +0 -7
  45. package/src/components/Chat/stories/ToolApproval.stories.tsx +51 -7
  46. package/src/components/Chat/stories/Tools.stories.tsx +0 -7
  47. package/src/components/Chat/stories/Variants.stories.tsx +5 -2
  48. package/src/components/Chat/stories/Welcome.stories.tsx +0 -8
  49. package/src/components/assistant-ui/assistant-sidecar.tsx +1 -4
  50. package/src/components/assistant-ui/attachment.tsx +1 -4
  51. package/src/components/assistant-ui/error-boundary.tsx +6 -0
  52. package/src/components/assistant-ui/thread-list.tsx +3 -1
  53. package/src/components/assistant-ui/thread.tsx +10 -12
  54. package/src/components/ui/dialog.tsx +10 -1
  55. package/src/components/ui/popover.tsx +10 -12
  56. package/src/components/ui/tooltip.tsx +7 -2
  57. package/src/constants/tailwind.ts +2 -0
  58. package/src/contexts/ElementsProvider.tsx +13 -1
  59. package/src/contexts/portal-container-context.ts +4 -0
  60. package/src/contexts/portal-container.tsx +20 -0
  61. package/src/global.css +129 -16
  62. package/src/hooks/useAuth.ts +6 -16
  63. package/src/hooks/usePortalContainer.ts +16 -0
  64. package/src/hooks/useSession.ts +1 -3
  65. package/src/index.ts +5 -0
  66. package/src/lib/api.test.ts +5 -5
  67. package/src/lib/auth.ts +4 -4
  68. package/src/lib/errorTracking.config.ts +16 -0
  69. package/src/lib/errorTracking.ts +104 -0
  70. package/src/lib/tools.ts +37 -8
  71. package/src/types/index.ts +48 -16
  72. package/src/vite-env.d.ts +3 -0
  73. package/dist/components/Chat/stories/ColorScheme.stories.d.ts +0 -8
  74. package/src/components/Chat/stories/ColorScheme.stories.tsx +0 -52
@@ -8,11 +8,9 @@ import { useQuery, useQueryClient } from '@tanstack/react-query'
8
8
  export const useSession = ({
9
9
  getSession,
10
10
  projectSlug,
11
- enabled,
12
11
  }: {
13
12
  getSession: GetSessionFn | null
14
13
  projectSlug: string
15
- enabled: boolean
16
14
  }): string | null => {
17
15
  const queryClient = useQueryClient()
18
16
  const queryKey = ['chatSession', projectSlug]
@@ -29,7 +27,7 @@ export const useSession = ({
29
27
  const { data: fetchedSessionToken } = useQuery({
30
28
  queryKey,
31
29
  queryFn: () => getSession!({ projectSlug }),
32
- enabled: enabled && shouldFetch && getSession !== null,
30
+ enabled: shouldFetch && getSession !== null,
33
31
  staleTime: Infinity, // Session tokens don't need to be refetched
34
32
  gcTime: Infinity, // Keep in cache indefinitely
35
33
  })
package/src/index.ts CHANGED
@@ -15,6 +15,10 @@ export { ThreadList as ChatHistory } from '@/components/assistant-ui/thread-list
15
15
  export { defineFrontendTool } from './lib/tools'
16
16
  export type { FrontendTool } from './lib/tools'
17
17
 
18
+ // Error Tracking
19
+ export { trackError } from './lib/errorTracking'
20
+ export type { ErrorContext } from './lib/errorTracking'
21
+
18
22
  // Types
19
23
  export type {
20
24
  AttachmentsConfig,
@@ -27,6 +31,7 @@ export type {
27
31
  Dimension,
28
32
  Dimensions,
29
33
  ElementsConfig,
34
+ ErrorTrackingConfigOption,
30
35
  GetSessionFn,
31
36
  HistoryConfig,
32
37
  ModalConfig,
@@ -1,5 +1,5 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest'
2
1
  import type { ElementsConfig } from '@/types'
2
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
3
3
 
4
4
  describe('getApiUrl', () => {
5
5
  beforeEach(() => {
@@ -16,7 +16,7 @@ describe('getApiUrl', () => {
16
16
  const getApiUrl = await loadGetApiUrl('https://env.example.com')
17
17
  const config: ElementsConfig = {
18
18
  projectSlug: 'test',
19
- api: { url: 'https://config.example.com', UNSAFE_apiKey: 'test-key' },
19
+ api: { url: 'https://config.example.com', sessionToken: 'test-key' },
20
20
  }
21
21
 
22
22
  expect(getApiUrl(config)).toBe('https://config.example.com')
@@ -26,7 +26,7 @@ describe('getApiUrl', () => {
26
26
  const getApiUrl = await loadGetApiUrl('https://env.example.com')
27
27
  const config: ElementsConfig = {
28
28
  projectSlug: 'test',
29
- api: { UNSAFE_apiKey: 'test-key' },
29
+ api: { sessionToken: 'test-key' },
30
30
  }
31
31
 
32
32
  expect(getApiUrl(config)).toBe('https://env.example.com')
@@ -63,7 +63,7 @@ describe('getApiUrl', () => {
63
63
  const getApiUrl = await loadGetApiUrl('https://env.example.com')
64
64
  const config: ElementsConfig = {
65
65
  projectSlug: 'test',
66
- api: { url: '', UNSAFE_apiKey: 'test-key' },
66
+ api: { url: '', sessionToken: 'test-key' },
67
67
  }
68
68
 
69
69
  expect(getApiUrl(config)).toBe('https://env.example.com')
@@ -73,7 +73,7 @@ describe('getApiUrl', () => {
73
73
  const getApiUrl = await loadGetApiUrl('')
74
74
  const config: ElementsConfig = {
75
75
  projectSlug: 'test',
76
- api: { url: 'https://config.example.com///', UNSAFE_apiKey: 'test-key' },
76
+ api: { url: 'https://config.example.com///', sessionToken: 'test-key' },
77
77
  }
78
78
 
79
79
  expect(getApiUrl(config)).toBe('https://config.example.com')
package/src/lib/auth.ts CHANGED
@@ -1,12 +1,12 @@
1
- import { ApiKeyAuthConfig, ApiConfig, SessionAuthConfig } from '@/types'
1
+ import { ApiConfig, SessionAuthConfig, StaticSessionAuthConfig } from '@/types'
2
2
 
3
3
  /**
4
4
  * Checks if the auth config is an API key auth config
5
5
  */
6
- export function isApiKeyAuth(
6
+ export function isStaticSessionAuth(
7
7
  auth: ApiConfig | undefined
8
- ): auth is ApiKeyAuthConfig {
9
- return !!auth && 'UNSAFE_apiKey' in auth
8
+ ): auth is StaticSessionAuthConfig {
9
+ return !!auth && 'sessionToken' in auth
10
10
  }
11
11
 
12
12
  export function hasExplicitSessionAuth(
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Datadog RUM configuration for Gram Elements.
3
+ * Values are injected at build time via environment variables.
4
+ * These client tokens are designed to be client-side safe.
5
+ *
6
+ * Required env vars for build:
7
+ * - VITE_DATADOG_APPLICATION_ID
8
+ * - VITE_DATADOG_CLIENT_TOKEN
9
+ * - VITE_DATADOG_SITE (optional, defaults to datadoghq.com)
10
+ */
11
+ export const DATADOG_CONFIG = {
12
+ applicationId: import.meta.env.VITE_DATADOG_APPLICATION_ID ?? '',
13
+ clientToken: import.meta.env.VITE_DATADOG_CLIENT_TOKEN ?? '',
14
+ site: import.meta.env.VITE_DATADOG_SITE ?? 'datadoghq.com',
15
+ service: 'gram-elements',
16
+ } as const
@@ -0,0 +1,104 @@
1
+ import { datadogRum } from '@datadog/browser-rum'
2
+ import { DATADOG_CONFIG } from './errorTracking.config'
3
+
4
+ let initialized = false
5
+ let enabled = true
6
+
7
+ export interface ErrorTrackingConfig {
8
+ enabled?: boolean
9
+ projectSlug?: string
10
+ variant?: string
11
+ }
12
+
13
+ export interface ErrorContext {
14
+ source: 'error-boundary' | 'streaming' | 'stream-creation' | 'custom'
15
+ componentStack?: string
16
+ [key: string]: unknown
17
+ }
18
+
19
+ /**
20
+ * Initialize Datadog RUM for error tracking.
21
+ * Should be called once when the ElementsProvider mounts.
22
+ */
23
+ export function initErrorTracking(config: ErrorTrackingConfig = {}): void {
24
+ // Check if explicitly disabled
25
+ if (config.enabled === false) {
26
+ enabled = false
27
+ return
28
+ }
29
+
30
+ // Prevent double initialization
31
+ if (initialized) {
32
+ return
33
+ }
34
+
35
+ // Skip if credentials not configured (e.g., local dev without env vars)
36
+ if (!DATADOG_CONFIG.applicationId || !DATADOG_CONFIG.clientToken) {
37
+ enabled = false
38
+ return
39
+ }
40
+
41
+ try {
42
+ datadogRum.init({
43
+ applicationId: DATADOG_CONFIG.applicationId,
44
+ clientToken: DATADOG_CONFIG.clientToken,
45
+ site: DATADOG_CONFIG.site,
46
+ service: DATADOG_CONFIG.service,
47
+ env: process.env.NODE_ENV || 'production',
48
+ sessionSampleRate: 100,
49
+ sessionReplaySampleRate: 100,
50
+ trackUserInteractions: true,
51
+ trackResources: true,
52
+ trackLongTasks: true,
53
+
54
+ // Note: we need to mask everything, not just user input, as sensitive data may be echo-ed
55
+ // back in the LLM messages or the user messages in the chat window
56
+ defaultPrivacyLevel: 'mask',
57
+ })
58
+
59
+ // Set global context
60
+ if (config.projectSlug) {
61
+ datadogRum.setGlobalContextProperty('projectSlug', config.projectSlug)
62
+ }
63
+ if (config.variant) {
64
+ datadogRum.setGlobalContextProperty('variant', config.variant)
65
+ }
66
+
67
+ initialized = true
68
+ } catch (error) {
69
+ console.warn('[Elements] Failed to initialize Datadog RUM:', error)
70
+ enabled = false
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Track an error to Datadog RUM.
76
+ * Includes context about where the error originated.
77
+ */
78
+ export function trackError(
79
+ error: Error | unknown,
80
+ context: ErrorContext
81
+ ): void {
82
+ if (!enabled || !initialized) {
83
+ return
84
+ }
85
+
86
+ const errorObj = error instanceof Error ? error : new Error(String(error))
87
+
88
+ try {
89
+ datadogRum.addError(errorObj, {
90
+ ...context,
91
+ timestamp: new Date().toISOString(),
92
+ })
93
+ } catch (e) {
94
+ // Silently fail - we don't want error tracking to cause more errors
95
+ console.warn('[Elements] Failed to track error:', e)
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Check if error tracking is currently enabled.
101
+ */
102
+ export function isErrorTrackingEnabled(): boolean {
103
+ return enabled && initialized
104
+ }
package/src/lib/tools.ts CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  } from '@assistant-ui/react'
7
7
  import z from 'zod'
8
8
  import { FC } from 'react'
9
+ import type { ToolsRequiringApproval } from '@/types'
9
10
 
10
11
  /**
11
12
  * Converts from assistant-ui tool format to the AI SDK tool shape
@@ -50,7 +51,7 @@ export type FrontendTool<TArgs extends Record<string, unknown>, TResult> = FC<
50
51
  */
51
52
  let approvalConfig: {
52
53
  helpers: ApprovalHelpers
53
- toolsRequiringApproval: Set<string>
54
+ requiresApproval: (toolName: string) => boolean
54
55
  } | null = null
55
56
 
56
57
  /**
@@ -58,11 +59,12 @@ let approvalConfig: {
58
59
  */
59
60
  export function setFrontendToolApprovalConfig(
60
61
  helpers: ApprovalHelpers,
61
- toolsRequiringApproval: string[]
62
+ toolsRequiringApproval: ToolsRequiringApproval
62
63
  ): void {
64
+ const requiresApproval = createRequiresApprovalFn(toolsRequiringApproval)
63
65
  approvalConfig = {
64
66
  helpers,
65
- toolsRequiringApproval: new Set(toolsRequiringApproval),
67
+ requiresApproval,
66
68
  }
67
69
  }
68
70
 
@@ -73,6 +75,25 @@ export function clearFrontendToolApprovalConfig(): void {
73
75
  approvalConfig = null
74
76
  }
75
77
 
78
+ /**
79
+ * Creates a function that checks if a tool requires approval.
80
+ * Handles both array and function-based configurations.
81
+ */
82
+ function createRequiresApprovalFn(
83
+ toolsRequiringApproval: ToolsRequiringApproval | undefined
84
+ ): (toolName: string) => boolean {
85
+ if (!toolsRequiringApproval) {
86
+ return () => false
87
+ }
88
+
89
+ if (typeof toolsRequiringApproval === 'function') {
90
+ return (toolName: string) => toolsRequiringApproval({ toolName })
91
+ }
92
+
93
+ const approvalSet = new Set(toolsRequiringApproval)
94
+ return (toolName: string) => approvalSet.has(toolName)
95
+ }
96
+
76
97
  /**
77
98
  * Make a frontend tool
78
99
  */
@@ -90,7 +111,7 @@ export const defineFrontendTool = <
90
111
  ...tool,
91
112
  execute: async (args: TArgs, context: ToolExecutionContext) => {
92
113
  // Check if this tool requires approval at runtime
93
- if (approvalConfig?.toolsRequiringApproval.has(name)) {
114
+ if (approvalConfig?.requiresApproval(name)) {
94
115
  const { helpers } = approvalConfig
95
116
  const toolCallId = context.toolCallId ?? ''
96
117
 
@@ -136,18 +157,26 @@ export interface ApprovalHelpers {
136
157
  */
137
158
  export function wrapToolsWithApproval(
138
159
  tools: ToolSet,
139
- toolsRequiringApproval: string[] | undefined,
160
+ toolsRequiringApproval: ToolsRequiringApproval | undefined,
140
161
  approvalHelpers: ApprovalHelpers
141
162
  ): ToolSet {
142
- if (!toolsRequiringApproval || toolsRequiringApproval.length === 0) {
163
+ if (!toolsRequiringApproval) {
143
164
  return tools
144
165
  }
145
166
 
146
- const approvalSet = new Set(toolsRequiringApproval)
167
+ // Handle empty array case
168
+ if (
169
+ Array.isArray(toolsRequiringApproval) &&
170
+ toolsRequiringApproval.length === 0
171
+ ) {
172
+ return tools
173
+ }
174
+
175
+ const requiresApproval = createRequiresApprovalFn(toolsRequiringApproval)
147
176
 
148
177
  return Object.fromEntries(
149
178
  Object.entries(tools).map(([name, tool]) => {
150
- if (!approvalSet.has(name)) {
179
+ if (!requiresApproval(name)) {
151
180
  return [name, tool]
152
181
  }
153
182
 
@@ -288,6 +288,30 @@ export interface ElementsConfig {
288
288
  * }
289
289
  */
290
290
  api?: ApiConfig
291
+
292
+ /**
293
+ * Error tracking configuration.
294
+ * By default, errors are reported to help improve the Elements library.
295
+ *
296
+ * @example
297
+ * const config: ElementsConfig = {
298
+ * errorTracking: {
299
+ * enabled: false, // Opt out of error reporting
300
+ * },
301
+ * }
302
+ */
303
+ errorTracking?: ErrorTrackingConfigOption
304
+ }
305
+
306
+ /**
307
+ * Configuration for error tracking.
308
+ */
309
+ export interface ErrorTrackingConfigOption {
310
+ /**
311
+ * Set to false to disable error reporting.
312
+ * @default true
313
+ */
314
+ enabled?: boolean
291
315
  }
292
316
 
293
317
  /**
@@ -325,32 +349,27 @@ export type SessionAuthConfig = {
325
349
  }
326
350
 
327
351
  /**
328
- * The API key auth config is used to authenticate the Elements library using an API key only.
329
- *
330
- * NOTE: This is not recommended for production use, and a warning
331
- * will be displayed in the chat interface if you use this config.
332
- * Define a session endpoint instead to avoid this warning.
352
+ * The static session auth config is used to authenticate the Elements library using a static session token only.
333
353
  *
334
354
  * @example
335
355
  * const config: ElementsConfig = {
336
356
  * api: {
337
- * UNSAFE_apiKey: 'your-api-key',
357
+ * sessionToken: 'your-session-token',
338
358
  * },
339
359
  * }
340
360
  */
341
- export type ApiKeyAuthConfig = {
361
+ export type StaticSessionAuthConfig = {
342
362
  /**
343
- * The API key to use if you haven't yet configured a session endpoint.
344
- * Do not use this in production.
363
+ * A static session token to use if you haven't yet configured a session endpoint.
345
364
  *
346
365
  * @example
347
366
  * const config: ElementsConfig = {
348
367
  * api: {
349
- * UNSAFE_apiKey: 'your-api-key',
368
+ * sessionToken: 'your-session-token',
350
369
  * },
351
370
  * }
352
371
  */
353
- UNSAFE_apiKey: string
372
+ sessionToken: string
354
373
  }
355
374
 
356
375
  /**
@@ -359,7 +378,7 @@ export type ApiKeyAuthConfig = {
359
378
  export type ApiConfig =
360
379
  | BaseApiConfig
361
380
  | (BaseApiConfig & SessionAuthConfig)
362
- | (BaseApiConfig & ApiKeyAuthConfig)
381
+ | (BaseApiConfig & StaticSessionAuthConfig)
363
382
 
364
383
  /**
365
384
  * The LLM model to use for the Elements library.
@@ -490,6 +509,10 @@ export interface ComponentOverrides {
490
509
  >
491
510
  }
492
511
 
512
+ export type ToolsRequiringApproval =
513
+ | string[]
514
+ | (({ toolName }: { toolName: string }) => boolean)
515
+
493
516
  /**
494
517
  * ToolsConfig is used to configure tool support in the Elements library.
495
518
  * At the moment, you can override the default React components used by
@@ -504,7 +527,6 @@ export interface ComponentOverrides {
504
527
  * },
505
528
  * }
506
529
  */
507
-
508
530
  export interface ToolsConfig {
509
531
  /**
510
532
  * Whether individual tool calls within a group should be expanded by default.
@@ -584,17 +606,27 @@ export interface ToolsConfig {
584
606
 
585
607
  /**
586
608
  * List of tool names that require confirmation from the end user before
587
- * being executed. The user can choose to approve once or approve for the
609
+ * being executed. A function can also be provided to dynamically determine if a tool requires approval.
610
+ * The user can choose to approve once or approve for the
588
611
  * entire session via the UI.
589
612
  *
590
- * @example
613
+ * @example Using an array of tool names
591
614
  * ```ts
592
615
  * tools: {
593
616
  * toolsRequiringApproval: ['delete_file', 'send_email'],
594
617
  * }
595
618
  * ```
619
+ *
620
+ * @example Using a function to dynamically determine if a tool requires approval
621
+ * ```ts
622
+ * tools: {
623
+ * toolsRequiringApproval: (toolName) => {
624
+ * return toolName.startsWith('protected_')
625
+ * },
626
+ * }
627
+ * ```
596
628
  */
597
- toolsRequiringApproval?: string[]
629
+ toolsRequiringApproval?: ToolsRequiringApproval
598
630
  }
599
631
 
600
632
  export interface WelcomeConfig {
package/src/vite-env.d.ts CHANGED
@@ -5,6 +5,9 @@ declare const __GRAM_GIT_SHA__: string | undefined
5
5
  interface ImportMetaEnv {
6
6
  readonly VITE_GRAM_ELEMENTS_STORYBOOK_PROJECT_SLUG?: string | undefined
7
7
  readonly VITE_GRAM_ELEMENTS_STORYBOOK_MCP_URL?: string | undefined
8
+ readonly VITE_DATADOG_APPLICATION_ID?: string | undefined
9
+ readonly VITE_DATADOG_CLIENT_TOKEN?: string | undefined
10
+ readonly VITE_DATADOG_SITE?: string | undefined
8
11
  }
9
12
 
10
13
  interface ImportMeta {
@@ -1,8 +0,0 @@
1
- import { Chat } from '..';
2
- import { Meta, StoryFn } from '@storybook/react-vite';
3
- declare const meta: Meta<typeof Chat>;
4
- export default meta;
5
- type Story = StoryFn<typeof Chat>;
6
- export declare const Light: Story;
7
- export declare const Dark: Story;
8
- export declare const System: Story;
@@ -1,52 +0,0 @@
1
- import React from 'react'
2
- import { Chat } from '..'
3
- import type { Meta, StoryFn } from '@storybook/react-vite'
4
-
5
- const meta: Meta<typeof Chat> = {
6
- title: 'Chat/Color Scheme',
7
- component: Chat,
8
- parameters: {
9
- layout: 'fullscreen',
10
- },
11
- decorators: [
12
- (Story) => (
13
- <div className="m-auto flex h-screen w-full max-w-3xl flex-col">
14
- <Story />
15
- </div>
16
- ),
17
- ],
18
- } satisfies Meta<typeof Chat>
19
-
20
- export default meta
21
-
22
- type Story = StoryFn<typeof Chat>
23
-
24
- export const Light: Story = () => <Chat />
25
- Light.parameters = {
26
- elements: {
27
- config: {
28
- variant: 'standalone',
29
- theme: { colorScheme: 'light' },
30
- },
31
- },
32
- }
33
-
34
- export const Dark: Story = () => <Chat />
35
- Dark.parameters = {
36
- elements: {
37
- config: {
38
- variant: 'standalone',
39
- theme: { colorScheme: 'dark' },
40
- },
41
- },
42
- }
43
-
44
- export const System: Story = () => <Chat />
45
- System.parameters = {
46
- elements: {
47
- config: {
48
- variant: 'standalone',
49
- theme: { colorScheme: 'system' },
50
- },
51
- },
52
- }