@constructor-io/constructorio-ui-pia 2.14.0 → 2.15.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.
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const react_1 = tslib_1.__importDefault(require("react"));
5
+ const translate_1 = require("../../utils/translate");
6
+ function CheckoutTriggerBar({ triggers, state, translations, }) {
7
+ const visible = triggers.filter((t) => (t.triggerWhen ? t.triggerWhen(state) : true));
8
+ if (visible.length === 0)
9
+ return null;
10
+ return (react_1.default.createElement("div", { className: 'cio-pia-checkout-triggers', "data-testid": 'cio-pia-checkout-triggers' }, visible.map((trigger) => {
11
+ var _a;
12
+ const label = (_a = trigger.label) !== null && _a !== void 0 ? _a : (0, translate_1.translate)('Checkout', translations);
13
+ const onClick = () => trigger.onTrigger(state);
14
+ if (trigger.renderButton) {
15
+ return (react_1.default.createElement(react_1.default.Fragment, { key: trigger.id }, trigger.renderButton({
16
+ onClick,
17
+ label,
18
+ disabled: trigger.disabled,
19
+ id: trigger.id,
20
+ })));
21
+ }
22
+ return (react_1.default.createElement("button", { key: trigger.id, type: 'button', className: 'cio-pia-checkout-trigger', "data-testid": `cio-pia-checkout-trigger-${trigger.id}`, disabled: trigger.disabled, onClick: onClick }, label));
23
+ })));
24
+ }
25
+ exports.default = CheckoutTriggerBar;
@@ -18,11 +18,12 @@ const PiaInlineAnswer_1 = tslib_1.__importDefault(require("../PiaInlineAnswer/Pi
18
18
  const PiaModal_1 = tslib_1.__importDefault(require("../PiaConversation/PiaModal"));
19
19
  const PiaConversation_1 = tslib_1.__importDefault(require("../PiaConversation/PiaConversation"));
20
20
  const StatusRegion_1 = tslib_1.__importStar(require("../StatusRegion/StatusRegion"));
21
+ const CheckoutTriggerBar_1 = tslib_1.__importDefault(require("./CheckoutTriggerBar"));
21
22
  /** The question-and-answer experience: `mode: 'default'`, `mode: 'conversation'`, and the modal. */
22
23
  // eslint-disable-next-line complexity
23
24
  function CioPiaQna(props) {
24
25
  var _a;
25
- const { apiKey, itemId, itemName, threadId, variationId, cioClient, displayConfigs, componentOverrides, callbacks, formatters, productCardProps, children, translations, suggestedQuestionsParameters, answerParameters, parameters, trackingConfigs, abTest, } = props;
26
+ const { apiKey, itemId, itemName, threadId, variationId, cioClient, displayConfigs, componentOverrides, callbacks, formatters, productCardProps, children, translations, suggestedQuestionsParameters, answerParameters, parameters, trackingConfigs, checkoutTriggers, abTest, } = props;
26
27
  const { learnMoreUrl, showFeedback, mode = 'default', type = 'inline', showPreviousItems, disclaimerPosition = 'bottom', } = displayConfigs || {};
27
28
  const isConversation = mode === 'conversation' || type === 'modal';
28
29
  const { priceCurrency } = productCardProps || {};
@@ -73,11 +74,13 @@ function CioPiaQna(props) {
73
74
  handleSubmitQuestion,
74
75
  conversationHistory,
75
76
  };
77
+ const checkoutElement = checkoutTriggers && checkoutTriggers.length > 0 ? (react_1.default.createElement(CheckoutTriggerBar_1.default, { triggers: checkoutTriggers, state: renderProps, translations: translations })) : null;
76
78
  const conversationHistoryProps = {
77
79
  conversationHistory,
78
80
  isLoading,
79
81
  isAnswerLoading,
80
82
  error,
83
+ checkoutElement,
81
84
  currentItems,
82
85
  showFeedback,
83
86
  showPreviousItems,
@@ -111,7 +114,8 @@ function CioPiaQna(props) {
111
114
  !isAnswerLoading && error && (react_1.default.createElement(ErrorBlock_1.default, { key: error.message || (0, translate_1.translate)('Unexpected error', translations), message: error.message, translations: translations })),
112
115
  !isAnswerLoading && !error && currentAnswer && (react_1.default.createElement(PiaInlineAnswer_1.default, { currentAnswer: currentAnswer, currentItems: currentItems, showFeedback: showFeedback, learnMoreUrl: learnMoreUrl, disclaimerPosition: disclaimerPosition, translations: translations, callbacks: callbacks, componentOverrides: componentOverrides, onFeedback: handleFeedback, onResultClick: tracking.trackResultClick, question: currentQuestion, qnaResultId: qnaResultId, priceCurrency: priceCurrency })),
113
116
  isLoading && react_1.default.createElement(SuggestedQuestionsSkeleton_1.default, null),
114
- !isLoading && !error && (react_1.default.createElement(SuggestedQuestionsContainer_1.default, { questions: displayedQuestions, onQuestionClick: handleQuestionClick, componentOverride: componentOverrides === null || componentOverrides === void 0 ? void 0 : componentOverrides.suggestedQuestions }))),
117
+ !isLoading && !error && (react_1.default.createElement(SuggestedQuestionsContainer_1.default, { questions: displayedQuestions, onQuestionClick: handleQuestionClick, componentOverride: componentOverrides === null || componentOverrides === void 0 ? void 0 : componentOverrides.suggestedQuestions })),
118
+ checkoutElement),
115
119
  react_1.default.createElement(StatusRegion_1.default, { message: answerStatus, "data-testid": 'answer-status' })));
116
120
  }
