Refactor ColumnDetailPanel and AppLayout for improved loading state handling and UI consistency. Enhance TabBar and TableListComponent styles for better user experience. Update V2SplitPanelLayoutConfigPanel to manage button visibility based on configuration. Introduce filter chips in TableListComponent for better filter management.

This commit is contained in:
DDD1542 2026-03-17 22:02:52 +09:00
parent b293d184bb
commit 13b2ebaf1f
5 changed files with 124 additions and 92 deletions

View File

@ -359,20 +359,10 @@ const RealtimePreviewDynamicComponent: React.FC<RealtimePreviewProps> = ({
return `${actualHeight}px`;
}
// 런타임 모드에서 컴포넌트 타입별 높이 처리
// 런타임 모드: ResponsiveGridRenderer가 ratio 기반으로 래퍼 높이를 설정하므로,
// 안쪽 컴포넌트는 "100%"로 래퍼를 채워야 비율이 정확하게 맞음
if (!isDesignMode) {
const compType = (component as any).componentType || component.componentConfig?.type || "";
// 테이블: 부모 flex 컨테이너가 높이 관리 (flex: 1)
const flexGrowTypes = [
"table-list", "v2-table-list",
"split-panel-layout", "split-panel-layout2",
"v2-split-panel-layout", "screen-split-panel",
"v2-tab-container", "tab-container",
"tabs-widget", "v2-tabs-widget",
];
if (flexGrowTypes.some(t => compType === t)) {
return "100%";
}
const autoHeightTypes = [
"table-search-widget", "v2-table-search-widget",
"flow-widget",
@ -380,9 +370,11 @@ const RealtimePreviewDynamicComponent: React.FC<RealtimePreviewProps> = ({
if (autoHeightTypes.some(t => compType === t || compType.includes(t))) {
return "auto";
}
// 나머지 모든 타입: 래퍼의 비율 스케일링을 따르도록 100%
return "100%";
}
// 1순위: size.height가 있으면 우선 사용
// 디자인 모드: 고정 픽셀 사용 (캔버스 내 절대 좌표 배치)
if (size?.height && size.height > 0) {
if (component.componentConfig?.type === "table-list") {
return `${Math.max(size.height, 200)}px`;
@ -390,17 +382,14 @@ const RealtimePreviewDynamicComponent: React.FC<RealtimePreviewProps> = ({
return `${size.height}px`;
}
// 2순위: componentStyle.height (컴포넌트 정의에서 온 기본 스타일)
if (componentStyle?.height) {
return typeof componentStyle.height === "number" ? `${componentStyle.height}px` : componentStyle.height;
}
// 3순위: 기본값
if (component.componentConfig?.type === "table-list") {
return "200px";
}
// 기본 높이
return "10px";
};

View File

@ -1410,7 +1410,7 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
const buttonElementStyle: React.CSSProperties = {
width: buttonWidth,
height: buttonHeight,
minHeight: "32px", // 🔧 최소 높이를 32px로 줄임
minHeight: undefined, // 비율 스케일링 시 래퍼 높이를 정확히 따르도록 제거
// 커스텀 테두리 스타일 (StyleEditor 설정 우선, shorthand 사용 안 함)
borderWidth: style?.borderWidth || "0",
borderStyle: (style?.borderStyle as React.CSSProperties["borderStyle"]) || (style?.borderWidth ? "solid" : "none"),

View File

@ -22,6 +22,7 @@ import {
FileSpreadsheet,
List,
PanelRight,
GripVertical,
} from "lucide-react";
import { dataApi } from "@/lib/api/data";
import { entityJoinApi } from "@/lib/api/entityJoin";
@ -313,10 +314,11 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
const [rightFilters, setRightFilters] = useState<TableFilter[]>([]);
const [rightGrouping, setRightGrouping] = useState<string[]>([]);
const [rightColumnVisibility, setRightColumnVisibility] = useState<ColumnVisibility[]>([]);
// 우측 패널 컬럼 헤더 드래그 (디자인 모드에서 순서 변경)
// 우측 패널 컬럼 헤더 드래그 (디자인 + 런타임 순서 변경)
const [rightDraggedColumnIndex, setRightDraggedColumnIndex] = useState<number | null>(null);
const [rightDropTargetColumnIndex, setRightDropTargetColumnIndex] = useState<number | null>(null);
const [rightDragSource, setRightDragSource] = useState<"main" | number | null>(null);
const [runtimeColumnOrder, setRuntimeColumnOrder] = useState<Record<string, number[]>>({});
// 데이터 상태
const [leftData, setLeftData] = useState<any[]>([]);
@ -2544,55 +2546,67 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
handleRightColumnDragEnd();
return;
}
if (!onUpdateComponent) {
handleRightColumnDragEnd();
return;
}
const rightPanel = componentConfig.rightPanel || {};
if (source === "main") {
const allColumns = rightPanel.columns || [];
const visibleColumns = allColumns.filter((c: any) => c.showInSummary !== false);
const hiddenColumns = allColumns.filter((c: any) => c.showInSummary === false);
if (fromIdx < 0 || fromIdx >= visibleColumns.length || targetIndex < 0 || targetIndex >= visibleColumns.length) {
handleRightColumnDragEnd();
return;
if (onUpdateComponent) {
// 디자인 모드: config에 영구 저장
const rightPanel = componentConfig.rightPanel || {};
if (source === "main") {
const allColumns = rightPanel.columns || [];
const visibleColumns = allColumns.filter((c: any) => c.showInSummary !== false);
const hiddenColumns = allColumns.filter((c: any) => c.showInSummary === false);
if (fromIdx < 0 || fromIdx >= visibleColumns.length || targetIndex < 0 || targetIndex >= visibleColumns.length) {
handleRightColumnDragEnd();
return;
}
const reordered = [...visibleColumns];
const [removed] = reordered.splice(fromIdx, 1);
reordered.splice(targetIndex, 0, removed);
const columns = [...reordered, ...hiddenColumns];
onUpdateComponent({
...component,
componentConfig: {
...componentConfig,
rightPanel: { ...rightPanel, columns },
},
});
} else {
const tabs = [...(rightPanel.additionalTabs || [])];
const tabConfig = tabs[source];
if (!tabConfig || !Array.isArray(tabConfig.columns)) {
handleRightColumnDragEnd();
return;
}
const allTabCols = tabConfig.columns;
const visibleTabCols = allTabCols.filter((c: any) => c.showInSummary !== false);
const hiddenTabCols = allTabCols.filter((c: any) => c.showInSummary === false);
if (fromIdx < 0 || fromIdx >= visibleTabCols.length || targetIndex < 0 || targetIndex >= visibleTabCols.length) {
handleRightColumnDragEnd();
return;
}
const reordered = [...visibleTabCols];
const [removed] = reordered.splice(fromIdx, 1);
reordered.splice(targetIndex, 0, removed);
const columns = [...reordered, ...hiddenTabCols];
const newTabs = tabs.map((t, i) => (i === source ? { ...t, columns } : t));
onUpdateComponent({
...component,
componentConfig: {
...componentConfig,
rightPanel: { ...rightPanel, additionalTabs: newTabs },
},
});
}
const reordered = [...visibleColumns];
const [removed] = reordered.splice(fromIdx, 1);
reordered.splice(targetIndex, 0, removed);
const columns = [...reordered, ...hiddenColumns];
onUpdateComponent({
...component,
componentConfig: {
...componentConfig,
rightPanel: { ...rightPanel, columns },
},
});
} else {
const tabs = [...(rightPanel.additionalTabs || [])];
const tabConfig = tabs[source];
if (!tabConfig || !Array.isArray(tabConfig.columns)) {
handleRightColumnDragEnd();
return;
}
const allTabCols = tabConfig.columns;
const visibleTabCols = allTabCols.filter((c: any) => c.showInSummary !== false);
const hiddenTabCols = allTabCols.filter((c: any) => c.showInSummary === false);
if (fromIdx < 0 || fromIdx >= visibleTabCols.length || targetIndex < 0 || targetIndex >= visibleTabCols.length) {
handleRightColumnDragEnd();
return;
}
const reordered = [...visibleTabCols];
const [removed] = reordered.splice(fromIdx, 1);
reordered.splice(targetIndex, 0, removed);
const columns = [...reordered, ...hiddenTabCols];
const newTabs = tabs.map((t, i) => (i === source ? { ...t, columns } : t));
onUpdateComponent({
...component,
componentConfig: {
...componentConfig,
rightPanel: { ...rightPanel, additionalTabs: newTabs },
},
// 런타임 모드: 로컬 상태로 순서 변경
const key = String(source);
setRuntimeColumnOrder((prev) => {
const existing = prev[key];
const maxLen = 100;
const order = existing || Array.from({ length: maxLen }, (_, i) => i);
const reordered = [...order];
const [removed] = reordered.splice(fromIdx, 1);
reordered.splice(targetIndex, 0, removed);
return { ...prev, [key]: reordered };
});
}
handleRightColumnDragEnd();
@ -2604,9 +2618,29 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
component,
onUpdateComponent,
handleRightColumnDragEnd,
setRuntimeColumnOrder,
],
);
// 런타임 컬럼 순서 적용 헬퍼
const applyRuntimeOrder = useCallback(
<T,>(columns: T[], source: "main" | number): T[] => {
const key = String(source);
const order = runtimeColumnOrder[key];
if (!order) return columns;
const result: T[] = [];
for (const idx of order) {
if (idx < columns.length) result.push(columns[idx]);
}
// order에 없는 나머지 컬럼 추가
for (let i = 0; i < columns.length; i++) {
if (!order.includes(i)) result.push(columns[i]);
}
return result.length > 0 ? result : columns;
},
[runtimeColumnOrder],
);
// 수정 모달 저장
const handleEditModalSave = useCallback(async () => {
const tableName =
@ -3946,11 +3980,10 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
{resizable && (
<div
onMouseDown={handleMouseDown}
className="group flex w-1.5 cursor-col-resize flex-col items-center justify-center gap-0.5 bg-border transition-colors hover:bg-primary"
className="group flex w-1.5 cursor-col-resize flex-col items-center justify-center gap-0.5 bg-border/60 transition-colors hover:bg-primary/25"
aria-label="분할선 드래그"
>
<div className="h-7 w-0.5 rounded-full bg-muted-foreground/40 transition-colors group-hover:bg-primary-foreground/80" />
<div className="h-7 w-0.5 rounded-full bg-muted-foreground/40 transition-colors group-hover:bg-primary-foreground/80" />
<div className="h-7 w-0.5 rounded-full bg-muted-foreground/30 transition-opacity group-hover:opacity-70" />
</div>
)}
@ -4107,7 +4140,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
// showInSummary가 false가 아닌 것만 메인 테이블에 표시
const tabSummaryColumns = tabColumns.filter((col: any) => col.showInSummary !== false);
const tabIndex = activeTabIndex - 1;
const canDragTabColumns = isDesignMode && tabSummaryColumns.length > 0 && !!onUpdateComponent;
const canDragTabColumns = tabSummaryColumns.length > 0;
return (
<div className="h-full overflow-auto">
<table className="w-full text-sm">
@ -4120,7 +4153,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
<th
key={col.name}
className={cn(
"text-muted-foreground px-3 py-[7px] text-left text-[9px] font-bold uppercase tracking-[0.04em]",
"group/th text-muted-foreground relative px-3 py-[7px] text-left text-[9px] font-bold uppercase tracking-[0.04em]",
isDropTarget && "border-l-[3px] border-l-primary bg-primary/5",
canDragTabColumns && "cursor-grab active:cursor-grabbing",
isDragging && "opacity-50",
@ -4131,6 +4164,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
onDragEnd={handleRightColumnDragEnd}
onDrop={(e) => canDragTabColumns && handleRightColumnDrop(e, idx, tabIndex)}
>
{canDragTabColumns && <GripVertical className="text-muted-foreground/30 group-hover/th:text-muted-foreground/60 absolute top-1/2 left-0.5 h-3 w-3 -translate-y-1/2 transition-opacity" />}
{col.label || col.name}
</th>
);
@ -4158,7 +4192,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
<tr
className={cn(
"group/action cursor-pointer border-b border-border/50 transition-[background] duration-75",
isTabExpanded ? "bg-primary/5" : idx % 2 === 1 ? "bg-muted/50 hover:bg-accent" : "hover:bg-accent",
isTabExpanded ? "bg-primary/5" : idx % 2 === 1 ? "bg-muted/20 hover:bg-accent" : "hover:bg-accent",
)}
onClick={() => toggleRightItemExpansion(`tab_${activeTabIndex}_${tabItemId}`)}
>
@ -4243,7 +4277,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
// showInSummary가 false가 아닌 것만 메인 테이블에 표시
const listSummaryColumns = tabColumns.filter((col: any) => col.showInSummary !== false);
const listTabIndex = activeTabIndex - 1;
const canDragListTabColumns = isDesignMode && listSummaryColumns.length > 0 && !!onUpdateComponent;
const canDragListTabColumns = listSummaryColumns.length > 0;
return (
<div className="h-full overflow-auto">
<table className="w-full text-sm">
@ -4256,7 +4290,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
<th
key={col.name}
className={cn(
"text-muted-foreground px-3 py-[7px] text-left text-[9px] font-bold uppercase tracking-[0.04em]",
"group/th text-muted-foreground relative px-3 py-[7px] text-left text-[9px] font-bold uppercase tracking-[0.04em]",
isDropTarget && "border-l-[3px] border-l-primary bg-primary/5",
canDragListTabColumns && "cursor-grab active:cursor-grabbing",
isDragging && "opacity-50",
@ -4267,6 +4301,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
onDragEnd={handleRightColumnDragEnd}
onDrop={(e) => canDragListTabColumns && handleRightColumnDrop(e, idx, listTabIndex)}
>
{canDragListTabColumns && <GripVertical className="text-muted-foreground/30 group-hover/th:text-muted-foreground/60 absolute top-1/2 left-0.5 h-3 w-3 -translate-y-1/2 transition-opacity" />}
{col.label || col.name}
</th>
);
@ -4293,7 +4328,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
<tr
className={cn(
"group/action cursor-pointer border-b border-border/50 transition-[background] duration-75",
isTabExpanded ? "bg-primary/5" : idx % 2 === 1 ? "bg-muted/50 hover:bg-accent" : "hover:bg-accent",
isTabExpanded ? "bg-primary/5" : idx % 2 === 1 ? "bg-muted/20 hover:bg-accent" : "hover:bg-accent",
)}
onClick={() => toggleRightItemExpansion(`tab_${activeTabIndex}_${tabItemId}`)}
>
@ -4646,6 +4681,14 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
}));
}
// 런타임 컬럼 순서 적용
if (!isDesignMode && runtimeColumnOrder["main"]) {
const keyColCount = columnsToShow.filter((c: any) => c._isKeyColumn).length;
const keyCols = columnsToShow.slice(0, keyColCount);
const dataCols = columnsToShow.slice(keyColCount);
columnsToShow = [...keyCols, ...applyRuntimeOrder(dataCols, "main")];
}
// 컬럼 너비 합계 계산 (작업 컬럼 제외, 100% 초과 시 스크롤)
const rightTotalColWidth = columnsToShow.reduce((sum, col) => {
const w = col.width && col.width <= 100 ? col.width : 0;
@ -4653,7 +4696,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
}, 0);
const rightConfigColumnStart = columnsToShow.filter((c: any) => c._isKeyColumn).length;
const canDragRightColumns = isDesignMode && displayColumns.length > 0 && !!onUpdateComponent;
const canDragRightColumns = displayColumns.length > 0;
return (
<div className="flex h-full w-full flex-col">
@ -4670,7 +4713,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
<th
key={idx}
className={cn(
"text-muted-foreground px-3 py-[7px] text-left text-[9px] font-bold uppercase tracking-[0.04em] whitespace-nowrap",
"group/th text-muted-foreground relative px-3 py-[7px] text-left text-[9px] font-bold uppercase tracking-[0.04em] whitespace-nowrap",
isDropTarget && "border-l-[3px] border-l-primary bg-primary/5",
isDraggable && "cursor-grab active:cursor-grabbing",
isDragging && "opacity-50",
@ -4685,6 +4728,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
onDragEnd={handleRightColumnDragEnd}
onDrop={(e) => isDraggable && handleRightColumnDrop(e, configColIndex, "main")}
>
{isDraggable && <GripVertical className="text-muted-foreground/30 group-hover/th:text-muted-foreground/60 absolute top-1/2 left-0.5 h-3 w-3 -translate-y-1/2 transition-opacity" />}
{col.label}
</th>
);
@ -4707,7 +4751,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
const rightDeleteVisible = (componentConfig.rightPanel?.showDelete ?? componentConfig.rightPanel?.deleteButton?.enabled) !== false;
return (
<tr key={itemId} className={cn("group/action border-b border-border/50 transition-[background] duration-75 hover:bg-accent", idx % 2 === 1 && "bg-muted/50")}>
<tr key={itemId} className={cn("group/action border-b border-border/50 transition-[background] duration-75 hover:bg-accent", idx % 2 === 1 && "bg-muted/20")}>
{columnsToShow.map((col, colIdx) => (
<td
key={colIdx}
@ -4851,7 +4895,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
<tr
className={cn(
"group/action cursor-pointer border-b border-border/50 transition-[background] duration-75",
isExpanded ? "bg-primary/5" : idx % 2 === 1 ? "bg-muted/50 hover:bg-accent" : "hover:bg-accent",
isExpanded ? "bg-primary/5" : idx % 2 === 1 ? "bg-muted/20 hover:bg-accent" : "hover:bg-accent",
)}
onClick={() => toggleRightItemExpansion(itemId)}
>

View File

@ -110,7 +110,7 @@ export const SingleTableWithSticky: React.FC<SingleTableWithStickyProps> = ({
>
<TableHeader
className={cn("border-b border-border/60", tableConfig?.stickyHeader && "sticky top-0 z-30 shadow-sm")}
style={{ backgroundColor: "hsl(var(--muted) / 0.8)" }}
style={{ backgroundColor: "hsl(var(--muted) / 0.4)" }}
>
<TableRow className="border-b border-border/60">
{actualColumns.map((column, colIndex) => {
@ -136,7 +136,7 @@ export const SingleTableWithSticky: React.FC<SingleTableWithStickyProps> = ({
? "h-9 border-0 px-3 py-1.5 text-center align-middle sm:px-4 sm:py-2"
: "text-muted-foreground hover:text-foreground h-9 cursor-pointer border-0 px-3 py-1.5 text-left align-middle text-[10px] font-bold uppercase tracking-[0.04em] whitespace-nowrap transition-all duration-200 select-none sm:px-4 sm:py-2 sm:text-xs",
`text-${column.align}`,
column.sortable && "hover:bg-muted/70",
column.sortable && "hover:bg-muted/50",
// 고정 컬럼 스타일
column.fixed === "left" && "border-border bg-background sticky z-40 border-r shadow-sm",
column.fixed === "right" && "border-border bg-background sticky z-40 border-l shadow-sm",
@ -151,7 +151,7 @@ export const SingleTableWithSticky: React.FC<SingleTableWithStickyProps> = ({
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap", // 텍스트 줄바꿈 방지
backgroundColor: "hsl(var(--muted) / 0.8)",
backgroundColor: "hsl(var(--muted) / 0.4)",
// sticky 위치 설정
...(column.fixed === "left" && { left: leftFixedWidth }),
...(column.fixed === "right" && { right: rightFixedWidth }),
@ -230,7 +230,7 @@ export const SingleTableWithSticky: React.FC<SingleTableWithStickyProps> = ({
key={`row-${index}`}
className={cn(
"cursor-pointer border-b border-border/50 transition-[background] duration-75",
index % 2 === 0 ? "bg-background" : "bg-muted/70",
index % 2 === 0 ? "bg-background" : "bg-muted/20",
tableConfig.tableStyle?.hoverEffect !== false && "hover:bg-accent",
)}
onClick={(e) => handleRowClick?.(row, index, e)}

View File

@ -5819,8 +5819,8 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
{/* 🆕 Multi-Level Headers (Column Bands) */}
{columnBandsInfo?.hasBands && (
<tr
className="border-primary/10 bg-muted/70 h-8 border-b sm:h-10"
style={{ backgroundColor: "hsl(var(--muted) / 0.7)" }}
className="border-border/60 bg-muted/40 h-8 border-b sm:h-10"
style={{ backgroundColor: "hsl(var(--muted) / 0.4)" }}
>
{visibleColumns.map((column, colIdx) => {
// 이 컬럼이 속한 band 찾기
@ -5863,7 +5863,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
<tr
className="bg-muted/80 h-10 border-b border-border/60 sm:h-12"
style={{
backgroundColor: "hsl(var(--muted) / 0.8)",
backgroundColor: "hsl(var(--muted) / 0.4)",
}}
>
{visibleColumns.map((column, columnIndex) => {
@ -5895,7 +5895,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
column.columnName === "__checkbox__" ? "px-0 py-1" : "px-3 py-2",
column.sortable !== false &&
column.columnName !== "__checkbox__" &&
"hover:text-foreground hover:bg-muted/70 cursor-pointer transition-colors",
"hover:text-foreground hover:bg-muted/50 cursor-pointer transition-colors",
sortColumn === column.columnName && "!text-primary",
isFrozen && "sticky z-40 shadow-[2px_0_4px_rgba(0,0,0,0.1)]",
// 🆕 Column Reordering 스타일
@ -5916,7 +5916,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
minWidth: column.columnName === "__checkbox__" ? "48px" : undefined,
maxWidth: column.columnName === "__checkbox__" ? "48px" : undefined,
userSelect: "none",
backgroundColor: "hsl(var(--muted) / 0.8)",
backgroundColor: "hsl(var(--muted) / 0.4)",
...(isFrozen && { left: `${leftPosition}px` }),
}}
// 🆕 Column Reordering 이벤트
@ -6167,7 +6167,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
key={index}
className={cn(
"hover:bg-accent cursor-pointer border-b border-border/50 transition-[background] duration-75",
index % 2 === 0 ? "bg-background" : "bg-muted/70",
index % 2 === 0 ? "bg-background" : "bg-muted/20",
)}
onClick={(e) => handleRowClick(row, index, e)}
>
@ -6306,9 +6306,8 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
key={index}
className={cn(
"hover:bg-accent cursor-pointer border-b border-border/50 transition-[background] duration-75",
index % 2 === 0 ? "bg-background" : "bg-muted/70",
isRowSelected && "!bg-primary/15 hover:!bg-primary/20",
isRowSelected && "[&_td]:!border-b-primary/30",
index % 2 === 0 ? "bg-background" : "bg-muted/20",
isRowSelected && "!bg-primary/10 hover:!bg-primary/15",
isRowFocused && "ring-primary/50 ring-1 ring-inset",
isDragEnabled && "cursor-grab active:cursor-grabbing",
isDragging && "bg-muted opacity-50",
@ -6566,7 +6565,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
: undefined,
...(isFrozen && {
left: `${leftPosition}px`,
backgroundColor: "hsl(var(--muted) / 0.8)",
backgroundColor: "hsl(var(--muted) / 0.4)",
}),
}}
>