Skip to content

Commit

Permalink
Merge pull request #33 from DigitalCommons/directory-item-about-text
Browse files Browse the repository at this point in the history
Directory item about text
  • Loading branch information
ms0ur1s authored and Nick Stokoe committed Oct 23, 2024
2 parents 537e5c3 + 364d0c8 commit ab1d574
Show file tree
Hide file tree
Showing 7 changed files with 279 additions and 38 deletions.
78 changes: 72 additions & 6 deletions apps/front-end/src/components/panel/Panel.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,51 @@ import Panel from "./Panel";
import { store } from "../../app/store";
import { Provider } from "react-redux";

// Helper function to prevent link navigation and handle clicks
const attachLinkClickListeners = async (
canvasElement: HTMLElement,
onLinkClick: (link: string) => void,
) => {
const canvas = within(canvasElement);
const links = await canvas.getAllByRole("link");

// Prevent default behavior for all links
links.forEach((link) => {
link.addEventListener("click", (e) => {
e.preventDefault();
onLinkClick(link.getAttribute("href") || "unknown"); // Trigger the onLinkClick action
});
});

// Simulate clicking the first link for testing
if (links.length > 0) {
await userEvent.click(links[0]);
}
};

// Helper function to switch tabs and attach listeners
const clickInteraction = async (canvasElement: HTMLElement, args: any) => {
const canvas = within(canvasElement);

// Click the "Directory" tab to show DirectoryPanel
const directoryTab = await canvas.getByRole("tab", { name: /Directory/i });
await userEvent.click(directoryTab);

// Attach event listeners to prevent navigation
await attachLinkClickListeners(canvasElement, args.onLinkClick);
};

