@hydralms/components 0.1.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 (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -0
  3. package/dist/assessment-toolbar/assessment-toolbar.d.ts +2 -0
  4. package/dist/assessment-toolbar/index.d.ts +4 -0
  5. package/dist/assessment-toolbar/question-navigator.d.ts +2 -0
  6. package/dist/assessment-toolbar/timer-display.d.ts +2 -0
  7. package/dist/assessment-toolbar/types.d.ts +89 -0
  8. package/dist/common/confirm-dialog.d.ts +2 -0
  9. package/dist/common/due-date-display.d.ts +2 -0
  10. package/dist/common/empty-state.d.ts +2 -0
  11. package/dist/common/index.d.ts +6 -0
  12. package/dist/common/search-input.d.ts +2 -0
  13. package/dist/common/status-badge.d.ts +2 -0
  14. package/dist/common/types.d.ts +124 -0
  15. package/dist/components.css +1 -0
  16. package/dist/content/content-block.d.ts +2 -0
  17. package/dist/content/file-upload-zone.d.ts +2 -0
  18. package/dist/content/index.d.ts +3 -0
  19. package/dist/content/types.d.ts +95 -0
  20. package/dist/curriculum/curriculum-item.d.ts +2 -0
  21. package/dist/curriculum/curriculum-tree.d.ts +2 -0
  22. package/dist/curriculum/index.d.ts +4 -0
  23. package/dist/curriculum/learning-object-icon.d.ts +2 -0
  24. package/dist/curriculum/types.d.ts +79 -0
  25. package/dist/feedback/feedback-banner.d.ts +2 -0
  26. package/dist/feedback/index.d.ts +4 -0
  27. package/dist/feedback/likert-scale.d.ts +2 -0
  28. package/dist/feedback/star-rating.d.ts +2 -0
  29. package/dist/feedback/types.d.ts +83 -0
  30. package/dist/flashcards/flashcard-deck.d.ts +2 -0
  31. package/dist/flashcards/flashcard.d.ts +2 -0
  32. package/dist/flashcards/index.d.ts +3 -0
  33. package/dist/flashcards/types.d.ts +58 -0
  34. package/dist/index.cjs +1 -0
  35. package/dist/index.d.ts +13 -0
  36. package/dist/index.js +159 -0
  37. package/dist/lib/utils.d.ts +2 -0
  38. package/dist/progress/grade-indicator.d.ts +2 -0
  39. package/dist/progress/index.d.ts +4 -0
  40. package/dist/progress/progress-ring.d.ts +2 -0
  41. package/dist/progress/stat-card.d.ts +2 -0
  42. package/dist/progress/types.d.ts +73 -0
  43. package/dist/provider/HydraProvider.d.ts +9 -0
  44. package/dist/provider/index.d.ts +2 -0
  45. package/dist/questions/choice.d.ts +11 -0
  46. package/dist/questions/essay.d.ts +11 -0
  47. package/dist/questions/fill-in-the-blank.d.ts +11 -0
  48. package/dist/questions/index.d.ts +7 -0
  49. package/dist/questions/multiple-choice.d.ts +11 -0
  50. package/dist/questions/question-renderer.d.ts +12 -0
  51. package/dist/questions/true-false.d.ts +11 -0
  52. package/dist/questions/types.d.ts +47 -0
  53. package/dist/sections/AnnouncementFeed/AnnouncementFeed.d.ts +2 -0
  54. package/dist/sections/AnnouncementFeed/types.d.ts +52 -0
  55. package/dist/sections/AssessmentReview/AssessmentReview.d.ts +2 -0
  56. package/dist/sections/AssessmentReview/types.d.ts +58 -0
  57. package/dist/sections/AssignmentSubmission/AssignmentSubmission.d.ts +2 -0
  58. package/dist/sections/AssignmentSubmission/types.d.ts +65 -0
  59. package/dist/sections/CertificateViewer/CertificateViewer.d.ts +2 -0
  60. package/dist/sections/CertificateViewer/types.d.ts +47 -0
  61. package/dist/sections/CourseOutline/CourseOutline.d.ts +2 -0
  62. package/dist/sections/CourseOutline/types.d.ts +49 -0
  63. package/dist/sections/DiscussionThread/DiscussionThread.d.ts +2 -0
  64. package/dist/sections/DiscussionThread/types.d.ts +74 -0
  65. package/dist/sections/ExamSession/ExamSession.d.ts +2 -0
  66. package/dist/sections/ExamSession/types.d.ts +62 -0
  67. package/dist/sections/FlashcardStudySession/FlashcardStudySession.d.ts +2 -0
  68. package/dist/sections/FlashcardStudySession/types.d.ts +40 -0
  69. package/dist/sections/GradebookTable/GradebookTable.d.ts +2 -0
  70. package/dist/sections/GradebookTable/types.d.ts +71 -0
  71. package/dist/sections/LecturePlayer/LecturePlayer.d.ts +2 -0
  72. package/dist/sections/LecturePlayer/types.d.ts +47 -0
  73. package/dist/sections/LessonPage/LessonPage.d.ts +2 -0
  74. package/dist/sections/LessonPage/types.d.ts +40 -0
  75. package/dist/sections/PracticeQuiz/PracticeQuiz.d.ts +2 -0
  76. package/dist/sections/PracticeQuiz/types.d.ts +42 -0
  77. package/dist/sections/ProgressDashboard/ProgressDashboard.d.ts +2 -0
  78. package/dist/sections/ProgressDashboard/types.d.ts +73 -0
  79. package/dist/sections/QuizSession/QuizSession.d.ts +2 -0
  80. package/dist/sections/QuizSession/types.d.ts +46 -0
  81. package/dist/sections/ResourceLibrary/ResourceLibrary.d.ts +2 -0
  82. package/dist/sections/ResourceLibrary/types.d.ts +58 -0
  83. package/dist/sections/ScrollableQuiz/ScrollableQuiz.d.ts +2 -0
  84. package/dist/sections/ScrollableQuiz/types.d.ts +42 -0
  85. package/dist/sections/SurveyForm/SurveyForm.d.ts +2 -0
  86. package/dist/sections/SurveyForm/types.d.ts +69 -0
  87. package/dist/sections/index.d.ts +34 -0
  88. package/dist/sections.cjs +1 -0
  89. package/dist/sections.js +1898 -0
  90. package/dist/social/index.d.ts +3 -0
  91. package/dist/social/post-card.d.ts +2 -0
  92. package/dist/social/types.d.ts +59 -0
  93. package/dist/social/user-avatar.d.ts +2 -0
  94. package/dist/table-CW4_BYny.js +9869 -0
  95. package/dist/table-DSBBqb9X.cjs +56 -0
  96. package/dist/ui/alert-dialog.d.ts +14 -0
  97. package/dist/ui/alert.d.ts +9 -0
  98. package/dist/ui/avatar.d.ts +5 -0
  99. package/dist/ui/badge.d.ts +9 -0
  100. package/dist/ui/button.d.ts +10 -0
  101. package/dist/ui/card.d.ts +9 -0
  102. package/dist/ui/index.d.ts +15 -0
  103. package/dist/ui/input.d.ts +3 -0
  104. package/dist/ui/progress.d.ts +13 -0
  105. package/dist/ui/separator.d.ts +6 -0
  106. package/dist/ui/skeleton.d.ts +3 -0
  107. package/dist/ui/slot.d.ts +8 -0
  108. package/dist/ui/table.d.ts +10 -0
  109. package/dist/ui/tabs.d.ts +7 -0
  110. package/dist/ui/textarea.d.ts +3 -0
  111. package/dist/ui/tooltip.d.ts +8 -0
  112. package/dist/utils/debounce.d.ts +1 -0
  113. package/dist/utils/format-duration.d.ts +2 -0
  114. package/dist/video/index.d.ts +2 -0
  115. package/dist/video/types.d.ts +37 -0
  116. package/dist/video/video-player.d.ts +2 -0
  117. package/package.json +94 -0
@@ -0,0 +1,47 @@
1
+ export type QuestionTypeEnum = "multiple_choice" | "choice" | "true_false" | "fill_in_the_blank" | "essay";
2
+ export interface AnswerOption {
3
+ uid: string;
4
+ content: string;
5
+ explanation?: string;
6
+ isCorrect?: boolean;
7
+ sequence: number;
8
+ }
9
+ export interface SessionAnswer {
10
+ uid: string;
11
+ answerUid: string;
12
+ content?: string;
13
+ confidence?: string;
14
+ }
15
+ export interface QuestionData {
16
+ uid: string;
17
+ type: QuestionTypeEnum;
18
+ content: string;
19
+ explanation?: string;
20
+ answers?: AnswerOption[];
21
+ }
22
+ /**
23
+ * Shared props interface for all question type components.
24
+ *
25
+ * @example
26
+ * <QuestionRenderer
27
+ * question={{ uid: "q1", type: "choice", content: "What is JSX?", answers: [...] }}
28
+ * onAnswer={(answers) => saveAnswer(answers)}
29
+ * />
30
+ */
31
+ export interface QuestionProps {
32
+ /** The question data to render */
33
+ question: QuestionData;
34
+ /** Current user answers for this question */
35
+ sessionAnswers?: SessionAnswer[];
36
+ /** Called when the user selects or changes an answer */
37
+ onAnswer?: (answers: {
38
+ uid: string;
39
+ content?: string;
40
+ }[]) => void;
41
+ /** When true, disables all input interactions */
42
+ readOnly?: boolean;
43
+ /** When true, highlights correct/incorrect answers */
44
+ showCorrectAnswers?: boolean;
45
+ /** When true, disables inputs without showing review state */
46
+ disabled?: boolean;
47
+ }
@@ -0,0 +1,2 @@
1
+ import { AnnouncementFeedProps } from './types';
2
+ export declare function AnnouncementFeed({ announcements, onMarkRead, onSelect, showAvatars, previewLines, emptyMessage, readOnly, className, style, }: AnnouncementFeedProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * AnnouncementFeed section — a chronological announcement feed.
3
+ *
4
+ * Displays course announcements with pinned posts, read/unread
5
+ * tracking, expandable content, and author avatars.
6
+ *
7
+ * @example
8
+ * <AnnouncementFeed
9
+ * announcements={announcements}
10
+ * onMarkRead={(uid) => markRead(uid)}
11
+ * />
12
+ */
13
+ export interface AnnouncementFeedProps {
14
+ /** Announcements sorted by recency (newest first) */
15
+ announcements: Announcement[];
16
+ /** Called when the user marks an announcement as read */
17
+ onMarkRead?: (announcementUid: string) => void;
18
+ /** Called when the user clicks an announcement */
19
+ onSelect?: (announcement: Announcement) => void;
20
+ /** Whether to show author avatars */
21
+ showAvatars?: boolean;
22
+ /** Max lines before truncating with "Read more" */
23
+ previewLines?: number;
24
+ /** Empty state message */
25
+ emptyMessage?: string;
26
+ /** When true, disables interactions */
27
+ readOnly?: boolean;
28
+ /** CSS class name for the root element */
29
+ className?: string;
30
+ /** Inline styles for the root element */
31
+ style?: React.CSSProperties;
32
+ }
33
+ export interface Announcement {
34
+ /** Unique identifier */
35
+ uid: string;
36
+ /** Announcement title */
37
+ title: string;
38
+ /** Announcement body content */
39
+ content: string;
40
+ /** Author information */
41
+ author: {
42
+ displayName: string;
43
+ avatarUrl?: string;
44
+ role?: string;
45
+ };
46
+ /** Creation timestamp as ISO string */
47
+ createdAt: string;
48
+ /** Whether this announcement is pinned */
49
+ isPinned?: boolean;
50
+ /** Whether the current user has read this */
51
+ isRead?: boolean;
52
+ }
@@ -0,0 +1,2 @@
1
+ import { AssessmentReviewProps } from './types';
2
+ export declare function AssessmentReview({ questions, sessionAnswers, score, questionGroups, showCorrectAnswers, className, style, }: AssessmentReviewProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,58 @@
1
+ import { QuestionData, SessionAnswer } from '../../questions/types';
2
+ /**
3
+ * AssessmentReview section — read-only review of a completed assessment.
4
+ *
5
+ * Renders all questions in review mode with correct/incorrect highlighting
6
+ * and an optional score summary header. Supports optional grouping of
7
+ * questions by section label.
8
+ *
9
+ * @example
10
+ * <AssessmentReview
11
+ * questions={questions}
12
+ * sessionAnswers={submittedAnswers}
13
+ * score={{ correct: 8, total: 10, passed: true, passingScore: 70 }}
14
+ * />
15
+ */
16
+ export interface AssessmentReviewProps {
17
+ /** All questions that were in the assessment */
18
+ questions: QuestionData[];
19
+ /** The user's submitted answers */
20
+ sessionAnswers: SessionAnswer[];
21
+ /**
22
+ * Score metadata to display in the summary header.
23
+ * If omitted, the score header is not rendered.
24
+ */
25
+ score?: AssessmentScore;
26
+ /**
27
+ * Optional grouping: renders questions under section headings.
28
+ * Questions not referenced in any group are rendered last without a heading.
29
+ */
30
+ questionGroups?: AssessmentReviewGroup[];
31
+ /**
32
+ * Whether to show correct/incorrect answer highlighting on each question.
33
+ * @default true
34
+ */
35
+ showCorrectAnswers?: boolean;
36
+ /** CSS class name for the root element */
37
+ className?: string;
38
+ /** Inline styles for the root element */
39
+ style?: React.CSSProperties;
40
+ }
41
+ export interface AssessmentScore {
42
+ /** Number of correct answers */
43
+ correct: number;
44
+ /** Total number of questions */
45
+ total: number;
46
+ /** Optional pre-computed percentage (falls back to correct/total * 100) */
47
+ percentage?: number;
48
+ /** Whether the user passed */
49
+ passed?: boolean;
50
+ /** Passing threshold as a percentage (e.g. 70 means 70%) */
51
+ passingScore?: number;
52
+ }
53
+ export interface AssessmentReviewGroup {
54
+ /** Group label displayed as a section heading */
55
+ label: string;
56
+ /** UIDs of questions belonging to this group, in display order */
57
+ questionUids: string[];
58
+ }
@@ -0,0 +1,2 @@
1
+ import { AssignmentSubmissionProps } from './types';
2
+ export declare function AssignmentSubmission({ title, instructions, dueDate, maxScore, status, submissionTypes, existingSubmission, fileConstraints, onSubmit, onSaveDraft, grade, isSubmitting, readOnly, className, style, }: AssignmentSubmissionProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,65 @@
1
+ import { ReactNode } from 'react';
2
+ /**
3
+ * AssignmentSubmission section — an assignment detail and submission view.
4
+ *
5
+ * Displays assignment instructions, due date, and submission status.
6
+ * Supports file upload, text, and URL submission types with draft saving
7
+ * and grade/feedback display.
8
+ *
9
+ * @example
10
+ * <AssignmentSubmission
11
+ * title="Week 3 Essay"
12
+ * instructions={<p>Write a 500-word essay on React.</p>}
13
+ * dueDate="2025-03-15T23:59:00Z"
14
+ * status="not_started"
15
+ * submissionTypes={["text", "file"]}
16
+ * onSubmit={(data) => submitAssignment(data)}
17
+ * />
18
+ */
19
+ export interface AssignmentSubmissionProps {
20
+ /** Assignment title */
21
+ title: string;
22
+ /** Assignment instructions (rich content) */
23
+ instructions: ReactNode;
24
+ /** Due date as ISO string */
25
+ dueDate?: string;
26
+ /** Maximum score points */
27
+ maxScore?: number;
28
+ /** Current submission status */
29
+ status: "not_started" | "draft" | "submitted" | "late" | "graded" | "resubmit";
30
+ /** Allowed submission types */
31
+ submissionTypes: ("text" | "file" | "url")[];
32
+ /** Existing submission data for editing/viewing */
33
+ existingSubmission?: SubmissionData;
34
+ /** File upload constraints */
35
+ fileConstraints?: {
36
+ maxFiles?: number;
37
+ maxSizeMB?: number;
38
+ acceptedTypes?: string;
39
+ };
40
+ /** Called on final submission */
41
+ onSubmit: (submission: SubmissionData) => void;
42
+ /** Called on draft save */
43
+ onSaveDraft?: (submission: SubmissionData) => void;
44
+ /** Grade data when already graded */
45
+ grade?: {
46
+ score: number;
47
+ feedback?: ReactNode;
48
+ };
49
+ /** Whether the submit action is in flight */
50
+ isSubmitting?: boolean;
51
+ /** When true, disables all interactions */
52
+ readOnly?: boolean;
53
+ /** CSS class name for the root element */
54
+ className?: string;
55
+ /** Inline styles for the root element */
56
+ style?: React.CSSProperties;
57
+ }
58
+ export interface SubmissionData {
59
+ /** Text content */
60
+ textContent?: string;
61
+ /** Uploaded files */
62
+ files?: File[];
63
+ /** URL submission */
64
+ url?: string;
65
+ }
@@ -0,0 +1,2 @@
1
+ import { CertificateViewerProps } from './types';
2
+ export declare function CertificateViewer({ recipientName, courseTitle, completionDate, organizationName, organizationLogo, signatory, certificateId, variant, showActions, onPrint, onDownload, className, style, }: CertificateViewerProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * CertificateViewer section — a printable completion certificate.
3
+ *
4
+ * Displays a certificate with recipient details, course information,
5
+ * signatory, and verification ID. Supports three visual variants:
6
+ * classic, modern, and minimal.
7
+ *
8
+ * @example
9
+ * <CertificateViewer
10
+ * recipientName="Jane Smith"
11
+ * courseTitle="Advanced React"
12
+ * completionDate="2025-03-01"
13
+ * organizationName="HydraLMS Academy"
14
+ * variant="modern"
15
+ * />
16
+ */
17
+ export interface CertificateViewerProps {
18
+ /** Recipient's full name */
19
+ recipientName: string;
20
+ /** Course or program title */
21
+ courseTitle: string;
22
+ /** Completion date as ISO string or human-readable string */
23
+ completionDate: string;
24
+ /** Issuing organization name */
25
+ organizationName: string;
26
+ /** Organization logo URL */
27
+ organizationLogo?: string;
28
+ /** Signatory information */
29
+ signatory?: {
30
+ name: string;
31
+ title: string;
32
+ };
33
+ /** Unique certificate ID */
34
+ certificateId?: string;
35
+ /** Certificate template variant */
36
+ variant?: "classic" | "modern" | "minimal";
37
+ /** Whether to show print/download actions */
38
+ showActions?: boolean;
39
+ /** Called when print is triggered */
40
+ onPrint?: () => void;
41
+ /** Called when download is triggered */
42
+ onDownload?: () => void;
43
+ /** CSS class name for the root element */
44
+ className?: string;
45
+ /** Inline styles for the root element */
46
+ style?: React.CSSProperties;
47
+ }
@@ -0,0 +1,2 @@
1
+ import { CourseOutlineProps } from './types';
2
+ export declare function CourseOutline({ items, progress, courseTitle, activeItemUid, onItemClick, showOverallProgress, showDuration, showIcons, readOnly, className, style, }: CourseOutlineProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,49 @@
1
+ import { CurriculumItem, CurriculumItemProgress } from '../../curriculum/types';
2
+ /**
3
+ * CourseOutline section — a sidebar-ready course navigation panel.
4
+ *
5
+ * Wraps CurriculumTree with a course title header and an optional overall
6
+ * progress bar. Ready to drop into a sidebar layout without extra markup.
7
+ *
8
+ * @example
9
+ * <CourseOutline
10
+ * items={curriculum}
11
+ * progress={userProgress}
12
+ * courseTitle="Introduction to React"
13
+ * activeItemUid={currentLessonUid}
14
+ * onItemClick={(item) => navigate(item.uid)}
15
+ * />
16
+ */
17
+ export interface CourseOutlineProps {
18
+ /** The course curriculum items */
19
+ items: CurriculumItem[];
20
+ /** User progress data */
21
+ progress?: CurriculumItemProgress[];
22
+ /** Course title displayed in the header */
23
+ courseTitle?: string;
24
+ /** UID of the currently active/playing item */
25
+ activeItemUid?: string;
26
+ /** Called when the user clicks a leaf curriculum item */
27
+ onItemClick?: (item: CurriculumItem) => void;
28
+ /**
29
+ * Whether to show a linear progress bar summarising overall completion.
30
+ * @default true
31
+ */
32
+ showOverallProgress?: boolean;
33
+ /**
34
+ * Whether to show per-item duration labels in the tree.
35
+ * @default true
36
+ */
37
+ showDuration?: boolean;
38
+ /**
39
+ * Whether to show type icons per item.
40
+ * @default true
41
+ */
42
+ showIcons?: boolean;
43
+ /** When true, disables all click interactions */
44
+ readOnly?: boolean;
45
+ /** CSS class name for the root element */
46
+ className?: string;
47
+ /** Inline styles for the root element */
48
+ style?: React.CSSProperties;
49
+ }
@@ -0,0 +1,2 @@
1
+ import { DiscussionThreadProps } from './types';
2
+ export declare function DiscussionThread({ title, rootPost, replies, currentUser, onReply, onToggleLike, onMarkAnswer, maxDepth, allowReplies, sortOrder, readOnly, className, style, }: DiscussionThreadProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * DiscussionThread section — a threaded discussion forum.
3
+ *
4
+ * Supports nested replies, author avatars, timestamps, like/unlike,
5
+ * and mark-as-answer for Q&A threads. Replies nest up to a
6
+ * configurable maximum depth.
7
+ *
8
+ * @example
9
+ * <DiscussionThread
10
+ * title="How do React hooks work?"
11
+ * rootPost={rootPost}
12
+ * replies={replies}
13
+ * currentUser={user}
14
+ * onReply={(parentUid, content) => postReply(parentUid, content)}
15
+ * />
16
+ */
17
+ export interface DiscussionThreadProps {
18
+ /** Thread title */
19
+ title: string;
20
+ /** The initial/root post */
21
+ rootPost: DiscussionPost;
22
+ /** All replies (flat array — parentUid determines nesting) */
23
+ replies: DiscussionPost[];
24
+ /** The currently authenticated user */
25
+ currentUser: DiscussionUser;
26
+ /** Called when the user submits a reply */
27
+ onReply: (parentUid: string, content: string) => void;
28
+ /** Called when the user toggles a like */
29
+ onToggleLike?: (postUid: string) => void;
30
+ /** Called when an instructor marks a post as the answer */
31
+ onMarkAnswer?: (postUid: string) => void;
32
+ /** Maximum nesting depth before replies flatten */
33
+ maxDepth?: number;
34
+ /** Whether new replies are allowed */
35
+ allowReplies?: boolean;
36
+ /** Sort order for top-level replies */
37
+ sortOrder?: "newest" | "oldest" | "most_liked";
38
+ /** When true, disables interactions */
39
+ readOnly?: boolean;
40
+ /** CSS class name for the root element */
41
+ className?: string;
42
+ /** Inline styles for the root element */
43
+ style?: React.CSSProperties;
44
+ }
45
+ export interface DiscussionPost {
46
+ /** Unique identifier */
47
+ uid: string;
48
+ /** Parent post UID — null for root post */
49
+ parentUid: string | null;
50
+ /** Post author */
51
+ author: DiscussionUser;
52
+ /** Post body content */
53
+ content: string;
54
+ /** Creation timestamp */
55
+ createdAt: string;
56
+ /** Last update timestamp */
57
+ updatedAt?: string;
58
+ /** Number of likes */
59
+ likeCount: number;
60
+ /** Whether the current user has liked this post */
61
+ isLikedByCurrentUser: boolean;
62
+ /** Whether this post is marked as the answer */
63
+ isAnswer?: boolean;
64
+ }
65
+ export interface DiscussionUser {
66
+ /** Unique identifier */
67
+ uid: string;
68
+ /** Display name */
69
+ displayName: string;
70
+ /** Avatar image URL */
71
+ avatarUrl?: string;
72
+ /** User role */
73
+ role?: "student" | "instructor" | "ta" | "admin";
74
+ }
@@ -0,0 +1,2 @@
1
+ import { ExamSessionProps } from './types';
2
+ export declare function ExamSession({ questions, initialAnswers, onSubmit, onAnswerChange, timeLimitSeconds, timeElapsedSeconds, autoSubmitOnTimeout, timeWarningThreshold, allowBackNavigation, confirmBeforeSubmit, examTitle, instructions, isSubmitting, readOnly, className, style, }: ExamSessionProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,62 @@
1
+ import { ReactNode } from 'react';
2
+ import { QuestionData, SessionAnswer } from '../../questions/types';
3
+ /**
4
+ * ExamSession section — a formal timed exam experience.
5
+ *
6
+ * Provides enforced time limits with auto-submit on timeout, time warnings,
7
+ * optional back-navigation restriction, and a confirmation dialog before
8
+ * final submission.
9
+ *
10
+ * @example
11
+ * <ExamSession
12
+ * questions={questions}
13
+ * timeLimitSeconds={3600}
14
+ * timeElapsedSeconds={elapsed}
15
+ * onSubmit={(answers, meta) => submitExam(answers, meta)}
16
+ * examTitle="Final Exam"
17
+ * />
18
+ */
19
+ export interface ExamSessionProps {
20
+ /** Ordered list of questions */
21
+ questions: QuestionData[];
22
+ /** Pre-populated answers for resuming */
23
+ initialAnswers?: SessionAnswer[];
24
+ /** Called on submission with answers and metadata */
25
+ onSubmit: (answers: SessionAnswer[], metadata: ExamSubmitMetadata) => void;
26
+ /** Called whenever the user changes an answer */
27
+ onAnswerChange?: (answers: SessionAnswer[]) => void;
28
+ /** Time limit in seconds (required for exam mode) */
29
+ timeLimitSeconds: number;
30
+ /** Current elapsed time in seconds (controlled externally) */
31
+ timeElapsedSeconds: number;
32
+ /** Auto-submit when time runs out */
33
+ autoSubmitOnTimeout?: boolean;
34
+ /** Seconds remaining at which to show a time warning */
35
+ timeWarningThreshold?: number;
36
+ /** Whether the user can go back to previous questions */
37
+ allowBackNavigation?: boolean;
38
+ /** Show a confirmation dialog before final submission */
39
+ confirmBeforeSubmit?: boolean;
40
+ /** Title shown in the exam header */
41
+ examTitle?: string;
42
+ /** Instructions displayed above the first question */
43
+ instructions?: ReactNode;
44
+ /** Whether the submit action is in flight */
45
+ isSubmitting?: boolean;
46
+ /** When true, all inputs are disabled */
47
+ readOnly?: boolean;
48
+ /** CSS class name for the root element */
49
+ className?: string;
50
+ /** Inline styles for the root element */
51
+ style?: React.CSSProperties;
52
+ }
53
+ export interface ExamSubmitMetadata {
54
+ /** Total time the user spent in seconds */
55
+ timeElapsedSeconds: number;
56
+ /** Whether the submission was triggered by timeout */
57
+ wasAutoSubmitted: boolean;
58
+ /** Number of questions the user answered */
59
+ answeredCount: number;
60
+ /** Total questions in the exam */
61
+ totalQuestions: number;
62
+ }
@@ -0,0 +1,2 @@
1
+ import { FlashcardStudySessionProps } from './types';
2
+ export declare function FlashcardStudySession({ cards, title, description, shuffled, onComplete, readOnly, className, style, }: FlashcardStudySessionProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,40 @@
1
+ import { FlashcardData } from '../../flashcards/types';
2
+ /**
3
+ * FlashcardStudySession section — a complete flashcard study experience.
4
+ *
5
+ * Wraps FlashcardDeck with a session header and a completion screen
6
+ * (checkmark, stats, "Study Again" button). Drop in your cards and an
7
+ * optional onComplete callback to get a ready-to-use study session.
8
+ *
9
+ * @example
10
+ * <FlashcardStudySession
11
+ * cards={cards}
12
+ * title="React Fundamentals"
13
+ * shuffled
14
+ * onComplete={(stats) => trackStudySession(stats)}
15
+ * />
16
+ */
17
+ export interface FlashcardStudySessionProps {
18
+ /** The cards to study */
19
+ cards: FlashcardData[];
20
+ /** Session title displayed in the header */
21
+ title?: string;
22
+ /** Optional subtitle / description */
23
+ description?: string;
24
+ /** Whether to shuffle cards at session start — passed through to FlashcardDeck */
25
+ shuffled?: boolean;
26
+ /** Called when the user completes the deck */
27
+ onComplete?: (stats: FlashcardSessionStats) => void;
28
+ /** When true, disables card flipping */
29
+ readOnly?: boolean;
30
+ /** CSS class name for the root element */
31
+ className?: string;
32
+ /** Inline styles for the root element */
33
+ style?: React.CSSProperties;
34
+ }
35
+ export interface FlashcardSessionStats {
36
+ /** Total number of cards in the deck */
37
+ totalCards: number;
38
+ /** Whether the deck was shuffled */
39
+ wasShuffled: boolean;
40
+ }
@@ -0,0 +1,2 @@
1
+ import { GradebookTableProps } from './types';
2
+ export declare function GradebookTable({ items, categories, overallGrade, showWeights, showCategoryTotals, onItemClick, readOnly, className, style, }: GradebookTableProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * GradebookTable section — a tabular student gradebook.
3
+ *
4
+ * Displays assignment scores, weights, and an overall computed grade
5
+ * with sortable columns and optional category grouping.
6
+ *
7
+ * @example
8
+ * <GradebookTable
9
+ * items={gradeItems}
10
+ * categories={gradeCategories}
11
+ * overallGrade={{ percentage: 87, letterGrade: "B+", pointsEarned: 435, pointsPossible: 500 }}
12
+ * />
13
+ */
14
+ export interface GradebookTableProps {
15
+ /** Grade items (assignments, quizzes, etc.) */
16
+ items: GradeItem[];
17
+ /** Optional category grouping */
18
+ categories?: GradeCategory[];
19
+ /** Overall course grade summary */
20
+ overallGrade?: OverallGrade;
21
+ /** Whether to show the weight column */
22
+ showWeights?: boolean;
23
+ /** Whether to show category subtotals */
24
+ showCategoryTotals?: boolean;
25
+ /** Called when the user clicks a grade item row */
26
+ onItemClick?: (item: GradeItem) => void;
27
+ /** When true, disables interactions */
28
+ readOnly?: boolean;
29
+ /** CSS class name for the root element */
30
+ className?: string;
31
+ /** Inline styles for the root element */
32
+ style?: React.CSSProperties;
33
+ }
34
+ export interface GradeItem {
35
+ /** Unique identifier */
36
+ uid: string;
37
+ /** Assignment name */
38
+ name: string;
39
+ /** Category UID for grouping */
40
+ categoryUid?: string;
41
+ /** Score earned — null if not yet graded */
42
+ score: number | null;
43
+ /** Maximum possible score */
44
+ maxScore: number;
45
+ /** Weight as a percentage */
46
+ weight?: number;
47
+ /** Due date as ISO string */
48
+ dueDate?: string;
49
+ /** Submission date */
50
+ submittedDate?: string;
51
+ /** Item status */
52
+ status: "graded" | "submitted" | "pending" | "missing" | "excused";
53
+ }
54
+ export interface GradeCategory {
55
+ /** Unique identifier */
56
+ uid: string;
57
+ /** Category name (e.g. "Assignments", "Quizzes") */
58
+ name: string;
59
+ /** Category weight percentage */
60
+ weight?: number;
61
+ }
62
+ export interface OverallGrade {
63
+ /** Overall percentage */
64
+ percentage: number;
65
+ /** Letter grade */
66
+ letterGrade?: string;
67
+ /** Points earned */
68
+ pointsEarned: number;
69
+ /** Points possible */
70
+ pointsPossible: number;
71
+ }
@@ -0,0 +1,2 @@
1
+ import { LecturePlayerProps } from './types';
2
+ export declare function LecturePlayer({ video, notes, layout, notesPanelWidth, notesPanelHeight, className, style, }: LecturePlayerProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,47 @@
1
+ import { ReactNode } from 'react';
2
+ import { VideoPlayerProps } from '../../video/types';
3
+ /**
4
+ * LecturePlayer section — video player paired with an optional notes/transcript panel.
5
+ *
6
+ * Supports horizontal (side-by-side) and vertical (stacked) layouts with
7
+ * configurable panel dimensions. When notes are omitted, the video fills
8
+ * the full container.
9
+ *
10
+ * @example
11
+ * <LecturePlayer
12
+ * video={{ src: "https://example.com/lecture.mp4", title: "React Hooks" }}
13
+ * notes={<TranscriptPanel />}
14
+ * layout="horizontal"
15
+ * />
16
+ */
17
+ export interface LecturePlayerProps {
18
+ /** Props passed directly to the underlying VideoPlayer */
19
+ video: VideoPlayerProps;
20
+ /**
21
+ * Content rendered in the companion panel.
22
+ * Can be any ReactNode — transcript, MDX, note editor, etc.
23
+ * If omitted, the player fills the full container with no panel.
24
+ */
25
+ notes?: ReactNode;
26
+ /**
27
+ * Layout direction of the two-pane split.
28
+ * - "horizontal": video left, notes right
29
+ * - "vertical": video top, notes bottom
30
+ * @default "horizontal"
31
+ */
32
+ layout?: "horizontal" | "vertical";
33
+ /**
34
+ * Width of the notes panel when layout is "horizontal".
35
+ * @default "340px"
36
+ */
37
+ notesPanelWidth?: string | number;
38
+ /**
39
+ * Height of the notes panel when layout is "vertical".
40
+ * @default "240px"
41
+ */
42
+ notesPanelHeight?: string | number;
43
+ /** CSS class name for the root element */
44
+ className?: string;
45
+ /** Inline styles for the root element */
46
+ style?: React.CSSProperties;
47
+ }
@@ -0,0 +1,2 @@
1
+ import { LessonPageProps } from './types';
2
+ export declare function LessonPage({ title, blocks, isCompleted, onMarkComplete, onNextLesson, nextLessonTitle, estimatedDuration, showDuration, readOnly, className, style, }: LessonPageProps): import("react/jsx-runtime").JSX.Element;