mirror of
https://github.com/KwiTsukasa/kt-template-admin.git
synced 2026-05-27 16:35:47 +08:00
perf: 优化KtTable布局与滚动性能
This commit is contained in:
parent
dcb32e6037
commit
1c342d3ab3
@ -136,6 +136,7 @@ export default defineComponent({
|
|||||||
scheduleTableLayout,
|
scheduleTableLayout,
|
||||||
tableBodyRef,
|
tableBodyRef,
|
||||||
tableScrollY,
|
tableScrollY,
|
||||||
|
tableViewportWidth,
|
||||||
} = useKtTableLayout({ hasSummary });
|
} = useKtTableLayout({ hasSummary });
|
||||||
|
|
||||||
const context: KtTableContext = {
|
const context: KtTableContext = {
|
||||||
@ -187,6 +188,7 @@ export default defineComponent({
|
|||||||
props,
|
props,
|
||||||
rowActions,
|
rowActions,
|
||||||
scheduleTableLayout,
|
scheduleTableLayout,
|
||||||
|
tableViewportWidth,
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -451,7 +453,7 @@ export default defineComponent({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ASpace class="kt-table__row-actions" size={1}>
|
<ASpace class="kt-table__row-actions" size={0}>
|
||||||
{inlineActions.map((action) => renderRowAction(action, record))}
|
{inlineActions.map((action) => renderRowAction(action, record))}
|
||||||
{overflowActions.length > 0 ? (
|
{overflowActions.length > 0 ? (
|
||||||
<APopover
|
<APopover
|
||||||
@ -555,6 +557,27 @@ export default defineComponent({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成表格布局监听签名,只收集会影响容器高度、横向滚动和列宽的轻量信号。
|
||||||
|
* 行内字段变化仍由 Vue/Antdv 正常渲染,不再触发布局重算,避免 deep watch 遍历整页数据。
|
||||||
|
*/
|
||||||
|
function createLayoutWatchKey() {
|
||||||
|
return columns.value
|
||||||
|
.map((column) =>
|
||||||
|
[
|
||||||
|
column.key,
|
||||||
|
Array.isArray(column.dataIndex)
|
||||||
|
? column.dataIndex.join('.')
|
||||||
|
: column.dataIndex,
|
||||||
|
column.width,
|
||||||
|
column.fixed,
|
||||||
|
]
|
||||||
|
.map((value) => String(value ?? ''))
|
||||||
|
.join(':'),
|
||||||
|
)
|
||||||
|
.join('|');
|
||||||
|
}
|
||||||
|
|
||||||
expose(registerApi);
|
expose(registerApi);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@ -569,13 +592,17 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
[columns, rows, searchVisible, fullscreen, tableSize],
|
() => [
|
||||||
|
createLayoutWatchKey(),
|
||||||
|
rows.value.length,
|
||||||
|
searchVisible.value,
|
||||||
|
fullscreen.value,
|
||||||
|
tableSize.value,
|
||||||
|
hasSummary.value,
|
||||||
|
],
|
||||||
() => {
|
() => {
|
||||||
scheduleTableLayout();
|
scheduleTableLayout();
|
||||||
},
|
},
|
||||||
{
|
|
||||||
deep: true,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
|
|||||||
@ -186,6 +186,20 @@ export default defineComponent({
|
|||||||
return h('th', attrs, slots.default?.());
|
return h('th', attrs, slots.default?.());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!props.onResize) {
|
||||||
|
return h(
|
||||||
|
'th',
|
||||||
|
{
|
||||||
|
...attrs,
|
||||||
|
style: {
|
||||||
|
...(attrs.style as Record<string, unknown> | undefined),
|
||||||
|
width: `${props.width}px`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
slots.default?.(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return h(
|
return h(
|
||||||
'th',
|
'th',
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,8 +2,12 @@ import type { KtTableFormGridOptions } from '../types';
|
|||||||
|
|
||||||
export const KT_TABLE_ACTION_COLUMN_KEY = '__kt_table_actions__';
|
export const KT_TABLE_ACTION_COLUMN_KEY = '__kt_table_actions__';
|
||||||
|
|
||||||
|
export const KT_TABLE_ACTION_COLUMN_WIDTH = 112;
|
||||||
|
|
||||||
export const KT_TABLE_INDEX_COLUMN_KEY = '__kt_table_index__';
|
export const KT_TABLE_INDEX_COLUMN_KEY = '__kt_table_index__';
|
||||||
|
|
||||||
|
export const KT_TABLE_INDEX_COLUMN_WIDTH = 40;
|
||||||
|
|
||||||
export const KT_TABLE_ROW_ACTION_OVERFLOW_LIMIT = 3;
|
export const KT_TABLE_ROW_ACTION_OVERFLOW_LIMIT = 3;
|
||||||
|
|
||||||
export const KT_TABLE_ROW_ACTION_VISIBLE_COUNT = 2;
|
export const KT_TABLE_ROW_ACTION_VISIBLE_COUNT = 2;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import type { TableColumnType } from 'antdv-next';
|
import type { TableColumnType } from 'antdv-next';
|
||||||
|
|
||||||
import type { ComputedRef } from 'vue';
|
import type { ComputedRef, Ref } from 'vue';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
KtTableRecord,
|
KtTableRecord,
|
||||||
@ -12,8 +12,9 @@ import { computed, reactive, ref, watch } from 'vue';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
KT_TABLE_ACTION_COLUMN_KEY,
|
KT_TABLE_ACTION_COLUMN_KEY,
|
||||||
|
KT_TABLE_ACTION_COLUMN_WIDTH,
|
||||||
KT_TABLE_INDEX_COLUMN_KEY,
|
KT_TABLE_INDEX_COLUMN_KEY,
|
||||||
KT_TABLE_ROW_ACTION_OVERFLOW_LIMIT,
|
KT_TABLE_INDEX_COLUMN_WIDTH,
|
||||||
} from '../config/constants';
|
} from '../config/constants';
|
||||||
import { getColumnKey } from '../utils/index';
|
import { getColumnKey } from '../utils/index';
|
||||||
|
|
||||||
@ -21,8 +22,18 @@ interface UseKtTableColumnsOptions {
|
|||||||
props: KtTableResolvedProps;
|
props: KtTableResolvedProps;
|
||||||
rowActions: ComputedRef<KtTableRowAction[]>;
|
rowActions: ComputedRef<KtTableRowAction[]>;
|
||||||
scheduleTableLayout: () => void;
|
scheduleTableLayout: () => void;
|
||||||
|
tableViewportWidth: Ref<number>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ColumnResizeHandler = (
|
||||||
|
event: MouseEvent,
|
||||||
|
info: {
|
||||||
|
size: {
|
||||||
|
width: number;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 管理 KtTable 的列顺序、列显隐、列宽拖拽和横向滚动宽度。
|
* 管理 KtTable 的列顺序、列显隐、列宽拖拽和横向滚动宽度。
|
||||||
*
|
*
|
||||||
@ -30,10 +41,12 @@ interface UseKtTableColumnsOptions {
|
|||||||
* @param options.props 表格最终合并后的配置。
|
* @param options.props 表格最终合并后的配置。
|
||||||
* @param options.rowActions 当前行操作按钮列表,用于决定是否追加操作列。
|
* @param options.rowActions 当前行操作按钮列表,用于决定是否追加操作列。
|
||||||
* @param options.scheduleTableLayout 表格布局重算函数,用于列宽变更后同步滚动高度。
|
* @param options.scheduleTableLayout 表格布局重算函数,用于列宽变更后同步滚动高度。
|
||||||
|
* @param options.tableViewportWidth 当前表格容器可视宽度,用于把宽屏剩余宽度分配给业务列。
|
||||||
*/
|
*/
|
||||||
export function useKtTableColumns(options: UseKtTableColumnsOptions) {
|
export function useKtTableColumns(options: UseKtTableColumnsOptions) {
|
||||||
const { props, rowActions, scheduleTableLayout } = options;
|
const { props, rowActions, scheduleTableLayout, tableViewportWidth } =
|
||||||
// 列系统集中处理可见列、拖拽宽度和横向滚动宽度,避免主组件继续堆列计算细节。
|
options;
|
||||||
|
// 列系统集中处理可见列、拖拽宽度和横向滚动启停,避免主组件继续堆列计算细节。
|
||||||
const columnWidths = reactive<Record<string, number>>({});
|
const columnWidths = reactive<Record<string, number>>({});
|
||||||
const columnOrderKeys = ref<string[]>([]);
|
const columnOrderKeys = ref<string[]>([]);
|
||||||
const visibleColumnKeys = ref<string[]>([]);
|
const visibleColumnKeys = ref<string[]>([]);
|
||||||
@ -60,12 +73,54 @@ export function useKtTableColumns(options: UseKtTableColumnsOptions) {
|
|||||||
.map((key) => columnMap.get(key))
|
.map((key) => columnMap.get(key))
|
||||||
.filter(Boolean) as Array<TableColumnType<KtTableRecord>>;
|
.filter(Boolean) as Array<TableColumnType<KtTableRecord>>;
|
||||||
});
|
});
|
||||||
const visibleColumns = computed(() =>
|
const visibleSourceColumns = computed(() =>
|
||||||
orderedSourceColumns.value
|
orderedSourceColumns.value.filter((column) =>
|
||||||
.filter((column) =>
|
|
||||||
visibleColumnKeys.value.includes(getColumnKey(column)),
|
visibleColumnKeys.value.includes(getColumnKey(column)),
|
||||||
)
|
),
|
||||||
.map((column) => normalizeColumnWidth(column)),
|
);
|
||||||
|
const rawTableWidth = computed(() => {
|
||||||
|
const selectionWidth = props.showSelection ? 48 : 0;
|
||||||
|
const indexWidth = props.showIndex ? KT_TABLE_INDEX_COLUMN_WIDTH : 0;
|
||||||
|
const actionWidth =
|
||||||
|
rowActions.value.length > 0 ? KT_TABLE_ACTION_COLUMN_WIDTH : 0;
|
||||||
|
const businessWidth = visibleSourceColumns.value.reduce(
|
||||||
|
(total, column) => total + getColumnRenderWidth(column),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
return selectionWidth + indexWidth + businessWidth + actionWidth;
|
||||||
|
});
|
||||||
|
const tableRenderWidth = computed(() => {
|
||||||
|
const hasFlexibleColumns = visibleSourceColumns.value.length > 0;
|
||||||
|
|
||||||
|
if (!hasFlexibleColumns) {
|
||||||
|
return rawTableWidth.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.max(rawTableWidth.value, tableViewportWidth.value, 720);
|
||||||
|
});
|
||||||
|
const tableScrollX = computed(() => {
|
||||||
|
const viewportWidth = tableViewportWidth.value;
|
||||||
|
|
||||||
|
if (viewportWidth <= 0) return rawTableWidth.value;
|
||||||
|
|
||||||
|
return rawTableWidth.value > viewportWidth + 1
|
||||||
|
? rawTableWidth.value
|
||||||
|
: undefined;
|
||||||
|
});
|
||||||
|
const surplusWidthMap = computed(() =>
|
||||||
|
createFlexibleSurplusMap(
|
||||||
|
visibleSourceColumns.value,
|
||||||
|
Math.max(0, tableRenderWidth.value - rawTableWidth.value),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const visibleColumns = computed(() =>
|
||||||
|
visibleSourceColumns.value.map((column) =>
|
||||||
|
normalizeColumnWidth(
|
||||||
|
column,
|
||||||
|
surplusWidthMap.value.get(getColumnKey(column)) || 0,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
const indexColumn = computed<null | TableColumnType<KtTableRecord>>(() => {
|
const indexColumn = computed<null | TableColumnType<KtTableRecord>>(() => {
|
||||||
if (!props.showIndex) return null;
|
if (!props.showIndex) return null;
|
||||||
@ -75,22 +130,21 @@ export function useKtTableColumns(options: UseKtTableColumnsOptions) {
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
fixed: 'left',
|
fixed: 'left',
|
||||||
key: KT_TABLE_INDEX_COLUMN_KEY,
|
key: KT_TABLE_INDEX_COLUMN_KEY,
|
||||||
minWidth: 40,
|
minWidth: KT_TABLE_INDEX_COLUMN_WIDTH,
|
||||||
title: '序号',
|
title: '序号',
|
||||||
width: 48,
|
width: KT_TABLE_INDEX_COLUMN_WIDTH,
|
||||||
} as TableColumnType<KtTableRecord>);
|
} as TableColumnType<KtTableRecord>);
|
||||||
});
|
});
|
||||||
const actionColumn = computed<null | TableColumnType<KtTableRecord>>(() => {
|
const actionColumn = computed<null | TableColumnType<KtTableRecord>>(() => {
|
||||||
if (rowActions.value.length === 0) return null;
|
if (rowActions.value.length === 0) return null;
|
||||||
const actionColumnWidth = resolveActionColumnWidth(rowActions.value.length);
|
|
||||||
|
|
||||||
return normalizeColumnWidth({
|
return normalizeColumnWidth({
|
||||||
className: 'kt-table__action-column',
|
className: 'kt-table__action-column',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
key: KT_TABLE_ACTION_COLUMN_KEY,
|
key: KT_TABLE_ACTION_COLUMN_KEY,
|
||||||
minWidth: actionColumnWidth,
|
minWidth: KT_TABLE_ACTION_COLUMN_WIDTH,
|
||||||
title: '操作',
|
title: '操作',
|
||||||
width: actionColumnWidth,
|
width: KT_TABLE_ACTION_COLUMN_WIDTH,
|
||||||
} as TableColumnType<KtTableRecord>);
|
} as TableColumnType<KtTableRecord>);
|
||||||
});
|
});
|
||||||
const columns = computed(
|
const columns = computed(
|
||||||
@ -99,16 +153,6 @@ export function useKtTableColumns(options: UseKtTableColumnsOptions) {
|
|||||||
Boolean,
|
Boolean,
|
||||||
) as Array<TableColumnType<KtTableRecord>>,
|
) as Array<TableColumnType<KtTableRecord>>,
|
||||||
);
|
);
|
||||||
const tableScrollX = computed(() =>
|
|
||||||
Math.max(
|
|
||||||
columns.value.reduce(
|
|
||||||
(total, column) => total + readColumnWidth(column.width, 140),
|
|
||||||
props.showSelection ? 48 : 0,
|
|
||||||
),
|
|
||||||
720,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
sourceColumns,
|
sourceColumns,
|
||||||
(nextColumns) => {
|
(nextColumns) => {
|
||||||
@ -127,17 +171,6 @@ export function useKtTableColumns(options: UseKtTableColumnsOptions) {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
* 重置列顺序和可见列到源码配置的初始状态。
|
|
||||||
*/
|
|
||||||
function resetColumns() {
|
|
||||||
const sourceKeys = sourceColumns.value
|
|
||||||
.map((column) => getColumnKey(column))
|
|
||||||
.filter(Boolean);
|
|
||||||
columnOrderKeys.value = [...sourceKeys];
|
|
||||||
visibleColumnKeys.value = [...sourceKeys];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将现有列顺序和最新源码列 key 合并,保留用户排序并追加新增列。
|
* 将现有列顺序和最新源码列 key 合并,保留用户排序并追加新增列。
|
||||||
*
|
*
|
||||||
@ -168,6 +201,28 @@ export function useKtTableColumns(options: UseKtTableColumnsOptions) {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空所有业务列拖拽宽度,让列宽回到源码默认配置。
|
||||||
|
*/
|
||||||
|
function resetColumnWidths() {
|
||||||
|
Object.keys(columnWidths).forEach((key) => {
|
||||||
|
Reflect.deleteProperty(columnWidths, key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置列顺序、可见列和拖拽列宽到源码配置的初始状态。
|
||||||
|
*/
|
||||||
|
function resetColumns() {
|
||||||
|
const sourceKeys = sourceColumns.value
|
||||||
|
.map((column) => getColumnKey(column))
|
||||||
|
.filter(Boolean);
|
||||||
|
columnOrderKeys.value = [...sourceKeys];
|
||||||
|
visibleColumnKeys.value = [...sourceKeys];
|
||||||
|
resetColumnWidths();
|
||||||
|
scheduleTableLayout();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将列宽配置解析成数字宽度。
|
* 将列宽配置解析成数字宽度。
|
||||||
*
|
*
|
||||||
@ -195,43 +250,124 @@ export function useKtTableColumns(options: UseKtTableColumnsOptions) {
|
|||||||
function getColumnMinWidth(column: TableColumnType<KtTableRecord>) {
|
function getColumnMinWidth(column: TableColumnType<KtTableRecord>) {
|
||||||
const minWidth = Number((column as any).minWidth || 96);
|
const minWidth = Number((column as any).minWidth || 96);
|
||||||
if (getColumnKey(column) === KT_TABLE_INDEX_COLUMN_KEY) {
|
if (getColumnKey(column) === KT_TABLE_INDEX_COLUMN_KEY) {
|
||||||
return Number.isFinite(minWidth) ? Math.max(minWidth, 40) : 40;
|
return Number.isFinite(minWidth)
|
||||||
|
? Math.max(minWidth, KT_TABLE_INDEX_COLUMN_WIDTH)
|
||||||
|
: KT_TABLE_INDEX_COLUMN_WIDTH;
|
||||||
}
|
}
|
||||||
if (getColumnKey(column) === KT_TABLE_ACTION_COLUMN_KEY) {
|
if (getColumnKey(column) === KT_TABLE_ACTION_COLUMN_KEY) {
|
||||||
return Number.isFinite(minWidth) ? Math.max(minWidth, 96) : 112;
|
return Number.isFinite(minWidth)
|
||||||
|
? Math.max(minWidth, KT_TABLE_ACTION_COLUMN_WIDTH)
|
||||||
|
: KT_TABLE_ACTION_COLUMN_WIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Number.isFinite(minWidth) ? Math.max(minWidth, 80) : 96;
|
return Number.isFinite(minWidth) ? Math.max(minWidth, 80) : 96;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据行操作按钮数量计算操作列默认宽度。
|
* 读取列当前渲染宽度,业务列会叠加宽屏剩余宽度,系统列保持固定宽度。
|
||||||
*
|
*
|
||||||
* @param actionCount 当前可见行操作按钮数量。
|
* @param column 当前表格列配置。
|
||||||
|
* @param extraWidth 宽屏下分配给当前业务列的额外宽度。
|
||||||
*/
|
*/
|
||||||
function resolveActionColumnWidth(actionCount: number) {
|
function getColumnRenderWidth(
|
||||||
if (actionCount > KT_TABLE_ROW_ACTION_OVERFLOW_LIMIT) return 112;
|
column: TableColumnType<KtTableRecord>,
|
||||||
if (actionCount === KT_TABLE_ROW_ACTION_OVERFLOW_LIMIT) return 112;
|
extraWidth = 0,
|
||||||
if (actionCount === 2) return 96;
|
) {
|
||||||
|
const key = getColumnKey(column);
|
||||||
|
const width =
|
||||||
|
key && columnWidths[key]
|
||||||
|
? columnWidths[key]
|
||||||
|
: readColumnWidth(column.width, 160);
|
||||||
|
const minWidth = getColumnMinWidth(column);
|
||||||
|
|
||||||
return 80;
|
return Math.max(width + extraWidth, minWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 把宽屏下 Antdv 可能平均分配的剩余宽度提前分摊给业务列,避免系统列被撑大。
|
||||||
|
* 这里的剩余宽度只影响业务列渲染,不直接开启 scroll.x,避免宽屏下常驻横向滚动条。
|
||||||
|
*
|
||||||
|
* @param sourceColumns 当前可见业务列。
|
||||||
|
* @param surplusWidth 表格容器剩余宽度。
|
||||||
|
*/
|
||||||
|
function createFlexibleSurplusMap(
|
||||||
|
sourceColumns: Array<TableColumnType<KtTableRecord>>,
|
||||||
|
surplusWidth: number,
|
||||||
|
) {
|
||||||
|
const map = new Map<string, number>();
|
||||||
|
if (surplusWidth <= 0) return map;
|
||||||
|
|
||||||
|
const entries = sourceColumns
|
||||||
|
.map((column) => ({
|
||||||
|
key: getColumnKey(column),
|
||||||
|
width: getColumnRenderWidth(column),
|
||||||
|
}))
|
||||||
|
.filter(
|
||||||
|
(entry): entry is { key: string; width: number } =>
|
||||||
|
!!entry.key && !isFixedSystemColumn(entry.key),
|
||||||
|
);
|
||||||
|
const totalWidth = entries.reduce((total, entry) => total + entry.width, 0);
|
||||||
|
if (totalWidth <= 0) return map;
|
||||||
|
|
||||||
|
entries.forEach((entry) => {
|
||||||
|
map.set(entry.key, (surplusWidth * entry.width) / totalWidth);
|
||||||
|
});
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断当前列是否为 KtTable 内置系统列。
|
||||||
|
*
|
||||||
|
* @param key 当前列的唯一 key。
|
||||||
|
*/
|
||||||
|
function isFixedSystemColumn(key?: string) {
|
||||||
|
return (
|
||||||
|
key === KT_TABLE_INDEX_COLUMN_KEY || key === KT_TABLE_ACTION_COLUMN_KEY
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建业务列列宽拖拽处理器,系统列固定宽度所以不返回处理器。
|
||||||
|
*
|
||||||
|
* @param column 当前需要绑定拖拽行为的列配置。
|
||||||
|
* @param originalResize 业务侧原始表头 resize 回调。
|
||||||
|
*/
|
||||||
|
function createColumnResizeHandler(
|
||||||
|
column: TableColumnType<KtTableRecord>,
|
||||||
|
originalResize?: ColumnResizeHandler,
|
||||||
|
) {
|
||||||
|
if (isFixedSystemColumn(getColumnKey(column))) return undefined;
|
||||||
|
|
||||||
|
return (event: MouseEvent, info: Parameters<ColumnResizeHandler>[1]) => {
|
||||||
|
originalResize?.(event, info);
|
||||||
|
resizeColumnWidth(column, info.size.width);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 为列注入可拖拽列宽配置并补齐默认 ellipsis。
|
* 为列注入可拖拽列宽配置并补齐默认 ellipsis。
|
||||||
*
|
*
|
||||||
* @param column 当前需要渲染的表格列配置。
|
* @param column 当前需要渲染的表格列配置。
|
||||||
|
* @param extraWidth 宽屏下分配给当前业务列的额外宽度。
|
||||||
*/
|
*/
|
||||||
function normalizeColumnWidth(column: TableColumnType<KtTableRecord>) {
|
function normalizeColumnWidth(
|
||||||
|
column: TableColumnType<KtTableRecord>,
|
||||||
|
extraWidth = 0,
|
||||||
|
) {
|
||||||
const key = getColumnKey(column);
|
const key = getColumnKey(column);
|
||||||
const width =
|
|
||||||
key && columnWidths[key]
|
|
||||||
? columnWidths[key]
|
|
||||||
: readColumnWidth(column.width, 160);
|
|
||||||
const originalHeaderCell = column.onHeaderCell;
|
const originalHeaderCell = column.onHeaderCell;
|
||||||
const originalCell = column.onCell;
|
const originalCell = column.onCell;
|
||||||
const minWidth = getColumnMinWidth(column);
|
const minWidth = getColumnMinWidth(column);
|
||||||
const nextWidth = Math.max(width, minWidth);
|
const nextWidth = getColumnRenderWidth(column, extraWidth);
|
||||||
|
const isSystemColumn = isFixedSystemColumn(key);
|
||||||
|
const fixedWidthStyle = isSystemColumn
|
||||||
|
? {
|
||||||
|
maxWidth: `${nextWidth}px`,
|
||||||
|
minWidth: `${nextWidth}px`,
|
||||||
|
width: `${nextWidth}px`,
|
||||||
|
}
|
||||||
|
: undefined;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...column,
|
...column,
|
||||||
@ -244,24 +380,18 @@ export function useKtTableColumns(options: UseKtTableColumnsOptions) {
|
|||||||
onHeaderCell: (targetColumn: TableColumnType<KtTableRecord>) => {
|
onHeaderCell: (targetColumn: TableColumnType<KtTableRecord>) => {
|
||||||
const originalProps = (originalHeaderCell?.(targetColumn) ||
|
const originalProps = (originalHeaderCell?.(targetColumn) ||
|
||||||
{}) as Record<string, any>;
|
{}) as Record<string, any>;
|
||||||
|
const resizeHandler = createColumnResizeHandler(
|
||||||
|
column,
|
||||||
|
originalProps.onResize,
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...originalProps,
|
...originalProps,
|
||||||
/**
|
onResize: resizeHandler,
|
||||||
* 响应表头拖拽列宽事件。
|
|
||||||
*
|
|
||||||
* @param event 鼠标拖拽事件。
|
|
||||||
* @param info 拖拽组件返回的新尺寸信息。
|
|
||||||
* @param info.size 拖拽后的尺寸对象。
|
|
||||||
* @param info.size.width 拖拽后的列宽。
|
|
||||||
*/
|
|
||||||
onResize: (event: MouseEvent, info: { size: { width: number } }) => {
|
|
||||||
originalProps.onResize?.(event, info);
|
|
||||||
resizeColumnWidth(column, info.size.width);
|
|
||||||
},
|
|
||||||
style: {
|
style: {
|
||||||
...(originalProps.style as Record<string, unknown>),
|
...(originalProps.style as Record<string, unknown>),
|
||||||
minWidth: `${minWidth}px`,
|
minWidth: `${minWidth}px`,
|
||||||
|
...fixedWidthStyle,
|
||||||
},
|
},
|
||||||
width: nextWidth,
|
width: nextWidth,
|
||||||
};
|
};
|
||||||
@ -283,6 +413,7 @@ export function useKtTableColumns(options: UseKtTableColumnsOptions) {
|
|||||||
style: {
|
style: {
|
||||||
...(originalProps.style as Record<string, unknown>),
|
...(originalProps.style as Record<string, unknown>),
|
||||||
minWidth: `${minWidth}px`,
|
minWidth: `${minWidth}px`,
|
||||||
|
...fixedWidthStyle,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,6 +17,7 @@ export function useKtTableLayout(options: UseKtTableLayoutOptions) {
|
|||||||
// 搜索区动画期间冻结表格高度重算,等过渡结束后再同步一次,避免频繁重算导致动画卡顿。
|
// 搜索区动画期间冻结表格高度重算,等过渡结束后再同步一次,避免频繁重算导致动画卡顿。
|
||||||
const tableBodyRef = ref<HTMLElement | null>(null);
|
const tableBodyRef = ref<HTMLElement | null>(null);
|
||||||
const tableScrollY = ref(260);
|
const tableScrollY = ref(260);
|
||||||
|
const tableViewportWidth = ref(0);
|
||||||
const searchTransitioning = ref(false);
|
const searchTransitioning = ref(false);
|
||||||
let layoutFrame: number | undefined;
|
let layoutFrame: number | undefined;
|
||||||
let resizeObserver: ResizeObserver | undefined;
|
let resizeObserver: ResizeObserver | undefined;
|
||||||
@ -51,6 +52,8 @@ export function useKtTableLayout(options: UseKtTableLayoutOptions) {
|
|||||||
const wrapper = tableBodyRef.value;
|
const wrapper = tableBodyRef.value;
|
||||||
if (!wrapper) return;
|
if (!wrapper) return;
|
||||||
|
|
||||||
|
tableViewportWidth.value = wrapper.clientWidth;
|
||||||
|
|
||||||
const header = wrapper.querySelector(
|
const header = wrapper.querySelector(
|
||||||
'.ant-table-header',
|
'.ant-table-header',
|
||||||
) as HTMLElement | null;
|
) as HTMLElement | null;
|
||||||
@ -148,5 +151,6 @@ export function useKtTableLayout(options: UseKtTableLayoutOptions) {
|
|||||||
scheduleTableLayout,
|
scheduleTableLayout,
|
||||||
tableBodyRef,
|
tableBodyRef,
|
||||||
tableScrollY,
|
tableScrollY,
|
||||||
|
tableViewportWidth,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,580 +1,9 @@
|
|||||||
.kt-table {
|
@use './styles/layout';
|
||||||
display: flex;
|
@use './styles/search';
|
||||||
flex-direction: column;
|
@use './styles/header';
|
||||||
height: 100%;
|
@use './styles/table';
|
||||||
min-height: 0;
|
@use './styles/footer';
|
||||||
overflow: hidden;
|
@use './styles/actions';
|
||||||
|
@use './styles/settings';
|
||||||
&--fullscreen {
|
@use './styles/resizable';
|
||||||
position: fixed;
|
@use './styles/responsive';
|
||||||
inset: 0;
|
|
||||||
z-index: 1000;
|
|
||||||
padding: 16px;
|
|
||||||
background: hsl(var(--background));
|
|
||||||
}
|
|
||||||
|
|
||||||
&__main {
|
|
||||||
display: flex;
|
|
||||||
flex: 1 1 0;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
background: hsl(var(--card));
|
|
||||||
}
|
|
||||||
|
|
||||||
&__main-content {
|
|
||||||
display: flex;
|
|
||||||
flex: 1 1 0;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 0;
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__search {
|
|
||||||
--kt-table-form-action-fr: 6fr;
|
|
||||||
--kt-table-form-action-min-width: 180px;
|
|
||||||
--kt-table-form-content-fr: 18fr;
|
|
||||||
--kt-table-form-content-span: 18;
|
|
||||||
--kt-table-form-item-span: 4;
|
|
||||||
--kt-table-form-tablet-columns: 2;
|
|
||||||
|
|
||||||
flex-shrink: 0;
|
|
||||||
padding: 12px 16px 0;
|
|
||||||
background: hsl(var(--card));
|
|
||||||
}
|
|
||||||
|
|
||||||
&__search-content-shell {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__search-content-shell--transitioning {
|
|
||||||
transition: height 0.22s cubic-bezier(0.22, 1, 0.36, 1);
|
|
||||||
will-change: height;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__search-content-motion {
|
|
||||||
min-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__search-content {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__search-form {
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__search-actions {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__search-action-stack {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 8px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-start;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__search-toggle {
|
|
||||||
padding-inline: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__search-toggle-icon {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
transition: transform 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__search-toggle-icon--expanded {
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&__search-split {
|
|
||||||
height: 1px;
|
|
||||||
margin-top: 12px;
|
|
||||||
background: hsl(var(--border));
|
|
||||||
}
|
|
||||||
|
|
||||||
&__form-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__form-item {
|
|
||||||
min-width: 0;
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__form-control {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__header {
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
gap: 12px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__header-align {
|
|
||||||
display: flex;
|
|
||||||
flex: 1 1 0;
|
|
||||||
gap: 12px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-start;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__header-title {
|
|
||||||
min-width: 0;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__header-button {
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 8px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__header-toolbar {
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__header-divider {
|
|
||||||
margin-inline: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__body {
|
|
||||||
--kt-table-scroll-y: 260px;
|
|
||||||
|
|
||||||
position: relative;
|
|
||||||
flex: 1 1 0;
|
|
||||||
min-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
border: 1px solid hsl(var(--border));
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__ant,
|
|
||||||
&__ant .ant-spin-nested-loading,
|
|
||||||
&__ant .ant-spin-container {
|
|
||||||
height: 100%;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__ant {
|
|
||||||
.ant-table,
|
|
||||||
.ant-table-container,
|
|
||||||
.ant-table-content,
|
|
||||||
.ant-table-header,
|
|
||||||
.ant-table-body {
|
|
||||||
overscroll-behavior: contain;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-table table {
|
|
||||||
table-layout: fixed !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-spin-container,
|
|
||||||
.ant-table {
|
|
||||||
display: flex;
|
|
||||||
flex: 1 1 0;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-table-container {
|
|
||||||
display: flex;
|
|
||||||
flex: 1 1 0;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-table-header {
|
|
||||||
position: relative;
|
|
||||||
z-index: 5;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
contain: paint;
|
|
||||||
background: hsl(var(--card));
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-table-body {
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
min-height: 0;
|
|
||||||
max-height: var(--kt-table-scroll-y) !important;
|
|
||||||
contain: paint;
|
|
||||||
overflow: auto !important;
|
|
||||||
scrollbar-gutter: stable;
|
|
||||||
will-change: scroll-position;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-table-summary {
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin-top: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-table-cell {
|
|
||||||
border-bottom-color: hsl(var(--border)) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-table-cell-fix-left,
|
|
||||||
.ant-table-cell-fix-right,
|
|
||||||
.ant-table-cell-fix-start,
|
|
||||||
.ant-table-cell-fix-end {
|
|
||||||
background: hsl(var(--card)) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-table-thead > tr > th.ant-table-cell-fix-left,
|
|
||||||
.ant-table-thead > tr > th.ant-table-cell-fix-right,
|
|
||||||
.ant-table-thead > tr > th.ant-table-cell-fix-start,
|
|
||||||
.ant-table-thead > tr > th.ant-table-cell-fix-end {
|
|
||||||
z-index: 6;
|
|
||||||
background: hsl(var(--card)) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-table-tbody > tr:hover > td.ant-table-cell-fix-left,
|
|
||||||
.ant-table-tbody > tr:hover > td.ant-table-cell-fix-right,
|
|
||||||
.ant-table-tbody > tr:hover > td.ant-table-cell-fix-start,
|
|
||||||
.ant-table-tbody > tr:hover > td.ant-table-cell-fix-end {
|
|
||||||
background: hsl(var(--accent)) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-table-summary .ant-table-cell-fix-left,
|
|
||||||
.ant-table-summary .ant-table-cell-fix-right,
|
|
||||||
.ant-table-summary .ant-table-cell-fix-start,
|
|
||||||
.ant-table-summary .ant-table-cell-fix-end {
|
|
||||||
background: hsl(var(--card)) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 固定列阴影会在横向滚动时随 Antdv shadow class 反复重绘,KT 表格用边框区分固定列即可。
|
|
||||||
.ant-table-cell-fix-start-shadow::after,
|
|
||||||
.ant-table-cell-fix-end-shadow::after,
|
|
||||||
.ant-table-cell-fix-left-last::after,
|
|
||||||
.ant-table-cell-fix-right-first::after {
|
|
||||||
box-shadow: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-table-thead > tr > th {
|
|
||||||
position: relative;
|
|
||||||
top: 0;
|
|
||||||
z-index: 5;
|
|
||||||
background: hsl(var(--card)) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
tfoot.ant-table-summary .ant-table-cell,
|
|
||||||
tfoot.ant-table-summary > tr > td {
|
|
||||||
height: 44px;
|
|
||||||
padding: 0 16px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 20px;
|
|
||||||
color: hsl(var(--foreground));
|
|
||||||
white-space: nowrap;
|
|
||||||
border-bottom: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__body + &__footer {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__footer {
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 12px;
|
|
||||||
align-items: center;
|
|
||||||
min-height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__footer-settings {
|
|
||||||
display: flex;
|
|
||||||
flex: 1 1 0;
|
|
||||||
gap: 12px;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__footer-selection {
|
|
||||||
color: hsl(var(--muted-foreground));
|
|
||||||
}
|
|
||||||
|
|
||||||
&__footer-selection-count {
|
|
||||||
margin-inline: 4px;
|
|
||||||
color: hsl(var(--foreground));
|
|
||||||
}
|
|
||||||
|
|
||||||
&__summary-value {
|
|
||||||
display: inline-flex;
|
|
||||||
gap: 4px;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__summary-label {
|
|
||||||
color: hsl(var(--muted-foreground));
|
|
||||||
}
|
|
||||||
|
|
||||||
&__summary-title {
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__row-actions {
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
.ant-btn {
|
|
||||||
min-width: auto;
|
|
||||||
padding-inline: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__action-column {
|
|
||||||
min-width: 112px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__row-action-more {
|
|
||||||
min-width: 18px;
|
|
||||||
padding-inline: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__row-actions &__row-action-more {
|
|
||||||
min-width: 18px;
|
|
||||||
padding-inline: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__row-action-more-icon {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__button-icon,
|
|
||||||
&__toolbar-icon {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__toolbar-button {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-popover {
|
|
||||||
width: 240px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-popover-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-popover-title {
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-popover-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
max-height: 260px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-column-item {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
gap: 6px;
|
|
||||||
align-items: center;
|
|
||||||
min-height: 32px;
|
|
||||||
padding: 4px 6px;
|
|
||||||
border-radius: 4px;
|
|
||||||
transition:
|
|
||||||
background 0.16s ease,
|
|
||||||
opacity 0.16s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-column-item:hover {
|
|
||||||
background: hsl(var(--accent));
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-column-item::before,
|
|
||||||
&__settings-column-item::after {
|
|
||||||
position: absolute;
|
|
||||||
right: 6px;
|
|
||||||
left: 6px;
|
|
||||||
height: 2px;
|
|
||||||
content: '';
|
|
||||||
background: transparent;
|
|
||||||
border-radius: 999px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-column-item::before {
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-column-item::after {
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-column-item--dragging {
|
|
||||||
opacity: 0.45;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-column-item--drop-before::before,
|
|
||||||
&__settings-column-item--drop-after::after {
|
|
||||||
background: hsl(var(--primary));
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-column-drag {
|
|
||||||
display: inline-flex;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 20px;
|
|
||||||
height: 24px;
|
|
||||||
padding: 0;
|
|
||||||
color: hsl(var(--muted-foreground));
|
|
||||||
cursor: grab;
|
|
||||||
background: transparent;
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-column-drag:active {
|
|
||||||
cursor: grabbing;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-column-drag-icon {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__settings-column-checkbox {
|
|
||||||
flex: 1 1 0;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__resizable-title {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__resizable-handle {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: -4px;
|
|
||||||
bottom: 0;
|
|
||||||
z-index: 4;
|
|
||||||
width: 8px;
|
|
||||||
cursor: col-resize;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__resizable-handle:hover {
|
|
||||||
background: hsl(var(--primary) / 18%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1280px) {
|
|
||||||
.kt-table {
|
|
||||||
&__search-content {
|
|
||||||
grid-template-columns:
|
|
||||||
minmax(0, var(--kt-table-form-content-fr))
|
|
||||||
minmax(
|
|
||||||
var(--kt-table-form-action-min-width),
|
|
||||||
var(--kt-table-form-action-fr)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
&__search-actions,
|
|
||||||
&__search-action-stack {
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__form-grid {
|
|
||||||
grid-template-columns: repeat(
|
|
||||||
var(--kt-table-form-content-span),
|
|
||||||
minmax(0, 1fr)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
&__form-item {
|
|
||||||
grid-column: span var(--kt-table-form-item-span) / span
|
|
||||||
var(--kt-table-form-item-span);
|
|
||||||
}
|
|
||||||
|
|
||||||
&__form-item--collapsed-visible {
|
|
||||||
display: flex !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) and (max-width: 1279px) {
|
|
||||||
.kt-table {
|
|
||||||
&__form-grid {
|
|
||||||
grid-template-columns: repeat(
|
|
||||||
var(--kt-table-form-tablet-columns),
|
|
||||||
minmax(0, 1fr)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
&__form-item {
|
|
||||||
grid-column: span 1 / span 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__form-item--range {
|
|
||||||
grid-column: 1 / -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.kt-table--column-resizing,
|
|
||||||
.kt-table--column-resizing * {
|
|
||||||
cursor: col-resize !important;
|
|
||||||
user-select: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.kt-table__resize-guide {
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
z-index: 3000;
|
|
||||||
width: 1px;
|
|
||||||
pointer-events: none;
|
|
||||||
background: hsl(var(--primary));
|
|
||||||
box-shadow: 0 0 0 1px hsl(var(--primary) / 18%);
|
|
||||||
will-change: transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
.kt-table__row-action-popover-content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 4px;
|
|
||||||
min-width: 72px;
|
|
||||||
|
|
||||||
.ant-btn {
|
|
||||||
justify-content: flex-start;
|
|
||||||
padding-inline: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-reduced-motion: reduce) {
|
|
||||||
.kt-table {
|
|
||||||
&__search-content-shell--transitioning {
|
|
||||||
transition: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -0,0 +1,52 @@
|
|||||||
|
@use './tokens' as kt;
|
||||||
|
|
||||||
|
@include kt.block {
|
||||||
|
&__row-actions {
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
.ant-space-item {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-space-item + .ant-space-item::before {
|
||||||
|
display: inline-block;
|
||||||
|
width: 1px;
|
||||||
|
height: 14px;
|
||||||
|
margin: 0 4px;
|
||||||
|
content: '';
|
||||||
|
background: hsl(var(--border));
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-btn {
|
||||||
|
min-width: auto;
|
||||||
|
padding-inline: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__row-action-more {
|
||||||
|
min-width: 18px;
|
||||||
|
padding-inline: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__row-actions &__row-action-more {
|
||||||
|
min-width: 18px;
|
||||||
|
padding-inline: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__row-action-more-icon {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#{kt.$block}__row-action-popover-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
min-width: 72px;
|
||||||
|
|
||||||
|
.ant-btn {
|
||||||
|
justify-content: flex-start;
|
||||||
|
padding-inline: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
@use './tokens' as kt;
|
||||||
|
|
||||||
|
@include kt.block {
|
||||||
|
&__body + &__footer {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__footer {
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__footer-settings {
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 0;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__footer-selection {
|
||||||
|
color: hsl(var(--muted-foreground));
|
||||||
|
}
|
||||||
|
|
||||||
|
&__footer-selection-count {
|
||||||
|
margin-inline: 4px;
|
||||||
|
color: hsl(var(--foreground));
|
||||||
|
}
|
||||||
|
|
||||||
|
&__summary-value {
|
||||||
|
display: inline-flex;
|
||||||
|
gap: 4px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__summary-label {
|
||||||
|
color: hsl(var(--muted-foreground));
|
||||||
|
}
|
||||||
|
|
||||||
|
&__summary-title {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
@use './tokens' as kt;
|
||||||
|
|
||||||
|
@include kt.block {
|
||||||
|
&__header {
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__header-align {
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 0;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__header-title {
|
||||||
|
min-width: 0;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__header-button {
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__header-toolbar {
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__header-divider {
|
||||||
|
margin-inline: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__button-icon,
|
||||||
|
&__toolbar-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__toolbar-button {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
@use './tokens' as kt;
|
||||||
|
|
||||||
|
@include kt.block {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&--fullscreen {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
padding: 16px;
|
||||||
|
background: hsl(var(--background));
|
||||||
|
}
|
||||||
|
|
||||||
|
&__main {
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 0;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background: hsl(var(--card));
|
||||||
|
}
|
||||||
|
|
||||||
|
&__main-content {
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 0;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
@use './tokens' as kt;
|
||||||
|
|
||||||
|
@include kt.block {
|
||||||
|
&__resizable-title {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__resizable-handle {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: -4px;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 4;
|
||||||
|
width: 8px;
|
||||||
|
cursor: col-resize;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__resizable-handle:hover {
|
||||||
|
background: hsl(var(--primary) / 18%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#{kt.$block}--column-resizing,
|
||||||
|
#{kt.$block}--column-resizing * {
|
||||||
|
cursor: col-resize !important;
|
||||||
|
user-select: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#{kt.$block}__resize-guide {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
z-index: 3000;
|
||||||
|
width: 1px;
|
||||||
|
pointer-events: none;
|
||||||
|
background: hsl(var(--primary));
|
||||||
|
box-shadow: 0 0 0 1px hsl(var(--primary) / 18%);
|
||||||
|
will-change: transform;
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
@use './tokens' as kt;
|
||||||
|
|
||||||
|
@media (min-width: 1280px) {
|
||||||
|
@include kt.block {
|
||||||
|
&__search-content {
|
||||||
|
grid-template-columns:
|
||||||
|
minmax(0, var(--kt-table-form-content-fr))
|
||||||
|
minmax(
|
||||||
|
var(--kt-table-form-action-min-width),
|
||||||
|
var(--kt-table-form-action-fr)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__search-actions,
|
||||||
|
&__search-action-stack {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__form-grid {
|
||||||
|
grid-template-columns: repeat(
|
||||||
|
var(--kt-table-form-content-span),
|
||||||
|
minmax(0, 1fr)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__form-item {
|
||||||
|
grid-column: span var(--kt-table-form-item-span) / span
|
||||||
|
var(--kt-table-form-item-span);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__form-item--collapsed-visible {
|
||||||
|
display: flex !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) and (max-width: 1279px) {
|
||||||
|
@include kt.block {
|
||||||
|
&__form-grid {
|
||||||
|
grid-template-columns: repeat(
|
||||||
|
var(--kt-table-form-tablet-columns),
|
||||||
|
minmax(0, 1fr)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__form-item {
|
||||||
|
grid-column: span 1 / span 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__form-item--range {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
@include kt.block {
|
||||||
|
&__search-content-shell--transitioning {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
@use './tokens' as kt;
|
||||||
|
|
||||||
|
@include kt.block {
|
||||||
|
&__search {
|
||||||
|
--kt-table-form-action-fr: 6fr;
|
||||||
|
--kt-table-form-action-min-width: 180px;
|
||||||
|
--kt-table-form-content-fr: 18fr;
|
||||||
|
--kt-table-form-content-span: 18;
|
||||||
|
--kt-table-form-item-span: 4;
|
||||||
|
--kt-table-form-tablet-columns: 2;
|
||||||
|
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 12px 16px 0;
|
||||||
|
background: hsl(var(--card));
|
||||||
|
}
|
||||||
|
|
||||||
|
&__search-content-shell {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__search-content-shell--transitioning {
|
||||||
|
transition: height 0.22s cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
|
will-change: height;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__search-content-motion {
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__search-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__search-form {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__search-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__search-action-stack {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__search-toggle {
|
||||||
|
padding-inline: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__search-toggle-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
transition: transform 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__search-toggle-icon--expanded {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__search-split {
|
||||||
|
height: 1px;
|
||||||
|
margin-top: 12px;
|
||||||
|
background: hsl(var(--border));
|
||||||
|
}
|
||||||
|
|
||||||
|
&__form-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__form-item {
|
||||||
|
min-width: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__form-control {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,98 @@
|
|||||||
|
@use './tokens' as kt;
|
||||||
|
|
||||||
|
@include kt.block {
|
||||||
|
&__settings-popover {
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__settings-popover-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__settings-popover-title {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__settings-popover-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
max-height: 260px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__settings-column-item {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 32px;
|
||||||
|
padding: 4px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition:
|
||||||
|
background 0.16s ease,
|
||||||
|
opacity 0.16s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__settings-column-item:hover {
|
||||||
|
background: hsl(var(--accent));
|
||||||
|
}
|
||||||
|
|
||||||
|
&__settings-column-item::before,
|
||||||
|
&__settings-column-item::after {
|
||||||
|
position: absolute;
|
||||||
|
right: 6px;
|
||||||
|
left: 6px;
|
||||||
|
height: 2px;
|
||||||
|
content: '';
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 999px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__settings-column-item::before {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__settings-column-item::after {
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__settings-column-item--dragging {
|
||||||
|
opacity: 0.45;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__settings-column-item--drop-before::before,
|
||||||
|
&__settings-column-item--drop-after::after {
|
||||||
|
background: hsl(var(--primary));
|
||||||
|
}
|
||||||
|
|
||||||
|
&__settings-column-drag {
|
||||||
|
display: inline-flex;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 20px;
|
||||||
|
height: 24px;
|
||||||
|
padding: 0;
|
||||||
|
color: hsl(var(--muted-foreground));
|
||||||
|
cursor: grab;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__settings-column-drag:active {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__settings-column-drag-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__settings-column-checkbox {
|
||||||
|
flex: 1 1 0;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
159
apps/web-antdv-next/src/components/ktTable/styles/table.scss
Normal file
159
apps/web-antdv-next/src/components/ktTable/styles/table.scss
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
@use './tokens' as kt;
|
||||||
|
|
||||||
|
@include kt.block {
|
||||||
|
&__body {
|
||||||
|
--kt-table-scroll-y: 260px;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
flex: 1 1 0;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid hsl(var(--border));
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__ant,
|
||||||
|
&__ant .ant-spin-nested-loading,
|
||||||
|
&__ant .ant-spin-container {
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__ant {
|
||||||
|
.ant-table,
|
||||||
|
.ant-table-container,
|
||||||
|
.ant-table-content,
|
||||||
|
.ant-table-header,
|
||||||
|
.ant-table-body {
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table table {
|
||||||
|
table-layout: fixed !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-spin-container,
|
||||||
|
.ant-table {
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 0;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-container {
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 0;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-header {
|
||||||
|
position: relative;
|
||||||
|
z-index: 5;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
contain: paint;
|
||||||
|
background: hsl(var(--card));
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-body {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
min-height: 0;
|
||||||
|
max-height: var(--kt-table-scroll-y) !important;
|
||||||
|
contain: paint;
|
||||||
|
overflow: auto !important;
|
||||||
|
scrollbar-gutter: stable;
|
||||||
|
will-change: scroll-position;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-summary {
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-top: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-cell {
|
||||||
|
border-bottom-color: hsl(var(--border)) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-cell-fix-left,
|
||||||
|
.ant-table-cell-fix-right,
|
||||||
|
.ant-table-cell-fix-start,
|
||||||
|
.ant-table-cell-fix-end {
|
||||||
|
background: hsl(var(--card)) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-thead > tr > th.ant-table-cell-fix-left,
|
||||||
|
.ant-table-thead > tr > th.ant-table-cell-fix-right,
|
||||||
|
.ant-table-thead > tr > th.ant-table-cell-fix-start,
|
||||||
|
.ant-table-thead > tr > th.ant-table-cell-fix-end {
|
||||||
|
z-index: 6;
|
||||||
|
background: hsl(var(--card)) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-tbody > tr:hover > td.ant-table-cell-fix-left,
|
||||||
|
.ant-table-tbody > tr:hover > td.ant-table-cell-fix-right,
|
||||||
|
.ant-table-tbody > tr:hover > td.ant-table-cell-fix-start,
|
||||||
|
.ant-table-tbody > tr:hover > td.ant-table-cell-fix-end {
|
||||||
|
background: hsl(var(--accent)) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-summary .ant-table-cell-fix-left,
|
||||||
|
.ant-table-summary .ant-table-cell-fix-right,
|
||||||
|
.ant-table-summary .ant-table-cell-fix-start,
|
||||||
|
.ant-table-summary .ant-table-cell-fix-end {
|
||||||
|
background: hsl(var(--card)) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fixed column shadows repaint while Antdv toggles shadow classes during horizontal scroll.
|
||||||
|
.ant-table-cell-fix-start-shadow::after,
|
||||||
|
.ant-table-cell-fix-end-shadow::after,
|
||||||
|
.ant-table-cell-fix-left-last::after,
|
||||||
|
.ant-table-cell-fix-right-first::after {
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-thead > tr > th {
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
z-index: 5;
|
||||||
|
background: hsl(var(--card)) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
tfoot.ant-table-summary .ant-table-cell,
|
||||||
|
tfoot.ant-table-summary > tr > td {
|
||||||
|
height: 44px;
|
||||||
|
padding: 0 16px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: hsl(var(--foreground));
|
||||||
|
white-space: nowrap;
|
||||||
|
border-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__index-column {
|
||||||
|
width: 40px;
|
||||||
|
min-width: 40px;
|
||||||
|
max-width: 40px;
|
||||||
|
padding-inline: 4px !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
text-overflow: clip !important;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__index-column .ant-table-cell-content,
|
||||||
|
&__index-column .ant-table-column-title {
|
||||||
|
min-width: 0;
|
||||||
|
overflow: visible;
|
||||||
|
text-overflow: clip;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__action-column {
|
||||||
|
width: 112px;
|
||||||
|
min-width: 112px;
|
||||||
|
max-width: 112px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
$block: '.kt-table';
|
||||||
|
|
||||||
|
// Keep the block selector in one namespace so every partial shares the same BEM root.
|
||||||
|
@mixin block {
|
||||||
|
#{$block} {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,6 +9,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 3px;
|
gap: 3px;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
contain: paint;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__component-title {
|
&__component-title {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user