Skip to content
This repository was archived by the owner on Jan 16, 2026. It is now read-only.

Commit 71036c0

Browse files
committed
Worksheet improvements and text markdown text/paragraph
1 parent 05dbc32 commit 71036c0

7 files changed

Lines changed: 184 additions & 58 deletions

File tree

src/components/worksheet/block.ts

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ export class Block {
2828
questionEditor!: Editor;
2929
questionSpaceSize!: HTMLInputElement;
3030
answerEditor!: Editor;
31-
showAnswerCheckbox!: HTMLInputElement;
31+
showSolutionCheckbox!: HTMLInputElement;
3232
blankSpaceSize!: HTMLInputElement;
33+
paragraphEditor!: Editor;
3334

3435
constructor(block: WorksheetBlock) {
3536
this.id = block.id;
@@ -65,25 +66,29 @@ export class Block {
6566
Delete
6667
</div>
6768
</button>
68-
<label class="checkbox circle icon small primary small-padding right-round">
69+
<label class="checkbox circle icon small primary small-padding right-round" style="max-width: 32px;">
6970
<input type="checkbox" id="${id}-hidden">
7071
<span class="on-primary">
71-
<i class="large" style="color: var(--on-primary);">expand_less</i>
72-
<i class="large" style="color: var(--on-primary);">expand_more</i>
72+
<i class="extra" style="color: var(--on-primary); font-size: 24px;">expand_less</i>
73+
<i class="extra" style="color: var(--on-primary); font-size: 24px;">expand_more</i>
7374
</span>
7475
</label>
7576
</nav>
7677
</div>
7778
<div id="${id}-content" class="block-content">
7879
<nav class="margin max toolbar round scroll surface-container-high" id="${id}-block-type">
79-
<a class="active" data-ui="#${id}-question">
80-
<i>help</i>
81-
<span class="l">Question</span>
82-
</a>
8380
<a data-ui="#${id}-header">
8481
<i>format_h1</i>
8582
<span class="l">Header</span>
8683
</a>
84+
<a data-ui="#${id}-paragraph">
85+
<i>text_fields</i>
86+
<span class="l">Text</span>
87+
</a>
88+
<a class="active" data-ui="#${id}-question">
89+
<i>help</i>
90+
<span class="l">Question</span>
91+
</a>
8792
<a data-ui="#${id}-divider">
8893
<i>horizontal_rule</i>
8994
<span class="l">Divider</span>
@@ -110,16 +115,20 @@ export class Block {
110115
<label>Question Space Size</label>
111116
</div>
112117
</div>
113-
<h6>Question</h6>
118+
<div class="large-text top-margin">Question</div>
114119
<div id="${id}-question-container"></div>
115-
<h6>Answer (Optional)</h6>
116-
<div id="${id}-answer-container"></div>
120+
<div class="large-text top-margin">Solution</div>
121+
<div id="${id}-solution-container"></div>
117122
<label class="checkbox">
118-
<input type="checkbox" id="${id}-show-answer">
119-
<span>Show Answer</span>
123+
<input type="checkbox" id="${id}-show-solution">
124+
<span>Show Solution</span>
120125
</label>
121126
</div>
122127
128+
<div class="page padding" id="${id}-paragraph">
129+
<div id="${id}-paragraph-container"></div>
130+
</div>
131+
123132
<div class="page padding" id="${id}-header">
124133
<div class="field label suffix border round">
125134
<select id="${id}-header-type">
@@ -203,11 +212,11 @@ export class Block {
203212
this.emitChanged({ title: this.block.title }, "title");
204213
});
205214

206-
this.showAnswerCheckbox = this.element.querySelector(`#${this.id}-show-answer`) as HTMLInputElement;
207-
this.showAnswerCheckbox.checked = this.block.showAnswer || false;
208-
this.showAnswerCheckbox.addEventListener("change", () => {
209-
this.block.showAnswer = this.showAnswerCheckbox.checked;
210-
this.emitChanged({ showAnswer: this.block.showAnswer }, "showAnswer");
215+
this.showSolutionCheckbox = this.element.querySelector(`#${this.id}-show-solution`) as HTMLInputElement;
216+
this.showSolutionCheckbox.checked = this.block.showSolution || false;
217+
this.showSolutionCheckbox.addEventListener("change", () => {
218+
this.block.showSolution = this.showSolutionCheckbox.checked;
219+
this.emitChanged({ showSolution: this.block.showSolution }, "showSolution");
211220
});
212221

213222
this.blankSpaceSize = this.element.querySelector(`#${this.id}-blank-space-size`) as HTMLInputElement;
@@ -265,7 +274,8 @@ export class Block {
265274
this.setHidden(this.hiddenCheckbox.checked);
266275

267276
const questionEl = this.element.querySelector(`#${this.id}-question-container`) as HTMLElement;
268-
const answerEl = this.element.querySelector(`#${this.id}-answer-container`) as HTMLElement;
277+
const solutionEl = this.element.querySelector(`#${this.id}-solution-container`) as HTMLElement;
278+
const paragraphEl = this.element.querySelector(`#${this.id}-paragraph-container`) as HTMLElement;
269279

270280
// Prevent double-init if Swapy re-attaches elements
271281
if (!this.questionEditor) {
@@ -287,7 +297,7 @@ export class Block {
287297

288298
if (!this.answerEditor) {
289299
this.answerEditor = new Editor({
290-
el: answerEl,
300+
el: solutionEl,
291301
previewStyle: "vertical",
292302
height: "150px",
293303
initialEditType: "wysiwyg",
@@ -301,8 +311,25 @@ export class Block {
301311
});
302312
this.answerEditor?.on("focus", () => setPreviewActiveBlock(this.id));
303313
}
314+
if (!this.paragraphEditor) {
315+
this.paragraphEditor = new Editor({
316+
el: paragraphEl,
317+
previewStyle: "vertical",
318+
height: "250px",
319+
initialEditType: "wysiwyg",
320+
usageStatistics: true,
321+
});
322+
this.paragraphEditor.setMarkdown(this.block.paragraphMarkdown?.replaceAll("$$", "\\$\\$") || "");
323+
this.paragraphEditor.on("change", () => {
324+
this.block.paragraphMarkdown = this.paragraphEditor.getMarkdown();
325+
this.emitChanged({ paragraphMarkdown: this.block.paragraphMarkdown }, "paragraphMarkdown");
326+
setPreviewActiveBlock(this.id, false)
327+
});
328+
this.paragraphEditor?.on("focus", () => setPreviewActiveBlock(this.id));
329+
}
304330

305331
this.element.addEventListener("dblclick", () => {
332+
if (!this.hiddenCheckbox.checked) return;
306333
this.hiddenCheckbox.checked = !this.hiddenCheckbox.checked;
307334
this.setHidden(this.hiddenCheckbox.checked);
308335
})

src/components/worksheet/preview.ts

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@ export class Preview {
1515

1616
const headerElement = document.createElement("div");
1717
headerElement.innerHTML = `
18-
<nav class="row center-align">
19-
<strong>${escapeHtml(this.worksheet.topic)}</strong>
18+
<nav class="row bottom-align">
19+
<span>${escapeHtml(this.worksheet.topic)}</span>
2020
<h6 class="max center-align">${escapeHtml(this.worksheet.name)}</h6>
21-
<strong>Due: ${escapeHtml(this.worksheet.date)}</strong>
21+
<span>Due: ${escapeHtml(this.worksheet.date)}</span>
2222
</nav>
2323
<hr>
2424
<nav class="row">
25-
<div class="worksheet-notes max padding">
25+
<div class="worksheet-notes max padding small-text no-line">
2626
${await renderWorksheetMarkdown(this.worksheet.teacherNotes || "")}
2727
</div>
28-
<div>Name <hr class="small-width"></div>
28+
<div class="max">Name <hr></div>
2929
</nav>
3030
<hr>
3131
<nav class="row right-align">
@@ -46,9 +46,7 @@ export class Preview {
4646
case WorksheetBlockType.Question: {
4747
const space = block.questionSpaceSize ?? 1;
4848
const qHtml = await renderWorksheetMarkdown(block.questionMarkdown || "");
49-
const aHtml = block.showAnswer
50-
? await renderWorksheetMarkdown(block.answerMarkdown || "")
51-
: "";
49+
const sHtml = block.showSolution ? await renderWorksheetMarkdown(block.answerMarkdown || "") : "";
5250

5351
blockElement.innerHTML = `
5452
<div class="row top-align">
@@ -59,22 +57,27 @@ export class Preview {
5957
<div class="worksheet-question">
6058
${qHtml || "<span class='italic'>(no question)</span>"}
6159
</div>
62-
63-
${block.showAnswer && (block.answerMarkdown || "").trim()
64-
? `<div class="worksheet-answer">
65-
<h6>Answer</h6>
66-
${aHtml}
67-
</div>`
68-
: ""
69-
}
70-
</div>
7160
</div>
72-
<div class="question-space" style="height:${space * 24}px"></div>
61+
</div>
62+
<div class="question-space" style="min-height:${space * 24}px" data-height="${space * 24}px">
63+
${block.showSolution && (block.answerMarkdown || "").trim()
64+
? `<div class="worksheet-solution">
65+
<span class="italic">Solution</span>${sHtml}
66+
</div>`
67+
: ""}
68+
<span class="height-line"></span>
69+
</div>
7370
`.trim();
7471

7572
break;
7673
}
7774

75+
case WorksheetBlockType.Paragraph: {
76+
const pHtml = await renderWorksheetMarkdown(block.paragraphMarkdown || "");
77+
blockElement.innerHTML = `<div class="worksheet-paragraph">${pHtml}</div>`;
78+
break;
79+
}
80+
7881
case WorksheetBlockType.SectionHeader: {
7982
const titleHtml = await renderWorksheetMarkdown(block.title || "");
8083

@@ -97,8 +100,9 @@ export class Preview {
97100

98101
case WorksheetBlockType.BlankSpace: {
99102
const size = block.size ?? 1;
100-
blockElement.classList.add("blank-space");
101-
blockElement.style.height = `${size * 24}px`;
103+
blockElement.innerHTML = `<div class="blank-space" style="min-height:${size * 24}px" data-height="${size * 24}px">
104+
<span class="height-line"></span>
105+
</div>`
102106
break;
103107
}
104108

src/config/webpack.common.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,20 @@ module.exports = {
8585
target: "es2017",
8686
},
8787
},
88+
{
89+
test: /\.(woff2?|ttf|eot|otf)$/i,
90+
type: "asset/resource",
91+
generator: {
92+
filename: "fonts/[name][ext][query]",
93+
},
94+
},
8895
{
8996
test: /\.css$/i,
9097
use: [MiniCssExtractPlugin.loader,
9198
{
9299
loader: "css-loader",
93100
options: {
94-
url: false, // <-- do not resolve url(...)
101+
url: true,
95102
},
96103
}],
97104
},

src/models/worksheet.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export enum WorksheetBlockType {
22
Question = "question",
3+
Paragraph = "paragraph",
34
SectionHeader = "header",
45
Divider = "divider",
56
BlankSpace = "space",
@@ -22,8 +23,9 @@ export interface IWorksheetBlock {
2223
points?: number; // default 5
2324
questionMarkdown?: string;
2425
answerMarkdown?: string;
25-
showAnswer?: boolean;
26+
showSolution?: boolean;
2627
questionSpaceSize?: number;
28+
paragraphMarkdown?: string;
2729

2830
// -------------------------
2931
// HEADER FIELDS

src/pages/worksheet/worksheet.html

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,13 @@ <h5 class="max">Details</h5>
134134
</nav>
135135
</summary>
136136
<div class="grid">
137-
<div class="s12 m12 l6 field label border round">
137+
<div class="s12 m12 l6 prefix field label border round">
138+
<i>topic</i>
138139
<input type="text" id="topic">
139140
<label>Topic</label>
140141
</div>
141-
<div class="s12 m12 l6 field label border round">
142+
<div class="s12 m12 l6 prefix field label border round">
143+
<i>title</i>
142144
<input type="text" id="name">
143145
<label>Name</label>
144146
</div>
@@ -152,11 +154,13 @@ <h5 class="max">Details</h5>
152154
<input type="text" id="grade-level">
153155
<label>Grade Level</label>
154156
</div>
155-
<div class="s12 m12 l6 field label border round">
157+
<div class="s12 m12 l6 prefix field label border round">
158+
<i>event</i>
156159
<input type="text" id="date">
157160
<label>Due Date</label>
158161
</div>
159-
<div class="s12 m12 l6 field label border round">
162+
<div class="s12 m12 l6 prefix field label border round">
163+
<i>font_download</i>
160164
<select id="worksheet-font">
161165
<option value="system">System Default</option>
162166
<option value="latin">Latin Modern Roman</option>
@@ -194,18 +198,24 @@ <h6>Teacher Notes</h6>
194198
<i>add</i>
195199
</button>
196200
<menu class="top transparent no-wrap left right-align">
197-
<li>
198-
<button class="fill small-elevate" id="add-block-question">
199-
<i>help</i>
200-
<span>Question</span>
201-
</button>
202-
</li>
203201
<li>
204202
<button class="fill small-elevate" id="add-block-header">
205203
<i>format_h1</i>
206204
<span>Header</span>
207205
</button>
208206
</li>
207+
<li>
208+
<button class="fill small-elevate" id="add-block-paragraph">
209+
<i>text_fields</i>
210+
<span>Text</span>
211+
</button>
212+
</li>
213+
<li>
214+
<button class="fill small-elevate" id="add-block-question">
215+
<i>help</i>
216+
<span>Question</span>
217+
</button>
218+
</li>
209219
<li>
210220
<button class="fill small-elevate" id="add-block-section">
211221
<i>horizontal_rule</i>

src/pages/worksheet/worksheet.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import "@utils/theme";
22
import "@utils/firebase";
3+
import "katex/dist/katex.min.css";
34
import "@static/css/style.css";
45
import "@static/css/worksheet.css";
56
import "beercss";
@@ -15,7 +16,6 @@ import { SnackbarComponent } from "@components/common/snackbar/snackbar";
1516
import { WorksheetsAPI } from "@api/worksheets-api";
1617
import { Worksheet, WorksheetBlock, WorksheetBlockType } from "@models/worksheet";
1718
import { Preview } from "@components/worksheet/preview";
18-
import "katex/dist/katex.min.css";
1919
import { CurricularOutcomesSection } from "@components/lesson/curricular-outcome-selection";
2020

2121
type ViewMode = "editor-preview" | "editor-only" | "preview-only";
@@ -523,6 +523,16 @@ document.addEventListener("DOMContentLoaded", async () => {
523523
});
524524
});
525525

526+
bindAll("#add-block-paragraph", (el) => {
527+
el.addEventListener("click", async () => {
528+
const newBlock = addNewBlock();
529+
newBlock.showPage(WorksheetBlockType.Paragraph);
530+
blocks.push(newBlock);
531+
if (!worksheetLoaded) return;
532+
await preview.render();
533+
});
534+
});
535+
526536
bindAll("#add-block-header", (el) => {
527537
el.addEventListener("click", async () => {
528538
const newBlock = addNewBlock();

0 commit comments

Comments
 (0)