@hydralms/components 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ForumBoard-CHXU3mjC.js +2207 -0
- package/dist/ForumBoard-d1w5-r6n.cjs +1 -0
- package/dist/assessment-toolbar/assessment-toolbar.d.ts +1 -1
- package/dist/assessment-toolbar/index.d.ts +5 -1
- package/dist/assessment-toolbar/question-header-bar.d.ts +2 -0
- package/dist/assessment-toolbar/question-materials-drawer.d.ts +2 -0
- package/dist/assessment-toolbar/question-navigator.d.ts +1 -1
- package/dist/assessment-toolbar/types.d.ts +52 -4
- package/dist/assessment-toolbar/use-countdown.d.ts +43 -0
- package/dist/common/index.d.ts +2 -1
- package/dist/common/stepper.d.ts +6 -0
- package/dist/common/types.d.ts +37 -0
- package/dist/components.css +1 -1
- package/dist/content/attachment-list.d.ts +6 -0
- package/dist/content/content-block.d.ts +1 -1
- package/dist/content/index.d.ts +2 -1
- package/dist/content/types.d.ts +39 -0
- package/dist/curriculum/curriculum-item.d.ts +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +551 -312
- package/dist/modules/AssignmentModule/AssignmentModule.d.ts +8 -0
- package/dist/modules/AssignmentModule/types.d.ts +65 -0
- package/dist/modules/CertificateModule/CertificateModule.d.ts +9 -0
- package/dist/modules/CertificateModule/types.d.ts +49 -0
- package/dist/modules/DiscussionModule/DiscussionModule.d.ts +8 -0
- package/dist/modules/DiscussionModule/types.d.ts +47 -0
- package/dist/modules/ExamModule/ExamModule.d.ts +8 -0
- package/dist/modules/ExamModule/types.d.ts +64 -0
- package/dist/modules/GradeCenterModule/GradeCenterModule.d.ts +9 -0
- package/dist/modules/GradeCenterModule/types.d.ts +54 -0
- package/dist/modules/QuizModule/QuizModule.d.ts +1 -1
- package/dist/modules/QuizModule/types.d.ts +6 -1
- package/dist/modules/SurveyModule/SurveyModule.d.ts +7 -0
- package/dist/modules/SurveyModule/types.d.ts +49 -0
- package/dist/modules/index.d.ts +12 -0
- package/dist/modules.cjs +1 -0
- package/dist/modules.js +1422 -0
- package/dist/progress/achievement-badge.d.ts +6 -0
- package/dist/progress/activity-timeline.d.ts +6 -0
- package/dist/progress/index.d.ts +4 -1
- package/dist/progress/stat-card.d.ts +1 -1
- package/dist/progress/streak-badge.d.ts +6 -0
- package/dist/progress/types.d.ts +97 -0
- package/dist/questions/essay.d.ts +1 -1
- package/dist/questions/hotspot.d.ts +21 -0
- package/dist/questions/index.d.ts +9 -1
- package/dist/questions/inline-choice.d.ts +21 -0
- package/dist/questions/matching.d.ts +22 -0
- package/dist/questions/numeric.d.ts +11 -0
- package/dist/questions/ordering.d.ts +12 -0
- package/dist/questions/scenario.d.ts +23 -0
- package/dist/questions/scoring.d.ts +22 -0
- package/dist/questions/spreadsheet.d.ts +29 -0
- package/dist/questions/types.d.ts +106 -1
- package/dist/questions/use-drag-reorder.d.ts +17 -0
- package/dist/sections/CertificateViewer/types.d.ts +7 -5
- package/dist/sections/ExamSession/ExamSession.d.ts +1 -1
- package/dist/sections/ExamSession/types.d.ts +6 -1
- package/dist/sections/ForumBoard/ForumBoard.d.ts +8 -0
- package/dist/sections/ForumBoard/types.d.ts +64 -0
- package/dist/sections/QuizSession/QuizSession.d.ts +1 -1
- package/dist/sections/QuizSession/types.d.ts +6 -1
- package/dist/sections/RequirementsChecklist/RequirementsChecklist.d.ts +8 -0
- package/dist/sections/RequirementsChecklist/types.d.ts +37 -0
- package/dist/sections/RubricView/RubricView.d.ts +9 -0
- package/dist/sections/RubricView/types.d.ts +50 -0
- package/dist/sections/index.d.ts +7 -1
- package/dist/sections.cjs +1 -1
- package/dist/sections.js +250 -1715
- package/dist/social/post-card.d.ts +1 -1
- package/dist/tabs-DRM2Iq_J.cjs +172 -0
- package/dist/tabs-Wf3h_Cx3.js +21580 -0
- package/dist/ui/alert.d.ts +1 -1
- package/dist/ui/badge.d.ts +1 -1
- package/dist/ui/button.d.ts +1 -1
- package/dist/ui/drawer.d.ts +84 -0
- package/dist/ui/index.d.ts +3 -0
- package/dist/ui/progress.d.ts +1 -1
- package/dist/ui/rich-text-editor.d.ts +30 -0
- package/dist/ui/rich-text-toolbar.d.ts +8 -0
- package/dist/utils/array-utils.d.ts +4 -0
- package/dist/utils/flatten-leaves.d.ts +6 -0
- package/dist/utils/format-file-size.d.ts +1 -0
- package/dist/utils/format-timestamp.d.ts +1 -0
- package/dist/utils/is-empty-html.d.ts +5 -0
- package/dist/utils/shuffle.d.ts +1 -0
- package/dist/utils/string-utils.d.ts +12 -0
- package/dist/video/video-bookmark.d.ts +1 -1
- package/dist/video/video-playlist-item.d.ts +1 -1
- package/package.json +92 -3
- package/src/assessment-toolbar/assessment-toolbar.tsx +54 -49
- package/src/assessment-toolbar/index.ts +6 -0
- package/src/assessment-toolbar/question-header-bar.tsx +61 -0
- package/src/assessment-toolbar/question-materials-drawer.tsx +55 -0
- package/src/assessment-toolbar/question-navigator.tsx +3 -31
- package/src/assessment-toolbar/timer-display.tsx +2 -2
- package/src/assessment-toolbar/types.ts +54 -4
- package/src/assessment-toolbar/use-countdown.ts +153 -0
- package/src/common/index.ts +3 -0
- package/src/common/search-input.tsx +7 -6
- package/src/common/stepper.tsx +100 -0
- package/src/common/types.ts +39 -0
- package/src/content/attachment-list.tsx +90 -0
- package/src/content/content-block.tsx +4 -2
- package/src/content/file-upload-zone.tsx +1 -6
- package/src/content/index.ts +3 -0
- package/src/content/types.ts +41 -0
- package/src/curriculum/curriculum-item.tsx +7 -3
- package/src/feedback/feedback-banner.tsx +12 -14
- package/src/flashcards/flashcard-deck.tsx +1 -9
- package/src/flashcards/flashcard.tsx +1 -1
- package/src/modules/AssignmentModule/AssignmentModule.tsx +305 -0
- package/src/modules/AssignmentModule/types.ts +73 -0
- package/src/modules/CertificateModule/CertificateModule.tsx +161 -0
- package/src/modules/CertificateModule/types.ts +47 -0
- package/src/modules/CoursePlayer/CoursePlayer.tsx +44 -48
- package/src/modules/DiscussionModule/DiscussionModule.tsx +110 -0
- package/src/modules/DiscussionModule/types.ts +54 -0
- package/src/modules/ExamModule/ExamModule.tsx +285 -0
- package/src/modules/ExamModule/types.ts +66 -0
- package/src/modules/FlashcardLab/FlashcardLab.tsx +29 -16
- package/src/modules/GradeCenterModule/GradeCenterModule.tsx +169 -0
- package/src/modules/GradeCenterModule/types.ts +63 -0
- package/src/modules/QuizModule/QuizModule.tsx +88 -88
- package/src/modules/QuizModule/types.ts +6 -1
- package/src/modules/SurveyModule/SurveyModule.tsx +180 -0
- package/src/modules/SurveyModule/types.ts +51 -0
- package/src/modules/index.ts +24 -0
- package/src/progress/achievement-badge.tsx +52 -0
- package/src/progress/activity-timeline.tsx +84 -0
- package/src/progress/index.ts +7 -0
- package/src/progress/stat-card.tsx +30 -18
- package/src/progress/streak-badge.tsx +35 -0
- package/src/progress/types.ts +101 -0
- package/src/questions/choice.tsx +7 -9
- package/src/questions/essay.tsx +23 -25
- package/src/questions/fill-in-the-blank.tsx +13 -16
- package/src/questions/hotspot.tsx +154 -0
- package/src/questions/index.ts +16 -0
- package/src/questions/inline-choice.tsx +151 -0
- package/src/questions/matching.tsx +228 -0
- package/src/questions/multiple-choice.tsx +7 -9
- package/src/questions/numeric.tsx +102 -0
- package/src/questions/ordering.tsx +159 -0
- package/src/questions/question-renderer.tsx +21 -0
- package/src/questions/scenario.tsx +140 -0
- package/src/questions/scoring.ts +201 -0
- package/src/questions/spreadsheet.tsx +259 -0
- package/src/questions/true-false.tsx +7 -9
- package/src/questions/types.ts +123 -1
- package/src/questions/use-drag-reorder.ts +80 -0
- package/src/sections/AnnouncementFeed/AnnouncementFeed.tsx +2 -15
- package/src/sections/AssessmentReview/AssessmentReview.tsx +13 -2
- package/src/sections/AssignmentSubmission/AssignmentSubmission.tsx +7 -5
- package/src/sections/CertificateViewer/CertificateViewer.tsx +409 -56
- package/src/sections/CertificateViewer/types.ts +13 -5
- package/src/sections/CourseOutline/CourseOutline.tsx +4 -14
- package/src/sections/DiscussionThread/DiscussionThread.tsx +13 -10
- package/src/sections/ExamSession/ExamSession.tsx +44 -7
- package/src/sections/ExamSession/types.ts +6 -1
- package/src/sections/ForumBoard/ForumBoard.tsx +284 -0
- package/src/sections/ForumBoard/types.ts +67 -0
- package/src/sections/GradebookTable/GradebookTable.tsx +1 -1
- package/src/sections/LecturePlayer/LecturePlayer.tsx +1 -1
- package/src/sections/LessonPage/LessonPage.tsx +5 -9
- package/src/sections/PracticeQuiz/PracticeQuiz.tsx +15 -26
- package/src/sections/ProgressDashboard/ProgressDashboard.tsx +65 -65
- package/src/sections/QuizSession/QuizSession.tsx +67 -8
- package/src/sections/QuizSession/types.ts +6 -1
- package/src/sections/RequirementsChecklist/RequirementsChecklist.tsx +107 -0
- package/src/sections/RequirementsChecklist/types.ts +38 -0
- package/src/sections/ResourceLibrary/ResourceLibrary.tsx +4 -9
- package/src/sections/RubricView/RubricView.tsx +138 -0
- package/src/sections/RubricView/types.ts +52 -0
- package/src/sections/ScrollableQuiz/ScrollableQuiz.tsx +23 -9
- package/src/sections/SurveyForm/SurveyForm.tsx +8 -5
- package/src/sections/index.ts +20 -1
- package/src/social/post-card.tsx +8 -19
- package/src/social/user-avatar.tsx +1 -0
- package/src/styles/globals.css +13 -0
- package/src/ui/drawer.tsx +600 -0
- package/src/ui/index.ts +19 -0
- package/src/ui/rich-text-editor.tsx +109 -0
- package/src/ui/rich-text-toolbar.tsx +156 -0
- package/src/utils/array-utils.ts +17 -0
- package/src/utils/flatten-leaves.ts +17 -0
- package/src/utils/format-file-size.ts +5 -0
- package/src/utils/format-timestamp.ts +13 -0
- package/src/utils/is-empty-html.ts +7 -0
- package/src/utils/shuffle.ts +8 -0
- package/src/utils/string-utils.ts +30 -0
- package/src/video/video-bookmark.tsx +4 -3
- package/src/video/video-chapter-list.tsx +9 -4
- package/src/video/video-player.tsx +11 -4
- package/src/video/video-playlist-item.tsx +8 -3
- package/src/video/video-thumbnail-card.tsx +4 -0
- package/src/video/video-transcript.tsx +8 -5
- package/dist/table-BrS5cDQu.js +0 -2510
- package/dist/table-D6AkBBEo.cjs +0 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RubricView section — displays a grading rubric with criteria and proficiency levels.
|
|
3
|
+
*
|
|
4
|
+
* Shows criteria as rows with level columns. When `selectedLevels` is provided,
|
|
5
|
+
* highlights the scored level per criterion and shows total score.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* <RubricView
|
|
9
|
+
* criteria={rubricCriteria}
|
|
10
|
+
* selectedLevels={{ "c1": "l2", "c2": "l3" }}
|
|
11
|
+
* totalScore={85}
|
|
12
|
+
* maxScore={100}
|
|
13
|
+
* />
|
|
14
|
+
*/
|
|
15
|
+
export interface RubricViewProps {
|
|
16
|
+
/** Rubric criteria (rows) */
|
|
17
|
+
criteria: RubricCriterion[];
|
|
18
|
+
/** Selected level UID per criterion UID — highlights scored cells */
|
|
19
|
+
selectedLevels?: Record<string, string>;
|
|
20
|
+
/** Overall rubric score (sum of selected levels) */
|
|
21
|
+
totalScore?: number;
|
|
22
|
+
/** Maximum possible score */
|
|
23
|
+
maxScore?: number;
|
|
24
|
+
/** Instructor feedback text */
|
|
25
|
+
feedback?: string;
|
|
26
|
+
/** CSS class name for the root element */
|
|
27
|
+
className?: string;
|
|
28
|
+
/** Inline styles for the root element */
|
|
29
|
+
style?: React.CSSProperties;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface RubricCriterion {
|
|
33
|
+
/** Unique identifier */
|
|
34
|
+
uid: string;
|
|
35
|
+
/** Criterion name (e.g. "Organization", "Evidence") */
|
|
36
|
+
name: string;
|
|
37
|
+
/** Optional description of what this criterion evaluates */
|
|
38
|
+
description?: string;
|
|
39
|
+
/** Proficiency levels from lowest to highest */
|
|
40
|
+
levels: RubricLevel[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface RubricLevel {
|
|
44
|
+
/** Unique identifier */
|
|
45
|
+
uid: string;
|
|
46
|
+
/** Level label (e.g. "Excellent", "Good", "Needs Work") */
|
|
47
|
+
label: string;
|
|
48
|
+
/** Description of what this level looks like */
|
|
49
|
+
description: string;
|
|
50
|
+
/** Point value for this level */
|
|
51
|
+
points: number;
|
|
52
|
+
}
|
|
@@ -3,6 +3,7 @@ import { QuestionRenderer } from "../../questions";
|
|
|
3
3
|
import type { SessionAnswer } from "../../questions/types";
|
|
4
4
|
import { Button } from "../../ui/button";
|
|
5
5
|
import { Card, CardContent } from "../../ui/card";
|
|
6
|
+
import { Separator } from "../../ui/separator";
|
|
6
7
|
import { cn } from "../../lib/utils";
|
|
7
8
|
import type { ScrollableQuizProps } from "./types";
|
|
8
9
|
|
|
@@ -23,10 +24,20 @@ export function ScrollableQuiz({
|
|
|
23
24
|
const [activeUid, setActiveUid] = useState<string | null>(questions[0]?.uid ?? null);
|
|
24
25
|
const questionRefs = useRef<Map<string, HTMLElement>>(new Map());
|
|
25
26
|
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
const answersByQuestion = useMemo(() => {
|
|
28
|
+
const map = new Map<string, SessionAnswer[]>();
|
|
29
|
+
for (const a of sessionAnswers) {
|
|
30
|
+
const list = map.get(a.uid);
|
|
31
|
+
if (list) list.push(a);
|
|
32
|
+
else map.set(a.uid, [a]);
|
|
33
|
+
}
|
|
34
|
+
return map;
|
|
35
|
+
}, [sessionAnswers]);
|
|
36
|
+
|
|
37
|
+
const answeredCount = useMemo(
|
|
38
|
+
() => questions.filter((q) => answersByQuestion.has(q.uid)).length,
|
|
39
|
+
[questions, answersByQuestion],
|
|
40
|
+
);
|
|
30
41
|
|
|
31
42
|
useEffect(() => {
|
|
32
43
|
const observer = new IntersectionObserver(
|
|
@@ -90,7 +101,7 @@ export function ScrollableQuiz({
|
|
|
90
101
|
{/* Main content */}
|
|
91
102
|
<div className="flex-1 min-w-0">
|
|
92
103
|
{orderedQuestions.map((group, gi) => (
|
|
93
|
-
<div key={gi}>
|
|
104
|
+
<div key={group.label ?? `ungrouped-${gi}`}>
|
|
94
105
|
{group.label && (
|
|
95
106
|
<p className={cn("text-lg font-semibold mb-2 text-foreground", gi > 0 && "mt-4")}>
|
|
96
107
|
{group.label}
|
|
@@ -113,7 +124,7 @@ export function ScrollableQuiz({
|
|
|
113
124
|
)}
|
|
114
125
|
<QuestionRenderer
|
|
115
126
|
question={q}
|
|
116
|
-
sessionAnswers={
|
|
127
|
+
sessionAnswers={answersByQuestion.get(q.uid) ?? []}
|
|
117
128
|
onAnswer={(answers) => handleAnswer(q.uid, answers)}
|
|
118
129
|
readOnly={readOnly}
|
|
119
130
|
/>
|
|
@@ -123,7 +134,8 @@ export function ScrollableQuiz({
|
|
|
123
134
|
})}
|
|
124
135
|
</div>
|
|
125
136
|
))}
|
|
126
|
-
<
|
|
137
|
+
<Separator className="my-3" />
|
|
138
|
+
<div className="flex justify-between items-center">
|
|
127
139
|
<span className="text-sm text-muted-foreground">
|
|
128
140
|
{answeredCount} of {questions.length} answered
|
|
129
141
|
</span>
|
|
@@ -138,11 +150,12 @@ export function ScrollableQuiz({
|
|
|
138
150
|
|
|
139
151
|
{/* Sidebar navigator */}
|
|
140
152
|
{showNavigator && (
|
|
141
|
-
<Card className="hidden md:block w-50 shrink-0 sticky top-4 self-start
|
|
153
|
+
<Card className="hidden md:block w-50 shrink-0 sticky top-4 self-start">
|
|
154
|
+
<CardContent className="p-3">
|
|
142
155
|
<p className="font-semibold text-sm mb-1 text-foreground">Questions</p>
|
|
143
156
|
<div className="flex flex-wrap gap-1">
|
|
144
157
|
{questions.map((q, i) => {
|
|
145
|
-
const isAnswered =
|
|
158
|
+
const isAnswered = answersByQuestion.has(q.uid);
|
|
146
159
|
const isActive = activeUid === q.uid;
|
|
147
160
|
return (
|
|
148
161
|
<button
|
|
@@ -163,6 +176,7 @@ export function ScrollableQuiz({
|
|
|
163
176
|
);
|
|
164
177
|
})}
|
|
165
178
|
</div>
|
|
179
|
+
</CardContent>
|
|
166
180
|
</Card>
|
|
167
181
|
)}
|
|
168
182
|
</div>
|
|
@@ -3,7 +3,8 @@ import { LikertScale, StarRating } from "../../feedback";
|
|
|
3
3
|
import { Button } from "../../ui/button";
|
|
4
4
|
import { Card, CardContent } from "../../ui/card";
|
|
5
5
|
import { Progress } from "../../ui/progress";
|
|
6
|
-
import {
|
|
6
|
+
import { Separator } from "../../ui/separator";
|
|
7
|
+
import { RichTextEditor } from "../../ui/rich-text-editor";
|
|
7
8
|
import type { SurveyFormProps, SurveyAnswer } from "./types";
|
|
8
9
|
|
|
9
10
|
export function SurveyForm({
|
|
@@ -95,12 +96,13 @@ export function SurveyForm({
|
|
|
95
96
|
)}
|
|
96
97
|
|
|
97
98
|
{q.type === "open_text" && (
|
|
98
|
-
<
|
|
99
|
+
<RichTextEditor
|
|
99
100
|
placeholder="Type your response..."
|
|
100
101
|
value={(answer?.value as string) ?? ""}
|
|
101
|
-
onChange={(
|
|
102
|
-
|
|
102
|
+
onChange={(html) => setAnswer(q.uid, html)}
|
|
103
|
+
readOnly={readOnly}
|
|
103
104
|
className="min-h-24"
|
|
105
|
+
variant="minimal"
|
|
104
106
|
/>
|
|
105
107
|
)}
|
|
106
108
|
|
|
@@ -164,7 +166,8 @@ export function SurveyForm({
|
|
|
164
166
|
);
|
|
165
167
|
})}
|
|
166
168
|
|
|
167
|
-
<
|
|
169
|
+
<Separator className="my-3" />
|
|
170
|
+
<div className="flex justify-between items-center">
|
|
168
171
|
<span className="text-sm text-muted-foreground">
|
|
169
172
|
{answeredCount} of {questions.length} answered
|
|
170
173
|
</span>
|
package/src/sections/index.ts
CHANGED
|
@@ -87,4 +87,23 @@ export type {
|
|
|
87
87
|
} from "./ProgressDashboard/types";
|
|
88
88
|
|
|
89
89
|
export { CertificateViewer } from "./CertificateViewer/CertificateViewer";
|
|
90
|
-
export type {
|
|
90
|
+
export type {
|
|
91
|
+
CertificateViewerProps,
|
|
92
|
+
CertificateVariant,
|
|
93
|
+
} from "./CertificateViewer/types";
|
|
94
|
+
|
|
95
|
+
export { RubricView } from "./RubricView/RubricView";
|
|
96
|
+
export type {
|
|
97
|
+
RubricViewProps,
|
|
98
|
+
RubricCriterion,
|
|
99
|
+
RubricLevel,
|
|
100
|
+
} from "./RubricView/types";
|
|
101
|
+
|
|
102
|
+
export { RequirementsChecklist } from "./RequirementsChecklist/RequirementsChecklist";
|
|
103
|
+
export type {
|
|
104
|
+
RequirementsChecklistProps,
|
|
105
|
+
Requirement,
|
|
106
|
+
} from "./RequirementsChecklist/types";
|
|
107
|
+
|
|
108
|
+
export { ForumBoard } from "./ForumBoard/ForumBoard";
|
|
109
|
+
export type { ForumBoardProps, ForumTopic, ForumSortOrder } from "./ForumBoard/types";
|
package/src/social/post-card.tsx
CHANGED
|
@@ -1,29 +1,17 @@
|
|
|
1
|
+
import { memo } from "react";
|
|
1
2
|
import { Pin } from "lucide-react";
|
|
2
3
|
import { UserAvatar } from "./user-avatar";
|
|
3
4
|
import { Separator } from "../ui/separator";
|
|
4
5
|
import type { PostCardProps } from "./types";
|
|
5
6
|
import { cn } from "../lib/utils";
|
|
6
|
-
|
|
7
|
-
function formatTimestamp(iso: string): string {
|
|
8
|
-
const date = new Date(iso);
|
|
9
|
-
const now = new Date();
|
|
10
|
-
const diffMs = now.getTime() - date.getTime();
|
|
11
|
-
const diffMins = Math.floor(diffMs / 60000);
|
|
12
|
-
if (diffMins < 1) return "Just now";
|
|
13
|
-
if (diffMins < 60) return `${diffMins}m ago`;
|
|
14
|
-
const diffHours = Math.floor(diffMins / 60);
|
|
15
|
-
if (diffHours < 24) return `${diffHours}h ago`;
|
|
16
|
-
const diffDays = Math.floor(diffHours / 24);
|
|
17
|
-
if (diffDays < 7) return `${diffDays}d ago`;
|
|
18
|
-
return date.toLocaleDateString();
|
|
19
|
-
}
|
|
7
|
+
import { formatTimestamp } from "../utils/format-timestamp";
|
|
20
8
|
|
|
21
9
|
const HIGHLIGHT_BORDERS: Record<string, string> = {
|
|
22
10
|
pinned: "var(--warning)",
|
|
23
11
|
answer: "var(--success)",
|
|
24
12
|
};
|
|
25
13
|
|
|
26
|
-
export function PostCard({
|
|
14
|
+
export const PostCard = memo(function PostCard({
|
|
27
15
|
author,
|
|
28
16
|
content,
|
|
29
17
|
createdAt,
|
|
@@ -73,9 +61,10 @@ export function PostCard({
|
|
|
73
61
|
)}
|
|
74
62
|
{highlight === "pinned" && <Pin size={14} />}
|
|
75
63
|
</div>
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
<div
|
|
65
|
+
className="mt-1 text-sm [&_p]:mb-1 [&_ul]:list-disc [&_ul]:pl-5 [&_ol]:list-decimal [&_ol]:pl-5 [&_a]:text-primary [&_a]:underline"
|
|
66
|
+
dangerouslySetInnerHTML={{ __html: content }}
|
|
67
|
+
/>
|
|
79
68
|
{actions && (
|
|
80
69
|
<>
|
|
81
70
|
<Separator className="my-2" />
|
|
@@ -88,4 +77,4 @@ export function PostCard({
|
|
|
88
77
|
</div>
|
|
89
78
|
</div>
|
|
90
79
|
);
|
|
91
|
-
}
|
|
80
|
+
});
|
package/src/styles/globals.css
CHANGED
|
@@ -123,3 +123,16 @@
|
|
|
123
123
|
.flashcard-back-content p {
|
|
124
124
|
margin: 0.25em 0;
|
|
125
125
|
}
|
|
126
|
+
|
|
127
|
+
/* Tiptap rich text editor */
|
|
128
|
+
.tiptap:focus {
|
|
129
|
+
outline: none;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.tiptap p.is-editor-empty:first-child::before {
|
|
133
|
+
color: var(--muted-foreground);
|
|
134
|
+
content: attr(data-placeholder);
|
|
135
|
+
float: left;
|
|
136
|
+
height: 0;
|
|
137
|
+
pointer-events: none;
|
|
138
|
+
}
|