You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 107748d
Browse filesBrowse the repository at this point in the historyBrowse files
improvement(ui): consolidate the disclosure chevron and order resource menus like the sidebar (#6447)
* improvement(ui): consolidate the disclosure chevron and order resource menus like the sidebar
#6400 aligned the workflow-tree folder chevron to the sidebar section header
(16px/100ms -> 14px/150ms) but left the literal hand-copied in three files, so the
next edit could drift them apart again. Extracts `disclosureChevronClass` into
chip-chrome as the single source and points the section header and both sidebar
trees at it. Adds `chipIconSlotClass` for the 16px slot that ChipChevronDown,
ChipSelect, ChipDropdown and ChipDatePicker each re-derived.
Both Back buttons rendered a ChevronDown rotated 90deg at 10px — wrong glyph, and
4px under every other chevron in the app; they are now ChevronLeft at 14px in that
shared slot. The sidebar file tree drew hand-inlined SVGs at strokeWidth 2 next to
the workflow tree's emcn icons at 1.55, so the two trees showed different folder
glyphs; both now use the emcn set. Its file rows also indented by the chevron's
width alone, landing their icon 4px left of a folder's and 2px smaller despite the
comment claiming they lined up — they now clear the chevron plus the row gap at
the same 16px size.
Separately, the chat `+`/`@` resource menus rendered every foldered family as a
submenu and only then the flat ones, which pinned Workflows to the top regardless
of any ordering. Adds `RESOURCE_MENU_ORDER` mirroring the sidebar top-down and
merges both kinds into one ordered pass, so the menus read Integrations, Chats,
Tables, Files, Knowledge Bases, Logs, Workflows, then Browser and Terminal on
desktop. Documents the general rule in .claude/rules/sim-list-ordering.md.
* improvement(ui): order the remaining resource menus the way the user reads them
An audit of every menu, tab strip, and context menu against the surface the user
already reads those items on turned up six more divergences.
The table row context menu put View execution before the Run/Re-run/Stop cluster
while the action bar puts it after, so the same four actions read in two orders;
the menu now follows the bar. The Files, Tables, and Knowledge empty-space create
menus were each the exact reverse of their own page header, and each named the
same action differently ("Create table" vs "New table", "Add knowledge base" vs
"New base") — reversed to match, labels unified.
Recently Deleted led with Workflows and buried Chats last, and put Knowledge Bases
ahead of Files; it now follows the sidebar after the default All tab. The command
palette hoisted Workflows from last to second for the same reason, and is now in
sidebar order too. Chats stays first in both, so the palette's Enter default is
unchanged.
Drops the unused RESOURCE_TYPES export: nothing consumed it, and its declaration
order was nearly the inverse of RESOURCE_MENU_ORDER, so the first consumer to map
it would have silently rendered a backwards menu.
Not included: buildUnifiedSettingsNavigation never applies its own unified.order
and returns registry declaration order instead. Nothing user-visible today (the
sidebar re-sorts before rendering) but navigation.test.ts pins the unsorted order
as canonical, so fixing it means changing that test — worth doing deliberately
rather than inside this PR.
**A list orders itself the way the user already reads the same things somewhere else.** Dropdowns, context menus, tab strips, command palettes, and settings navs are all *second* presentations of a set the user has already seen — in the sidebar, in a toolbar, in a column-header row. When the second presentation reorders that set, the user re-reads it from scratch every time.
11
+
12
+
This is not a style preference. Order is the cheapest affordance a list has, and the only one that costs nothing to get right.
13
+
14
+
## The rule
15
+
16
+
Before writing a list of items, find where the user sees those same items *first*. That surface owns the order; your list mirrors it.
| A "New …" menu | the order those things appear once created |
24
+
25
+
Left-to-right becomes top-to-bottom. A toolbar reading `Filter · Sort · Export · Delete` becomes a menu reading Filter, Sort, Export, Delete — never alphabetized, never grouped by implementation, never "destructive last" unless the toolbar already puts it last.
26
+
27
+
Platform-only entries (desktop **Browser** and **Terminal**) trail the shared set rather than interleaving, so the common prefix is identical on every platform.
28
+
29
+
## Encode the order once
30
+
31
+
An order duplicated across surfaces is an order that will drift. Export **one** constant and sort by it — do not hand-maintain a matching literal per menu.
32
+
33
+
```ts
34
+
/** Top-down order for every menu listing resource families, mirroring the sidebar. */
Canonical instance: `app/workspace/[workspaceId]/home/components/mothership-view/components/resource-registry/resource-registry.tsx`, consumed by `useAvailableResources` and `ResourceMenuSections`.
46
+
47
+
## Render kinds in one pass, not one phase per kind
48
+
49
+
The most common way a canonical order gets silently defeated: emitting all items of one *kind* and then all of another. Every submenu-backed family lands above every flat family regardless of what the order constant says.
50
+
51
+
```tsx
52
+
// ✗ Bad — two phases; the trees always pin to the top
The same trap appears as "render the pinned ones, then the rest", "render enabled, then disabled", and "render the groups, then the loose items".
63
+
64
+
## When order may diverge
65
+
66
+
Only for reasons the user can perceive:
67
+
68
+
-**Search/filter results** rank by match quality — the whole point is that ranking beats position.
69
+
-**User-controlled ordering** (drag-to-reorder, manual `sortOrder`) wins over any canonical order.
70
+
-**Recency lists** ("Recent chats") order by time, which *is* the order the user reads them elsewhere.
71
+
72
+
"Grouped by which hook provides it", "alphabetical because it was easy", and "that's the order the array was built in" are not reasons.
73
+
74
+
## Reviewing
75
+
76
+
When a diff adds or edits a list of items, ask: where does the user see this set already, and does this match? If the answer is a different file with a different order, the diff needs a shared constant, not a second literal.
Co-locate a `search-params.ts` per feature exporting the parser map (single source of truth, shared by client `useQueryStates`/`useQueryState` and server `createSearchParamsCache`). Never `import { z }` in client code for params — use nuqs parsers. Full decision framework, conventions, the debounced-input pattern, and the workflow-editor carve-out are in `.claude/rules/sim-url-state.md`.
380
380
381
+
## List & Menu Ordering
382
+
383
+
A list orders itself the way the user already reads the same things somewhere else. Resource menus (`+` attach, `@` mention, resource-tab `+`) mirror the **sidebar** top-down; a row or root **context menu** mirrors that surface's **toolbar**, left-to-right becoming top-to-bottom; tab strips mirror their nav. Platform-only entries (desktop Browser, Terminal) trail the shared set.
384
+
385
+
Encode the order in ONE exported constant and sort by it — never a hand-maintained literal per menu (`RESOURCE_MENU_ORDER` / `byResourceMenuOrder` in `home/components/mothership-view/components/resource-registry`). Render mixed item kinds in a single ordered pass; emitting all submenu-backed families and then all flat ones silently pins every submenu to the top no matter what the constant says. Divergence is allowed only for search ranking, user-controlled ordering, and recency. Full rule in `.claude/rules/sim-list-ordering.md`.
386
+
381
387
## Styling
382
388
383
389
Use Tailwind only, no inline styles. Use `cn()` from `@sim/emcn` for conditional classes.
Copy file name to clipboardExpand all lines: apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/add-resource-dropdown/add-resource-dropdown.tsx
Copy file name to clipboardExpand all lines: apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/add-resource-dropdown/index.ts
Copy file name to clipboardExpand all lines: apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-registry/resource-registry.tsx
0 commit comments