style: compact spread filter toolbar layout

This commit is contained in:
wxs 2026-06-29 17:18:31 +08:00
parent 0122e63872
commit ccfb8f14fe
2 changed files with 82 additions and 12 deletions

View File

@ -730,42 +730,53 @@ function findNativeActionButton(
function applyToolbarRootStyles(root: HTMLElement): void { function applyToolbarRootStyles(root: HTMLElement): void {
root.style.display = "inline-flex"; root.style.display = "inline-flex";
root.style.alignItems = "center"; root.style.alignItems = "center";
root.style.columnGap = "8px"; root.style.columnGap = "10px";
root.style.flexWrap = "wrap"; root.style.flex = "1 1 auto";
root.style.minWidth = "0";
root.style.flexWrap = "nowrap";
} }
function applyToolbarPanelStyles(panel: HTMLElement): void { function applyToolbarPanelStyles(panel: HTMLElement): void {
panel.style.display = "flex"; panel.style.display = "flex";
panel.style.flexDirection = "column"; panel.style.flexDirection = "column";
panel.style.gap = "8px"; panel.style.alignItems = "stretch";
panel.style.gap = "6px";
panel.style.flex = "1 1 auto";
panel.style.minWidth = "0"; panel.style.minWidth = "0";
panel.style.padding = "4px 0"; panel.style.padding = "2px 0";
panel.style.overflowX = "visible";
panel.style.overflowY = "hidden";
} }
function applyToolbarRowStyles(row: HTMLElement): void { function applyToolbarRowStyles(row: HTMLElement): void {
row.style.display = "flex"; row.style.display = "flex";
row.style.alignItems = "center"; row.style.alignItems = "center";
row.style.gap = "10px"; row.style.justifyContent = "flex-start";
row.style.gap = "6px";
row.style.minHeight = "32px"; row.style.minHeight = "32px";
row.style.minWidth = "0"; row.style.minWidth = "0";
row.style.flexWrap = "wrap"; row.style.width = "100%";
row.style.flexWrap = "nowrap";
} }
function applyToolbarGroupStyles(group: HTMLElement): void { function applyToolbarGroupStyles(group: HTMLElement): void {
group.style.display = "flex"; group.style.display = "flex";
group.style.alignItems = "center"; group.style.alignItems = "center";
group.style.gap = "8px"; group.style.gap = "6px";
group.style.minWidth = "0"; group.style.minWidth = "0";
group.style.flexWrap = "wrap"; group.style.flex = "0 0 auto";
group.style.flexWrap = "nowrap";
} }
function createToolbarGroupTitle(document: Document, label: string): HTMLElement { function createToolbarGroupTitle(document: Document, label: string): HTMLElement {
const title = document.createElement("span"); const title = document.createElement("span");
title.dataset.pluginToolbarTitle = label;
title.textContent = label; title.textContent = label;
title.style.color = "#64748b"; title.style.color = "#64748b";
title.style.fontSize = "12px"; title.style.fontSize = "12px";
title.style.fontWeight = "700"; title.style.fontWeight = "700";
title.style.lineHeight = "32px"; title.style.lineHeight = "32px";
title.style.flex = "0 0 auto";
title.style.whiteSpace = "nowrap"; title.style.whiteSpace = "nowrap";
return title; return title;
} }
@ -781,7 +792,8 @@ function applyToolbarActionStyles(actions: HTMLElement): void {
actions.style.display = "flex"; actions.style.display = "flex";
actions.style.alignItems = "center"; actions.style.alignItems = "center";
actions.style.gap = "8px"; actions.style.gap = "8px";
actions.style.paddingLeft = "12px"; actions.style.flex = "0 0 auto";
actions.style.paddingLeft = "10px";
actions.style.borderLeft = "1px solid #e5e7eb"; actions.style.borderLeft = "1px solid #e5e7eb";
} }
@ -839,10 +851,11 @@ function applyNativeControlStyles(
element.style.height = "32px"; element.style.height = "32px";
element.style.border = "1px solid #d0d7de"; element.style.border = "1px solid #d0d7de";
element.style.borderRadius = "6px"; element.style.borderRadius = "6px";
element.style.padding = "0 10px"; element.style.padding = "0 8px";
element.style.background = "#fff"; element.style.background = "#fff";
element.style.color = "#1f2329"; element.style.color = "#1f2329";
element.style.boxSizing = "border-box"; element.style.boxSizing = "border-box";
element.style.flex = "0 0 auto";
}); });
controls.exportRangeSelect.style.minWidth = "104px"; controls.exportRangeSelect.style.minWidth = "104px";
@ -854,7 +867,7 @@ function applyNativeControlStyles(
controls.spreadFilterFlowTypeSelect, controls.spreadFilterFlowTypeSelect,
controls.spreadFilterRangeSelect controls.spreadFilterRangeSelect
].forEach((select) => { ].forEach((select) => {
select.style.minWidth = "92px"; select.style.minWidth = "84px";
}); });
Object.values(controls).forEach((element) => { Object.values(controls).forEach((element) => {
@ -863,7 +876,7 @@ function applyNativeControlStyles(
element.dataset.pluginSpreadThreshold element.dataset.pluginSpreadThreshold
) { ) {
element.style.width = element.style.width =
element.dataset.pluginSpreadThreshold === "playMedian" ? "112px" : "86px"; element.dataset.pluginSpreadThreshold === "playMedian" ? "104px" : "78px";
} }
}); });
} }

