mirror of
https://github.com/luxfi/safe-wallet.git
synced 2026-10-30 15:19:21 +00:00
* refactor(spaces): unify Team and Address book tables on shadcn
Both the Spaces "Team" (Members) list and the Address book now render
through a shared PaginatedDataTable built on shadcn table primitives,
replacing the MUI EnhancedTable in MembersList. This keeps each table's
own functionality (member edit/renew/remove, address-book actions,
duplicate dimming, added-by/last-updated column) while sharing one
paginated, consistently-styled table shell.
- Add space between the tabs and the table on the Members page
- Wrap both tables in a rounded `bg-card` container, drop the border line
- Convert member role/declined/expired chips to shadcn Badge and the
email cell to a shadcn Tooltip with truncation
* style(spaces): use muted color for data table column headers
Render the shared PaginatedDataTable column headers with
text-muted-foreground so the header titles read as a subtle gray in
light mode (and a lighter gray in dark mode) instead of the strong
foreground color.
* refactor(spaces): drop MUI from member row actions
Replace the MUI Tooltip/IconButton/SvgIcon in the members Edit and Remove
buttons with shadcn Tooltip + Button, rendering the existing edit/delete
SVGs via fill-current so no MUI is used in MembersList.
* feat(spaces): restore column sorting in the members table
Add opt-in, per-column sorting to the shared PaginatedDataTable (asc →
desc → unsorted, with empty values sorted last) and enable it on the
members Name, Email and Role columns, restoring the sorting the previous
MUI table provided.
* feat(spaces): make address book table sortable, drop redundant name tooltip
Enable column sorting on the address book (name, address, chains by
count, added by / last updated) so both spaces tables sort by default,
and remove the tooltip on the name cell that just repeated the visible
name.
* refactor(spaces): stabilize members data, harden table paging, extract MemberRow
- Memoize useSpaceMembersByStatus (and use a stable empty array) so the
members lists keep a stable identity; without this the shared table's
reset-on-rows-change effect could bounce a paginated members list back
to the first page on unrelated re-renders.
- Clamp the current page in PaginatedDataTable so a shrinking data set
can never strand the user on an empty page, and pull the sort
indicator into a small SortIcon/ariaSortValue helper.
- Extract the inline members renderRow into a MemberRow component.
* refactor(spaces): drop redundant per-component dark wrappers, inherit from root ShadcnProvider
The Members and Address book components re-derived dark mode via useDarkMode()
and re-applied a `shadcn-scope`/`dark` wrapper, but the whole app is already
wrapped in <ShadcnProvider dark={isDarkMode}> at the root (_app.tsx). Since the
shadcn CSS variables inherit, the dark theme already cascades down — the local
wrappers were redundant. Rely on the root provider instead (dark mode set
globally, cascading through stylesheets).
* feat(spaces): make Members and Address book tables responsive on mobile
Hide secondary columns below 768px and surface their data elsewhere so the
shared PaginatedDataTable no longer overflows on small screens:
- PaginatedDataTable: renderRow -> renderCell(row, column) so the component
owns each cell and injects responsive classes once per column. New column
fields: priority ('secondary' hides <768px), sticky (mobile-only pin),
minWidth, cellClassName, cellTestId. Optional renderRowDetail collapsible
mobile row. md:table-fixed keeps desktop proportions + truncation; mobile
uses auto layout. Pagination buttons get aria-labels.
- Members: email hides on mobile and shows under the name; actions collapse
into a kebab (MemberRowActionsMenu). Extracted useRenewInvite, shared by the
desktop button and the kebab (renew analytics Track preserved on both).
- Address book: name pinned, address shortened on mobile, chains + "Added by"
move into the detail row; actions become a kebab on mobile.
Mobile sorting uses the visible column headers only (no separate control).
* refactor(spaces): co-locate cell renderers with column config in PaginatedDataTable
Replace the table-level renderCell(row, column) switch with a per-column
cell(row) renderer on DataTableColumn. Drops the magic-string `column.id`
switches in MembersList and SpaceAddressBookTable — each column now owns its
own rendering next to its config. `id` stays for React keys and sort state.
* refactor(spaces): replace open className escape hatches with bounded column variants
Decouple styling from the table's data model: DataTableColumn no longer takes
free-form className/cellClassName strings (the drift vector). Styling is now a
bounded, CVA-backed API — align ('start'|'center'|'end'), emphasis
('default'|'strong'), and width (a fixed scale) — so a consumer cannot type a
one-off color/radius/font into a column. Layout/visuals are unchanged
(align:'end' == text-right, emphasis:'strong' == font-bold, width == md:w-[N%]).
First step of the design-system table direction; promoting these variants onto
the shared ui/table.tsx primitive app-wide is the follow-up.
* tests(spaces): drop dead useDarkMode mock from Members test
The Members component no longer consumes useDarkMode (dark mode now
cascades from the root ShadcnProvider), so the mock was unused.
* fix(spaces): uniform tab-to-content spacing in Address book
The Workspace/My contacts tabs rendered an action bar (mt-4/mb-4)
between the tabs and the card, while the Pending tab had none, leaving
its card flush against the tabs. Use a constant mt-6 gap on both the
action bar and the content card so the spacing matches across all three
tabs and both data/empty states, consistent with the Members view.
---------
Co-authored-by: Hanzo Dev <[email protected]>