Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
4206d7fd
authored
Jun 19, 2026
by
CaIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(data-table): enhance mobile card view handling and improve layout logic
parent
50b8f2a2
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
42 additions
and
20 deletions
+42
-20
web/default/src/components/data-table/index.ts
+1
-1
web/default/src/components/data-table/layout/data-table-page.tsx
+41
-18
web/default/src/features/channels/components/channels-table.tsx
+0
-1
No files found.
web/default/src/components/data-table/index.ts
View file @
4206d7fd
...
@@ -64,4 +64,4 @@ export const DISABLED_ROW_DESKTOP =
...
@@ -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'
'[--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
=
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)]'
web/default/src/components/data-table/layout/data-table-page.tsx
View file @
4206d7fd
...
@@ -134,17 +134,6 @@ export type DataTablePageProps<TData> = {
...
@@ -134,17 +134,6 @@ export type DataTablePageProps<TData> = {
hideMobile
?:
boolean
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.
* Row className resolver — applied to both desktop `TableRow` and mobile card.
* Composes with the default `data-state="selected"` styling on desktop.
* Composes with the default `data-state="selected"` styling on desktop.
* The `ctx.isMobile` flag is provided so consumers can return the
* The `ctx.isMobile` flag is provided so consumers can return the
...
@@ -235,9 +224,8 @@ export type DataTablePageProps<TData> = {
...
@@ -235,9 +224,8 @@ export type DataTablePageProps<TData> = {
* pages render the table only and behave exactly as before. When enabled, a
* pages render the table only and behave exactly as before. When enabled, a
* {@link DataTableViewModeToggle} is injected into the default toolbar
* {@link DataTableViewModeToggle} is injected into the default toolbar
* (requires `toolbarProps`; ignored when a fully custom `toolbar` is used)
* (requires `toolbarProps`; ignored when a fully custom `toolbar` is used)
* and the desktop view switches between the table and a card grid.
* 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.
* The mobile layout is unaffected — it always renders the mobile list.
*/
*/
enableCardView
?:
boolean
enableCardView
?:
boolean
...
@@ -323,7 +311,7 @@ export function DataTablePage<TData>(props: DataTablePageProps<TData>) {
...
@@ -323,7 +311,7 @@ export function DataTablePage<TData>(props: DataTablePageProps<TData>) {
)
:
undefined
)
:
undefined
const
toolbarNode
=
renderToolbar
(
props
,
viewToggle
)
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
desktopNode
=
renderDesktop
(
props
,
showMobile
,
cardViewActive
,
viewMode
)
const
paginationNode
=
renderPagination
(
props
)
const
paginationNode
=
renderPagination
(
props
)
...
@@ -393,12 +381,15 @@ function renderPagination<TData>(
...
@@ -393,12 +381,15 @@ function renderPagination<TData>(
function
renderMobile
<
TData
>
(
function
renderMobile
<
TData
>
(
props
:
DataTablePageProps
<
TData
>
,
props
:
DataTablePageProps
<
TData
>
,
showMobile
:
boolean
showMobile
:
boolean
,
cardViewActive
:
boolean
,
viewMode
:
DataTableViewMode
):
React
.
ReactNode
{
):
React
.
ReactNode
{
if
(
!
showMobile
)
{
if
(
!
showMobile
)
{
return
null
return
null
}
}
const
isFetchingOnly
=
props
.
isFetching
&&
!
props
.
isLoading
const
ownGetRowClassName
=
props
.
getRowClassName
const
ownGetRowClassName
=
props
.
getRowClassName
const
mobileGetRowClassName
=
const
mobileGetRowClassName
=
props
.
mobileProps
?.
getRowClassName
??
props
.
mobileProps
?.
getRowClassName
??
...
@@ -408,7 +399,36 @@ function renderMobile<TData>(
...
@@ -408,7 +399,36 @@ function renderMobile<TData>(
let
mobileContent
=
props
.
mobile
let
mobileContent
=
props
.
mobile
if
(
mobileContent
===
undefined
)
{
if
(
mobileContent
===
undefined
)
{
mobileContent
=
props
.
mobileCardView
?
(
if
(
cardViewActive
&&
viewMode
===
DATA_TABLE_VIEW_MODES
.
TABLE
)
{
mobileContent
=
(
<
DataTableView
table=
{
props
.
table
}
isLoading=
{
props
.
isLoading
}
emptyTitle=
{
props
.
emptyTitle
}
emptyDescription=
{
props
.
emptyDescription
}
emptyIcon=
{
props
.
emptyIcon
}
emptyAction=
{
props
.
emptyAction
}
skeletonKeyPrefix=
{
props
.
skeletonKeyPrefix
}
renderRow=
{
props
.
renderRow
}
applyHeaderSize=
{
props
.
applyHeaderSize
}
tableHeaderClassName=
{
cn
(
'[background-color:var(--table-header)]'
,
props
.
tableHeaderClassName
)
}
getColumnClassName=
{
props
.
getColumnClassName
}
pinnedColumns=
{
props
.
pinnedColumns
}
containerClassName=
{
cn
(
'transition-opacity duration-150'
,
isFetchingOnly
&&
'pointer-events-none opacity-60'
,
props
.
tableClassName
)
}
getRowClassName=
{
(
row
)
=>
props
.
getRowClassName
?.(
row
,
{
isMobile
:
false
})
}
/>
)
}
else
if
(
cardViewActive
)
{
mobileContent
=
(
<
DataTableCardGrid
<
DataTableCardGrid
table=
{
props
.
table
}
table=
{
props
.
table
}
isLoading=
{
props
.
isLoading
}
isLoading=
{
props
.
isLoading
}
...
@@ -421,7 +441,9 @@ function renderMobile<TData>(
...
@@ -421,7 +441,9 @@ function renderMobile<TData>(
getRowKey=
{
props
.
mobileProps
?.
getRowKey
}
getRowKey=
{
props
.
mobileProps
?.
getRowKey
}
getRowClassName=
{
mobileGetRowClassName
}
getRowClassName=
{
mobileGetRowClassName
}
/>
/>
)
:
(
)
}
else
{
mobileContent
=
(
<
MobileCardList
<
MobileCardList
table=
{
props
.
table
}
table=
{
props
.
table
}
isLoading=
{
props
.
isLoading
}
isLoading=
{
props
.
isLoading
}
...
@@ -432,6 +454,7 @@ function renderMobile<TData>(
...
@@ -432,6 +454,7 @@ function renderMobile<TData>(
/>
/>
)
)
}
}
}
return
<
div
className=
'min-h-0 flex-1 overflow-y-auto'
>
{
mobileContent
}
</
div
>
return
<
div
className=
'min-h-0 flex-1 overflow-y-auto'
>
{
mobileContent
}
</
div
>
}
}
...
...
web/default/src/features/channels/components/channels-table.tsx
View file @
4206d7fd
...
@@ -361,7 +361,6 @@ export function ChannelsTable() {
...
@@ -361,7 +361,6 @@ export function ChannelsTable() {
viewModeStorageKey=
{
CHANNELS_VIEW_MODE_STORAGE_KEY
}
viewModeStorageKey=
{
CHANNELS_VIEW_MODE_STORAGE_KEY
}
renderCard=
{
(
row
)
=>
<
ChannelCard
row=
{
row
}
/>
}
renderCard=
{
(
row
)
=>
<
ChannelCard
row=
{
row
}
/>
}
cardGridClassName=
'grid grid-cols-1 gap-3 sm:gap-4 lg:grid-cols-2 2xl:grid-cols-3'
cardGridClassName=
'grid grid-cols-1 gap-3 sm:gap-4 lg:grid-cols-2 2xl:grid-cols-3'
mobileCardView
applyHeaderSize
applyHeaderSize
toolbarProps=
{
{
toolbarProps=
{
{
searchPlaceholder
:
t
(
'Filter by name, ID, or key...'
),
searchPlaceholder
:
t
(
'Filter by name, ID, or key...'
),
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment