mirror of
https://github.com/LukeHagar/firecamp.git
synced 2025-12-10 12:27:45 +00:00
ui(Modal): removed previous modal package & updated stories
This commit is contained in:
@@ -84,7 +84,6 @@
|
||||
"react-ga": "^3.1.2",
|
||||
"react-hook-form": "^6.8.1",
|
||||
"react-hotkeys-hook": "^3.3.1",
|
||||
"react-responsive-modal": "^6.2.0",
|
||||
"redux": "^3.2.1",
|
||||
"xml-js": "^1.6.9",
|
||||
"xmljson": "^0.2.0",
|
||||
|
||||
@@ -85,7 +85,7 @@ export const PromptInput: FC<IPromptInput> = ({
|
||||
onClose={_close}
|
||||
size={400}
|
||||
classNames={{
|
||||
header: 'border-0',
|
||||
header: 'border-0 pb-0',
|
||||
body: 'px-6',
|
||||
content: 'min-h-0',
|
||||
}}
|
||||
@@ -96,7 +96,7 @@ export const PromptInput: FC<IPromptInput> = ({
|
||||
}
|
||||
>
|
||||
<ProgressBar active={state.isExecuting} />
|
||||
<div className="">
|
||||
<div className="pt-4">
|
||||
<div className="">
|
||||
<Input
|
||||
autoFocus={true}
|
||||
|
||||
@@ -94,7 +94,7 @@ export const PromptSaveItem: FC<IPromptSaveItem> = ({
|
||||
onClose={_close}
|
||||
size={400}
|
||||
classNames={{
|
||||
header: 'border-0 px-6 pt-6',
|
||||
header: 'border-0 px-6 pt-6 pb-0',
|
||||
|
||||
}}
|
||||
title={
|
||||
@@ -105,7 +105,7 @@ export const PromptSaveItem: FC<IPromptSaveItem> = ({
|
||||
>
|
||||
<ProgressBar active={state.isExecuting} />
|
||||
<>
|
||||
<div className='h-[340px]'>
|
||||
<div className='h-[340px] pt-4'>
|
||||
<div className="mt-4">
|
||||
<Input
|
||||
autoFocus={true}
|
||||
|
||||
@@ -110,7 +110,6 @@
|
||||
"react-complex-tree": "^2.0.0",
|
||||
"react-hook-form": "^6.8.1",
|
||||
"react-reflex": "^4.0.3",
|
||||
"react-responsive-modal": "^6.2.0",
|
||||
"react-table": "7.8.0",
|
||||
"react-tiny-popover": "^7.0.1",
|
||||
"react-window": "^1.8.5",
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
/*-----Modal css Start------------*/
|
||||
|
||||
.react-responsive-modal-modal {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.react-responsive-modal-closeButton {
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
a.border {
|
||||
border-color: inherit !important;
|
||||
}
|
||||
|
||||
.fc-modal-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 90vh;
|
||||
min-height: 400px;
|
||||
}
|
||||
/*-----Modal css End------------*/
|
||||
@@ -7,43 +7,12 @@ import LinkTo from '@storybook/addon-links/react';
|
||||
|
||||
Modal : To create modals
|
||||
|
||||
- Consists of sub-section like :
|
||||
- header
|
||||
- Consists of section like :
|
||||
- header (includes title)
|
||||
- body
|
||||
- footer
|
||||
- Any of the section can be used individually as well.
|
||||
|
||||
#### **Component Usage**:
|
||||
|
||||
Use `Modal` as wrapper to use single/multiple sub sections <br/>
|
||||
Modal is created using `react-responsive-modal`
|
||||
|
||||
| Component | Description |
|
||||
| ------------ | -------------------------------------------------------------- |
|
||||
| Modal | Wrapper for which takes height & width of its parent component |
|
||||
| Modal.Header | section for the header having height of its content |
|
||||
| Modal.Body | section for the body having the height of its content |
|
||||
| Modal.Footer | section for the footer having height of its content |
|
||||
|
||||
#### **Best Practices**:
|
||||
|
||||
Do:
|
||||
|
||||
```
|
||||
<Modal>
|
||||
<Modal.Header>
|
||||
Header Section
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<component> Body Section </component>
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
Footer Section
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
```
|
||||
|
||||
- #### **Examples**:
|
||||
- <LinkTo kind="ui-kit-modal--modal-demo" className="!text-primaryColor">
|
||||
Modal Examples
|
||||
</LinkTo>
|
||||
- The Modal component is implemented using MantineModal.
|
||||
- It shares the same prop usage as described in the documentation for MantineModal.
|
||||
- It is essential to supply values for the "opened" prop and the "onClose" prop to control the modal's visibility and handle the close event, respectively.
|
||||
|
||||
@@ -1,118 +1,113 @@
|
||||
import { useState } from "react";
|
||||
import { VscGithub } from "@react-icons/all-files/vsc/VscGithub";
|
||||
import { VscLock } from "@react-icons/all-files/vsc/VscLock";
|
||||
import { VscAccount } from "@react-icons/all-files/vsc/VscAccount";
|
||||
import { GrGoogle } from "@react-icons/all-files/gr/GrGoogle";
|
||||
import { useState } from 'react';
|
||||
import { VscGithub } from '@react-icons/all-files/vsc/VscGithub';
|
||||
import { VscLock } from '@react-icons/all-files/vsc/VscLock';
|
||||
import { VscAccount } from '@react-icons/all-files/vsc/VscAccount';
|
||||
|
||||
import { default as Modal } from './Modal';
|
||||
import { default as Button } from '../buttons/Button';
|
||||
import { default as FormField } from '../form/FormField';
|
||||
import { default as Input } from '../input/Input';
|
||||
import { Modal, Button, FormField, Input, IModal } from '@firecamp/ui';
|
||||
|
||||
export default {
|
||||
title: "UI-Kit/Modal",
|
||||
component: Modal,
|
||||
argTypes: {
|
||||
className: ""
|
||||
}
|
||||
title: 'UI-Kit/Modal',
|
||||
component: Modal,
|
||||
argTypes: {
|
||||
className: '',
|
||||
},
|
||||
};
|
||||
|
||||
const Template = (args: any) => {
|
||||
const [isOpen, toggleOpen] = useState(true);
|
||||
const Template = ({ opened, ...args }: IModal) => {
|
||||
const [isOpen, openModal] = useState(opened);
|
||||
|
||||
return <div className="bg-app-background h-screen w-screen block">
|
||||
<Button text="Open Modal" onClick={() => toggleOpen(true)} />
|
||||
<Modal {...args} isOpen={isOpen} onClose={() => toggleOpen(false)}>
|
||||
<Modal.Header >
|
||||
{args?.header() || ''}
|
||||
</Modal.Header>
|
||||
<Modal.Body >
|
||||
{args?.body() || ''}
|
||||
</Modal.Body>
|
||||
<Modal.Footer >
|
||||
{args?.footer() || ''}
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
return (
|
||||
<div>
|
||||
<Button text="Open Modal" onClick={() => openModal(true)} />
|
||||
<Modal opened={isOpen} onClose={() => openModal(false)} {...args} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const ModalDemo = Template.bind({});
|
||||
|
||||
ModalDemo.args = {
|
||||
className: 'test',
|
||||
header: () => <ModalHeader />,
|
||||
body: () => <ModalBody />,
|
||||
footer: () => <ModalFooter />
|
||||
opened: true,
|
||||
title: <div>SignIn to Firecamp</div>,
|
||||
children: <FormPreview />,
|
||||
};
|
||||
|
||||
export const SignUpDemo = Template.bind({});
|
||||
|
||||
SignUpDemo.args = {
|
||||
className: 'test',
|
||||
header: () => <SignUpHeader />,
|
||||
body: () => <SignUpBody />,
|
||||
footer: () => <SignUpFooter />
|
||||
export const ModalTitleWithoutBorder = Template.bind({});
|
||||
ModalTitleWithoutBorder.args = {
|
||||
opened: true,
|
||||
title: <div>SignIn to Firecamp</div>,
|
||||
classNames: {
|
||||
header: 'border-0',
|
||||
},
|
||||
children: <FormPreview />,
|
||||
};
|
||||
export const ModalContentOverflow = Template.bind({});
|
||||
ModalContentOverflow.args = {
|
||||
opened: true,
|
||||
title: <div>SignIn to Firecamp</div>,
|
||||
children: (
|
||||
<>
|
||||
<FormPreview overflowContent />
|
||||
<FormPreview overflowContent />
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
||||
const SignUpHeader = () => {
|
||||
return (
|
||||
<div className="text-modal-foreground-active text-lg text-center mb-6">sign in to your firecamp account</div>
|
||||
)
|
||||
}
|
||||
|
||||
const SignUpBody = () => {
|
||||
return (
|
||||
<div>
|
||||
<div className="" >
|
||||
<div className="text-center w-full mb-5">new to firecamp? <a className="text-primaryColor cursor-pointer">sign up</a></div>
|
||||
<a href="#" className="text-app-foreground flex items-center justify-center bg-focusColor !border-app-border border p-1.5 hover:bg-input-background-focus hover:border-transparent hover:text-modal-foreground-active mb-6"> <VscGithub size={20} className="mr-2" /> continue with <span className="text-modal-foreground-active ml-2">github</span></a>
|
||||
<a href="#" className="text-app-foreground flex items-center justify-center bg-focusColor !border-app-border border p-1.5 hover:bg-input-background-focus hover:border-transparent hover:text-modal-foreground-active mb-6"> <GrGoogle size={20} className="mr-2" /> continue with <span className="text-modal-foreground-active ml-2">google</span></a>
|
||||
</div>
|
||||
<hr className="border-modal-border -ml-8 -mr-8 mb-6" />
|
||||
<div className="">
|
||||
<FormField label="Username or E-mail" >
|
||||
<Input
|
||||
placeholder='Username or E-mail'
|
||||
iconPosition='left'
|
||||
icon={<VscAccount title="Account" size={16} />} />
|
||||
</FormField>
|
||||
<FormField label="password">
|
||||
<Input placeholder='password' iconPosition='left' icon={<VscLock title="Account" size={16} />} />
|
||||
</FormField>
|
||||
<Button text="sign in" fullWidth primary sm/>
|
||||
<a className="cursor-pointer text-app-foreground block pb-6 text-right text-sm -mt-4">Already have an account? Sign In</a>
|
||||
</div>
|
||||
function FormPreview({ overflowContent = false }) {
|
||||
return (
|
||||
<div className="pt-6">
|
||||
<div>
|
||||
<div className="">
|
||||
<a
|
||||
href="#"
|
||||
className="text-app-foreground flex items-center justify-center bg-focusColor !border-app-border border p-1.5 hover:bg-input-background-focus hover:border-transparent hover:text-modal-foreground-active mb-6"
|
||||
>
|
||||
{' '}
|
||||
<VscGithub size={20} className="mr-2" /> continue with{' '}
|
||||
<span className="text-modal-foreground-active ml-2">github</span>
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const SignUpFooter = () => {
|
||||
return (
|
||||
<div className="text-sm mt-6">
|
||||
By moving forward, you acknowledge that you have read and accept the <a className="text-modal-foreground-active cursor-pointer">Terms of Service</a> and <a className="text-modal-foreground-active">Privacy Policy.</a>
|
||||
<div className="relative my-4 flex justify-center items-center">
|
||||
<hr className="border-t border-app-border w-full" />
|
||||
<span className="text-xs text-app-foreground-inactive bg-modal-background absolute px-1">
|
||||
OR
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const ModalHeader = () => {
|
||||
return (
|
||||
<div className="text-modal-foreground-active text-lg mb-6">Modal Header</div>
|
||||
)
|
||||
}
|
||||
|
||||
const ModalBody = () => {
|
||||
return (
|
||||
<div>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
|
||||
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
|
||||
<div className="">
|
||||
<div className="text-center w-full text-sm mb-5">
|
||||
Sign in again to continue
|
||||
</div>
|
||||
<FormField label="Username or E-mail">
|
||||
<Input
|
||||
value="dnishchit@gmail.com"
|
||||
iconPosition="left"
|
||||
icon={<VscAccount title="Account" size={16} />}
|
||||
/>
|
||||
</FormField>
|
||||
<FormField label="password">
|
||||
<Input
|
||||
placeholder="password"
|
||||
iconPosition="left"
|
||||
icon={<VscLock title="Account" size={16} />}
|
||||
/>
|
||||
</FormField>
|
||||
<a className="cursor-pointer text-app-foreground block pb-6 text-right text-sm">
|
||||
Forgot Password?
|
||||
</a>
|
||||
<Button text="sign in" fullWidth primary sm />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
||||
const ModalFooter = () => {
|
||||
return (
|
||||
<div className="text-sm mt-6">
|
||||
Modal Footer
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{overflowContent ? (
|
||||
<>
|
||||
<hr className="border-modal-border -ml-8 -mr-8 mb-6 mt-6" />
|
||||
<div className="text-sm mt-6">
|
||||
<div className="text-center">SignOut Forcefully</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,88 +1,85 @@
|
||||
import { useState } from "react";
|
||||
import "@testing-library/jest-dom";
|
||||
import { screen, render, waitFor } from "@testing-library/react";
|
||||
import { default as Modal } from './Modal';
|
||||
import Button from "../buttons/Button";
|
||||
import { click } from "../../../__mocks__/eventMock";
|
||||
// TODO : update tests based on new button
|
||||
|
||||
const Template = (args: any) => {
|
||||
const [isOpen, toggleOpen] = useState(true);
|
||||
// import { useState } from "react";
|
||||
// import "@testing-library/jest-dom";
|
||||
// import { screen, render, waitFor } from "@testing-library/react";
|
||||
// import { default as Modal } from './Modal';
|
||||
// import Button from "../buttons/Button";
|
||||
// import { click } from "../../../__mocks__/eventMock";
|
||||
|
||||
return <div className="bg-app-background h-screen w-screen block">
|
||||
<Button text={isOpen ? "Close Modal" : "Open Modal"} onClick={() => toggleOpen(true)} data-testid={'togglePreview'} />
|
||||
<Modal {...args} isOpen={isOpen} onClose={() => toggleOpen(false)}>
|
||||
<Modal.Header>
|
||||
<div className="text-modal-foreground-active text-lg mb-6">Modal Header</div>
|
||||
</Modal.Header>
|
||||
<Modal.Body >
|
||||
<div>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
|
||||
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
|
||||
</div>
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<div className="text-sm mt-6">
|
||||
Modal Footer
|
||||
</div>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
</div>
|
||||
};
|
||||
// const Template = (args: any) => {
|
||||
// const [isOpen, toggleOpen] = useState(true);
|
||||
|
||||
describe("Modal component", () => {
|
||||
// return <div className="bg-app-background h-screen w-screen block">
|
||||
// <Button text={isOpen ? "Close Modal" : "Open Modal"} onClick={() => toggleOpen(true)} data-testid={'togglePreview'} />
|
||||
// <Modal {...args} isOpen={isOpen} onClose={() => toggleOpen(false)}>
|
||||
// <Modal.Header>
|
||||
// <div className="text-modal-foreground-active text-lg mb-6">Modal Header</div>
|
||||
// </Modal.Header>
|
||||
// <Modal.Body >
|
||||
// <div>
|
||||
// Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
|
||||
// Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
|
||||
// </div>
|
||||
// </Modal.Body>
|
||||
// <Modal.Footer>
|
||||
// <div className="text-sm mt-6">
|
||||
// Modal Footer
|
||||
// </div>
|
||||
// </Modal.Footer>
|
||||
// </Modal>
|
||||
// </div>
|
||||
// };
|
||||
|
||||
test("Validating child element count and styles of modal wrapper", () => {
|
||||
render(<Template id={'modal-container-div'} />);
|
||||
// describe("Modal component", () => {
|
||||
|
||||
const ModalContainer = screen.queryByTestId('root');
|
||||
const ModalContainerDiv = ModalContainer.querySelector('#modal-container-div');
|
||||
// test("Validating child element count and styles of modal wrapper", () => {
|
||||
// render(<Template id={'modal-container-div'} />);
|
||||
|
||||
expect(ModalContainerDiv).toHaveClass('max-w-screen-md min-w-screen-md bg-modal-background text-app-foreground w-full relative z-9999 max-h-modal flex fc-modal-wrapper');
|
||||
expect(ModalContainerDiv.childElementCount).toBe(3);
|
||||
// const ModalContainer = screen.queryByTestId('root');
|
||||
// const ModalContainerDiv = ModalContainer.querySelector('#modal-container-div');
|
||||
|
||||
// expect(ModalContainerDiv).toHaveClass('max-w-screen-md min-w-screen-md bg-modal-background text-app-foreground w-full relative z-9999 max-h-modal flex fc-modal-wrapper');
|
||||
// expect(ModalContainerDiv.childElementCount).toBe(3);
|
||||
|
||||
});
|
||||
// });
|
||||
|
||||
test("Validating default classnames for modal children elements", () => {
|
||||
render(<Template id={'modal-container-div'} />);
|
||||
// test("Validating default classnames for modal children elements", () => {
|
||||
// render(<Template id={'modal-container-div'} />);
|
||||
|
||||
const ModalContainer = screen.queryByTestId('root');
|
||||
const ModalContainerDiv = ModalContainer.querySelector('#modal-container-div');
|
||||
const ModalContainerElements = ModalContainerDiv.children;
|
||||
// const ModalContainer = screen.queryByTestId('root');
|
||||
// const ModalContainerDiv = ModalContainer.querySelector('#modal-container-div');
|
||||
// const ModalContainerElements = ModalContainerDiv.children;
|
||||
|
||||
//Header - dont have default class names
|
||||
// //Header - dont have default class names
|
||||
|
||||
//Body
|
||||
expect(ModalContainerElements[1]).toHaveClass('flex flex-col overflow-auto')
|
||||
// //Body
|
||||
// expect(ModalContainerElements[1]).toHaveClass('flex flex-col overflow-auto')
|
||||
|
||||
//Footer
|
||||
expect(ModalContainerElements[2]).toHaveClass('flex')
|
||||
});
|
||||
// //Footer
|
||||
// expect(ModalContainerElements[2]).toHaveClass('flex')
|
||||
// });
|
||||
|
||||
test("should appears/disappers based on button click event", async () => {
|
||||
render(<Template id={'modal-container-div'} />);
|
||||
// test("should appears/disappers based on button click event", async () => {
|
||||
// render(<Template id={'modal-container-div'} />);
|
||||
|
||||
// when react-responsive-modal is visible
|
||||
const container = screen.queryByTestId('overlay');
|
||||
expect(container).toHaveStyle("animation: react-responsive-modal-overlay-in 300ms");
|
||||
// // when react-responsive-modal is visible
|
||||
// const container = screen.queryByTestId('overlay');
|
||||
// expect(container).toHaveStyle("animation: react-responsive-modal-overlay-in 300ms");
|
||||
|
||||
// validate the button text for popup state
|
||||
let button = screen.queryByText('Close Modal');
|
||||
expect(button).toBeInTheDocument();
|
||||
// // validate the button text for popup state
|
||||
// let button = screen.queryByText('Close Modal');
|
||||
// expect(button).toBeInTheDocument();
|
||||
|
||||
// modal should not be visible after clicking close button
|
||||
const ClosePopupButton = screen.queryByTestId("close-button");
|
||||
click(ClosePopupButton);
|
||||
// // modal should not be visible after clicking close button
|
||||
// const ClosePopupButton = screen.queryByTestId("close-button");
|
||||
// click(ClosePopupButton);
|
||||
|
||||
button = await waitFor(() => screen.queryByText('Open Modal'));
|
||||
expect(button).toBeInTheDocument();
|
||||
// button = await waitFor(() => screen.queryByText('Open Modal'));
|
||||
// expect(button).toBeInTheDocument();
|
||||
|
||||
// visibility of react-responsive-modal is seen by update in style property
|
||||
expect(container).toHaveStyle("animation: react-responsive-modal-overlay-out 300ms");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Todo update the import in Modal component to run the test case
|
||||
// import Container from "../grid/Container";
|
||||
// import Row from "../grid/Row";
|
||||
// // visibility of react-responsive-modal is seen by update in style property
|
||||
// expect(container).toHaveStyle("animation: react-responsive-modal-overlay-out 300ms");
|
||||
// });
|
||||
|
||||
// });
|
||||
|
||||
@@ -1,101 +1,93 @@
|
||||
import { FC } from 'react';
|
||||
import cx from 'classnames';
|
||||
import { VscClose } from '@react-icons/all-files/vsc/VscClose';
|
||||
import ResponsiveModal from 'react-responsive-modal';
|
||||
import 'react-responsive-modal/styles.css';
|
||||
import './Modal.scss';
|
||||
import { Modal as MantineModal, ModalProps, ScrollArea } from '@mantine/core';
|
||||
import { createStyles } from '@mantine/core';
|
||||
|
||||
import { Container, Row } from '../../ui-kit';
|
||||
export interface IModal extends ModalProps {}
|
||||
|
||||
import { IModal, IHeader, IBody, IFooter } from './interfaces/Modal.interface';
|
||||
// custom styles for variants
|
||||
const useStyles = createStyles((theme, { title }: IModal) => ({
|
||||
content: {
|
||||
borderRadius: '0px',
|
||||
backgroundColor:
|
||||
theme.colorScheme === 'light'
|
||||
? theme.colors.gray[1]
|
||||
: theme.colors.dark[6],
|
||||
color:
|
||||
theme.colorScheme === 'light'
|
||||
? theme.colors.dark[5]
|
||||
: theme.colors.gray[4],
|
||||
maxWidth: '48rem',
|
||||
minHeight: '400px',
|
||||
},
|
||||
header: {
|
||||
backgroundColor: 'transparent',
|
||||
color:
|
||||
theme.colorScheme === 'light'
|
||||
? theme.colors.dark[5]
|
||||
: theme.colors.gray[4],
|
||||
paddingRight: '1rem',
|
||||
paddingTop: '1rem',
|
||||
paddingBottom: !!title ? '1rem' : '0px',
|
||||
...(!!title
|
||||
? {
|
||||
borderBottom: `1px solid ${
|
||||
theme.colorScheme === 'light'
|
||||
? theme.colors.gray[4]
|
||||
: theme.colors.dark[4]
|
||||
}`,
|
||||
backgroundColor:
|
||||
theme.colorScheme === 'light'
|
||||
? theme.colors.gray[1]
|
||||
: theme.colors.dark[6],
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
body: {
|
||||
paddingLeft: '2rem',
|
||||
paddingRight: '2rem',
|
||||
paddingBottom: '2rem',
|
||||
position: 'relative',
|
||||
},
|
||||
}));
|
||||
|
||||
const Modal: FC<IModal> & {
|
||||
Header: FC<IHeader>;
|
||||
Body: FC<IBody>;
|
||||
Footer: FC<IFooter>;
|
||||
} = ({
|
||||
const Modal: FC<IModal> = ({
|
||||
id = '',
|
||||
showCloseIcon = true,
|
||||
isOpen = false,
|
||||
className = '',
|
||||
modalClass = '',
|
||||
modalConfig = {},
|
||||
opened = false,
|
||||
classNames = {},
|
||||
onClose = () => {},
|
||||
children = '',
|
||||
height,
|
||||
width,
|
||||
children = <></>,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<ResponsiveModal
|
||||
open={isOpen}
|
||||
onClose={() => {
|
||||
onClose();
|
||||
}}
|
||||
center
|
||||
closeIcon={<VscClose size={20} className="cursor-pointer z-50" />}
|
||||
{...modalConfig}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
className,
|
||||
'max-w-screen-md min-w-screen-md bg-modal-background text-app-foreground w-full relative z-9999 max-h-modal flex fc-modal-wrapper h-full'
|
||||
)}
|
||||
style={{ height: height, width: width }}
|
||||
id={id}
|
||||
>
|
||||
{/* {showCloseIcon ? (
|
||||
<VscClose
|
||||
size={20}
|
||||
className="absolute top-3 right-3 cursor-pointer z-50"
|
||||
onClick={(e) => {
|
||||
onClose();
|
||||
}}
|
||||
/>
|
||||
) : <></>} */}
|
||||
{children}
|
||||
</div>
|
||||
</ResponsiveModal>
|
||||
);
|
||||
};
|
||||
const { classes, cx, theme } = useStyles({
|
||||
title: props.title,
|
||||
opened,
|
||||
onClose: () => {},
|
||||
});
|
||||
|
||||
// `id`: is not being updated on the element
|
||||
let Header: FC<IHeader> = ({ id = '', children = '', className = '' }) => {
|
||||
return (
|
||||
<Container.Header className={className || ''} id={id}>
|
||||
{children}
|
||||
</Container.Header>
|
||||
);
|
||||
};
|
||||
|
||||
// `id`: is not being updated on the element
|
||||
let Body: FC<IBody> = ({
|
||||
id = '',
|
||||
children = '',
|
||||
className = '',
|
||||
scrollbar = true,
|
||||
}) => {
|
||||
return (
|
||||
<Container.Body
|
||||
className={cx(className, 'flex flex-col overflow-auto thin !p-4', {
|
||||
'visible-scrollbar': scrollbar,
|
||||
})}
|
||||
<MantineModal
|
||||
opened={opened}
|
||||
onClose={() => onClose()}
|
||||
id={id}
|
||||
centered
|
||||
classNames={{
|
||||
...classNames,
|
||||
content: cx('invisible-scrollbar', classes.content, classNames.content),
|
||||
header: cx(classes.header, classNames.header),
|
||||
body: cx(classes.body, classNames.body),
|
||||
}}
|
||||
scrollAreaComponent={ScrollArea.Autosize}
|
||||
closeButtonProps={{
|
||||
bg:
|
||||
theme.colorScheme === 'light'
|
||||
? theme.colors.gray[1]
|
||||
: theme.colors.dark[6],
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Container.Body>
|
||||
</MantineModal>
|
||||
);
|
||||
};
|
||||
|
||||
let Footer: FC<IFooter> = ({ id = '', children = '', className = '' }) => {
|
||||
return (
|
||||
<Container.Footer className={className || 'flex'} id={id}>
|
||||
<Row className="w-full with-divider">{children}</Row>
|
||||
</Container.Footer>
|
||||
);
|
||||
};
|
||||
|
||||
Modal.Header = Header;
|
||||
Modal.Body = Body;
|
||||
Modal.Footer = Footer;
|
||||
|
||||
export default Modal;
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
import { FC } from 'react';
|
||||
import { Modal as MantineModal, ModalProps, ScrollArea } from '@mantine/core';
|
||||
import { createStyles } from '@mantine/core';
|
||||
|
||||
export interface IModal extends ModalProps {}
|
||||
|
||||
// custom styles for variants
|
||||
const useStyles = createStyles((theme, { title }: IModal) => ({
|
||||
content: {
|
||||
borderRadius: '0px',
|
||||
backgroundColor:
|
||||
theme.colorScheme === 'light'
|
||||
? theme.colors.gray[1]
|
||||
: theme.colors.dark[6],
|
||||
color:
|
||||
theme.colorScheme === 'light'
|
||||
? theme.colors.dark[5]
|
||||
: theme.colors.gray[4],
|
||||
maxWidth: '48rem',
|
||||
minHeight: '400px',
|
||||
},
|
||||
header: {
|
||||
backgroundColor: 'transparent',
|
||||
color:
|
||||
theme.colorScheme === 'light'
|
||||
? theme.colors.dark[5]
|
||||
: theme.colors.gray[4],
|
||||
paddingRight: '1rem',
|
||||
paddingTop: '1rem',
|
||||
paddingBottom: !!title ? '1rem' : '0px',
|
||||
...(!!title
|
||||
? {
|
||||
borderBottom: `1px solid ${
|
||||
theme.colorScheme === 'light'
|
||||
? theme.colors.gray[4]
|
||||
: theme.colors.dark[4]
|
||||
}`,
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
body: {
|
||||
paddingLeft: '2rem',
|
||||
paddingRight: '2rem',
|
||||
paddingBottom: '2rem',
|
||||
position: 'relative',
|
||||
},
|
||||
}));
|
||||
|
||||
const Modal: FC<IModal> = ({
|
||||
id = '',
|
||||
opened = false,
|
||||
classNames = {},
|
||||
onClose = () => {},
|
||||
children = <></>,
|
||||
...props
|
||||
}) => {
|
||||
const { classes, cx, theme } = useStyles({
|
||||
title: props.title,
|
||||
opened,
|
||||
onClose: () => {},
|
||||
});
|
||||
|
||||
return (
|
||||
<MantineModal
|
||||
opened={opened}
|
||||
onClose={() => onClose()}
|
||||
id={id}
|
||||
centered
|
||||
classNames={{
|
||||
...classNames,
|
||||
content: cx('invisible-scrollbar', classes.content, classNames.content),
|
||||
header: cx(classes.header, classNames.header),
|
||||
body: cx(classes.body, classNames.body),
|
||||
}}
|
||||
scrollAreaComponent={ScrollArea.Autosize}
|
||||
closeButtonProps={{
|
||||
bg:
|
||||
theme.colorScheme === 'light'
|
||||
? theme.colors.gray[1]
|
||||
: theme.colors.dark[6],
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</MantineModal>
|
||||
);
|
||||
};
|
||||
|
||||
export default Modal;
|
||||
@@ -1,83 +0,0 @@
|
||||
import { useState } from "react";
|
||||
import { VscGithub } from "@react-icons/all-files/vsc/VscGithub";
|
||||
import { VscLock } from "@react-icons/all-files/vsc/VscLock";
|
||||
import { VscAccount } from "@react-icons/all-files/vsc/VscAccount";
|
||||
import { GrGoogle } from "@react-icons/all-files/gr/GrGoogle";
|
||||
|
||||
import { default as Modal } from './Modal';
|
||||
import { default as Button } from '../buttons/Button';
|
||||
import { default as FormField } from '../form/FormField';
|
||||
import { default as Input } from '../input/Input';
|
||||
|
||||
|
||||
export default {
|
||||
title: "UI-Kit/Modal",
|
||||
component: Modal,
|
||||
argTypes: {
|
||||
className: ""
|
||||
}
|
||||
};
|
||||
|
||||
const Template = (args: any) => {
|
||||
let [isOpen, toggleOpen] = useState(true);
|
||||
|
||||
return <div className="bg-app-background h-screen w-screen block">
|
||||
<Button text="Open Modal" onClick={() => toggleOpen(true)}/>
|
||||
<Modal {...args} isOpen={isOpen} onClose={() => toggleOpen(false)}>
|
||||
<Modal.Header >
|
||||
{args?.header() || ''}
|
||||
</Modal.Header>
|
||||
<Modal.Body >
|
||||
{args?.body() || ''}
|
||||
</Modal.Body>
|
||||
<Modal.Footer >
|
||||
{args?.footer() || ''}
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
</div>};
|
||||
|
||||
export const SessionExpireDemo = Template.bind({});
|
||||
SessionExpireDemo.args = {
|
||||
className: 'test',
|
||||
header: () => <SignUpHeader />,
|
||||
body: () => <SignUpBody />,
|
||||
footer: () => <SignUpFooter />
|
||||
};
|
||||
|
||||
const SignUpHeader = () => {
|
||||
return (
|
||||
<div className="text-error text-lg text-center mb-6">Session expired</div>
|
||||
)
|
||||
}
|
||||
const SignUpBody = () => {
|
||||
return (
|
||||
<div>
|
||||
<div className="" >
|
||||
<div className="text-center w-full text-sm mb-5">Sign in again to continue</div>
|
||||
<FormField label="Username or E-mail" >
|
||||
<VscAccount title="Account" size={16} />
|
||||
<Input value="dnishchit@gmail.com" />
|
||||
</FormField>
|
||||
<FormField label="password" >
|
||||
<Input placeholder='password' iconPosition='left' icon={<VscLock title="Account" size={16} />} />
|
||||
</FormField>
|
||||
<a className="cursor-pointer text-app-foreground block pb-6 text-right text-sm">Forgot Password?</a>
|
||||
<Button text="sign in" fullWidth primary sm/>
|
||||
</div>
|
||||
<hr className="border-modal-border -ml-8 -mr-8 mb-6 mt-6" />
|
||||
<div className="">
|
||||
|
||||
<a href="#" className="text-app-foreground flex items-center justify-center bg-focusColor !border-app-border border p-1.5 hover:bg-input-background-focus hover:border-transparent hover:text-modal-foreground-active mb-6"> <VscGithub size={20} className="mr-2" /> continue with <span className="text-modal-foreground-active ml-2">github</span></a>
|
||||
<a href="#" className="text-app-foreground flex items-center justify-center bg-focusColor !border-app-border border p-1.5 hover:bg-input-background-focus hover:border-transparent hover:text-modal-foreground-active mb-6"> <GrGoogle size={20} className="mr-2" /> continue with <span className="text-modal-foreground-active ml-2">google</span></a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
const SignUpFooter = () => {
|
||||
return (
|
||||
<div className="text-sm mt-6">
|
||||
<div className="text-center">SignOut Forcefully</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
import { ReactChildren } from 'react';
|
||||
|
||||
export interface IModal {
|
||||
/**
|
||||
* DOM id
|
||||
*/
|
||||
id?: string;
|
||||
/**
|
||||
* Show close icon flag
|
||||
*/
|
||||
showCloseIcon?: boolean;
|
||||
/**
|
||||
* Is modal open or not
|
||||
*/
|
||||
isOpen?: boolean;
|
||||
/**
|
||||
* Classname to show custom styling
|
||||
*/
|
||||
className?: string;
|
||||
/**
|
||||
* Modal class name
|
||||
*/
|
||||
modalClass?: string;
|
||||
/**
|
||||
* Modal (react-responsive-modal) configuration
|
||||
* @ref: https://react-responsive-modal.leopradel.com/#props
|
||||
*/
|
||||
modalConfig?: object;
|
||||
/**
|
||||
* Function to call on close modal
|
||||
*/
|
||||
onClose?: (e?: any) => any;
|
||||
/**
|
||||
* child component
|
||||
*/
|
||||
children?: any;
|
||||
|
||||
height?: number | string;
|
||||
width?: number | string;
|
||||
|
||||
scrollbar?: boolean;
|
||||
}
|
||||
|
||||
export interface IHeader {
|
||||
id?: string;
|
||||
children?: any;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export interface IBody {
|
||||
id?: string;
|
||||
children?: any;
|
||||
className?: string;
|
||||
scrollbar?: boolean;
|
||||
}
|
||||
|
||||
export interface IFooter {
|
||||
id?: string;
|
||||
children?: any;
|
||||
className?: string;
|
||||
}
|
||||
@@ -123,6 +123,18 @@ const FirecampThemeProvider: FC<IFirecampThemeProvider> = ({
|
||||
>
|
||||
<MantineProvider
|
||||
theme={{
|
||||
// TODO: add preflight css in globalstyles to prevent any styling issue
|
||||
globalStyles: (theme) => ({
|
||||
'button,input,optgroup,select,textarea': {
|
||||
fontFamily: 'inherit',
|
||||
fontSize: '100%',
|
||||
fontWeight: 'inherit',
|
||||
lineHeight: 'inherit',
|
||||
color: 'inherit',
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
},
|
||||
}),
|
||||
colorScheme,
|
||||
colors: {
|
||||
'primary-color': [
|
||||
|
||||
@@ -453,10 +453,6 @@
|
||||
.z-30{
|
||||
z-index: 30;
|
||||
|
||||
}
|
||||
.z-50{
|
||||
z-index: 50;
|
||||
|
||||
}
|
||||
.float-right{
|
||||
float: right;
|
||||
@@ -2087,6 +2083,10 @@
|
||||
.pt-3{
|
||||
padding-top: 0.75rem;
|
||||
|
||||
}
|
||||
.pt-4{
|
||||
padding-top: 1rem;
|
||||
|
||||
}
|
||||
.pt-5{
|
||||
padding-top: 1.25rem;
|
||||
|
||||
@@ -29,8 +29,8 @@ export { default as Input } from './components/input/Input';
|
||||
export { default as FileInput } from './components/input/FileInput';
|
||||
|
||||
// Modal
|
||||
export { default as Modal } from './components/modal/Modalv2';
|
||||
export type { IModal } from './components/modal/Modalv2';
|
||||
export { default as Modal } from './components/modal/Modal';
|
||||
export type { IModal } from './components/modal/Modal';
|
||||
|
||||
export { default as SplitView } from './components/split-view/SplitView';
|
||||
|
||||
|
||||
10239
pnpm-lock.yaml
generated
10239
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user