Redesign expandable lists to a leaner, flat style
Course tree (lesson-page sidebar + dashboard's loaded-course view) and File Management's Manage Library browser both move from boxed, bordered rows to a flat list: no per-row background/border, a small leading chevron that doubles as the expand affordance instead of a separate right-edge button, indentation for hierarchy. The chevron's rotation is pure CSS (:has(+ .tree-content.expanded) / :has(+ .curate-children.expanded)) rather than JS swapping glyph text, which also let a fair amount of now-redundant JS come out. The course tree's new styles are scoped under .tree-container (course dashboard) and .lesson-sidebar (lesson page) so they don't leak into the Library folder browser and other rows that reuse the same base .tree-header/.lesson-item/etc. class names elsewhere in course_dashboard.html - confirmed those are visually untouched. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -682,6 +682,89 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Course-outline tree: a leaner, flatter look than the boxed rows
|
||||
above - those stay as-is since directoryRowHtml (the Library
|
||||
folder browser) reuses the same base .tree-header/.tree-icon/
|
||||
.lesson-item/etc. classes and isn't part of this redesign.
|
||||
Scoped under .tree-container (exclusive to the course tree) so
|
||||
nothing outside it is affected. No per-row background/border; a
|
||||
small leading chevron doubles as the expand affordance instead
|
||||
of a separate right-edge button, rotating via :has() so JS
|
||||
never has to touch the icon directly - toggling is just
|
||||
add/remove of one class on .tree-content. */
|
||||
.tree-container .tree-header {
|
||||
background: none;
|
||||
border-left: none;
|
||||
padding: 6px 8px;
|
||||
gap: 8px;
|
||||
}
|
||||
.tree-container .tree-header:hover {
|
||||
background: var(--bg-tertiary);
|
||||
}
|
||||
.tree-container .tree-toggle-icon {
|
||||
display: inline-block;
|
||||
width: 14px;
|
||||
flex-shrink: 0;
|
||||
color: var(--accent);
|
||||
font-size: 0.85em;
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
.tree-container .tree-header:has(+ .tree-content.expanded) .tree-toggle-icon {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
.tree-container .tree-name {
|
||||
font-weight: 600;
|
||||
}
|
||||
.tree-container .tree-content {
|
||||
margin-left: 20px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.tree-container .lesson-item {
|
||||
background: none;
|
||||
border-left: none;
|
||||
padding: 5px 8px;
|
||||
margin-bottom: 0;
|
||||
gap: 8px;
|
||||
justify-content: flex-start;
|
||||
transform: none;
|
||||
}
|
||||
.tree-container .lesson-item .lesson-name {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-weight: 400;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
.tree-container .lesson-item:hover {
|
||||
background: var(--bg-tertiary);
|
||||
transform: none;
|
||||
}
|
||||
.tree-container .lesson-item.completed {
|
||||
background: none;
|
||||
}
|
||||
.tree-container .lesson-item.completed:hover {
|
||||
background: var(--bg-tertiary);
|
||||
}
|
||||
.tree-container .lesson-item.current {
|
||||
background: var(--bg-tertiary);
|
||||
cursor: default;
|
||||
}
|
||||
.tree-container .lesson-item.current .lesson-name {
|
||||
font-weight: 600;
|
||||
color: var(--accent);
|
||||
}
|
||||
.tree-container .lesson-item .lesson-icon {
|
||||
font-size: 0.9em;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.tree-container .lesson-item .lesson-duration {
|
||||
font-size: 0.8em;
|
||||
color: var(--text-muted);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.library-toolbar {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
@@ -1376,13 +1459,13 @@
|
||||
}
|
||||
|
||||
function toggleTree(element) {
|
||||
// Find the content div that comes after this header
|
||||
// Find the content div that comes after this header - the
|
||||
// chevron's rotation is pure CSS (:has(+ .tree-content.expanded)
|
||||
// in _course_tree.html's consumers), so toggling this one class
|
||||
// is the entire job here.
|
||||
const content = element.nextElementSibling;
|
||||
const toggle = element.querySelector('.tree-toggle');
|
||||
|
||||
if (content && content.classList.contains('tree-content')) {
|
||||
const isExpanded = content.classList.toggle('expanded');
|
||||
if (toggle) toggle.textContent = isExpanded ? '▼' : '▶';
|
||||
if (content.dataset.sectionPath) saveSectionExpanded(content.dataset.sectionPath, isExpanded);
|
||||
}
|
||||
}
|
||||
@@ -1410,11 +1493,7 @@
|
||||
const saved = getExpandedSectionPaths();
|
||||
if (!saved.size) return;
|
||||
document.querySelectorAll('.tree-content[data-section-path]').forEach(function(content) {
|
||||
if (!saved.has(content.dataset.sectionPath)) return;
|
||||
content.classList.add('expanded');
|
||||
const header = content.previousElementSibling;
|
||||
const toggle = header ? header.querySelector('.tree-toggle') : null;
|
||||
if (toggle) toggle.textContent = '▼';
|
||||
if (saved.has(content.dataset.sectionPath)) content.classList.add('expanded');
|
||||
});
|
||||
}
|
||||
restoreExpandedSections();
|
||||
@@ -1430,9 +1509,6 @@
|
||||
const shouldExpand = !contents.every(c => c.classList.contains('expanded'));
|
||||
contents.forEach(function(content) {
|
||||
content.classList.toggle('expanded', shouldExpand);
|
||||
const header = content.previousElementSibling;
|
||||
const toggle = header ? header.querySelector('.tree-toggle') : null;
|
||||
if (toggle) toggle.textContent = shouldExpand ? '▼' : '▶';
|
||||
if (content.dataset.sectionPath) saveSectionExpanded(content.dataset.sectionPath, shouldExpand);
|
||||
});
|
||||
if (btnEl) btnEl.textContent = shouldExpand ? 'Collapse all' : 'Expand all';
|
||||
|
||||
Reference in New Issue
Block a user