@constructor-io/constructorio-ui-pia 2.10.4 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/constructorio-ui-pia-bundled.js +55 -55
- package/lib/cjs/components/CioPia/CioPia.js +8 -96
- package/lib/cjs/components/CioPia/CioPiaQna.js +111 -0
- package/lib/cjs/components/CioPia/CioPiaStyles.css +19 -0
- package/lib/cjs/components/CioPia/PiaCustomCarousel.js +24 -29
- package/lib/cjs/components/CioPiaRecs/CioPiaRecs.js +73 -0
- package/lib/cjs/components/CioPiaRecs/CioPiaRecsStyles.css +138 -0
- package/lib/cjs/components/CioPiaRecs/RecsCarouselSkeleton.js +58 -0
- package/lib/cjs/components/CioPiaRecs/RecsOptionsSkeleton.js +18 -0
- package/lib/cjs/components/CioPiaRecs/RecsPodRefinement.js +27 -0
- package/lib/cjs/components/Input/Input.js +27 -9
- package/lib/cjs/components/Input/InputStyles.css +27 -0
- package/lib/cjs/components/SuggestedQuestion/SuggestedQuestion.js +2 -3
- package/lib/cjs/components/SuggestedQuestionsContainer/SuggestedQuestionsContainerStyles.css +1 -1
- package/lib/cjs/constants.js +12 -1
- package/lib/cjs/hooks/useAnswerResults.js +4 -14
- package/lib/cjs/hooks/useCioPia.js +48 -18
- package/lib/cjs/hooks/usePiaClient.js +21 -0
- package/lib/cjs/hooks/useRecsPod.js +134 -0
- package/lib/cjs/hooks/useSuggestedQuestions.js +10 -26
- package/lib/cjs/hooks/useViewportTracking.js +3 -2
- package/lib/cjs/styles.css +1 -0
- package/lib/cjs/types.js +0 -2
- package/lib/cjs/utils/classNames.js +13 -0
- package/lib/cjs/utils/recs.js +13 -0
- package/lib/cjs/utils/translate.js +5 -0
- package/lib/cjs/version.js +1 -1
- package/lib/mjs/components/CioPia/CioPia.js +7 -95
- package/lib/mjs/components/CioPia/CioPiaQna.js +106 -0
- package/lib/mjs/components/CioPia/CioPiaStyles.css +19 -0
- package/lib/mjs/components/CioPia/PiaCustomCarousel.js +43 -30
- package/lib/mjs/components/CioPiaRecs/CioPiaRecs.js +69 -0
- package/lib/mjs/components/CioPiaRecs/CioPiaRecsStyles.css +138 -0
- package/lib/mjs/components/CioPiaRecs/RecsCarouselSkeleton.js +54 -0
- package/lib/mjs/components/CioPiaRecs/RecsOptionsSkeleton.js +14 -0
- package/lib/mjs/components/CioPiaRecs/RecsPodRefinement.js +23 -0
- package/lib/mjs/components/Input/Input.js +27 -9
- package/lib/mjs/components/Input/InputStyles.css +27 -0
- package/lib/mjs/components/SuggestedQuestion/SuggestedQuestion.js +2 -3
- package/lib/mjs/components/SuggestedQuestionsContainer/SuggestedQuestionsContainerStyles.css +1 -1
- package/lib/mjs/constants.js +11 -0
- package/lib/mjs/hooks/useAnswerResults.js +4 -13
- package/lib/mjs/hooks/useCioPia.js +49 -18
- package/lib/mjs/hooks/usePiaClient.js +17 -0
- package/lib/mjs/hooks/useRecsPod.js +129 -0
- package/lib/mjs/hooks/useSuggestedQuestions.js +12 -24
- package/lib/mjs/hooks/useViewportTracking.js +3 -2
- package/lib/mjs/styles.css +1 -0
- package/lib/mjs/types.js +0 -1
- package/lib/mjs/utils/classNames.js +9 -0
- package/lib/mjs/utils/recs.js +9 -0
- package/lib/mjs/utils/translate.js +6 -1
- package/lib/mjs/version.js +1 -1
- package/lib/types/components/CioPia/CioPia.d.ts +1 -36
- package/lib/types/components/CioPia/CioPiaQna.d.ts +4 -0
- package/lib/types/components/CioPia/index.d.ts +1 -0
- package/lib/types/components/CioPia/types.d.ts +55 -0
- package/lib/types/components/CioPiaRecs/CioPiaRecs.d.ts +13 -0
- package/lib/types/components/CioPiaRecs/RecsCarouselSkeleton.d.ts +16 -0
- package/lib/types/components/CioPiaRecs/RecsOptionsSkeleton.d.ts +16 -0
- package/lib/types/components/CioPiaRecs/RecsPodRefinement.d.ts +21 -0
- package/lib/types/components/Input/Input.d.ts +9 -1
- package/lib/types/components/SuggestedQuestion/SuggestedQuestion.d.ts +4 -2
- package/lib/types/constants.d.ts +11 -0
- package/lib/types/hooks/useAnswerResults.d.ts +4 -4
- package/lib/types/hooks/useCioPia.d.ts +20 -5
- package/lib/types/hooks/usePiaClient.d.ts +12 -0
- package/lib/types/hooks/useRecsPod.d.ts +52 -0
- package/lib/types/hooks/useSuggestedQuestions.d.ts +3 -4
- package/lib/types/hooks/useViewportTracking.d.ts +2 -1
- package/lib/types/types.d.ts +119 -7
- package/lib/types/utils/classNames.d.ts +9 -0
- package/lib/types/utils/recs.d.ts +6 -0
- package/lib/types/version.d.ts +1 -1
- package/package.json +2 -2
- package/lib/cjs/hooks/mocks/MockConstructorIOClient.js +0 -24
- package/lib/cjs/hooks/mocks/agent.js +0 -166
- package/lib/mjs/hooks/mocks/MockConstructorIOClient.js +0 -38
- package/lib/mjs/hooks/mocks/agent.js +0 -158
- package/lib/types/hooks/mocks/MockConstructorIOClient.d.ts +0 -14
- package/lib/types/hooks/mocks/agent.d.ts +0 -10
- package/lib/types/hooks/mocks/types.d.ts +0 -77
- /package/lib/cjs/{hooks/mocks → components/CioPia}/types.js +0 -0
- /package/lib/mjs/{hooks/mocks → components/CioPia}/types.js +0 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { CioPiaProps } from '../CioPia/types';
|
|
3
|
+
/**
|
|
4
|
+
* A pod of AI-curated product suggestions: a personalized title, a row of products, and short
|
|
5
|
+
* options for narrowing them down. It asks no questions and makes no Q&A requests, so a retailer
|
|
6
|
+
* can use it on its own.
|
|
7
|
+
*
|
|
8
|
+
* Renders nothing at all once a request has settled with no products, so whatever the retailer
|
|
9
|
+
* already had in that slot shows through instead of an empty shell. That is the default: a caller
|
|
10
|
+
* that supplied its own root — `children` or `componentOverrides.reactNode` — still gets it in that
|
|
11
|
+
* state, with `error` available, and decides what belongs there.
|
|
12
|
+
*/
|
|
13
|
+
export default function CioPiaRecs(props: CioPiaProps): React.JSX.Element | null;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ComponentOverrideProps } from '@constructor-io/constructorio-ui-components';
|
|
3
|
+
import { LoadingRenderProps } from '../../types';
|
|
4
|
+
interface RecsCarouselSkeletonProps {
|
|
5
|
+
/** How many cards to draw. Defaults to the widest band the carousel lays out. */
|
|
6
|
+
count?: number;
|
|
7
|
+
componentOverride?: ComponentOverrideProps<LoadingRenderProps>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The product row, greyed out. It uses the real carousel rather than a set of measurements copied
|
|
11
|
+
* out of the package, so its padding, its gaps, how many cards it fits at the current width and its
|
|
12
|
+
* arrows are all right by construction. Matching the real heights is what keeps the page from
|
|
13
|
+
* jumping when the data lands.
|
|
14
|
+
*/
|
|
15
|
+
export default function RecsCarouselSkeleton({ count, componentOverride, }: RecsCarouselSkeletonProps): React.JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface RecsOptionsSkeletonProps {
|
|
3
|
+
/** How many pills to draw. Defaults to what the row usually holds. */
|
|
4
|
+
count?: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* The refinement options, greyed out. Matching the real height is what keeps the row from
|
|
8
|
+
* collapsing and shifting the page when the options land.
|
|
9
|
+
*
|
|
10
|
+
* Takes no override, the same way `SuggestedQuestionsSkeleton` takes none: `componentOverrides.
|
|
11
|
+
* loading` stands in for the band above this one, and a caller who replaced it keeps these pills
|
|
12
|
+
* underneath, exactly as a caller who replaces the answer skeleton in question-and-answer keeps the
|
|
13
|
+
* question pills under theirs.
|
|
14
|
+
*/
|
|
15
|
+
export default function RecsOptionsSkeleton({ count }: RecsOptionsSkeletonProps): React.JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { CioPiaComponentOverrides, RecsRefinement, Translations } from '../../types';
|
|
3
|
+
interface RecsPodRefinementProps {
|
|
4
|
+
refinement: RecsRefinement | null;
|
|
5
|
+
isLoading: boolean;
|
|
6
|
+
/** Message for a value the shopper submitted that came back rejected. */
|
|
7
|
+
inputError: string | null;
|
|
8
|
+
showInput: boolean;
|
|
9
|
+
translations?: Translations;
|
|
10
|
+
componentOverrides?: CioPiaComponentOverrides;
|
|
11
|
+
onRefine: (text: string) => void;
|
|
12
|
+
onSubmit: (value: string) => void;
|
|
13
|
+
onInputFocus: () => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The row under the products: a prompt line, the short options the API suggested, and a box for
|
|
17
|
+
* anything it did not think of. The prompt line is held still while the rest reloads, so the row
|
|
18
|
+
* never changes height under the shopper's cursor.
|
|
19
|
+
*/
|
|
20
|
+
export default function RecsPodRefinement({ refinement, isLoading, inputError, showInput, translations, componentOverrides, onRefine, onSubmit, onInputFocus, }: RecsPodRefinementProps): React.JSX.Element;
|
|
21
|
+
export {};
|
|
@@ -10,6 +10,14 @@ interface InputProps {
|
|
|
10
10
|
onFocus?: () => void;
|
|
11
11
|
translations?: Translations;
|
|
12
12
|
componentOverride?: ComponentOverrideProps<InputRenderProps>;
|
|
13
|
+
error?: string;
|
|
14
|
+
placeholderKey?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Render the Send button after the field.
|
|
17
|
+
*
|
|
18
|
+
* @default true
|
|
19
|
+
*/
|
|
20
|
+
showSendButton?: boolean;
|
|
13
21
|
}
|
|
14
|
-
declare function Input({ value: providedValue, placeholder, disabled, onSubmit, onFocus, translations, componentOverride, }: InputProps): React.JSX.Element;
|
|
22
|
+
declare function Input({ value: providedValue, placeholder, disabled, onSubmit, onFocus, translations, componentOverride, error, placeholderKey, showSendButton, }: InputProps): React.JSX.Element;
|
|
15
23
|
export default Input;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
2
|
interface SuggestedQuestionProps {
|
|
3
3
|
question: string;
|
|
4
4
|
onClick?: () => void;
|
|
5
|
+
/** Replaces the leading icon. Defaults to a question mark. */
|
|
6
|
+
icon?: ReactNode;
|
|
5
7
|
}
|
|
6
|
-
declare function SuggestedQuestion({ question, onClick }: SuggestedQuestionProps): React.JSX.Element;
|
|
8
|
+
declare function SuggestedQuestion({ question, onClick, icon }: SuggestedQuestionProps): React.JSX.Element;
|
|
7
9
|
export default SuggestedQuestion;
|
package/lib/types/constants.d.ts
CHANGED
|
@@ -7,3 +7,14 @@ export declare const MOCK_QUESTIONS: {
|
|
|
7
7
|
value: string;
|
|
8
8
|
}[];
|
|
9
9
|
export declare const DISCLAIMER_TEXT = "AI-generated answers aim to help, but they may occasionally miss details or be inaccurate. Double-check important information before purchasing.";
|
|
10
|
+
/**
|
|
11
|
+
* Recommendations pod strings the API cannot supply, because in these states there is either
|
|
12
|
+
* no response yet or no usable response at all. Everything else the pod shows comes from the
|
|
13
|
+
* API. All five are `Translations` keys, so reference the constants instead of retyping the
|
|
14
|
+
* literals - a mistyped key falls back to itself with no warning.
|
|
15
|
+
*/
|
|
16
|
+
export declare const RECS_LOADING_TITLE = "Adapting recommendations to your preference";
|
|
17
|
+
export declare const RECS_FALLBACK_TITLE = "Best selling products";
|
|
18
|
+
export declare const RECS_UNSUPPORTED_REQUEST = "Unsupported request, try a different feature.";
|
|
19
|
+
export declare const RECS_REFINEMENT_LABEL = "Not what you're looking for? Try:";
|
|
20
|
+
export declare const RECS_INPUT_PLACEHOLDER = "Describe something else...";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Nullable } from '@constructor-io/constructorio-client-javascript';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
2
|
+
import { AnswerRequestParameters, Formatters, Item, GetAnswerResultsResponse } from '../types';
|
|
3
|
+
import type { CioClient } from './usePiaClient';
|
|
4
4
|
export interface UseAnswerResultsProps {
|
|
5
5
|
itemId: string;
|
|
6
6
|
variationId?: string;
|
|
7
7
|
threadId?: string;
|
|
8
|
-
cioClient:
|
|
9
|
-
parameters?:
|
|
8
|
+
cioClient: CioClient;
|
|
9
|
+
parameters?: AnswerRequestParameters;
|
|
10
10
|
formatImageUrl?: Formatters['formatImageUrl'];
|
|
11
11
|
}
|
|
12
12
|
export interface UseAnswerResultsReturn {
|
|
@@ -1,18 +1,33 @@
|
|
|
1
1
|
import { Tracker } from '@constructor-io/constructorio-client-javascript/lib/types/constructorio';
|
|
2
|
-
import { Formatters, SuggestedQuestionsParameters } from '../types';
|
|
3
|
-
import MockConstructorIOClient from './mocks/MockConstructorIOClient';
|
|
2
|
+
import { AnswerRequestParameters, Formatters, SuggestedQuestionsParameters } from '../types';
|
|
4
3
|
import { UseAnswerResultsReturn } from './useAnswerResults';
|
|
4
|
+
import { CioClient } from './usePiaClient';
|
|
5
5
|
import { UseSuggestedQuestionsReturn } from './useSuggestedQuestions';
|
|
6
|
+
export type { CioClient };
|
|
6
7
|
export interface UseCioPiaProps {
|
|
7
8
|
apiKey: string;
|
|
8
9
|
itemId: string;
|
|
9
10
|
variationId?: string;
|
|
10
11
|
threadId?: string;
|
|
11
|
-
cioClient?:
|
|
12
|
+
cioClient?: CioClient;
|
|
12
13
|
suggestedQuestionsParameters?: SuggestedQuestionsParameters;
|
|
14
|
+
answerParameters?: AnswerRequestParameters;
|
|
13
15
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
+
* @deprecated Use `answerParameters` and `suggestedQuestionsParameters` instead.
|
|
17
|
+
*
|
|
18
|
+
* Only the following keys are forwarded (snake_case or camelCase accepted):
|
|
19
|
+
*
|
|
20
|
+
* Suggested-questions endpoint:
|
|
21
|
+
* - `num_results` / `numResults` → numResults
|
|
22
|
+
* - `pre_filter_expression` / `preFilterExpression` → preFilterExpression (JSON-parsed if string)
|
|
23
|
+
*
|
|
24
|
+
* Answer endpoint:
|
|
25
|
+
* - `guard` → guard
|
|
26
|
+
* - `pre_filter_expression` / `preFilterExpression` → preFilterExpression (JSON-parsed if string)
|
|
27
|
+
* - `fmt_options` / `fmtOptions` → fmtOptions (JSON-parsed if string)
|
|
28
|
+
*
|
|
29
|
+
* All other keys (e.g. `ef-*`) are silently dropped.
|
|
30
|
+
* Typed parameters take precedence over values specified here.
|
|
16
31
|
*/
|
|
17
32
|
parameters?: Record<string, string | number | boolean>;
|
|
18
33
|
/** Define outside the component or wrap with useCallback to avoid unnecessary re-renders. */
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import ConstructorIOClient from '@constructor-io/constructorio-client-javascript';
|
|
2
|
+
export type CioClient = InstanceType<typeof ConstructorIOClient>;
|
|
3
|
+
export interface UsePiaClientProps {
|
|
4
|
+
apiKey: string;
|
|
5
|
+
threadId?: string;
|
|
6
|
+
cioClient?: CioClient;
|
|
7
|
+
}
|
|
8
|
+
export interface UsePiaClientReturn {
|
|
9
|
+
cioClient: CioClient;
|
|
10
|
+
threadId: string;
|
|
11
|
+
}
|
|
12
|
+
export default function usePiaClient({ apiKey, threadId: providedThreadId, cioClient: providedClient, }: UsePiaClientProps): UsePiaClientReturn;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { CioClient } from './usePiaClient';
|
|
2
|
+
import { Formatters, Item, RecsPodParameters, RecsRefinement, Translations } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* What the shopper did to ask for this refinement.
|
|
5
|
+
*
|
|
6
|
+
* Worth distinguishing because a rejected request is only the shopper's business when the text
|
|
7
|
+
* came from them. An option is a label the API itself suggested, so a rejection there is ours to
|
|
8
|
+
* answer for, not something to flag under their input.
|
|
9
|
+
*/
|
|
10
|
+
export type RefinementSource = 'option' | 'input';
|
|
11
|
+
export interface UseRecsPodProps {
|
|
12
|
+
itemId: string;
|
|
13
|
+
variationId?: string;
|
|
14
|
+
threadId?: string;
|
|
15
|
+
cioClient?: CioClient;
|
|
16
|
+
parameters?: RecsPodParameters;
|
|
17
|
+
formatImageUrl?: Formatters['formatImageUrl'];
|
|
18
|
+
translations?: Translations;
|
|
19
|
+
}
|
|
20
|
+
export interface UseRecsPodReturn {
|
|
21
|
+
/** The title to show right now, already resolved for the current state. */
|
|
22
|
+
title: string;
|
|
23
|
+
/** The products to render, or `null` when there are none. Never an empty array. */
|
|
24
|
+
items: Array<Item> | null;
|
|
25
|
+
refinement: RecsRefinement | null;
|
|
26
|
+
/** True while a request is in flight. */
|
|
27
|
+
isLoading: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* The failure behind the fallback title, for callers rendering their own error handling.
|
|
30
|
+
* Only set for an outright failure: a degraded response (`status: 'partial'`) shows the fallback
|
|
31
|
+
* title with `error` still null, because that response arrived and its products are usable.
|
|
32
|
+
*/
|
|
33
|
+
error: Error | null;
|
|
34
|
+
/** Message to show under the input when the text the shopper sent was rejected. */
|
|
35
|
+
inputError: string | null;
|
|
36
|
+
/** The text behind what is currently on screen. Empty when nothing has been refined. */
|
|
37
|
+
lastShopperInput: string;
|
|
38
|
+
/**
|
|
39
|
+
* Fetches again, narrowed by `text`. Used by both the options and the free-text input, and
|
|
40
|
+
* `source` is how a rejected request finds the right place to be reported.
|
|
41
|
+
*/
|
|
42
|
+
refine: (text: string, source: RefinementSource) => void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Owns everything a recommendations pod shows: one request on mount, one on every refinement,
|
|
46
|
+
* and the title that belongs to whichever of those is happening right now.
|
|
47
|
+
*
|
|
48
|
+
* The previous items are deliberately kept while a new request is in flight, so a refinement
|
|
49
|
+
* swaps the products without collapsing the row they sit in. The title is the one thing that does
|
|
50
|
+
* change, so the shopper can see the pod reacting to what they asked for.
|
|
51
|
+
*/
|
|
52
|
+
export default function useRecsPod({ itemId, variationId, threadId, cioClient, parameters, formatImageUrl, translations, }: UseRecsPodProps): UseRecsPodReturn;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { Question, SuggestedQuestionsParameters } from '../types';
|
|
2
|
-
import
|
|
2
|
+
import type { CioClient } from './usePiaClient';
|
|
3
3
|
export interface UseSuggestedQuestionsProps {
|
|
4
4
|
itemId: string;
|
|
5
5
|
variationId?: string;
|
|
6
6
|
threadId?: string;
|
|
7
|
-
cioClient?:
|
|
7
|
+
cioClient?: CioClient;
|
|
8
8
|
parameters?: SuggestedQuestionsParameters;
|
|
9
|
-
requestParameters?: Record<string, string | number | boolean>;
|
|
10
9
|
}
|
|
11
10
|
export interface UseSuggestedQuestionsReturn {
|
|
12
11
|
data: Array<Question>;
|
|
@@ -14,4 +13,4 @@ export interface UseSuggestedQuestionsReturn {
|
|
|
14
13
|
error: Error | null;
|
|
15
14
|
getSuggestedQuestions: () => void;
|
|
16
15
|
}
|
|
17
|
-
export default function useSuggestedQuestions({ itemId, variationId, threadId, cioClient, parameters,
|
|
16
|
+
export default function useSuggestedQuestions({ itemId, variationId, threadId, cioClient, parameters, }: UseSuggestedQuestionsProps): UseSuggestedQuestionsReturn;
|
|
@@ -3,8 +3,9 @@ import { UseTrackingReturn } from './useTracking';
|
|
|
3
3
|
export interface UseViewportTrackingProps {
|
|
4
4
|
tracking: UseTrackingReturn;
|
|
5
5
|
questions: Question[];
|
|
6
|
+
viewThreshold?: number;
|
|
6
7
|
}
|
|
7
8
|
export interface UseViewportTrackingReturn {
|
|
8
9
|
containerRef: (node: HTMLDivElement | null) => void;
|
|
9
10
|
}
|
|
10
|
-
export default function useViewportTracking({ tracking, questions, }: UseViewportTrackingProps): UseViewportTrackingReturn;
|
|
11
|
+
export default function useViewportTracking({ tracking, questions, viewThreshold, }: UseViewportTrackingProps): UseViewportTrackingReturn;
|
package/lib/types/types.d.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { Product, CarouselOverrides, ComponentOverrideProps } from '@constructor-io/constructorio-ui-components';
|
|
3
|
-
import { ConstructorClientOptions, Nullable } from '@constructor-io/constructorio-client-javascript';
|
|
4
|
-
import {
|
|
5
|
-
import MockConstructorIOClient from './hooks/mocks/MockConstructorIOClient';
|
|
3
|
+
import { ConstructorClientOptions, FilterExpression, ItemData, Nullable } from '@constructor-io/constructorio-client-javascript';
|
|
4
|
+
import type { CioClient } from './hooks/usePiaClient';
|
|
6
5
|
export declare enum FeedbackType {
|
|
7
6
|
UP = "up",
|
|
8
7
|
DOWN = "down"
|
|
9
8
|
}
|
|
10
9
|
export interface PiaContextValue {
|
|
11
|
-
cioClient: Nullable<
|
|
10
|
+
cioClient: Nullable<CioClient>;
|
|
12
11
|
cioClientOptions: CioClientOptions;
|
|
13
12
|
setCioClientOptions: React.Dispatch<CioClientOptions>;
|
|
14
13
|
itemId: string;
|
|
@@ -23,11 +22,18 @@ export interface CioPiaProviderProps {
|
|
|
23
22
|
variationId?: string;
|
|
24
23
|
/** Thread ID for conversation context. Must be a valid UUID (e.g., "550e8400-e29b-41d4-a716-446655440000") */
|
|
25
24
|
threadId?: string;
|
|
26
|
-
cioClient?: Nullable<
|
|
25
|
+
cioClient?: Nullable<CioClient>;
|
|
27
26
|
}
|
|
28
|
-
export type CioPiaMode = 'default' | 'conversation';
|
|
27
|
+
export type CioPiaMode = 'default' | 'conversation' | 'recommendations';
|
|
29
28
|
export type CioPiaType = 'inline' | 'modal';
|
|
30
29
|
export type DisclaimerPosition = 'top' | 'bottom';
|
|
30
|
+
export type CioPiaTrackingConfigs = {
|
|
31
|
+
/**
|
|
32
|
+
* Fraction of the container (0–1) that must be visible before the
|
|
33
|
+
* `product_insights_agent.view` event fires. Defaults to `0.5`.
|
|
34
|
+
*/
|
|
35
|
+
viewThreshold?: number;
|
|
36
|
+
};
|
|
31
37
|
export type CioPiaDisplayConfigs = {
|
|
32
38
|
learnMoreUrl?: string;
|
|
33
39
|
showFeedback?: boolean;
|
|
@@ -60,6 +66,16 @@ export type Translations = {
|
|
|
60
66
|
'Learn More.'?: string;
|
|
61
67
|
'Ask about this product'?: string;
|
|
62
68
|
'Add to Cart'?: string;
|
|
69
|
+
/** Recommendations pod title shown while a request is in flight. */
|
|
70
|
+
'Adapting recommendations to your preference'?: string;
|
|
71
|
+
/** Recommendations pod title shown when a request fails or comes back degraded. */
|
|
72
|
+
'Best selling products'?: string;
|
|
73
|
+
/** Shown under the recommendations pod input when the request was rejected as unsuitable. */
|
|
74
|
+
'Unsupported request, try a different feature.'?: string;
|
|
75
|
+
/** Introduces the recommendations pod refinement options when the API sends no prompt of its own. */
|
|
76
|
+
"Not what you're looking for? Try:"?: string;
|
|
77
|
+
/** Placeholder for the recommendations pod refinement input. */
|
|
78
|
+
'Describe something else...'?: string;
|
|
63
79
|
};
|
|
64
80
|
export type QuestionSource = 'user' | 'suggestion';
|
|
65
81
|
export interface PiaCallbackContext {
|
|
@@ -115,6 +131,62 @@ export interface ConversationEntry {
|
|
|
115
131
|
threadId?: string;
|
|
116
132
|
qnaResultId?: string;
|
|
117
133
|
}
|
|
134
|
+
/** Which kind of recommendations to fetch. */
|
|
135
|
+
export type RecsStrategy = 'complementary_items' | 'alternative_items' | 'bestsellers' | 'bundles' | 'buy_it_again' | 'recently_viewed_items' | 'visually_similar_items';
|
|
136
|
+
/** A prompt line plus the short labels the shopper can pick from to narrow the results. */
|
|
137
|
+
export interface RecsRefinement {
|
|
138
|
+
/** Introduces the options. Falls back to a translatable default when absent. */
|
|
139
|
+
question?: string;
|
|
140
|
+
options: string[];
|
|
141
|
+
}
|
|
142
|
+
/** One recommendations response, in the shape the pod renders. */
|
|
143
|
+
export interface RecsResult {
|
|
144
|
+
title: string;
|
|
145
|
+
items: Item[] | null;
|
|
146
|
+
refinement: RecsRefinement | null;
|
|
147
|
+
resultId?: string;
|
|
148
|
+
threadId?: string;
|
|
149
|
+
/** `'partial'` means the response is degraded, but any items it carries are still usable. */
|
|
150
|
+
status?: 'complete' | 'partial';
|
|
151
|
+
}
|
|
152
|
+
export interface RecsPodParameters {
|
|
153
|
+
/**
|
|
154
|
+
* Which kind of recommendations to fetch. Inert until the recommendations endpoint ships: it is
|
|
155
|
+
* forwarded to `agent.getRecs`, which has nothing to send it to yet, so only a caller's own
|
|
156
|
+
* `getRecs` acts on it today.
|
|
157
|
+
*
|
|
158
|
+
* @default 'complementary_items'
|
|
159
|
+
*/
|
|
160
|
+
strategy?: RecsStrategy;
|
|
161
|
+
/** Last-resort title, used when the API returns items but no title of its own. */
|
|
162
|
+
defaultTitle?: string;
|
|
163
|
+
/**
|
|
164
|
+
* Render the free-text refinement input next to the refinement options.
|
|
165
|
+
*
|
|
166
|
+
* @default true
|
|
167
|
+
*/
|
|
168
|
+
showInput?: boolean;
|
|
169
|
+
/** How many products to request. */
|
|
170
|
+
numResults?: number;
|
|
171
|
+
}
|
|
172
|
+
/** Arguments for one recommendations request. */
|
|
173
|
+
export interface GetRecsProps {
|
|
174
|
+
itemId: string;
|
|
175
|
+
variationId?: string;
|
|
176
|
+
/** Thread ID for conversation context. Must be a valid UUID. */
|
|
177
|
+
threadId?: string;
|
|
178
|
+
/** @default 'complementary_items' */
|
|
179
|
+
strategy?: RecsStrategy;
|
|
180
|
+
/** Free text the shopper submitted to narrow the results. Absent on the first request. */
|
|
181
|
+
shopperInput?: string;
|
|
182
|
+
numResults?: number;
|
|
183
|
+
/**
|
|
184
|
+
* Applied while the raw results are converted to Items. It lives on the request rather than
|
|
185
|
+
* in the component because the raw response shape is provisional, and keeping the conversion
|
|
186
|
+
* behind this one call is what makes the endpoint swappable later.
|
|
187
|
+
*/
|
|
188
|
+
formatImageUrl?: Formatters['formatImageUrl'];
|
|
189
|
+
}
|
|
118
190
|
/**
|
|
119
191
|
* Render props passed to CioPia children function
|
|
120
192
|
*/
|
|
@@ -155,6 +227,8 @@ export interface InputRenderProps {
|
|
|
155
227
|
onSubmit: (value: string) => void;
|
|
156
228
|
onFocus?: () => void;
|
|
157
229
|
translations?: Translations;
|
|
230
|
+
/** Validation message for the value that was just submitted, when there is one. */
|
|
231
|
+
error?: string;
|
|
158
232
|
}
|
|
159
233
|
/**
|
|
160
234
|
* Component overrides for CioPia.
|
|
@@ -169,4 +243,42 @@ export interface CioPiaComponentOverrides extends ComponentOverrideProps<CioPiaR
|
|
|
169
243
|
feedback?: ComponentOverrideProps<FeedbackRenderProps>;
|
|
170
244
|
loading?: ComponentOverrideProps<LoadingRenderProps>;
|
|
171
245
|
}
|
|
172
|
-
export
|
|
246
|
+
export interface Question {
|
|
247
|
+
value: string;
|
|
248
|
+
}
|
|
249
|
+
export interface QuestionResponse {
|
|
250
|
+
questions: Array<Question>;
|
|
251
|
+
}
|
|
252
|
+
export interface SuggestedQuestionsParameters {
|
|
253
|
+
numResults?: number;
|
|
254
|
+
preFilterExpression?: FilterExpression;
|
|
255
|
+
}
|
|
256
|
+
export interface AnswerRequestParameters {
|
|
257
|
+
preFilterExpression?: FilterExpression;
|
|
258
|
+
guard?: boolean;
|
|
259
|
+
fmtOptions?: Record<string, any>;
|
|
260
|
+
}
|
|
261
|
+
export interface ApiItemVariation extends Record<string, any> {
|
|
262
|
+
value: string;
|
|
263
|
+
data?: ItemData;
|
|
264
|
+
}
|
|
265
|
+
export interface ApiItem extends Record<string, any> {
|
|
266
|
+
value: string;
|
|
267
|
+
matched_terms: Array<string>;
|
|
268
|
+
data: ItemData;
|
|
269
|
+
variations?: Array<ApiItemVariation> | null;
|
|
270
|
+
variations_map?: Record<string, any> | Array<Record<string, any>> | null;
|
|
271
|
+
}
|
|
272
|
+
export interface AnswerItemResults {
|
|
273
|
+
request?: Record<string, any>;
|
|
274
|
+
response: {
|
|
275
|
+
results: Array<ApiItem>;
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
export interface GetAnswerResultsResponse {
|
|
279
|
+
qna_result_id: string;
|
|
280
|
+
value: string;
|
|
281
|
+
item_results?: AnswerItemResults;
|
|
282
|
+
follow_up_questions?: Array<Question>;
|
|
283
|
+
thread_id?: string;
|
|
284
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Joins class names, dropping the falsy ones, so a conditional class can be written inline.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately not `clsx` or `classnames`: neither is a dependency of this package, and the copy of
|
|
5
|
+
* `clsx` in the tree belongs to `@constructor-io/constructorio-ui-components`, which is a peer
|
|
6
|
+
* dependency - importing it here would work locally and break in a consumer that hoists
|
|
7
|
+
* differently. Worth revisiting if this ever needs to accept objects or nested arrays.
|
|
8
|
+
*/
|
|
9
|
+
export declare const cx: (...parts: (string | false | null | undefined)[]) => string;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { RecsRefinement, Translations } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* The line that introduces the refinement options. Prefers the prompt the API sent, so our
|
|
4
|
+
* copy and theirs cannot drift.
|
|
5
|
+
*/
|
|
6
|
+
export declare function resolveRefinementQuestion(refinement: RecsRefinement | null, translations?: Translations): string;
|
package/lib/types/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "2.
|
|
1
|
+
declare const _default: "2.12.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.
|
|
3
|
+
"version": "2.12.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",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"prepare": "husky"
|
|
71
71
|
},
|
|
72
72
|
"peerDependencies": {
|
|
73
|
-
"@constructor-io/constructorio-client-javascript": "^2.
|
|
73
|
+
"@constructor-io/constructorio-client-javascript": "^2.93.0",
|
|
74
74
|
"@constructor-io/constructorio-ui-components": "^1.5.0",
|
|
75
75
|
"react": ">=16.12.0",
|
|
76
76
|
"react-dom": ">=16.12.0",
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const constructorio_client_javascript_1 = tslib_1.__importDefault(require("@constructor-io/constructorio-client-javascript"));
|
|
5
|
-
const agent_1 = tslib_1.__importDefault(require("./agent"));
|
|
6
|
-
const version_1 = tslib_1.__importDefault(require("../../version"));
|
|
7
|
-
class MockConstructorIOClient {
|
|
8
|
-
constructor(options) {
|
|
9
|
-
const isServer = typeof window === 'undefined' || typeof document === 'undefined';
|
|
10
|
-
const clientOptions = Object.assign(Object.assign(Object.assign({ version: options.version || `cio-ui-pia-${version_1.default}`, serviceUrl: options.serviceUrl || 'https://ac.cnstrc.com', quizzesServiceUrl: options.quizzesServiceUrl || 'https://quizzes.cnstrc.com', agentServiceUrl: options.agentServiceUrl || 'https://agent.cnstrc.com' }, (isServer && {
|
|
11
|
-
clientId: options.clientId || 'this-is-a-random-client-id',
|
|
12
|
-
})), { sendTrackingEvents: options.sendTrackingEvents !== undefined ? options.sendTrackingEvents : true, beaconMode: options.beaconMode !== undefined ? options.beaconMode : true, networkParameters: options.networkParameters || {} }), options);
|
|
13
|
-
const cioClient = new constructorio_client_javascript_1.default(clientOptions);
|
|
14
|
-
const { clientId, sessionId } = cioClient.agent.options;
|
|
15
|
-
this.options = Object.assign(Object.assign({}, clientOptions), { clientId, sessionId });
|
|
16
|
-
this.search = cioClient.search;
|
|
17
|
-
this.browse = cioClient.browse;
|
|
18
|
-
this.recommendations = cioClient.recommendations;
|
|
19
|
-
this.tracker = cioClient.tracker;
|
|
20
|
-
this.quizzes = cioClient.quizzes;
|
|
21
|
-
this.agent = new agent_1.default(this.options);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
exports.default = MockConstructorIOClient;
|