@devicai/ui 0.1.0
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.
- package/README.md +363 -0
- package/dist/cjs/api/client.js +118 -0
- package/dist/cjs/api/client.js.map +1 -0
- package/dist/cjs/components/ChatDrawer/ChatDrawer.js +122 -0
- package/dist/cjs/components/ChatDrawer/ChatDrawer.js.map +1 -0
- package/dist/cjs/components/ChatDrawer/ChatInput.js +128 -0
- package/dist/cjs/components/ChatDrawer/ChatInput.js.map +1 -0
- package/dist/cjs/components/ChatDrawer/ChatMessages.js +56 -0
- package/dist/cjs/components/ChatDrawer/ChatMessages.js.map +1 -0
- package/dist/cjs/components/ChatDrawer/ToolTimeline.js +26 -0
- package/dist/cjs/components/ChatDrawer/ToolTimeline.js.map +1 -0
- package/dist/cjs/hooks/useDevicChat.js +258 -0
- package/dist/cjs/hooks/useDevicChat.js.map +1 -0
- package/dist/cjs/hooks/useModelInterface.js +130 -0
- package/dist/cjs/hooks/useModelInterface.js.map +1 -0
- package/dist/cjs/hooks/usePolling.js +109 -0
- package/dist/cjs/hooks/usePolling.js.map +1 -0
- package/dist/cjs/index.js +36 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/provider/DevicContext.js +32 -0
- package/dist/cjs/provider/DevicContext.js.map +1 -0
- package/dist/cjs/provider/DevicProvider.js +43 -0
- package/dist/cjs/provider/DevicProvider.js.map +1 -0
- package/dist/cjs/styles.css +1 -0
- package/dist/cjs/utils/index.js +117 -0
- package/dist/cjs/utils/index.js.map +1 -0
- package/dist/esm/api/client.d.ts +56 -0
- package/dist/esm/api/client.js +115 -0
- package/dist/esm/api/client.js.map +1 -0
- package/dist/esm/api/types.d.ts +184 -0
- package/dist/esm/components/ChatDrawer/ChatDrawer.d.ts +27 -0
- package/dist/esm/components/ChatDrawer/ChatDrawer.js +120 -0
- package/dist/esm/components/ChatDrawer/ChatDrawer.js.map +1 -0
- package/dist/esm/components/ChatDrawer/ChatDrawer.types.d.ts +197 -0
- package/dist/esm/components/ChatDrawer/ChatInput.d.ts +5 -0
- package/dist/esm/components/ChatDrawer/ChatInput.js +126 -0
- package/dist/esm/components/ChatDrawer/ChatInput.js.map +1 -0
- package/dist/esm/components/ChatDrawer/ChatMessages.d.ts +5 -0
- package/dist/esm/components/ChatDrawer/ChatMessages.js +54 -0
- package/dist/esm/components/ChatDrawer/ChatMessages.js.map +1 -0
- package/dist/esm/components/ChatDrawer/ToolTimeline.d.ts +5 -0
- package/dist/esm/components/ChatDrawer/ToolTimeline.js +24 -0
- package/dist/esm/components/ChatDrawer/ToolTimeline.js.map +1 -0
- package/dist/esm/components/ChatDrawer/index.d.ts +5 -0
- package/dist/esm/hooks/index.d.ts +6 -0
- package/dist/esm/hooks/useDevicChat.d.ts +120 -0
- package/dist/esm/hooks/useDevicChat.js +256 -0
- package/dist/esm/hooks/useDevicChat.js.map +1 -0
- package/dist/esm/hooks/useModelInterface.d.ts +68 -0
- package/dist/esm/hooks/useModelInterface.js +128 -0
- package/dist/esm/hooks/useModelInterface.js.map +1 -0
- package/dist/esm/hooks/usePolling.d.ts +64 -0
- package/dist/esm/hooks/usePolling.js +107 -0
- package/dist/esm/hooks/usePolling.js.map +1 -0
- package/dist/esm/index.d.ts +10 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/provider/DevicContext.d.ts +15 -0
- package/dist/esm/provider/DevicContext.js +28 -0
- package/dist/esm/provider/DevicContext.js.map +1 -0
- package/dist/esm/provider/DevicProvider.d.ts +17 -0
- package/dist/esm/provider/DevicProvider.js +41 -0
- package/dist/esm/provider/DevicProvider.js.map +1 -0
- package/dist/esm/provider/index.d.ts +3 -0
- package/dist/esm/provider/types.d.ts +58 -0
- package/dist/esm/styles.css +1 -0
- package/dist/esm/utils/index.d.ts +32 -0
- package/dist/esm/utils/index.js +109 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Devic API client using native fetch
|
|
3
|
+
*/
|
|
4
|
+
class DevicApiClient {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.config = config;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Update client configuration
|
|
10
|
+
*/
|
|
11
|
+
setConfig(config) {
|
|
12
|
+
this.config = { ...this.config, ...config };
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Make an authenticated request to the API
|
|
16
|
+
*/
|
|
17
|
+
async request(endpoint, options = {}) {
|
|
18
|
+
const url = `${this.config.baseUrl}${endpoint}`;
|
|
19
|
+
const headers = {
|
|
20
|
+
'Content-Type': 'application/json',
|
|
21
|
+
'Authorization': `Bearer ${this.config.apiKey}`,
|
|
22
|
+
...options.headers,
|
|
23
|
+
};
|
|
24
|
+
const response = await fetch(url, {
|
|
25
|
+
...options,
|
|
26
|
+
headers,
|
|
27
|
+
});
|
|
28
|
+
if (!response.ok) {
|
|
29
|
+
let errorData;
|
|
30
|
+
try {
|
|
31
|
+
errorData = await response.json();
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
errorData = {
|
|
35
|
+
statusCode: response.status,
|
|
36
|
+
message: response.statusText,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
throw new DevicApiError(errorData);
|
|
40
|
+
}
|
|
41
|
+
// Handle responses that may have a wrapper structure
|
|
42
|
+
const data = await response.json();
|
|
43
|
+
// If the response has a data property, extract it (common wrapper pattern)
|
|
44
|
+
if (data && typeof data === 'object' && 'data' in data) {
|
|
45
|
+
return data.data;
|
|
46
|
+
}
|
|
47
|
+
return data;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get all assistant specializations
|
|
51
|
+
*/
|
|
52
|
+
async getAssistants(external = false) {
|
|
53
|
+
const query = external ? '?external=true' : '';
|
|
54
|
+
return this.request(`/api/v1/assistants${query}`);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get a specific assistant specialization
|
|
58
|
+
*/
|
|
59
|
+
async getAssistant(identifier) {
|
|
60
|
+
return this.request(`/api/v1/assistants/${identifier}`);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Send a message to an assistant (sync mode)
|
|
64
|
+
*/
|
|
65
|
+
async sendMessage(assistantId, dto) {
|
|
66
|
+
return this.request(`/api/v1/assistants/${assistantId}/messages`, {
|
|
67
|
+
method: 'POST',
|
|
68
|
+
body: JSON.stringify(dto),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Send a message to an assistant (async mode)
|
|
73
|
+
*/
|
|
74
|
+
async sendMessageAsync(assistantId, dto) {
|
|
75
|
+
return this.request(`/api/v1/assistants/${assistantId}/messages?async=true`, {
|
|
76
|
+
method: 'POST',
|
|
77
|
+
body: JSON.stringify(dto),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get real-time chat history (for polling in async mode)
|
|
82
|
+
*/
|
|
83
|
+
async getRealtimeHistory(assistantId, chatUid) {
|
|
84
|
+
return this.request(`/api/v1/assistants/${assistantId}/chats/${chatUid}/realtime`);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get chat history for a specific conversation
|
|
88
|
+
*/
|
|
89
|
+
async getChatHistory(assistantId, chatUid) {
|
|
90
|
+
return this.request(`/api/v1/assistants/${assistantId}/chats/${chatUid}`);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Send tool call responses back to the assistant
|
|
94
|
+
*/
|
|
95
|
+
async sendToolResponses(assistantId, chatUid, responses) {
|
|
96
|
+
return this.request(`/api/v1/assistants/${assistantId}/chats/${chatUid}/tool-response`, {
|
|
97
|
+
method: 'POST',
|
|
98
|
+
body: JSON.stringify({ responses }),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Custom error class for API errors
|
|
104
|
+
*/
|
|
105
|
+
class DevicApiError extends Error {
|
|
106
|
+
constructor(error) {
|
|
107
|
+
super(error.message);
|
|
108
|
+
this.name = 'DevicApiError';
|
|
109
|
+
this.statusCode = error.statusCode;
|
|
110
|
+
this.errorType = error.error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export { DevicApiClient, DevicApiError };
|
|
115
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sources":["../../../src/api/client.ts"],"sourcesContent":["import type {\n ProcessMessageDto,\n ChatMessage,\n AsyncResponse,\n RealtimeChatHistory,\n ChatHistory,\n AssistantSpecialization,\n ApiError,\n ToolCallResponse,\n} from './types';\n\nexport interface DevicApiClientConfig {\n apiKey: string;\n baseUrl: string;\n}\n\n/**\n * Devic API client using native fetch\n */\nexport class DevicApiClient {\n private config: DevicApiClientConfig;\n\n constructor(config: DevicApiClientConfig) {\n this.config = config;\n }\n\n /**\n * Update client configuration\n */\n setConfig(config: Partial<DevicApiClientConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Make an authenticated request to the API\n */\n private async request<T>(\n endpoint: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`;\n\n const headers: HeadersInit = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n ...options.headers,\n };\n\n const response = await fetch(url, {\n ...options,\n headers,\n });\n\n if (!response.ok) {\n let errorData: ApiError;\n try {\n errorData = await response.json();\n } catch {\n errorData = {\n statusCode: response.status,\n message: response.statusText,\n };\n }\n throw new DevicApiError(errorData);\n }\n\n // Handle responses that may have a wrapper structure\n const data = await response.json();\n\n // If the response has a data property, extract it (common wrapper pattern)\n if (data && typeof data === 'object' && 'data' in data) {\n return data.data as T;\n }\n\n return data as T;\n }\n\n /**\n * Get all assistant specializations\n */\n async getAssistants(external = false): Promise<AssistantSpecialization[]> {\n const query = external ? '?external=true' : '';\n return this.request<AssistantSpecialization[]>(`/api/v1/assistants${query}`);\n }\n\n /**\n * Get a specific assistant specialization\n */\n async getAssistant(identifier: string): Promise<AssistantSpecialization> {\n return this.request<AssistantSpecialization>(`/api/v1/assistants/${identifier}`);\n }\n\n /**\n * Send a message to an assistant (sync mode)\n */\n async sendMessage(\n assistantId: string,\n dto: ProcessMessageDto\n ): Promise<ChatMessage[]> {\n return this.request<ChatMessage[]>(\n `/api/v1/assistants/${assistantId}/messages`,\n {\n method: 'POST',\n body: JSON.stringify(dto),\n }\n );\n }\n\n /**\n * Send a message to an assistant (async mode)\n */\n async sendMessageAsync(\n assistantId: string,\n dto: ProcessMessageDto\n ): Promise<AsyncResponse> {\n return this.request<AsyncResponse>(\n `/api/v1/assistants/${assistantId}/messages?async=true`,\n {\n method: 'POST',\n body: JSON.stringify(dto),\n }\n );\n }\n\n /**\n * Get real-time chat history (for polling in async mode)\n */\n async getRealtimeHistory(\n assistantId: string,\n chatUid: string\n ): Promise<RealtimeChatHistory> {\n return this.request<RealtimeChatHistory>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}/realtime`\n );\n }\n\n /**\n * Get chat history for a specific conversation\n */\n async getChatHistory(\n assistantId: string,\n chatUid: string\n ): Promise<ChatHistory> {\n return this.request<ChatHistory>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}`\n );\n }\n\n /**\n * Send tool call responses back to the assistant\n */\n async sendToolResponses(\n assistantId: string,\n chatUid: string,\n responses: ToolCallResponse[]\n ): Promise<AsyncResponse> {\n return this.request<AsyncResponse>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}/tool-response`,\n {\n method: 'POST',\n body: JSON.stringify({ responses }),\n }\n );\n }\n}\n\n/**\n * Custom error class for API errors\n */\nexport class DevicApiError extends Error {\n public statusCode: number;\n public errorType?: string;\n\n constructor(error: ApiError) {\n super(error.message);\n this.name = 'DevicApiError';\n this.statusCode = error.statusCode;\n this.errorType = error.error;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File attachment for messages
|
|
3
|
+
*/
|
|
4
|
+
export interface ChatFile {
|
|
5
|
+
name: string;
|
|
6
|
+
downloadUrl?: string;
|
|
7
|
+
fileType?: 'image' | 'document' | 'audio' | 'video' | 'other';
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Message content structure
|
|
11
|
+
*/
|
|
12
|
+
export interface MessageContent {
|
|
13
|
+
message?: string;
|
|
14
|
+
data?: any;
|
|
15
|
+
files?: Array<{
|
|
16
|
+
name: string;
|
|
17
|
+
url: string;
|
|
18
|
+
type: string;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Tool call from the model
|
|
23
|
+
*/
|
|
24
|
+
export interface ToolCall {
|
|
25
|
+
id: string;
|
|
26
|
+
type: 'function';
|
|
27
|
+
function: {
|
|
28
|
+
name: string;
|
|
29
|
+
arguments: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Chat message structure
|
|
34
|
+
*/
|
|
35
|
+
export interface ChatMessage {
|
|
36
|
+
uid: string;
|
|
37
|
+
role: 'user' | 'assistant' | 'developer' | 'tool';
|
|
38
|
+
content: MessageContent;
|
|
39
|
+
timestamp: number;
|
|
40
|
+
chatUid?: string;
|
|
41
|
+
tool_calls?: ToolCall[];
|
|
42
|
+
tool_call_id?: string;
|
|
43
|
+
summary?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Previous conversation message for initialization
|
|
47
|
+
*/
|
|
48
|
+
export interface PreviousMessage {
|
|
49
|
+
message: string;
|
|
50
|
+
role: 'user' | 'assistant';
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Model interface tool schema following OpenAI function calling format
|
|
54
|
+
*/
|
|
55
|
+
export interface ModelInterfaceToolSchema {
|
|
56
|
+
type: 'function';
|
|
57
|
+
function: {
|
|
58
|
+
name: string;
|
|
59
|
+
description: string;
|
|
60
|
+
parameters: {
|
|
61
|
+
type: 'object';
|
|
62
|
+
properties: Record<string, any>;
|
|
63
|
+
required?: string[];
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Model interface tool definition for client-side tools
|
|
69
|
+
*/
|
|
70
|
+
export interface ModelInterfaceTool {
|
|
71
|
+
toolName: string;
|
|
72
|
+
schema: ModelInterfaceToolSchema;
|
|
73
|
+
callback: (params: any) => Promise<any> | any;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Tool call response to send back to the API
|
|
77
|
+
*/
|
|
78
|
+
export interface ToolCallResponse {
|
|
79
|
+
tool_call_id: string;
|
|
80
|
+
content: any;
|
|
81
|
+
role: 'tool';
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* DTO for sending messages to the assistant
|
|
85
|
+
*/
|
|
86
|
+
export interface ProcessMessageDto {
|
|
87
|
+
message: string;
|
|
88
|
+
chatUid?: string;
|
|
89
|
+
userName?: string;
|
|
90
|
+
files?: ChatFile[];
|
|
91
|
+
metadata?: {
|
|
92
|
+
promptTemplateParams?: Record<string, any>;
|
|
93
|
+
tenantToken?: string;
|
|
94
|
+
[key: string]: any;
|
|
95
|
+
};
|
|
96
|
+
tenantId?: string;
|
|
97
|
+
previousConversation?: PreviousMessage[];
|
|
98
|
+
enabledTools?: string[];
|
|
99
|
+
provider?: string;
|
|
100
|
+
model?: string;
|
|
101
|
+
tools?: ModelInterfaceToolSchema[];
|
|
102
|
+
applicationState?: Record<string, any>;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Response from the assistant
|
|
106
|
+
*/
|
|
107
|
+
export interface AssistantResponse {
|
|
108
|
+
messages: ChatMessage[];
|
|
109
|
+
chatUid: string;
|
|
110
|
+
inputTokens?: number;
|
|
111
|
+
outputTokens?: number;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Async mode response
|
|
115
|
+
*/
|
|
116
|
+
export interface AsyncResponse {
|
|
117
|
+
chatUid: string;
|
|
118
|
+
message?: string;
|
|
119
|
+
error?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Real-time chat history status
|
|
123
|
+
*/
|
|
124
|
+
export type RealtimeStatus = 'processing' | 'completed' | 'error' | 'waiting_for_tool_response';
|
|
125
|
+
/**
|
|
126
|
+
* Real-time chat history response
|
|
127
|
+
*/
|
|
128
|
+
export interface RealtimeChatHistory {
|
|
129
|
+
chatUID: string;
|
|
130
|
+
clientUID: string;
|
|
131
|
+
chatHistory: ChatMessage[];
|
|
132
|
+
status: RealtimeStatus;
|
|
133
|
+
lastUpdatedAt: number;
|
|
134
|
+
pendingToolCalls?: ToolCall[];
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Chat history structure
|
|
138
|
+
*/
|
|
139
|
+
export interface ChatHistory {
|
|
140
|
+
chatUID: string;
|
|
141
|
+
clientUID: string;
|
|
142
|
+
userUID: string;
|
|
143
|
+
chatContent: ChatMessage[];
|
|
144
|
+
name?: string;
|
|
145
|
+
assistantSpecializationIdentifier: string;
|
|
146
|
+
creationTimestampMs: number;
|
|
147
|
+
lastEditTimestampMs?: number;
|
|
148
|
+
llm?: string;
|
|
149
|
+
inputTokens?: number;
|
|
150
|
+
outputTokens?: number;
|
|
151
|
+
metadata?: Record<string, any>;
|
|
152
|
+
tenantId?: string;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Assistant specialization info
|
|
156
|
+
*/
|
|
157
|
+
export interface AssistantSpecialization {
|
|
158
|
+
identifier: string;
|
|
159
|
+
name: string;
|
|
160
|
+
description: string;
|
|
161
|
+
state: 'active' | 'inactive' | 'coming_soon';
|
|
162
|
+
imgUrl?: string;
|
|
163
|
+
availableToolsGroups?: Array<{
|
|
164
|
+
name: string;
|
|
165
|
+
description?: string;
|
|
166
|
+
uid?: string;
|
|
167
|
+
iconUrl?: string;
|
|
168
|
+
tools?: Array<{
|
|
169
|
+
name: string;
|
|
170
|
+
description: string;
|
|
171
|
+
}>;
|
|
172
|
+
}>;
|
|
173
|
+
model?: string;
|
|
174
|
+
isCustom?: boolean;
|
|
175
|
+
creationTimestampMs?: number;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* API error response
|
|
179
|
+
*/
|
|
180
|
+
export interface ApiError {
|
|
181
|
+
statusCode: number;
|
|
182
|
+
message: string;
|
|
183
|
+
error?: string;
|
|
184
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ChatDrawerProps } from './ChatDrawer.types';
|
|
2
|
+
import './styles.css';
|
|
3
|
+
/**
|
|
4
|
+
* Chat drawer component for Devic assistants
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```tsx
|
|
8
|
+
* <ChatDrawer
|
|
9
|
+
* assistantId="my-assistant"
|
|
10
|
+
* options={{
|
|
11
|
+
* position: 'right',
|
|
12
|
+
* width: 400,
|
|
13
|
+
* welcomeMessage: 'Hello! How can I help you?',
|
|
14
|
+
* suggestedMessages: ['Help me with...', 'Tell me about...'],
|
|
15
|
+
* }}
|
|
16
|
+
* modelInterfaceTools={[
|
|
17
|
+
* {
|
|
18
|
+
* toolName: 'get_user_location',
|
|
19
|
+
* schema: { ... },
|
|
20
|
+
* callback: async () => ({ lat: 40.7, lng: -74.0 })
|
|
21
|
+
* }
|
|
22
|
+
* ]}
|
|
23
|
+
* onMessageReceived={(msg) => console.log('Received:', msg)}
|
|
24
|
+
* />
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function ChatDrawer({ assistantId, chatUid: initialChatUid, options, enabledTools, modelInterfaceTools, tenantId, tenantMetadata, apiKey, baseUrl, onMessageSent, onMessageReceived, onToolCall, onError, onChatCreated, onOpen, onClose, isOpen: controlledIsOpen, className, }: ChatDrawerProps): JSX.Element;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo, useState, useCallback, useEffect } from 'react';
|
|
3
|
+
import { useDevicChat } from '../../hooks/useDevicChat.js';
|
|
4
|
+
import { ChatMessages } from './ChatMessages.js';
|
|
5
|
+
import { ChatInput } from './ChatInput.js';
|
|
6
|
+
|
|
7
|
+
const DEFAULT_OPTIONS = {
|
|
8
|
+
position: 'right',
|
|
9
|
+
width: 400,
|
|
10
|
+
defaultOpen: false,
|
|
11
|
+
color: '#1890ff',
|
|
12
|
+
welcomeMessage: '',
|
|
13
|
+
suggestedMessages: [],
|
|
14
|
+
enableFileUploads: false,
|
|
15
|
+
allowedFileTypes: { images: true, documents: true },
|
|
16
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
17
|
+
inputPlaceholder: 'Type a message...',
|
|
18
|
+
title: 'Chat',
|
|
19
|
+
showToolTimeline: true,
|
|
20
|
+
zIndex: 1000,
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Chat drawer component for Devic assistants
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```tsx
|
|
27
|
+
* <ChatDrawer
|
|
28
|
+
* assistantId="my-assistant"
|
|
29
|
+
* options={{
|
|
30
|
+
* position: 'right',
|
|
31
|
+
* width: 400,
|
|
32
|
+
* welcomeMessage: 'Hello! How can I help you?',
|
|
33
|
+
* suggestedMessages: ['Help me with...', 'Tell me about...'],
|
|
34
|
+
* }}
|
|
35
|
+
* modelInterfaceTools={[
|
|
36
|
+
* {
|
|
37
|
+
* toolName: 'get_user_location',
|
|
38
|
+
* schema: { ... },
|
|
39
|
+
* callback: async () => ({ lat: 40.7, lng: -74.0 })
|
|
40
|
+
* }
|
|
41
|
+
* ]}
|
|
42
|
+
* onMessageReceived={(msg) => console.log('Received:', msg)}
|
|
43
|
+
* />
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
function ChatDrawer({ assistantId, chatUid: initialChatUid, options = {}, enabledTools, modelInterfaceTools, tenantId, tenantMetadata, apiKey, baseUrl, onMessageSent, onMessageReceived, onToolCall, onError, onChatCreated, onOpen, onClose, isOpen: controlledIsOpen, className, }) {
|
|
47
|
+
// Merge options with defaults
|
|
48
|
+
const mergedOptions = useMemo(() => ({ ...DEFAULT_OPTIONS, ...options }), [options]);
|
|
49
|
+
// Drawer open state (can be controlled or uncontrolled)
|
|
50
|
+
const [internalIsOpen, setInternalIsOpen] = useState(mergedOptions.defaultOpen);
|
|
51
|
+
const isOpen = controlledIsOpen ?? internalIsOpen;
|
|
52
|
+
// Use chat hook
|
|
53
|
+
const chat = useDevicChat({
|
|
54
|
+
assistantId,
|
|
55
|
+
chatUid: initialChatUid,
|
|
56
|
+
apiKey,
|
|
57
|
+
baseUrl,
|
|
58
|
+
tenantId,
|
|
59
|
+
tenantMetadata,
|
|
60
|
+
enabledTools,
|
|
61
|
+
modelInterfaceTools,
|
|
62
|
+
onMessageSent,
|
|
63
|
+
onMessageReceived,
|
|
64
|
+
onToolCall,
|
|
65
|
+
onError,
|
|
66
|
+
onChatCreated,
|
|
67
|
+
});
|
|
68
|
+
// Handle open/close
|
|
69
|
+
const handleOpen = useCallback(() => {
|
|
70
|
+
setInternalIsOpen(true);
|
|
71
|
+
onOpen?.();
|
|
72
|
+
}, [onOpen]);
|
|
73
|
+
const handleClose = useCallback(() => {
|
|
74
|
+
setInternalIsOpen(false);
|
|
75
|
+
onClose?.();
|
|
76
|
+
}, [onClose]);
|
|
77
|
+
// Handle send message
|
|
78
|
+
const handleSend = useCallback((message, files) => {
|
|
79
|
+
chat.sendMessage(message, { files });
|
|
80
|
+
}, [chat]);
|
|
81
|
+
// Handle suggested message click
|
|
82
|
+
const handleSuggestedClick = useCallback((message) => {
|
|
83
|
+
chat.sendMessage(message);
|
|
84
|
+
}, [chat]);
|
|
85
|
+
// Apply CSS variable for primary color
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (mergedOptions.color !== DEFAULT_OPTIONS.color) {
|
|
88
|
+
document.documentElement.style.setProperty('--devic-primary', mergedOptions.color);
|
|
89
|
+
}
|
|
90
|
+
}, [mergedOptions.color]);
|
|
91
|
+
// Build style object
|
|
92
|
+
const drawerStyle = useMemo(() => ({
|
|
93
|
+
width: mergedOptions.width,
|
|
94
|
+
zIndex: mergedOptions.zIndex,
|
|
95
|
+
}), [mergedOptions.width, mergedOptions.zIndex]);
|
|
96
|
+
const overlayStyle = useMemo(() => ({
|
|
97
|
+
zIndex: mergedOptions.zIndex - 1,
|
|
98
|
+
}), [mergedOptions.zIndex]);
|
|
99
|
+
const triggerStyle = useMemo(() => ({
|
|
100
|
+
zIndex: mergedOptions.zIndex - 1,
|
|
101
|
+
[mergedOptions.position]: 20,
|
|
102
|
+
bottom: 20,
|
|
103
|
+
}), [mergedOptions.zIndex, mergedOptions.position]);
|
|
104
|
+
return (jsxs(Fragment, { children: [jsx("div", { className: "devic-drawer-overlay", "data-open": isOpen, style: overlayStyle, onClick: handleClose }), jsxs("div", { className: `devic-chat-drawer ${className || ''}`, "data-position": mergedOptions.position, "data-open": isOpen, style: drawerStyle, children: [jsxs("div", { className: "devic-drawer-header", children: [jsx("h2", { className: "devic-drawer-title", children: mergedOptions.title }), jsx("button", { className: "devic-drawer-close", onClick: handleClose, type: "button", "aria-label": "Close chat", children: jsx(CloseIcon, {}) })] }), chat.error && (jsx("div", { className: "devic-error", children: chat.error.message })), jsx(ChatMessages, { messages: chat.messages, isLoading: chat.isLoading, welcomeMessage: mergedOptions.welcomeMessage, suggestedMessages: mergedOptions.suggestedMessages, onSuggestedClick: handleSuggestedClick, showToolTimeline: mergedOptions.showToolTimeline }), jsx(ChatInput, { onSend: handleSend, disabled: chat.isLoading, placeholder: mergedOptions.inputPlaceholder, enableFileUploads: mergedOptions.enableFileUploads, allowedFileTypes: mergedOptions.allowedFileTypes, maxFileSize: mergedOptions.maxFileSize })] }), !isOpen && (jsx("button", { className: "devic-trigger", onClick: handleOpen, style: triggerStyle, type: "button", "aria-label": "Open chat", children: jsx(ChatIcon, {}) }))] }));
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Close icon
|
|
108
|
+
*/
|
|
109
|
+
function CloseIcon() {
|
|
110
|
+
return (jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }));
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Chat icon for trigger button
|
|
114
|
+
*/
|
|
115
|
+
function ChatIcon() {
|
|
116
|
+
return (jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: jsx("path", { d: "M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z" }) }));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export { ChatDrawer };
|
|
120
|
+
//# sourceMappingURL=ChatDrawer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatDrawer.js","sources":["../../../../src/components/ChatDrawer/ChatDrawer.tsx"],"sourcesContent":["import React, { useState, useEffect, useCallback, useMemo } from 'react';\nimport { useDevicChat } from '../../hooks/useDevicChat';\nimport { ChatMessages } from './ChatMessages';\nimport { ChatInput } from './ChatInput';\nimport type { ChatDrawerProps, ChatDrawerOptions } from './ChatDrawer.types';\nimport './styles.css';\n\nconst DEFAULT_OPTIONS: Required<ChatDrawerOptions> = {\n position: 'right',\n width: 400,\n defaultOpen: false,\n color: '#1890ff',\n welcomeMessage: '',\n suggestedMessages: [],\n enableFileUploads: false,\n allowedFileTypes: { images: true, documents: true },\n maxFileSize: 10 * 1024 * 1024,\n inputPlaceholder: 'Type a message...',\n title: 'Chat',\n showToolTimeline: true,\n zIndex: 1000,\n};\n\n/**\n * Chat drawer component for Devic assistants\n *\n * @example\n * ```tsx\n * <ChatDrawer\n * assistantId=\"my-assistant\"\n * options={{\n * position: 'right',\n * width: 400,\n * welcomeMessage: 'Hello! How can I help you?',\n * suggestedMessages: ['Help me with...', 'Tell me about...'],\n * }}\n * modelInterfaceTools={[\n * {\n * toolName: 'get_user_location',\n * schema: { ... },\n * callback: async () => ({ lat: 40.7, lng: -74.0 })\n * }\n * ]}\n * onMessageReceived={(msg) => console.log('Received:', msg)}\n * />\n * ```\n */\nexport function ChatDrawer({\n assistantId,\n chatUid: initialChatUid,\n options = {},\n enabledTools,\n modelInterfaceTools,\n tenantId,\n tenantMetadata,\n apiKey,\n baseUrl,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated,\n onOpen,\n onClose,\n isOpen: controlledIsOpen,\n className,\n}: ChatDrawerProps): JSX.Element {\n // Merge options with defaults\n const mergedOptions = useMemo(\n () => ({ ...DEFAULT_OPTIONS, ...options }),\n [options]\n );\n\n // Drawer open state (can be controlled or uncontrolled)\n const [internalIsOpen, setInternalIsOpen] = useState(mergedOptions.defaultOpen);\n const isOpen = controlledIsOpen ?? internalIsOpen;\n\n // Use chat hook\n const chat = useDevicChat({\n assistantId,\n chatUid: initialChatUid,\n apiKey,\n baseUrl,\n tenantId,\n tenantMetadata,\n enabledTools,\n modelInterfaceTools,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated,\n });\n\n // Handle open/close\n const handleOpen = useCallback(() => {\n setInternalIsOpen(true);\n onOpen?.();\n }, [onOpen]);\n\n const handleClose = useCallback(() => {\n setInternalIsOpen(false);\n onClose?.();\n }, [onClose]);\n\n // Handle send message\n const handleSend = useCallback(\n (message: string, files?: any[]) => {\n chat.sendMessage(message, { files });\n },\n [chat]\n );\n\n // Handle suggested message click\n const handleSuggestedClick = useCallback(\n (message: string) => {\n chat.sendMessage(message);\n },\n [chat]\n );\n\n // Apply CSS variable for primary color\n useEffect(() => {\n if (mergedOptions.color !== DEFAULT_OPTIONS.color) {\n document.documentElement.style.setProperty(\n '--devic-primary',\n mergedOptions.color\n );\n }\n }, [mergedOptions.color]);\n\n // Build style object\n const drawerStyle = useMemo(\n () => ({\n width: mergedOptions.width,\n zIndex: mergedOptions.zIndex,\n }),\n [mergedOptions.width, mergedOptions.zIndex]\n );\n\n const overlayStyle = useMemo(\n () => ({\n zIndex: mergedOptions.zIndex - 1,\n }),\n [mergedOptions.zIndex]\n );\n\n const triggerStyle = useMemo(\n () => ({\n zIndex: mergedOptions.zIndex - 1,\n [mergedOptions.position]: 20,\n bottom: 20,\n }),\n [mergedOptions.zIndex, mergedOptions.position]\n );\n\n return (\n <>\n {/* Overlay */}\n <div\n className=\"devic-drawer-overlay\"\n data-open={isOpen}\n style={overlayStyle}\n onClick={handleClose}\n />\n\n {/* Drawer */}\n <div\n className={`devic-chat-drawer ${className || ''}`}\n data-position={mergedOptions.position}\n data-open={isOpen}\n style={drawerStyle}\n >\n {/* Header */}\n <div className=\"devic-drawer-header\">\n <h2 className=\"devic-drawer-title\">{mergedOptions.title}</h2>\n <button\n className=\"devic-drawer-close\"\n onClick={handleClose}\n type=\"button\"\n aria-label=\"Close chat\"\n >\n <CloseIcon />\n </button>\n </div>\n\n {/* Error display */}\n {chat.error && (\n <div className=\"devic-error\">\n {chat.error.message}\n </div>\n )}\n\n {/* Messages */}\n <ChatMessages\n messages={chat.messages}\n isLoading={chat.isLoading}\n welcomeMessage={mergedOptions.welcomeMessage}\n suggestedMessages={mergedOptions.suggestedMessages}\n onSuggestedClick={handleSuggestedClick}\n showToolTimeline={mergedOptions.showToolTimeline}\n />\n\n {/* Input */}\n <ChatInput\n onSend={handleSend}\n disabled={chat.isLoading}\n placeholder={mergedOptions.inputPlaceholder}\n enableFileUploads={mergedOptions.enableFileUploads}\n allowedFileTypes={mergedOptions.allowedFileTypes}\n maxFileSize={mergedOptions.maxFileSize}\n />\n </div>\n\n {/* Trigger button (when drawer is closed) */}\n {!isOpen && (\n <button\n className=\"devic-trigger\"\n onClick={handleOpen}\n style={triggerStyle}\n type=\"button\"\n aria-label=\"Open chat\"\n >\n <ChatIcon />\n </button>\n )}\n </>\n );\n}\n\n/**\n * Close icon\n */\nfunction CloseIcon(): JSX.Element {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n\n/**\n * Chat icon for trigger button\n */\nfunction ChatIcon(): JSX.Element {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <path d=\"M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z\" />\n </svg>\n );\n}\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import type { ChatMessage, ModelInterfaceTool, ChatFile } from '../../api/types';
|
|
2
|
+
/**
|
|
3
|
+
* Allowed file types for upload
|
|
4
|
+
*/
|
|
5
|
+
export interface AllowedFileTypes {
|
|
6
|
+
images?: boolean;
|
|
7
|
+
documents?: boolean;
|
|
8
|
+
audio?: boolean;
|
|
9
|
+
video?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* ChatDrawer display options
|
|
13
|
+
*/
|
|
14
|
+
export interface ChatDrawerOptions {
|
|
15
|
+
/**
|
|
16
|
+
* Drawer position
|
|
17
|
+
* @default 'right'
|
|
18
|
+
*/
|
|
19
|
+
position?: 'left' | 'right';
|
|
20
|
+
/**
|
|
21
|
+
* Drawer width in pixels
|
|
22
|
+
* @default 400
|
|
23
|
+
*/
|
|
24
|
+
width?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Whether drawer starts open
|
|
27
|
+
* @default false
|
|
28
|
+
*/
|
|
29
|
+
defaultOpen?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Primary color for theming
|
|
32
|
+
* @default '#1890ff'
|
|
33
|
+
*/
|
|
34
|
+
color?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Welcome message shown at start
|
|
37
|
+
*/
|
|
38
|
+
welcomeMessage?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Suggested messages to display as quick actions
|
|
41
|
+
*/
|
|
42
|
+
suggestedMessages?: string[];
|
|
43
|
+
/**
|
|
44
|
+
* Enable file uploads
|
|
45
|
+
* @default false
|
|
46
|
+
*/
|
|
47
|
+
enableFileUploads?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Allowed file types for upload
|
|
50
|
+
*/
|
|
51
|
+
allowedFileTypes?: AllowedFileTypes;
|
|
52
|
+
/**
|
|
53
|
+
* Maximum file size in bytes
|
|
54
|
+
* @default 10485760 (10MB)
|
|
55
|
+
*/
|
|
56
|
+
maxFileSize?: number;
|
|
57
|
+
/**
|
|
58
|
+
* Placeholder text for input
|
|
59
|
+
* @default 'Type a message...'
|
|
60
|
+
*/
|
|
61
|
+
inputPlaceholder?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Title displayed in header
|
|
64
|
+
*/
|
|
65
|
+
title?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Show tool execution timeline
|
|
68
|
+
* @default true
|
|
69
|
+
*/
|
|
70
|
+
showToolTimeline?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Z-index for the drawer
|
|
73
|
+
* @default 1000
|
|
74
|
+
*/
|
|
75
|
+
zIndex?: number;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Props for the ChatDrawer component
|
|
79
|
+
*/
|
|
80
|
+
export interface ChatDrawerProps {
|
|
81
|
+
/**
|
|
82
|
+
* Assistant identifier
|
|
83
|
+
*/
|
|
84
|
+
assistantId: string;
|
|
85
|
+
/**
|
|
86
|
+
* Existing chat UID to continue conversation
|
|
87
|
+
*/
|
|
88
|
+
chatUid?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Display and behavior options
|
|
91
|
+
*/
|
|
92
|
+
options?: ChatDrawerOptions;
|
|
93
|
+
/**
|
|
94
|
+
* Tools enabled from assistant's configured tool groups
|
|
95
|
+
*/
|
|
96
|
+
enabledTools?: string[];
|
|
97
|
+
/**
|
|
98
|
+
* Client-side tools for model interface protocol
|
|
99
|
+
*/
|
|
100
|
+
modelInterfaceTools?: ModelInterfaceTool[];
|
|
101
|
+
/**
|
|
102
|
+
* Tenant ID (overrides provider)
|
|
103
|
+
*/
|
|
104
|
+
tenantId?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Tenant metadata (overrides provider)
|
|
107
|
+
*/
|
|
108
|
+
tenantMetadata?: Record<string, any>;
|
|
109
|
+
/**
|
|
110
|
+
* API key (overrides provider)
|
|
111
|
+
*/
|
|
112
|
+
apiKey?: string;
|
|
113
|
+
/**
|
|
114
|
+
* Base URL (overrides provider)
|
|
115
|
+
*/
|
|
116
|
+
baseUrl?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Callback when a message is sent
|
|
119
|
+
*/
|
|
120
|
+
onMessageSent?: (message: ChatMessage) => void;
|
|
121
|
+
/**
|
|
122
|
+
* Callback when a message is received
|
|
123
|
+
*/
|
|
124
|
+
onMessageReceived?: (message: ChatMessage) => void;
|
|
125
|
+
/**
|
|
126
|
+
* Callback when a tool is called
|
|
127
|
+
*/
|
|
128
|
+
onToolCall?: (toolName: string, params: any) => void;
|
|
129
|
+
/**
|
|
130
|
+
* Callback when an error occurs
|
|
131
|
+
*/
|
|
132
|
+
onError?: (error: Error) => void;
|
|
133
|
+
/**
|
|
134
|
+
* Callback when chat is created
|
|
135
|
+
*/
|
|
136
|
+
onChatCreated?: (chatUid: string) => void;
|
|
137
|
+
/**
|
|
138
|
+
* Callback when drawer opens
|
|
139
|
+
*/
|
|
140
|
+
onOpen?: () => void;
|
|
141
|
+
/**
|
|
142
|
+
* Callback when drawer closes
|
|
143
|
+
*/
|
|
144
|
+
onClose?: () => void;
|
|
145
|
+
/**
|
|
146
|
+
* External control of open state
|
|
147
|
+
*/
|
|
148
|
+
isOpen?: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Additional class name
|
|
151
|
+
*/
|
|
152
|
+
className?: string;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Props for ChatMessages component
|
|
156
|
+
*/
|
|
157
|
+
export interface ChatMessagesProps {
|
|
158
|
+
messages: ChatMessage[];
|
|
159
|
+
isLoading: boolean;
|
|
160
|
+
welcomeMessage?: string;
|
|
161
|
+
suggestedMessages?: string[];
|
|
162
|
+
onSuggestedClick?: (message: string) => void;
|
|
163
|
+
showToolTimeline?: boolean;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Props for ChatInput component
|
|
167
|
+
*/
|
|
168
|
+
export interface ChatInputProps {
|
|
169
|
+
onSend: (message: string, files?: ChatFile[]) => void;
|
|
170
|
+
disabled?: boolean;
|
|
171
|
+
placeholder?: string;
|
|
172
|
+
enableFileUploads?: boolean;
|
|
173
|
+
allowedFileTypes?: AllowedFileTypes;
|
|
174
|
+
maxFileSize?: number;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Props for ToolTimeline component
|
|
178
|
+
*/
|
|
179
|
+
export interface ToolTimelineProps {
|
|
180
|
+
toolCalls: Array<{
|
|
181
|
+
id: string;
|
|
182
|
+
name: string;
|
|
183
|
+
status: 'pending' | 'executing' | 'completed' | 'error';
|
|
184
|
+
result?: any;
|
|
185
|
+
error?: string;
|
|
186
|
+
timestamp: number;
|
|
187
|
+
}>;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Trigger button position
|
|
191
|
+
*/
|
|
192
|
+
export interface TriggerPosition {
|
|
193
|
+
bottom?: number;
|
|
194
|
+
right?: number;
|
|
195
|
+
left?: number;
|
|
196
|
+
top?: number;
|
|
197
|
+
}
|