117
121
  exports.default = CioPiaQna;
@@ -54,3 +54,36 @@
54
54
  outline: 2px solid #0f1324;
55
55
  outline-offset: 2px;
56
56
  }
57
+
58
+ .cio-pia-checkout-triggers {
59
+ display: flex;
60
+ flex-wrap: wrap;
61
+ gap: 8px;
62
+ margin-top: 4px;
63
+ }
64
+
65
+ .cio-pia-checkout-trigger {
66
+ background: #0f1324;
67
+ color: #fff;
68
+ border: none;
69
+ border-radius: 6px;
70
+ padding: 10px 16px;
71
+ font-size: 14px;
72
+ font-weight: 500;
73
+ cursor: pointer;
74
+ transition: opacity 0.15s ease;
75
+ }
76
+
77
+ .cio-pia-checkout-trigger:hover {
78
+ opacity: 0.9;
79
+ }
80
+
81
+ .cio-pia-checkout-trigger:focus-visible {
82
+ outline: 2px solid #0f1324;
83
+ outline-offset: 2px;
84
+ }
85
+
86
+ .cio-pia-checkout-trigger:disabled {
87
+ opacity: 0.5;
88
+ cursor: not-allowed;
89
+ }
@@ -7,11 +7,12 @@ const SuggestedQuestionsContainer_1 = tslib_1.__importDefault(require("../Sugges
7
7
  const SuggestedQuestionsSkeleton_1 = tslib_1.__importDefault(require("../SuggestedQuestionsContainer/SuggestedQuestionsSkeleton"));
8
8
  const translate_1 = require("../../utils/translate");
9
9
  const ConversationHistory_1 = tslib_1.__importDefault(require("../ConversationHistory/ConversationHistory"));
10
- function PiaConversation({ conversationHistory, isLoading, error, currentItems, showFeedback, showPreviousItems, learnMoreUrl, disclaimerPosition, translations, callbacks, componentOverrides, displayedQuestions, handleSubmitQuestion, handleQuestionClick, containerRef, handleFeedback, onResultClick, qnaResultId, onInputFocus, priceCurrency, }) {
10
+ function PiaConversation({ conversationHistory, isLoading, error, currentItems, showFeedback, showPreviousItems, learnMoreUrl, disclaimerPosition, translations, callbacks, componentOverrides, displayedQuestions, handleSubmitQuestion, handleQuestionClick, containerRef, handleFeedback, onResultClick, qnaResultId, onInputFocus, priceCurrency, checkoutElement, }) {
11
11
  const hasHistory = conversationHistory.length > 0;
12
12
  return (react_1.default.createElement("div", { ref: containerRef, className: 'cio-pia-container cio-pia-conversation', "data-testid": 'cio-pia-container' },
13
13
  !hasHistory && (react_1.default.createElement("p", { className: 'cio-pia-title', "data-testid": 'cio-pia-title' }, (0, translate_1.translate)('Any questions about this product?', translations))),
14
14
  react_1.default.createElement(ConversationHistory_1.default, { conversationHistory: conversationHistory, isLoading: isLoading, error: error, currentItems: currentItems, showFeedback: showFeedback, showPreviousItems: showPreviousItems, learnMoreUrl: learnMoreUrl, disclaimerPosition: disclaimerPosition, translations: translations, callbacks: callbacks, componentOverrides: componentOverrides, handleFeedback: handleFeedback, onResultClick: onResultClick, qnaResultId: qnaResultId, priceCurrency: priceCurrency }),
15
+ checkoutElement && react_1.default.createElement("div", { className: 'cio-pia-conversation-checkout' }, checkoutElement),
15
16
  react_1.default.createElement("div", { className: 'cio-pia-conversation-footer' },
16
17
  isLoading && !error && react_1.default.createElement(SuggestedQuestionsSkeleton_1.default, null),
17
18
  !isLoading && !error && (react_1.default.createElement(SuggestedQuestionsContainer_1.default, { questions: displayedQuestions, onQuestionClick: handleQuestionClick, componentOverride: componentOverrides === null || componentOverrides === void 0 ? void 0 : componentOverrides.suggestedQuestions })),
@@ -2,6 +2,11 @@
2
2
  max-height: var(--cio-pia-conversation-max-height);
3
3
  }
4
4
 
5
+ .cio-pia-conversation-checkout {
6
+ flex-shrink: 0;
7
+ margin-bottom: 8px;
8
+ }
9
+
5
10
  .cio-pia-conversation-footer {
6
11
  display: flex;
7
12
  flex-direction: column;
@@ -25,8 +25,8 @@ div.link-list {
25
25
  }
26
26
  }
27
27
 
28
- @media all and (-ms-high-contrast:none) {
29
- div.link-list {
28
+ @media all and (-ms-high-contrast: none) {
29
+ div.link-list {
30
30
  display: -ms-grid;
31
31
  -ms-grid-columns: 1fr 1fr;
32
32
  -ms-grid-rows: 1fr 1fr;
@@ -38,20 +38,23 @@ a.link-item {
38
38
  padding: 20px;
39
39
  border: 1px solid #00000010;
40
40
  border-radius: 5px;
41
- transition: background 150ms ease-out, border 150ms ease-out, transform 150ms ease-out;
41
+ transition:
42
+ background 150ms ease-out,
43
+ border 150ms ease-out,
44
+ transform 150ms ease-out;
42
45
  color: #333333;
43
46
  display: flex;
44
47
  align-items: flex-start;
45
48
  }
46
49
 
47
50
  a.link-item:hover {
48
- border-color: #1EA7FD50;
51
+ border-color: #1ea7fd50;
49
52
  transform: translate3d(0, -3px, 0);
50
53
  box-shadow: rgba(0, 0, 0, 0.08) 0 3px 10px 0;
51
54
  }
52
55
 
53
56
  a.link-item:active {
54
- border-color: #1EA7FD;
57
+ border-color: #1ea7fd;
55
58
  transform: translate3d(0, 0, 0);
56
59
  }
57
60
 
@@ -81,8 +84,8 @@ span.badge {
81
84
  font-size: 11px;
82
85
  line-height: 12px;
83
86
  font-weight: 700;
84
- background: #E7FDD8;
85
- color: #66BF3C;
87
+ background: #e7fdd8;
88
+ color: #66bf3c;
86
89
  padding: 4px 12px;
87
90
  margin-right: 10px;
88
91
  vertical-align: top;
@@ -100,10 +103,9 @@ div.badge-wrapper code {
100
103
  display: inline-block;
101
104
  }
102
105
 
103
-
104
106
  .badge.tip {
105
- background: #E7FDD8;
106
- color: #66BF3C;
107
+ background: #e7fdd8;
108
+ color: #66bf3c;
107
109
  }
108
110
 
109
111
  .badge.note {
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = '2.14.0';
3
+ exports.default = '2.15.0';
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { translate } from '../../utils/translate';
3
+ export default function CheckoutTriggerBar({ triggers, state, translations, }) {
4
+ const visible = triggers.filter((t) => (t.triggerWhen ? t.triggerWhen(state) : true));
5
+ if (visible.length === 0)
6
+ return null;
7
+ return (React.createElement("div", { className: 'cio-pia-checkout-triggers', "data-testid": 'cio-pia-checkout-triggers' }, visible.map((trigger) => {
8
+ const label = trigger.label ?? translate('Checkout', translations);
9
+ const onClick = () => trigger.onTrigger(state);
10
+ if (trigger.renderButton) {
11
+ return (React.createElement(React.Fragment, { key: trigger.id }, trigger.renderButton({
12
+ onClick,
13
+ label,
14
+ disabled: trigger.disabled,
15
+ id: trigger.id,
16
+ })));
17
+ }
18
+ return (React.createElement("button", { key: trigger.id, type: 'button', className: 'cio-pia-checkout-trigger', "data-testid": `cio-pia-checkout-trigger-${trigger.id}`, disabled: trigger.disabled, onClick: onClick }, label));
19
+ })));
20
+ }
@@ -15,10 +15,11 @@ import PiaInlineAnswer from '../PiaInlineAnswer/PiaInlineAnswer';
15
15
  import PiaModal from '../PiaConversation/PiaModal';
16
16
  import PiaConversation from '../PiaConversation/PiaConversation';
17
17
  import StatusRegion, { answerStatusMessage } from '../StatusRegion/StatusRegion';
18
+ import CheckoutTriggerBar from './CheckoutTriggerBar';
18
19
  /** The question-and-answer experience: `mode: 'default'`, `mode: 'conversation'`, and the modal. */
19
20
  // eslint-disable-next-line complexity
20
21
  export default function CioPiaQna(props) {
21
- const { apiKey, itemId, itemName, threadId, variationId, cioClient, displayConfigs, componentOverrides, callbacks, formatters, productCardProps, children, translations, suggestedQuestionsParameters, answerParameters, parameters, trackingConfigs, abTest, } = props;
22
+ const { apiKey, itemId, itemName, threadId, variationId, cioClient, displayConfigs, componentOverrides, callbacks, formatters, productCardProps, children, translations, suggestedQuestionsParameters, answerParameters, parameters, trackingConfigs, checkoutTriggers, abTest, } = props;
22
23
  const { learnMoreUrl, showFeedback, mode = 'default', type = 'inline', showPreviousItems, disclaimerPosition = 'bottom', } = displayConfigs || {};
23
24
  const isConversation = mode === 'conversation' || type === 'modal';
24
25
  const { priceCurrency } = productCardProps || {};
@@ -69,11 +70,13 @@ export default function CioPiaQna(props) {
69
70
  handleSubmitQuestion,
70
71
  conversationHistory,
71
72
  };
73
+ const checkoutElement = checkoutTriggers && checkoutTriggers.length > 0 ? (React.createElement(CheckoutTriggerBar, { triggers: checkoutTriggers, state: renderProps, translations: translations })) : null;
72
74
  const conversationHistoryProps = {
73
75
  conversationHistory,
74
76
  isLoading,
75
77
  isAnswerLoading,
76
78
  error,
79
+ checkoutElement,
77
80
  currentItems,
78
81
  showFeedback,
79
82
  showPreviousItems,
@@ -107,6 +110,7 @@ export default function CioPiaQna(props) {
107
110
  !isAnswerLoading && error && (React.createElement(ErrorBlock, { key: error.message || translate('Unexpected error', translations), message: error.message, translations: translations })),
108
111
  !isAnswerLoading && !error && currentAnswer && (React.createElement(PiaInlineAnswer, { currentAnswer: currentAnswer, currentItems: currentItems, showFeedback: showFeedback, learnMoreUrl: learnMoreUrl, disclaimerPosition: disclaimerPosition, translations: translations, callbacks: callbacks, componentOverrides: componentOverrides, onFeedback: handleFeedback, onResultClick: tracking.trackResultClick, question: currentQuestion, qnaResultId: qnaResultId, priceCurrency: priceCurrency })),
109
112
  isLoading && React.createElement(SuggestedQuestionsSkeleton, null),
110
- !isLoading && !error && (React.createElement(SuggestedQuestionsContainer, { questions: displayedQuestions, onQuestionClick: handleQuestionClick, componentOverride: componentOverrides?.suggestedQuestions }))),
113
+ !isLoading && !error && (React.createElement(SuggestedQuestionsContainer, { questions: displayedQuestions, onQuestionClick: handleQuestionClick, componentOverride: componentOverrides?.suggestedQuestions })),
114
+ checkoutElement),
111
115
  React.createElement(StatusRegion, { message: answerStatus, "data-testid": 'answer-status' })));
112
116
  }
@@ -54,3 +54,36 @@
54
54
  outline: 2px solid #0f1324;
55
55
  outline-offset: 2px;
56
56
  }
57
+
58
+ .cio-pia-checkout-triggers {
59
+ display: flex;
60
+ flex-wrap: wrap;
61
+ gap: 8px;
62
+ margin-top: 4px;
63
+ }
64
+
65
+ .cio-pia-checkout-trigger {
66
+ background: #0f1324;
67
+ color: #fff;
68
+ border: none;
69
+ border-radius: 6px;
70
+ padding: 10px 16px;
71
+ font-size: 14px;
72
+ font-weight: 500;
73
+ cursor: pointer;
74
+ transition: opacity 0.15s ease;
75
+ }
76
+
77
+ .cio-pia-checkout-trigger:hover {
78
+ opacity: 0.9;
79
+ }
80
+
81
+ .cio-pia-checkout-trigger:focus-visible {
82
+ outline: 2px solid #0f1324;
83
+ outline-offset: 2px;
84
+ }
85
+
86
+ .cio-pia-checkout-trigger:disabled {
87
+ opacity: 0.5;
88
+ cursor: not-allowed;
89
+ }
@@ -4,11 +4,12 @@ import SuggestedQuestionsContainer from '../SuggestedQuestionsContainer/Suggeste
4
4
  import SuggestedQuestionsSkeleton from '../SuggestedQuestionsContainer/SuggestedQuestionsSkeleton';
5
5
  import { translate } from '../../utils/translate';
6
6
  import ConversationHistory from '../ConversationHistory/ConversationHistory';
7
- export default function PiaConversation({ conversationHistory, isLoading, error, currentItems, showFeedback, showPreviousItems, learnMoreUrl, disclaimerPosition, translations, callbacks, componentOverrides, displayedQuestions, handleSubmitQuestion, handleQuestionClick, containerRef, handleFeedback, onResultClick, qnaResultId, onInputFocus, priceCurrency, }) {
7
+ export default function PiaConversation({ conversationHistory, isLoading, error, currentItems, showFeedback, showPreviousItems, learnMoreUrl, disclaimerPosition, translations, callbacks, componentOverrides, displayedQuestions, handleSubmitQuestion, handleQuestionClick, containerRef, handleFeedback, onResultClick, qnaResultId, onInputFocus, priceCurrency, checkoutElement, }) {
8
8
  const hasHistory = conversationHistory.length > 0;
9
9
  return (React.createElement("div", { ref: containerRef, className: 'cio-pia-container cio-pia-conversation', "data-testid": 'cio-pia-container' },
10
10
  !hasHistory && (React.createElement("p", { className: 'cio-pia-title', "data-testid": 'cio-pia-title' }, translate('Any questions about this product?', translations))),
11
11
  React.createElement(ConversationHistory, { conversationHistory: conversationHistory, isLoading: isLoading, error: error, currentItems: currentItems, showFeedback: showFeedback, showPreviousItems: showPreviousItems, learnMoreUrl: learnMoreUrl, disclaimerPosition: disclaimerPosition, translations: translations, callbacks: callbacks, componentOverrides: componentOverrides, handleFeedback: handleFeedback, onResultClick: onResultClick, qnaResultId: qnaResultId, priceCurrency: priceCurrency }),
12
+ checkoutElement && React.createElement("div", { className: 'cio-pia-conversation-checkout' }, checkoutElement),
12
13
  React.createElement("div", { className: 'cio-pia-conversation-footer' },
13
14
  isLoading && !error && React.createElement(SuggestedQuestionsSkeleton, null),
14
15
  !isLoading && !error && (React.createElement(SuggestedQuestionsContainer, { questions: displayedQuestions, onQuestionClick: handleQuestionClick, componentOverride: componentOverrides?.suggestedQuestions })),
@@ -2,6 +2,11 @@
2
2
  max-height: var(--cio-pia-conversation-max-height);
3
3
  }
4
4
 
5
+ .cio-pia-conversation-checkout {
6
+ flex-shrink: 0;
7
+ margin-bottom: 8px;
8
+ }
9
+
5
10
  .cio-pia-conversation-footer {
6
11
  display: flex;
7
12
  flex-direction: column;
@@ -25,8 +25,8 @@ div.link-list {
25
25
  }
26
26
  }
27
27
 
28
- @media all and (-ms-high-contrast:none) {
29
- div.link-list {
28
+ @media all and (-ms-high-contrast: none) {
29
+ div.link-list {
30
30
  display: -ms-grid;
31
31
  -ms-grid-columns: 1fr 1fr;
32
32
  -ms-grid-rows: 1fr 1fr;
@@ -38,20 +38,23 @@ a.link-item {
38
38
  padding: 20px;
39
39
  border: 1px solid #00000010;
40
40
  border-radius: 5px;
41
- transition: background 150ms ease-out, border 150ms ease-out, transform 150ms ease-out;
41
+ transition:
42
+ background 150ms ease-out,
43
+ border 150ms ease-out,
44
+ transform 150ms ease-out;
42
45
  color: #333333;
43
46
  display: flex;
44
47
  align-items: flex-start;
45
48
  }
46
49
 
47
50
  a.link-item:hover {
48
- border-color: #1EA7FD50;
51
+ border-color: #1ea7fd50;
49
52
  transform: translate3d(0, -3px, 0);
50
53
  box-shadow: rgba(0, 0, 0, 0.08) 0 3px 10px 0;
51
54
  }
52
55
 
53
56
  a.link-item:active {
54
- border-color: #1EA7FD;
57
+ border-color: #1ea7fd;
55
58
  transform: translate3d(0, 0, 0);
56
59
  }
57
60
 
@@ -81,8 +84,8 @@ span.badge {
81
84
  font-size: 11px;
82
85
  line-height: 12px;
83
86
  font-weight: 700;
84
- background: #E7FDD8;
85
- color: #66BF3C;
87
+ background: #e7fdd8;
88
+ color: #66bf3c;
86
89
  padding: 4px 12px;
87
90
  margin-right: 10px;
88
91
  vertical-align: top;
@@ -100,10 +103,9 @@ div.badge-wrapper code {
100
103
  display: inline-block;
101
104
  }
102
105
 
103
-
104
106
  .badge.tip {
105
- background: #E7FDD8;
106
- color: #66BF3C;
107
+ background: #e7fdd8;
108
+ color: #66bf3c;
107
109
  }
108
110
 
109
111
  .badge.note {
@@ -1 +1 @@
1
- export default '2.14.0';
1
+ export default '2.15.0';
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { CioPiaRenderProps } from '../../types';
3
+ import { translate } from '../../utils/translate';
4
+ import type { CheckoutTrigger } from './types';
5
+ interface CheckoutTriggerBarProps {
6
+ triggers: CheckoutTrigger[];
7
+ state: CioPiaRenderProps;
8
+ translations?: Parameters<typeof translate>[1];
9
+ }
10
+ export default function CheckoutTriggerBar({ triggers, state, translations, }: CheckoutTriggerBarProps): React.JSX.Element | null;
11
+ export {};
@@ -1,4 +1,4 @@
1
1
  import CioPia from './CioPia';
2
2
  export * from './CioPia';
3
- export type { CioPiaProps } from './types';
3
+ export type { CioPiaProps, CheckoutTrigger } from './types';
4
4
  export default CioPia;
@@ -1,6 +1,43 @@
1
+ import { ReactNode } from 'react';
1
2
  import { IncludeComponentOverrides, IncludeRenderProps } from '@constructor-io/constructorio-ui-components';
2
3
  import { CioPiaRenderProps, CioPiaComponentOverrides, Callbacks, CioPiaAbTest, CioPiaDisplayConfigs, CioPiaTrackingConfigs, Translations, SuggestedQuestionsParameters, AnswerRequestParameters, RecsPodParameters, Formatters, ProductCardDisplayProps } from '../../types';
3
4
  import type { CioClient } from '../../hooks/usePiaClient';
5
+ /**
6
+ * A single checkout entry point rendered inside the PIA `default` mode.
7
+ * The merchant owns the checkout flow itself (typically the `@constructor-io/constructorio-ui-checkout`
8
+ * `CheckoutFlowProvider`); PIA only surfaces the button(s) that start it.
9
+ */
10
+ export interface CheckoutTrigger {
11
+ /** Stable identifier for the trigger — used as React key and forwarded to `renderButton`. */
12
+ id: string;
13
+ /** Button label. Defaults to "Checkout". */
14
+ label?: string;
15
+ /** Disables the button. Forwarded to `renderButton`, which is responsible for applying it. */
16
+ disabled?: boolean;
17
+ /**
18
+ * Predicate deciding whether this trigger should render. Called with the same
19
+ * render-props snapshot the `children`/`componentOverrides.reactNode` render callback
20
+ * receives, so consumers can gate on conversation state (e.g. "at least one answer
21
+ * shown", "at least two turns"). Defaults to always visible.
22
+ *
23
+ * `state.conversationHistory` is only filled in `conversation` mode and the modal; in
24
+ * `default` mode it stays empty, so gate on `currentAnswer` there.
25
+ */
26
+ triggerWhen?: (state: CioPiaRenderProps) => boolean;
27
+ /** Custom button renderer. When provided, `label` / `disabled` are passed through but styling is your call. */
28
+ renderButton?: (props: {
29
+ onClick: () => void;
30
+ label: string;
31
+ disabled?: boolean;
32
+ id: string;
33
+ }) => ReactNode;
34
+ /**
35
+ * Fires when the button is clicked. The merchant wires this to their checkout entry
36
+ * (e.g. `flow.start()` from `useCheckoutFlow`). Receives the render-props snapshot so
37
+ * the handler can seed the checkout with the current answer/items/conversation.
38
+ */
39
+ onTrigger: (state: CioPiaRenderProps) => void;
40
+ }
4
41
  export interface CioPiaProps extends IncludeRenderProps<CioPiaRenderProps>, IncludeComponentOverrides<CioPiaComponentOverrides> {
5
42
  /** Your Constructor.io API key. */
6
43
  apiKey: string;
@@ -28,6 +65,11 @@ export interface CioPiaProps extends IncludeRenderProps<CioPiaRenderProps>, Incl
28
65
  formatters?: Formatters;
29
66
  /** Props forwarded to the ProductCard rendered inside the carousel. */
30
67
  productCardProps?: ProductCardDisplayProps;
68
+ /**
69
+ * One or more checkout entry points. Rendered in `default` and `conversation` modes and
70
+ * in the modal, after the answer; ignored in `recommendations` mode.
71
+ */
72
+ checkoutTriggers?: CheckoutTrigger[];
31
73
  /** UI string translations for internationalization. */
32
74
  translations?: Translations;
33
75
  /** Parameters for the suggested questions request. */
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { ReactNode } from 'react';
2
2
  import { FeedbackType, Item, Question } from '../../types';
3
3
  import { ConversationHistoryProps } from '../ConversationHistory/ConversationHistory';
4
4
  export interface PiaConversationProps extends ConversationHistoryProps {
@@ -10,5 +10,6 @@ export interface PiaConversationProps extends ConversationHistoryProps {
10
10
  onResultClick?: (item: Item, position: number, question: string, qnaResultId?: string) => void;
11
11
  qnaResultId?: string;
12
12
  onInputFocus?: () => void;
13
+ checkoutElement?: ReactNode;
13
14
  }
14
- export default function PiaConversation({ conversationHistory, isLoading, error, currentItems, showFeedback, showPreviousItems, learnMoreUrl, disclaimerPosition, translations, callbacks, componentOverrides, displayedQuestions, handleSubmitQuestion, handleQuestionClick, containerRef, handleFeedback, onResultClick, qnaResultId, onInputFocus, priceCurrency, }: PiaConversationProps): React.JSX.Element;
15
+ export default function PiaConversation({ conversationHistory, isLoading, error, currentItems, showFeedback, showPreviousItems, learnMoreUrl, disclaimerPosition, translations, callbacks, componentOverrides, displayedQuestions, handleSubmitQuestion, handleQuestionClick, containerRef, handleFeedback, onResultClick, qnaResultId, onInputFocus, priceCurrency, checkoutElement, }: PiaConversationProps): React.JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import CioPia from './components/CioPia';
2
2
  export { default as CioPia } from './components/CioPia';
3
- export type { CioPiaProps } from './components/CioPia';
3
+ export type { CioPiaProps, CheckoutTrigger } from './components/CioPia';
4
4
  export { sanitizeHtml, renderMarkdown } from './utils/contentTransformers';
5
5
  export type { RenderMarkdownOptions, SanitizeOptions } from './utils/contentTransformers';
6
6
  export { AgentRequestError } from './errors';
@@ -1,2 +1,2 @@
1
- declare const _default: "2.14.0";
1
+ declare const _default: "2.15.0";
2
2
  export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructor-io/constructorio-ui-pia",
3
- "version": "2.14.0",
3
+ "version": "2.15.0",
4
4
  "description": "Constructor.io AI Product Insights Agent UI library for web applications",
5
5
  "author": "Constructor.io Corporation",
6
6
  "license": "MIT",