diff --git a/__test__/components/DuplicateEvent.test.tsx b/__test__/components/DuplicateEvent.test.tsx
index 92dbfe8..b612964 100644
--- a/__test__/components/DuplicateEvent.test.tsx
+++ b/__test__/components/DuplicateEvent.test.tsx
@@ -95,6 +95,9 @@ describe("EventDuplication", () => {
fireEvent.click(screen.getByText("Duplicate event"));
+ // Cancel button only appears in expanded mode
+ fireEvent.click(screen.getByText("More options"));
+
fireEvent.click(screen.getByRole("button", { name: /Cancel/i }));
expect(handleClose).toHaveBeenCalled();
diff --git a/__test__/components/RepeatEvent.test.tsx b/__test__/components/RepeatEvent.test.tsx
index 66e03b1..99c97d4 100644
--- a/__test__/components/RepeatEvent.test.tsx
+++ b/__test__/components/RepeatEvent.test.tsx
@@ -102,8 +102,8 @@ async function setupEventPopover(
const titleInput = screen.getByLabelText("Title");
fireEvent.change(titleInput, { target: { value: "Meeting" } });
- // Click Show More to expand the dialog
- const showMoreButton = screen.getByText("Show More");
+ // Click More options to expand the dialog
+ const showMoreButton = screen.getByText("More options");
fireEvent.click(showMoreButton);
// Check Repeat checkbox to show repeat options
diff --git a/__test__/components/ResponsiveDialog.test.tsx b/__test__/components/ResponsiveDialog.test.tsx
index a78fd4c..54d2b37 100644
--- a/__test__/components/ResponsiveDialog.test.tsx
+++ b/__test__/components/ResponsiveDialog.test.tsx
@@ -295,4 +295,80 @@ describe("ResponsiveDialog", () => {
expect(screen.getByText("Extended Content")).toBeInTheDocument();
expect(screen.getByLabelText("show less")).toBeInTheDocument();
});
+
+ it("renders expand and close icons in normal mode when showHeaderActions is true", () => {
+ render(
+
+ Content
+
+ );
+
+ expect(screen.getByLabelText("expand")).toBeInTheDocument();
+ expect(screen.getByLabelText("close")).toBeInTheDocument();
+ });
+
+ it("does not render header icons when showHeaderActions is false", () => {
+ render(
+
+ Content
+
+ );
+
+ expect(screen.queryByLabelText("expand")).not.toBeInTheDocument();
+ expect(screen.queryByLabelText("close")).not.toBeInTheDocument();
+ expect(screen.getByText("Test Title")).toBeInTheDocument();
+ });
+
+ it("calls onClose when close icon is clicked", () => {
+ render(
+
+ Content
+
+ );
+
+ const closeButton = screen.getByLabelText("close");
+ fireEvent.click(closeButton);
+
+ expect(mockOnClose).toHaveBeenCalledTimes(1);
+ });
+
+ it("calls onExpandToggle when expand icon is clicked", () => {
+ render(
+
+ Content
+
+ );
+
+ const expandButton = screen.getByLabelText("expand");
+ fireEvent.click(expandButton);
+
+ expect(mockOnExpandToggle).toHaveBeenCalledTimes(1);
+ });
});
diff --git a/__test__/features/Calendars/CalendarModal.test.tsx b/__test__/features/Calendars/CalendarModal.test.tsx
index 1783dcd..61527f0 100644
--- a/__test__/features/Calendars/CalendarModal.test.tsx
+++ b/__test__/features/Calendars/CalendarModal.test.tsx
@@ -325,9 +325,12 @@ describe("CalendarPopover - Tabs Scenarios", () => {
const input = screen.getByLabelText(/CalDAV access/i);
expect(input).toHaveValue("https://cal.example.org/calendars/user1/cal1");
- // Click copy button
- const copyButton = screen.getAllByRole("button")[0];
- fireEvent.click(copyButton);
+ // Click copy button (find button containing ContentCopyIcon)
+ const copyIcon = screen.getByTestId("ContentCopyIcon");
+ const copyButton = copyIcon.closest("button");
+ if (copyButton) {
+ fireEvent.click(copyButton);
+ }
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(
"https://cal.example.org/calendars/user1/cal1"
diff --git a/__test__/features/Events/EventModal.test.tsx b/__test__/features/Events/EventModal.test.tsx
index 03275b8..6b44658 100644
--- a/__test__/features/Events/EventModal.test.tsx
+++ b/__test__/features/Events/EventModal.test.tsx
@@ -124,10 +124,10 @@ describe("EventPopover", () => {
expect(calendarSelect).toBeInTheDocument();
// Check button
- expect(screen.getByText("Show More")).toBeInTheDocument();
+ expect(screen.getByText("More options")).toBeInTheDocument();
// Extended mode
- fireEvent.click(screen.getByText("Show More"));
+ fireEvent.click(screen.getByText("More options"));
// Back button appears
expect(screen.getByLabelText("show less")).toBeInTheDocument();
@@ -330,6 +330,9 @@ describe("EventPopover", () => {
it("calls onClose when Cancel clicked", () => {
renderPopover();
+ // Cancel button only appears in expanded mode
+ fireEvent.click(screen.getByText("More options"));
+
fireEvent.click(screen.getByText("Cancel"));
expect(mockOnClose).toHaveBeenCalledWith({}, "backdropClick");
diff --git a/src/components/Dialog/ResponsiveDialog.tsx b/src/components/Dialog/ResponsiveDialog.tsx
index fe9bcb6..c1477d9 100644
--- a/src/components/Dialog/ResponsiveDialog.tsx
+++ b/src/components/Dialog/ResponsiveDialog.tsx
@@ -10,8 +10,11 @@ import {
Stack,
SxProps,
Theme,
+ Box,
} from "@mui/material";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
+import CloseIcon from "@mui/icons-material/Close";
+import OpenInFullIcon from "@mui/icons-material/OpenInFull";
import React, { ReactNode } from "react";
/**
@@ -73,6 +76,8 @@ interface ResponsiveDialogProps
dialogTitleProps?: Omit;
/** Whether to display dividers between title/content/actions */
dividers?: boolean;
+ /** Whether to show header action icons (expand/close) in normal mode (default: true) */
+ showHeaderActions?: boolean;
}
function ResponsiveDialog({
@@ -93,6 +98,7 @@ function ResponsiveDialog({
dialogContentProps,
dialogTitleProps,
dividers = false,
+ showHeaderActions = true,
sx,
...otherDialogProps
}: ResponsiveDialogProps) {
@@ -150,6 +156,29 @@ function ResponsiveDialog({
>
+ ) : showHeaderActions ? (
+
+ {title}
+
+ {onExpandToggle && (
+
+
+
+ )}
+
+
+
+
+
) : (
title
)}
diff --git a/src/features/Events/EventDisplayPreview.tsx b/src/features/Events/EventDisplayPreview.tsx
index 72eaf12..6066574 100644
--- a/src/features/Events/EventDisplayPreview.tsx
+++ b/src/features/Events/EventDisplayPreview.tsx
@@ -115,6 +115,7 @@ export default function EventPreviewModal({
onClose({}, "backdropClick")}
+ showHeaderActions={false}
style={{ overflow: "auto" }}
title={
event.title && (
diff --git a/src/features/Events/EventModal.tsx b/src/features/Events/EventModal.tsx
index 2cb1458..307be39 100644
--- a/src/features/Events/EventModal.tsx
+++ b/src/features/Events/EventModal.tsx
@@ -1,7 +1,5 @@
import { CalendarApi, DateSelectArg } from "@fullcalendar/core";
import {
- Box,
- Button,
Checkbox,
FormControl,
FormControlLabel,
@@ -23,6 +21,8 @@ import {
ContentCopy as CopyIcon,
Close as DeleteIcon,
} from "@mui/icons-material";
+import { Box, Button } from "@mui/material";
+import AddIcon from "@mui/icons-material/Add";
import React, {
useEffect,
useState,
@@ -409,12 +409,16 @@ function EventPopover({
const dialogActions = (
{!showMore && (
-
+ } onClick={() => setShowMore(!showMore)}>
+ More options
+
)}
-
+ {showMore && (
+
+ )}
diff --git a/src/features/Events/EventUpdateModal.tsx b/src/features/Events/EventUpdateModal.tsx
index 31bb817..ad85c46 100644
--- a/src/features/Events/EventUpdateModal.tsx
+++ b/src/features/Events/EventUpdateModal.tsx
@@ -1,4 +1,5 @@
import { Box, Button } from "@mui/material";
+import AddIcon from "@mui/icons-material/Add";
import React, {
useEffect,
useState,
@@ -658,12 +659,16 @@ function EventUpdateModal({
const dialogActions = (
{!showMore && (
-
+ } onClick={() => setShowMore(!showMore)}>
+ More options
+
)}
-
+ {showMore && (
+
+ )}