@sapia-ai/chatbot-v3 1.5.0 → 1.7.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.
Files changed (44) hide show
  1. package/dist/{EmbeddedVideoPlayer-Dn-boxdp.js → EmbeddedVideoPlayer-Bhz8DKO8.js} +14 -14
  2. package/dist/{Preview-CtMz5fNh.js → Preview-B1ZmYM9V.js} +3 -3
  3. package/dist/api/client.d.ts +8 -1
  4. package/dist/api/types/messages.d.ts +8 -1
  5. package/dist/api/types/responses.d.ts +54 -12
  6. package/dist/api.js +2 -2
  7. package/dist/{client-DfRBtXIE.js → client-C2MWNOYf.js} +552 -545
  8. package/dist/core/bubbles/cards.d.ts +3 -1
  9. package/dist/core/bubbles/demographicRun.d.ts +57 -0
  10. package/dist/core/bubbles/selection.d.ts +3 -1
  11. package/dist/core/bubbles/types.d.ts +11 -0
  12. package/dist/core/interview/engine.d.ts +33 -2
  13. package/dist/core/interview/reveal.d.ts +5 -2
  14. package/dist/core/store.d.ts +10 -2
  15. package/dist/core/theme/branding.d.ts +5 -2
  16. package/dist/{dist-Cl2Oi3Sl.js → dist-CoO0i-y0.js} +3 -3
  17. package/dist/embed/createChatbot.d.ts +0 -2
  18. package/dist/{fix-webm-duration-CVQSf7rp.js → fix-webm-duration-CXijcUXq.js} +2 -2
  19. package/dist/index.js +5995 -5692
  20. package/dist/{jsx-runtime-CdNykazB.js → jsx-runtime-BcXxfixh.js} +2 -2
  21. package/dist/react/SapiaChatbot.d.ts +1 -3
  22. package/dist/react/strings.d.ts +10 -9
  23. package/dist/react/useDemographicForm.d.ts +14 -0
  24. package/dist/{react-BIgNJUOD.js → react-Cp-K_L89.js} +3 -3
  25. package/dist/{react-DlJlpUiG.js → react-D3tMg8u4.js} +3 -3
  26. package/dist/{react-DEJ3NRa3.js → react-D8jZKei2.js} +3 -3
  27. package/dist/{react-BKViU2cv.js → react-DtGzNzM1.js} +3 -3
  28. package/dist/{react-BC7MhdYE.js → react-LDcTld2q.js} +3 -3
  29. package/dist/{react-78ZA32q8.js → react-g5b2mM7w.js} +3 -3
  30. package/dist/{react-BSaO3Elx.js → react-hklchtwF.js} +3 -3
  31. package/dist/{react-eOBKoj54.js → react-vc8uDric.js} +3 -3
  32. package/dist/{react-D4Z0N-x7.js → react-wrZMUHWq.js} +2 -2
  33. package/dist/ui/chat/ActionDock/ActionDock.d.ts +5 -0
  34. package/dist/ui/chat/ChatLog/ChatLog.d.ts +3 -7
  35. package/dist/ui/chat/DemographicDetailsCard/DemographicDetailsCard.d.ts +14 -0
  36. package/dist/ui/chat/TypingIndicator/TypingIndicator.d.ts +9 -25
  37. package/dist/ui/chat/types.d.ts +8 -1
  38. package/dist/ui/inputs/DemographicForm/DemographicForm.d.ts +35 -0
  39. package/dist/ui/inputs/LocationAnswerInput/LocationCombobox.d.ts +4 -2
  40. package/dist/ui/inputs/OptionList/OptionList.d.ts +4 -0
  41. package/dist/ui/inputs/formCard.d.ts +12 -0
  42. package/dist/ui/shell/LogoTile/LogoTile.d.ts +6 -1
  43. package/dist-umd/sapia-chatbot.umd.js +274 -274
  44. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { R as e } from "./client-DfRBtXIE.js";
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-CdNykazB.js.map
24
+ //# sourceMappingURL=jsx-runtime-BcXxfixh.js.map
@@ -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, readingPhaseMs, }: SapiaChatbotProps) => import("react").JSX.Element;
29
+ export declare const SapiaChatbot: ({ env, region, appId, assessmentId, apiOrigin, theme, showHeader, isInternalUser, language, redirectUrl, placesApiKey, onEvent, emitter, fetchImpl, }: SapiaChatbotProps) => import("react").JSX.Element;
@@ -7,8 +7,7 @@ export declare const buildStrings: (t: Translator) => {
7
7
  headerTitle: string;
8
8
  videoBadge: string;
9
9
  typingLabel: string;
10
- typingReading: string;
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}". */
@@ -40,16 +39,16 @@ export declare const buildStrings: (t: Translator) => {
40
39
  /**
41
40
  * Label + description + icon for a breakdown row. The label is pluralised on `count` and carries
42
41
  * the number itself. The video description interpolates the retry budget the recorder actually
43
- * enforces, so the card and the recorder can never disagree. A category the widget has no copy
44
- * for — one the backend adds before the widget ships for it — falls back to a generic mark and
45
- * the bare count, so the row still says how many.
42
+ * enforces, so the card and the recorder can never disagree. The written description names the
43
+ * hiring company; without one the placeholder empties and the sentence still reads. A category
44
+ * the widget has no copy for — one the backend adds before the widget ships for it — falls back
45
+ * to a generic mark and the bare count, so the row still says how many.
46
46
  */
47
- summaryCategory: (category: AssessmentSummaryCategory, count: number) => {
47
+ summaryCategory: (category: AssessmentSummaryCategory, count: number, company?: string) => {
48
48
  label: string;
49
49
  description: string;
50
50
  kind: SummaryKind;
51
51
  };
52
- composerFooter: string;
53
52
  richToolbar: string;
54
53
  richBulletList: string;
55
54
  richNumberList: string;
@@ -123,8 +122,8 @@ export declare const buildStrings: (t: Translator) => {
123
122
  continueLabel: string;
124
123
  loadingLabel: string;
125
124
  preparingLabel: string;
126
- doneTitle: (name?: string) => string;
127
- doneSubtitle: (company?: string) => string;
125
+ doneTitle: string;
126
+ doneSubtitle: (name?: string) => string;
128
127
  doneNextLabel: string;
129
128
  doneSteps: [string, string, string];
130
129
  /** Ends the finished transcript when there is nowhere to send the candidate on to. */
@@ -167,6 +166,8 @@ export declare const buildStrings: (t: Translator) => {
167
166
  /** The answered feedback turn's lines: "Rating: 8/10", "Feedback: Good". */
168
167
  csatAnswerRating: (rating: number, max: number) => string;
169
168
  csatAnswerComment: (comment: string) => string;
169
+ deiTitle: string;
170
+ deiSubmit: string;
170
171
  videoOpenCamera: string;
171
172
  videoStartRecording: string;
172
173
  videoStopRecording: 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,5 +1,5 @@
1
- import { B as e } from "./client-DfRBtXIE.js";
2
- import { t } from "./react-D4Z0N-x7.js";
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-BIgNJUOD.js.map
312
+ //# sourceMappingURL=react-Cp-K_L89.js.map
@@ -1,5 +1,5 @@
1
- import { B as e } from "./client-DfRBtXIE.js";
2
- import { t } from "./react-D4Z0N-x7.js";
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-DlJlpUiG.js.map
193
+ //# sourceMappingURL=react-D3tMg8u4.js.map
@@ -1,5 +1,5 @@
1
- import { B as e } from "./client-DfRBtXIE.js";
2
- import { t } from "./react-D4Z0N-x7.js";
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-DEJ3NRa3.js.map
218
+ //# sourceMappingURL=react-D8jZKei2.js.map
@@ -1,5 +1,5 @@
1
- import { B as e } from "./client-DfRBtXIE.js";
2
- import { t } from "./react-D4Z0N-x7.js";
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-BKViU2cv.js.map
458
+ //# sourceMappingURL=react-DtGzNzM1.js.map
@@ -1,5 +1,5 @@
1
- import { B as e } from "./client-DfRBtXIE.js";
2
- import { t } from "./react-D4Z0N-x7.js";
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-BC7MhdYE.js.map
2210
+ //# sourceMappingURL=react-LDcTld2q.js.map
@@ -1,5 +1,5 @@
1
- import { B as e } from "./client-DfRBtXIE.js";
2
- import { t } from "./react-D4Z0N-x7.js";
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-78ZA32q8.js.map
372
+ //# sourceMappingURL=react-g5b2mM7w.js.map
@@ -1,5 +1,5 @@
1
- import { B as e } from "./client-DfRBtXIE.js";
2
- import { t } from "./react-D4Z0N-x7.js";
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-BSaO3Elx.js.map
335
+ //# sourceMappingURL=react-hklchtwF.js.map
@@ -1,5 +1,5 @@
1
- import { B as e } from "./client-DfRBtXIE.js";
2
- import { t } from "./react-D4Z0N-x7.js";
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-eOBKoj54.js.map
368
+ //# sourceMappingURL=react-vc8uDric.js.map
@@ -1,4 +1,4 @@
1
- import { R as e } from "./client-DfRBtXIE.js";
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-D4Z0N-x7.js.map
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
- /** Phase-1 loading phrase shown after a candidate answer. */
13
- typingReadingLabel: string;
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, typingReadingLabel, typingThinkingLabel, typingReadingPhaseMs, bubbleLabels, hintLabels, sliderLabels, dropdownLabels, mediaLabels, onRetry, onSelectOption, onToggleOption, onConfirmSelections, onSubmitSlider, onEdit, onRetryVideo, onResolveVideoUrl, cardFooter, cardFooterItemId, editingFooter, renderCard, }: ChatLogProps) => import("react").JSX.Element;
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
- /** Phase-1 status shown briefly when responding to a candidate answer. */
14
- readingLabel: string;
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
- * Pre-stream loading status: the Tia mark drawing itself beside a phrase that is itself the
24
- * animation — a gradient sweeping through the glyphs (`.sc-thinking-shimmer`). Both are
25
- * ported from the Tia bot. Rendered directly
26
- * in the transcript (no bubble/background) under the interviewer left rule. When
27
- * responding to an answer it reads "Reading your response…" then "Thinking about
28
- * it…"; mid-turn it shows only the "thinking" phrase; and until the candidate has
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, readingLabel, thinkingLabel, phase, readingPhaseMs, }: TypingIndicatorProps) => import("react").JSX.Element;
15
+ export declare const TypingIndicator: ({ ariaLabel, label }: TypingIndicatorProps) => import("react").JSX.Element;
@@ -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 = {
@@ -92,6 +97,8 @@ export type ChatLogItem = {
92
97
  title: string;
93
98
  rows: PiiDetailRow[];
94
99
  };
100
+ /** Content for ChatCardKind.DEMOGRAPHIC_DETAILS; the card kind alone does not carry it. */
101
+ demographicDetails?: DemographicDetailRow[];
95
102
  /** Selectable options rendered inside the bubble (option-type questions). */
96
103
  options?: ChatOptionItem[];
97
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. */
@@ -1,3 +1,15 @@
1
+ import { KeyboardEvent } from 'react';
1
2
  export declare const FORM_CARD_WIDTH_CLASS = "sc:w-full sc:min-w-[min(100%,500px)] sc:max-w-[672px]";
2
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";
3
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,5 +1,10 @@
1
+ export declare enum LogoTileSize {
2
+ Compact = "compact",
3
+ Large = "large"
4
+ }
1
5
  export type LogoTileProps = {
2
6
  src?: string;
7
+ size?: LogoTileSize;
3
8
  alt?: string;
4
9
  className?: string;
5
10
  };
@@ -7,4 +12,4 @@ export type LogoTileProps = {
7
12
  * Customer logo on a white square tile. Renders nothing when there is no logo or it fails to
8
13
  * load — a broken-image glyph would read as a fault on a candidate-facing surface.
9
14
  */
10
- export declare const LogoTile: ({ src, alt, className }: LogoTileProps) => import("react").JSX.Element | null;
15
+ export declare const LogoTile: ({ src, alt, size, className, }: LogoTileProps) => import("react").JSX.Element | null;