View File

@ -384,6 +384,63 @@ describe("market-content-entry", () => {
expect(audienceProfileByIdExportButton?.style.color).toBe("rgb(255, 255, 255)"); expect(audienceProfileByIdExportButton?.style.color).toBe("rgb(255, 255, 255)");
}); });
test("keeps plugin filters in two compact aligned rows", async () => {
document.body.innerHTML = buildMarketFixture();
const { createMarketController } = await import("../src/content/market/index");
const controller = trackController(createMarketController({
document,
loadAuthorMetrics: async () => ({
success: false,
reason: "request-failed"
}),
window
}));
await controller.ready;
const toolbar = document.querySelector(
'[data-plugin-toolbar="root"]'
) as HTMLElement | null;
const panel = document.querySelector(
'[data-plugin-toolbar-panel="root"]'
) as HTMLElement | null;
const rows = document.querySelectorAll("[data-plugin-toolbar-row]");
const primaryRow = document.querySelector(
'[data-plugin-toolbar-row="primary"]'
) as HTMLElement | null;
const thresholdRow = document.querySelector(
'[data-plugin-toolbar-row="thresholds"]'
) as HTMLElement | null;
const dataGroup = document.querySelector(
'[data-plugin-toolbar-group="data"]'
) as HTMLElement | null;
const videoGroup = document.querySelector(
'[data-plugin-toolbar-group="video"]'
) as HTMLElement | null;
const thresholdGroup = document.querySelector(
'[data-plugin-toolbar-group="thresholds"]'
) as HTMLElement | null;
const titles = Array.from(document.querySelectorAll("[data-plugin-toolbar-title]"))
.map((element) => element.textContent);
expect(toolbar?.style.flexWrap).toBe("nowrap");
expect(panel?.style.flexDirection).toBe("column");
expect(panel?.style.alignItems).toBe("stretch");
expect(panel?.style.padding).toBe("2px 0px");
expect(panel?.style.overflowX).toBe("visible");
expect(rows).toHaveLength(2);
expect(primaryRow?.style.flexWrap).toBe("nowrap");
expect(thresholdRow?.style.flexWrap).toBe("nowrap");
expect(dataGroup?.parentElement).toBe(primaryRow);
expect(videoGroup?.parentElement).toBe(primaryRow);
expect(thresholdGroup?.parentElement).toBe(thresholdRow);
expect(thresholdGroup?.style.flexWrap).toBe("nowrap");
expect(primaryRow?.style.justifyContent).toBe("flex-start");
expect(thresholdRow?.style.justifyContent).toBe("flex-start");
expect(titles).toEqual(["达人数据", "视频口径", "传播指标"]);
});
test("remounts the plugin action bar when the native market action row appears later", async () => { test("remounts the plugin action bar when the native market action row appears later", async () => {
document.body.innerHTML = buildMarketTableOnlyFixture(); document.body.innerHTML = buildMarketTableOnlyFixture();
const observer = createMutationObserverFactory(); const observer = createMutationObserverFactory();