Skip to content

Tree toolbar: Collapse split-button is inverted relative to Expand (icons + actions) #208

Description

@JohnRDOrazio

Problem

The Expand and Collapse split-button groups in the tree toolbar use opposite layouts. Each group is a two-button cluster: a main button (with label) on the left and a small icon-only button on the right. The conventions don't match between the two groups.

components/editor/shared/EntityTreeToolbar.tsx:

Group Left (main, labeled) Right (icon-only)
Expand (lines 105-126) ChevronDown (single) → expandOneLevel ChevronsDown (double) → expandAllFully
Collapse (lines 132-148) ChevronsRight (double) → collapseAll ChevronRight (single) → collapseOneLevel

So the Expand group reads "main button = one level, right add-on = all levels" while the Collapse group reads the opposite: "main button = all levels, right add-on = one level". Both the icon weight and the action mapping flip.

This is a real ergonomic problem, not just cosmetic: a user who learns "the labeled button is the conservative one-step action" from the Expand group will accidentally collapse the entire tree on first click of the Collapse group, because there it's the destructive "all levels" action.

Proposed fix

Mirror the Expand group's structure in the Collapse group: single-caret + label = "one level" (the conservative default), double-caret right add-on = "all levels".

 {/* Collapse split-button group */}
 {showCollapseGroup && (
   <div className="flex rounded-md border border-slate-200 dark:border-slate-600">
     <button
-      onClick={onCollapseAll}
+      onClick={onCollapseOneLevel}
       disabled={collapseDisabled}
       className={cn(btnBase, "rounded-l-md border-r border-slate-200 dark:border-slate-600", collapseDisabled ? btnDisabled : btnEnabled)}
-      aria-label="Collapse all"
+      aria-label="Collapse one level"
     >
-      <ChevronsRight className="h-3.5 w-3.5" />
+      <ChevronRight className="h-3.5 w-3.5" />
       <span className="hidden sm:inline">Collapse</span>
     </button>
     <button
-      onClick={onCollapseOneLevel}
+      onClick={onCollapseAll}
       disabled={collapseDisabled}
       className={cn(btnBase, "rounded-r-md px-1", collapseDisabled ? btnDisabled : btnEnabled)}
-      aria-label="Collapse one level"
+      aria-label="Collapse all"
     >
-      <ChevronRight className="h-3.5 w-3.5" />
+      <ChevronsRight className="h-3.5 w-3.5" />
     </button>
   </div>
 )}

After this change, both split-button groups read the same way:

Group Left (main, labeled) Right (icon-only)
Expand ChevronDown (single) → expand one level ChevronsDown (double) → expand all levels
Collapse ChevronRight (single) → collapse one level ChevronsRight (double) → collapse all levels

Done criteria

  • Clicking the Collapse button (left, labeled) collapses one level, not the whole tree.
  • The right add-on with the double-caret collapses all levels.
  • aria-label on each Collapse button matches its new action.
  • Tooltips / title attributes (if any are present) updated accordingly.
  • Existing keyboard / shortcut handlers that wire to the labeled button (if any — e.g., Ctrl+Shift+E for "Expand", Ctrl+Shift+C for "Collapse") still work and now collapse one level instead of the whole tree. If those shortcuts intentionally meant "collapse all," they should be re-bound or renamed.

Out of scope

  • Switching the Collapse icons from ChevronRight/ChevronsRight to ChevronUp/ChevronsUp (which the user mentioned as an alternative). Either direction-set is internally consistent; using the same Chevron(s)Right family that Expand mirrors with Chevron(s)Down reads as "fold sideways" the same way Expand reads as "unfold downward". If a future polish pass prefers up-carets for collapse, that's a small, separate change.

Related

Other v0.5.0 polish items in the editor chrome: #204, #205, #206, #207. This one is small enough to bundle into the same PR as one of the others if convenient.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions