@quizparts/react 0.0.1

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 (112) hide show
  1. package/dist/components/Choice.d.ts +11 -0
  2. package/dist/components/Choice.d.ts.map +1 -0
  3. package/dist/components/Choice.js +36 -0
  4. package/dist/components/ChoiceIndicator.d.ts +10 -0
  5. package/dist/components/ChoiceIndicator.d.ts.map +1 -0
  6. package/dist/components/ChoiceIndicator.js +19 -0
  7. package/dist/components/Choices.d.ts +7 -0
  8. package/dist/components/Choices.d.ts.map +1 -0
  9. package/dist/components/Choices.js +8 -0
  10. package/dist/components/ContinueButton.d.ts +7 -0
  11. package/dist/components/ContinueButton.d.ts.map +1 -0
  12. package/dist/components/ContinueButton.js +7 -0
  13. package/dist/components/DefaultQuestionLayout.d.ts +16 -0
  14. package/dist/components/DefaultQuestionLayout.d.ts.map +1 -0
  15. package/dist/components/DefaultQuestionLayout.js +20 -0
  16. package/dist/components/Feedback.d.ts +5 -0
  17. package/dist/components/Feedback.d.ts.map +1 -0
  18. package/dist/components/Feedback.js +8 -0
  19. package/dist/components/Hint.d.ts +12 -0
  20. package/dist/components/Hint.d.ts.map +1 -0
  21. package/dist/components/Hint.js +11 -0
  22. package/dist/components/Instruction.d.ts +10 -0
  23. package/dist/components/Instruction.d.ts.map +1 -0
  24. package/dist/components/Instruction.js +16 -0
  25. package/dist/components/MatchPairs.d.ts +2 -0
  26. package/dist/components/MatchPairs.d.ts.map +1 -0
  27. package/dist/components/MatchPairs.js +38 -0
  28. package/dist/components/NextButton.d.ts +6 -0
  29. package/dist/components/NextButton.d.ts.map +1 -0
  30. package/dist/components/NextButton.js +6 -0
  31. package/dist/components/OrderList.d.ts +2 -0
  32. package/dist/components/OrderList.d.ts.map +1 -0
  33. package/dist/components/OrderList.js +48 -0
  34. package/dist/components/Progress.d.ts +5 -0
  35. package/dist/components/Progress.d.ts.map +1 -0
  36. package/dist/components/Progress.js +6 -0
  37. package/dist/components/ProgressBar.d.ts +6 -0
  38. package/dist/components/ProgressBar.d.ts.map +1 -0
  39. package/dist/components/ProgressBar.js +7 -0
  40. package/dist/components/Prompt.d.ts +5 -0
  41. package/dist/components/Prompt.d.ts.map +1 -0
  42. package/dist/components/Prompt.js +8 -0
  43. package/dist/components/Question.d.ts +7 -0
  44. package/dist/components/Question.d.ts.map +1 -0
  45. package/dist/components/Question.js +8 -0
  46. package/dist/components/QuestionBody.d.ts +8 -0
  47. package/dist/components/QuestionBody.d.ts.map +1 -0
  48. package/dist/components/QuestionBody.js +3 -0
  49. package/dist/components/QuestionCard.d.ts +10 -0
  50. package/dist/components/QuestionCard.d.ts.map +1 -0
  51. package/dist/components/QuestionCard.js +3 -0
  52. package/dist/components/QuestionCounter.d.ts +9 -0
  53. package/dist/components/QuestionCounter.d.ts.map +1 -0
  54. package/dist/components/QuestionCounter.js +9 -0
  55. package/dist/components/QuestionFooter.d.ts +8 -0
  56. package/dist/components/QuestionFooter.d.ts.map +1 -0
  57. package/dist/components/QuestionFooter.js +3 -0
  58. package/dist/components/QuestionHeader.d.ts +8 -0
  59. package/dist/components/QuestionHeader.d.ts.map +1 -0
  60. package/dist/components/QuestionHeader.js +3 -0
  61. package/dist/components/QuestionInput.d.ts +9 -0
  62. package/dist/components/QuestionInput.d.ts.map +1 -0
  63. package/dist/components/QuestionInput.js +33 -0
  64. package/dist/components/QuizComplete.d.ts +17 -0
  65. package/dist/components/QuizComplete.d.ts.map +1 -0
  66. package/dist/components/QuizComplete.js +13 -0
  67. package/dist/components/QuizFlow.d.ts +24 -0
  68. package/dist/components/QuizFlow.d.ts.map +1 -0
  69. package/dist/components/QuizFlow.js +15 -0
  70. package/dist/components/QuizRoot.d.ts +9 -0
  71. package/dist/components/QuizRoot.d.ts.map +1 -0
  72. package/dist/components/QuizRoot.js +7 -0
  73. package/dist/components/SentenceBuilder.d.ts +2 -0
  74. package/dist/components/SentenceBuilder.d.ts.map +1 -0
  75. package/dist/components/SentenceBuilder.js +36 -0
  76. package/dist/components/SubmitButton.d.ts +7 -0
  77. package/dist/components/SubmitButton.d.ts.map +1 -0
  78. package/dist/components/SubmitButton.js +7 -0
  79. package/dist/components/TextInput.d.ts +7 -0
  80. package/dist/components/TextInput.d.ts.map +1 -0
  81. package/dist/components/TextInput.js +22 -0
  82. package/dist/components/ThemeVarsProvider.d.ts +15 -0
  83. package/dist/components/ThemeVarsProvider.d.ts.map +1 -0
  84. package/dist/components/ThemeVarsProvider.js +7 -0
  85. package/dist/constants/defaultInstructions.d.ts +3 -0
  86. package/dist/constants/defaultInstructions.d.ts.map +1 -0
  87. package/dist/constants/defaultInstructions.js +8 -0
  88. package/dist/context/QuizContext.d.ts +40 -0
  89. package/dist/context/QuizContext.d.ts.map +1 -0
  90. package/dist/context/QuizContext.js +88 -0
  91. package/dist/hooks/useProgress.d.ts +16 -0
  92. package/dist/hooks/useProgress.d.ts.map +1 -0
  93. package/dist/hooks/useProgress.js +22 -0
  94. package/dist/hooks/useQuestion.d.ts +55 -0
  95. package/dist/hooks/useQuestion.d.ts.map +1 -0
  96. package/dist/hooks/useQuestion.js +77 -0
  97. package/dist/hooks/useQuiz.d.ts +22 -0
  98. package/dist/hooks/useQuiz.d.ts.map +1 -0
  99. package/dist/hooks/useQuiz.js +59 -0
  100. package/dist/hooks/useQuizContext.d.ts +2 -0
  101. package/dist/hooks/useQuizContext.d.ts.map +1 -0
  102. package/dist/hooks/useQuizContext.js +10 -0
  103. package/dist/index.d.ts +48 -0
  104. package/dist/index.d.ts.map +1 -0
  105. package/dist/index.js +47 -0
  106. package/dist/index.test.d.ts +2 -0
  107. package/dist/index.test.d.ts.map +1 -0
  108. package/dist/index.test.js +135 -0
  109. package/dist/test/setup.d.ts +2 -0
  110. package/dist/test/setup.d.ts.map +1 -0
  111. package/dist/test/setup.js +1 -0
  112. package/package.json +53 -0
