feat(chat): show playful teacher introductions on hover
This commit is contained in:
@@ -6,19 +6,22 @@ import { usePreviewClearance } from '@/pages/Chat/use-preview-clearance';
|
||||
let resize: () => void;
|
||||
let bubbleRect: DOMRect;
|
||||
let pageRect: DOMRect;
|
||||
let introductionRect: DOMRect;
|
||||
const bubble = document.createElement('div');
|
||||
const introduction = document.createElement('div');
|
||||
const rect = (x: number, y: number, width: number, height: number) => new DOMRect(x, y, width, height);
|
||||
|
||||
function Harness({ visible = true, open = true }: { visible?: boolean; open?: boolean }) {
|
||||
function Harness({ visible = true, open = true, intro = false }: { visible?: boolean; open?: boolean; intro?: boolean }) {
|
||||
const panel = useRef<HTMLDivElement>(null);
|
||||
const viewport = useRef<HTMLDivElement>(null);
|
||||
usePreviewClearance(panel, viewport, visible ? bubble : null, open);
|
||||
usePreviewClearance(panel, viewport, visible ? bubble : null, open, intro ? introduction : null);
|
||||
return <div ref={panel} data-testid="panel"><div ref={viewport} data-testid="viewport" /></div>;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
bubbleRect = rect(960, 48, 340, 164);
|
||||
pageRect = rect(192, 184, 1200, 600);
|
||||
introductionRect = rect(950, 50, 304, 290);
|
||||
vi.stubGlobal('ResizeObserver', class {
|
||||
constructor(callback: () => void) { resize = callback; }
|
||||
observe() {}
|
||||
@@ -26,6 +29,7 @@ beforeEach(() => {
|
||||
});
|
||||
vi.spyOn(HTMLElement.prototype, 'getBoundingClientRect').mockImplementation(function (this: HTMLElement) {
|
||||
if (this === bubble) return bubbleRect;
|
||||
if (this === introduction) return introductionRect;
|
||||
const offset = Number.parseFloat(this.parentElement?.style.marginTop ?? '') || 0;
|
||||
return rect(pageRect.x, pageRect.y + offset, pageRect.width, pageRect.height - offset);
|
||||
});
|
||||
@@ -73,3 +77,22 @@ it('removes clearance when the bubble is dismissed or Work closes', () => {
|
||||
view.rerender(<Harness open={false} />);
|
||||
expect(screen.getByTestId('panel').style.marginTop).toBe('');
|
||||
});
|
||||
|
||||
it('clears a hovered introduction even when no proactive bubble exists', () => {
|
||||
const view = render(<Harness visible={false} intro />);
|
||||
expect(screen.getByTestId('panel').style.marginTop).toBe('164px');
|
||||
act(() => { resize(); resize(); });
|
||||
expect(screen.getByTestId('panel').style.marginTop).toBe('164px');
|
||||
view.rerender(<Harness visible={false} intro={false} />);
|
||||
expect(screen.getByTestId('panel').style.marginTop).toBe('');
|
||||
});
|
||||
|
||||
it('keeps the deeper overlapping surface clear without adding both heights', () => {
|
||||
const view = render(<Harness intro />);
|
||||
expect(screen.getByTestId('panel').style.marginTop).toBe('164px');
|
||||
introductionRect = rect(950, 50, 304, 100);
|
||||
act(() => resize());
|
||||
expect(screen.getByTestId('panel').style.marginTop).toBe('36px');
|
||||
view.rerender(<Harness intro={false} />);
|
||||
expect(screen.getByTestId('panel').style.marginTop).toBe('36px');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user