@constructor-io/constructorio-ui-quizzes 1.18.0 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/constructorio-ui-quizzes-bundled.js +21 -21
  2. package/lib/cjs/components/CioQuiz/actions.js +5 -3
  3. package/lib/cjs/components/CioQuiz/index.js +2 -1
  4. package/lib/cjs/components/CioQuiz/quizApiReducer.js +3 -0
  5. package/lib/cjs/components/CioQuiz/quizLocalReducer.js +23 -12
  6. package/lib/cjs/hooks/usePropsGetters/index.js +6 -3
  7. package/lib/cjs/hooks/usePropsGetters/useJumpToQuestionButtonProps.js +34 -0
  8. package/lib/cjs/hooks/usePropsGetters/useSelectInputProps.js +3 -2
  9. package/lib/cjs/hooks/useQuiz.js +7 -1
  10. package/lib/cjs/hooks/useQuizEvents/index.js +7 -0
  11. package/lib/cjs/hooks/useQuizEvents/useJumpToQuestion.js +25 -0
  12. package/lib/cjs/hooks/useQuizState/useQuizApiState.js +1 -1
  13. package/lib/cjs/hooks/useQuizState/useSessionStorageState.js +2 -1
  14. package/lib/cjs/version.js +1 -1
  15. package/lib/mjs/components/CioQuiz/actions.js +5 -3
  16. package/lib/mjs/components/CioQuiz/index.js +2 -1
  17. package/lib/mjs/components/CioQuiz/quizApiReducer.js +8 -0
  18. package/lib/mjs/components/CioQuiz/quizLocalReducer.js +35 -39
  19. package/lib/mjs/hooks/usePropsGetters/index.js +6 -3
  20. package/lib/mjs/hooks/usePropsGetters/useJumpToQuestionButtonProps.js +29 -0
  21. package/lib/mjs/hooks/usePropsGetters/useSelectInputProps.js +3 -2
  22. package/lib/mjs/hooks/useQuiz.js +7 -1
  23. package/lib/mjs/hooks/useQuizEvents/index.js +7 -0
  24. package/lib/mjs/hooks/useQuizEvents/useJumpToQuestion.js +21 -0
  25. package/lib/mjs/hooks/useQuizState/useQuizApiState.js +1 -1
  26. package/lib/mjs/hooks/useQuizState/useSessionStorageState.js +3 -2
  27. package/lib/mjs/version.js +1 -1
  28. package/lib/types/components/CioQuiz/actions.d.ts +13 -6
  29. package/lib/types/components/CioQuiz/context.d.ts +2 -1
  30. package/lib/types/hooks/usePropsGetters/index.d.ts +9 -2
  31. package/lib/types/hooks/usePropsGetters/useJumpToQuestionButtonProps.d.ts +4 -0
  32. package/lib/types/hooks/usePropsGetters/useSelectInputProps.d.ts +1 -1
  33. package/lib/types/hooks/useQuizEvents/useJumpToQuestion.d.ts +11 -0
  34. package/lib/types/hooks/useQuizEvents/useQuizResetClick.d.ts +1 -1
  35. package/lib/types/types.d.ts +10 -0
  36. package/lib/types/version.d.ts +1 -1
  37. package/package.json +2 -2
@@ -1,8 +1,9 @@
1
- import { useEffect } from 'react';
1
+ import { useEffect, useState } from 'react';
2
2
  import { getStateFromSessionStorage } from '../../utils';
3
3
  import { quizSessionStateKey } from '../../constants';
4
4
  const useSessionStorageState = (quizId, quizLocalState, sessionStateOptions, enableHydration) => {
5
5
  const quizSessionStorageStateKey = sessionStateOptions?.sessionStateKey || quizSessionStateKey;
6
+ const [quizData, setQuizData] = useState(getStateFromSessionStorage(quizSessionStorageStateKey));
6
7
  // Save state to session storage
7
8
  useEffect(() => {
8
9
  // don't save state if initial state
@@ -13,9 +14,9 @@ const useSessionStorageState = (quizId, quizLocalState, sessionStateOptions, ena
13
14
  [quizId]: quizLocalState,
14
15
  };
15
16
  window?.sessionStorage?.setItem(quizSessionStorageStateKey, JSON.stringify(dataToSave));
17
+ setQuizData(data);
16
18
  }
17
19
  }, [quizLocalState, quizSessionStorageStateKey, enableHydration, quizId]);
