// @vitest-environment jsdom
import * as React from "react";
import { cleanup, fireEvent, render } from "@testing-library/react";
import { afterEach, describe, expect, it } from "vitest";
import { PanelSection } from "../panel/panel-section";
import { ControlItem } from "./index";
afterEach(cleanup);
const compoundAnchor = "has-data-[control-section-divider=compound]:relative";
const compound =
Palette
;
function getCompoundItems(container: HTMLElement): HTMLElement[] {
return Array.from(container.querySelectorAll(
'[data-control-item-compound-context]:has([data-control-section-divider="compound"])',
));
}
describe("ControlItem compound divider ownership", () => {
it.each([
["top", false],
["top", true],
["bottom", false],
["bottom", true],
["both", false],
["both", true],
] as const)("anchors %s dividers locally with flush=%s", (placement, flush) => {
const { container } = render(
{compound}
,
);
const items = getCompoundItems(container);
expect(items).toHaveLength(1);
const item = items[0]!;
expect(item.classList.contains(compoundAnchor)).toBe(true);
for (const [edge, visible] of [
["before", placement !== "bottom"],
["after", placement !== "top"],
] as const) {
expect(item.classList.contains(
`has-data-[control-section-divider=compound]:${edge}:absolute`,
)).toBe(visible);
expect(item.classList.contains(
`has-data-[control-section-divider=compound]:${edge}:inset-x-${flush ? 0 : 3}`,
)).toBe(visible);
}
});
it("does not add a containing block or separators when dividers are disabled", () => {
const { container } = render({compound});
const item = container.firstElementChild!;
expect(item.classList.contains(compoundAnchor)).toBe(false);
expect(item.className).not.toContain(":before:");
expect(item.className).not.toContain(":after:");
});
it("keeps a single compound control free of section dividers", () => {
const { container } = render({compound});
expect(getCompoundItems(container)).toHaveLength(0);
expect(container.querySelector('[data-control-section-divider="compound"]')).not.toBeNull();
expect(container.innerHTML).not.toContain(compoundAnchor);
});
it("keeps each last-item divider local across sections and collapse/reopen", () => {
const sections = (collapsed: boolean) => (
{["A", "B", "C"].map((key) => (
Ordinary control
{compound}
))}
);
const { container, rerender } = render(sections(false));
const assertLocalLastItems = () => {
const items = getCompoundItems(container);
expect(items).toHaveLength(3);
for (const item of items) {
expect(item.dataset.controlItemCompoundDividerPlacement).toBe("top");
expect(item.classList.contains(compoundAnchor)).toBe(true);
}
};
assertLocalLastItems();
rerender(sections(true));
for (const body of container.querySelectorAll('[data-slot="panel-section-collapsible-body"]')) {
fireEvent.transitionEnd(body);
}
expect(getCompoundItems(container)).toHaveLength(0);
rerender(sections(false));
assertLocalLastItems();
});
});