@constructor-io/constructorio-ui-quizzes 1.8.3 → 1.9.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/constructorio-ui-quizzes-bundled.js +20 -20
- package/lib/cjs/package.json +1 -1
- package/lib/cjs/src/components/CioQuiz/actions.js +1 -0
- package/lib/cjs/src/components/CioQuiz/index.js +2 -1
- package/lib/cjs/src/components/CioQuiz/quizLocalReducer.js +21 -0
- package/lib/cjs/src/components/ControlBar/ControlBar.js +5 -2
- package/lib/cjs/src/components/SkipButton/SkipButton.js +13 -0
- package/lib/cjs/src/constants.js +2 -0
- package/lib/cjs/src/hooks/usePropsGetters/index.js +4 -1
- package/lib/cjs/src/hooks/usePropsGetters/useSkipQuestionButtonProps.js +21 -0
- package/lib/cjs/src/hooks/useQuizEvents/index.js +3 -0
- package/lib/cjs/src/hooks/useQuizEvents/useQuizSkipClick.js +31 -0
- package/lib/cjs/src/stories/Quiz/tests/mocks.js +1 -0
- package/lib/cjs/src/utils.js +1 -0
- package/lib/mjs/package.json +1 -1
- package/lib/mjs/src/components/CioQuiz/actions.js +1 -0
- package/lib/mjs/src/components/CioQuiz/index.js +2 -1
- package/lib/mjs/src/components/CioQuiz/quizLocalReducer.js +25 -0
- package/lib/mjs/src/components/ControlBar/ControlBar.js +5 -2
- package/lib/mjs/src/components/SkipButton/SkipButton.js +10 -0
- package/lib/mjs/src/constants.js +2 -0
- package/lib/mjs/src/hooks/usePropsGetters/index.js +4 -1
- package/lib/mjs/src/hooks/usePropsGetters/useSkipQuestionButtonProps.js +17 -0
- package/lib/mjs/src/hooks/useQuizEvents/index.js +3 -0
- package/lib/mjs/src/hooks/useQuizEvents/useQuizSkipClick.js +31 -0
- package/lib/mjs/src/stories/Quiz/tests/mocks.js +4 -0
- package/lib/mjs/src/utils.js +1 -0
- package/lib/styles.css +35 -1
- package/lib/types/src/components/CioQuiz/actions.d.ts +2 -1
- package/lib/types/src/components/CioQuiz/context.d.ts +2 -1
- package/lib/types/src/components/SkipButton/SkipButton.d.ts +6 -0
- package/lib/types/src/constants.d.ts +2 -2
- package/lib/types/src/hooks/usePropsGetters/index.d.ts +2 -1
- package/lib/types/src/hooks/usePropsGetters/useSkipQuestionButtonProps.d.ts +3 -0
- package/lib/types/src/hooks/useQuizEvents/useQuizSkipClick.d.ts +6 -0
- package/lib/types/src/stories/Quiz/tests/mocks.d.ts +2 -2
- package/lib/types/src/types.d.ts +13 -1
- package/lib/types/src/utils.d.ts +1 -0
- package/package.json +1 -1
package/lib/cjs/package.json
CHANGED
|
@@ -9,6 +9,7 @@ var QuestionTypes;
|
|
|
9
9
|
QuestionTypes["SingleSelect"] = "single";
|
|
10
10
|
QuestionTypes["MultipleSelect"] = "multiple";
|
|
11
11
|
QuestionTypes["Next"] = "next";
|
|
12
|
+
QuestionTypes["Skip"] = "skip";
|
|
12
13
|
QuestionTypes["Back"] = "back";
|
|
13
14
|
QuestionTypes["Reset"] = "reset";
|
|
14
15
|
QuestionTypes["Hydrate"] = "hydrate";
|
|
@@ -14,7 +14,7 @@ const utils_1 = require("../../utils");
|
|
|
14
14
|
const ProgressBar_1 = tslib_1.__importDefault(require("../ProgressBar/ProgressBar"));
|
|
15
15
|
function CioQuiz(props) {
|
|
16
16
|
var _a;
|
|
17
|
-
const { cioClient, state, events: { hydrateQuiz, resetSessionStorageState }, getAddToCartButtonProps, getAddToFavoritesButtonProps, getCoverQuestionProps, getHydrateQuizButtonProps, getNextQuestionButtonProps, getOpenTextInputProps, getPreviousQuestionButtonProps, getQuizImageProps, getQuizResultButtonProps, getQuizResultLinkProps, getResetQuizButtonProps, getSelectInputProps, primaryColorStyles, } = (0, useQuiz_1.default)(props);
|
|
17
|
+
const { cioClient, state, events: { hydrateQuiz, resetSessionStorageState }, getAddToCartButtonProps, getAddToFavoritesButtonProps, getCoverQuestionProps, getHydrateQuizButtonProps, getNextQuestionButtonProps, getSkipQuestionButtonProps, getOpenTextInputProps, getPreviousQuestionButtonProps, getQuizImageProps, getQuizResultButtonProps, getQuizResultLinkProps, getResetQuizButtonProps, getSelectInputProps, primaryColorStyles, } = (0, useQuiz_1.default)(props);
|
|
18
18
|
const [showSessionPrompt, setShowSessionPrompt] = (0, react_1.useState)(false);
|
|
19
19
|
const { resultsPageOptions, sessionStateOptions } = props;
|
|
20
20
|
const { quizSessionStorageState: { hasSessionStorageState, skipToResults }, } = state;
|
|
@@ -36,6 +36,7 @@ function CioQuiz(props) {
|
|
|
36
36
|
getCoverQuestionProps,
|
|
37
37
|
getHydrateQuizButtonProps,
|
|
38
38
|
getNextQuestionButtonProps,
|
|
39
|
+
getSkipQuestionButtonProps,
|
|
39
40
|
getOpenTextInputProps,
|
|
40
41
|
getPreviousQuestionButtonProps,
|
|
41
42
|
getQuizImageProps,
|
|
@@ -51,6 +51,27 @@ function quizLocalReducer(state, action) {
|
|
|
51
51
|
// We now commit current answers to prevAnswerInputs
|
|
52
52
|
prevAnswerInputs: answerInputs, answers: newAnswers, isQuizCompleted: false });
|
|
53
53
|
}
|
|
54
|
+
case actions_1.QuestionTypes.Skip: {
|
|
55
|
+
const { answers, answerInputs } = state;
|
|
56
|
+
const newAnswers = [...answers];
|
|
57
|
+
const lastAnswerInputIndex = answers.length;
|
|
58
|
+
const currentAnswerInput = Object.values(state.answerInputs)[lastAnswerInputIndex];
|
|
59
|
+
switch (currentAnswerInput.type) {
|
|
60
|
+
case actions_1.QuestionTypes.OpenText:
|
|
61
|
+
newAnswers.push(['false']);
|
|
62
|
+
break;
|
|
63
|
+
case actions_1.QuestionTypes.Cover:
|
|
64
|
+
newAnswers.push(['seen']);
|
|
65
|
+
break;
|
|
66
|
+
case actions_1.QuestionTypes.SingleSelect:
|
|
67
|
+
case actions_1.QuestionTypes.MultipleSelect:
|
|
68
|
+
default:
|
|
69
|
+
newAnswers.push([]);
|
|
70
|
+
}
|
|
71
|
+
return Object.assign(Object.assign({}, state), {
|
|
72
|
+
// We now commit current answers to prevAnswerInputs
|
|
73
|
+
prevAnswerInputs: answerInputs, answers: newAnswers, isQuizCompleted: false });
|
|
74
|
+
}
|
|
54
75
|
case actions_1.QuestionTypes.Back: {
|
|
55
76
|
const prevAnswerInputs = Object.assign({}, state.prevAnswerInputs);
|
|
56
77
|
return Object.assign(Object.assign({}, state), { answerInputs: prevAnswerInputs, answers: [...state.answers.slice(0, -1)], isLastAnswer: false, isQuizCompleted: false });
|
|
@@ -4,12 +4,15 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
const react_1 = tslib_1.__importStar(require("react"));
|
|
5
5
|
const BackButton_1 = tslib_1.__importDefault(require("../BackButton/BackButton"));
|
|
6
6
|
const CTAButton_1 = tslib_1.__importDefault(require("../CTAButton/CTAButton"));
|
|
7
|
+
const SkipButton_1 = tslib_1.__importDefault(require("../SkipButton/SkipButton"));
|
|
7
8
|
const context_1 = tslib_1.__importDefault(require("../CioQuiz/context"));
|
|
8
9
|
function ControlBar(props) {
|
|
9
10
|
const { ctaButtonText } = props;
|
|
10
|
-
const { getNextQuestionButtonProps } = (0, react_1.useContext)(context_1.default);
|
|
11
|
+
const { getNextQuestionButtonProps, getSkipQuestionButtonProps } = (0, react_1.useContext)(context_1.default);
|
|
11
12
|
return (react_1.default.createElement("div", { className: 'cio-question-buttons-container' },
|
|
12
13
|
react_1.default.createElement(BackButton_1.default, null),
|
|
13
|
-
react_1.default.createElement(
|
|
14
|
+
react_1.default.createElement("div", { className: 'cio-question-buttons-group' },
|
|
15
|
+
react_1.default.createElement(SkipButton_1.default, { propsGetters: getSkipQuestionButtonProps }),
|
|
16
|
+
react_1.default.createElement(CTAButton_1.default, { ctaText: ctaButtonText, propsGetters: getNextQuestionButtonProps }))));
|
|
14
17
|
}
|
|
15
18
|
exports.default = ControlBar;
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
+
function SkipButton(props) {
|
|
6
|
+
const { propsGetters, className = 'cio-button-container' } = props, rest = tslib_1.__rest(props, ["propsGetters", "className"]);
|
|
7
|
+
return (react_1.default.createElement("div", { className: `${className || ''}` }, propsGetters && (
|
|
8
|
+
// eslint-disable-next-line react/button-has-type
|
|
9
|
+
react_1.default.createElement("button", Object.assign({}, rest, propsGetters()),
|
|
10
|
+
"Skip",
|
|
11
|
+
react_1.default.createElement("span", null, " question")))));
|
|
12
|
+
}
|
|
13
|
+
exports.default = SkipButton;
|
package/lib/cjs/src/constants.js
CHANGED
|
@@ -25,6 +25,7 @@ exports.componentDescription = `- import \`CioQuiz\` to render in your JSX.
|
|
|
25
25
|
- \`numResultsToDisplay\` is an optional parameter that determines how many results should be displayed on results page
|
|
26
26
|
- \`callbacks\` lets you pass callback functions that will be called on certain actions
|
|
27
27
|
- \`onQuizNextQuestion\` is an optional callback function that will be called when user moves to the next question
|
|
28
|
+
- \`onQuizSkipQuestion\` is an optional callback function that will be called when user skips a question
|
|
28
29
|
- \`sessionStateOptions\` lets you configure the session modal behavior
|
|
29
30
|
- \`showSessionModal\` is a boolean used to decide whether to show the session modal. The default behavior is to show the session modal
|
|
30
31
|
- \`showSessionModalOnResults\` is a boolean to decide whether to show the session modal after reaching the results page. The default behavior is to not show the session modal
|
|
@@ -57,6 +58,7 @@ const {
|
|
|
57
58
|
getCoverQuestionProps: () => ({...})), // prop getter for jsx quiz cover question,
|
|
58
59
|
getHydrateQuizButtonProps: () => ({...})), // prop getter for jsx hydrate quiz button,
|
|
59
60
|
getNextQuestionButtonProps: () => ({...})), // prop getter for jsx next button to traverse the quiz,
|
|
61
|
+
getSkipQuestionButtonProps: () => ({...})), // prop getter for jsx skip button to traverse the quiz,
|
|
60
62
|
getPreviousQuestionButtonProps: () => ({...})), // prop getter for jsx back button to traverse the quiz,
|
|
61
63
|
getOpenTextInputProps: () => ({...})), // prop getter for jsx open text input,
|
|
62
64
|
getSelectInputProps: () => ({...})), // prop getter for jsx select input for select type questions,
|
|
@@ -8,13 +8,15 @@ const useOpenTextInputProps_1 = tslib_1.__importDefault(require("./useOpenTextIn
|
|
|
8
8
|
const useNextQuestionButtonProps_1 = tslib_1.__importDefault(require("./useNextQuestionButtonProps"));
|
|
9
9
|
const usePreviousQuestionButtonProps_1 = tslib_1.__importDefault(require("./usePreviousQuestionButtonProps"));
|
|
10
10
|
const useAddToFavoritesButtonProps_1 = tslib_1.__importDefault(require("./useAddToFavoritesButtonProps"));
|
|
11
|
+
const useSkipQuestionButtonProps_1 = tslib_1.__importDefault(require("./useSkipQuestionButtonProps"));
|
|
11
12
|
const usePropsGetters = (quizEvents, quizApiState, quizLocalState) => {
|
|
12
13
|
var _a, _b, _c;
|
|
13
|
-
const { quizAnswerChanged, nextQuestion, previousQuestion, resetQuiz, hydrateQuiz, addToCart, addToFavorites, resultClick, } = quizEvents;
|
|
14
|
+
const { quizAnswerChanged, nextQuestion, skipQuestion, previousQuestion, resetQuiz, hydrateQuiz, addToCart, addToFavorites, resultClick, } = quizEvents;
|
|
14
15
|
const getOpenTextInputProps = (0, useOpenTextInputProps_1.default)(quizAnswerChanged, nextQuestion, (_a = quizApiState.quizCurrentQuestion) === null || _a === void 0 ? void 0 : _a.next_question, quizLocalState.answerInputs);
|
|
15
16
|
const getCoverQuestionProps = (0, useCoverQuestionProps_1.default)(quizAnswerChanged, (_b = quizApiState.quizCurrentQuestion) === null || _b === void 0 ? void 0 : _b.next_question);
|
|
16
17
|
const getSelectInputProps = (0, useSelectInputProps_1.default)(quizAnswerChanged, nextQuestion, (_c = quizApiState.quizCurrentQuestion) === null || _c === void 0 ? void 0 : _c.next_question, quizLocalState.answerInputs);
|
|
17
18
|
const getNextQuestionButtonProps = (0, useNextQuestionButtonProps_1.default)(nextQuestion, quizApiState, quizLocalState);
|
|
19
|
+
const getSkipQuestionButtonProps = (0, useSkipQuestionButtonProps_1.default)(skipQuestion, quizApiState);
|
|
18
20
|
const getPreviousQuestionButtonProps = (0, usePreviousQuestionButtonProps_1.default)(quizApiState, previousQuestion);
|
|
19
21
|
const getResetQuizButtonProps = (0, react_1.useCallback)((stylesType = 'primary') => ({
|
|
20
22
|
className: stylesType === 'primary' ? 'cio-question-cta-button' : 'cio-question-redo-button',
|
|
@@ -83,6 +85,7 @@ const usePropsGetters = (quizEvents, quizApiState, quizLocalState) => {
|
|
|
83
85
|
getAddToFavoritesButtonProps,
|
|
84
86
|
getQuizResultButtonProps,
|
|
85
87
|
getQuizResultLinkProps,
|
|
88
|
+
getSkipQuestionButtonProps,
|
|
86
89
|
};
|
|
87
90
|
};
|
|
88
91
|
exports.default = usePropsGetters;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const react_1 = require("react");
|
|
4
|
+
function useSkipQuestionButtonProps(skipQuestion, quizApiState) {
|
|
5
|
+
const getSkipQuestionButtonProps = (0, react_1.useCallback)(() => {
|
|
6
|
+
var _a, _b, _c, _d;
|
|
7
|
+
const currentQuestionId = (_b = (_a = quizApiState.quizCurrentQuestion) === null || _a === void 0 ? void 0 : _a.next_question) === null || _b === void 0 ? void 0 : _b.id;
|
|
8
|
+
const isHidden = currentQuestionId &&
|
|
9
|
+
(((_c = quizApiState.quizCurrentQuestion) === null || _c === void 0 ? void 0 : _c.isCoverQuestion) ||
|
|
10
|
+
!((_d = quizApiState.quizCurrentQuestion) === null || _d === void 0 ? void 0 : _d.next_question.is_skippable));
|
|
11
|
+
return {
|
|
12
|
+
className: isHidden ? 'cio-question-skip-button hide' : 'cio-question-skip-button',
|
|
13
|
+
type: 'button',
|
|
14
|
+
onClick: () => {
|
|
15
|
+
skipQuestion();
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}, [quizApiState.quizCurrentQuestion, skipQuestion]);
|
|
19
|
+
return getSkipQuestionButtonProps;
|
|
20
|
+
}
|
|
21
|
+
exports.default = useSkipQuestionButtonProps;
|
|
@@ -11,6 +11,7 @@ const useQuizResetClick_1 = tslib_1.__importDefault(require("./useQuizResetClick
|
|
|
11
11
|
const useHydrateQuizLocalState_1 = tslib_1.__importDefault(require("./useHydrateQuizLocalState"));
|
|
12
12
|
const utils_1 = require("../../utils");
|
|
13
13
|
const useQuizAddToFavorites_1 = tslib_1.__importDefault(require("./useQuizAddToFavorites"));
|
|
14
|
+
const useQuizSkipClick_1 = tslib_1.__importDefault(require("./useQuizSkipClick"));
|
|
14
15
|
const useQuizEvents = (quizOptions, cioClient, quizState) => {
|
|
15
16
|
const { quizApiState, dispatchLocalState, dispatchApiState, quizLocalState, quizSessionStorageState, } = quizState;
|
|
16
17
|
const { resultsPageOptions, callbacks } = quizOptions;
|
|
@@ -19,6 +20,7 @@ const useQuizEvents = (quizOptions, cioClient, quizState) => {
|
|
|
19
20
|
const quizAnswerChanged = (0, useQuizAnswerChangeHandler_1.default)(quizApiState, dispatchLocalState);
|
|
20
21
|
// Quiz Next button click callback
|
|
21
22
|
const nextQuestion = (0, useQuizNextClick_1.default)(quizApiState, quizLocalState, dispatchLocalState, callbacks === null || callbacks === void 0 ? void 0 : callbacks.onQuizNextQuestion);
|
|
23
|
+
const skipQuestion = (0, useQuizSkipClick_1.default)(quizApiState, quizLocalState, dispatchLocalState, callbacks === null || callbacks === void 0 ? void 0 : callbacks.onQuizSkipQuestion);
|
|
22
24
|
// Quiz Back button click callback
|
|
23
25
|
const previousQuestion = (0, useQuizBackClick_1.default)(quizApiState, dispatchLocalState);
|
|
24
26
|
// Quiz result add to cart callback
|
|
@@ -39,6 +41,7 @@ const useQuizEvents = (quizOptions, cioClient, quizState) => {
|
|
|
39
41
|
quizAnswerChanged,
|
|
40
42
|
previousQuestion,
|
|
41
43
|
nextQuestion,
|
|
44
|
+
skipQuestion,
|
|
42
45
|
resetQuiz,
|
|
43
46
|
hydrateQuiz: hydrateQuizLocalState,
|
|
44
47
|
resetSessionStorageState: (0, utils_1.resetQuizSessionStorageState)(quizSessionStorageState.key),
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const react_1 = require("react");
|
|
4
|
+
const actions_1 = require("../../components/CioQuiz/actions");
|
|
5
|
+
const utils_1 = require("../../utils");
|
|
6
|
+
const useQuizSkipClick = (quizApiState, quizLocalState, dispatchLocalState, onQuizSkipQuestion) => {
|
|
7
|
+
const quizSkipClickHandler = (0, react_1.useCallback)(() => {
|
|
8
|
+
var _a;
|
|
9
|
+
const currentQuestion = (_a = quizApiState.quizCurrentQuestion) === null || _a === void 0 ? void 0 : _a.next_question;
|
|
10
|
+
const currentQuestionId = currentQuestion === null || currentQuestion === void 0 ? void 0 : currentQuestion.id;
|
|
11
|
+
if (dispatchLocalState && currentQuestionId) {
|
|
12
|
+
if (!((currentQuestion === null || currentQuestion === void 0 ? void 0 : currentQuestion.type) === 'cover')) {
|
|
13
|
+
dispatchLocalState({
|
|
14
|
+
type: actions_1.QuestionTypes.Skip,
|
|
15
|
+
payload: quizApiState.quizCurrentQuestion,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
const currentAnswerInput = Object.assign(Object.assign({}, quizLocalState.answerInputs[currentQuestionId]), { value: (currentQuestion === null || currentQuestion === void 0 ? void 0 : currentQuestion.type) === 'open' ? 'false' : null });
|
|
19
|
+
if (currentQuestion && (0, utils_1.isFunction)(onQuizSkipQuestion)) {
|
|
20
|
+
onQuizSkipQuestion(Object.assign(Object.assign({}, currentQuestion), { answer: currentAnswerInput }));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}, [
|
|
24
|
+
dispatchLocalState,
|
|
25
|
+
onQuizSkipQuestion,
|
|
26
|
+
quizApiState.quizCurrentQuestion,
|
|
27
|
+
quizLocalState.answerInputs,
|
|
28
|
+
]);
|
|
29
|
+
return quizSkipClickHandler;
|
|
30
|
+
};
|
|
31
|
+
exports.default = useQuizSkipClick;
|
|
@@ -153,6 +153,7 @@ const useMockContextValue = (question) => {
|
|
|
153
153
|
getAddToFavoritesButtonProps: () => (Object.assign(Object.assign({}, mockElementProps), { className: 'cio-result-card-favorites-button' })),
|
|
154
154
|
getHydrateQuizButtonProps: () => (Object.assign(Object.assign({}, mockElementProps), { className: 'cio-question-cta-button' })),
|
|
155
155
|
getNextQuestionButtonProps: () => (Object.assign(Object.assign({}, mockElementProps), { className: 'cio-question-cta-button' })),
|
|
156
|
+
getSkipQuestionButtonProps: () => (Object.assign(Object.assign({}, mockElementProps), { className: 'cio-question-skip-button' })),
|
|
156
157
|
getPreviousQuestionButtonProps: () => (Object.assign(Object.assign({}, mockElementProps), { className: 'cio-question-back-button' })),
|
|
157
158
|
getQuizImageProps: () => mockElementProps,
|
|
158
159
|
getQuizResultButtonProps: () => mockElementProps,
|
package/lib/cjs/src/utils.js
CHANGED
|
@@ -48,6 +48,7 @@ exports.functionStrings = {
|
|
|
48
48
|
onAddToFavoritesClick: `(item) => console.dir(item)`,
|
|
49
49
|
onQuizResultsLoaded: `(results) => console.dir(results)`,
|
|
50
50
|
onQuizNextQuestion: `(question) => console.dir(question)`,
|
|
51
|
+
onQuizSkipQuestion: `(question) => console.dir(question)`,
|
|
51
52
|
cioJsClient: `cioJsClient`,
|
|
52
53
|
};
|
|
53
54
|
const stringifyWithDefaults = (obj) => {
|
package/lib/mjs/package.json
CHANGED
|
@@ -6,6 +6,7 @@ export var QuestionTypes;
|
|
|
6
6
|
QuestionTypes["SingleSelect"] = "single";
|
|
7
7
|
QuestionTypes["MultipleSelect"] = "multiple";
|
|
8
8
|
QuestionTypes["Next"] = "next";
|
|
9
|
+
QuestionTypes["Skip"] = "skip";
|
|
9
10
|
QuestionTypes["Back"] = "back";
|
|
10
11
|
QuestionTypes["Reset"] = "reset";
|
|
11
12
|
QuestionTypes["Hydrate"] = "hydrate";
|
|
@@ -10,7 +10,7 @@ import SessionPromptModal from '../SessionPromptModal/SessionPromptModal';
|
|
|
10
10
|
import { convertPrimaryColorsToString, renderImages } from '../../utils';
|
|
11
11
|
import ProgressBar from '../ProgressBar/ProgressBar';
|
|
12
12
|
export default function CioQuiz(props) {
|
|
13
|
-
const { cioClient, state, events: { hydrateQuiz, resetSessionStorageState }, getAddToCartButtonProps, getAddToFavoritesButtonProps, getCoverQuestionProps, getHydrateQuizButtonProps, getNextQuestionButtonProps, getOpenTextInputProps, getPreviousQuestionButtonProps, getQuizImageProps, getQuizResultButtonProps, getQuizResultLinkProps, getResetQuizButtonProps, getSelectInputProps, primaryColorStyles, } = useQuiz(props);
|
|
13
|
+
const { cioClient, state, events: { hydrateQuiz, resetSessionStorageState }, getAddToCartButtonProps, getAddToFavoritesButtonProps, getCoverQuestionProps, getHydrateQuizButtonProps, getNextQuestionButtonProps, getSkipQuestionButtonProps, getOpenTextInputProps, getPreviousQuestionButtonProps, getQuizImageProps, getQuizResultButtonProps, getQuizResultLinkProps, getResetQuizButtonProps, getSelectInputProps, primaryColorStyles, } = useQuiz(props);
|
|
14
14
|
const [showSessionPrompt, setShowSessionPrompt] = useState(false);
|
|
15
15
|
const { resultsPageOptions, sessionStateOptions } = props;
|
|
16
16
|
const { quizSessionStorageState: { hasSessionStorageState, skipToResults }, } = state;
|
|
@@ -32,6 +32,7 @@ export default function CioQuiz(props) {
|
|
|
32
32
|
getCoverQuestionProps,
|
|
33
33
|
getHydrateQuizButtonProps,
|
|
34
34
|
getNextQuestionButtonProps,
|
|
35
|
+
getSkipQuestionButtonProps,
|
|
35
36
|
getOpenTextInputProps,
|
|
36
37
|
getPreviousQuestionButtonProps,
|
|
37
38
|
getQuizImageProps,
|
|
@@ -74,6 +74,31 @@ export default function quizLocalReducer(state, action) {
|
|
|
74
74
|
isQuizCompleted: false,
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
+
case QuestionTypes.Skip: {
|
|
78
|
+
const { answers, answerInputs } = state;
|
|
79
|
+
const newAnswers = [...answers];
|
|
80
|
+
const lastAnswerInputIndex = answers.length;
|
|
81
|
+
const currentAnswerInput = Object.values(state.answerInputs)[lastAnswerInputIndex];
|
|
82
|
+
switch (currentAnswerInput.type) {
|
|
83
|
+
case QuestionTypes.OpenText:
|
|
84
|
+
newAnswers.push(['false']);
|
|
85
|
+
break;
|
|
86
|
+
case QuestionTypes.Cover:
|
|
87
|
+
newAnswers.push(['seen']);
|
|
88
|
+
break;
|
|
89
|
+
case QuestionTypes.SingleSelect:
|
|
90
|
+
case QuestionTypes.MultipleSelect:
|
|
91
|
+
default:
|
|
92
|
+
newAnswers.push([]);
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
...state,
|
|
96
|
+
// We now commit current answers to prevAnswerInputs
|
|
97
|
+
prevAnswerInputs: answerInputs,
|
|
98
|
+
answers: newAnswers,
|
|
99
|
+
isQuizCompleted: false,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
77
102
|
case QuestionTypes.Back: {
|
|
78
103
|
const prevAnswerInputs = { ...state.prevAnswerInputs };
|
|
79
104
|
return {
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import React, { useContext } from 'react';
|
|
2
2
|
import BackButton from '../BackButton/BackButton';
|
|
3
3
|
import CTAButton from '../CTAButton/CTAButton';
|
|
4
|
+
import SkipButton from '../SkipButton/SkipButton';
|
|
4
5
|
import QuizContext from '../CioQuiz/context';
|
|
5
6
|
function ControlBar(props) {
|
|
6
7
|
const { ctaButtonText } = props;
|
|
7
|
-
const { getNextQuestionButtonProps } = useContext(QuizContext);
|
|
8
|
+
const { getNextQuestionButtonProps, getSkipQuestionButtonProps } = useContext(QuizContext);
|
|
8
9
|
return (React.createElement("div", { className: 'cio-question-buttons-container' },
|
|
9
10
|
React.createElement(BackButton, null),
|
|
10
|
-
React.createElement(
|
|
11
|
+
React.createElement("div", { className: 'cio-question-buttons-group' },
|
|
12
|
+
React.createElement(SkipButton, { propsGetters: getSkipQuestionButtonProps }),
|
|
13
|
+
React.createElement(CTAButton, { ctaText: ctaButtonText, propsGetters: getNextQuestionButtonProps }))));
|
|
11
14
|
}
|
|
12
15
|
export default ControlBar;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
function SkipButton(props) {
|
|
3
|
+
const { propsGetters, className = 'cio-button-container', ...rest } = props;
|
|
4
|
+
return (React.createElement("div", { className: `${className || ''}` }, propsGetters && (
|
|
5
|
+
// eslint-disable-next-line react/button-has-type
|
|
6
|
+
React.createElement("button", { ...rest, ...propsGetters() },
|
|
7
|
+
"Skip",
|
|
8
|
+
React.createElement("span", null, " question")))));
|
|
9
|
+
}
|
|
10
|
+
export default SkipButton;
|
package/lib/mjs/src/constants.js
CHANGED
|
@@ -22,6 +22,7 @@ export const componentDescription = `- import \`CioQuiz\` to render in your JSX.
|
|
|
22
22
|
- \`numResultsToDisplay\` is an optional parameter that determines how many results should be displayed on results page
|
|
23
23
|
- \`callbacks\` lets you pass callback functions that will be called on certain actions
|
|
24
24
|
- \`onQuizNextQuestion\` is an optional callback function that will be called when user moves to the next question
|
|
25
|
+
- \`onQuizSkipQuestion\` is an optional callback function that will be called when user skips a question
|
|
25
26
|
- \`sessionStateOptions\` lets you configure the session modal behavior
|
|
26
27
|
- \`showSessionModal\` is a boolean used to decide whether to show the session modal. The default behavior is to show the session modal
|
|
27
28
|
- \`showSessionModalOnResults\` is a boolean to decide whether to show the session modal after reaching the results page. The default behavior is to not show the session modal
|
|
@@ -54,6 +55,7 @@ const {
|
|
|
54
55
|
getCoverQuestionProps: () => ({...})), // prop getter for jsx quiz cover question,
|
|
55
56
|
getHydrateQuizButtonProps: () => ({...})), // prop getter for jsx hydrate quiz button,
|
|
56
57
|
getNextQuestionButtonProps: () => ({...})), // prop getter for jsx next button to traverse the quiz,
|
|
58
|
+
getSkipQuestionButtonProps: () => ({...})), // prop getter for jsx skip button to traverse the quiz,
|
|
57
59
|
getPreviousQuestionButtonProps: () => ({...})), // prop getter for jsx back button to traverse the quiz,
|
|
58
60
|
getOpenTextInputProps: () => ({...})), // prop getter for jsx open text input,
|
|
59
61
|
getSelectInputProps: () => ({...})), // prop getter for jsx select input for select type questions,
|
|
@@ -5,12 +5,14 @@ import useOpenTextInputProps from './useOpenTextInputProps';
|
|
|
5
5
|
import useNextQuestionButtonProps from './useNextQuestionButtonProps';
|
|
6
6
|
import usePreviousQuestionButtonProps from './usePreviousQuestionButtonProps';
|
|
7
7
|
import useAddToFavoritesButtonProps from './useAddToFavoritesButtonProps';
|
|
8
|
+
import useSkipQuestionButtonProps from './useSkipQuestionButtonProps';
|
|
8
9
|
const usePropsGetters = (quizEvents, quizApiState, quizLocalState) => {
|
|
9
|
-
const { quizAnswerChanged, nextQuestion, previousQuestion, resetQuiz, hydrateQuiz, addToCart, addToFavorites, resultClick, } = quizEvents;
|
|
10
|
+
const { quizAnswerChanged, nextQuestion, skipQuestion, previousQuestion, resetQuiz, hydrateQuiz, addToCart, addToFavorites, resultClick, } = quizEvents;
|
|
10
11
|
const getOpenTextInputProps = useOpenTextInputProps(quizAnswerChanged, nextQuestion, quizApiState.quizCurrentQuestion?.next_question, quizLocalState.answerInputs);
|
|
11
12
|
const getCoverQuestionProps = useCoverQuestionProps(quizAnswerChanged, quizApiState.quizCurrentQuestion?.next_question);
|
|
12
13
|
const getSelectInputProps = useSelectInputProps(quizAnswerChanged, nextQuestion, quizApiState.quizCurrentQuestion?.next_question, quizLocalState.answerInputs);
|
|
13
14
|
const getNextQuestionButtonProps = useNextQuestionButtonProps(nextQuestion, quizApiState, quizLocalState);
|
|
15
|
+
const getSkipQuestionButtonProps = useSkipQuestionButtonProps(skipQuestion, quizApiState);
|
|
14
16
|
const getPreviousQuestionButtonProps = usePreviousQuestionButtonProps(quizApiState, previousQuestion);
|
|
15
17
|
const getResetQuizButtonProps = useCallback((stylesType = 'primary') => ({
|
|
16
18
|
className: stylesType === 'primary' ? 'cio-question-cta-button' : 'cio-question-redo-button',
|
|
@@ -70,6 +72,7 @@ const usePropsGetters = (quizEvents, quizApiState, quizLocalState) => {
|
|
|
70
72
|
getAddToFavoritesButtonProps,
|
|
71
73
|
getQuizResultButtonProps,
|
|
72
74
|
getQuizResultLinkProps,
|
|
75
|
+
getSkipQuestionButtonProps,
|
|
73
76
|
};
|
|
74
77
|
};
|
|
75
78
|
export default usePropsGetters;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
export default function useSkipQuestionButtonProps(skipQuestion, quizApiState) {
|
|
3
|
+
const getSkipQuestionButtonProps = useCallback(() => {
|
|
4
|
+
const currentQuestionId = quizApiState.quizCurrentQuestion?.next_question?.id;
|
|
5
|
+
const isHidden = currentQuestionId &&
|
|
6
|
+
(quizApiState.quizCurrentQuestion?.isCoverQuestion ||
|
|
7
|
+
!quizApiState.quizCurrentQuestion?.next_question.is_skippable);
|
|
8
|
+
return {
|
|
9
|
+
className: isHidden ? 'cio-question-skip-button hide' : 'cio-question-skip-button',
|
|
10
|
+
type: 'button',
|
|
11
|
+
onClick: () => {
|
|
12
|
+
skipQuestion();
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
}, [quizApiState.quizCurrentQuestion, skipQuestion]);
|
|
16
|
+
return getSkipQuestionButtonProps;
|
|
17
|
+
}
|
|
@@ -8,6 +8,7 @@ import useQuizResetClick from './useQuizResetClick';
|
|
|
8
8
|
import useHydrateQuizLocalState from './useHydrateQuizLocalState';
|
|
9
9
|
import { resetQuizSessionStorageState } from '../../utils';
|
|
10
10
|
import useQuizAddToFavorites from './useQuizAddToFavorites';
|
|
11
|
+
import useQuizSkipClick from './useQuizSkipClick';
|
|
11
12
|
const useQuizEvents = (quizOptions, cioClient, quizState) => {
|
|
12
13
|
const { quizApiState, dispatchLocalState, dispatchApiState, quizLocalState, quizSessionStorageState, } = quizState;
|
|
13
14
|
const { resultsPageOptions, callbacks } = quizOptions;
|
|
@@ -16,6 +17,7 @@ const useQuizEvents = (quizOptions, cioClient, quizState) => {
|
|
|
16
17
|
const quizAnswerChanged = useQuizAnswerChangeHandler(quizApiState, dispatchLocalState);
|
|
17
18
|
// Quiz Next button click callback
|
|
18
19
|
const nextQuestion = useQuizNextClick(quizApiState, quizLocalState, dispatchLocalState, callbacks?.onQuizNextQuestion);
|
|
20
|
+
const skipQuestion = useQuizSkipClick(quizApiState, quizLocalState, dispatchLocalState, callbacks?.onQuizSkipQuestion);
|
|
19
21
|
// Quiz Back button click callback
|
|
20
22
|
const previousQuestion = useQuizBackClick(quizApiState, dispatchLocalState);
|
|
21
23
|
// Quiz result add to cart callback
|
|
@@ -36,6 +38,7 @@ const useQuizEvents = (quizOptions, cioClient, quizState) => {
|
|
|
36
38
|
quizAnswerChanged,
|
|
37
39
|
previousQuestion,
|
|
38
40
|
nextQuestion,
|
|
41
|
+
skipQuestion,
|
|
39
42
|
resetQuiz,
|
|
40
43
|
hydrateQuiz: hydrateQuizLocalState,
|
|
41
44
|
resetSessionStorageState: resetQuizSessionStorageState(quizSessionStorageState.key),
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { QuestionTypes } from '../../components/CioQuiz/actions';
|
|
3
|
+
import { isFunction } from '../../utils';
|
|
4
|
+
const useQuizSkipClick = (quizApiState, quizLocalState, dispatchLocalState, onQuizSkipQuestion) => {
|
|
5
|
+
const quizSkipClickHandler = useCallback(() => {
|
|
6
|
+
const currentQuestion = quizApiState.quizCurrentQuestion?.next_question;
|
|
7
|
+
const currentQuestionId = currentQuestion?.id;
|
|
8
|
+
if (dispatchLocalState && currentQuestionId) {
|
|
9
|
+
if (!(currentQuestion?.type === 'cover')) {
|
|
10
|
+
dispatchLocalState({
|
|
11
|
+
type: QuestionTypes.Skip,
|
|
12
|
+
payload: quizApiState.quizCurrentQuestion,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
const currentAnswerInput = {
|
|
16
|
+
...quizLocalState.answerInputs[currentQuestionId],
|
|
17
|
+
value: currentQuestion?.type === 'open' ? 'false' : null,
|
|
18
|
+
};
|
|
19
|
+
if (currentQuestion && isFunction(onQuizSkipQuestion)) {
|
|
20
|
+
onQuizSkipQuestion({ ...currentQuestion, answer: currentAnswerInput });
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}, [
|
|
24
|
+
dispatchLocalState,
|
|
25
|
+
onQuizSkipQuestion,
|
|
26
|
+
quizApiState.quizCurrentQuestion,
|
|
27
|
+
quizLocalState.answerInputs,
|
|
28
|
+
]);
|
|
29
|
+
return quizSkipClickHandler;
|
|
30
|
+
};
|
|
31
|
+
export default useQuizSkipClick;
|
|
@@ -176,6 +176,10 @@ export const useMockContextValue = (question) => {
|
|
|
176
176
|
...mockElementProps,
|
|
177
177
|
className: 'cio-question-cta-button',
|
|
178
178
|
}),
|
|
179
|
+
getSkipQuestionButtonProps: () => ({
|
|
180
|
+
...mockElementProps,
|
|
181
|
+
className: 'cio-question-skip-button',
|
|
182
|
+
}),
|
|
179
183
|
getPreviousQuestionButtonProps: () => ({
|
|
180
184
|
...mockElementProps,
|
|
181
185
|
className: 'cio-question-back-button',
|
package/lib/mjs/src/utils.js
CHANGED
|
@@ -42,6 +42,7 @@ export const functionStrings = {
|
|
|
42
42
|
onAddToFavoritesClick: `(item) => console.dir(item)`,
|
|
43
43
|
onQuizResultsLoaded: `(results) => console.dir(results)`,
|
|
44
44
|
onQuizNextQuestion: `(question) => console.dir(question)`,
|
|
45
|
+
onQuizSkipQuestion: `(question) => console.dir(question)`,
|
|
45
46
|
cioJsClient: `cioJsClient`,
|
|
46
47
|
};
|
|
47
48
|
export const stringifyWithDefaults = (obj) => {
|
package/lib/styles.css
CHANGED
|
@@ -215,6 +215,14 @@
|
|
|
215
215
|
background-color: rgba(255, 255, 255, 0.87);
|
|
216
216
|
align-items: center;
|
|
217
217
|
}
|
|
218
|
+
.cio-quiz .cio-question-buttons-group {
|
|
219
|
+
width: 20rem;
|
|
220
|
+
height: var(--bottom-bar-height);
|
|
221
|
+
padding: 8px 16px;
|
|
222
|
+
display: flex;
|
|
223
|
+
align-items: center;
|
|
224
|
+
margin-left: auto;
|
|
225
|
+
}
|
|
218
226
|
.cio-quiz .cio-question-cta-button {
|
|
219
227
|
background: var(--primary-color);
|
|
220
228
|
color: #ffffff;
|
|
@@ -250,7 +258,27 @@
|
|
|
250
258
|
cursor: auto;
|
|
251
259
|
outline: none;
|
|
252
260
|
}
|
|
253
|
-
|
|
261
|
+
.cio-quiz .cio-question-skip-button {
|
|
262
|
+
background: transparent;
|
|
263
|
+
color: var(--gray-dust-500);
|
|
264
|
+
border: none;
|
|
265
|
+
cursor: pointer;
|
|
266
|
+
padding: 0;
|
|
267
|
+
outline: none;
|
|
268
|
+
font-size: 1rem;
|
|
269
|
+
width: 100%;
|
|
270
|
+
text-decoration: underline;
|
|
271
|
+
text-decoration-color: transparent;
|
|
272
|
+
transition: text-decoration-color 0.2s ease-in-out;
|
|
273
|
+
}
|
|
274
|
+
.cio-quiz .cio-question-skip-button:hover,
|
|
275
|
+
.cio-quiz .cio-question-skip-button:focus {
|
|
276
|
+
text-decoration-color: var(--gray-dust-200);
|
|
277
|
+
}
|
|
278
|
+
.cio-quiz .cio-question-skip-button.hide {
|
|
279
|
+
visibility: hidden;
|
|
280
|
+
pointer-events: none;
|
|
281
|
+
}
|
|
254
282
|
/* Back Button Component */
|
|
255
283
|
.cio-quiz .cio-question-back-button {
|
|
256
284
|
color: var(--primary-color);
|
|
@@ -639,6 +667,12 @@
|
|
|
639
667
|
|
|
640
668
|
/* Container Queries */
|
|
641
669
|
|
|
670
|
+
@container quiz (max-width: 640px) {
|
|
671
|
+
.cio-quiz .cio-question-skip-button span {
|
|
672
|
+
display: none;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
642
676
|
/* Small Tablet */
|
|
643
677
|
@container quiz (min-width: 640px) {
|
|
644
678
|
.cio-quiz .cio-container {
|
|
@@ -6,6 +6,7 @@ export declare enum QuestionTypes {
|
|
|
6
6
|
SingleSelect = "single",
|
|
7
7
|
MultipleSelect = "multiple",
|
|
8
8
|
Next = "next",
|
|
9
|
+
Skip = "skip",
|
|
9
10
|
Back = "back",
|
|
10
11
|
Reset = "reset",
|
|
11
12
|
Hydrate = "hydrate",
|
|
@@ -24,7 +25,7 @@ interface Action<Type, Payload = {}> {
|
|
|
24
25
|
payload?: Payload;
|
|
25
26
|
}
|
|
26
27
|
export type ActionAnswerInputQuestion = Action<QuestionTypes.OpenText, OpenTextQuestionPayload> | Action<QuestionTypes.SingleSelect, SelectQuestionPayload> | Action<QuestionTypes.MultipleSelect, SelectQuestionPayload> | Action<QuestionTypes.Cover, CoverQuestionPayload>;
|
|
27
|
-
export type ActionAnswerQuestion = ActionAnswerInputQuestion | Action<QuestionTypes.Next, CurrentQuestion> | Action<QuestionTypes.Back, CurrentQuestion> | Action<QuestionTypes.Reset> | Action<QuestionTypes.Complete> | Action<QuestionTypes.Hydrate, Partial<QuizLocalReducerState>>;
|
|
28
|
+
export type ActionAnswerQuestion = ActionAnswerInputQuestion | Action<QuestionTypes.Next, CurrentQuestion> | Action<QuestionTypes.Skip, CurrentQuestion> | Action<QuestionTypes.Back, CurrentQuestion> | Action<QuestionTypes.Reset> | Action<QuestionTypes.Complete> | Action<QuestionTypes.Hydrate, Partial<QuizLocalReducerState>>;
|
|
28
29
|
export declare enum QuizAPIActionTypes {
|
|
29
30
|
SET_IS_LOADING = 0,
|
|
30
31
|
SET_IS_ERROR = 1,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import ConstructorIOClient from '@constructor-io/constructorio-client-javascript';
|
|
3
|
-
import { GetAddToCartButtonProps, GetAddToFavoritesButtonProps, GetCoverQuestionProps, GetHydrateQuizButtonProps, GetNextQuestionButtonProps, GetOpenTextInputProps, GetPreviousQuestionButtonProps, GetQuizImageProps, GetQuizResultButtonProps, GetQuizResultLinkProps, GetResetQuizButtonProps, GetSelectInputProps, PrimaryColorStyles, QuizReturnState } from '../../types';
|
|
3
|
+
import { GetAddToCartButtonProps, GetAddToFavoritesButtonProps, GetCoverQuestionProps, GetHydrateQuizButtonProps, GetNextQuestionButtonProps, GetSkipQuestionButtonProps, GetOpenTextInputProps, GetPreviousQuestionButtonProps, GetQuizImageProps, GetQuizResultButtonProps, GetQuizResultLinkProps, GetResetQuizButtonProps, GetSelectInputProps, PrimaryColorStyles, QuizReturnState } from '../../types';
|
|
4
4
|
export interface QuizContextValue {
|
|
5
5
|
cioClient?: ConstructorIOClient;
|
|
6
6
|
state?: QuizReturnState;
|
|
7
7
|
getOpenTextInputProps: GetOpenTextInputProps;
|
|
8
8
|
getNextQuestionButtonProps: GetNextQuestionButtonProps;
|
|
9
|
+
getSkipQuestionButtonProps: GetSkipQuestionButtonProps;
|
|
9
10
|
getPreviousQuestionButtonProps: GetPreviousQuestionButtonProps;
|
|
10
11
|
getQuizImageProps: GetQuizImageProps;
|
|
11
12
|
getSelectInputProps: GetSelectInputProps;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface SkipButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
3
|
+
propsGetters?: () => React.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
4
|
+
}
|
|
5
|
+
declare function SkipButton(props: SkipButtonProps): JSX.Element;
|
|
6
|
+
export default SkipButton;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export declare const apiKey = "key_wJSdZSiesX5hiVLt";
|
|
2
2
|
export declare const quizId = "coffee-quiz";
|
|
3
3
|
export declare const quizSessionStateKey = "constructorIOQuizState";
|
|
4
|
-
export declare const componentDescription = "- import `CioQuiz` to render in your JSX.\n- This component handles state management, data fetching, and rendering logic.\n- To use this component, `quizId`, `resultsPageOptions`, and one of `apiKey` or `cioJsClient` are required.\n- `resultsPageOptions` lets you configure the results page\n - `onAddToCartClick` is a callback function that will be called when the \"Add to cart\" button is clicked\n - `onAddToFavoritesClick` is an optional callback function that will be called when the \"Add To Favorites\" heart icon is clicked\n - `onQuizResultClick` is an optional callback function that will be called when the result card is clicked. The default behavior is redirecting the user to the item's URL\n - `onQuizResultsLoaded` is an optional callback function that will be called when the quiz results are loaded\n - `resultCardRegularPriceKey` is a parameter that specifies the metadata field name for the regular price\n - `resultCardSalePriceKey` is an optional parameter that specifies the metadata field name for the sale price \n - `resultCardRatingCountKey` is an optional parameter that specifies the metadata field name for the ratings count \n - `resultCardRatingScoreKey` is an optional parameter that specifies the metadata field name for the ratings score \n - `renderResultCardPriceDetails` is an optional render function to render custom prices section in result card \n - `numResultsToDisplay` is an optional parameter that determines how many results should be displayed on results page\n- `callbacks` lets you pass callback functions that will be called on certain actions\n - `onQuizNextQuestion` is an optional callback function that will be called when user moves to the next question\n- `sessionStateOptions` lets you configure the session modal behavior\n - `showSessionModal` is a boolean used to decide whether to show the session modal. The default behavior is to show the session modal\n - `showSessionModalOnResults` is a boolean to decide whether to show the session modal after reaching the results page. The default behavior is to not show the session modal\n - `sessionStateKey` is a custom string that will be used as a session storage key\n- Use different props to configure the behavior of this component.\n- The following stories show how different props affect the component's behavior\n\n> Note: `cioJsClient` refers to an instance of the [constructorio-client-javascript](https://www.npmjs.com/package/@constructor-io/constructorio-client-javascript)\n";
|
|
5
|
-
export declare const hookDescription = "- import `useCioQuiz` and call this custom hook in a functional component.\n- This hook leaves rendering logic up to you, while handling:\n - state management\n - data fetching\n - keyboard navigation\n - mouse interactions\n - focus and submit event handling\n- Since the markup is controlled by you, the default styles might not be applied if you have a different DOM structure\n- To use this hook, an `apiKey` and `quizId` are required, and `resultsPageOptions` must be passed to the `useCioQuiz` hook to configure behavior. All other values are optional.\n- use the <a href=\"https://kentcdodds.com/blog/how-to-give-rendering-control-to-users-with-prop-getters\" target=\"__blank\">prop getters</a> and other variables returned by this hook (below) to leverage the functionality described above with jsx elements in your react component definitions\n\nCalling the `useCioQuiz` hook returns an object with the following keys:\n\n```jsx\nconst {\n // must be used for a hooks integrations\n state: QuizReturnState, // Quiz state\n events: [{...}], // array of quiz events\n getAddToCartButtonProps: () => ({...})), // prop getter for jsx add to cart button for quiz result,\n getAddToFavoritesButtonProps: () => ({...})), // prop getter for jsx add to favorites button for quiz result,\n getCoverQuestionProps: () => ({...})), // prop getter for jsx quiz cover question,\n getHydrateQuizButtonProps: () => ({...})), // prop getter for jsx hydrate quiz button,\n getNextQuestionButtonProps: () => ({...})), // prop getter for jsx next button to traverse the quiz,\n getPreviousQuestionButtonProps: () => ({...})), // prop getter for jsx back button to traverse the quiz, \n getOpenTextInputProps: () => ({...})), // prop getter for jsx open text input,\n getSelectInputProps: () => ({...})), // prop getter for jsx select input for select type questions,\n getQuizImageProps: () => ({...})), // prop getter for jsx quiz image,\n getQuizResultButtonProps: () => ({...})), // prop getter for jsx result card click as a button,\n getQuizResultLinkProps: () => ({...})), // prop getter for jsx result card click as a link. Should be spread into <a> tags,\n getResetQuizButtonProps: () => ({...})), // prop getter for jsx reset quiz button,\n cioClient, // instance of constructorio-client-javascript\n } = useCioQuiz(args);\n```\n\n> Note: when we say `cioClient`, we are referring to an instance of the [constructorio-client-javascript](https://www.npmjs.com/package/@constructor-io/constructorio-client-javascript)\n";
|
|
4
|
+
export declare const componentDescription = "- import `CioQuiz` to render in your JSX.\n- This component handles state management, data fetching, and rendering logic.\n- To use this component, `quizId`, `resultsPageOptions`, and one of `apiKey` or `cioJsClient` are required.\n- `resultsPageOptions` lets you configure the results page\n - `onAddToCartClick` is a callback function that will be called when the \"Add to cart\" button is clicked\n - `onAddToFavoritesClick` is an optional callback function that will be called when the \"Add To Favorites\" heart icon is clicked\n - `onQuizResultClick` is an optional callback function that will be called when the result card is clicked. The default behavior is redirecting the user to the item's URL\n - `onQuizResultsLoaded` is an optional callback function that will be called when the quiz results are loaded\n - `resultCardRegularPriceKey` is a parameter that specifies the metadata field name for the regular price\n - `resultCardSalePriceKey` is an optional parameter that specifies the metadata field name for the sale price \n - `resultCardRatingCountKey` is an optional parameter that specifies the metadata field name for the ratings count \n - `resultCardRatingScoreKey` is an optional parameter that specifies the metadata field name for the ratings score \n - `renderResultCardPriceDetails` is an optional render function to render custom prices section in result card \n - `numResultsToDisplay` is an optional parameter that determines how many results should be displayed on results page\n- `callbacks` lets you pass callback functions that will be called on certain actions\n - `onQuizNextQuestion` is an optional callback function that will be called when user moves to the next question\n - `onQuizSkipQuestion` is an optional callback function that will be called when user skips a question\n- `sessionStateOptions` lets you configure the session modal behavior\n - `showSessionModal` is a boolean used to decide whether to show the session modal. The default behavior is to show the session modal\n - `showSessionModalOnResults` is a boolean to decide whether to show the session modal after reaching the results page. The default behavior is to not show the session modal\n - `sessionStateKey` is a custom string that will be used as a session storage key\n- Use different props to configure the behavior of this component.\n- The following stories show how different props affect the component's behavior\n\n> Note: `cioJsClient` refers to an instance of the [constructorio-client-javascript](https://www.npmjs.com/package/@constructor-io/constructorio-client-javascript)\n";
|
|
5
|
+
export declare const hookDescription = "- import `useCioQuiz` and call this custom hook in a functional component.\n- This hook leaves rendering logic up to you, while handling:\n - state management\n - data fetching\n - keyboard navigation\n - mouse interactions\n - focus and submit event handling\n- Since the markup is controlled by you, the default styles might not be applied if you have a different DOM structure\n- To use this hook, an `apiKey` and `quizId` are required, and `resultsPageOptions` must be passed to the `useCioQuiz` hook to configure behavior. All other values are optional.\n- use the <a href=\"https://kentcdodds.com/blog/how-to-give-rendering-control-to-users-with-prop-getters\" target=\"__blank\">prop getters</a> and other variables returned by this hook (below) to leverage the functionality described above with jsx elements in your react component definitions\n\nCalling the `useCioQuiz` hook returns an object with the following keys:\n\n```jsx\nconst {\n // must be used for a hooks integrations\n state: QuizReturnState, // Quiz state\n events: [{...}], // array of quiz events\n getAddToCartButtonProps: () => ({...})), // prop getter for jsx add to cart button for quiz result,\n getAddToFavoritesButtonProps: () => ({...})), // prop getter for jsx add to favorites button for quiz result,\n getCoverQuestionProps: () => ({...})), // prop getter for jsx quiz cover question,\n getHydrateQuizButtonProps: () => ({...})), // prop getter for jsx hydrate quiz button,\n getNextQuestionButtonProps: () => ({...})), // prop getter for jsx next button to traverse the quiz,\n getSkipQuestionButtonProps: () => ({...})), // prop getter for jsx skip button to traverse the quiz,\n getPreviousQuestionButtonProps: () => ({...})), // prop getter for jsx back button to traverse the quiz, \n getOpenTextInputProps: () => ({...})), // prop getter for jsx open text input,\n getSelectInputProps: () => ({...})), // prop getter for jsx select input for select type questions,\n getQuizImageProps: () => ({...})), // prop getter for jsx quiz image,\n getQuizResultButtonProps: () => ({...})), // prop getter for jsx result card click as a button,\n getQuizResultLinkProps: () => ({...})), // prop getter for jsx result card click as a link. Should be spread into <a> tags,\n getResetQuizButtonProps: () => ({...})), // prop getter for jsx reset quiz button,\n cioClient, // instance of constructorio-client-javascript\n } = useCioQuiz(args);\n```\n\n> Note: when we say `cioClient`, we are referring to an instance of the [constructorio-client-javascript](https://www.npmjs.com/package/@constructor-io/constructorio-client-javascript)\n";
|
|
6
6
|
export declare const basicDescription = "Pass an `apiKey` and a `quizId` to request questions and quiz results from Constructor's servers";
|
|
7
7
|
export declare const cioJsClientDescription = "If you are already using an instance of the `ConstructorIOClient`, you can pass a `cioJsClient` instead of an `apiKey` to request results from Constructor's servers\n\n> Note: `cioJsClient` refers to an instance of the [constructorio-client-javascript](https://www.npmjs.com/package/@constructor-io/constructorio-client-javascript)";
|
|
8
8
|
export declare const smallContainerDescription = "If you are using the provided styles, CioQuiz component will respect the height and width of its parent container and use responsive styles based on the parent container's dimensions";
|