18
- const quizData = getStateFromSessionStorage(quizSessionStorageStateKey);
19
20
  const skipToResults = !!enableHydration &&
20
21
  !!quizData?.[quizId]?.isQuizCompleted &&
21
22
  !sessionStateOptions?.showSessionModalOnResults;
@@ -1 +1 @@
1
- export default '1.18.0';
1
+ export default '1.19.0';
@@ -12,7 +12,8 @@ export declare enum QuestionTypes {
12
12
  Back = "back",
13
13
  Reset = "reset",
14
14
  Hydrate = "hydrate",
15
- Complete = "complete"
15
+ Complete = "complete",
16
+ JumpToQuestion = "jump_to_question"
16
17
  }
17
18
  export interface QuestionAnswer<Value> {
18
19
  questionId: number;
@@ -26,16 +27,19 @@ interface Action<Type, Payload = {}> {
26
27
  payload?: Payload;
27
28
  }
28
29
  export type ActionAnswerInputQuestion = Action<QuestionTypes.OpenText, OpenTextQuestionPayload> | Action<QuestionTypes.SingleSelect, SelectQuestionPayload> | Action<QuestionTypes.MultipleSelect, SelectQuestionPayload> | Action<QuestionTypes.SingleFilterValue, SelectQuestionPayload> | Action<QuestionTypes.MultipleFilterValues, SelectQuestionPayload> | Action<QuestionTypes.Cover, CoverQuestionPayload>;
29
- 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>>;
30
+ export type ActionAnswerQuestion = ActionAnswerInputQuestion | Action<QuestionTypes.Next, CurrentQuestion> | Action<QuestionTypes.Skip, CurrentQuestion> | Action<QuestionTypes.Back, CurrentQuestion> | Action<QuestionTypes.Reset> | Action<QuestionTypes.Complete> | Action<QuestionTypes.JumpToQuestion, {
31
+ questionId: number;
32
+ }> | Action<QuestionTypes.Hydrate, Partial<QuizLocalReducerState>>;
30
33
  export declare enum QuizAPIActionTypes {
31
34
  SET_IS_LOADING = 0,
32
35
  SET_IS_ERROR = 1,
33
36
  SET_QUIZ_RESULTS = 2,
34
37
  SET_CURRENT_QUESTION = 3,
35
38
  RESET_QUIZ = 4,
36
- SET_QUIZ_SHARED_RESULTS = 5,
37
- SET_QUIZ_RESULTS_CONFIG = 6,
38
- SET_QUIZ_RESULTS_CONFIG_ERROR = 7
39
+ JUMP_TO_QUESTION = 5,
40
+ SET_QUIZ_SHARED_RESULTS = 6,
41
+ SET_QUIZ_RESULTS_CONFIG = 7,
42
+ SET_QUIZ_RESULTS_CONFIG_ERROR = 8
39
43
  }
40
44
  export type ActionSetIsLoading = Action<QuizAPIActionTypes.SET_IS_LOADING>;
41
45
  export type ActionSetIsError = Action<QuizAPIActionTypes.SET_IS_ERROR>;
@@ -50,9 +54,12 @@ export type ActionSetCurrentQuestion = Action<QuizAPIActionTypes.SET_CURRENT_QUE
50
54
  quizSessionId?: string;
51
55
  quizVersionId?: string;
52
56
  }>;
57
+ export type ActionJumpToQuestion = Action<QuizAPIActionTypes.JUMP_TO_QUESTION, {
58
+ questionId: number;
59
+ }>;
53
60
  export type ActionResetQuiz = Action<QuizAPIActionTypes.RESET_QUIZ>;
54
61
  export type ActionSetQuizResultsConfig = Action<QuizAPIActionTypes.SET_QUIZ_RESULTS_CONFIG, {
55
62
  quizResultsConfig: QuizResultsConfigResponse;
56
63
  }> | Action<QuizAPIActionTypes.SET_QUIZ_RESULTS_CONFIG_ERROR>;
