@constructor-io/constructorio-ui-quizzes 1.8.2 → 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.
Files changed (192) hide show
  1. package/dist/constructorio-ui-quizzes-bundled.js +20 -20
  2. package/lib/cjs/package.json +105 -0
  3. package/lib/cjs/{components → src/components}/CioQuiz/actions.js +1 -0
  4. package/lib/cjs/{components → src/components}/CioQuiz/index.js +2 -1
  5. package/lib/cjs/{components → src/components}/CioQuiz/quizLocalReducer.js +21 -0
  6. package/lib/cjs/{components → src/components}/ControlBar/ControlBar.js +5 -2
  7. package/lib/cjs/src/components/SkipButton/SkipButton.js +13 -0
  8. package/lib/cjs/{constants.js → src/constants.js} +2 -0
  9. package/lib/cjs/{hooks → src/hooks}/usePropsGetters/index.js +4 -1
  10. package/lib/cjs/src/hooks/usePropsGetters/useSkipQuestionButtonProps.js +21 -0
  11. package/lib/cjs/{hooks → src/hooks}/useQuizEvents/index.js +3 -0
  12. package/lib/cjs/src/hooks/useQuizEvents/useQuizSkipClick.js +31 -0
  13. package/lib/cjs/{services → src/services}/index.js +2 -1
  14. package/lib/cjs/{stories → src/stories}/Quiz/tests/mocks.js +1 -0
  15. package/lib/cjs/{utils.js → src/utils.js} +1 -0
  16. package/lib/mjs/package.json +105 -0
  17. package/lib/mjs/{components → src/components}/CioQuiz/actions.js +1 -0
  18. package/lib/mjs/{components → src/components}/CioQuiz/index.js +2 -1
  19. package/lib/mjs/{components → src/components}/CioQuiz/quizLocalReducer.js +25 -0
  20. package/lib/mjs/src/components/ControlBar/ControlBar.js +15 -0
  21. package/lib/mjs/src/components/SkipButton/SkipButton.js +10 -0
  22. package/lib/mjs/{constants.js → src/constants.js} +2 -0
  23. package/lib/mjs/{hooks → src/hooks}/usePropsGetters/index.js +4 -1
  24. package/lib/mjs/src/hooks/usePropsGetters/useSkipQuestionButtonProps.js +17 -0
  25. package/lib/mjs/{hooks → src/hooks}/useQuizEvents/index.js +3 -0
  26. package/lib/mjs/src/hooks/useQuizEvents/useQuizSkipClick.js +31 -0
  27. package/lib/mjs/{services → src/services}/index.js +2 -1
  28. package/lib/mjs/{stories → src/stories}/Quiz/tests/mocks.js +4 -0
  29. package/lib/mjs/{utils.js → src/utils.js} +1 -0
  30. package/lib/styles.css +35 -1
  31. package/lib/types/{components → src/components}/CioQuiz/actions.d.ts +2 -1
  32. package/lib/types/{components → src/components}/CioQuiz/context.d.ts +2 -1
  33. package/lib/types/src/components/SkipButton/SkipButton.d.ts +6 -0
  34. package/lib/types/{constants.d.ts → src/constants.d.ts} +2 -2
  35. package/lib/types/{hooks → src/hooks}/usePropsGetters/index.d.ts +2 -1
  36. package/lib/types/src/hooks/usePropsGetters/useSkipQuestionButtonProps.d.ts +3 -0
  37. package/lib/types/src/hooks/useQuizEvents/useQuizSkipClick.d.ts +6 -0
  38. package/lib/types/{stories → src/stories}/Quiz/tests/mocks.d.ts +2 -2
  39. package/lib/types/{types.d.ts → src/types.d.ts} +13 -1
  40. package/lib/types/{utils.d.ts → src/utils.d.ts} +1 -0
  41. package/package.json +1 -1
  42. package/lib/mjs/components/ControlBar/ControlBar.js +0 -12
  43. /package/lib/cjs/{components → src/components}/BackButton/BackButton.js +0 -0
  44. /package/lib/cjs/{components → src/components}/CTAButton/CTAButton.js +0 -0
  45. /package/lib/cjs/{components → src/components}/CioQuiz/context.js +0 -0
  46. /package/lib/cjs/{components → src/components}/CioQuiz/quizApiReducer.js +0 -0
  47. /package/lib/cjs/{components → src/components}/CoverTypeQuestion/CoverTypeQuestion.js +0 -0
  48. /package/lib/cjs/{components → src/components}/OpenTextTypeQuestion/OpenTextTypeQuestion.js +0 -0
  49. /package/lib/cjs/{components → src/components}/ProgressBar/ProgressBar.js +0 -0
  50. /package/lib/cjs/{components → src/components}/QuestionDescription/QuestionDescription.js +0 -0
  51. /package/lib/cjs/{components → src/components}/QuestionTitle/QuestionTitle.js +0 -0
  52. /package/lib/cjs/{components → src/components}/QuizQuestions/index.js +0 -0
  53. /package/lib/cjs/{components → src/components}/RedoButton/RedoButton.js +0 -0
  54. /package/lib/cjs/{components → src/components}/RedoButton/RedoSVG.js +0 -0
  55. /package/lib/cjs/{components → src/components}/ResultCard/ResultCard.js +0 -0
  56. /package/lib/cjs/{components → src/components}/ResultContainer/ResultContainer.js +0 -0
  57. /package/lib/cjs/{components → src/components}/ResultCtaButton/ResultCtaButton.js +0 -0
  58. /package/lib/cjs/{components → src/components}/ResultFavoritesButton/ResultFavoritesButton.js +0 -0
  59. /package/lib/cjs/{components → src/components}/ResultFilters/ResultFilters.js +0 -0
  60. /package/lib/cjs/{components → src/components}/ResultHeroCard/ResultHeroCard.js +0 -0
  61. /package/lib/cjs/{components → src/components}/Results/Results.js +0 -0
  62. /package/lib/cjs/{components → src/components}/SelectTypeQuestion/SelectTypeQuestion.js +0 -0
  63. /package/lib/cjs/{components → src/components}/SessionPromptModal/SessionPromptModal.js +0 -0
  64. /package/lib/cjs/{components → src/components}/Spinner/Spinner.js +0 -0
  65. /package/lib/cjs/{components → src/components}/ZeroResults/ZeroResults.js +0 -0
  66. /package/lib/cjs/{hooks → src/hooks}/useCioClient.js +0 -0
  67. /package/lib/cjs/{hooks → src/hooks}/useConsoleErrors.js +0 -0
  68. /package/lib/cjs/{hooks → src/hooks}/usePrimaryColorStyles.js +0 -0
  69. /package/lib/cjs/{hooks → src/hooks}/usePropsGetters/useAddToFavoritesButtonProps.js +0 -0
  70. /package/lib/cjs/{hooks → src/hooks}/usePropsGetters/useCoverQuestionProps.js +0 -0
  71. /package/lib/cjs/{hooks → src/hooks}/usePropsGetters/useNextQuestionButtonProps.js +0 -0
  72. /package/lib/cjs/{hooks → src/hooks}/usePropsGetters/useOpenTextInputProps.js +0 -0
  73. /package/lib/cjs/{hooks → src/hooks}/usePropsGetters/usePreviousQuestionButtonProps.js +0 -0
  74. /package/lib/cjs/{hooks → src/hooks}/usePropsGetters/useSelectInputProps.js +0 -0
  75. /package/lib/cjs/{hooks → src/hooks}/useQuiz.js +0 -0
  76. /package/lib/cjs/{hooks → src/hooks}/useQuizEvents/useHydrateQuizLocalState.js +0 -0
  77. /package/lib/cjs/{hooks → src/hooks}/useQuizEvents/useQuizAddToCart.js +0 -0
  78. /package/lib/cjs/{hooks → src/hooks}/useQuizEvents/useQuizAddToFavorites.js +0 -0
  79. /package/lib/cjs/{hooks → src/hooks}/useQuizEvents/useQuizAnswerChangeHandler.js +0 -0
  80. /package/lib/cjs/{hooks → src/hooks}/useQuizEvents/useQuizBackClick.js +0 -0
  81. /package/lib/cjs/{hooks → src/hooks}/useQuizEvents/useQuizNextClick.js +0 -0
  82. /package/lib/cjs/{hooks → src/hooks}/useQuizEvents/useQuizResetClick.js +0 -0
  83. /package/lib/cjs/{hooks → src/hooks}/useQuizEvents/useQuizResultClick.js +0 -0
  84. /package/lib/cjs/{hooks → src/hooks}/useQuizEvents/useQuizResultsLoaded.js +0 -0
  85. /package/lib/cjs/{hooks → src/hooks}/useQuizState/index.js +0 -0
  86. /package/lib/cjs/{hooks → src/hooks}/useQuizState/useQuizApiState.js +0 -0
  87. /package/lib/cjs/{hooks → src/hooks}/useQuizState/useQuizLocalState.js +0 -0
  88. /package/lib/cjs/{hooks → src/hooks}/useQuizState/useSessionStorageState.js +0 -0
  89. /package/lib/cjs/{index.js → src/index.js} +0 -0
  90. /package/lib/cjs/{stories → src/stories}/Quiz/argTypes.js +0 -0
  91. /package/lib/cjs/{types.js → src/types.js} +0 -0
  92. /package/lib/mjs/{components → src/components}/BackButton/BackButton.js +0 -0
  93. /package/lib/mjs/{components → src/components}/CTAButton/CTAButton.js +0 -0
  94. /package/lib/mjs/{components → src/components}/CioQuiz/context.js +0 -0
  95. /package/lib/mjs/{components → src/components}/CioQuiz/quizApiReducer.js +0 -0
  96. /package/lib/mjs/{components → src/components}/CoverTypeQuestion/CoverTypeQuestion.js +0 -0
  97. /package/lib/mjs/{components → src/components}/OpenTextTypeQuestion/OpenTextTypeQuestion.js +0 -0
  98. /package/lib/mjs/{components → src/components}/ProgressBar/ProgressBar.js +0 -0
  99. /package/lib/mjs/{components → src/components}/QuestionDescription/QuestionDescription.js +0 -0
  100. /package/lib/mjs/{components → src/components}/QuestionTitle/QuestionTitle.js +0 -0
  101. /package/lib/mjs/{components → src/components}/QuizQuestions/index.js +0 -0
  102. /package/lib/mjs/{components → src/components}/RedoButton/RedoButton.js +0 -0
  103. /package/lib/mjs/{components → src/components}/RedoButton/RedoSVG.js +0 -0
  104. /package/lib/mjs/{components → src/components}/ResultCard/ResultCard.js +0 -0
  105. /package/lib/mjs/{components → src/components}/ResultContainer/ResultContainer.js +0 -0
  106. /package/lib/mjs/{components → src/components}/ResultCtaButton/ResultCtaButton.js +0 -0
  107. /package/lib/mjs/{components → src/components}/ResultFavoritesButton/ResultFavoritesButton.js +0 -0
  108. /package/lib/mjs/{components → src/components}/ResultFilters/ResultFilters.js +0 -0
  109. /package/lib/mjs/{components → src/components}/ResultHeroCard/ResultHeroCard.js +0 -0
  110. /package/lib/mjs/{components → src/components}/Results/Results.js +0 -0
  111. /package/lib/mjs/{components → src/components}/SelectTypeQuestion/SelectTypeQuestion.js +0 -0
  112. /package/lib/mjs/{components → src/components}/SessionPromptModal/SessionPromptModal.js +0 -0
  113. /package/lib/mjs/{components → src/components}/Spinner/Spinner.js +0 -0
  114. /package/lib/mjs/{components → src/components}/ZeroResults/ZeroResults.js +0 -0
  115. /package/lib/mjs/{hooks → src/hooks}/useCioClient.js +0 -0
  116. /package/lib/mjs/{hooks → src/hooks}/useConsoleErrors.js +0 -0
  117. /package/lib/mjs/{hooks → src/hooks}/usePrimaryColorStyles.js +0 -0
  118. /package/lib/mjs/{hooks → src/hooks}/usePropsGetters/useAddToFavoritesButtonProps.js +0 -0
  119. /package/lib/mjs/{hooks → src/hooks}/usePropsGetters/useCoverQuestionProps.js +0 -0
  120. /package/lib/mjs/{hooks → src/hooks}/usePropsGetters/useNextQuestionButtonProps.js +0 -0
  121. /package/lib/mjs/{hooks → src/hooks}/usePropsGetters/useOpenTextInputProps.js +0 -0
  122. /package/lib/mjs/{hooks → src/hooks}/usePropsGetters/usePreviousQuestionButtonProps.js +0 -0
  123. /package/lib/mjs/{hooks → src/hooks}/usePropsGetters/useSelectInputProps.js +0 -0
  124. /package/lib/mjs/{hooks → src/hooks}/useQuiz.js +0 -0
  125. /package/lib/mjs/{hooks → src/hooks}/useQuizEvents/useHydrateQuizLocalState.js +0 -0
  126. /package/lib/mjs/{hooks → src/hooks}/useQuizEvents/useQuizAddToCart.js +0 -0
  127. /package/lib/mjs/{hooks → src/hooks}/useQuizEvents/useQuizAddToFavorites.js +0 -0
  128. /package/lib/mjs/{hooks → src/hooks}/useQuizEvents/useQuizAnswerChangeHandler.js +0 -0
  129. /package/lib/mjs/{hooks → src/hooks}/useQuizEvents/useQuizBackClick.js +0 -0
  130. /package/lib/mjs/{hooks → src/hooks}/useQuizEvents/useQuizNextClick.js +0 -0
  131. /package/lib/mjs/{hooks → src/hooks}/useQuizEvents/useQuizResetClick.js +0 -0
  132. /package/lib/mjs/{hooks → src/hooks}/useQuizEvents/useQuizResultClick.js +0 -0
  133. /package/lib/mjs/{hooks → src/hooks}/useQuizEvents/useQuizResultsLoaded.js +0 -0
  134. /package/lib/mjs/{hooks → src/hooks}/useQuizState/index.js +0 -0
  135. /package/lib/mjs/{hooks → src/hooks}/useQuizState/useQuizApiState.js +0 -0
  136. /package/lib/mjs/{hooks → src/hooks}/useQuizState/useQuizLocalState.js +0 -0
  137. /package/lib/mjs/{hooks → src/hooks}/useQuizState/useSessionStorageState.js +0 -0
  138. /package/lib/mjs/{index.js → src/index.js} +0 -0
  139. /package/lib/mjs/{stories → src/stories}/Quiz/argTypes.js +0 -0
  140. /package/lib/mjs/{types.js → src/types.js} +0 -0
  141. /package/lib/types/{components → src/components}/BackButton/BackButton.d.ts +0 -0
  142. /package/lib/types/{components → src/components}/CTAButton/CTAButton.d.ts +0 -0
  143. /package/lib/types/{components → src/components}/CioQuiz/index.d.ts +0 -0
  144. /package/lib/types/{components → src/components}/CioQuiz/quizApiReducer.d.ts +0 -0
  145. /package/lib/types/{components → src/components}/CioQuiz/quizLocalReducer.d.ts +0 -0
  146. /package/lib/types/{components → src/components}/ControlBar/ControlBar.d.ts +0 -0
  147. /package/lib/types/{components → src/components}/CoverTypeQuestion/CoverTypeQuestion.d.ts +0 -0
  148. /package/lib/types/{components → src/components}/OpenTextTypeQuestion/OpenTextTypeQuestion.d.ts +0 -0
  149. /package/lib/types/{components → src/components}/ProgressBar/ProgressBar.d.ts +0 -0
  150. /package/lib/types/{components → src/components}/QuestionDescription/QuestionDescription.d.ts +0 -0
  151. /package/lib/types/{components → src/components}/QuestionTitle/QuestionTitle.d.ts +0 -0
  152. /package/lib/types/{components → src/components}/QuizQuestions/index.d.ts +0 -0
  153. /package/lib/types/{components → src/components}/RedoButton/RedoButton.d.ts +0 -0
  154. /package/lib/types/{components → src/components}/RedoButton/RedoSVG.d.ts +0 -0
  155. /package/lib/types/{components → src/components}/ResultCard/ResultCard.d.ts +0 -0
  156. /package/lib/types/{components → src/components}/ResultContainer/ResultContainer.d.ts +0 -0
  157. /package/lib/types/{components → src/components}/ResultCtaButton/ResultCtaButton.d.ts +0 -0
  158. /package/lib/types/{components → src/components}/ResultFavoritesButton/ResultFavoritesButton.d.ts +0 -0
  159. /package/lib/types/{components → src/components}/ResultFilters/ResultFilters.d.ts +0 -0
  160. /package/lib/types/{components → src/components}/ResultHeroCard/ResultHeroCard.d.ts +0 -0
  161. /package/lib/types/{components → src/components}/Results/Results.d.ts +0 -0
  162. /package/lib/types/{components → src/components}/SelectTypeQuestion/SelectTypeQuestion.d.ts +0 -0
  163. /package/lib/types/{components → src/components}/SessionPromptModal/SessionPromptModal.d.ts +0 -0
  164. /package/lib/types/{components → src/components}/Spinner/Spinner.d.ts +0 -0
  165. /package/lib/types/{components → src/components}/ZeroResults/ZeroResults.d.ts +0 -0
  166. /package/lib/types/{hooks → src/hooks}/useCioClient.d.ts +0 -0
  167. /package/lib/types/{hooks → src/hooks}/useConsoleErrors.d.ts +0 -0
  168. /package/lib/types/{hooks → src/hooks}/usePrimaryColorStyles.d.ts +0 -0
  169. /package/lib/types/{hooks → src/hooks}/usePropsGetters/useAddToFavoritesButtonProps.d.ts +0 -0
  170. /package/lib/types/{hooks → src/hooks}/usePropsGetters/useCoverQuestionProps.d.ts +0 -0
  171. /package/lib/types/{hooks → src/hooks}/usePropsGetters/useNextQuestionButtonProps.d.ts +0 -0
  172. /package/lib/types/{hooks → src/hooks}/usePropsGetters/useOpenTextInputProps.d.ts +0 -0
  173. /package/lib/types/{hooks → src/hooks}/usePropsGetters/usePreviousQuestionButtonProps.d.ts +0 -0
  174. /package/lib/types/{hooks → src/hooks}/usePropsGetters/useSelectInputProps.d.ts +0 -0
  175. /package/lib/types/{hooks → src/hooks}/useQuiz.d.ts +0 -0
  176. /package/lib/types/{hooks → src/hooks}/useQuizEvents/index.d.ts +0 -0
  177. /package/lib/types/{hooks → src/hooks}/useQuizEvents/useHydrateQuizLocalState.d.ts +0 -0
  178. /package/lib/types/{hooks → src/hooks}/useQuizEvents/useQuizAddToCart.d.ts +0 -0
  179. /package/lib/types/{hooks → src/hooks}/useQuizEvents/useQuizAddToFavorites.d.ts +0 -0
  180. /package/lib/types/{hooks → src/hooks}/useQuizEvents/useQuizAnswerChangeHandler.d.ts +0 -0
  181. /package/lib/types/{hooks → src/hooks}/useQuizEvents/useQuizBackClick.d.ts +0 -0
  182. /package/lib/types/{hooks → src/hooks}/useQuizEvents/useQuizNextClick.d.ts +0 -0
  183. /package/lib/types/{hooks → src/hooks}/useQuizEvents/useQuizResetClick.d.ts +0 -0
  184. /package/lib/types/{hooks → src/hooks}/useQuizEvents/useQuizResultClick.d.ts +0 -0
  185. /package/lib/types/{hooks → src/hooks}/useQuizEvents/useQuizResultsLoaded.d.ts +0 -0
  186. /package/lib/types/{hooks → src/hooks}/useQuizState/index.d.ts +0 -0
  187. /package/lib/types/{hooks → src/hooks}/useQuizState/useQuizApiState.d.ts +0 -0
  188. /package/lib/types/{hooks → src/hooks}/useQuizState/useQuizLocalState.d.ts +0 -0
  189. /package/lib/types/{hooks → src/hooks}/useQuizState/useSessionStorageState.d.ts +0 -0
  190. /package/lib/types/{index.d.ts → src/index.d.ts} +0 -0
  191. /package/lib/types/{services → src/services}/index.d.ts +0 -0
  192. /package/lib/types/{stories → src/stories}/Quiz/argTypes.d.ts +0 -0
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "@constructor-io/constructorio-ui-quizzes",
3
+ "version": "1.9.0",
4
+ "description": "Constructor.io Quizzes UI library for web applications",
5
+ "author": "constructor.io",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/Constructor-io/constructorio-ui-quizzes#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Constructor-io/constructorio-ui-quizzes.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/Constructor-io/constructorio-ui-quizzes/issues"
14
+ },
15
+ "main": "lib/cjs/index.js",
16
+ "module": "lib/mjs/index.js",
17
+ "exports": {
18
+ "./styles.css": {
19
+ "import": "./lib/styles.css",
20
+ "require": "./lib/styles.css"
21
+ },
22
+ "./constructorio-ui-quizzes-bundled": {
23
+ "import": "./dist/constructorio-ui-quizzes-bundled.js",
24
+ "require": "./dist/constructorio-ui-quizzes-bundled.js"
25
+ },
26
+ ".": {
27
+ "import": "./lib/mjs/index.js",
28
+ "require": "./lib/cjs/index.js"
29
+ },
30
+ "./cjs": {
31
+ "import": "./lib/cjs/index.js",
32
+ "require": "./lib/cjs/index.js"
33
+ }
34
+ },
35
+ "files": [
36
+ "lib/**/*",
37
+ "dist/constructorio-ui-quizzes-bundled.js"
38
+ ],
39
+ "engines": {
40
+ "node": ">=14"
41
+ },
42
+ "types": "lib/types/index.d.ts",
43
+ "scripts": {
44
+ "lint": "eslint src --ext js,ts,jsx,tsx",
45
+ "check-types": "npx tsc --noEmit",
46
+ "copy-styles": "cp src/styles.css lib/styles.css",
47
+ "prepare": "husky install",
48
+ "dev": "storybook dev -p 6006",
49
+ "storybook:ci": "storybook dev --ci --quiet -p 6006",
50
+ "test-storybook": "test-storybook",
51
+ "test-storybook:watch": "test-storybook --watch",
52
+ "test-storybook:ci": "start-server-and-test storybook:ci http://localhost:6006 test-storybook",
53
+ "build-storybook": "storybook build -o 'docs'",
54
+ "serve-built-storybook": "npx http-server docs",
55
+ "verify-node-version": "chmod +x ./scripts/verify-node-version.sh && ./scripts/verify-node-version.sh",
56
+ "version": "npm run verify-node-version && npm run build-storybook && git add -u ./docs && git add ./docs/* && npm run compile",
57
+ "compile": "rm -rf lib && tsc -p tsconfig.json && tsc -p tsconfig-cjs.json && npm run copy-styles && vite build",
58
+ "check-license": "license-checker --production --onlyAllow 'Apache-2.0;BSD-3-Clause;MIT;0BSD;BSD-2-Clause' --excludePackages 'picocolors@1.0.0'"
59
+ },
60
+ "peerDependencies": {
61
+ "@constructor-io/constructorio-client-javascript": "^2.35.17",
62
+ "react": ">=16.12.0",
63
+ "react-dom": ">=16.12.0",
64
+ "tslib": "^2.4.0"
65
+ },
66
+ "devDependencies": {
67
+ "@axe-core/react": "^4.7.0",
68
+ "@cspell/eslint-plugin": "^6.18.1",
69
+ "@storybook/addon-a11y": "^7.0.11",
70
+ "@storybook/addon-actions": "7.0.11",
71
+ "@storybook/addon-essentials": "7.0.11",
72
+ "@storybook/addon-interactions": "^7.0.11",
73
+ "@storybook/addon-links": "7.0.11",
74
+ "@storybook/addon-docs": "7.0.11",
75
+ "@storybook/jest": "^0.1.0",
76
+ "@storybook/react-webpack5": "7.0.11",
77
+ "@storybook/test-runner": "0.10.0",
78
+ "@storybook/testing-library": "^0.1.0",
79
+ "@types/react": "^18.0.26",
80
+ "@types/react-dom": "^18.0.9",
81
+ "@typescript-eslint/eslint-plugin": "^5.47.0",
82
+ "@typescript-eslint/parser": "^5.47.0",
83
+ "chromatic": "^6.21.0",
84
+ "eslint": "^8.30.0",
85
+ "eslint-config-airbnb": "^19.0.4",
86
+ "eslint-config-airbnb-typescript": "^17.0.0",
87
+ "eslint-config-prettier": "^8.5.0",
88
+ "eslint-plugin-import": "^2.26.0",
89
+ "eslint-plugin-jsx-a11y": "^6.7.1",
90
+ "eslint-plugin-prettier": "^4.2.1",
91
+ "eslint-plugin-react": "^7.31.11",
92
+ "eslint-plugin-react-hooks": "^4.6.0",
93
+ "eslint-plugin-storybook": "^0.6.12",
94
+ "husky": "^8.0.1",
95
+ "license-checker": "^25.0.1",
96
+ "react": "^18.2.0",
97
+ "react-dom": "^18.2.0",
98
+ "start-server-and-test": "^2.0.0",
99
+ "storybook": "7.0.11",
100
+ "typescript": "^4.9.4",
101
+ "vite": "^4.2.1",
102
+ "vite-plugin-css-injected-by-js": "^3.1.0",
103
+ "webpack": "^5.75.0"
104
+ }
105
+ }
@@ -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(CTAButton_1.default, { ctaText: ctaButtonText, propsGetters: getNextQuestionButtonProps })));
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;
@@ -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;
@@ -4,12 +4,13 @@ exports.trackQuizConversion = exports.trackQuizResultClick = exports.trackQuizRe
4
4
  const tslib_1 = require("tslib");
