Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modal component #15

Merged
merged 13 commits into from
Sep 2, 2024
Merged
39 changes: 39 additions & 0 deletions src/components/Modal/Modal.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Modal } from './Modal';
import type { Meta, StoryObj } from '@storybook/react';

const meta = {
title: 'Components/Modal',
component: Modal,
} satisfies Meta<typeof Modal>;

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

const defaultProps = {

};

const disableControls = {
parameters: {
controls: {
disable: true
},
actions: {
disable: true
},
}
};

export const Demo: Story = {
args: {
...defaultProps
},
tags: ['excludeFromSidebar']
};

export const Default: Story = {
args: {
...defaultProps
},
...disableControls
};
35 changes: 35 additions & 0 deletions src/components/Modal/Modal.style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import styled from 'styled-components';
import { getLuminance, shade, tint } from 'polished';

export const StyledModal = styled.div`
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
background-color: ${(props) => {
const bgColor = props.theme.colors.background || '#ffffff';
const isDark = getLuminance(bgColor) < 0.5;
return isDark ? tint(0.1, bgColor) : 'white';
}};
border: 2px solid #000;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
padding: ${(props) => props.theme.spacing.md || '16px'};
z-index: 10000; /* Increase z-index to ensure it is above other elements */

h2 {
margin: 0;
font-size: ${(props) => props.theme.fontSizes.lg || '1.5rem'};
}

p {
margin-top: ${(props) => props.theme.spacing.sm || '8px'};
margin-bottom: 0;
font-size: ${(props) => props.theme.fontSizes.md || '1rem'};
color: ${(props) => {
const textColor = props.theme.colors.text || '#000000';
const isDark = getLuminance(props.theme.colors.background || '#ffffff') < 0.5;
return isDark ? tint(0.1, textColor) : shade(0.2, textColor);
}};
}
`;
42 changes: 42 additions & 0 deletions src/components/Modal/Modal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { renderWithDeps } from '../../../jest.utils';
import { fireEvent, screen } from '@testing-library/react';
import { Modal } from './Modal';

describe('<Modal />', () => {
it('renders', () => {
renderWithDeps(<Modal />);

const modal = screen.getByTestId('Modal');

expect(modal).toBeInTheDocument();
});

it('opens the modal when clicking the Open button', () => {
renderWithDeps(<Modal />);

const openButton = screen.getByText('Open modal');
fireEvent.click(openButton);

// Check if the modal content is visible
const modalTitle = screen.getByText('Text in a modal');
expect(modalTitle).toBeVisible();
});

it('closes the modal when clicking the Close button', () => {
renderWithDeps(<Modal />);

const openButton = screen.getByText('Open modal');
fireEvent.click(openButton);

// Check if the modal is opened
const modalTitle = screen.getByText('Text in a modal');
expect(modalTitle).toBeVisible();

// Click the close button
const closeButton = screen.getByText('Close');
fireEvent.click(closeButton);

// Check if the modal content is no longer visible
expect(modalTitle).not.toBeVisible();
});
});
26 changes: 26 additions & 0 deletions src/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { useState } from 'react';
import { StyledModal } from './Modal.style';

export const Modal: React.FC = () => {
const [open, setOpen] = useState(false);

const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);

return (
<div data-testid="Modal">
<button onClick={handleOpen}>Open modal</button>
Narinder788 marked this conversation as resolved.
Show resolved Hide resolved
{open && (
<>
<StyledModal onClick={handleClose}>
<h2 id="modal-title">Text in a modal</h2>
<p id="modal-description">
Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
</p>
<button onClick={handleClose}>Close</button>
</StyledModal>
</>
)}
</div>
);
};
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './components/Label/Label';
export * from './components/LinkButton/LinkButton';
export * from './components/Table/Table';
export * from './components/TruncatedText/TruncatedText';
export * from './components/Modal/Modal';
Loading