const meta: Meta<typeof Panel> = {
title: "Components/Panel",
component: Panel,
parameters: {
layout: "fullscreen",
},
argTypes: {
onTabChange: { action: "tabChanged" }, // Action for tab switching
onLinkClick: { action: "linkClicked" }, // Action for link clicks
onTogglePanel: { action: "panelToggled" }, // Action for toggling the panel
},
decorators: [
(Story) => (
<Provider store={store}>
Expand All @@ -32,14 +71,41 @@ export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
play: async ({ canvasElement }) => {
play: async ({
canvasElement,
args,
}: {
canvasElement: HTMLElement;
args: any;
}) => {
const canvas = within(canvasElement);

// Click to open the panel
const openButton = await canvas.getByRole("button");
await userEvent.click(openButton);
// Initially click on "Directory" tab to show DirectoryPanel
await clickInteraction(canvasElement, args);

// Now simulate switching to another tab and back to Directory
const searchTab = await canvas.getByRole("tab", { name: /Search/i });
await userEvent.click(searchTab);
args.onTabChange(1);

// Wait and then close the panel
await userEvent.click(openButton);
// Switch back to Directory tab
const directoryTab = await canvas.getByRole("tab", { name: /Directory/i });
await userEvent.click(directoryTab);
args.onTabChange(0);

// Re-apply the link click listeners when the Directory tab is re-selected
await attachLinkClickListeners(canvasElement, args.onLinkClick);
},
args: {
onTabChange: (tabIndex: number) => {
console.log(`Tab changed to ${tabIndex}`);
},
onLinkClick: (link: string) => {
console.log(`Link clicked: ${link}`);
},
onTogglePanel: (isOpen: boolean) => {
console.log(`Panel toggled: ${isOpen}`);
},
},
};

Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { Meta, StoryObj } from "@storybook/react";
import { userEvent, within } from "@storybook/test";
import DirectoryPanel from "./DirectoryPanel";
import { ThemeProvider } from "@mui/material/styles";
import theme from "../../../theme/theme";
import GlobalCSSVariables from "../../../theme/GlobalCSSVariables";

// Simulate a click event on a link within the DirectoryPanel
const clickInteraction = async (canvasElement: HTMLElement) => {
const canvas = within(canvasElement);
const links = await canvas.getAllByRole("link"); // Get all links in the panel

links.forEach((link) => {
link.addEventListener("click", (e) => e.preventDefault()); // Prevent navigation for all links
});

// Simulate clicking on the first link, for example
await userEvent.click(links[0]);
};

const meta = {
title: "DirectoryPanel",
component: DirectoryPanel,
decorators: [
(Story) => (
<ThemeProvider theme={theme}>
<GlobalCSSVariables />
<Story />
</ThemeProvider>
),
],
tags: ["autodocs"],
parameters: {
layout: "centered",
actions: {
handles: ["click a"],
},
},
} as Meta<typeof DirectoryPanel>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
play: ({ canvasElement }) => clickInteraction(canvasElement),
};
Original file line number Diff line number Diff line change
@@ -1,42 +1,71 @@
import Heading from "../heading/Heading";
import ContentPanel from "../contentPanel/ContentPanel";
import DirectoryItem from "./directoryItem/DirectoryItem";
import List from "@mui/material/List";
import ListItem from "@mui/material/ListItem";
import Link from "@mui/material/Link";
import Box from "@mui/material/Box";
import { styled } from "@mui/material/styles";

// Mock data
const countries = [
{ id: "1", name: "Argentina", link: "#" },
{ id: "2", name: "Australia", link: "#" },
{ id: "3", name: "Austria", link: "#" },
{ id: "4", name: "Bangladesh", link: "#" },
{ id: "5", name: "Barbados", link: "#" },
{ id: "6", name: "Belarus", link: "#" },
{ id: "7", name: "Belgium", link: "#" },
{ id: "8", name: "Bolivia", link: "#" },
{ id: "9", name: "Brazil", link: "#" },
{ id: "10", name: "Bulgaria", link: "#" },
{ id: "11", name: "Canada", link: "#" },
{ id: "12", name: "Chile", link: "#" },
{ id: "13", name: "China", link: "#" },
{ id: "14", name: "Colombia", link: "#" },
{ id: "15", name: "Costa Rica", link: "#" },
{ id: "16", name: "Côte d'Ivoire", link: "#" },
{ id: "17", name: "Curaçao", link: "#" },
{ id: "18", name: "Cyprus", link: "#" },
{ id: "19", name: "Czechia", link: "#" },
{ id: "1", name: "Argentina", link: "" },
{ id: "2", name: "Australia", link: "" },
{ id: "3", name: "Austria", link: "" },
{ id: "4", name: "Bangladesh", link: "" },
{ id: "5", name: "Barbados", link: "" },
{ id: "6", name: "Belarus", link: "" },
{ id: "7", name: "Belgium", link: "" },
{ id: "8", name: "Bolivia", link: "" },
{ id: "9", name: "Brazil", link: "" },
{ id: "10", name: "Bulgaria", link: "" },
{ id: "11", name: "Canada", link: "" },
{ id: "12", name: "Chile", link: "" },
{ id: "13", name: "China", link: "" },
{ id: "14", name: "Colombia", link: "" },
{ id: "15", name: "Costa Rica", link: "" },
{ id: "16", name: "Côte d'Ivoire", link: "" },
{ id: "17", name: "Curaçao", link: "" },
{ id: "18", name: "Cyprus", link: "" },
{ id: "19", name: "Czechia", link: "" },
];

const DirectoryPanel = () => {
interface DirectoryPanelProps {
onClick?: (e: React.MouseEvent) => void; // for storybook testing
}

const StyledDirectoryPanel = styled(Box)(() => ({
padding: "var(--spacing-medium) 0",
maxWidth: "var(--panel-width-desktop)",
margin: "0 auto",
"@media (min-width: 768px)": {
padding: "var(--spacing-large) 0",
},
}));

const StyledLink = styled(Link)(() => ({
color: "var(--color-primary)",
display: "block",
"&:hover": {
backgroundColor: "var(--color-neutral-light)",
},
}));

const DirectoryPanel = ({onClick}: DirectoryPanelProps) => {
return (
<>
<Heading title="Directory" />
<ContentPanel>
<StyledDirectoryPanel>
<List>
<ListItem>
<StyledLink href="" role="link" onClick={onClick}>
All Entries
</StyledLink>
</ListItem>
{countries.map((country) => (
<DirectoryItem key={country.id} {...country} link={country.link} />
))}
</List>
</ContentPanel>
</StyledDirectoryPanel>
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type { Meta, StoryObj } from "@storybook/react";
import { userEvent, within } from "@storybook/test";
import DirectoryItem from "./DirectoryItem";
import { ThemeProvider } from "@mui/material/styles";
import theme from "../../../../theme/theme";
import GlobalCSSVariables from "../../../../theme/GlobalCSSVariables";

// Simulate a click event on a link
const clickInteraction = async (canvasElement: HTMLElement) => {
const canvas = within(canvasElement);
const link = await canvas.getByRole("link");
await userEvent.click(link);
};

const meta = {
title: "DirectoryItem",
component: DirectoryItem,
decorators: [
(Story) => (
<ThemeProvider theme={theme}>
<GlobalCSSVariables />
<Story />
</ThemeProvider>
),
],
tags: ["autodocs"],
argTypes: {
onClick: { action: "clicked" }, // This action will log the event
},
args: {
link: "javascript:void(0)", // Prevent navigation by using this link
},
parameters: {
layout: "centered",
actions: {
handles: ["click a"],
},
},
} as Meta<typeof DirectoryItem>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
name: "Directory Item",
onClick: (e: React.MouseEvent) => {
e.preventDefault();
console.log("Link clicked"); // Log the event to show it's working
},
},
play: ({ canvasElement }) => clickInteraction(canvasElement),
};
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
import React from "react";
import ListItem from "@mui/material/ListItem";
import { styled } from "@mui/material/styles";
import Link from "@mui/material/Link";

interface DirectoryItemProps {
id: string;
name: string;
link: string;
onClick?: (e: React.MouseEvent) => void; // for storybook testing
}

const DirectoryItem = ({id, name, link}: DirectoryItemProps) => {
return <ListItem key={id}>{name}</ListItem>;
const StyledLink = styled(Link)(() => ({
color: "var(--color-text)",
"&:hover": {
backgroundColor: "var(--color-neutral-light)",
},
}));

const DirectoryItem = ({ id, name, link, onClick }: DirectoryItemProps) => {
return (
<ListItem key={id}>
<StyledLink href={link} role="link" onClick={onClick}>{name}</StyledLink>
</ListItem>
);
};

export default DirectoryItem;
3 changes: 3 additions & 0 deletions apps/front-end/src/theme/GlobalCSSVariables.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ const rootVariables = {
"--font-size-xlarge": "20px",
"--font-size-xxlarge": "24px",
"--font-size-xxxlarge": "32px",
"--font-weight-normal": 400,
"--font-weight-medium": 500,
"--font-weight-bold": 600,
};

const GlobalCSSVariables: FC = () => {
Expand Down
Loading

0 comments on commit ab1d574

Please sign in to comment.