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

Commit f7a71b9

Browse files
committed
feat: implement block visibility toggle and enhance worksheet details UI
1 parent 57950b1 commit f7a71b9

6 files changed

Lines changed: 79 additions & 69 deletions

File tree

src/components/swapy/swapy-manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export class SwapyManager {
1313

1414
this.swapy = createSwapy(this.container, {
1515
animation: "spring",
16-
swapMode: "hover",
16+
swapMode: "drop",
1717
autoScrollOnDrag: true,
1818
});
1919
}

src/components/worksheet/block.ts

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,26 @@ export class Block {
3131
this.element.innerHTML = `
3232
<div class="row">
3333
<div class="handle" data-swapy-handle><i>drag_indicator</i></div>
34-
<nav class="max toolbar round fill">
34+
<h6 class="max" id="${id}-title">Block</h6>
35+
<button id="${id}-duplicate" class="chip square">
36+
<i>content_copy</i>
37+
<div class="tooltip">
38+
Duplicate
39+
</div>
40+
</button>
41+
<button class="circle error chip" id="${id}-delete">
42+
<i>delete</i>
43+
</button>
44+
<label class="checkbox icon">
45+
<input type="checkbox" id="${id}-hidden">
46+
<span>
47+
<i>expand_less</i>
48+
<i>expand_more</i>
49+
</span>
50+
</label>
51+
</div>
52+
<div id="${id}-content" class="block-content">
53+
<nav class="margin max toolbar round fill">
3554
<a class="active" data-ui="#${id}-question">
3655
<i>help</i>
3756
<span class="l">Question</span>
@@ -53,12 +72,6 @@ export class Block {
5372
<span class="l">Page Break</span>
5473
</a>
5574
</nav>
56-
<button class="circle error" id="${id}-delete">
57-
<i>delete</i>
58-
</button>
59-
</div>
60-
61-
<div class="block-content">
6275
<div class="page padding active" id="${id}-question">
6376
<div class="prefix field label border round">
6477
<i>star</i>
@@ -89,7 +102,7 @@ export class Block {
89102
<label>Header</label>
90103
<i>arrow_drop_down</i>
91104
</div>
92-
<div class="field label border round no-margin">
105+
<div class="field label border round">
93106
<input type="text" id="${id}-title">
94107
<label>Title</label>
95108
</div>
@@ -130,9 +143,30 @@ export class Block {
130143
});
131144
}
132145

146+
setHidden(state: boolean) {
147+
const content = this.element.querySelector(`#${this.id}-content`) as HTMLElement;
148+
149+
// Update the block's hidden property
150+
(this as any).hidden = state;
151+
152+
if (state) {
153+
this.element.classList.add("block-collapsed");
154+
} else {
155+
this.element.classList.remove("block-collapsed");
156+
}
157+
}
158+
133159
mount() {
134160
const id = this.id;
135161

162+
const hiddenCheckbox = this.element.querySelector(`#${id}-hidden`) as HTMLInputElement;
163+
hiddenCheckbox.addEventListener("change", () => {
164+
this.setHidden(hiddenCheckbox.checked);
165+
});
166+
167+
// Restore UI on mount
168+
this.setHidden(hiddenCheckbox.checked);
169+
136170
const questionEl = this.element.querySelector(`#${id}-question-container`) as HTMLElement;
137171
const answerEl = this.element.querySelector(`#${id}-answer-container`) as HTMLElement;
138172
const notesEl = this.element.querySelector(`#${id}-notes-container`) as HTMLElement;

src/models/worksheet.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ export interface IWorksheetBlock {
4040
// nothing needed for divider / page break
4141
// but we could later store custom styles if wanted
4242
// -------------------------
43+
44+
hidden?: boolean;
4345
}
4446

4547
/** List of blocks inside the worksheet */

src/pages/worksheet/worksheet.html

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -126,28 +126,36 @@ <h6 class="left-align m l">Worksheet</h6>
126126
<div class="s12 m6 l6" id="editor-container">
127127
<div id="editor-pane" style="height: 100% !important; overflow-y: auto; overflow-x: hidden;">
128128
<article class="round small-margin">
129-
<div class="field label border round">
130-
<input type="text" id="topic">
131-
<label>Topic</label>
132-
</div>
133-
<div class="field label border round">
134-
<input type="text" id="name">
135-
<label>Name</label>
136-
</div>
137-
<div class="field label border round">
138-
<input type="text" id="author">
139-
<label>Author</label>
140-
</div>
141-
<div class="field label border round">
142-
<input type="text" id="grade-level">
143-
<label>Grade Level</label>
144-
</div>
145-
<div class="field label border round">
146-
<input type="text" id="date">
147-
<label>Date</label>
148-
</div>
149-
<h6>Teacher Notes</h6>
150-
<div id="teacher-notes-container"></div>
129+
<details id="worksheet-details" open>
130+
<summary>
131+
<nav>
132+
<h5 class="max">Worksheet Details</h5>
133+
<i>expand_more</i>
134+
</nav>
135+
</summary>
136+
<div class="field label border round">
137+
<input type="text" id="topic">
138+
<label>Topic</label>
139+
</div>
140+
<div class="field label border round">
141+
<input type="text" id="name">
142+
<label>Name</label>
143+
</div>
144+
<div class="field label border round">
145+
<input type="text" id="author">
146+
<label>Author</label>
147+
</div>
148+
<div class="field label border round">
149+
<input type="text" id="grade-level">
150+
<label>Grade Level</label>
151+
</div>
152+
<div class="field label border round">
153+
<input type="text" id="date">
154+
<label>Date</label>
155+
</div>
156+
<h6>Teacher Notes</h6>
157+
<div id="teacher-notes-container"></div>
158+
</details>
151159
</article>
152160
<div id="block-list" class="swapy-container"></div>
153161
</div>

src/pages/worksheet/worksheet.ts

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,9 @@ import "@static/css/worksheet.css";
55
import "beercss";
66
import "material-dynamic-colors";
77
import "@toast-ui/editor/dist/toastui-editor.css";
8-
9-
import { createSwapy } from "swapy";
10-
118
import { AppearanceDialog } from "@components/common/dialogs/appearance-dialog";
129
import { ShareWorksheetDialog } from "@components/common/dialogs/share-worksheet-dialog";
1310
import { ContentCopiedSnackbar } from "@components/common/snackbar/content-copied";
14-
15-
import { WorksheetsAPI } from "@api/worksheets-api";
1611
import { Block } from "@components/worksheet/block";
1712
import { SwapyManager } from "@components/swapy/swapy-manager";
1813
import Editor from "@toast-ui/editor";
@@ -160,39 +155,6 @@ function bindAll(selector: string, handler: (el: HTMLElement) => void) {
160155
document.querySelectorAll<HTMLElement>(selector).forEach(handler);
161156
}
162157

163-
let swapy: any = null;
164-
165-
function refreshSwapy() {
166-
const container = document.querySelector("#block-list")!;
167-
168-
// Remove old instance (if any)
169-
if (swapy) swapy.enable(false);
170-
171-
// The container must have slots
172-
container.querySelectorAll(".slot").forEach(s => s.remove());
173-
174-
// Wrap each block inside a slot
175-
// container.querySelectorAll("[data-swapy-item]").forEach(item => {
176-
// const slot = document.createElement("div");
177-
// slot.classList.add("slot");
178-
// slot.setAttribute("data-swapy-slot", "slot-" + item.getAttribute("data-swapy-item"));
179-
// item.replaceWith(slot);
180-
// slot.appendChild(item);
181-
// });
182-
183-
// Create new instance
184-
swapy = createSwapy(container, {
185-
animation: "dynamic"
186-
});
187-
188-
// Listen for reordering
189-
swapy.onSwap((event: any) => {
190-
console.log("New order:", event.newSlotItemMap.asArray);
191-
// TODO: update WorksheetBlocks order later
192-
});
193-
}
194-
195-
196158
function addNewBlock(): Block {
197159
const block = new Block();
198160
SwapyManager.get()

src/static/css/worksheet.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
cursor: move;
1717
}
1818

19+
.block-collapsed .block-content {
20+
display: none;
21+
}
22+
1923
.slot {
2024
min-height: 60px;
2125
border-radius: 32px;

0 commit comments

Comments
 (0)