From 4206d7fd585b72c6f8163592aa69dc7104413a28 Mon Sep 17 00:00:00 2001 From: CaIon Date: Fri, 19 Jun 2026 19:58:20 +0800 Subject: [PATCH] feat(data-table): enhance mobile card view handling and improve layout logic --- .../src/components/data-table/index.ts | 2 +- .../data-table/layout/data-table-page.tsx | 101 +++++++++++------- .../channels/components/channels-table.tsx | 1 - 3 files changed, 63 insertions(+), 41 deletions(-) diff --git a/web/default/src/components/data-table/index.ts b/web/default/src/components/data-table/index.ts index 1b6dd233..0a7db461 100644 --- a/web/default/src/components/data-table/index.ts +++ b/web/default/src/components/data-table/index.ts @@ -64,4 +64,4 @@ export const DISABLED_ROW_DESKTOP = '[--data-table-card-bg:var(--table-disabled)] hover:[--data-table-card-bg:var(--table-disabled-hover)] [background-color:var(--table-disabled)] hover:[background-color:var(--table-disabled-hover)] [&>td:first-child]:[border-left-color:var(--table-disabled-border)] [&>td:first-child]:border-l-4 [&>td:first-child]:pl-1' export const DISABLED_ROW_MOBILE = - '[--data-table-card-bg:var(--table-disabled)] [background-color:var(--table-disabled)] border-l-4 [border-left-color:var(--table-disabled-border)]' + '[--data-table-card-bg:var(--table-disabled)] [background-color:var(--table-disabled)]' diff --git a/web/default/src/components/data-table/layout/data-table-page.tsx b/web/default/src/components/data-table/layout/data-table-page.tsx index e998d116..7b9049a1 100644 --- a/web/default/src/components/data-table/layout/data-table-page.tsx +++ b/web/default/src/components/data-table/layout/data-table-page.tsx @@ -133,17 +133,6 @@ export type DataTablePageProps = { */ hideMobile?: boolean - /** - * Render the card view on mobile instead of the default {@link MobileCardList}. - * When enabled, the mobile layout reuses the same {@link DataTableCardGrid} - * (and therefore `renderCard` / `cardGridClassName`) as the desktop card view, - * stacked in a single column. Falls back to the generic card content when no - * `renderCard` is provided. Ignored when a custom `mobile` slot is supplied. - * - * Defaults to `false`, so existing pages keep the list-style mobile layout. - */ - mobileCardView?: boolean - /** * Row className resolver — applied to both desktop `TableRow` and mobile card. * Composes with the default `data-state="selected"` styling on desktop. @@ -235,9 +224,8 @@ export type DataTablePageProps = { * pages render the table only and behave exactly as before. When enabled, a * {@link DataTableViewModeToggle} is injected into the default toolbar * (requires `toolbarProps`; ignored when a fully custom `toolbar` is used) - * and the desktop view switches between the table and a card grid. - * - * The mobile layout is unaffected — it always renders the mobile list. + * and the view switches between the table and a card grid on desktop and + * mobile. Mobile card mode reuses the same card renderer in a single column. */ enableCardView?: boolean @@ -323,7 +311,7 @@ export function DataTablePage(props: DataTablePageProps) { ) : undefined const toolbarNode = renderToolbar(props, viewToggle) - const mobileNode = renderMobile(props, showMobile) + const mobileNode = renderMobile(props, showMobile, cardViewActive, viewMode) const desktopNode = renderDesktop(props, showMobile, cardViewActive, viewMode) const paginationNode = renderPagination(props) @@ -393,12 +381,15 @@ function renderPagination( function renderMobile( props: DataTablePageProps, - showMobile: boolean + showMobile: boolean, + cardViewActive: boolean, + viewMode: DataTableViewMode ): React.ReactNode { if (!showMobile) { return null } + const isFetchingOnly = props.isFetching && !props.isLoading const ownGetRowClassName = props.getRowClassName const mobileGetRowClassName = props.mobileProps?.getRowClassName ?? @@ -408,29 +399,61 @@ function renderMobile( let mobileContent = props.mobile if (mobileContent === undefined) { - mobileContent = props.mobileCardView ? ( - - ) : ( - - ) + if (cardViewActive && viewMode === DATA_TABLE_VIEW_MODES.TABLE) { + mobileContent = ( + + props.getRowClassName?.(row, { isMobile: false }) + } + /> + ) + } else if (cardViewActive) { + mobileContent = ( + + ) + } else { + mobileContent = ( + + ) + } } return
{mobileContent}
diff --git a/web/default/src/features/channels/components/channels-table.tsx b/web/default/src/features/channels/components/channels-table.tsx index 1e312e29..df2979e6 100644 --- a/web/default/src/features/channels/components/channels-table.tsx +++ b/web/default/src/features/channels/components/channels-table.tsx @@ -361,7 +361,6 @@ export function ChannelsTable() { viewModeStorageKey={CHANNELS_VIEW_MODE_STORAGE_KEY} renderCard={(row) => } cardGridClassName='grid grid-cols-1 gap-3 sm:gap-4 lg:grid-cols-2 2xl:grid-cols-3' - mobileCardView applyHeaderSize toolbarProps={{ searchPlaceholder: t('Filter by name, ID, or key...'),