refactor: display
This commit is contained in:
parent
ff091e2f31
commit
ca48d818cc
|
|
@ -22,6 +22,11 @@ export const TrackerView: Component<TrackerViewProps> = (props) => {
|
||||||
return String(attr.value);
|
return String(attr.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const formatAttributeShort = (name: string, attr: TrackerAttribute): string => {
|
||||||
|
const val = formatAttributeValue(attr);
|
||||||
|
return `${name}=${val}`;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="tracker-view flex-1 overflow-auto p-3 bg-white">
|
<div class="tracker-view flex-1 overflow-auto p-3 bg-white">
|
||||||
<Show
|
<Show
|
||||||
|
|
@ -30,35 +35,44 @@ export const TrackerView: Component<TrackerViewProps> = (props) => {
|
||||||
<div class="text-gray-400 text-center py-8">暂无追踪项目</div>
|
<div class="text-gray-400 text-center py-8">暂无追踪项目</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div class="space-y-4">
|
<div class="space-y-2">
|
||||||
<For each={props.items()}>
|
<For each={props.items()}>
|
||||||
{(item, index) => (
|
{(item, index) => (
|
||||||
<div class="border border-gray-200 rounded-lg p-3 bg-gray-50">
|
<div class="border border-gray-200 rounded-lg p-2 bg-gray-50">
|
||||||
{/* 头部:tag、id 和操作按钮 */}
|
{/* 第一行:tag#id.class + 操作按钮 */}
|
||||||
<div class="flex items-center justify-between mb-2">
|
<div class="flex items-center justify-between">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2 flex-1 min-w-0">
|
||||||
<span class="font-bold text-gray-800">{item.tag}</span>
|
<span class="font-bold text-gray-800 whitespace-nowrap">{item.tag}</span>
|
||||||
<Show when={item.id}>
|
<Show when={item.id}>
|
||||||
<span class="text-xs text-purple-600 font-mono">#{item.id}</span>
|
<span class="text-xs text-purple-600 font-mono whitespace-nowrap">#{item.id}</span>
|
||||||
|
</Show>
|
||||||
|
<Show when={item.classes.length > 0}>
|
||||||
|
<span class="text-xs text-blue-600 font-mono whitespace-nowrap">.{item.classes.join(".")}</span>
|
||||||
|
</Show>
|
||||||
|
{/* 属性简写 */}
|
||||||
|
<Show when={Object.keys(item.attributes).length > 0}>
|
||||||
|
<span class="text-xs text-gray-500 font-mono whitespace-nowrap truncate">
|
||||||
|
[{Object.entries(item.attributes).map(([k, v]) => formatAttributeShort(k, v)).join(" ")}]
|
||||||
|
</span>
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1 flex-shrink-0 ml-2">
|
||||||
<button
|
<button
|
||||||
class="p-1 text-gray-500 hover:text-blue-600 hover:bg-blue-50 rounded"
|
class="p-1 text-gray-500 hover:text-blue-600 hover:bg-blue-50 rounded text-xs"
|
||||||
title="上移"
|
title="上移"
|
||||||
onClick={() => props.onMoveUp?.(index())}
|
onClick={() => props.onMoveUp?.(index())}
|
||||||
>
|
>
|
||||||
↑
|
↑
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="p-1 text-gray-500 hover:text-blue-600 hover:bg-blue-50 rounded"
|
class="p-1 text-gray-500 hover:text-blue-600 hover:bg-blue-50 rounded text-xs"
|
||||||
title="下移"
|
title="下移"
|
||||||
onClick={() => props.onMoveDown?.(index())}
|
onClick={() => props.onMoveDown?.(index())}
|
||||||
>
|
>
|
||||||
↓
|
↓
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="p-1 text-gray-500 hover:text-red-600 hover:bg-red-50 rounded"
|
class="p-1 text-gray-500 hover:text-red-600 hover:bg-red-50 rounded text-xs"
|
||||||
title="移除"
|
title="移除"
|
||||||
onClick={() => props.onRemove?.(index())}
|
onClick={() => props.onRemove?.(index())}
|
||||||
>
|
>
|
||||||
|
|
@ -66,43 +80,6 @@ export const TrackerView: Component<TrackerViewProps> = (props) => {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Classes */}
|
|
||||||
<Show when={item.classes.length > 0}>
|
|
||||||
<div class="flex flex-wrap gap-1 mb-2">
|
|
||||||
<Index each={item.classes}>
|
|
||||||
{(cls) => (
|
|
||||||
<span class="inline-flex items-center gap-1 px-2 py-0.5 bg-blue-100 text-blue-700 text-xs rounded">
|
|
||||||
{cls()}
|
|
||||||
<button
|
|
||||||
class="hover:text-red-600"
|
|
||||||
onClick={() => props.onRemoveClass?.(index(), cls())}
|
|
||||||
title="移除类"
|
|
||||||
>
|
|
||||||
×
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</Index>
|
|
||||||
</div>
|
|
||||||
</Show>
|
|
||||||
|
|
||||||
{/* Attributes */}
|
|
||||||
<div class="grid grid-cols-2 gap-2">
|
|
||||||
<For each={Object.values(item.attributes)}>
|
|
||||||
{(attr: TrackerAttribute) => (
|
|
||||||
<div
|
|
||||||
class="flex items-center justify-between px-2 py-1 bg-white rounded border border-gray-200 cursor-pointer hover:border-blue-400"
|
|
||||||
onClick={() => props.onEditAttribute?.(index(), attr.name, attr)}
|
|
||||||
>
|
|
||||||
<span class="text-xs text-gray-600">{attr.name}</span>
|
|
||||||
<span class="text-sm font-mono text-gray-800">
|
|
||||||
{formatAttributeValue(attr)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,8 @@ export function parseEmmet(input: string): ParsedEmmet {
|
||||||
function parseAttributes(attrString: string): Record<string, TrackerAttribute> {
|
function parseAttributes(attrString: string): Record<string, TrackerAttribute> {
|
||||||
const attributes: Record<string, TrackerAttribute> = {};
|
const attributes: Record<string, TrackerAttribute> = {};
|
||||||
|
|
||||||
// 匹配键值对:key=value 或 key="value with spaces"
|
// 匹配键值对:使用,分隔
|
||||||
const regex = /(\w+)=(?:"([^"]*)"|'([^']*)'|([^\s]+))/g;
|
const regex = /(\w+)=(?:"([^"]*)"|'([^']*)'|([^,]+))/g;
|
||||||
let match: RegExpExecArray | null;
|
let match: RegExpExecArray | null;
|
||||||
|
|
||||||
while ((match = regex.exec(attrString)) !== null) {
|
while ((match = regex.exec(attrString)) !== null) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue