sidebar: smooth collapse/expand transition for custom labeled actions
CSS: - Force min-width:0 on .body-sidebar-bottom so it can shrink to the 50px collapsed width instead of refusing to clip past its widest label. - Animate label max-width and margin-left with the same 0.3s cubic-bezier as the sidebar width — labels now slide smoothly under their icons on collapse instead of leaving an ellipsized letter at the edge. - Hide v16.17's native .sidebar-bottom-actions row (about + collapse icon-buttons) since our labeled .jey-collapse-link replaces it. - Animate .nav-item padding so it stays in sync with the sidebar width transition (Frappe v16 toggles padding 0→8px instantly). JS: - Update collapse-link DOM in place (svg href + span text) instead of rebuilding innerHTML, so the span keeps its identity and the max-width transition plays smoothly across collapse/expand toggles. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
534c98e062
commit
2230a2854f
|
|
@ -370,6 +370,15 @@ input.list-header-checkbox:checked::after {
|
||||||
Sidebar — Full Width button
|
Sidebar — Full Width button
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
|
|
||||||
|
/* .body-sidebar-bottom is a flex item of .body-sidebar (column flex).
|
||||||
|
By default min-width:auto resolves to min-content, so it refuses to
|
||||||
|
shrink below the natural width of its widest text — and our buttons'
|
||||||
|
labels poke past the collapsed sidebar's right edge. Force min-width:0
|
||||||
|
so it can match the cross-axis (50px collapsed) and clip properly. */
|
||||||
|
.body-sidebar .body-sidebar-bottom {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.jey-fullwidth-link,
|
.jey-fullwidth-link,
|
||||||
.jey-theme-switch-link,
|
.jey-theme-switch-link,
|
||||||
.jey-collapse-link {
|
.jey-collapse-link {
|
||||||
|
|
@ -379,6 +388,8 @@ input.list-header-checkbox:checked::after {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jey-fullwidth-link svg,
|
.jey-fullwidth-link svg,
|
||||||
|
|
@ -392,9 +403,36 @@ input.list-header-checkbox:checked::after {
|
||||||
.jey-theme-switch-link span,
|
.jey-theme-switch-link span,
|
||||||
.jey-collapse-link span {
|
.jey-collapse-link span {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
|
max-width: 200px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
transition: max-width 0.3s cubic-bezier(0.4, 0, 0.2, 1),
|
||||||
|
margin-left 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When sidebar is collapsed, animate the label to zero width + zero
|
||||||
|
margin so it smoothly slides under the icon instead of leaving a
|
||||||
|
single ellipsized letter at the edge. */
|
||||||
|
.body-sidebar-container:not(.expanded) .jey-fullwidth-link span,
|
||||||
|
.body-sidebar-container:not(.expanded) .jey-theme-switch-link span,
|
||||||
|
.body-sidebar-container:not(.expanded) .jey-collapse-link span {
|
||||||
|
max-width: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide the v16.17 native bottom row (about + collapse icon-buttons).
|
||||||
|
Our labeled .jey-collapse-link replaces it. */
|
||||||
|
.body-sidebar .sidebar-bottom-actions {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Frappe v16 toggles .nav-item padding 0→8px instantly between
|
||||||
|
collapsed/expanded, while the sidebar width itself transitions over
|
||||||
|
0.3s — making the user/account button visibly jump 8px. Animate the
|
||||||
|
padding so it stays in sync with the width. */
|
||||||
|
.body-sidebar .nav-item {
|
||||||
|
transition: padding 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ==========================================================================
|
/* ==========================================================================
|
||||||
|
|
|
||||||
|
|
@ -761,9 +761,21 @@
|
||||||
var expanded = isExpanded();
|
var expanded = isExpanded();
|
||||||
var iconName = expanded ? "chevrons-left" : "chevrons-right";
|
var iconName = expanded ? "chevrons-left" : "chevrons-right";
|
||||||
var label = expanded ? __("Collapse Sidebar") : __("Expand Sidebar");
|
var label = expanded ? __("Collapse Sidebar") : __("Expand Sidebar");
|
||||||
link.innerHTML =
|
|
||||||
frappe.utils.icon(iconName, "sm", "", "", "text-ink-gray-7 current-color", true) +
|
var span = link.querySelector("span");
|
||||||
"<span>" + label + "</span>";
|
var use = link.querySelector("svg use");
|
||||||
|
|
||||||
|
if (!span || !use) {
|
||||||
|
// First render — build the DOM.
|
||||||
|
link.innerHTML =
|
||||||
|
frappe.utils.icon(iconName, "sm", "", "", "text-ink-gray-7 current-color", true) +
|
||||||
|
"<span>" + label + "</span>";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Update in place so the span keeps its identity and the
|
||||||
|
// max-width transition plays smoothly across collapse/expand.
|
||||||
|
use.setAttribute("href", "#icon-" + iconName);
|
||||||
|
span.textContent = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addCollapseButton() {
|
function addCollapseButton() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue