@crossed/ui
Version:
A universal & performant styling library for React Native, Next.js & React
219 lines (218 loc) • 12.8 kB
JavaScript
var import_jsx_runtime = require("react/jsx-runtime");
var import_test = require("@crossed/test");
var import__ = require("../index");
var import_overlay = require("../../overlay");
var import_MenuList = require("../MenuList");
var import_Divider = require("../../layout/Divider");
var import_useMedia = require("../../useMedia");
var import_typography = require("../../typography");
jest.mock("../../overlay", () => ({
Popover: Object.assign(
jest.fn(({ children }) => children),
{
Trigger: jest.fn(({ children }) => children),
Content: jest.fn(({ children }) => children)
}
),
useFloatingContext: jest.fn()
}));
jest.mock("../MenuList", () => ({
MenuList: Object.assign(
jest.fn(({ children }) => children),
{
Item: jest.fn(({ children }) => children),
Label: jest.fn(({ children }) => children),
Title: jest.fn(({ children }) => children)
}
)
}));
jest.mock("../../layout/Divider", () => ({
Divider: jest.fn(() => null)
}));
jest.mock("../../useMedia", () => ({
useMedia: jest.fn()
}));
const PopoverMocked = jest.mocked(import_overlay.Popover);
const MenuListMocked = jest.mocked(import_MenuList.MenuList);
const useFloatingContextMocked = jest.mocked(import_overlay.useFloatingContext);
const useMediaMocked = jest.mocked(import_useMedia.useMedia);
const DividerMocked = jest.mocked(import_Divider.Divider);
const mockUseMedia = (md) => {
useMediaMocked.mockReturnValue({
md,
sm: false,
lg: false,
xl: false
});
};
const mockFloatingContext = (onClose = jest.fn()) => {
useFloatingContextMocked.mockReturnValue({
onClose,
open: true,
onOpen: jest.fn()
});
};
describe("DropDownMenu", () => {
beforeEach(() => {
mockUseMedia(true);
mockFloatingContext();
});
afterEach(() => {
jest.clearAllMocks();
});
test("renders with default props", () => {
(0, import_test.render)(
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import__.DropDownMenu, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_typography.Text, { children: "Open Menu" }) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Item, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Label, { children: "Item 1" }) }) })
] })
);
const call = PopoverMocked.mock.calls[0][0];
expect(call).toHaveProperty("placement", "bottom-end");
expect(call).toHaveProperty("triggerStrategy", "onPress");
expect(call).toHaveProperty("children");
});
test("accepts custom placement", () => {
(0, import_test.render)(
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import__.DropDownMenu, { placement: "top-start", children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_typography.Text, { children: "Open Menu" }) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Item, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Label, { children: "Item 1" }) }) })
] })
);
const call = PopoverMocked.mock.calls[0][0];
expect(call).toHaveProperty("placement", "top-start");
});
test("accepts custom triggerStrategy", () => {
(0, import_test.render)(
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import__.DropDownMenu, { triggerStrategy: "onPointerEnter", children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_typography.Text, { children: "Open Menu" }) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Item, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Label, { children: "Item 1" }) }) })
] })
);
const call = PopoverMocked.mock.calls[0][0];
expect(call).toHaveProperty("triggerStrategy", "onPointerEnter");
});
test("forwards additional props to Popover", () => {
(0, import_test.render)(
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import__.DropDownMenu, { offsetValue: 15, children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_typography.Text, { children: "Open Menu" }) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Item, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Label, { children: "Item 1" }) }) })
] })
);
const call = PopoverMocked.mock.calls[0][0];
expect(call).toHaveProperty("offsetValue", 15);
});
test("renders all static components", () => {
expect(import__.DropDownMenu.Trigger).toBeDefined();
expect(import__.DropDownMenu.Content).toBeDefined();
expect(import__.DropDownMenu.Item).toBeDefined();
expect(import__.DropDownMenu.Label).toBeDefined();
expect(import__.DropDownMenu.Title).toBeDefined();
expect(import__.DropDownMenu.Divider).toBeDefined();
});
test("Content renders MenuList with bordered=true on desktop", () => {
mockUseMedia(true);
MenuListMocked.mockClear();
(0, import_test.render)(
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import__.DropDownMenu, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_typography.Text, { children: "Open Menu" }) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Item, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Label, { children: "Item 1" }) }) })
] })
);
const menuListCall = MenuListMocked.mock.calls[0][0];
expect(menuListCall).toHaveProperty("bordered", true);
});
test("Content renders MenuList with bordered=false on mobile", () => {
mockUseMedia(false);
MenuListMocked.mockClear();
(0, import_test.render)(
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import__.DropDownMenu, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_typography.Text, { children: "Open Menu" }) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Item, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Label, { children: "Item 1" }) }) })
] })
);
const menuListCall = MenuListMocked.mock.calls[0][0];
expect(menuListCall).toHaveProperty("bordered", false);
});
test("Item closes popover on press", () => {
const onClose = jest.fn();
mockFloatingContext(onClose);
const MenuListItemMocked = jest.mocked(import_MenuList.MenuList.Item);
(0, import_test.render)(
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import__.DropDownMenu, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_typography.Text, { children: "Open Menu" }) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Item, { onPress: () => {
}, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Label, { children: "Item 1" }) }) })
] })
);
const itemCall = MenuListItemMocked.mock.calls[0][0];
expect(itemCall).toHaveProperty("onPress");
if ("onPress" in itemCall && typeof itemCall.onPress === "function") {
itemCall.onPress({});
}
expect(onClose).toHaveBeenCalledTimes(1);
});
test("Item composes custom onPress with onClose", () => {
const onClose = jest.fn();
const customOnPress = jest.fn();
mockFloatingContext(onClose);
const MenuListItemMocked = jest.mocked(import_MenuList.MenuList.Item);
(0, import_test.render)(
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import__.DropDownMenu, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_typography.Text, { children: "Open Menu" }) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Item, { onPress: customOnPress, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Label, { children: "Item 1" }) }) })
] })
);
const itemCall = MenuListItemMocked.mock.calls[0][0];
if ("onPress" in itemCall && typeof itemCall.onPress === "function") {
itemCall.onPress({});
}
expect(customOnPress).toHaveBeenCalledTimes(1);
expect(onClose).toHaveBeenCalledTimes(1);
});
test("Label renders MenuList.Label", () => {
const MenuListLabelMocked = jest.mocked(import_MenuList.MenuList.Label);
(0, import_test.render)(
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import__.DropDownMenu, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_typography.Text, { children: "Open Menu" }) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Item, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Label, { children: "Item 1" }) }) })
] })
);
expect(MenuListLabelMocked).toHaveBeenCalled();
});
test("Title renders MenuList.Title", () => {
const MenuListTitleMocked = jest.mocked(import_MenuList.MenuList.Title);
(0, import_test.render)(
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import__.DropDownMenu, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_typography.Text, { children: "Open Menu" }) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Title, { children: "Menu Title" }) })
] })
);
expect(MenuListTitleMocked).toHaveBeenCalled();
});
test("Divider renders Divider component", () => {
(0, import_test.render)(
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import__.DropDownMenu, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_typography.Text, { children: "Open Menu" }) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import__.DropDownMenu.Content, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Item, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Label, { children: "Item 1" }) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Divider, {}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Item, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Label, { children: "Item 2" }) })
] })
] })
);
expect(DividerMocked).toHaveBeenCalled();
});
test("Divider forwards props", () => {
DividerMocked.mockClear();
(0, import_test.render)(
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import__.DropDownMenu, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_typography.Text, { children: "Open Menu" }) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.DropDownMenu.Divider, { direction: "vertical" }) })
] })
);
const dividerCall = DividerMocked.mock.calls[0][0];
expect(dividerCall).toHaveProperty("direction", "vertical");
});
});
//# sourceMappingURL=DropDownMenu.spec.js.map