优化列配置组件,添加点击外部关闭功能;改进数据转换逻辑,支持防抖处理以提升性能
This commit is contained in:
@@ -29,9 +29,29 @@
|
|||||||
config.format = undefined;
|
config.format = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Click outside to close
|
||||||
|
let panelEl: HTMLDivElement;
|
||||||
|
|
||||||
|
function onDocumentClick(e: MouseEvent) {
|
||||||
|
if (panelEl && !panelEl.contains(e.target as Node)) {
|
||||||
|
onclose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
// Delay listener attachment to avoid catching the opening click itself
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
document.addEventListener('click', onDocumentClick, true);
|
||||||
|
}, 0);
|
||||||
|
return () => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
document.removeEventListener('click', onDocumentClick, true);
|
||||||
|
};
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="absolute top-full left-0 z-50 mt-1 w-72 rounded-lg border border-gray-200 bg-white p-4 shadow-xl">
|
<div bind:this={panelEl} class="absolute top-full left-0 z-50 mt-1 w-72 rounded-lg border border-gray-200 bg-white p-4 shadow-xl">
|
||||||
<div class="mb-3 flex items-center justify-between">
|
<div class="mb-3 flex items-center justify-between">
|
||||||
<h4 class="text-sm font-semibold text-gray-700">列配置</h4>
|
<h4 class="text-sm font-semibold text-gray-700">列配置</h4>
|
||||||
<button onclick={onclose} aria-label="关闭配置" class="text-gray-400 hover:text-gray-600 cursor-pointer">
|
<button onclick={onclose} aria-label="关闭配置" class="text-gray-400 hover:text-gray-600 cursor-pointer">
|
||||||
|
|||||||
@@ -16,7 +16,24 @@
|
|||||||
|
|
||||||
// Derived
|
// Derived
|
||||||
const hasData = $derived(headers.length > 0 && rows.length > 0);
|
const hasData = $derived(headers.length > 0 && rows.length > 0);
|
||||||
const convertedJson = $derived(hasData ? convertData(rows, mappings) : []);
|
|
||||||
|
// Debounced conversion to avoid lag while editing mappings
|
||||||
|
let convertedJson = $state<Record<string, unknown>[]>([]);
|
||||||
|
let debounceTimer: ReturnType<typeof setTimeout>;
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
// $state.snapshot forces deep read of all nested properties,
|
||||||
|
// so changes to e.g. mappings[i].target will trigger this effect
|
||||||
|
const snapshotMappings = $state.snapshot(mappings);
|
||||||
|
const currentRows = rows;
|
||||||
|
const dataReady = hasData;
|
||||||
|
|
||||||
|
clearTimeout(debounceTimer);
|
||||||
|
debounceTimer = setTimeout(() => {
|
||||||
|
convertedJson = dataReady ? convertData(currentRows, snapshotMappings) : [];
|
||||||
|
}, 150);
|
||||||
|
});
|
||||||
|
|
||||||
const jsonString = $derived(JSON.stringify(convertedJson, null, 2));
|
const jsonString = $derived(JSON.stringify(convertedJson, null, 2));
|
||||||
|
|
||||||
// File handling
|
// File handling
|
||||||
|
|||||||
Reference in New Issue
Block a user