mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
feat(studio): add PinnedGroupRow always-open pinned-group primitive
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
||||
FlatSelectRow,
|
||||
FlatSlider,
|
||||
FlatToggle,
|
||||
PinnedGroupRow,
|
||||
PinnedZoneDivider,
|
||||
} from "./propertyPanelFlatPrimitives";
|
||||
|
||||
@@ -456,3 +457,21 @@ describe("FlatToggle", () => {
|
||||
act(() => root.unmount());
|
||||
});
|
||||
});
|
||||
|
||||
describe("PinnedGroupRow", () => {
|
||||
it("renders a 'Pinned' badge, filled pin icon, and always shows children", () => {
|
||||
const onUnpin = vi.fn();
|
||||
const { host, root } = renderInto(
|
||||
<PinnedGroupRow title="Motion" onUnpin={onUnpin}>
|
||||
<div data-testid="body">body</div>
|
||||
</PinnedGroupRow>,
|
||||
);
|
||||
expect(host.textContent).toContain("Pinned");
|
||||
expect(host.textContent).toContain("Motion");
|
||||
expect(host.querySelector('[data-testid="body"]')).not.toBeNull();
|
||||
const unpin = host.querySelector<HTMLButtonElement>('[data-pinned-group-unpin="true"]');
|
||||
act(() => unpin?.dispatchEvent(new MouseEvent("click", { bubbles: true })));
|
||||
expect(onUnpin).toHaveBeenCalledTimes(1);
|
||||
act(() => root.unmount());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -449,3 +449,47 @@ export function FlatToggle({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* PinnedGroupRow — always-open pinned group (design_handoff #8a) */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
export function PinnedGroupRow({
|
||||
title,
|
||||
accessory,
|
||||
onUnpin,
|
||||
children,
|
||||
}: {
|
||||
title: string;
|
||||
accessory?: ReactNode;
|
||||
onUnpin: () => void;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div className="border-b border-panel-hairline px-4 py-3" data-pinned-group="true">
|
||||
<div className="mb-2.5 flex items-center justify-between">
|
||||
<span className="flex items-center gap-1.5">
|
||||
<span className="text-[9px] font-semibold uppercase tracking-[0.08em] text-panel-accent">
|
||||
Pinned
|
||||
</span>
|
||||
<span className="text-[12px] font-semibold text-panel-text-0">{title}</span>
|
||||
</span>
|
||||
<span className="flex items-center gap-2.5 text-panel-text-5">
|
||||
{accessory}
|
||||
<button
|
||||
type="button"
|
||||
data-pinned-group-unpin="true"
|
||||
title="Unpin — returns to the stack"
|
||||
onClick={onUnpin}
|
||||
className="text-panel-accent"
|
||||
>
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="currentColor">
|
||||
<path d="M4 1h4v3.2l1.4 1.4V7H7v4L6 12l-1-1V7H2.6V5.6L4 4.2z" />
|
||||
</svg>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user