Skip to content

Commit eb63913

Browse files
committed
feat(Prompt): New component promptcomponent
Signed-off-by: Sudhanshu Dasgupta <[email protected]>
1 parent cec1406 commit eb63913

File tree

4 files changed

+156
-0
lines changed

4 files changed

+156
-0
lines changed

src/custom/Prompt/index.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import PromptComponent from './promt-component';
2+
3+
export default PromptComponent;

src/custom/Prompt/promt-component.tsx

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import { useTheme } from '@mui/material';
2+
import { forwardRef, useImperativeHandle, useRef, useState } from 'react';
3+
import { Typography } from '../../base';
4+
import { Modal, ModalBody, ModalButtonPrimary, ModalButtonSecondary, ModalFooter } from '../Modal';
5+
import { ActionComponent, Subtitle } from './style';
6+
7+
/* Promt variants are used to define the color of the prompt button */
8+
export const PROMPT_VARIANTS = {
9+
WARNING: 'warning',
10+
DANGER: 'error',
11+
SUCCESS: 'success',
12+
INFO: 'info'
13+
} as const;
14+
15+
type PromptVariant = (typeof PROMPT_VARIANTS)[keyof typeof PROMPT_VARIANTS];
16+
17+
interface PromptProps {
18+
variant?: PromptVariant;
19+
}
20+
21+
interface State {
22+
isOpen: boolean;
23+
title: string;
24+
subtitle?: string;
25+
primaryOption: string;
26+
showInfoIcon?: string;
27+
variant?: PromptVariant;
28+
}
29+
30+
interface ShowParams {
31+
title: string;
32+
subtitle: string;
33+
primaryOption: string;
34+
variant: PromptVariant;
35+
showInfoIcon?: string;
36+
}
37+
38+
interface PromptRef {
39+
show: (params: ShowParams) => Promise<string>;
40+
}
41+
42+
const PromptComponent = forwardRef<PromptRef, PromptProps>(({ variant }, ref) => {
43+
const [state, setState] = useState<State>({
44+
isOpen: false,
45+
title: '',
46+
subtitle: '',
47+
primaryOption: '',
48+
showInfoIcon: '',
49+
variant
50+
});
51+
52+
/* This ref is used to store the resolve and reject functions of the promise returned by the show method */
53+
const promiseInfoRef = useRef<{ resolve: (value: string) => void; reject: () => void }>({
54+
resolve: () => {},
55+
reject: () => {}
56+
});
57+
58+
const theme = useTheme();
59+
60+
/* This function is used to show the prompt */
61+
const show = (params: ShowParams) => {
62+
return new Promise<string>((resolve, reject) => {
63+
promiseInfoRef.current = { resolve, reject };
64+
setState({
65+
...params,
66+
isOpen: true,
67+
showInfoIcon: params.showInfoIcon || ''
68+
});
69+
});
70+
};
71+
72+
/* This function is used to hide the prompt */
73+
const hide = () => {
74+
setState((prevState) => ({ ...prevState, isOpen: false }));
75+
};
76+
77+
useImperativeHandle(ref, () => ({
78+
show
79+
}));
80+
81+
const { isOpen, primaryOption, title, subtitle, showInfoIcon } = state;
82+
const { resolve } = promiseInfoRef.current;
83+
84+
return (
85+
<Modal
86+
open={isOpen}
87+
closeModal={hide}
88+
title={title}
89+
id="searchClick"
90+
headerIcon={undefined}
91+
reactNode={undefined}
92+
>
93+
{subtitle && (
94+
<ModalBody>
95+
<Subtitle id="alert-dialog-description" variant="body1" component="div">
96+
<Typography variant="body1" component="div">
97+
{subtitle}
98+
</Typography>
99+
</Subtitle>
100+
</ModalBody>
101+
)}
102+
<ModalFooter variant="filled" helpText={showInfoIcon}>
103+
<ActionComponent>
104+
<ModalButtonSecondary
105+
onClick={() => {
106+
hide();
107+
resolve('CANCEL');
108+
}}
109+
>
110+
Cancel
111+
</ModalButtonSecondary>
112+
<ModalButtonPrimary
113+
onClick={() => {
114+
hide();
115+
resolve(primaryOption);
116+
}}
117+
style={
118+
state.variant && {
119+
backgroundColor: theme.palette.background[state.variant]?.default,
120+
textTransform: 'capitalize'
121+
}
122+
}
123+
type="submit"
124+
>
125+
{primaryOption}
126+
</ModalButtonPrimary>
127+
</ActionComponent>
128+
</ModalFooter>
129+
</Modal>
130+
);
131+
});
132+
133+
PromptComponent.displayName = 'PromptComponent';
134+
135+
export default PromptComponent;

src/custom/Prompt/style.tsx

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { styled } from '@mui/material';
2+
import { Box, DialogContentText } from '../../base';
3+
4+
export const Subtitle = styled(DialogContentText)(() => ({
5+
minWidth: 400,
6+
overflowWrap: 'anywhere',
7+
textAlign: 'center',
8+
padding: '5px'
9+
}));
10+
11+
export const ActionComponent = styled(Box)(() => ({
12+
display: 'flex',
13+
justifyContent: 'end',
14+
width: '100%',
15+
gap: '10px'
16+
}));

src/custom/index.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { LearningCard } from './LearningCard';
3333
import { RenderMarkdown } from './Markdown';
3434
import { ModalCard } from './ModalCard';
3535
import PopperListener, { IPopperListener } from './PopperListener';
36+
import PromptComponent from './Prompt';
3637
import ResponsiveDataTable, {
3738
DataTableEllipsisMenu,
3839
ResponsiveDataTableProps
@@ -71,6 +72,7 @@ export {
7172
LearningCard,
7273
ModalCard,
7374
PopperListener,
75+
PromptComponent,
7476
ResponsiveDataTable,
7577
SearchBar,
7678
StyledDialogActions,

0 commit comments

Comments
 (0)