@sapia-ai/chatbot-v3 1.4.2 → 1.6.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/dist/{EmbeddedVideoPlayer-G554aRrZ.js → EmbeddedVideoPlayer-Bhz8DKO8.js} +14 -14
- package/dist/{Preview-CSE0hI6e.js → Preview-B1ZmYM9V.js} +3 -3
- package/dist/api/client.d.ts +9 -1
- package/dist/api/types/messages.d.ts +8 -1
- package/dist/api/types/responses.d.ts +69 -12
- package/dist/api.js +2 -2
- package/dist/{client-DG-5x86F.js → client-C2MWNOYf.js} +559 -546
- package/dist/core/bubbles/cards.d.ts +3 -1
- package/dist/core/bubbles/demographicRun.d.ts +57 -0
- package/dist/core/bubbles/selection.d.ts +3 -1
- package/dist/core/bubbles/types.d.ts +11 -0
- package/dist/core/interview/engine.d.ts +45 -5
- package/dist/core/interview/reveal.d.ts +5 -2
- package/dist/core/persistence.d.ts +4 -0
- package/dist/core/store.d.ts +15 -2
- package/dist/core/theme/branding.d.ts +5 -2
- package/dist/{dist-DsGdVwdi.js → dist-CoO0i-y0.js} +3 -3
- package/dist/embed/createChatbot.d.ts +0 -2
- package/dist/{fix-webm-duration-Bie2OG-n.js → fix-webm-duration-CXijcUXq.js} +2 -2
- package/dist/index.js +6292 -5783
- package/dist/{jsx-runtime-B5vw3nIj.js → jsx-runtime-BcXxfixh.js} +2 -2
- package/dist/react/AnswerInput.d.ts +6 -1
- package/dist/react/SapiaChatbot.d.ts +1 -3
- package/dist/react/bubbleViewModel.d.ts +21 -1
- package/dist/react/strings.d.ts +9 -4
- package/dist/react/useDemographicForm.d.ts +14 -0
- package/dist/react/useVideoRecorder.d.ts +25 -4
- package/dist/{react-CN-F_7qV.js → react-Cp-K_L89.js} +3 -3
- package/dist/{react-_TUsDaHa.js → react-D3tMg8u4.js} +3 -3
- package/dist/{react-T5LsuM9r.js → react-D8jZKei2.js} +3 -3
- package/dist/{react-B46N_vb_.js → react-DtGzNzM1.js} +3 -3
- package/dist/{react-SKFkpgRr.js → react-LDcTld2q.js} +3 -3
- package/dist/{react-Dd6J2Pyv.js → react-g5b2mM7w.js} +3 -3
- package/dist/{react-abEVBgXB.js → react-hklchtwF.js} +3 -3
- package/dist/{react-CpnhkRge.js → react-vc8uDric.js} +3 -3
- package/dist/{react-DHdgNnK2.js → react-wrZMUHWq.js} +2 -2
- package/dist/ui/chat/ActionDock/ActionDock.d.ts +5 -0
- package/dist/ui/chat/ChatLog/ChatLog.d.ts +3 -7
- package/dist/ui/chat/DemographicDetailsCard/DemographicDetailsCard.d.ts +14 -0
- package/dist/ui/chat/TypingIndicator/TypingIndicator.d.ts +9 -25
- package/dist/ui/chat/types.d.ts +13 -1
- package/dist/ui/inputs/DemographicForm/DemographicForm.d.ts +35 -0
- package/dist/ui/inputs/LocationAnswerInput/LocationCombobox.d.ts +4 -2
- package/dist/ui/inputs/OptionList/OptionList.d.ts +4 -0
- package/dist/ui/inputs/VideoRecorder/VideoRecorder.d.ts +10 -1
- package/dist/ui/inputs/formCard.d.ts +13 -0
- package/dist/ui/media/VideoPlayer/VideoPlayer.d.ts +8 -4
- package/dist/ui/primitives/Dialog/Dialog.d.ts +2 -0
- package/dist/ui/shell/AgcGuidanceDialog/AgcGuidanceDialog.d.ts +13 -0
- package/dist/ui/shell/DoneScreen/DoneScreen.d.ts +3 -1
- package/dist/ui/shell/LogoTile/LogoTile.d.ts +15 -0
- package/dist-umd/sapia-chatbot.umd.js +295 -295
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as e } from "./client-C2MWNOYf.js";
|
|
2
2
|
//#region ../../node_modules/.pnpm/react@19.2.7/node_modules/react/cjs/react-jsx-runtime.production.js
|
|
3
3
|
var t = /* @__PURE__ */ e(((e) => {
|
|
4
4
|
var t = Symbol.for("react.transitional.element"), n = Symbol.for("react.fragment");
|
|
@@ -21,4 +21,4 @@ var t = /* @__PURE__ */ e(((e) => {
|
|
|
21
21
|
//#endregion
|
|
22
22
|
export { n as t };
|
|
23
23
|
|
|
24
|
-
//# sourceMappingURL=jsx-runtime-
|
|
24
|
+
//# sourceMappingURL=jsx-runtime-BcXxfixh.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { InterviewEngine } from '../core/interview/engine';
|
|
2
2
|
import { Region } from '../api/config';
|
|
3
3
|
import { CurrentInputKind, EditingDraft, WordCountRule } from './bubbleViewModel';
|
|
4
|
+
import { SubmittedTakeSource } from './useVideoRecorder';
|
|
4
5
|
import { UiStrings } from './strings';
|
|
5
6
|
export type AnswerInputProps = {
|
|
6
7
|
engine: InterviewEngine;
|
|
@@ -16,6 +17,10 @@ export type AnswerInputProps = {
|
|
|
16
17
|
placesApiKey?: string;
|
|
17
18
|
/** Max video answer length in seconds (video questions). */
|
|
18
19
|
maxVideoSeconds?: number;
|
|
20
|
+
/** The answer a video Retry reopens for review; absent on a first recording. */
|
|
21
|
+
submittedVideo?: SubmittedTakeSource;
|
|
22
|
+
/** Question the video recorder answers, so its take count survives a reload. */
|
|
23
|
+
videoQuestionId?: string;
|
|
19
24
|
/** Stored answer to open the composer on when re-editing. */
|
|
20
25
|
draft?: EditingDraft;
|
|
21
26
|
/**
|
|
@@ -36,4 +41,4 @@ export type AnswerInputProps = {
|
|
|
36
41
|
expanded: boolean;
|
|
37
42
|
onExpandedChange: (expanded: boolean) => void;
|
|
38
43
|
};
|
|
39
|
-
export declare const AnswerInput: ({ engine, assessmentId, kind, disabled, wordCountRule, strings, candidateCountryCode, region, placesApiKey, maxVideoSeconds, draft, draftQuestionId, allowPaste, isFeedbackComment, onBlockedPaste, focusOnOpen, expanded, onExpandedChange, }: AnswerInputProps) => import("react").JSX.Element;
|
|
44
|
+
export declare const AnswerInput: ({ engine, assessmentId, kind, disabled, wordCountRule, strings, candidateCountryCode, region, placesApiKey, maxVideoSeconds, submittedVideo, videoQuestionId, draft, draftQuestionId, allowPaste, isFeedbackComment, onBlockedPaste, focusOnOpen, expanded, onExpandedChange, }: AnswerInputProps) => import("react").JSX.Element;
|
|
@@ -25,7 +25,5 @@ export type SapiaChatbotProps = {
|
|
|
25
25
|
emitter?: ChatbotEventEmitter;
|
|
26
26
|
/** @internal streaming transport override (mock SSE for the demo / tests). */
|
|
27
27
|
fetchImpl?: typeof fetch;
|
|
28
|
-
/** @internal holds the typing indicator's "reading" phrase open (demo / tests). */
|
|
29
|
-
readingPhaseMs?: number;
|
|
30
28
|
};
|
|
31
|
-
export declare const SapiaChatbot: ({ env, region, appId, assessmentId, apiOrigin, theme, showHeader, isInternalUser, language, redirectUrl, placesApiKey, onEvent, emitter, fetchImpl,
|
|
29
|
+
export declare const SapiaChatbot: ({ env, region, appId, assessmentId, apiOrigin, theme, showHeader, isInternalUser, language, redirectUrl, placesApiKey, onEvent, emitter, fetchImpl, }: SapiaChatbotProps) => import("react").JSX.Element;
|
|
@@ -67,6 +67,13 @@ export declare const currentQuestionId: (bubbles: MessageBubble[], editingQuesti
|
|
|
67
67
|
* the retry together.
|
|
68
68
|
*/
|
|
69
69
|
export declare const isAgcGuidanceAwaitingAnswer: (bubbles: MessageBubble[]) => boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Whether the terms consent is waiting in a dialogue that never drew the AI-use guidance.
|
|
72
|
+
* Dialogues generated before the introduction carried the guidance marker reach consent without
|
|
73
|
+
* the candidate having been told answers are checked for AI content, so the widget raises the
|
|
74
|
+
* guidance as a pop-up there instead. Once consent is answered the moment has passed.
|
|
75
|
+
*/
|
|
76
|
+
export declare const isTermsConsentMissingAgcGuidance: (bubbles: MessageBubble[]) => boolean;
|
|
70
77
|
/** The stored answer of the question under edit, used to seed the composer. */
|
|
71
78
|
export type EditingDraft = {
|
|
72
79
|
text: string;
|
|
@@ -78,6 +85,17 @@ export type EditingDraft = {
|
|
|
78
85
|
* composer renders back into the editor.
|
|
79
86
|
*/
|
|
80
87
|
export declare const editingAnswerDraft: (bubbles: MessageBubble[], editingQuestionId?: string) => EditingDraft | undefined;
|
|
88
|
+
/** The answer a Retry reopens: the local recording when this session made it, else what to fetch. */
|
|
89
|
+
export type SubmittedVideoTake = {
|
|
90
|
+
questionId: string;
|
|
91
|
+
blob?: Blob;
|
|
92
|
+
extension?: string;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* The submitted take behind the video answer being retried, so the recorder can open on it for
|
|
96
|
+
* review. Undefined when nothing is being edited or the edited answer is not a video.
|
|
97
|
+
*/
|
|
98
|
+
export declare const editingVideoTake: (bubbles: MessageBubble[], editingQuestionId?: string) => SubmittedVideoTake | undefined;
|
|
81
99
|
/** Eyebrow/badge copy builders, supplied by react/strings (keeps i18n out of the view-model). */
|
|
82
100
|
export type QuestionCardLabels = {
|
|
83
101
|
/** Eyebrow copy per scale, e.g. "Written question {n} of {total}". */
|
|
@@ -113,7 +131,9 @@ export type QuestionTotals = Record<QuestionScale, number>;
|
|
|
113
131
|
export declare const buildQuestionCards: (bubbles: MessageBubble[], totals: QuestionTotals, labels: QuestionCardLabels) => Map<string, QuestionCard>;
|
|
114
132
|
/**
|
|
115
133
|
* Bubble id of the active video question, so its recorder renders inside the
|
|
116
|
-
* card.
|
|
134
|
+
* card. While a video answer is re-edited this is the edited question's card, so
|
|
135
|
+
* the recorder reopens beside the question it re-answers rather than docking under
|
|
136
|
+
* a transcript that has since moved on. Undefined for any other question.
|
|
117
137
|
*/
|
|
118
138
|
export declare const activeVideoCardId: (bubbles: MessageBubble[], editingQuestionId?: string) => string | undefined;
|
|
119
139
|
/** The bottom free-text/PII input is shown only for FTQ-typed questions. */
|
package/dist/react/strings.d.ts
CHANGED
|
@@ -7,8 +7,7 @@ export declare const buildStrings: (t: Translator) => {
|
|
|
7
7
|
headerTitle: string;
|
|
8
8
|
videoBadge: string;
|
|
9
9
|
typingLabel: string;
|
|
10
|
-
|
|
11
|
-
typingThinking: string;
|
|
10
|
+
typingLoading: string;
|
|
12
11
|
scrollToLatest: string;
|
|
13
12
|
progressLabel: string;
|
|
14
13
|
/** Question-card eyebrow for a free-text question: "Written question {current} of {total}". */
|
|
@@ -66,6 +65,7 @@ export declare const buildStrings: (t: Translator) => {
|
|
|
66
65
|
cancelEditLabel: string;
|
|
67
66
|
editingLabel: string;
|
|
68
67
|
editBannerLabel: string;
|
|
68
|
+
videoRetryBannerLabel: string;
|
|
69
69
|
optionsGroupLabel: string;
|
|
70
70
|
/**
|
|
71
71
|
* What the candidate is being asked to do with the options. Only a cap below the number on offer
|
|
@@ -122,8 +122,8 @@ export declare const buildStrings: (t: Translator) => {
|
|
|
122
122
|
continueLabel: string;
|
|
123
123
|
loadingLabel: string;
|
|
124
124
|
preparingLabel: string;
|
|
125
|
-
doneTitle:
|
|
126
|
-
doneSubtitle: (
|
|
125
|
+
doneTitle: string;
|
|
126
|
+
doneSubtitle: (name?: string) => string;
|
|
127
127
|
doneNextLabel: string;
|
|
128
128
|
doneSteps: [string, string, string];
|
|
129
129
|
/** Ends the finished transcript when there is nowhere to send the candidate on to. */
|
|
@@ -166,11 +166,14 @@ export declare const buildStrings: (t: Translator) => {
|
|
|
166
166
|
/** The answered feedback turn's lines: "Rating: 8/10", "Feedback: Good". */
|
|
167
167
|
csatAnswerRating: (rating: number, max: number) => string;
|
|
168
168
|
csatAnswerComment: (comment: string) => string;
|
|
169
|
+
deiTitle: string;
|
|
170
|
+
deiSubmit: string;
|
|
169
171
|
videoOpenCamera: string;
|
|
170
172
|
videoStartRecording: string;
|
|
171
173
|
videoStopRecording: string;
|
|
172
174
|
videoReRecord: string;
|
|
173
175
|
videoSubmit: string;
|
|
176
|
+
videoKeep: string;
|
|
174
177
|
videoCameraError: string;
|
|
175
178
|
videoPreview: string;
|
|
176
179
|
videoCamera: string;
|
|
@@ -198,9 +201,11 @@ export declare const buildStrings: (t: Translator) => {
|
|
|
198
201
|
agcMessage: (attempt: number) => string;
|
|
199
202
|
agcEdit: string;
|
|
200
203
|
agcContinue: string;
|
|
204
|
+
agcGuidanceTitle: string;
|
|
201
205
|
agcGuidanceBody: string;
|
|
202
206
|
agcGuidanceCheckbox: string;
|
|
203
207
|
agcGuidanceTip: string;
|
|
208
|
+
agcGuidanceCta: string;
|
|
204
209
|
editFailedTitle: string;
|
|
205
210
|
editFailedMessage: string;
|
|
206
211
|
editFailedDismiss: string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DemographicFormField } from '../api/types/responses';
|
|
2
|
+
import { InterviewEngine } from '../core/interview/engine';
|
|
3
|
+
import { DemographicFormProps } from '../ui/inputs/DemographicForm/DemographicForm';
|
|
4
|
+
import { UiStrings } from './strings';
|
|
5
|
+
/**
|
|
6
|
+
* Everything the diversity card needs except the sending flag, spread straight onto it. Called
|
|
7
|
+
* unconditionally; a new run — told apart by its opening question — starts with nothing ticked.
|
|
8
|
+
* The card is sendable only once every question has at least its minimum.
|
|
9
|
+
*/
|
|
10
|
+
export declare const useDemographicForm: ({ engine, fields, strings, }: {
|
|
11
|
+
engine: InterviewEngine;
|
|
12
|
+
fields: DemographicFormField[];
|
|
13
|
+
strings: UiStrings;
|
|
14
|
+
}) => Omit<DemographicFormProps, "submitting">;
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import { RecorderMedia, RecorderState } from '../core/media/recorder';
|
|
2
2
|
/** Max number of takes a candidate may record (client-side UX cap). */
|
|
3
3
|
export declare const MAX_VIDEO_ATTEMPTS = 5;
|
|
4
|
+
/** Where finished takes are counted, so the cap survives a reload and a Retry. */
|
|
5
|
+
export type VideoTakesScope = {
|
|
6
|
+
assessmentId: string;
|
|
7
|
+
questionId: string;
|
|
8
|
+
};
|
|
9
|
+
/** An answer already submitted: its recording from this session, or a fetch for one from before. */
|
|
10
|
+
export type SubmittedTakeSource = {
|
|
11
|
+
blob?: Blob;
|
|
12
|
+
resolveUrl?: () => Promise<string>;
|
|
13
|
+
};
|
|
14
|
+
export type UseVideoRecorderOptions = {
|
|
15
|
+
media?: RecorderMedia;
|
|
16
|
+
/** Without it the count lives for this mount only. Memoize: effects key on its identity. */
|
|
17
|
+
takes?: VideoTakesScope;
|
|
18
|
+
/** Opens in review on this take instead of on the camera button. Memoize, as for `takes`. */
|
|
19
|
+
submittedTake?: SubmittedTakeSource;
|
|
20
|
+
};
|
|
4
21
|
export type UseVideoRecorder = {
|
|
5
22
|
state: RecorderState;
|
|
6
23
|
videoRef: React.RefObject<HTMLVideoElement | null>;
|
|
@@ -9,11 +26,15 @@ export type UseVideoRecorder = {
|
|
|
9
26
|
micOn: boolean;
|
|
10
27
|
/** 3-2-1 countdown value before recording starts, or null when inactive. */
|
|
11
28
|
countdown: number | null;
|
|
12
|
-
/**
|
|
13
|
-
|
|
29
|
+
/** Takes spent on this question, the one under review included, and the cap. */
|
|
30
|
+
takesUsed: number;
|
|
14
31
|
maxAttempts: number;
|
|
15
|
-
/**
|
|
32
|
+
/** URL of the take under review: the fresh recording, or the submitted one. */
|
|
16
33
|
reviewUrl: string | null;
|
|
34
|
+
/** True while the review shows the already-submitted answer rather than a new take. */
|
|
35
|
+
reviewingSubmitted: boolean;
|
|
36
|
+
/** True from a Re-record press until the new take starts recording. */
|
|
37
|
+
retaking: boolean;
|
|
17
38
|
openCamera: () => void;
|
|
18
39
|
beginCountdown: () => void;
|
|
19
40
|
stopRecording: () => void;
|
|
@@ -21,4 +42,4 @@ export type UseVideoRecorder = {
|
|
|
21
42
|
toggleCamera: () => void;
|
|
22
43
|
toggleMicrophone: () => void;
|
|
23
44
|
};
|
|
24
|
-
export declare const useVideoRecorder: (maxSeconds: number, media?:
|
|
45
|
+
export declare const useVideoRecorder: (maxSeconds: number, { media, takes, submittedTake }?: UseVideoRecorderOptions) => UseVideoRecorder;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t } from "./react-
|
|
1
|
+
import { H as e } from "./client-C2MWNOYf.js";
|
|
2
|
+
import { t } from "./react-wrZMUHWq.js";
|
|
3
3
|
import { t as n } from "./defineProperty-DiFpLzd2.js";
|
|
4
4
|
import { a as r, i, n as a, r as o, t as s } from "./classPrivateFieldSet2-DtQPURVD.js";
|
|
5
5
|
//#region ../../node_modules/.pnpm/spotify-audio-element@1.0.4/node_modules/spotify-audio-element/dist/spotify-audio-element.js
|
|
@@ -309,4 +309,4 @@ var W = H({
|
|
|
309
309
|
//#endregion
|
|
310
310
|
export { W as default };
|
|
311
311
|
|
|
312
|
-
//# sourceMappingURL=react-
|
|
312
|
+
//# sourceMappingURL=react-Cp-K_L89.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t } from "./react-
|
|
1
|
+
import { H as e } from "./client-C2MWNOYf.js";
|
|
2
|
+
import { t } from "./react-wrZMUHWq.js";
|
|
3
3
|
import { t as n } from "./defineProperty-DiFpLzd2.js";
|
|
4
4
|
import { i as r, n as i, t as a } from "./classPrivateFieldSet2-DtQPURVD.js";
|
|
5
5
|
import { n as o, t as s } from "./dist-BOe6WyvN.js";
|
|
@@ -190,4 +190,4 @@ var S = b({
|
|
|
190
190
|
//#endregion
|
|
191
191
|
export { S as default };
|
|
192
192
|
|
|
193
|
-
//# sourceMappingURL=react-
|
|
193
|
+
//# sourceMappingURL=react-D3tMg8u4.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t } from "./react-
|
|
1
|
+
import { H as e } from "./client-C2MWNOYf.js";
|
|
2
|
+
import { t } from "./react-wrZMUHWq.js";
|
|
3
3
|
import { t as n } from "./defineProperty-DiFpLzd2.js";
|
|
4
4
|
import { n as r } from "./hls-mBncGwsE.js";
|
|
5
5
|
import { a as i, i as a, n as o, r as s, t as c } from "./classPrivateFieldSet2-DtQPURVD.js";
|
|
@@ -215,4 +215,4 @@ var b = v({
|
|
|
215
215
|
//#endregion
|
|
216
216
|
export { b as default };
|
|
217
217
|
|
|
218
|
-
//# sourceMappingURL=react-
|
|
218
|
+
//# sourceMappingURL=react-D8jZKei2.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t } from "./react-
|
|
1
|
+
import { H as e } from "./client-C2MWNOYf.js";
|
|
2
|
+
import { t } from "./react-wrZMUHWq.js";
|
|
3
3
|
import { t as n } from "./defineProperty-DiFpLzd2.js";
|
|
4
4
|
import { a as r, i, n as a, r as o, t as s } from "./classPrivateFieldSet2-DtQPURVD.js";
|
|
5
5
|
import { t as c } from "./dist-FvHBWiRa.js";
|
|
@@ -455,4 +455,4 @@ var $ = Z({
|
|
|
455
455
|
//#endregion
|
|
456
456
|
export { $ as default };
|
|
457
457
|
|
|
458
|
-
//# sourceMappingURL=react-
|
|
458
|
+
//# sourceMappingURL=react-DtGzNzM1.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t } from "./react-
|
|
1
|
+
import { H as e } from "./client-C2MWNOYf.js";
|
|
2
|
+
import { t } from "./react-wrZMUHWq.js";
|
|
3
3
|
import { t as n } from "./defineProperty-DiFpLzd2.js";
|
|
4
4
|
import { a as r, i, n as a, r as o, t as s } from "./classPrivateFieldSet2-DtQPURVD.js";
|
|
5
5
|
import { t as c } from "./dist-FvHBWiRa.js";
|
|
@@ -2207,4 +2207,4 @@ var rt = tt({
|
|
|
2207
2207
|
//#endregion
|
|
2208
2208
|
export { rt as default };
|
|
2209
2209
|
|
|
2210
|
-
//# sourceMappingURL=react-
|
|
2210
|
+
//# sourceMappingURL=react-LDcTld2q.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t } from "./react-
|
|
1
|
+
import { H as e } from "./client-C2MWNOYf.js";
|
|
2
|
+
import { t } from "./react-wrZMUHWq.js";
|
|
3
3
|
import { t as n } from "./defineProperty-DiFpLzd2.js";
|
|
4
4
|
import { a as r, i, n as a, r as o, t as s } from "./classPrivateFieldSet2-DtQPURVD.js";
|
|
5
5
|
//#region ../../node_modules/.pnpm/super-media-element@1.4.2/node_modules/super-media-element/super-media-element.js
|
|
@@ -369,4 +369,4 @@ var P = M({
|
|
|
369
369
|
//#endregion
|
|
370
370
|
export { P as default };
|
|
371
371
|
|
|
372
|
-
//# sourceMappingURL=react-
|
|
372
|
+
//# sourceMappingURL=react-g5b2mM7w.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t } from "./react-
|
|
1
|
+
import { H as e } from "./client-C2MWNOYf.js";
|
|
2
|
+
import { t } from "./react-wrZMUHWq.js";
|
|
3
3
|
import { t as n } from "./defineProperty-DiFpLzd2.js";
|
|
4
4
|
import { a as r, i, n as a, r as o, t as s } from "./classPrivateFieldSet2-DtQPURVD.js";
|
|
5
5
|
//#region ../../node_modules/.pnpm/tiktok-video-element@0.1.2/node_modules/tiktok-video-element/dist/tiktok-video-element.js
|
|
@@ -332,4 +332,4 @@ var K = W({
|
|
|
332
332
|
//#endregion
|
|
333
333
|
export { K as default };
|
|
334
334
|
|
|
335
|
-
//# sourceMappingURL=react-
|
|
335
|
+
//# sourceMappingURL=react-hklchtwF.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t } from "./react-
|
|
1
|
+
import { H as e } from "./client-C2MWNOYf.js";
|
|
2
|
+
import { t } from "./react-wrZMUHWq.js";
|
|
3
3
|
import { t as n } from "./defineProperty-DiFpLzd2.js";
|
|
4
4
|
import { a as r, i, n as a, r as o, t as s } from "./classPrivateFieldSet2-DtQPURVD.js";
|
|
5
5
|
//#region ../../node_modules/.pnpm/twitch-video-element@0.1.6/node_modules/twitch-video-element/dist/twitch-video-element.js
|
|
@@ -365,4 +365,4 @@ var J = K({
|
|
|
365
365
|
//#endregion
|
|
366
366
|
export { J as default };
|
|
367
367
|
|
|
368
|
-
//# sourceMappingURL=react-
|
|
368
|
+
//# sourceMappingURL=react-vc8uDric.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as e } from "./client-C2MWNOYf.js";
|
|
2
2
|
//#region ../../node_modules/.pnpm/react@19.2.7/node_modules/react/cjs/react.production.js
|
|
3
3
|
var t = /* @__PURE__ */ e(((e) => {
|
|
4
4
|
var t = Symbol.for("react.transitional.element"), n = Symbol.for("react.portal"), r = Symbol.for("react.fragment"), i = Symbol.for("react.strict_mode"), a = Symbol.for("react.profiler"), o = Symbol.for("react.consumer"), s = Symbol.for("react.context"), c = Symbol.for("react.forward_ref"), l = Symbol.for("react.suspense"), u = Symbol.for("react.memo"), d = Symbol.for("react.lazy"), f = Symbol.for("react.activity"), p = Symbol.iterator;
|
|
@@ -292,4 +292,4 @@ var t = /* @__PURE__ */ e(((e) => {
|
|
|
292
292
|
//#endregion
|
|
293
293
|
export { n as t };
|
|
294
294
|
|
|
295
|
-
//# sourceMappingURL=react-
|
|
295
|
+
//# sourceMappingURL=react-wrZMUHWq.js.map
|
|
@@ -15,6 +15,11 @@ export type ActionDockProps = ActionDockBase & ({
|
|
|
15
15
|
enabled: boolean;
|
|
16
16
|
/** An acknowledgement is in flight. */
|
|
17
17
|
pending?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Enter presses the button while nothing that owns Enter has focus. Opt-in, so the caller
|
|
20
|
+
* decides which prompts are safe to hit by habit.
|
|
21
|
+
*/
|
|
22
|
+
triggerOnEnter?: boolean;
|
|
18
23
|
onClick: () => void;
|
|
19
24
|
});
|
|
20
25
|
/**
|
|
@@ -9,12 +9,8 @@ export type ChatLogProps = {
|
|
|
9
9
|
typingLabel: string;
|
|
10
10
|
/** Accessible name for the jump-to-end button, e.g. "Scroll to the latest message". */
|
|
11
11
|
scrollToLatestLabel: string;
|
|
12
|
-
/**
|
|
13
|
-
|
|
14
|
-
/** Phase-2 loading phrase (and the only one mid-turn). */
|
|
15
|
-
typingThinkingLabel: string;
|
|
16
|
-
/** @internal Holds the phase-1 phrase open for longer than its 400ms default (demo only). */
|
|
17
|
-
typingReadingPhaseMs?: number;
|
|
12
|
+
/** The loading phrase shown beside the mark, e.g. "Loading…". */
|
|
13
|
+
typingLoadingLabel: string;
|
|
18
14
|
bubbleLabels: ChatBubbleLabels;
|
|
19
15
|
/** Copy for the collapse/expand toggle on a folded hint run. */
|
|
20
16
|
hintLabels: HintDisclosureLabels;
|
|
@@ -45,4 +41,4 @@ export type ChatLogProps = {
|
|
|
45
41
|
* are announced once through a separate visually-hidden live region (the transcript itself is
|
|
46
42
|
* deliberately not one — see the announcer effect below).
|
|
47
43
|
*/
|
|
48
|
-
export declare const ChatLog: ({ items, typing, typingLabel, scrollToLatestLabel,
|
|
44
|
+
export declare const ChatLog: ({ items, typing, typingLabel, scrollToLatestLabel, typingLoadingLabel, bubbleLabels, hintLabels, sliderLabels, dropdownLabels, mediaLabels, onRetry, onSelectOption, onToggleOption, onConfirmSelections, onSubmitSlider, onEdit, onRetryVideo, onResolveVideoUrl, cardFooter, cardFooterItemId, editingFooter, renderCard, }: ChatLogProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type DemographicDetailRow = {
|
|
2
|
+
/** The template's question, as the card asked it. */
|
|
3
|
+
label: string;
|
|
4
|
+
value: string;
|
|
5
|
+
};
|
|
6
|
+
export type DemographicDetailsCardProps = {
|
|
7
|
+
rows: DemographicDetailRow[];
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* The diversity answers the candidate sent, drawn as the single candidate turn the card collected
|
|
11
|
+
* them in. Read-only by design: nothing commits until the card is sent, so the card itself was the
|
|
12
|
+
* place to change an answer.
|
|
13
|
+
*/
|
|
14
|
+
export declare const DemographicDetailsCard: ({ rows }: DemographicDetailsCardProps) => import("react").JSX.Element;
|
|
@@ -1,31 +1,15 @@
|
|
|
1
|
-
/** What the interviewer can honestly claim to be doing while the candidate waits. */
|
|
2
|
-
export declare enum TypingPhase {
|
|
3
|
-
/** The candidate has said nothing yet, so there is no response to read and nothing to consider. */
|
|
4
|
-
SILENT = "silent",
|
|
5
|
-
/** The candidate has answered earlier in the interview, but not as the last thing said. */
|
|
6
|
-
THINKING = "thinking",
|
|
7
|
-
/** The candidate's answer is the last thing in the transcript. */
|
|
8
|
-
AFTER_ANSWER = "after-answer"
|
|
9
|
-
}
|
|
10
1
|
export type TypingIndicatorProps = {
|
|
11
2
|
/** Stable accessible description for screen readers, e.g. "Interviewer is typing". */
|
|
12
3
|
ariaLabel: string;
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
/** Phase-2 status (and the only status when there's no fresh answer to read). */
|
|
16
|
-
thinkingLabel: string;
|
|
17
|
-
/** Decides which status phrase — if any — the mark is allowed to carry. */
|
|
18
|
-
phase: TypingPhase;
|
|
19
|
-
/** @internal Overrides READING_PHASE_MS so the demo can hold the phase open to look at it. */
|
|
20
|
-
readingPhaseMs?: number;
|
|
4
|
+
/** The status phrase beside the mark. */
|
|
5
|
+
label: string;
|
|
21
6
|
};
|
|
22
7
|
/**
|
|
23
|
-
*
|
|
24
|
-
* animation — a gradient sweeping through the glyphs
|
|
25
|
-
* ported from the Tia bot. Rendered directly
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* answered anything the mark animates alone, because both phrases would be a lie.
|
|
8
|
+
* Loading status while the next message is on its way: the Tia mark drawing itself beside a
|
|
9
|
+
* phrase that is itself the animation — a gradient sweeping through the glyphs
|
|
10
|
+
* (`.sc-thinking-shimmer`). Both are ported from the Tia bot. Rendered directly in the transcript
|
|
11
|
+
* (no bubble/background) under the interviewer left rule. The phrase is deliberately neutral: the
|
|
12
|
+
* interview is predefined, so nothing here may suggest an interviewer reading the answer or
|
|
13
|
+
* composing a reply for this candidate.
|
|
30
14
|
*/
|
|
31
|
-
export declare const TypingIndicator: ({ ariaLabel,
|
|
15
|
+
export declare const TypingIndicator: ({ ariaLabel, label }: TypingIndicatorProps) => import("react").JSX.Element;
|
package/dist/ui/chat/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DemographicDetailRow } from './DemographicDetailsCard/DemographicDetailsCard';
|
|
1
2
|
import { PiiDetailRow } from './PiiDetailsCard/PiiDetailsCard';
|
|
2
3
|
export declare enum ChatItemSender {
|
|
3
4
|
AGENT = "agent",
|
|
@@ -33,7 +34,11 @@ export declare enum ChatCardKind {
|
|
|
33
34
|
/** The rating and comment asked after the interview, drawn as one card. */
|
|
34
35
|
CUSTOMER_SATISFACTION_FORM = "csat-form",
|
|
35
36
|
/** The single line the interviewer says before that card. */
|
|
36
|
-
CUSTOMER_SATISFACTION_INTRO = "csat-intro"
|
|
37
|
+
CUSTOMER_SATISFACTION_INTRO = "csat-intro",
|
|
38
|
+
/** Every diversity question, drawn as one card. */
|
|
39
|
+
DEMOGRAPHIC_FORM = "dei-form",
|
|
40
|
+
/** That card once sent, drawn as one read-only list of the answers. */
|
|
41
|
+
DEMOGRAPHIC_DETAILS = "dei-details"
|
|
37
42
|
}
|
|
38
43
|
/** A selectable answer option (MCQ/dropdown option or button-group button). */
|
|
39
44
|
export type ChatOptionItem = {
|
|
@@ -49,6 +54,11 @@ export type ChatVideoItem = {
|
|
|
49
54
|
/** For historical answers: fetch a signed playback URL via these. */
|
|
50
55
|
questionId: string;
|
|
51
56
|
extension?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Short-lived URL the backend signed when it sent a reloaded answer. Good enough to draw the
|
|
59
|
+
* thumbnail without a request of our own; playback falls back to a fresh URL once it expires.
|
|
60
|
+
*/
|
|
61
|
+
previewUrl?: string;
|
|
52
62
|
/** Upload failed; retry available. */
|
|
53
63
|
failed?: boolean;
|
|
54
64
|
};
|
|
@@ -87,6 +97,8 @@ export type ChatLogItem = {
|
|
|
87
97
|
title: string;
|
|
88
98
|
rows: PiiDetailRow[];
|
|
89
99
|
};
|
|
100
|
+
/** Content for ChatCardKind.DEMOGRAPHIC_DETAILS; the card kind alone does not carry it. */
|
|
101
|
+
demographicDetails?: DemographicDetailRow[];
|
|
90
102
|
/** Selectable options rendered inside the bubble (option-type questions). */
|
|
91
103
|
options?: ChatOptionItem[];
|
|
92
104
|
optionsKind?: ChatOptionsKind;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ChatOptionItem } from '../../chat/types';
|
|
2
|
+
/** One diversity question as the card draws it. */
|
|
3
|
+
export type DemographicFormQuestion = {
|
|
4
|
+
questionId: string;
|
|
5
|
+
/** The template's wording, drawn as the question's label. */
|
|
6
|
+
prompt: string;
|
|
7
|
+
options: ChatOptionItem[];
|
|
8
|
+
selectedOptionIds: string[];
|
|
9
|
+
/** Builds a set rather than taking one tap; a multi-select capped at one pick is not. */
|
|
10
|
+
multi: boolean;
|
|
11
|
+
/** Multi-select only: the rule, e.g. "Select up to 2", appended to the label. */
|
|
12
|
+
instruction?: string;
|
|
13
|
+
/** Multi-select only: progress against the cap, e.g. "1 of 2 selected". */
|
|
14
|
+
countLabel?: string;
|
|
15
|
+
capReached?: boolean;
|
|
16
|
+
};
|
|
17
|
+
export type DemographicFormProps = {
|
|
18
|
+
questions: DemographicFormQuestion[];
|
|
19
|
+
title: string;
|
|
20
|
+
submitLabel: string;
|
|
21
|
+
/** Every question carries an answer. */
|
|
22
|
+
canSubmit: boolean;
|
|
23
|
+
submitting: boolean;
|
|
24
|
+
onToggle: (questionId: string, optionId: string) => void;
|
|
25
|
+
onSubmit: () => void;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Every diversity question collected on one card. There is no skip: a candidate who does not want
|
|
29
|
+
* to disclose picks that question's own decline option, so the one button stays disabled until
|
|
30
|
+
* every question carries an answer. Nothing is recorded until the card is sent, so a mistaken tap
|
|
31
|
+
* is simply replaced.
|
|
32
|
+
*
|
|
33
|
+
* Presentational: the selections and the sending flag are owned by the caller.
|
|
34
|
+
*/
|
|
35
|
+
export declare const DemographicForm: ({ questions, title, submitLabel, canSubmit, submitting, onToggle, onSubmit, }: DemographicFormProps) => import("react").JSX.Element;
|
|
@@ -34,12 +34,14 @@ export type LocationComboboxProps = {
|
|
|
34
34
|
/** Announced once a set of predictions settles, e.g. "5 locations found". */
|
|
35
35
|
suggestionsAnnouncement: (count: number) => string;
|
|
36
36
|
placement?: LocationPopupPlacement;
|
|
37
|
-
/** Enter pressed with no prediction chosen. */
|
|
37
|
+
/** Enter pressed with no prediction chosen. Omit to let Enter submit the enclosing form. */
|
|
38
38
|
onSubmitText?: () => void;
|
|
39
39
|
onSelectSuggestion: (suggestion: LocationSuggestionItem) => void;
|
|
40
40
|
/** Control drawn inside the field after the input (the composer's send button). */
|
|
41
41
|
trailing?: ReactNode;
|
|
42
42
|
className?: string;
|
|
43
|
+
/** Box around the input and trailing control; the form field draws its own. */
|
|
44
|
+
fieldClassName?: string;
|
|
43
45
|
inputClassName?: string;
|
|
44
46
|
};
|
|
45
47
|
/**
|
|
@@ -49,4 +51,4 @@ export type LocationComboboxProps = {
|
|
|
49
51
|
*
|
|
50
52
|
* The caller owns the text so it can validate and post it; this owns only the popup state.
|
|
51
53
|
*/
|
|
52
|
-
export declare const LocationCombobox: ({ suggestions, text, onTextChange, disabled, manualMode, placeholder, required, describedBy, inputLabel, labelledBy, inputId, suggestionsLabel, suggestionsAnnouncement, placement, onSubmitText, onSelectSuggestion, trailing, className, inputClassName, }: LocationComboboxProps) => import("react").JSX.Element;
|
|
54
|
+
export declare const LocationCombobox: ({ suggestions, text, onTextChange, disabled, manualMode, placeholder, required, describedBy, inputLabel, labelledBy, inputId, suggestionsLabel, suggestionsAnnouncement, placement, onSubmitText, onSelectSuggestion, trailing, className, fieldClassName, inputClassName, }: LocationComboboxProps) => import("react").JSX.Element;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { ChatOptionItem } from '../../chat/types';
|
|
2
|
+
/** Selected-state tick; colour comes from the parent via currentColor. */
|
|
3
|
+
export declare const CheckIcon: ({ className }: {
|
|
4
|
+
className?: string;
|
|
5
|
+
}) => import("react").JSX.Element;
|
|
2
6
|
export type OptionListProps = {
|
|
3
7
|
options: ChatOptionItem[];
|
|
4
8
|
/** The chosen option (highlighted; stays highlighted after answering). Single-select only. */
|
|
@@ -6,6 +6,8 @@ export type VideoRecorderLabels = {
|
|
|
6
6
|
stopRecording: string;
|
|
7
7
|
reRecord: string;
|
|
8
8
|
submit: string;
|
|
9
|
+
/** Primary review action on the already-submitted answer, e.g. "Keep this answer". */
|
|
10
|
+
keep: string;
|
|
9
11
|
cameraError: string;
|
|
10
12
|
preview: string;
|
|
11
13
|
/** Design-only setup/recording labels (optional; fall back to no chrome). */
|
|
@@ -49,10 +51,17 @@ export type VideoRecorderProps = {
|
|
|
49
51
|
canRetake?: boolean;
|
|
50
52
|
/** Object URL for the recorded take, played back in review. */
|
|
51
53
|
reviewUrl?: string | null;
|
|
54
|
+
/** Review shows the answer already submitted, so the primary action keeps it instead of sending. */
|
|
55
|
+
reviewingSubmitted?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* A Re-record is under way: the camera reopens and the countdown starts on its own. The stage and
|
|
58
|
+
* the Record row hold their place while it does, so the card keeps the height the review had.
|
|
59
|
+
*/
|
|
60
|
+
retaking?: boolean;
|
|
52
61
|
};
|
|
53
62
|
/**
|
|
54
63
|
* Camera preview + record/review controls, styled to the Chat-3000 design.
|
|
55
64
|
* The MediaRecorder lifecycle, countdown, toggles and attempts live in
|
|
56
65
|
* react/useVideoRecorder; this component only renders state + buttons.
|
|
57
66
|
*/
|
|
58
|
-
export declare const VideoRecorder: ({ phase, elapsedSeconds, maxSeconds, hasResult, showPreview, videoRef, disabled, labels, onOpenCamera, onBeginCountdown, onStartRecording, onStopRecording, onReRecord, onSubmit, camOn, micOn, onToggleCamera, onToggleMicrophone, countdown, attemptsLabel, canRetake, reviewUrl, }: VideoRecorderProps) => import("react").JSX.Element;
|
|
67
|
+
export declare const VideoRecorder: ({ phase, elapsedSeconds, maxSeconds, hasResult, showPreview, videoRef, disabled, labels, onOpenCamera, onBeginCountdown, onStartRecording, onStopRecording, onReRecord, onSubmit, camOn, micOn, onToggleCamera, onToggleMicrophone, countdown, attemptsLabel, canRetake, reviewUrl, reviewingSubmitted, retaking, }: VideoRecorderProps) => import("react").JSX.Element;
|
|
@@ -1,2 +1,15 @@
|
|
|
1
|
+
import { KeyboardEvent } from 'react';
|
|
2
|
+
export declare const FORM_CARD_WIDTH_CLASS = "sc:w-full sc:min-w-[min(100%,500px)] sc:max-w-[672px]";
|
|
1
3
|
export declare const FORM_CARD_CLASS = "sc:w-full sc:min-w-[min(100%,500px)] sc:max-w-[672px] sc:overflow-hidden sc:rounded-2xl sc:border sc:border-line sc:bg-white";
|
|
2
4
|
export declare const FORM_CTA_CLASS = "sc:w-full sc:rounded-full sc:py-3.5 sc:text-base";
|
|
5
|
+
/**
|
|
6
|
+
* Makes Enter press the card's primary button from any control inside it, not only from a text
|
|
7
|
+
* input: native implicit submission skips radios, selects, textareas and the option buttons.
|
|
8
|
+
* Shift+Enter keeps its newline in the comment box. A control that already used the key (the
|
|
9
|
+
* location combobox choosing a prediction) and a disabled primary leave Enter to its native
|
|
10
|
+
* meaning, so an unanswered card still lets Enter pick an option.
|
|
11
|
+
*
|
|
12
|
+
* Attach it to the form, or to a card that wraps the form when focus can land outside it (the PII
|
|
13
|
+
* card moves focus to its heading on every step, and the review step has no field to focus).
|
|
14
|
+
*/
|
|
15
|
+
export declare const submitFormOnEnter: (event: KeyboardEvent<HTMLElement>) => void;
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
export type VideoPlayerProps = {
|
|
2
2
|
/** Local recorded blob (just-submitted answer), played without a network call. */
|
|
3
3
|
blob?: Blob;
|
|
4
|
-
/**
|
|
4
|
+
/** Backend-signed URL that came with a reloaded answer; draws the thumbnail, may have expired. */
|
|
5
|
+
previewUrl?: string;
|
|
6
|
+
/** Lazily resolves a fresh signed playback URL (historical answers). */
|
|
5
7
|
resolveUrl?: () => Promise<string>;
|
|
6
8
|
playLabel: string;
|
|
7
9
|
label: string;
|
|
8
10
|
};
|
|
9
11
|
/**
|
|
10
|
-
* Plays a recorded video answer.
|
|
11
|
-
*
|
|
12
|
+
* Plays a recorded video answer. Shows its first frame behind a play button, drawn from the local
|
|
13
|
+
* blob or the URL the backend signed into a reloaded answer; a press plays it in place. With no
|
|
14
|
+
* usable source (none sent, or the signed URL expired) it falls back to a fresh URL on demand.
|
|
15
|
+
* Native <video controls> once playing — keyboard accessible.
|
|
12
16
|
*/
|
|
13
|
-
export declare const VideoPlayer: ({ blob, resolveUrl, playLabel, label }: VideoPlayerProps) => import("react").JSX.Element;
|
|
17
|
+
export declare const VideoPlayer: ({ blob, previewUrl, resolveUrl, playLabel, label, }: VideoPlayerProps) => import("react").JSX.Element;
|