@qafka/react-native 2.0.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/CHANGELOG.md +12 -0
- package/CONTRIBUTING.md +92 -0
- package/LICENSE +22 -0
- package/README.md +109 -0
- package/SECURITY.md +67 -0
- package/android/build.gradle +35 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/qafka/attestation/QafkaAttestationModule.kt +92 -0
- package/android/src/main/java/com/qafka/attestation/QafkaAttestationPackage.kt +22 -0
- package/android/src/main/java/com/qafka/audio/QafkaAudioModule.kt +290 -0
- package/android/src/main/java/com/qafka/clipboard/QafkaClipboardModule.kt +28 -0
- package/android/src/main/java/com/qafka/storage/QafkaStorageModule.kt +80 -0
- package/app.plugin.js +1 -0
- package/dist/QafkaSDK.d.ts +174 -0
- package/dist/QafkaSDK.js +461 -0
- package/dist/cards/bindings/resolveFieldName.d.ts +25 -0
- package/dist/cards/bindings/resolveFieldName.js +82 -0
- package/dist/cards/cta/CardContext.d.ts +16 -0
- package/dist/cards/cta/CardContext.js +58 -0
- package/dist/cards/cta/dispatcher.d.ts +7 -0
- package/dist/cards/cta/dispatcher.js +90 -0
- package/dist/cards/cta/types.d.ts +66 -0
- package/dist/cards/cta/types.js +2 -0
- package/dist/cards/index.d.ts +20 -0
- package/dist/cards/index.js +34 -0
- package/dist/cards/primitives/QButton.d.ts +10 -0
- package/dist/cards/primitives/QButton.js +115 -0
- package/dist/cards/primitives/QDivider.d.ts +7 -0
- package/dist/cards/primitives/QDivider.js +17 -0
- package/dist/cards/primitives/QIcon.d.ts +13 -0
- package/dist/cards/primitives/QIcon.js +26 -0
- package/dist/cards/primitives/QImage.d.ts +9 -0
- package/dist/cards/primitives/QImage.js +22 -0
- package/dist/cards/primitives/QText.d.ts +9 -0
- package/dist/cards/primitives/QText.js +30 -0
- package/dist/cards/primitives/QView.d.ts +8 -0
- package/dist/cards/primitives/QView.js +19 -0
- package/dist/cards/renderer/CardRenderer.d.ts +19 -0
- package/dist/cards/renderer/CardRenderer.js +64 -0
- package/dist/cards/renderer/renderNode.d.ts +13 -0
- package/dist/cards/renderer/renderNode.js +42 -0
- package/dist/cards/types.d.ts +110 -0
- package/dist/cards/types.js +6 -0
- package/dist/components/ActionResultBadge.d.ts +12 -0
- package/dist/components/ActionResultBadge.js +58 -0
- package/dist/components/ChatPage.d.ts +44 -0
- package/dist/components/ChatPage.js +84 -0
- package/dist/components/DataChip.d.ts +8 -0
- package/dist/components/DataChip.js +80 -0
- package/dist/components/DataChipList.d.ts +13 -0
- package/dist/components/DataChipList.js +21 -0
- package/dist/components/FloatingButton.d.ts +11 -0
- package/dist/components/FloatingButton.js +162 -0
- package/dist/components/InputArea.d.ts +57 -0
- package/dist/components/InputArea.js +142 -0
- package/dist/components/MarkdownText.d.ts +15 -0
- package/dist/components/MarkdownText.js +283 -0
- package/dist/components/MessageBubble.d.ts +134 -0
- package/dist/components/MessageBubble.js +384 -0
- package/dist/components/NavigationSuggestion.d.ts +11 -0
- package/dist/components/NavigationSuggestion.js +109 -0
- package/dist/components/Qafka.d.ts +39 -0
- package/dist/components/Qafka.handlers.d.ts +21 -0
- package/dist/components/Qafka.handlers.js +54 -0
- package/dist/components/Qafka.js +493 -0
- package/dist/components/Qafka.styles.d.ts +19 -0
- package/dist/components/Qafka.styles.js +101 -0
- package/dist/components/Qafka.types.d.ts +744 -0
- package/dist/components/Qafka.types.js +2 -0
- package/dist/components/Qafka.utils.d.ts +7 -0
- package/dist/components/Qafka.utils.js +34 -0
- package/dist/components/QafkaProvider.d.ts +12 -0
- package/dist/components/QafkaProvider.js +87 -0
- package/dist/components/QuickReplies.d.ts +14 -0
- package/dist/components/QuickReplies.js +48 -0
- package/dist/components/StepProgressIndicator.d.ts +12 -0
- package/dist/components/StepProgressIndicator.js +48 -0
- package/dist/components/SuggestionButton.d.ts +42 -0
- package/dist/components/SuggestionButton.js +67 -0
- package/dist/components/ToolStatusPill.d.ts +20 -0
- package/dist/components/ToolStatusPill.js +43 -0
- package/dist/components/TypingIndicator.d.ts +28 -0
- package/dist/components/TypingIndicator.js +109 -0
- package/dist/components/VoicePage.d.ts +48 -0
- package/dist/components/VoicePage.js +683 -0
- package/dist/components/defaults/DefaultCard.d.ts +14 -0
- package/dist/components/defaults/DefaultCard.js +156 -0
- package/dist/components/defaults/DefaultDetail.d.ts +14 -0
- package/dist/components/defaults/DefaultDetail.js +138 -0
- package/dist/components/defaults/DefaultList.d.ts +12 -0
- package/dist/components/defaults/DefaultList.js +98 -0
- package/dist/components/defaults/DefaultTable.d.ts +14 -0
- package/dist/components/defaults/DefaultTable.js +204 -0
- package/dist/components/defaults/index.d.ts +14 -0
- package/dist/components/defaults/index.js +25 -0
- package/dist/components/index.d.ts +22 -0
- package/dist/components/index.js +36 -0
- package/dist/constants.d.ts +10 -0
- package/dist/constants.js +13 -0
- package/dist/hooks/useChatMessages.d.ts +72 -0
- package/dist/hooks/useChatMessages.js +505 -0
- package/dist/hooks/useContextManager.d.ts +12 -0
- package/dist/hooks/useContextManager.js +46 -0
- package/dist/hooks/useProjectTheme.d.ts +19 -0
- package/dist/hooks/useProjectTheme.js +163 -0
- package/dist/hooks/useSDK.d.ts +31 -0
- package/dist/hooks/useSDK.js +103 -0
- package/dist/hooks/useVoiceChat.d.ts +110 -0
- package/dist/hooks/useVoiceChat.js +436 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +59 -0
- package/dist/native/QafkaAttestation.d.ts +23 -0
- package/dist/native/QafkaAttestation.js +70 -0
- package/dist/native/QafkaAudio.d.ts +14 -0
- package/dist/native/QafkaAudio.js +31 -0
- package/dist/native/QafkaClipboard.d.ts +11 -0
- package/dist/native/QafkaClipboard.js +14 -0
- package/dist/native/QafkaStorage.d.ts +15 -0
- package/dist/native/QafkaStorage.js +12 -0
- package/dist/resolve-project-config.d.ts +35 -0
- package/dist/resolve-project-config.js +41 -0
- package/dist/runtime-config-loader.d.ts +37 -0
- package/dist/runtime-config-loader.js +53 -0
- package/dist/services/AttestationManager.d.ts +38 -0
- package/dist/services/AttestationManager.js +296 -0
- package/dist/services/BackendService.d.ts +156 -0
- package/dist/services/BackendService.js +755 -0
- package/dist/services/ConversationManager.d.ts +43 -0
- package/dist/services/ConversationManager.js +96 -0
- package/dist/services/NavigationHandler.d.ts +29 -0
- package/dist/services/NavigationHandler.js +70 -0
- package/dist/services/RealtimeService.d.ts +83 -0
- package/dist/services/RealtimeService.js +203 -0
- package/dist/services/storage.d.ts +11 -0
- package/dist/services/storage.js +15 -0
- package/dist/services/storageCore.d.ts +17 -0
- package/dist/services/storageCore.js +46 -0
- package/dist/themes/dark.d.ts +5 -0
- package/dist/themes/dark.js +129 -0
- package/dist/themes/index.d.ts +12 -0
- package/dist/themes/index.js +33 -0
- package/dist/themes/light.d.ts +5 -0
- package/dist/themes/light.js +129 -0
- package/dist/themes/types.d.ts +155 -0
- package/dist/themes/types.js +5 -0
- package/dist/types/chat.d.ts +126 -0
- package/dist/types/chat.js +5 -0
- package/dist/types/components.d.ts +56 -0
- package/dist/types/components.js +16 -0
- package/dist/types/external-navigation.d.ts +19 -0
- package/dist/types/external-navigation.js +8 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.js +25 -0
- package/dist/types/navigation.d.ts +86 -0
- package/dist/types/navigation.js +5 -0
- package/dist/types/sdk.d.ts +36 -0
- package/dist/types/sdk.js +5 -0
- package/dist/utils/deepMerge.d.ts +46 -0
- package/dist/utils/deepMerge.js +70 -0
- package/dist/utils/fontUtils.d.ts +8 -0
- package/dist/utils/fontUtils.js +16 -0
- package/dist/validate-end-user.d.ts +18 -0
- package/dist/validate-end-user.js +74 -0
- package/expo-plugin/withQafkaAttestation.js +57 -0
- package/ios/QafkaAttestation.m +25 -0
- package/ios/QafkaAttestation.swift +128 -0
- package/ios/QafkaAudio.m +23 -0
- package/ios/QafkaAudio.swift +519 -0
- package/ios/QafkaClipboard.m +10 -0
- package/ios/QafkaClipboard.swift +21 -0
- package/ios/QafkaReactImports.h +2 -0
- package/ios/QafkaStorage.m +26 -0
- package/ios/QafkaStorage.swift +118 -0
- package/package.json +82 -0
- package/qafka.config.d.ts +9 -0
- package/qafka.config.js +9 -0
- package/react-native-qafka.podspec +28 -0
- package/react-native.config.js +14 -0
|
@@ -0,0 +1,744 @@
|
|
|
1
|
+
import { ViewStyle } from 'react-native';
|
|
2
|
+
import { Theme, ThemeOverride } from '../themes';
|
|
3
|
+
import { ComponentRegistry } from '../types/components';
|
|
4
|
+
import { ExternalSuggestion } from '../types/external-navigation';
|
|
5
|
+
import { NavigationSuggestion } from '../types/navigation';
|
|
6
|
+
import { VoiceChatState } from './VoicePage';
|
|
7
|
+
/**
|
|
8
|
+
* Augmentation hook for consumer-side projectId literal types.
|
|
9
|
+
*
|
|
10
|
+
* The Qafka CLI generates a `qafka.config.d.ts` file alongside
|
|
11
|
+
* `qafka.config.js` whenever it writes the runtime config. That `.d.ts`
|
|
12
|
+
* augments this interface with the consumer's project ids as keys —
|
|
13
|
+
* giving `<Qafka projectId="..." />` autocomplete + typo validation.
|
|
14
|
+
*
|
|
15
|
+
* When the augmentation is absent (fresh project, `qafka init` not yet
|
|
16
|
+
* run), `keyof QafkaProjectIds` is `never` and `ProjectIdOf` falls back
|
|
17
|
+
* to plain `string` for backwards compatibility.
|
|
18
|
+
*
|
|
19
|
+
* Consumers don't interact with this interface directly — the CLI manages it.
|
|
20
|
+
*/
|
|
21
|
+
export interface QafkaProjectIds {
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolves to the consumer's registered project ids (literal union) when
|
|
25
|
+
* the CLI-generated `qafka.config.d.ts` has populated `QafkaProjectIds`,
|
|
26
|
+
* or to `string` otherwise.
|
|
27
|
+
*/
|
|
28
|
+
export type ProjectIdOf = [keyof QafkaProjectIds] extends [never] ? string : keyof QafkaProjectIds;
|
|
29
|
+
/**
|
|
30
|
+
* Controls what `addResponse` does inside an `onToolSuggested` handler.
|
|
31
|
+
* Same semantics in both voice and text chat.
|
|
32
|
+
*
|
|
33
|
+
* - `"ui"`: Only update the rendered tool UI / chat card. Does NOT close the
|
|
34
|
+
* tool flow. Use for progress updates, optimistic state, or partial render
|
|
35
|
+
* before the real result arrives. You MUST eventually call `addResponse`
|
|
36
|
+
* again with `"both"` or `"data"` to close the tool out.
|
|
37
|
+
* - `"data"`: Commit the tool flow without touching the UI.
|
|
38
|
+
* - `"both"` (default): UI render + commit.
|
|
39
|
+
*/
|
|
40
|
+
export type ToolResponseMode = 'ui' | 'data' | 'both';
|
|
41
|
+
/**
|
|
42
|
+
* Props passed to custom voice indicator component.
|
|
43
|
+
*
|
|
44
|
+
* `isMuted` reflects the user's manual mute toggle, not the internal
|
|
45
|
+
* tool-flow mute. Use it to dim or otherwise mark the indicator while the
|
|
46
|
+
* user has the mic off.
|
|
47
|
+
*/
|
|
48
|
+
export interface VoiceIndicatorProps {
|
|
49
|
+
state: VoiceChatState;
|
|
50
|
+
amplitude: number;
|
|
51
|
+
theme: Theme;
|
|
52
|
+
isMuted?: boolean;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Props passed to a custom voice mute button. Same shape across all three
|
|
56
|
+
* VoicePage layouts (centered orb, chat layout, compact tool bar); the
|
|
57
|
+
* layout decides where to place it, the component only renders the control.
|
|
58
|
+
*/
|
|
59
|
+
export interface VoiceMuteButtonProps {
|
|
60
|
+
isMuted: boolean;
|
|
61
|
+
onToggle: () => void;
|
|
62
|
+
theme: Theme;
|
|
63
|
+
state: VoiceChatState;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Props passed to custom voice background component
|
|
67
|
+
*/
|
|
68
|
+
export interface VoiceBackgroundProps {
|
|
69
|
+
state: VoiceChatState;
|
|
70
|
+
amplitude: number;
|
|
71
|
+
theme: Theme;
|
|
72
|
+
children: React.ReactNode;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* One completed conversational turn captured during a voice session. Live
|
|
76
|
+
* (still-streaming) AI text and just-finalized-but-not-yet-pushed user text
|
|
77
|
+
* are NOT in here — those are still on `transcript` / `userTranscript`.
|
|
78
|
+
*/
|
|
79
|
+
export interface VoiceTranscriptTurn {
|
|
80
|
+
id: string;
|
|
81
|
+
role: 'user' | 'assistant';
|
|
82
|
+
text: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Render mode for the voice transcript area.
|
|
86
|
+
*
|
|
87
|
+
* - `"centered"`: a single line of the current AI transcript centered above
|
|
88
|
+
* the state label. Minimal vertical footprint. No history.
|
|
89
|
+
* - `"chat"`: scrolling chat history of both user and AI turns, lightweight
|
|
90
|
+
* (no bubble backgrounds, role-aligned, older turns fade) so it stays
|
|
91
|
+
* visually distinct from text mode. While a tool is rendered on screen,
|
|
92
|
+
* the chat collapses automatically — the compact status bar takes over,
|
|
93
|
+
* and the chat reappears when the tool UI is dismissed.
|
|
94
|
+
* - `"off"`: transcripts and state label hidden. Only the orb is visible.
|
|
95
|
+
*/
|
|
96
|
+
export type VoiceTranscriptMode = 'off' | 'centered' | 'chat';
|
|
97
|
+
/**
|
|
98
|
+
* Props passed to custom voice transcript component.
|
|
99
|
+
*
|
|
100
|
+
* `history` and `mode` are only populated when the consumer opts into
|
|
101
|
+
* `voiceTranscript="chat"`. For the default `"centered"` mode, the custom
|
|
102
|
+
* component should rely on the live `transcript` string only.
|
|
103
|
+
*/
|
|
104
|
+
export interface VoiceTranscriptProps {
|
|
105
|
+
transcript: string;
|
|
106
|
+
userTranscript: string;
|
|
107
|
+
state: VoiceChatState;
|
|
108
|
+
theme: Theme;
|
|
109
|
+
mode?: VoiceTranscriptMode;
|
|
110
|
+
history?: VoiceTranscriptTurn[];
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Custom voice components registry
|
|
114
|
+
* Allows customers to provide their own Lottie, GIF, Image, or any React component
|
|
115
|
+
* for the voice chat UI. If not provided, defaults are used.
|
|
116
|
+
*/
|
|
117
|
+
export interface VoiceComponents {
|
|
118
|
+
VoiceIndicator?: React.ComponentType<VoiceIndicatorProps>;
|
|
119
|
+
VoiceBackground?: React.ComponentType<VoiceBackgroundProps>;
|
|
120
|
+
VoiceTranscript?: React.ComponentType<VoiceTranscriptProps>;
|
|
121
|
+
/**
|
|
122
|
+
* Slot for the manual mute toggle rendered on the right side of the orb
|
|
123
|
+
* row in every voice layout. Defaults to a circular icon button.
|
|
124
|
+
*/
|
|
125
|
+
VoiceMuteButton?: React.ComponentType<VoiceMuteButtonProps>;
|
|
126
|
+
/**
|
|
127
|
+
* Slot for the multi-chip list rendered when the AI calls the built-in
|
|
128
|
+
* `qafka_display` tool with mode="chip".
|
|
129
|
+
*/
|
|
130
|
+
dataChipList?: React.ComponentType<{
|
|
131
|
+
items: Array<{
|
|
132
|
+
label: string;
|
|
133
|
+
value: string;
|
|
134
|
+
copyable?: boolean;
|
|
135
|
+
}>;
|
|
136
|
+
theme?: any;
|
|
137
|
+
}>;
|
|
138
|
+
/**
|
|
139
|
+
* Slot for an individual chip used inside the default DataChipList.
|
|
140
|
+
*/
|
|
141
|
+
dataChip?: React.ComponentType<{
|
|
142
|
+
label: string;
|
|
143
|
+
value: string;
|
|
144
|
+
copyable?: boolean;
|
|
145
|
+
theme?: any;
|
|
146
|
+
}>;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Imperative handle returned by Qafka via `ref`.
|
|
150
|
+
*
|
|
151
|
+
* Use when your custom logic has async work outside of `onToolSuggested`
|
|
152
|
+
* (e.g. the developer is driving a multi-step flow manually).
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* const qafkaRef = useRef<QafkaHandle>(null);
|
|
156
|
+
* qafkaRef.current?.setLoading(true, 'Fetching data...');
|
|
157
|
+
* // ...do work...
|
|
158
|
+
* qafkaRef.current?.setLoading(false);
|
|
159
|
+
*
|
|
160
|
+
* <Qafka ref={qafkaRef} />
|
|
161
|
+
*/
|
|
162
|
+
export interface QafkaHandle {
|
|
163
|
+
/**
|
|
164
|
+
* Manually control the voice-mode loading pill + mic pause state.
|
|
165
|
+
* Use when your custom logic has async work outside of onToolSuggested.
|
|
166
|
+
*
|
|
167
|
+
* @param visible - true to show pill + pause mic, false to hide + resume
|
|
168
|
+
* @param message - optional pill text. Defaults to "Processing…" when omitted.
|
|
169
|
+
*/
|
|
170
|
+
setLoading(visible: boolean, message?: string): void;
|
|
171
|
+
/**
|
|
172
|
+
* Clear all currently rendered voice tool UI cards. Useful when starting
|
|
173
|
+
* a fresh interaction or when the consumer wants to reset the view
|
|
174
|
+
* outside of the tool-result flow.
|
|
175
|
+
*/
|
|
176
|
+
clearRenderedTools(): void;
|
|
177
|
+
/**
|
|
178
|
+
* Send a text message to the AI as if the user typed it. Triggers the
|
|
179
|
+
* normal message-send pipeline — streaming reply, tool suggestions, etc.
|
|
180
|
+
* Useful for quick-reply buttons, deep links, or programmatic prompts.
|
|
181
|
+
*/
|
|
182
|
+
sendMessage(text: string): void;
|
|
183
|
+
/**
|
|
184
|
+
* Open the realtime voice session programmatically. Same as the user
|
|
185
|
+
* tapping the mic button.
|
|
186
|
+
*/
|
|
187
|
+
connectVoice(): Promise<void>;
|
|
188
|
+
/**
|
|
189
|
+
* Close the realtime voice session programmatically. Safe to call when
|
|
190
|
+
* already disconnected (no-op).
|
|
191
|
+
*/
|
|
192
|
+
disconnectVoice(): Promise<void>;
|
|
193
|
+
/**
|
|
194
|
+
* Pause microphone capture without ending the voice session. The AI keeps
|
|
195
|
+
* speaking, the user just cannot be heard until {@link resumeMic} is
|
|
196
|
+
* called. Useful for push-to-talk patterns or letting the user mute
|
|
197
|
+
* temporarily.
|
|
198
|
+
*/
|
|
199
|
+
pauseMic(): Promise<void>;
|
|
200
|
+
/**
|
|
201
|
+
* Resume microphone capture after a {@link pauseMic} call. Idempotent —
|
|
202
|
+
* safe to call when the mic is already active.
|
|
203
|
+
*/
|
|
204
|
+
resumeMic(): Promise<void>;
|
|
205
|
+
/**
|
|
206
|
+
* Manually toggle the user-controlled mute. Independent from the internal
|
|
207
|
+
* tool-flow mute the SDK applies during AI / tool transitions — user mute
|
|
208
|
+
* persists across those, matching Teams/Zoom semantics.
|
|
209
|
+
*/
|
|
210
|
+
toggleMute(): void;
|
|
211
|
+
/**
|
|
212
|
+
* Engage the user mute. Idempotent.
|
|
213
|
+
*/
|
|
214
|
+
mute(): void;
|
|
215
|
+
/**
|
|
216
|
+
* Lift the user mute. Idempotent. If a tool flow is currently muting the
|
|
217
|
+
* mic internally, the mic stays off until that flow completes.
|
|
218
|
+
*/
|
|
219
|
+
unmute(): void;
|
|
220
|
+
/**
|
|
221
|
+
* Whether the user has the mic muted right now. Reflects the user toggle
|
|
222
|
+
* only, not the internal tool-flow mute.
|
|
223
|
+
*/
|
|
224
|
+
readonly isMuted: boolean;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Props for Qafka Component
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* // Basic usage
|
|
231
|
+
* <Qafka projectId="proj_abc123" />
|
|
232
|
+
*/
|
|
233
|
+
export interface QafkaProps {
|
|
234
|
+
style?: ViewStyle;
|
|
235
|
+
/**
|
|
236
|
+
* Project identifier when the runtime config registers more than one
|
|
237
|
+
* project. Selects which project's development key the SDK uses in
|
|
238
|
+
* development builds (loaded from `qafka.config.js`).
|
|
239
|
+
*
|
|
240
|
+
* Leave undefined to use the runtime config's default project. Pass a
|
|
241
|
+
* project id that is unknown to the runtime config and the SDK throws on
|
|
242
|
+
* mount — silent fallback would mask a typo.
|
|
243
|
+
*
|
|
244
|
+
* In production builds this prop is ignored by the key-resolution path,
|
|
245
|
+
* which does not rely on a bundled key.
|
|
246
|
+
*
|
|
247
|
+
* When the Qafka CLI has been run (`qafka init` / `qafka project` /
|
|
248
|
+
* `qafka sync`), this prop is narrowed to the registered project ids —
|
|
249
|
+
* giving autocomplete and typo validation. Without the CLI augmentation
|
|
250
|
+
* the type falls back to `string` for backwards compatibility.
|
|
251
|
+
*
|
|
252
|
+
* @example "proj_abc123"
|
|
253
|
+
*/
|
|
254
|
+
projectId?: ProjectIdOf;
|
|
255
|
+
/**
|
|
256
|
+
* Backend API URL (OPTIONAL — advanced, leave unset for production).
|
|
257
|
+
*/
|
|
258
|
+
apiUrl?: string;
|
|
259
|
+
/**
|
|
260
|
+
* Sub-Project Identifier (OPTIONAL)
|
|
261
|
+
*
|
|
262
|
+
* Used for multi-tenant setups where a single project serves multiple
|
|
263
|
+
* sub-projects (e.g., per-region or per-tenant rollouts).
|
|
264
|
+
*
|
|
265
|
+
* When provided, sub-project routing is applied server-side.
|
|
266
|
+
* If omitted, the parent project is used directly (backward compatible).
|
|
267
|
+
*
|
|
268
|
+
* @example "tenant-a"
|
|
269
|
+
*/
|
|
270
|
+
subProjectId?: string;
|
|
271
|
+
/**
|
|
272
|
+
* BCP 47 locale (e.g. "tr", "en", "tr-TR").
|
|
273
|
+
*
|
|
274
|
+
* Drives UI strings (placeholder, buttons, dashboard-supplied multi-locale
|
|
275
|
+
* greeting) and is forwarded to the backend as part of `sdkContext.locale`.
|
|
276
|
+
* Pair with the server-side language priority rule: when set, the AI
|
|
277
|
+
* answers in this locale unless project instructions explicitly demand
|
|
278
|
+
* another language.
|
|
279
|
+
*
|
|
280
|
+
* Leave undefined to fall back to whatever language the project
|
|
281
|
+
* instructions are written in.
|
|
282
|
+
*
|
|
283
|
+
* @example "tr"
|
|
284
|
+
* @example "en-US"
|
|
285
|
+
*/
|
|
286
|
+
locale?: string;
|
|
287
|
+
/**
|
|
288
|
+
* Widget display mode
|
|
289
|
+
*/
|
|
290
|
+
mode?: 'fullscreen' | 'inline' | 'floating';
|
|
291
|
+
/**
|
|
292
|
+
* Theme mode or custom theme object
|
|
293
|
+
*/
|
|
294
|
+
theme?: 'light' | 'dark' | Theme;
|
|
295
|
+
/**
|
|
296
|
+
* Theme overrides (partial theme)
|
|
297
|
+
* Allows overriding specific theme properties without replacing the entire theme
|
|
298
|
+
* @example { colors: { background: '#FF0000' } }
|
|
299
|
+
*/
|
|
300
|
+
themeOverride?: ThemeOverride;
|
|
301
|
+
/**
|
|
302
|
+
* Full custom theme that replaces the default theme entirely. Pair this with
|
|
303
|
+
* `themeOverride` only when you need to merge partial overrides on top.
|
|
304
|
+
*/
|
|
305
|
+
customTheme?: Theme;
|
|
306
|
+
/**
|
|
307
|
+
* Enable streaming responses (real-time typing effect)
|
|
308
|
+
*/
|
|
309
|
+
enableStreaming?: boolean;
|
|
310
|
+
/**
|
|
311
|
+
* Whether the current user is authenticated.
|
|
312
|
+
* Controls which screens are suggested in navigation:
|
|
313
|
+
* - true: authenticated screens suggested, unauthenticated screens hidden
|
|
314
|
+
* - false: unauthenticated screens suggested, authenticated screens hidden
|
|
315
|
+
* - undefined: backward compatible behavior (all screens suggested)
|
|
316
|
+
*
|
|
317
|
+
* @example isAuthenticated={!!user}
|
|
318
|
+
*/
|
|
319
|
+
isAuthenticated?: boolean;
|
|
320
|
+
/**
|
|
321
|
+
* Stable identifier for the end user using this SDK instance.
|
|
322
|
+
*
|
|
323
|
+
* Required. The backend uses this id to group conversations, action logs,
|
|
324
|
+
* and audience analytics per user. Send a constant placeholder
|
|
325
|
+
* (`"anonymous"`, `"anon-${deviceId}"`, ...) before the user signs in so
|
|
326
|
+
* pre-login activity still has a stable lane.
|
|
327
|
+
*
|
|
328
|
+
* The value is validated on mount and on every chat request:
|
|
329
|
+
* - empty / null / whitespace → runtime Error
|
|
330
|
+
* - longer than 256 characters → runtime Error
|
|
331
|
+
*
|
|
332
|
+
* Numbers are accepted and coerced to string before they leave the SDK.
|
|
333
|
+
*
|
|
334
|
+
* NOT forwarded to the LLM prompt — operator dashboards and tool action
|
|
335
|
+
* templates can reach it via `{{endUser.id}}` without leaking it to the AI.
|
|
336
|
+
*
|
|
337
|
+
* @example endUserId={user?.id ?? `anon-${deviceId}`}
|
|
338
|
+
*/
|
|
339
|
+
endUserId: string | number;
|
|
340
|
+
/**
|
|
341
|
+
* Optional structured profile data for operator dashboards and tool
|
|
342
|
+
* action templates (`{{endUser.data.<key>}}`).
|
|
343
|
+
*
|
|
344
|
+
* NEVER forwarded to the LLM prompt. If you want the AI to see something,
|
|
345
|
+
* put it in `context` instead.
|
|
346
|
+
*
|
|
347
|
+
* Limited to 8KB when serialized to JSON; exceeding the limit causes the
|
|
348
|
+
* field to be dropped from the request (with a `console.error`) — chat
|
|
349
|
+
* and tracking continue to work.
|
|
350
|
+
*
|
|
351
|
+
* @example endUserData={{ email: 'user@example.com', plan: 'pro' }}
|
|
352
|
+
*/
|
|
353
|
+
endUserData?: Record<string, unknown>;
|
|
354
|
+
/**
|
|
355
|
+
* Context object for Tool Registry.
|
|
356
|
+
* Provides runtime context to match and execute tools.
|
|
357
|
+
* @example { userId: '456', selectedItemId: '123' }
|
|
358
|
+
*/
|
|
359
|
+
context?: Record<string, any>;
|
|
360
|
+
/**
|
|
361
|
+
* Context description for the AI.
|
|
362
|
+
* Helps the AI understand what the context keys mean.
|
|
363
|
+
* @example "User is on the settings screen"
|
|
364
|
+
*/
|
|
365
|
+
contextDescription?: string;
|
|
366
|
+
/**
|
|
367
|
+
* Custom component registry for Tool Registry responses.
|
|
368
|
+
* Register your own components to render tool responses.
|
|
369
|
+
* @example { ProductCard: MyProductCard, OrderCard: MyOrderCard }
|
|
370
|
+
*/
|
|
371
|
+
components?: ComponentRegistry;
|
|
372
|
+
/**
|
|
373
|
+
* Show timestamps on messages
|
|
374
|
+
*/
|
|
375
|
+
showTimestamps?: boolean;
|
|
376
|
+
/**
|
|
377
|
+
* Input placeholder text
|
|
378
|
+
*/
|
|
379
|
+
placeholder?: string;
|
|
380
|
+
/**
|
|
381
|
+
* Header title
|
|
382
|
+
*/
|
|
383
|
+
title?: string;
|
|
384
|
+
/**
|
|
385
|
+
* Show header
|
|
386
|
+
*/
|
|
387
|
+
showHeader?: boolean;
|
|
388
|
+
/**
|
|
389
|
+
* Maximum message length
|
|
390
|
+
*/
|
|
391
|
+
maxMessageLength?: number;
|
|
392
|
+
/**
|
|
393
|
+
* Custom users greeting message (overrides Project API greeting)
|
|
394
|
+
*/
|
|
395
|
+
greetingMessage?: string;
|
|
396
|
+
/**
|
|
397
|
+
* Callback when widget is ready
|
|
398
|
+
*/
|
|
399
|
+
onReady?: () => void;
|
|
400
|
+
/**
|
|
401
|
+
* Callback when message is sent
|
|
402
|
+
*/
|
|
403
|
+
onMessageSent?: (message: string) => void;
|
|
404
|
+
/**
|
|
405
|
+
* Callback when response is received
|
|
406
|
+
*/
|
|
407
|
+
onResponseReceived?: (response: any) => void;
|
|
408
|
+
/**
|
|
409
|
+
* Callback on error
|
|
410
|
+
*/
|
|
411
|
+
onError?: (error: Error) => void;
|
|
412
|
+
/**
|
|
413
|
+
* Callback when navigation is suggested (always triggered)
|
|
414
|
+
*/
|
|
415
|
+
onNavigationSuggest?: (suggestion: NavigationSuggestion) => void;
|
|
416
|
+
/**
|
|
417
|
+
* Callback when navigation button is pressed by user.
|
|
418
|
+
* If not provided, SDK automatically navigates using `suggestion.route` via Expo Router.
|
|
419
|
+
*/
|
|
420
|
+
onNavigationAction?: (suggestion: NavigationSuggestion) => void;
|
|
421
|
+
/**
|
|
422
|
+
* Callback when an external suggestion button is pressed by user
|
|
423
|
+
* (WhatsApp, phone, map, app store, etc.).
|
|
424
|
+
*
|
|
425
|
+
* If not provided, the SDK opens the suggestion's `url` via
|
|
426
|
+
* `Linking.openURL`, falling back to `fallbackUrl` when the primary URL
|
|
427
|
+
* is not handleable on the device (e.g. the target app isn't installed).
|
|
428
|
+
*
|
|
429
|
+
* @example
|
|
430
|
+
* onExternalSuggestion={(s) => {
|
|
431
|
+
* analytics.track('external_nav_press', { type: s.type, id: s.id });
|
|
432
|
+
* Linking.openURL(s.url);
|
|
433
|
+
* }}
|
|
434
|
+
*/
|
|
435
|
+
onExternalSuggestion?: (suggestion: ExternalSuggestion) => void;
|
|
436
|
+
/**
|
|
437
|
+
* Card Template CTA host callbacks. Invoked when a button
|
|
438
|
+
* inside a rendered card fires an action that crosses the SDK boundary
|
|
439
|
+
* (deep_link, share, suggest_message, copy, external_navigation, tool_trigger).
|
|
440
|
+
*
|
|
441
|
+
* The most common one is `onCardDeepLink` — partner navigates to an internal
|
|
442
|
+
* route from a card button:
|
|
443
|
+
*
|
|
444
|
+
* @example
|
|
445
|
+
* onCardDeepLink={(path) => router.push(path)}
|
|
446
|
+
*
|
|
447
|
+
* `copy` and `share` have sensible RN defaults (Clipboard / Share.share),
|
|
448
|
+
* so partners only register them when they want custom behavior (e.g.
|
|
449
|
+
* show a toast on copy success).
|
|
450
|
+
*/
|
|
451
|
+
onCardDeepLink?: (path: string, action?: any) => void | Promise<void>;
|
|
452
|
+
onCardSuggestMessage?: (text: string) => void | Promise<void>;
|
|
453
|
+
onCardExternalNavigation?: (action: any) => void | Promise<void>;
|
|
454
|
+
onCardShare?: (payload: {
|
|
455
|
+
text?: string;
|
|
456
|
+
url?: string;
|
|
457
|
+
}) => void | Promise<void>;
|
|
458
|
+
onCardCopy?: (value: string) => void | Promise<void>;
|
|
459
|
+
/**
|
|
460
|
+
* Invoked when a card button has type "tool_trigger". The host can
|
|
461
|
+
* forward this to the SDK's tool execution path or surface it as a new
|
|
462
|
+
* chat message. Optional; if unset the action is silently skipped.
|
|
463
|
+
*/
|
|
464
|
+
onCardToolTrigger?: (toolName: string, params: Record<string, unknown>, meta: {
|
|
465
|
+
ctaDisplayMode: 'user_message' | 'silent';
|
|
466
|
+
}) => void | Promise<void>;
|
|
467
|
+
/**
|
|
468
|
+
* CTA telemetry hook — called once per click. The event payload mirrors
|
|
469
|
+
* `CardCTATelemetryEvent` from the cards module:
|
|
470
|
+
* - `item` carries the bound record (the iterated item in list mode,
|
|
471
|
+
* full tool result in detail mode), so partners don't have to look
|
|
472
|
+
* it up by index.
|
|
473
|
+
* - `itemIndex` is present only in list mode.
|
|
474
|
+
*/
|
|
475
|
+
onCardCTAClick?: (event: {
|
|
476
|
+
event: 'cta_click';
|
|
477
|
+
cardTemplateId: string;
|
|
478
|
+
cardSlug: string;
|
|
479
|
+
actionType: string;
|
|
480
|
+
toolName?: string;
|
|
481
|
+
messageId?: string;
|
|
482
|
+
itemIndex?: number;
|
|
483
|
+
item: unknown;
|
|
484
|
+
confirmed: boolean;
|
|
485
|
+
}) => void;
|
|
486
|
+
/**
|
|
487
|
+
* Callback when Tool Registry suggests tools
|
|
488
|
+
* Called during streaming when backend identifies matching tools
|
|
489
|
+
* @param tools - Array of matched tool definitions with relevance scores and customData
|
|
490
|
+
* @param addResponse - Helper function to add tool response to chat
|
|
491
|
+
* @example
|
|
492
|
+
* onToolSuggested={async (tools, addResponse) => {
|
|
493
|
+
* const tool = tools[0];
|
|
494
|
+
* // tool.customData contains any custom data you attached to this tool
|
|
495
|
+
* const response = await fetch(tool.customData.apiBaseUrl + tool.endpoint);
|
|
496
|
+
* addResponse(tool.key, await response.json(), tool);
|
|
497
|
+
* }}
|
|
498
|
+
*/
|
|
499
|
+
onToolSuggested?: (tools: any[], addResponse: (data: any, tool: any, mode?: ToolResponseMode) => void) => void | Promise<void>;
|
|
500
|
+
/**
|
|
501
|
+
* Callback when backend action execution results arrive
|
|
502
|
+
* Called during streaming when the backend sends action_result SSE events
|
|
503
|
+
* @param results - Array of action execution results
|
|
504
|
+
* @example
|
|
505
|
+
* onActionResult={(results) => {
|
|
506
|
+
* results.forEach(r => {
|
|
507
|
+
* if (r.success) Toast.show(r.message);
|
|
508
|
+
* });
|
|
509
|
+
* }}
|
|
510
|
+
*/
|
|
511
|
+
onActionResult?: (results: Array<{
|
|
512
|
+
actionType: string;
|
|
513
|
+
success: boolean;
|
|
514
|
+
message: string;
|
|
515
|
+
}>) => void;
|
|
516
|
+
/**
|
|
517
|
+
* Tool Data Channel — partner-provided resolver for transient PII bags.
|
|
518
|
+
*
|
|
519
|
+
* Partner-provided resolver invoked when a suggested tool references
|
|
520
|
+
* `{{tooldata.X}}` tokens in its email/webhook body. Returned values are
|
|
521
|
+
* POSTed to backend's request-scoped cache and substituted into action
|
|
522
|
+
* payloads — **never sent to the LLM, never written to the Qafka DB**.
|
|
523
|
+
*
|
|
524
|
+
* Backend signals the need via `needData: true` on the `tool_suggestions`
|
|
525
|
+
* SSE event. SDK calls this resolver, POSTs the resulting opaque bag to
|
|
526
|
+
* `/chat/tool-data`, backend looks it up by `toolExecutionId` when running
|
|
527
|
+
* the tool's actions (email/webhook).
|
|
528
|
+
*
|
|
529
|
+
* Resolver may be sync or async. Throwing or rejecting is fail-soft —
|
|
530
|
+
* SDK posts an empty bag and `{{tooldata.X}}` tokens resolve to empty
|
|
531
|
+
* strings on the server, allowing the action to still run (just without
|
|
532
|
+
* the substituted PII).
|
|
533
|
+
*
|
|
534
|
+
* @param tool Suggested tool descriptor (key + name).
|
|
535
|
+
* @returns Plain object of key → string/number/boolean values, OR a
|
|
536
|
+
* Promise of the same.
|
|
537
|
+
* @example
|
|
538
|
+
* onToolDataRequested={async ({ key }) => {
|
|
539
|
+
* if (key === 'sendInvoice') {
|
|
540
|
+
* const user = await store.getCurrentUser();
|
|
541
|
+
* return { gsm: user.phone, email: user.email };
|
|
542
|
+
* }
|
|
543
|
+
* return {};
|
|
544
|
+
* }}
|
|
545
|
+
*/
|
|
546
|
+
onToolDataRequested?: (tool: {
|
|
547
|
+
key: string;
|
|
548
|
+
name: string;
|
|
549
|
+
}) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
550
|
+
/** Called when a step side-effect completes during a multi-step tool flow */
|
|
551
|
+
onStepCompleted?: (result: {
|
|
552
|
+
tool: string;
|
|
553
|
+
step: string;
|
|
554
|
+
data: Record<string, any>;
|
|
555
|
+
actionResults?: Array<{
|
|
556
|
+
actionType: string;
|
|
557
|
+
success: boolean;
|
|
558
|
+
message: string;
|
|
559
|
+
}>;
|
|
560
|
+
}) => void;
|
|
561
|
+
/**
|
|
562
|
+
* Called when a tool requires file upload from the user.
|
|
563
|
+
* The app should open its own file picker and call submit() with the selected file.
|
|
564
|
+
*
|
|
565
|
+
* @example
|
|
566
|
+
* onFileUploadRequest={({ toolId, fileInput, submit, cancel }) => {
|
|
567
|
+
* ImagePicker.launchImageLibrary({ mediaType: 'photo' }, (response) => {
|
|
568
|
+
* if (response.assets?.[0]) {
|
|
569
|
+
* submit({
|
|
570
|
+
* uri: response.assets[0].uri!,
|
|
571
|
+
* name: response.assets[0].fileName!,
|
|
572
|
+
* type: response.assets[0].type!,
|
|
573
|
+
* });
|
|
574
|
+
* } else {
|
|
575
|
+
* cancel();
|
|
576
|
+
* }
|
|
577
|
+
* });
|
|
578
|
+
* }}
|
|
579
|
+
*/
|
|
580
|
+
onFileUploadRequest?: (request: {
|
|
581
|
+
toolId: string;
|
|
582
|
+
fileInput: {
|
|
583
|
+
accept: string[];
|
|
584
|
+
maxSize: number;
|
|
585
|
+
sources: string[];
|
|
586
|
+
};
|
|
587
|
+
submit: (file: {
|
|
588
|
+
uri: string;
|
|
589
|
+
name: string;
|
|
590
|
+
type: string;
|
|
591
|
+
}) => void;
|
|
592
|
+
cancel: () => void;
|
|
593
|
+
}) => void;
|
|
594
|
+
/**
|
|
595
|
+
* Called when document extraction completes after file upload.
|
|
596
|
+
* Contains the structured data extracted by AI from the uploaded document.
|
|
597
|
+
*
|
|
598
|
+
* @example
|
|
599
|
+
* onExtractionResult={({ toolId, data, status }) => {
|
|
600
|
+
* if (status === 'success') {
|
|
601
|
+
* setFormFields(data);
|
|
602
|
+
* }
|
|
603
|
+
* }}
|
|
604
|
+
*/
|
|
605
|
+
onExtractionResult?: (result: {
|
|
606
|
+
fileId: string;
|
|
607
|
+
toolId: string;
|
|
608
|
+
data: Record<string, any>;
|
|
609
|
+
status: 'success' | 'partial' | 'failed';
|
|
610
|
+
incompleteFields?: string[];
|
|
611
|
+
}) => void;
|
|
612
|
+
/** Opt-out of voice chat. Server must also allow it. Default: true */
|
|
613
|
+
voiceEnabled?: boolean;
|
|
614
|
+
/**
|
|
615
|
+
* Custom voice page components
|
|
616
|
+
* Override the default voice indicator, background, or transcript components
|
|
617
|
+
* with your own (e.g. Lottie animation, GIF, custom visuals).
|
|
618
|
+
*
|
|
619
|
+
* @example
|
|
620
|
+
* voiceComponents={{
|
|
621
|
+
* VoiceIndicator: ({ state, amplitude, theme }) => (
|
|
622
|
+
* <LottieView source={lottieFile} speed={amplitude} />
|
|
623
|
+
* ),
|
|
624
|
+
* }}
|
|
625
|
+
*/
|
|
626
|
+
voiceComponents?: VoiceComponents;
|
|
627
|
+
/**
|
|
628
|
+
* How the voice mode transcript area is displayed.
|
|
629
|
+
*
|
|
630
|
+
* - `"centered"` (default): single line of the current AI transcript above
|
|
631
|
+
* the state label. Backward-compatible with prior SDK versions.
|
|
632
|
+
* - `"chat"`: scrolling history of user + AI turns. Hands-free friendly:
|
|
633
|
+
* the chat collapses automatically when a tool result is rendered, and
|
|
634
|
+
* resumes when the tool UI is dismissed.
|
|
635
|
+
* - `"off"`: hide transcripts and state label entirely; only the orb shows.
|
|
636
|
+
*
|
|
637
|
+
* @default "centered"
|
|
638
|
+
*/
|
|
639
|
+
voiceTranscript?: VoiceTranscriptMode;
|
|
640
|
+
/**
|
|
641
|
+
* Controls how voice tool results accumulate on screen.
|
|
642
|
+
*
|
|
643
|
+
* - `"upsert"` (default): same toolKey replaces its previous entry; results
|
|
644
|
+
* from different tools coexist (e.g. `show_results` + `show_details`
|
|
645
|
+
* stack vertically). Best for browsing scenarios.
|
|
646
|
+
* - `"replace"`: every new tool result clears previous entries — only the
|
|
647
|
+
* latest single tool stays visible. Best for single-focus voice flows
|
|
648
|
+
* where switching tools means switching the whole view.
|
|
649
|
+
*
|
|
650
|
+
* @default "upsert"
|
|
651
|
+
*/
|
|
652
|
+
toolRenderMode?: 'upsert' | 'replace';
|
|
653
|
+
/**
|
|
654
|
+
* Callback when close button is pressed
|
|
655
|
+
* If provided, a close button will be shown in the top right corner
|
|
656
|
+
*/
|
|
657
|
+
onClose?: () => void;
|
|
658
|
+
/**
|
|
659
|
+
* Callback when back button is pressed
|
|
660
|
+
* If provided, a back button will be shown in the top left corner
|
|
661
|
+
*/
|
|
662
|
+
onBack?: () => void;
|
|
663
|
+
/**
|
|
664
|
+
* Custom Close Component
|
|
665
|
+
* Overrides default close button
|
|
666
|
+
*/
|
|
667
|
+
CloseComponent?: React.ComponentType<any>;
|
|
668
|
+
/**
|
|
669
|
+
* Custom Back Component
|
|
670
|
+
* Overrides default back button
|
|
671
|
+
*/
|
|
672
|
+
BackComponent?: React.ComponentType<any>;
|
|
673
|
+
/**
|
|
674
|
+
* Navigation button label format function
|
|
675
|
+
* Allows customizing the navigation button text format
|
|
676
|
+
* Receives the screen name and returns the formatted label
|
|
677
|
+
*
|
|
678
|
+
* @example
|
|
679
|
+
* // Custom format: "Navigate to Profile"
|
|
680
|
+
* navigationLabelFormat={(screenName) => `Navigate to ${screenName}`}
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* // Custom format: "Target screen: Profile"
|
|
684
|
+
* navigationLabelFormat={(screenName) => `Target screen: ${screenName}`}
|
|
685
|
+
*/
|
|
686
|
+
navigationLabelFormat?: (screenName: string) => string;
|
|
687
|
+
/**
|
|
688
|
+
* Custom Navigation Button Component
|
|
689
|
+
* Overrides the default navigation button
|
|
690
|
+
* Receives the navigation suggestion data as props
|
|
691
|
+
*
|
|
692
|
+
* @example
|
|
693
|
+
* NavigationButtonComponent={({ screenName, onPress, style }) => (
|
|
694
|
+
* <TouchableOpacity onPress={onPress} style={yourCustomStyle}>
|
|
695
|
+
* <Text>Go to {screenName}</Text>
|
|
696
|
+
* </TouchableOpacity>
|
|
697
|
+
* )}
|
|
698
|
+
*/
|
|
699
|
+
NavigationButtonComponent?: React.ComponentType<NavigationButtonProps>;
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Props for custom NavigationButtonComponent
|
|
703
|
+
*/
|
|
704
|
+
export interface NavigationButtonProps {
|
|
705
|
+
/**
|
|
706
|
+
* The suggested screen name to navigate to
|
|
707
|
+
*/
|
|
708
|
+
screenName: string;
|
|
709
|
+
/**
|
|
710
|
+
* Full navigation suggestion data from the backend
|
|
711
|
+
*/
|
|
712
|
+
suggestion: NavigationSuggestion;
|
|
713
|
+
/**
|
|
714
|
+
* Callback when button is pressed
|
|
715
|
+
*/
|
|
716
|
+
onPress: () => void;
|
|
717
|
+
/**
|
|
718
|
+
* Current theme
|
|
719
|
+
*/
|
|
720
|
+
theme: Theme;
|
|
721
|
+
/**
|
|
722
|
+
* Button style variant
|
|
723
|
+
*/
|
|
724
|
+
style?: 'primary' | 'secondary' | 'success' | 'danger' | 'warning';
|
|
725
|
+
/**
|
|
726
|
+
* The formatted label text (already formatted by navigationLabelFormat or default)
|
|
727
|
+
*/
|
|
728
|
+
label: string;
|
|
729
|
+
/**
|
|
730
|
+
* Optional icon for the button
|
|
731
|
+
*/
|
|
732
|
+
icon?: string;
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Action button type
|
|
736
|
+
*/
|
|
737
|
+
export interface ActionButton {
|
|
738
|
+
id: string;
|
|
739
|
+
type: 'navigation' | 'custom';
|
|
740
|
+
label: string;
|
|
741
|
+
icon?: string;
|
|
742
|
+
data: any;
|
|
743
|
+
style?: 'primary' | 'secondary' | 'success' | 'danger' | 'warning';
|
|
744
|
+
}
|