fix(striker-ui): isolate message box for reuse

main
Tsu-ba-me 3 years ago
parent 131c50863e
commit 8632f29db2
  1. 34
      striker-ui/components/Files/Files.tsx
  2. 100
      striker-ui/components/MessageBox.tsx
  3. 43
      striker-ui/components/Text/BodyText.tsx

@ -9,39 +9,21 @@ import { styled } from '@mui/material/styles';
import EventEmitter from 'events'; import EventEmitter from 'events';
import API_BASE_URL from '../../lib/consts/API_BASE_URL'; import API_BASE_URL from '../../lib/consts/API_BASE_URL';
import { BLUE, PURPLE, RED } from '../../lib/consts/DEFAULT_THEME'; import { BLUE } from '../../lib/consts/DEFAULT_THEME';
import ICON_BUTTON_STYLE from '../../lib/consts/ICON_BUTTON_STYLE'; import ICON_BUTTON_STYLE from '../../lib/consts/ICON_BUTTON_STYLE';
import { Panel } from '../Panels'; import FileEditForm from './FileEditForm';
import Spinner from '../Spinner';
import { BodyText, HeaderText } from '../Text';
import FileList from './FileList'; import FileList from './FileList';
import FileUploadForm from './FileUploadForm'; import FileUploadForm from './FileUploadForm';
import FileEditForm from './FileEditForm'; import { Panel } from '../Panels';
import MessageBox from '../MessageBox';
import Spinner from '../Spinner';
import { HeaderText } from '../Text';
import fetchJSON from '../../lib/fetchers/fetchJSON'; import fetchJSON from '../../lib/fetchers/fetchJSON';
const StyledIconButton = styled(IconButton)(ICON_BUTTON_STYLE); const StyledIconButton = styled(IconButton)(ICON_BUTTON_STYLE);
const MESSAGE_BOX_CLASS_PREFIX = 'MessageBox';
const MESSAGE_BOX_CLASSES = {
error: `${MESSAGE_BOX_CLASS_PREFIX}-error`,
warning: `${MESSAGE_BOX_CLASS_PREFIX}-warning`,
};
const MessageBox = styled(Box)({
padding: '.2em .4em',
[`&.${MESSAGE_BOX_CLASSES.error}`]: {
backgroundColor: RED,
},
[`&.${MESSAGE_BOX_CLASSES.warning}`]: {
backgroundColor: PURPLE,
},
});
const Files = (): JSX.Element => { const Files = (): JSX.Element => {
const [rawFilesOverview, setRawFilesOverview] = useState<string[][]>([]); const [rawFilesOverview, setRawFilesOverview] = useState<string[][]>([]);
const [fetchRawFilesError, setFetchRawFilesError] = useState<string>(); const [fetchRawFilesError, setFetchRawFilesError] = useState<string>();
@ -135,9 +117,7 @@ const Files = (): JSX.Element => {
</StyledIconButton> </StyledIconButton>
</Box> </Box>
{fetchRawFilesError && ( {fetchRawFilesError && (
<MessageBox className={MESSAGE_BOX_CLASSES.error}> <MessageBox text={fetchRawFilesError} type="error" />
<BodyText text={fetchRawFilesError} />
</MessageBox>
)} )}
<FileUploadForm <FileUploadForm
{...{ eventEmitter: fileUploadFormEventEmitter }} {...{ eventEmitter: fileUploadFormEventEmitter }}

@ -0,0 +1,100 @@
import { Box, styled } from '@mui/material';
import {
Error as ErrorIcon,
Info as InfoIcon,
Warning as WarningIcon,
} from '@mui/icons-material';
import {
BLACK,
BORDER_RADIUS,
GREY,
PURPLE,
RED,
TEXT,
} from '../lib/consts/DEFAULT_THEME';
import { BodyText } from './Text';
type MessageBoxType = 'error' | 'info' | 'warning';
type MessageBoxProps = {
text: string;
type: MessageBoxType;
};
const MESSAGE_BOX_CLASS_PREFIX = 'MessageBox';
const MESSAGE_BOX_CLASSES: Record<MessageBoxType, string> = {
error: `${MESSAGE_BOX_CLASS_PREFIX}-error`,
info: `${MESSAGE_BOX_CLASS_PREFIX}-info`,
warning: `${MESSAGE_BOX_CLASS_PREFIX}-warning`,
};
const StyledBox = styled(Box)({
alignItems: 'center',
borderRadius: BORDER_RADIUS,
display: 'flex',
flexDirection: 'row',
padding: '.3em .6em',
'& > *': {
color: TEXT,
},
'& > :first-child': {
marginRight: '.3em',
},
[`&.${MESSAGE_BOX_CLASSES.error}`]: {
backgroundColor: RED,
},
[`&.${MESSAGE_BOX_CLASSES.info}`]: {
backgroundColor: GREY,
'& > :first-child': {
color: `${BLACK}`,
},
},
[`&.${MESSAGE_BOX_CLASSES.warning}`]: {
backgroundColor: PURPLE,
},
});
const MessageBox = ({ type, text }: MessageBoxProps): JSX.Element => {
const buildMessageBoxClasses = (messageBoxType: MessageBoxType) => {
return MESSAGE_BOX_CLASSES[messageBoxType];
};
const buildMessageIcon = (messageBoxType: MessageBoxType) => {
let messageIcon;
switch (messageBoxType) {
case 'error':
messageIcon = <ErrorIcon />;
break;
case 'warning':
messageIcon = <WarningIcon />;
break;
default:
messageIcon = <InfoIcon />;
}
return messageIcon;
};
const buildMessage = (message: string, messageBoxType: MessageBoxType) => {
return <BodyText inverted={messageBoxType === 'info'} text={message} />;
};
return (
<StyledBox className={buildMessageBoxClasses(type)}>
{buildMessageIcon(type)}
{buildMessage(text, type)}
</StyledBox>
);
};
export default MessageBox;

@ -1,15 +1,20 @@
import { styled, Typography, TypographyProps } from '@mui/material'; import { styled, Typography, TypographyProps } from '@mui/material';
import { TEXT, UNSELECTED } from '../../lib/consts/DEFAULT_THEME'; import { BLACK, TEXT, UNSELECTED } from '../../lib/consts/DEFAULT_THEME';
const PREFIX = 'BodyText'; const PREFIX = 'BodyText';
const classes = { const classes = {
inverted: `${PREFIX}-inverted`,
selected: `${PREFIX}-selected`, selected: `${PREFIX}-selected`,
unselected: `${PREFIX}-unselected`, unselected: `${PREFIX}-unselected`,
}; };
const StyledTypography = styled(Typography)(() => ({ const StyledTypography = styled(Typography)(() => ({
[`&.${classes.inverted}`]: {
color: BLACK,
},
[`&.${classes.selected}`]: { [`&.${classes.selected}`]: {
color: TEXT, color: TEXT,
}, },
@ -20,15 +25,44 @@ const StyledTypography = styled(Typography)(() => ({
})); }));
type BodyTextProps = TypographyProps & { type BodyTextProps = TypographyProps & {
text: string; inverted?: boolean;
selected?: boolean; selected?: boolean;
text: string;
}; };
const BodyText = ({ sx, text, selected }: BodyTextProps): JSX.Element => { const BodyText = ({
inverted,
selected,
sx,
text,
}: BodyTextProps): JSX.Element => {
const buildBodyTextClasses = ({
isInvert,
isSelect,
}: {
isInvert?: boolean;
isSelect?: boolean;
}) => {
let bodyTextClasses = '';
if (isInvert) {
bodyTextClasses += classes.inverted;
} else if (isSelect) {
bodyTextClasses += classes.selected;
} else {
bodyTextClasses += classes.unselected;
}
return bodyTextClasses;
};
return ( return (
<StyledTypography <StyledTypography
{...{ sx }} {...{ sx }}
className={selected ? classes.selected : classes.unselected} className={buildBodyTextClasses({
isInvert: inverted,
isSelect: selected,
})}
variant="subtitle1" variant="subtitle1"
> >
{text} {text}
@ -37,6 +71,7 @@ const BodyText = ({ sx, text, selected }: BodyTextProps): JSX.Element => {
}; };
BodyText.defaultProps = { BodyText.defaultProps = {
inverted: false,
selected: true, selected: true,
}; };

Loading…
Cancel
Save