Conversation
…947) The mods page now renders Page/PageHeader/PageScroll/PageContent and the new Toolbar instead of the legacy MainPage chrome and IconBar, and its table gets the edge-to-edge sticky-header treatment the extensions page uses. The toolbar takes actions rather than components, so a new hook adapts the mod-icons registrations for it — hidden when a condition returns false, disabled when it returns a string, ordered by the registered position, exactly as IconBar showed them. Anything that doesn't fit the width collapses into the overflow menu, which ToolbarGroup already handles. The five toolbar entries that were React components had no equivalent in the action shape, so they are now plain actions with their behaviour carried over: Install From File, Check for Updates, Deploy Mods and Purge Mods in the hook, Manage Rules as a plain registration in mod-dependency-manager. The button components they replace are deleted; CheckModVersionsButton stays because it is still the table's row action. Deliberate differences, all of which the toolbar redesign revisits: - Deploy is highlighted via brand colour rather than the flashing class - Manage Rules loses its unresolved-conflict emphasis - a string condition greys an action out without showing the explanation E2E selectors move from the ids those components carried to the data-testid the toolbar renders.
A sticky-header table scrolls with the page rather than in a pane of its own, so it carries `height: auto` and stopped at its last row. The details pane is positioned against that container, which meant double-clicking a row in a table holding one row opened a pane one row tall. The container now also takes `flex-auto`, and the mods and extensions pages lay their scroll content out as full-height flex columns so there is height to grow into. `flex-auto` rather than `flex-1` keeps the basis on the content, so a table taller than the page still scrolls it. Both page-header toolbars take `flex-1 justify-end` for the same sort of reason: as a flex item a toolbar is sized by its content, and a toolbar sized by its content can't tell how much room it has, so it kept every action and ran over the page title instead of collapsing into its overflow menu. Growing rather than only shrinking is what lets it expand again when space returns. The mods toolbar moves out of ModList into a component of its own.
The row reads Install From File, Open, History, Check for Updates, Categories, Manage Rules, which moves Open to position 30 and History to 40. Position is a single ordering for the row and the overflow menu both, so those two move up the menu as well. Open is new here: the five folder actions move out of `mod-icons` into a group of their own, which the page folds into one button with a menu behind it, so they take one slot on the row between them. `ToolbarPanelButton` now honours `panelRole`, so that menu is styled as a dropdown and focuses its own first row rather than being treated as a panel of settings — it hardcoded the latter. Icons: Manage Rules asks for a "rules" icon of its own rather than borrowing the profile transfer "connection" one, Install From File takes a plus, and an icon name we have no path for now shows a puzzle piece — such a name comes from an extension — rather than a generic shape.
…ton each (LAZ-947) IconBar grouped every `mod-icons` action sharing an icon into one dropdown, labelled with whatever leading words their titles had in common. That is how the five "Open ..." actions came to sit behind an "Open" button, and the two "Import From ..." ones behind an "Import" button, without anyone asking for it. The new toolbar only knew about a hardcoded `mod-icons-open` group, so any action that had relied on the icon grouping became a button of its own — Witcher 3's "Open TW3 Documents Folder", and both importers. An action now lands in one of those menus either by registering into the menu's group, which is how to ask for it going forward, or by registering into `mod-icons` under the menu's icon, which is what extensions we don't ship still do. A menu holding a single action renders as that action rather than a menu of one, the way IconBar did, so a game supporting only one importer doesn't grow a button to reach it.
…LAZ-947) A menu row now takes the same `brand` a Button does, so an action reads the same on a toolbar as it does in the overflow menu it collapsed into — Deploy Mods kept its primary colour on the bar and lost it the moment it collapsed. `IToolbarAction` inherits the brand from `IMenuAction` rather than declaring its own, so there is one union behind both. A row tints its icon and leaves the labels an even column of text to read down; `danger` is the exception and colours the whole row, a destructive action being the one thing in a menu that should be hard to pick by accident. `danger` was already a dropdown-item style but no Button brand answered to it, so it becomes a real brand: the token ramp was there, only the `nxm-button-danger` block and the union value were missing. `DropdownItem` takes a brand too, which lets ToolRow's Delete row drop the class it applied by hand. Also renames `nxm-dropdown-item-active` to `-focus`, along with the props and state behind it. Headless UI 2 deprecated the `active` render prop in favour of `focus`, and in a stylesheet `-active` reads against CSS's own `:active`, which means something else entirely.
…pty state (LAZ-947) Four things that all belonged to the bottom half of the page. The table's multi-selection bar moves out of the table and into the page's own bottom section, above the drop panel. `Table` takes a `footerContainer` and portals the footer into it, so the bar lays out in the page's flow instead of absolutely filling the bottom of the table — which also frees the 48px the rows used to give up to a placeholder keeping them clear of it. A table that passes no container keeps the footer where it was, which is every other table. The drop panel gains a wrapper of its own to position against, since the bar is now a sibling of it inside that section: the collapse toggle is absolute, and with the `relative` still on the section it would have been positioning against a box holding both. Collapsing reaches only the dropzone. The hint standing in for the bar below two selections becomes an `Alert`. It is still dismissed for good — `UsageAlert` keeps the decision in `settings.interface.usage` under the same id `Usage` used, so anyone who has already dismissed it won't see this one either. `Usage` stays for its four other callers, which use the reopenable `persistent` mode this doesn't offer. "Get more mods" stops sticking to the bottom of the page as you scroll and sits after the last row, the page rather than the table being what scrolls now. Its translucent band goes with the sticky, nothing passing behind it any more. The empty state becomes `NoResults`, and its way out is a button named for the game — "Get Skyrim SE mods" rather than "But don't worry, I know a place...", which moves up to the message. Where more than one source offers somewhere to browse it becomes a menu, on the design-system `Dropdown` rather than the bootstrap one the bar still uses. The filter deciding that is now shared with the bar rather than written out twice. The details pane a row opens on a double click is positioned against the table container, and a sticky-header table is as tall as its rows and as wide as its columns — so the pane stood the full height of the table and slid out of view as the page scrolled sideways. A layer between the two sticks to the top right of the page scroll instead and stands as tall as it, which keeps the pane on the part of the table you can see. The container spans the columns the table overflows into, sticking only carrying as far as the containing block, and the scroll region becomes a size container so the layer has something to measure. The pane's collapse button takes the scrollbar's width as padding, or its icon would sit behind a horizontal scrollbar.
|
This PR has conflicts. You need to rebase the PR before it can be merged. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
https://linear.app/nexus-mods/issue/LAZ-947/implement-redesign-of-mods-page-layout-toolbar-and-table
Page & toolbar — The page renders
Page/PageHeader/PageScroll/PageContent and the new Toolbar instead of MainPage chrome and IconBar; the table gets the edge-to-edge sticky-header treatment the extensions page uses. A new hook adapts the existing mod-icons registrations into toolbar actions — hidden on a false condition, disabled on a string, ordered by registered position, as IconBar showed them. The five entries that were React components become plain actions (Install From File, Check for Updates, Deploy, Purge in the hook; Manage Rules in mod-dependency-manager) and their button components are deleted.
Order & icons
The row reads Install From File, Open, History, Check for Updates, Categories, Manage Rules. The "Open …" and "Import From …" actions each fold behind one button again, now via explicit groups rather than IconBar's icon-matching; a menu holding one action renders as that action. Manage Rules gets a rules icon of its own, Install From File a plus, and an unknown icon name shows a puzzle piece.
Menu/Button primitives
Menu rows take the same brand a Button does, so an action looks the same on the bar and in the overflow menu it collapses into; danger becomes a real Button brand; nxm-dropdown-item-active is renamed -focus (Headless UI 2 deprecated active, and -active misreads against CSS :active).
Bottom of the page
The multi-selection bar portals out of the table into the page's own bottom section via a new footerContainer prop (other tables keep the footer where it was), freeing the 48px the rows gave up to a placeholder. The two-selection hint becomes UsageAlert, keyed the same as Usage so existing dismissals carry. "Get more mods" stops sticking to the bottom, and the empty state becomes NoResults with a game-named button (or menu, where several sources offer one).
Table sizing & details pane
A sticky-header table's container takes flex-auto and spans the columns it overflows into. The details pane a double click opens now sticks to the top/bottom/right of the page scroll rather than standing the full height of the table and sliding out of view on horizontal scroll; PageScroll becomes a size container so it has something to measure.
Toolbar labels
The Open and Import buttons get their
...back, appended to the label so the words stay the translated key. Manage Rules now names its unresolved conflicts in the tooltip ("Manage Rules (3 unresolved conflicts)") instead of losing the flash it used to get: an action can carry anoticein its options, which the toolbar brackets after the title.mod-dependency-managerowns the text and now stores the count, not just a boolean.Deliberate differences,
All revisited by the toolbar redesign: Deploy is highlighted by brand colour rather than the flashing class.