5
5
  /* eslint-disable @typescript-eslint/naming-convention */
6
6
  const constructorio_client_javascript_1 = tslib_1.__importDefault(require("@constructor-io/constructorio-client-javascript"));
7
+ const package_json_1 = require("../../package.json");
7
8
  const getCioClient = (apiKey) => {
8
9
  if (apiKey) {
9
10
  return new constructorio_client_javascript_1.default({
10
11
  apiKey,
11
12
  sendTrackingEvents: true,
12
- version: 'cio-ui-quizzes',
13
+ version: `cio-ui-quizzes-${package_json_1.version}`,
13
14
  });
14
15
  }
15
16
  return undefined;
@@ -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,
@@ -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) => {
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "@constructor-io/constructorio-ui-quizzes",
3
+ "version": "1.9.0",
4
+ "description": "Constructor.io Quizzes UI library for web applications",
5
+ "author": "constructor.io",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/Constructor-io/constructorio-ui-quizzes#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Constructor-io/constructorio-ui-quizzes.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/Constructor-io/constructorio-ui-quizzes/issues"
14
+ },
15
+ "main": "lib/cjs/index.js",
16
+ "module": "lib/mjs/index.js",
17
+ "exports": {
18
+ "./styles.css": {
19
+ "import": "./lib/styles.css",
20
+ "require": "./lib/styles.css"
21
+ },
22
+ "./constructorio-ui-quizzes-bundled": {
23
+ "import": "./dist/constructorio-ui-quizzes-bundled.js",
24
+ "require": "./dist/constructorio-ui-quizzes-bundled.js"
25
+ },
26
+ ".": {
27
+ "import": "./lib/mjs/index.js",
28
+ "require": "./lib/cjs/index.js"
29
+ },
30
+ "./cjs": {
31
+ "import": "./lib/cjs/index.js",
32
+ "require": "./lib/cjs/index.js"
33
+ }
34
+ },
35
+ "files": [
36
+ "lib/**/*",
37
+ "dist/constructorio-ui-quizzes-bundled.js"
38
+ ],
39
+ "engines": {
40
+ "node": ">=14"
41
+ },
42
+ "types": "lib/types/index.d.ts",
43
+ "scripts": {
44
+ "lint": "eslint src --ext js,ts,jsx,tsx",
45
+ "check-types": "npx tsc --noEmit",
46
+ "copy-styles": "cp src/styles.css lib/styles.css",
47
+ "prepare": "husky install",
48
+ "dev": "storybook dev -p 6006",
49
+ "storybook:ci": "storybook dev --ci --quiet -p 6006",
50
+ "test-storybook": "test-storybook",
51
+ "test-storybook:watch": "test-storybook --watch",
52
+ "test-storybook:ci": "start-server-and-test storybook:ci http://localhost:6006 test-storybook",
53
+ "build-storybook": "storybook build -o 'docs'",
54
+ "serve-built-storybook": "npx http-server docs",
55
+ "verify-node-version": "chmod +x ./scripts/verify-node-version.sh && ./scripts/verify-node-version.sh",
56
+ "version": "npm run verify-node-version && npm run build-storybook && git add -u ./docs && git add ./docs/* && npm run compile",
57
+ "compile": "rm -rf lib && tsc -p tsconfig.json && tsc -p tsconfig-cjs.json && npm run copy-styles && vite build",
58
+ "check-license": "license-checker --production --onlyAllow 'Apache-2.0;BSD-3-Clause;MIT;0BSD;BSD-2-Clause' --excludePackages 'picocolors@1.0.0'"
59
+ },
60
+ "peerDependencies": {
61
+ "@constructor-io/constructorio-client-javascript": "^2.35.17",
62
+ "react": ">=16.12.0",
63
+ "react-dom": ">=16.12.0",
64
+ "tslib": "^2.4.0"
65
+ },
66
+ "devDependencies": {
67
+ "@axe-core/react": "^4.7.0",
68
+ "@cspell/eslint-plugin": "^6.18.1",
69
+ "@storybook/addon-a11y": "^7.0.11",
70
+ "@storybook/addon-actions": "7.0.11",
71
+ "@storybook/addon-essentials": "7.0.11",
72
+ "@storybook/addon-interactions": "^7.0.11",
73
+ "@storybook/addon-links": "7.0.11",
74
+ "@storybook/addon-docs": "7.0.11",
75
+ "@storybook/jest": "^0.1.0",
76
+ "@storybook/react-webpack5": "7.0.11",
77
+ "@storybook/test-runner": "0.10.0",
78
+ "@storybook/testing-library": "^0.1.0",
79
+ "@types/react": "^18.0.26",
80
+ "@types/react-dom": "^18.0.9",
81
+ "@typescript-eslint/eslint-plugin": "^5.47.0",
82
+ "@typescript-eslint/parser": "^5.47.0",
83
+ "chromatic": "^6.21.0",
84
+ "eslint": "^8.30.0",
85
+ "eslint-config-airbnb": "^19.0.4",
86
+ "eslint-config-airbnb-typescript": "^17.0.0",
87
+ "eslint-config-prettier": "^8.5.0",
88
+ "eslint-plugin-import": "^2.26.0",
89
+ "eslint-plugin-jsx-a11y": "^6.7.1",
90
+ "eslint-plugin-prettier": "^4.2.1",
91
+ "eslint-plugin-react": "^7.31.11",
92
+ "eslint-plugin-react-hooks": "^4.6.0",
93
+ "eslint-plugin-storybook": "^0.6.12",
94
+ "husky": "^8.0.1",
95
+ "license-checker": "^25.0.1",
96
+ "react": "^18.2.0",
97
+ "react-dom": "^18.2.0",
98
+ "start-server-and-test": "^2.0.0",
99
+ "storybook": "7.0.11",
100
+ "typescript": "^4.9.4",
101
+ "vite": "^4.2.1",
102
+ "vite-plugin-css-injected-by-js": "^3.1.0",
103
+ "webpack": "^5.75.0"
104
+ }
105
+ }
@@ -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 {
@@ -0,0 +1,15 @@
1
+ import React, { useContext } from 'react';
2
+ import BackButton from '../BackButton/BackButton';
3
+ import CTAButton from '../CTAButton/CTAButton';
4
+ import SkipButton from '../SkipButton/SkipButton';
5
+ import QuizContext from '../CioQuiz/context';
6
+ function ControlBar(props) {
7
+ const { ctaButtonText } = props;
8
+ const { getNextQuestionButtonProps, getSkipQuestionButtonProps } = useContext(QuizContext);
9
+ return (React.createElement("div", { className: 'cio-question-buttons-container' },
10
+ React.createElement(BackButton, null),
11
+ React.createElement("div", { className: 'cio-question-buttons-group' },
12
+ React.createElement(SkipButton, { propsGetters: getSkipQuestionButtonProps }),
13
+ React.createElement(CTAButton, { ctaText: ctaButtonText, propsGetters: getNextQuestionButtonProps }))));
14
+ }
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;
@@ -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),