mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-07 00:13:56 +00:00
test: check the calendar picker and the kit checkbox against the app's one menu, which draws a tick instead of a box and closes on page scroll after it opens
The booking calendar picker is now the app's context menu: its header is the menu's header row, it lays out from its measured width and starts listening for scroll a tick after it opens. Menu check items show a tick instead of a drawn box, so the kit checkbox copies the Files select box only.
This commit is contained in:
@@ -349,7 +349,12 @@ describe('BookingCalendarActions', () => {
|
||||
expect(document.activeElement).toBe(items[2]);
|
||||
fireEvent.keyDown(menu, { key: 'Home' });
|
||||
expect(document.activeElement).toBe(items[0]);
|
||||
expect(menu.querySelector('div')?.getAttribute('role')).toBe('presentation');
|
||||
// The heading is the app menu's header row: not an item, so the keys skip it.
|
||||
const header = menu.querySelector<HTMLElement>('[data-context-menu-header]');
|
||||
expect(header?.textContent).toBe('select_calendar');
|
||||
expect(header?.closest('[role="menuitem"]')).toBeNull();
|
||||
expect(header?.hasAttribute('tabindex')).toBe(false);
|
||||
expect(items.map((item) => item.textContent)).toEqual(['Personal', 'Work', 'Travel']);
|
||||
});
|
||||
|
||||
it('closes the picker on Escape and gives focus back to its button', async () => {
|
||||
@@ -361,9 +366,12 @@ describe('BookingCalendarActions', () => {
|
||||
|
||||
it('stays open while its own list scrolls, and closes when the page scrolls', async () => {
|
||||
const { menu } = await openPicker();
|
||||
fireEvent.scroll(menu);
|
||||
// The menu starts listening a tick after it opens, so the click that opened it doesn't close it.
|
||||
await act(async () => { await new Promise((resolve) => setTimeout(resolve, 0)); });
|
||||
fireEvent.scroll(menu.firstElementChild ?? menu);
|
||||
expect(screen.queryByRole('menu')).not.toBeNull();
|
||||
fireEvent.scroll(window);
|
||||
// A page scroll is fired at the document.
|
||||
fireEvent.scroll(document);
|
||||
expect(screen.queryByRole('menu')).toBeNull();
|
||||
});
|
||||
|
||||
@@ -378,6 +386,13 @@ describe('BookingCalendarActions', () => {
|
||||
useCalendarStore.setState({ calendars: [cal('Personal', { isDefault: true }), cal('Work')] });
|
||||
const width = window.innerWidth;
|
||||
Object.defineProperty(window, 'innerWidth', { configurable: true, value: 390 });
|
||||
// jsdom lays nothing out: the menu measures as 208 px wide, as it is on a phone.
|
||||
const measure = vi.spyOn(HTMLElement.prototype, 'getBoundingClientRect').mockImplementation(function (this: HTMLElement) {
|
||||
const isMenu = this.getAttribute('role') === 'menu';
|
||||
const w = isMenu ? 208 : 0;
|
||||
const h = isMenu ? 120 : 0;
|
||||
return { left: 0, right: w, top: 0, bottom: h, width: w, height: h, x: 0, y: 0, toJSON: () => ({}) };
|
||||
});
|
||||
try {
|
||||
render(<BookingCalendarActions booking={await bookingFrom([OUT])} email={EMAIL} />);
|
||||
const button = await screen.findByRole('button', { name: /add_to_calendar/ });
|
||||
@@ -388,6 +403,7 @@ describe('BookingCalendarActions', () => {
|
||||
expect(left).toBeGreaterThanOrEqual(8);
|
||||
expect(left + 208).toBeLessThanOrEqual(390 - 8);
|
||||
} finally {
|
||||
measure.mockRestore();
|
||||
Object.defineProperty(window, 'innerWidth', { configurable: true, value: width });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -65,7 +65,9 @@ describe('plugin UI kit components', () => {
|
||||
['components/settings/settings-section.tsx', 'bg-muted-foreground ltr:translate-x-1 rtl:-translate-x-1'],
|
||||
['components/settings/settings-section.tsx', 'flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between sm:gap-4 py-3 border-b border-border last:border-0'],
|
||||
['components/settings/settings-section.tsx', 'px-3 py-1.5 text-xs rounded-md transition-colors duration-150'],
|
||||
['components/email/composer-toolbar-menu.tsx', 'mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border'],
|
||||
['components/files/file-views.tsx', 'w-4 h-4 rounded border flex items-center justify-center shrink-0'],
|
||||
['components/files/file-views.tsx', 'bg-primary border-primary text-primary-foreground'],
|
||||
['components/files/file-views.tsx', 'border-muted-foreground/50 bg-background'],
|
||||
['components/calendar/ical-import-modal.tsx', 'flex items-center gap-1.5 px-4 py-2 text-sm font-medium border-b-2 transition-colors'],
|
||||
['components/ui/empty-state.tsx', 'w-14 h-14 rounded-full bg-muted flex items-center justify-center mb-4'],
|
||||
['components/files/file-views.tsx', 'border-b border-border/60'],
|
||||
|
||||
@@ -669,7 +669,7 @@ export interface KitCheckboxProps {
|
||||
id?: string;
|
||||
}
|
||||
|
||||
/** The composer's check items and the Files app's select box: a drawn box, not the browser's. */
|
||||
/** The Files app's select box: a drawn box, not the browser's. */
|
||||
export function Checkbox({ checked, onChange, label, hint, disabled = false, id, ariaLabel }: KitCheckboxProps) {
|
||||
const autoId = React.useId();
|
||||
const boxId = id ?? autoId;
|
||||
|
||||
Reference in New Issue
Block a user