parent
1c0ddd59b0
commit
74495758e0
4 changed files with 122 additions and 63 deletions
@ -1,78 +1,108 @@ |
||||
import { styled, Typography, TypographyProps } from '@mui/material'; |
||||
import { FC, ReactNode } from 'react'; |
||||
import { |
||||
Typography as MUITypography, |
||||
TypographyProps as MUITypographyProps, |
||||
} from '@mui/material'; |
||||
|
||||
import { BLACK, TEXT, UNSELECTED } from '../../lib/consts/DEFAULT_THEME'; |
||||
|
||||
const PREFIX = 'BodyText'; |
||||
type BodyTextOptionalProps = { |
||||
inverted?: boolean; |
||||
monospaced?: boolean; |
||||
selected?: boolean; |
||||
text?: null | ReactNode | string; |
||||
}; |
||||
|
||||
type BodyTextProps = MUITypographyProps & BodyTextOptionalProps; |
||||
|
||||
const BODY_TEXT_CLASS_PREFIX = 'BodyText'; |
||||
|
||||
const classes = { |
||||
inverted: `${PREFIX}-inverted`, |
||||
selected: `${PREFIX}-selected`, |
||||
unselected: `${PREFIX}-unselected`, |
||||
const BODY_TEXT_DEFAULT_PROPS: Required<BodyTextOptionalProps> = { |
||||
inverted: false, |
||||
monospaced: false, |
||||
selected: true, |
||||
text: null, |
||||
}; |
||||
|
||||
const StyledTypography = styled(Typography)(() => ({ |
||||
[`&.${classes.inverted}`]: { |
||||
color: BLACK, |
||||
}, |
||||
const BODY_TEXT_CLASSES = { |
||||
inverted: `${BODY_TEXT_CLASS_PREFIX}-inverted`, |
||||
monospaced: `${BODY_TEXT_CLASS_PREFIX}-monospaced`, |
||||
selected: `${BODY_TEXT_CLASS_PREFIX}-selected`, |
||||
unselected: `${BODY_TEXT_CLASS_PREFIX}-unselected`, |
||||
}; |
||||
|
||||
[`&.${classes.selected}`]: { |
||||
color: TEXT, |
||||
}, |
||||
const buildBodyTextClasses = ({ |
||||
isInvert, |
||||
isMonospace, |
||||
isSelect, |
||||
}: { |
||||
isInvert?: boolean; |
||||
isMonospace?: boolean; |
||||
isSelect?: boolean; |
||||
}) => { |
||||
const bodyTextClasses: string[] = []; |
||||
|
||||
[`&.${classes.unselected}`]: { |
||||
color: UNSELECTED, |
||||
}, |
||||
})); |
||||
if (isInvert) { |
||||
bodyTextClasses.push(BODY_TEXT_CLASSES.inverted); |
||||
} else if (isSelect) { |
||||
bodyTextClasses.push(BODY_TEXT_CLASSES.selected); |
||||
} else { |
||||
bodyTextClasses.push(BODY_TEXT_CLASSES.unselected); |
||||
} |
||||
|
||||
type BodyTextProps = TypographyProps & { |
||||
inverted?: boolean; |
||||
selected?: boolean; |
||||
text: string; |
||||
if (isMonospace) { |
||||
bodyTextClasses.push(BODY_TEXT_CLASSES.monospaced); |
||||
} |
||||
|
||||
return bodyTextClasses.join(' '); |
||||
}; |
||||
|
||||
const BodyText = ({ |
||||
inverted, |
||||
selected, |
||||
const BodyText: FC<BodyTextProps> = ({ |
||||
children, |
||||
inverted = BODY_TEXT_DEFAULT_PROPS.inverted, |
||||
monospaced = BODY_TEXT_DEFAULT_PROPS.monospaced, |
||||
selected = BODY_TEXT_DEFAULT_PROPS.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 ( |
||||
<StyledTypography |
||||
{...{ sx }} |
||||
className={buildBodyTextClasses({ |
||||
text = BODY_TEXT_DEFAULT_PROPS.text, |
||||
...muiTypographyRestProps |
||||
}) => ( |
||||
<MUITypography |
||||
{...{ |
||||
className: buildBodyTextClasses({ |
||||
isInvert: inverted, |
||||
isMonospace: monospaced, |
||||
isSelect: selected, |
||||
})} |
||||
variant="subtitle1" |
||||
> |
||||
{text} |
||||
</StyledTypography> |
||||
); |
||||
}; |
||||
}), |
||||
variant: 'subtitle1', |
||||
...muiTypographyRestProps, |
||||
sx: { |
||||
[`&.${BODY_TEXT_CLASSES.inverted}`]: { |
||||
color: BLACK, |
||||
}, |
||||
|
||||
BodyText.defaultProps = { |
||||
inverted: false, |
||||
selected: true, |
||||
}; |
||||
[`&.${BODY_TEXT_CLASSES.monospaced}`]: { |
||||
fontFamily: 'Source Code Pro', |
||||
fontWeight: 400, |
||||
}, |
||||
|
||||
[`&.${BODY_TEXT_CLASSES.selected}`]: { |
||||
color: TEXT, |
||||
}, |
||||
|
||||
[`&.${BODY_TEXT_CLASSES.unselected}`]: { |
||||
color: UNSELECTED, |
||||
}, |
||||
|
||||
...sx, |
||||
}, |
||||
}} |
||||
> |
||||
{text ?? children} |
||||
</MUITypography> |
||||
); |
||||
|
||||
BodyText.defaultProps = BODY_TEXT_DEFAULT_PROPS; |
||||
|
||||
export type { BodyTextProps }; |
||||
|
||||
export default BodyText; |
||||
|
@ -0,0 +1,27 @@ |
||||
import { FC } from 'react'; |
||||
|
||||
import { |
||||
BORDER_RADIUS, |
||||
MONOSPACE_BACKGROUND, |
||||
} from '../../lib/consts/DEFAULT_THEME'; |
||||
|
||||
import BodyText, { BodyTextProps } from './BodyText'; |
||||
|
||||
const Monospace: FC<BodyTextProps> = ({ sx, ...bodyTextRestProps }) => ( |
||||
<BodyText |
||||
{...{ |
||||
...bodyTextRestProps, |
||||
monospaced: true, |
||||
sx: { |
||||
backgroundColor: MONOSPACE_BACKGROUND, |
||||
borderRadius: BORDER_RADIUS, |
||||
display: 'inline', |
||||
padding: '.1rem .3rem', |
||||
|
||||
...sx, |
||||
}, |
||||
}} |
||||
/> |
||||
); |
||||
|
||||
export default Monospace; |
@ -1,4 +1,5 @@ |
||||
import HeaderText from './HeaderText'; |
||||
import BodyText from './BodyText'; |
||||
import HeaderText from './HeaderText'; |
||||
import Monospace from './Monospace'; |
||||
|
||||
export { HeaderText, BodyText }; |
||||
export { BodyText, HeaderText, Monospace }; |
||||
|
Loading…
Reference in new issue