57
- export type ActionQuizAPI = ActionSetIsLoading | ActionSetIsError | ActionSetQuizResults | ActionSetCurrentQuestion | ActionResetQuiz | ActionSetQuizSharedResults | ActionSetQuizResultsConfig;
64
+ export type ActionQuizAPI = ActionSetIsLoading | ActionSetIsError | ActionSetQuizResults | ActionSetCurrentQuestion | ActionResetQuiz | ActionSetQuizSharedResults | ActionSetQuizResultsConfig | ActionJumpToQuestion;
58
65
  export {};
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import ConstructorIOClient from '@constructor-io/constructorio-client-javascript';
3
- import { GetAddToCartButtonProps, GetAddToFavoritesButtonProps, GetCoverQuestionProps, GetHydrateQuizButtonProps, GetNextQuestionButtonProps, GetSkipQuestionButtonProps, GetOpenTextInputProps, GetPreviousQuestionButtonProps, GetQuizImageProps, GetQuizResultButtonProps, GetQuizResultLinkProps, GetResetQuizButtonProps, GetSelectInputProps, PrimaryColorStyles, QuizReturnState, GetShareResultsButtonProps } from '../../types';
3
+ import { GetAddToCartButtonProps, GetAddToFavoritesButtonProps, GetCoverQuestionProps, GetHydrateQuizButtonProps, GetNextQuestionButtonProps, GetSkipQuestionButtonProps, GetOpenTextInputProps, GetPreviousQuestionButtonProps, GetQuizImageProps, GetQuizResultButtonProps, GetQuizResultLinkProps, GetResetQuizButtonProps, GetSelectInputProps, PrimaryColorStyles, QuizReturnState, GetShareResultsButtonProps, GetJumpToQuestionButtonProps } from '../../types';
4
4
  export interface QuizContextValue {
5
5
  cioClient?: ConstructorIOClient;
6
6
  state?: QuizReturnState;
@@ -18,6 +18,7 @@ export interface QuizContextValue {
18
18
  getAddToFavoritesButtonProps: GetAddToFavoritesButtonProps;
19
19
  getQuizResultButtonProps: GetQuizResultButtonProps;
20
20
  getQuizResultLinkProps: GetQuizResultLinkProps;
21
+ getJumpToQuestionButtonProps: GetJumpToQuestionButtonProps;
21
22
  primaryColorStyles: PrimaryColorStyles;
22
23
  customClickItemCallback: boolean;
23
24
  customAddToFavoritesCallback: boolean;
@@ -1,7 +1,13 @@
1
- import { GetResetQuizButtonProps, GetCoverQuestionProps, GetNextQuestionButtonProps, GetOpenTextInputProps, GetPreviousQuestionButtonProps, GetQuizImageProps, GetSelectInputProps, QuizEventsReturn, GetHydrateQuizButtonProps, GetAddToCartButtonProps, GetQuizResultButtonProps, GetQuizResultLinkProps, GetSelectQuestionImageProps, GetAddToFavoritesButtonProps, GetSkipQuestionButtonProps, GetShareResultsButtonProps } from '../../types';
1
+ import { GetResetQuizButtonProps, GetCoverQuestionProps, GetNextQuestionButtonProps, GetOpenTextInputProps, GetPreviousQuestionButtonProps, GetQuizImageProps, GetSelectInputProps, QuizEventsReturn, GetHydrateQuizButtonProps, GetAddToCartButtonProps, GetQuizResultButtonProps, GetQuizResultLinkProps, GetSelectQuestionImageProps, GetAddToFavoritesButtonProps, GetSkipQuestionButtonProps, GetShareResultsButtonProps, GetJumpToQuestionButtonProps, QuestionsPageOptions } from '../../types';
2
2
  import { QuizAPIReducerState } from '../../components/CioQuiz/quizApiReducer';
3
3
  import { QuizLocalReducerState } from '../../components/CioQuiz/quizLocalReducer';
4
- declare const usePropsGetters: (quizEvents: QuizEventsReturn, quizApiState: QuizAPIReducerState, quizLocalState: QuizLocalReducerState, favoriteItems?: string[]) => {
4
+ declare const usePropsGetters: ({ questionsPageOptions, favoriteItems, quizEvents, quizApiState, quizLocalState, }: {
5
+ quizEvents: QuizEventsReturn;
6
+ quizApiState: QuizAPIReducerState;
7
+ quizLocalState: QuizLocalReducerState;
8
+ favoriteItems?: string[] | undefined;
9
+ questionsPageOptions?: QuestionsPageOptions | undefined;
10
+ }) => {
5
11
  getOpenTextInputProps: GetOpenTextInputProps;
6
12
  getNextQuestionButtonProps: GetNextQuestionButtonProps;
7
13
  getPreviousQuestionButtonProps: GetPreviousQuestionButtonProps;
@@ -17,5 +23,6 @@ declare const usePropsGetters: (quizEvents: QuizEventsReturn, quizApiState: Quiz
17
23
  getQuizResultButtonProps: GetQuizResultButtonProps;
18
24
  getQuizResultLinkProps: GetQuizResultLinkProps;
19
25
  getSkipQuestionButtonProps: GetSkipQuestionButtonProps;
26
+ getJumpToQuestionButtonProps: GetJumpToQuestionButtonProps;
20
27
  };
21
28
  export default usePropsGetters;
@@ -0,0 +1,4 @@
1
+ import { QuizAPIReducerState } from '../../components/CioQuiz/quizApiReducer';
2
+ import { GetJumpToQuestionButtonProps, QuizEventsReturn } from '../../types';
3
+ import { QuizLocalReducerState } from '../../components/CioQuiz/quizLocalReducer';
4
+ export default function useJumpToQuestionButtonProps(jumpToQuestion: QuizEventsReturn.JumpToQuestion, quizApiState: QuizAPIReducerState, quizLocalState: QuizLocalReducerState): GetJumpToQuestionButtonProps;
@@ -1,3 +1,3 @@
1
1
  import { Nullable } from '@constructor-io/constructorio-client-javascript/lib/types';
2
2
  import { AnswerInputState, GetSelectInputProps, Question, QuizEventsReturn } from '../../types';
3
- export default function useSelectInputProps(quizAnswerChanged: QuizEventsReturn.QuizAnswerChanged, nextQuestion: QuizEventsReturn.NextQuestion, currentQuestionData?: Nullable<Question>, answerInputs?: AnswerInputState): GetSelectInputProps;
3
+ export default function useSelectInputProps(quizAnswerChanged: QuizEventsReturn.QuizAnswerChanged, nextQuestion: QuizEventsReturn.NextQuestion, currentQuestionData?: Nullable<Question>, answerInputs?: AnswerInputState, nextQuestionOnSingleSelect?: boolean): GetSelectInputProps;
@@ -0,0 +1,11 @@
1
+ /// <reference types="react" />
2
+ import { ActionAnswerQuestion, ActionQuizAPI } from '../../components/CioQuiz/actions';
3
+ import { QuizEventsReturn } from '../../types';
4
+ import { QuizAPIReducerState } from '../../components/CioQuiz/quizApiReducer';
5
+ type IUseJumpToQuestionProps = {
6
+ dispatchLocalState: React.Dispatch<ActionAnswerQuestion>;
7
+ dispatchApiState: React.Dispatch<ActionQuizAPI>;
8
+ quizApiState: QuizAPIReducerState;
9
+ };
10
+ declare const useJumpToQuestion: (props: IUseJumpToQuestionProps) => QuizEventsReturn.JumpToQuestion;
11
+ export default useJumpToQuestion;
@@ -7,5 +7,5 @@ type IUseQuizResetClickProps = {
7
7
  dispatchApiState: React.Dispatch<ActionQuizAPI>;
8
8
  quizResults?: QuizResultsResponse | QuizSharedResultsData;
9
9
  };
10
- declare const useQuizResetClick: (props: IUseQuizResetClickProps) => QuizEventsReturn.NextQuestion;
10
+ declare const useQuizResetClick: (props: IUseQuizResetClickProps) => QuizEventsReturn.ResetQuiz;
11
11
  export default useQuizResetClick;
@@ -46,6 +46,7 @@ export interface ResultsPageOptions {
46
46
  }
47
47
  export interface QuestionsPageOptions {
48
48
  skipQuestionButtonText?: string;
49
+ nextQuestionOnSingleSelect?: boolean;
49
50
  }
50
51
  export interface SessionStateOptions {
51
52
  showSessionModal?: boolean;
@@ -126,6 +127,7 @@ export declare namespace QuizEventsReturn {
126
127
  type SkipQuestion = () => void;
127
128
  type PreviousQuestion = () => void;
128
129
  type ResetQuiz = () => void;
130
+ type JumpToQuestion = (questionId: number) => void;
129
131
  type ResultClick = (result: QuizResultDataPartial, position: number) => void;
130
132
  type AddToCart = (e: React.MouseEvent<HTMLElement>, result: QuizResultDataPartial, price?: number | string) => void;
131
133
  type AddToFavorites = (e: React.MouseEvent<HTMLElement>, result: QuizResultDataPartial, price?: number | string, sendEvent?: boolean) => void;
@@ -135,6 +137,7 @@ export declare namespace QuizEventsReturn {
135
137
  export interface QuizEventsReturn {
136
138
  nextQuestion: QuizEventsReturn.NextQuestion;
137
139
  skipQuestion: QuizEventsReturn.SkipQuestion;
140
+ jumpToQuestion: QuizEventsReturn.JumpToQuestion;
138
141
  quizAnswerChanged: QuizEventsReturn.QuizAnswerChanged;
139
142
  previousQuestion: QuizEventsReturn.PreviousQuestion;
140
143
  resetQuiz: QuizEventsReturn.ResetQuiz;
@@ -225,12 +228,18 @@ export interface SelectInputProps {
225
228
  tabIndex: number;
226
229
  key: number | string;
227
230
  }
231
+ export interface JumpToQuestionButtonProps {
232
+ className: string;
233
+ onClick: React.MouseEventHandler<HTMLElement>;
234
+ style?: Record<string, string>;
235
+ }
228
236
  export type GetOpenTextInputProps = () => OpenTextInputProps;
229
237
  export type GetCoverQuestionProps = () => CoverQuestionProps;
230
238
  export type GetSelectInputProps = (option: QuestionOption) => SelectInputProps;
231
239
  export type GetNextQuestionButtonProps = () => NextQuestionButtonProps;
232
240
  export type GetSkipQuestionButtonProps = () => SkipQuestionButtonProps;
233
241
  export type GetPreviousQuestionButtonProps = () => PreviousQuestionButtonProps;
242
+ export type GetJumpToQuestionButtonProps = (id: number) => JumpToQuestionButtonProps;
234
243
  export type GetResetQuizButtonProps = (stylesType?: 'primary' | 'secondary') => ResetQuizButtonProps;
235
244
  export type GetShareResultsButtonProps = () => ShareResultsButtonProps;
236
245
  export type GetHydrateQuizButtonProps = () => HydrateQuizButtonProps;
@@ -269,6 +278,7 @@ export interface UseQuizReturn {
269
278
  getAddToFavoritesButtonProps: GetAddToFavoritesButtonProps;
270
279
  getQuizResultButtonProps: GetQuizResultButtonProps;
271
280
  getQuizResultLinkProps: GetQuizResultLinkProps;
281
+ getJumpToQuestionButtonProps: GetJumpToQuestionButtonProps;
272
282
  primaryColorStyles: PrimaryColorStyles;
273
283
  }
274
284
  export type UseQuiz = (quizProps: IQuizProps) => UseQuizReturn;
@@ -1,2 +1,2 @@
1
- declare const _default: "1.18.0";
1
+ declare const _default: "1.19.0";
2
2
  export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructor-io/constructorio-ui-quizzes",
3
- "version": "1.18.0",
3
+ "version": "1.19.0",
4
4
  "description": "Constructor.io Quizzes UI library for web applications",
5
5
  "author": "Constructor.io Corporation",
6
6
  "license": "MIT",
@@ -112,7 +112,7 @@
112
112
  "storybook": "^7.6.20",
113
113
  "ts-jest": "^29.1.2",
114
114
  "typescript": "^4.9.4",
115
- "vite": "^4.2.1",
115
+ "vite": "^7.1.5",
116
116
  "vite-plugin-css-injected-by-js": "^3.1.0",
117
117
  "webpack": "^5.75.0",
118
118
  "whatwg-fetch": "^3.6.20"