@@ -0,0 +1,11 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface ChoiceProps {
3
+ /** Id of the choice (must match question.choices[].id). */
4
+ choiceId: string;
5
+ /** When true, renders ChoiceIndicator before the label (default false). */
6
+ showIndicator?: boolean;
7
+ children?: ReactNode;
8
+ }
9
+ /** Renders one multiple_choice or multi_select option. Use inside Choices; toggles/selects on click. */
10
+ export declare const Choice: ({ choiceId, showIndicator, children }: ChoiceProps) => import("react/jsx-runtime").JSX.Element | null;
11
+ //# sourceMappingURL=Choice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Choice.d.ts","sourceRoot":"","sources":["../../src/components/Choice.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,wGAAwG;AACxG,eAAO,MAAM,MAAM,GAAI,uCAA+C,WAAW,mDAwDhF,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useQuestion } from '../hooks/useQuestion.js';
3
+ import { ChoiceIndicator } from './ChoiceIndicator.js';
4
+ /** Renders one multiple_choice or multi_select option. Use inside Choices; toggles/selects on click. */
5
+ export const Choice = ({ choiceId, showIndicator = false, children }) => {
6
+ const { question, selectedChoiceId, selectedChoiceIds, selectChoice, toggleChoice, isSubmitted } = useQuestion();
7
+ if (!question || (question.type !== 'multiple_choice' && question.type !== 'multi_select'))
8
+ return null;
9
+ const choice = 'choices' in question ? question.choices.find((c) => c.id === choiceId) : null;
10
+ if (!choice)
11
+ return null;
12
+ const isMultiSelect = question.type === 'multi_select';
13
+ const selected = isMultiSelect
14
+ ? selectedChoiceIds.includes(choiceId)
15
+ : selectedChoiceId === choiceId;
16
+ const disabled = isSubmitted;
17
+ const answerIds = isMultiSelect && 'answer' in question ? question.answer : [];
18
+ const showCorrect = isSubmitted && (isMultiSelect ? answerIds.includes(choiceId) : question.answer === choiceId);
19
+ const showIncorrect = isSubmitted && selected && !showCorrect;
20
+ const handleClick = () => {
21
+ if (disabled)
22
+ return;
23
+ if (isMultiSelect)
24
+ toggleChoice(choiceId);
25
+ else
26
+ selectChoice(choiceId);
27
+ };
28
+ const label = children ?? choice.text;
29
+ const content = showIndicator ? (_jsxs(_Fragment, { children: [_jsx(ChoiceIndicator, { choiceId: choiceId, variant: isMultiSelect ? 'checkbox' : 'radio' }), ' ', label] })) : label;
30
+ return (_jsx("button", { type: "button", role: "option", "aria-selected": selected, "data-choice": true, "data-choice-id": choiceId, ...(selected && { 'data-selected': true }), ...(isSubmitted && { 'data-submitted': true }), ...(showCorrect && { 'data-correct': true }), ...(showIncorrect && { 'data-incorrect': true }), ...(disabled && { 'data-disabled': true }), disabled: disabled, onClick: handleClick, onKeyDown: (e) => {
31
+ if (e.key === 'Enter' || e.key === ' ') {
32
+ e.preventDefault();
33
+ handleClick();
34
+ }
35
+ }, children: content }));
36
+ };
@@ -0,0 +1,10 @@
1
+ export interface ChoiceIndicatorProps {
2
+ /** Id of the choice this indicator belongs to (must match Choice choiceId). */
3
+ choiceId: string;
4
+ /** 'radio' for single select, 'checkbox' for multi select. */
5
+ variant?: 'radio' | 'checkbox';
6
+ as?: keyof JSX.IntrinsicElements;
7
+ }
8
+ /** Visual or semantic marker for choice state (selected, correct, incorrect). Use inside Choice. */
9
+ export declare const ChoiceIndicator: ({ choiceId, variant, as: Component, }: ChoiceIndicatorProps) => import("react/jsx-runtime").JSX.Element | null;
10
+ //# sourceMappingURL=ChoiceIndicator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChoiceIndicator.d.ts","sourceRoot":"","sources":["../../src/components/ChoiceIndicator.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC/B,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;CAClC;AAED,oGAAoG;AACpG,eAAO,MAAM,eAAe,GAAI,uCAI7B,oBAAoB,mDAyBtB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useQuestion } from '../hooks/useQuestion.js';
3
+ /** Visual or semantic marker for choice state (selected, correct, incorrect). Use inside Choice. */
4
+ export const ChoiceIndicator = ({ choiceId, variant = 'radio', as: Component = 'span', }) => {
5
+ const { question, selectedChoiceId, selectedChoiceIds, isSubmitted } = useQuestion();
6
+ if (!question || (question.type !== 'multiple_choice' && question.type !== 'multi_select'))
7
+ return null;
8
+ const choice = 'choices' in question ? question.choices.find((c) => c.id === choiceId) : null;
9
+ if (!choice)
10
+ return null;
11
+ const isMultiSelect = question.type === 'multi_select';
12
+ const selected = isMultiSelect
13
+ ? selectedChoiceIds.includes(choiceId)
14
+ : selectedChoiceId === choiceId;
15
+ const answerIds = isMultiSelect && 'answer' in question ? question.answer : [];
16
+ const showCorrect = isSubmitted && (isMultiSelect ? answerIds.includes(choiceId) : question.answer === choiceId);
17
+ const showIncorrect = isSubmitted && selected && !showCorrect;
18
+ return (_jsx(Component, { "data-quiz-choice-indicator": true, "data-variant": variant, "aria-hidden": true, ...(selected && { 'data-selected': true }), ...(showCorrect && { 'data-correct': true }), ...(showIncorrect && { 'data-incorrect': true }) }));
19
+ };
@@ -0,0 +1,7 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface ChoicesProps {
3
+ children: ReactNode;
4
+ as?: keyof JSX.IntrinsicElements;
5
+ }
6
+ export declare const Choices: ({ children, as: Component }: ChoicesProps) => import("react/jsx-runtime").JSX.Element | null;
7
+ //# sourceMappingURL=Choices.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Choices.d.ts","sourceRoot":"","sources":["../../src/components/Choices.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,SAAS,CAAC;IACpB,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;CAClC;AAED,eAAO,MAAM,OAAO,GAAI,6BAAqC,YAAY,mDASxE,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useQuestion } from '../hooks/useQuestion.js';
3
+ export const Choices = ({ children, as: Component = 'div' }) => {
4
+ const { question } = useQuestion();
5
+ if (!question || (question.type !== 'multiple_choice' && question.type !== 'multi_select'))
6
+ return null;
7
+ return (_jsx(Component, { "data-quiz-choices": true, role: "listbox", "aria-label": "Choices", children: children }));
8
+ };
@@ -0,0 +1,7 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface ContinueButtonProps {
3
+ children?: ReactNode;
4
+ }
5
+ /** Advances to the next question after submit. Same behavior as NextButton; default label "Skip". */
6
+ export declare const ContinueButton: ({ children }: ContinueButtonProps) => import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=ContinueButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContinueButton.d.ts","sourceRoot":"","sources":["../../src/components/ContinueButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,qGAAqG;AACrG,eAAO,MAAM,cAAc,GAAI,cAAuB,mBAAmB,4CAaxE,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useQuiz } from '../hooks/useQuiz.js';
3
+ /** Advances to the next question after submit. Same behavior as NextButton; default label "Skip". */
4
+ export const ContinueButton = ({ children = 'Skip' }) => {
5
+ const { canGoNext, goToNextQuestion } = useQuiz();
6
+ return (_jsx("button", { type: "button", "data-quiz-continue": true, ...(!canGoNext && { 'data-disabled': true }), disabled: !canGoNext, onClick: () => canGoNext && goToNextQuestion(), children: children }));
7
+ };
@@ -0,0 +1,16 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface DefaultQuestionLayoutProps {
3
+ /** Optional hint below the input (string or node). */
4
+ hint?: ReactNode;
5
+ /** Submit button label (default "Answer"). */
6
+ submitLabel?: ReactNode;
7
+ /** Skip button label before submit (default "Skip"). */
8
+ continueLabel?: ReactNode;
9
+ /** Next button label after submit (default "Next"). Shown in place of Answer + Skip. */
10
+ nextLabel?: ReactNode;
11
+ /** Whether choices show the indicator (default true). */
12
+ showChoiceIndicator?: boolean;
13
+ }
14
+ /** Default question layout: before submit shows Answer + Skip; after submit shows only Next so users get used to that button. */
15
+ export declare const DefaultQuestionLayout: ({ hint, submitLabel, continueLabel, nextLabel, showChoiceIndicator, }: DefaultQuestionLayoutProps) => import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=DefaultQuestionLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultQuestionLayout.d.ts","sourceRoot":"","sources":["../../src/components/DefaultQuestionLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAgBvC,MAAM,WAAW,0BAA0B;IACzC,sDAAsD;IACtD,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,wDAAwD;IACxD,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,wFAAwF;IACxF,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,yDAAyD;IACzD,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,iIAAiI;AACjI,eAAO,MAAM,qBAAqB,GAAI,uEAMnC,0BAA0B,4CA0B5B,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useQuestion } from '../hooks/useQuestion.js';
3
+ import { QuestionCard } from './QuestionCard.js';
4
+ import { QuestionHeader } from './QuestionHeader.js';
5
+ import { QuestionBody } from './QuestionBody.js';
6
+ import { QuestionFooter } from './QuestionFooter.js';
7
+ import { ProgressBar } from './ProgressBar.js';
8
+ import { QuestionCounter } from './QuestionCounter.js';
9
+ import { Prompt } from './Prompt.js';
10
+ import { QuestionInput } from './QuestionInput.js';
11
+ import { Hint } from './Hint.js';
12
+ import { SubmitButton } from './SubmitButton.js';
13
+ import { ContinueButton } from './ContinueButton.js';
14
+ import { NextButton } from './NextButton.js';
15
+ import { Feedback } from './Feedback.js';
16
+ /** Default question layout: before submit shows Answer + Skip; after submit shows only Next so users get used to that button. */
17
+ export const DefaultQuestionLayout = ({ hint, submitLabel = 'Answer', continueLabel = 'Skip', nextLabel = 'Next', showChoiceIndicator = true, }) => {
18
+ const { isSubmitted } = useQuestion();
19
+ return (_jsxs(QuestionCard, { children: [_jsxs(QuestionHeader, { children: [_jsx(ProgressBar, {}), _jsx(QuestionCounter, {})] }), _jsxs(QuestionBody, { children: [_jsx(Prompt, {}), _jsx(QuestionInput, { showChoiceIndicator: showChoiceIndicator }), hint != null && (typeof hint === 'string' ? _jsx(Hint, { hint: hint }) : _jsx(Hint, { children: hint }))] }), _jsxs(QuestionFooter, { children: [!isSubmitted ? (_jsxs(_Fragment, { children: [_jsx(SubmitButton, { children: submitLabel }), _jsx(ContinueButton, { children: continueLabel })] })) : (_jsx(NextButton, { children: nextLabel })), _jsx(Feedback, {})] })] }));
20
+ };
@@ -0,0 +1,5 @@
1
+ export interface FeedbackProps {
2
+ as?: keyof JSX.IntrinsicElements;
3
+ }
4
+ export declare const Feedback: ({ as: Component }: FeedbackProps) => import("react/jsx-runtime").JSX.Element | null;
5
+ //# sourceMappingURL=Feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Feedback.d.ts","sourceRoot":"","sources":["../../src/components/Feedback.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;CAClC;AAED,eAAO,MAAM,QAAQ,GAAI,mBAA2B,aAAa,mDAgBhE,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useQuestion } from '../hooks/useQuestion.js';
3
+ export const Feedback = ({ as: Component = 'div' }) => {
4
+ const { feedback, isSubmitted } = useQuestion();
5
+ if (!isSubmitted || !feedback)
6
+ return null;
7
+ return (_jsxs(Component, { "data-quiz-feedback": true, "data-correct": feedback.isCorrect || undefined, "data-incorrect": !feedback.isCorrect || undefined, role: "status", children: [feedback.isCorrect ? 'Correct!' : 'Incorrect.', feedback.isCorrect && feedback.explanation != null && feedback.explanation !== '' && (_jsx("p", { "data-quiz-explanation": true, children: feedback.explanation }))] }));
8
+ };
@@ -0,0 +1,12 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface HintProps {
3
+ /** Hint text. When absent, children can be used. */
4
+ hint?: string;
5
+ children?: ReactNode;
6
+ /** When false, render nothing (for future "show hint" toggles). */
7
+ visible?: boolean;
8
+ as?: keyof JSX.IntrinsicElements;
9
+ }
10
+ /** Renders a hint. Use for study practice or scaffolded exercises. */
11
+ export declare const Hint: ({ hint, children, visible, as: Component, }: HintProps) => import("react/jsx-runtime").JSX.Element | null;
12
+ //# sourceMappingURL=Hint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Hint.d.ts","sourceRoot":"","sources":["../../src/components/Hint.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,SAAS;IACxB,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;CAClC;AAED,sEAAsE;AACtE,eAAO,MAAM,IAAI,GAAI,6CAKlB,SAAS,mDAUX,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /** Renders a hint. Use for study practice or scaffolded exercises. */
3
+ export const Hint = ({ hint, children, visible = true, as: Component = 'div', }) => {
4
+ if (!visible)
5
+ return null;
6
+ const hasHint = hint != null && hint !== '';
7
+ const hasChildren = children != null;
8
+ if (!hasHint && !hasChildren)
9
+ return null;
10
+ return (_jsx(Component, { "data-quiz-hint": true, children: hasHint ? hint : children }));
11
+ };
@@ -0,0 +1,10 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface InstructionProps {
3
+ /** Instructional copy. When omitted, uses default for current question type (e.g. "Choose one.", "Select all that apply."). */
4
+ instruction?: string;
5
+ children?: ReactNode;
6
+ as?: keyof JSX.IntrinsicElements;
7
+ }
8
+ /** Short instruction separate from the main prompt. Uses default by question type when instruction is not provided. */
9
+ export declare const Instruction: ({ instruction: instructionProp, children, as: Component, }: InstructionProps) => import("react/jsx-runtime").JSX.Element | null;
10
+ //# sourceMappingURL=Instruction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Instruction.d.ts","sourceRoot":"","sources":["../../src/components/Instruction.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,WAAW,gBAAgB;IAC/B,+HAA+H;IAC/H,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;CAClC;AAED,uHAAuH;AACvH,eAAO,MAAM,WAAW,GAAI,4DAIzB,gBAAgB,mDAelB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useQuestion } from '../hooks/useQuestion.js';
3
+ import { DEFAULT_INSTRUCTIONS } from '../constants/defaultInstructions.js';
4
+ /** Short instruction separate from the main prompt. Uses default by question type when instruction is not provided. */
5
+ export const Instruction = ({ instruction: instructionProp, children, as: Component = 'p', }) => {
6
+ const { question } = useQuestion();
7
+ const instruction = instructionProp != null && instructionProp !== ''
8
+ ? instructionProp
9
+ : question && question.type in DEFAULT_INSTRUCTIONS
10
+ ? DEFAULT_INSTRUCTIONS[question.type]
11
+ : null;
12
+ const hasChildren = children != null;
13
+ if (!instruction && !hasChildren)
14
+ return null;
15
+ return (_jsx(Component, { "data-quiz-instruction": true, children: instruction ?? children }));
16
+ };
@@ -0,0 +1,2 @@
1
+ export declare const MatchPairs: () => import("react/jsx-runtime").JSX.Element | null;
2
+ //# sourceMappingURL=MatchPairs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MatchPairs.d.ts","sourceRoot":"","sources":["../../src/components/MatchPairs.tsx"],"names":[],"mappings":"AAKA,eAAO,MAAM,UAAU,sDAiGtB,CAAC"}
@@ -0,0 +1,38 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState } from 'react';
4
+ import { useQuestion } from '../hooks/useQuestion.js';
5
+ export const MatchPairs = () => {
6
+ const { question, matchPairs, setMatchPairs, isSubmitted } = useQuestion();
7
+ const [selectedLeft, setSelectedLeft] = useState(null);
8
+ if (!question || question.type !== 'match_pairs')
9
+ return null;
10
+ const { pairs } = question;
11
+ const lefts = pairs.map((p) => p.left);
12
+ const rights = pairs.map((p) => p.right);
13
+ const usedLeft = new Set(matchPairs.map(([l]) => l));
14
+ const usedRight = new Set(matchPairs.map(([, r]) => r));
15
+ const availableLeft = lefts.filter((l) => !usedLeft.has(l));
16
+ const availableRight = rights.filter((r) => !usedRight.has(r));
17
+ const disabled = isSubmitted;
18
+ const handleLeftClick = (left) => {
19
+ if (disabled)
20
+ return;
21
+ setSelectedLeft((prev) => (prev === left ? null : left));
22
+ };
23
+ const handleRightClick = (right) => {
24
+ if (disabled || !selectedLeft)
25
+ return;
26
+ setMatchPairs([...matchPairs, [selectedLeft, right]]);
27
+ setSelectedLeft(null);
28
+ };
29
+ const handleRemovePair = (index) => {
30
+ if (disabled)
31
+ return;
32
+ setMatchPairs(matchPairs.filter((_, i) => i !== index));
33
+ };
34
+ return (_jsxs("div", { "data-quiz-match-pairs": true, style: { display: 'flex', flexDirection: 'column', gap: '0.75rem' }, role: "group", "aria-label": "Match pairs", children: [matchPairs.length > 0 && (_jsxs("div", { children: [_jsx("span", { id: "match-pairs-formed", style: { fontSize: '0.875rem', fontWeight: 600 }, children: "Matched:" }), _jsx("ul", { style: { listStyle: 'none', padding: 0, margin: '0.25rem 0 0', display: 'flex', flexWrap: 'wrap', gap: '0.5rem' }, children: matchPairs.map(([l, r], i) => (_jsx("li", { children: _jsxs("button", { type: "button", onClick: () => handleRemovePair(i), disabled: disabled, style: { padding: '0.25rem 0.5rem', fontSize: '0.875rem' }, "data-match-pair": true, children: [l, " \u2192 ", r, " ", !disabled && '✕'] }) }, `${l}-${r}-${i}`))) })] })), _jsxs("div", { style: { display: 'flex', gap: '1rem', flexWrap: 'wrap' }, children: [_jsxs("div", { role: "group", "aria-labelledby": "match-left-label", children: [_jsx("span", { id: "match-left-label", style: { fontSize: '0.875rem', fontWeight: 600 }, children: "Left" }), _jsx("ul", { style: { listStyle: 'none', padding: 0, margin: '0.25rem 0 0', display: 'flex', flexDirection: 'column', gap: '0.25rem' }, role: "list", children: availableLeft.map((left) => (_jsx("li", { children: _jsx("button", { type: "button", onClick: () => handleLeftClick(left), disabled: disabled, "data-match-left": true, ...(selectedLeft === left && { 'data-selected': '' }), "aria-pressed": selectedLeft === left, style: {
35
+ padding: '0.5rem 0.75rem',
36
+ fontWeight: selectedLeft === left ? 600 : 400,
37
+ }, children: left }) }, left))) })] }), _jsxs("div", { role: "group", "aria-labelledby": "match-right-label", children: [_jsx("span", { id: "match-right-label", style: { fontSize: '0.875rem', fontWeight: 600 }, children: "Right" }), _jsx("ul", { style: { listStyle: 'none', padding: 0, margin: '0.25rem 0 0', display: 'flex', flexDirection: 'column', gap: '0.25rem' }, role: "list", children: availableRight.map((right) => (_jsx("li", { children: _jsx("button", { type: "button", onClick: () => handleRightClick(right), disabled: disabled, "data-match-right": true, style: { padding: '0.5rem 0.75rem' }, children: right }) }, right))) })] })] })] }));
38
+ };
@@ -0,0 +1,6 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface NextButtonProps {
3
+ children?: ReactNode;
4
+ }
5
+ export declare const NextButton: ({ children }: NextButtonProps) => import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=NextButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NextButton.d.ts","sourceRoot":"","sources":["../../src/components/NextButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,eAAO,MAAM,UAAU,GAAI,cAAuB,eAAe,4CAahE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useQuiz } from '../hooks/useQuiz.js';
3
+ export const NextButton = ({ children = 'Next' }) => {
4
+ const { canGoNext, goToNextQuestion } = useQuiz();
5
+ return (_jsx("button", { type: "button", "data-quiz-next": true, ...(!canGoNext && { 'data-disabled': true }), disabled: !canGoNext, onClick: () => canGoNext && goToNextQuestion(), children: children }));
6
+ };
@@ -0,0 +1,2 @@
1
+ export declare const OrderList: () => import("react/jsx-runtime").JSX.Element | null;
2
+ //# sourceMappingURL=OrderList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrderList.d.ts","sourceRoot":"","sources":["../../src/components/OrderList.tsx"],"names":[],"mappings":"AAaA,eAAO,MAAM,SAAS,sDAqErB,CAAC"}
@@ -0,0 +1,48 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect } from 'react';
4
+ import { useQuestion } from '../hooks/useQuestion.js';
5
+ const move = (ids, index, direction) => {
6
+ const next = [...ids];
7
+ const target = direction === 'up' ? index - 1 : index + 1;
8
+ if (target < 0 || target >= next.length)
9
+ return next;
10
+ [next[index], next[target]] = [next[target], next[index]];
11
+ return next;
12
+ };
13
+ export const OrderList = () => {
14
+ const { question, orderedIds, setOrderedIds, isSubmitted } = useQuestion();
15
+ if (!question || question.type !== 'order_items')
16
+ return null;
17
+ const { items } = question;
18
+ const itemMap = new Map(items.map((i) => [i.id, i]));
19
+ const ids = orderedIds.length > 0 ? orderedIds : items.map((i) => i.id);
20
+ const disabled = isSubmitted;
21
+ useEffect(() => {
22
+ if (orderedIds.length === 0 && items.length > 0) {
23
+ setOrderedIds(items.map((i) => i.id));
24
+ }
25
+ }, [items, orderedIds.length, setOrderedIds]);
26
+ const handleMoveUp = (index) => {
27
+ if (disabled || index <= 0)
28
+ return;
29
+ setOrderedIds(move(ids, index, 'up'));
30
+ };
31
+ const handleMoveDown = (index) => {
32
+ if (disabled || index >= ids.length - 1)
33
+ return;
34
+ setOrderedIds(move(ids, index, 'down'));
35
+ };
36
+ return (_jsx("div", { "data-quiz-order-list": true, style: { display: 'flex', flexDirection: 'column', gap: '0.5rem' }, role: "group", "aria-label": "Order items", children: _jsx("ul", { style: { listStyle: 'none', padding: 0, margin: 0 }, role: "list", children: ids.map((id, index) => {
37
+ const item = itemMap.get(id);
38
+ if (!item)
39
+ return null;
40
+ return (_jsxs("li", { "data-order-item": true, "data-item-id": id, style: {
41
+ display: 'flex',
42
+ alignItems: 'center',
43
+ gap: '0.5rem',
44
+ padding: '0.5rem 0',
45
+ borderBottom: '1px solid #eee',
46
+ }, children: [_jsx("span", { style: { flex: 1 }, children: item.text }), _jsx("button", { type: "button", onClick: () => handleMoveUp(index), disabled: disabled || index === 0, "aria-label": `Move ${item.text} up`, style: { padding: '0.25rem 0.5rem' }, children: "\u2191" }), _jsx("button", { type: "button", onClick: () => handleMoveDown(index), disabled: disabled || index === ids.length - 1, "aria-label": `Move ${item.text} down`, style: { padding: '0.25rem 0.5rem' }, children: "\u2193" })] }, id));
47
+ }) }) }));
48
+ };
@@ -0,0 +1,5 @@
1
+ export interface ProgressProps {
2
+ as?: keyof JSX.IntrinsicElements;
3
+ }
4
+ export declare const Progress: ({ as: Component }: ProgressProps) => import("react/jsx-runtime").JSX.Element;
5
+ //# sourceMappingURL=Progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Progress.d.ts","sourceRoot":"","sources":["../../src/components/Progress.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;CAClC;AAED,eAAO,MAAM,QAAQ,GAAI,mBAA2B,aAAa,4CAkBhE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useProgress } from '../hooks/useProgress.js';
3
+ export const Progress = ({ as: Component = 'div' }) => {
4
+ const { current, total, percent, score } = useProgress();
5
+ return (_jsxs(Component, { "data-quiz-progress": true, role: "progressbar", "aria-valuenow": current, "aria-valuemin": 1, "aria-valuemax": total, "aria-label": `Question ${current} of ${total}`, children: [_jsxs("span", { "data-quiz-progress-text": true, children: [current, " / ", total] }), _jsxs("span", { "data-quiz-progress-percent": true, children: [percent, "%"] }), _jsxs("span", { "data-quiz-progress-score": true, children: ["Score: ", score] })] }));
6
+ };
@@ -0,0 +1,6 @@
1
+ export interface ProgressBarProps {
2
+ as?: keyof JSX.IntrinsicElements;
3
+ }
4
+ /** Visual progress track and fill. Use progress from useProgress; theme targets data-quiz-progress-bar. */
5
+ export declare const ProgressBar: ({ as: Component }: ProgressBarProps) => import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=ProgressBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProgressBar.d.ts","sourceRoot":"","sources":["../../src/components/ProgressBar.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;CAClC;AAED,2GAA2G;AAC3G,eAAO,MAAM,WAAW,GAAI,mBAA2B,gBAAgB,4CAiBtE,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useProgress } from '../hooks/useProgress.js';
3
+ /** Visual progress track and fill. Use progress from useProgress; theme targets data-quiz-progress-bar. */
4
+ export const ProgressBar = ({ as: Component = 'div' }) => {
5
+ const { percent } = useProgress();
6
+ return (_jsxs(Component, { "data-quiz-progress-bar": true, role: "progressbar", "aria-valuenow": percent, "aria-valuemin": 0, "aria-valuemax": 100, children: [_jsx("span", { "data-quiz-progress-bar-track": true }), _jsx("span", { "data-quiz-progress-bar-fill": true, style: { width: `${percent}%` } })] }));
7
+ };
@@ -0,0 +1,5 @@
1
+ export interface PromptProps {
2
+ as?: keyof JSX.IntrinsicElements;
3
+ }
4
+ export declare const Prompt: ({ as: Component }: PromptProps) => import("react/jsx-runtime").JSX.Element | null;
5
+ //# sourceMappingURL=Prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Prompt.d.ts","sourceRoot":"","sources":["../../src/components/Prompt.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;CAClC;AAED,eAAO,MAAM,MAAM,GAAI,mBAAyB,WAAW,mDAI1D,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useQuestion } from '../hooks/useQuestion.js';
3
+ export const Prompt = ({ as: Component = 'p' }) => {
4
+ const { question } = useQuestion();
5
+ if (!question)
6
+ return null;
7
+ return _jsx(Component, { "data-quiz-prompt": true, children: question.prompt });
8
+ };
@@ -0,0 +1,7 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface QuestionProps {
3
+ children?: ReactNode;
4
+ as?: keyof JSX.IntrinsicElements;
5
+ }
6
+ export declare const Question: ({ children, as: Component }: QuestionProps) => import("react/jsx-runtime").JSX.Element | null;
7
+ //# sourceMappingURL=Question.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Question.d.ts","sourceRoot":"","sources":["../../src/components/Question.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;CAClC;AAED,eAAO,MAAM,QAAQ,GAAI,6BAAqC,aAAa,mDAa1E,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useQuestion } from '../hooks/useQuestion.js';
3
+ export const Question = ({ children, as: Component = 'div' }) => {
4
+ const { question, status } = useQuestion();
5
+ if (!question)
6
+ return null;
7
+ return (_jsx(Component, { "data-quiz-question": true, "data-question-id": question.id, "data-question-type": question.type, "data-status": status, children: children }));
8
+ };
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface QuestionBodyProps {
3
+ children: ReactNode;
4
+ as?: keyof JSX.IntrinsicElements;
5
+ }
6
+ /** Middle content area (prompt, instruction, choices, inputs). */
7
+ export declare const QuestionBody: ({ children, as: Component, }: QuestionBodyProps) => import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=QuestionBody.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuestionBody.d.ts","sourceRoot":"","sources":["../../src/components/QuestionBody.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;CAClC;AAED,kEAAkE;AAClE,eAAO,MAAM,YAAY,GAAI,8BAG1B,iBAAiB,4CAEnB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /** Middle content area (prompt, instruction, choices, inputs). */
3
+ export const QuestionBody = ({ children, as: Component = 'div', }) => (_jsx(Component, { "data-quiz-question-body": true, children: children }));
@@ -0,0 +1,10 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface QuestionCardProps {
3
+ children: ReactNode;
4
+ /** Root element (default 'div'). Use for semantics or React Native. */
5
+ as?: keyof JSX.IntrinsicElements;
6
+ className?: string;
7
+ }
8
+ /** Layout wrapper for the main question surface. Theme targets data-quiz-question-card. */
9
+ export declare const QuestionCard: ({ children, as: Component, className, }: QuestionCardProps) => import("react/jsx-runtime").JSX.Element;
10
+ //# sourceMappingURL=QuestionCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuestionCard.d.ts","sourceRoot":"","sources":["../../src/components/QuestionCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,uEAAuE;IACvE,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2FAA2F;AAC3F,eAAO,MAAM,YAAY,GAAI,yCAI1B,iBAAiB,4CAInB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /** Layout wrapper for the main question surface. Theme targets data-quiz-question-card. */
3
+ export const QuestionCard = ({ children, as: Component = 'div', className, }) => (_jsx(Component, { "data-quiz-question-card": true, className: className, children: children }));
@@ -0,0 +1,9 @@
1
+ export interface QuestionCounterProps {
2
+ /** Custom format: "{current}" and "{total}" are replaced. Default "Question {current} of {total}". */
3
+ format?: string;
4
+ children?: React.ReactNode;
5
+ as?: keyof JSX.IntrinsicElements;
6
+ }
7
+ /** Displays current question index and total (e.g. "Question 3 of 10"). */
8
+ export declare const QuestionCounter: ({ format, children, as: Component, }: QuestionCounterProps) => import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=QuestionCounter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuestionCounter.d.ts","sourceRoot":"","sources":["../../src/components/QuestionCounter.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,sGAAsG;IACtG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;CAClC;AAID,2EAA2E;AAC3E,eAAO,MAAM,eAAe,GAAI,sCAI7B,oBAAoB,4CAQtB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useProgress } from '../hooks/useProgress.js';
3
+ const DEFAULT_FORMAT = 'Question {current} of {total}';
4
+ /** Displays current question index and total (e.g. "Question 3 of 10"). */
5
+ export const QuestionCounter = ({ format = DEFAULT_FORMAT, children, as: Component = 'span', }) => {
6
+ const { current, total } = useProgress();
7
+ const text = format.replace('{current}', String(current)).replace('{total}', String(total));
8
+ return (_jsx(Component, { "data-quiz-question-counter": true, "aria-live": "polite", children: children ?? text }));
9
+ };
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface QuestionFooterProps {
3
+ children: ReactNode;
4
+ as?: keyof JSX.IntrinsicElements;
5
+ }
6
+ /** Bottom area for actions and feedback (submit, continue, retry, feedback). */
7
+ export declare const QuestionFooter: ({ children, as: Component, }: QuestionFooterProps) => import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=QuestionFooter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuestionFooter.d.ts","sourceRoot":"","sources":["../../src/components/QuestionFooter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,SAAS,CAAC;IACpB,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;CAClC;AAED,gFAAgF;AAChF,eAAO,MAAM,cAAc,GAAI,8BAG5B,mBAAmB,4CAErB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /** Bottom area for actions and feedback (submit, continue, retry, feedback). */
3
+ export const QuestionFooter = ({ children, as: Component = 'footer', }) => (_jsx(Component, { "data-quiz-question-footer": true, children: children }));
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface QuestionHeaderProps {
3
+ children: ReactNode;
4
+ as?: keyof JSX.IntrinsicElements;
5
+ }
6
+ /** Top area of a question card (counter, progress, prompt, media). */
7
+ export declare const QuestionHeader: ({ children, as: Component, }: QuestionHeaderProps) => import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=QuestionHeader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuestionHeader.d.ts","sourceRoot":"","sources":["../../src/components/QuestionHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,SAAS,CAAC;IACpB,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;CAClC;AAED,sEAAsE;AACtE,eAAO,MAAM,cAAc,GAAI,8BAG5B,mBAAmB,4CAErB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /** Top area of a question card (counter, progress, prompt, media). */
3
+ export const QuestionHeader = ({ children, as: Component = 'header', }) => (_jsx(Component, { "data-quiz-question-header": true, children: children }));
@@ -0,0 +1,9 @@
1
+ export interface QuestionInputProps {
2
+ /** When true, Choice renders with ChoiceIndicator (default true). */
3
+ showChoiceIndicator?: boolean;
4
+ /** Custom instruction; when omitted, Instruction uses default for question type. */
5
+ instruction?: string;
6
+ }
7
+ /** Renders the appropriate input for the current question type (choices, text, match pairs, order, sentence builder) with optional Instruction. */
8
+ export declare const QuestionInput: ({ showChoiceIndicator, instruction, }: QuestionInputProps) => import("react/jsx-runtime").JSX.Element | null;
9
+ //# sourceMappingURL=QuestionInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuestionInput.d.ts","sourceRoot":"","sources":["../../src/components/QuestionInput.tsx"],"names":[],"mappings":"AASA,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,mJAAmJ;AACnJ,eAAO,MAAM,aAAa,GAAI,uCAG3B,kBAAkB,mDAuDpB,CAAC"}